Skip to content

Conversation

@hykilpikonna
Copy link
Collaborator

@hykilpikonna hykilpikonna commented Oct 24, 2025

This would finally make AquaDX pure kotlin

TODO next:

  • Remove all java dependencies???

Sourcery 总结

删除遗留的Java模块和依赖项,将代码库转换为纯Kotlin,重构工具类和加密逻辑,引入新的ByteBuf扩展和CardMakerController API,并添加Flyway迁移以删除旧的数据库表。

新功能:

  • 为ByteBuf添加ByteBuf.toBytes()和toAllBytes()扩展函数
  • 引入纯Kotlin的CardMakerController及相关的控制器建议

改进:

  • 将Jackson映射工具迁移到Kotlin util包中,并相应更新导入
  • 重构加密方法以使用ByteBuf扩展并删除ByteBufUtil依赖
  • 通过将细粒度的util导入替换为ext.*来整合导入语句

构建:

  • 添加Flyway SQL迁移以删除遗留的maimai和chuni表

杂项:

  • 删除DIVA、chunithm、maimai及其他遗留模块的所有基于Java的处理程序和模型类
  • 删除.gitlab-ci.yml和Windows启动脚本
Original summary in English

Summary by Sourcery

Drop legacy Java modules and dependencies to convert the codebase to pure Kotlin, refactor utilities and encryption logic, introduce new ByteBuf extensions and a CardMakerController API, and add a Flyway migration to remove old database tables.

New Features:

  • Add ByteBuf.toBytes() and toAllBytes() extension functions for ByteBuf
  • Introduce a pure Kotlin CardMakerController and associated controller advice

Enhancements:

  • Migrate Jackson mapping utilities into a Kotlin util package and update imports accordingly
  • Refactor encryption methods to use ByteBuf extensions and remove ByteBufUtil dependency
  • Consolidate import statements by replacing granular util imports with ext.*

Build:

  • Add a Flyway SQL migration to drop legacy maimai and chuni tables

Chores:

  • Remove all Java-based handler and model classes for DIVA, chunithm, maimai, and other legacy modules
  • Delete .gitlab-ci.yml and Windows startup script

@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Oct 24, 2025

审阅者指南

此 PR 清理了遗留的 Java 代码库,转而采用纯 Kotlin 实现,标准化了跨模块的工具和导入用法,重组了 JSON 序列化辅助工具,添加了新的卡片制作器 API,并包含一个数据库迁移以删除废弃的表。

数据库迁移中已删除表的 ER 图

erDiagram
    MAIMAI_USER_WEB_OPTION ||--o| MAIMAI_USER_DATA : "user_id"
    MAIMAI_USER_SURVIVAL ||--o| MAIMAI_USER_DATA : "user_id"
    MAIMAI_USER_PRESENT_EVENT ||--o| MAIMAI_USER_DATA : "user_id"
    MAIMAI_USER_PLAYLOG ||--o| MAIMAI_USER_DATA : "user_id"
    MAIMAI_USER_OPTION ||--o| MAIMAI_USER_DATA : "user_id"
    MAIMAI_USER_MUSIC_DETAIL ||--o| MAIMAI_USER_DATA : "user_id"
    MAIMAI_USER_GENERAL_DATA ||--o| MAIMAI_USER_DATA : "user_id"
    MAIMAI_USER_CHARACTER ||--o| MAIMAI_USER_DATA : "user_id"
    MAIMAI_USER_BOSS ||--o| MAIMAI_USER_DATA : "user_id"
    MAIMAI_USER_ACTIVITY ||--o| MAIMAI_USER_DATA : "user_id"
    MAIMAI_USER_ITEM ||--o| MAIMAI_USER_DATA : "user_id"
    MAIMAI_GAME_EVENT ||--o| MAIMAI_USER_DATA : "event_id"
    CHUNI_GAME_CHARACTER ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_GAME_CHARGE ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_GAME_EVENT ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_GAME_MESSAGE ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_GAME_SKILL ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_MUSIC_LEVEL ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_USER_ACTIVITY ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_USER_CHARACTER ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_USER_CHARGE ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_USER_COURSE ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_USER_DUEL ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_USER_GAME_OPTION ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_USER_GAME_OPTION_EX ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_USER_GENERAL_DATA ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_USER_ITEM ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_USER_MAP ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_USER_MUSIC_DETAIL ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_USER_PLAYLOG ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_MUSIC ||--o| CHUNI_USER_DATA : "music_id"
    CHUNI_USER_DATA_EX ||--o| CHUNI_USER_DATA : "user_id"
    SEGA_GAME_VERSION ||--o| CHUNI_USER_DATA : "version_id"
Loading

新 CardMakerController 和 CardMakerControllerAdvice 的类图

classDiagram
    class CardMakerController {
        +BasicMapper mapper
        +String ALLNET_HOST
        +String ALLNET_PORT
        +String SERVER_PORT
        +getGameSetting(request: MutableMap<String, Any>): Any?
        +getGameConnect(request: MutableMap<String, Any>): Any?
        +getClientBookkeeping(request: MutableMap<String, Any>): Any?
        +upsertClientBookkeeping(): String
        +upsertClientSetting(): String
    }
    class CardMakerControllerAdvice {
        +preHandle(request: HttpServletRequest): MutableMap<String, Any>
    }
    CardMakerController --> BasicMapper
    CardMakerControllerAdvice --> HttpServletRequest
Loading

新 PropertyEntry 和 PropertyEntryRepository 的类图

classDiagram
    class PropertyEntry {
        +Long id
        +String propertyKey
        +String propertyValue
        +PropertyEntry(propertyKey: String, propertyValue: String)
        +PropertyEntry()
    }
    class PropertyEntryRepository {
        +findByPropertyKey(key: String): Optional<PropertyEntry>
    }
    PropertyEntryRepository --> PropertyEntry
Loading

新 CompressRequestWrapper 的类图

classDiagram
    class CompressRequestWrapper {
        +ByteArrayInputStream input
        +ServletInputStream? filterInput
        +getInputStream(): ServletInputStream
    }
    CompressRequestWrapper --> HttpServletRequestWrapper
Loading

新 UserRecentRating 的类图

classDiagram
    class UserRecentRating {
        +Int musicId
        +Int difficultId
        +String romVersionCode
        +Int score
        +toString(): String
    }
Loading

新 CardRepository 的类图

classDiagram
    class CardRepository {
        +findByExtId(extId: Long): Optional<Card>
        +findByLuid(luid: String): Optional<Card>
    }
    CardRepository --> Card
Loading

新 URIEncoder 对象的类图

classDiagram
    class URIEncoder {
        +encode(str: String): String
    }
Loading

文件级变更

变更 详情 文件
将 ByteBufUtil 替换为 Kotlin 扩展函数以支持 ByteBuf 加密
  • 添加了 ByteBuf.toBytes() 和 toAllBytes() 扩展函数
  • 更新了 AimeDbEncryption.encrypt/decrypt 以使用新的扩展
src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbEncryption.kt
清理并标准化网络和游戏模块中的导入
  • 删除了未使用的/特定的导入,转而使用 ext.* 或目标 ext 函数
  • 重新排序了 Spring 和工具导入以保持一致性
src/main/java/icu/samnyan/aqua/net/Fedy.kt
src/main/java/icu/samnyan/aqua/net/games/mai2/Maimai2.kt
src/main/java/icu/samnyan/aqua/sega/maimai2/Maimai2ServletController.kt
src/main/java/icu/samnyan/aqua/sega/chusan/ChusanController.kt
src/main/java/icu/samnyan/aqua/sega/ongeki/OngekiController.kt
src/main/java/icu/samnyan/aqua/net/games/ImportController.kt
将 JSON 序列化工具从 util.jackson 迁移到 util 包
  • 将 BasicMapper 和相关序列化器移动到 icu.samnyan.aqua.sega.util 中
  • 更新了处理程序和控制器中的导入,以引用新包
src/main/java/icu/samnyan/aqua/sega/util/BasicMapper.kt
src/main/java/icu/samnyan/aqua/sega/util/Serializers.kt
multiple handler and controller files
引入新的 CardMakerController 及其建议,以处理卡片制作器 API
  • 添加了基于 Kotlin 的 CardMakerController,包含游戏设置/连接/记账端点
  • 添加了 CardMakerControllerAdvice 用于 JSON 请求解析
src/main/java/icu/samnyan/aqua/sega/cardmaker/CardMakerController.kt
src/main/java/icu/samnyan/aqua/sega/cardmaker/CardMakerControllerAdvice.kt
添加数据库迁移以删除废弃的表作为代码库清理的一部分
  • 创建了 V1000_60__drop_the_codebase.sql,其中列出了 maimai、chuni 和 version 表的 DROP TABLE 语句
src/main/resources/db/80/V1000_60__drop_the_codebase.sql
删除遗留的 Java DIVA 处理程序和旧的卡片制作器控制器
  • 删除了所有基于 Java 的 DIVA 服务器处理程序和过时的卡片制作器 Java 类
  • 删除了废弃的 .gitlab-ci.yml 条目和相关的 Java 工件
multiple Java files under src/main/java/icu/samnyan/aqua/sega/diva
various Java files under src/main/java/icu/samnyan/aqua/sega/cardmaker
重构 CardService 方法签名以保持一致性
  • 移除了 getCardByExtId 的可空重载
  • 统一方法以仅接受非空 Long
src/main/java/icu/samnyan/aqua/sega/general/service/CardService.kt

提示和命令

与 Sourcery 交互

  • 触发新审阅: 在拉取请求上评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的审阅评论。
  • 从审阅评论生成 GitHub issue: 通过回复审阅评论,让 Sourcery 从中创建一个 issue。你也可以回复审阅评论并加上 @sourcery-ai issue 来创建 issue。
  • 生成拉取请求标题: 随时在拉取请求标题中的任意位置写入 @sourcery-ai 以生成标题。你也可以在拉取请求上评论 @sourcery-ai title 以随时(重新)生成标题。
  • 生成拉取请求摘要: 随时在拉取请求正文中的任意位置写入 @sourcery-ai summary 以在你想要的位置生成 PR 摘要。你也可以在拉取请求上评论 @sourcery-ai summary 以随时(重新)生成摘要。
  • 生成审阅者指南: 在拉取请求上评论 @sourcery-ai guide 以随时(重新)生成审阅者指南。
  • 解决所有 Sourcery 评论: 在拉取请求上评论 @sourcery-ai resolve 以解决所有 Sourcery 评论。如果你已经解决了所有评论并且不想再看到它们,这会很有用。
  • 驳回所有 Sourcery 审阅: 在拉取请求上评论 @sourcery-ai dismiss 以驳回所有现有的 Sourcery 审阅。如果你想重新开始一个新审阅,这会特别有用——别忘了评论 @sourcery-ai review 来触发新审阅!

自定义你的体验

访问你的仪表盘以:

  • 启用或禁用审阅功能,例如 Sourcery 生成的拉取请求摘要、审阅者指南以及其他功能。
  • 更改审阅语言。
  • 添加、删除或编辑自定义审阅说明。
  • 调整其他审阅设置。

获取帮助

Original review guide in English

Reviewer's Guide

This PR purges the legacy Java codebase in favor of a pure Kotlin implementation, standardizes utility and import usage across modules, reorganizes JSON serialization helpers, adds new card maker APIs, and includes a database migration to drop obsolete tables.

ER diagram for dropped tables in database migration

erDiagram
    MAIMAI_USER_WEB_OPTION ||--o| MAIMAI_USER_DATA : "user_id"
    MAIMAI_USER_SURVIVAL ||--o| MAIMAI_USER_DATA : "user_id"
    MAIMAI_USER_PRESENT_EVENT ||--o| MAIMAI_USER_DATA : "user_id"
    MAIMAI_USER_PLAYLOG ||--o| MAIMAI_USER_DATA : "user_id"
    MAIMAI_USER_OPTION ||--o| MAIMAI_USER_DATA : "user_id"
    MAIMAI_USER_MUSIC_DETAIL ||--o| MAIMAI_USER_DATA : "user_id"
    MAIMAI_USER_GENERAL_DATA ||--o| MAIMAI_USER_DATA : "user_id"
    MAIMAI_USER_CHARACTER ||--o| MAIMAI_USER_DATA : "user_id"
    MAIMAI_USER_BOSS ||--o| MAIMAI_USER_DATA : "user_id"
    MAIMAI_USER_ACTIVITY ||--o| MAIMAI_USER_DATA : "user_id"
    MAIMAI_USER_ITEM ||--o| MAIMAI_USER_DATA : "user_id"
    MAIMAI_GAME_EVENT ||--o| MAIMAI_USER_DATA : "event_id"
    CHUNI_GAME_CHARACTER ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_GAME_CHARGE ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_GAME_EVENT ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_GAME_MESSAGE ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_GAME_SKILL ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_MUSIC_LEVEL ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_USER_ACTIVITY ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_USER_CHARACTER ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_USER_CHARGE ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_USER_COURSE ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_USER_DUEL ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_USER_GAME_OPTION ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_USER_GAME_OPTION_EX ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_USER_GENERAL_DATA ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_USER_ITEM ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_USER_MAP ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_USER_MUSIC_DETAIL ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_USER_PLAYLOG ||--o| CHUNI_USER_DATA : "user_id"
    CHUNI_MUSIC ||--o| CHUNI_USER_DATA : "music_id"
    CHUNI_USER_DATA_EX ||--o| CHUNI_USER_DATA : "user_id"
    SEGA_GAME_VERSION ||--o| CHUNI_USER_DATA : "version_id"
Loading

Class diagram for new CardMakerController and CardMakerControllerAdvice

classDiagram
    class CardMakerController {
        +BasicMapper mapper
        +String ALLNET_HOST
        +String ALLNET_PORT
        +String SERVER_PORT
        +getGameSetting(request: MutableMap<String, Any>): Any?
        +getGameConnect(request: MutableMap<String, Any>): Any?
        +getClientBookkeeping(request: MutableMap<String, Any>): Any?
        +upsertClientBookkeeping(): String
        +upsertClientSetting(): String
    }
    class CardMakerControllerAdvice {
        +preHandle(request: HttpServletRequest): MutableMap<String, Any>
    }
    CardMakerController --> BasicMapper
    CardMakerControllerAdvice --> HttpServletRequest
Loading

Class diagram for new PropertyEntry and PropertyEntryRepository

classDiagram
    class PropertyEntry {
        +Long id
        +String propertyKey
        +String propertyValue
        +PropertyEntry(propertyKey: String, propertyValue: String)
        +PropertyEntry()
    }
    class PropertyEntryRepository {
        +findByPropertyKey(key: String): Optional<PropertyEntry>
    }
    PropertyEntryRepository --> PropertyEntry
Loading

Class diagram for new CompressRequestWrapper

classDiagram
    class CompressRequestWrapper {
        +ByteArrayInputStream input
        +ServletInputStream? filterInput
        +getInputStream(): ServletInputStream
    }
    CompressRequestWrapper --> HttpServletRequestWrapper
Loading

Class diagram for new UserRecentRating

classDiagram
    class UserRecentRating {
        +Int musicId
        +Int difficultId
        +String romVersionCode
        +Int score
        +toString(): String
    }
Loading

Class diagram for new CardRepository

classDiagram
    class CardRepository {
        +findByExtId(extId: Long): Optional<Card>
        +findByLuid(luid: String): Optional<Card>
    }
    CardRepository --> Card
Loading

Class diagram for new URIEncoder object

classDiagram
    class URIEncoder {
        +encode(str: String): String
    }
Loading

File-Level Changes

Change Details Files
Replace ByteBufUtil with Kotlin extension functions for ByteBuf encryption support
  • Added ByteBuf.toBytes() and toAllBytes() extension functions
  • Updated AimeDbEncryption.encrypt/decrypt to use new extensions
src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbEncryption.kt
Clean up and standardize imports across network and game modules
  • Removed unused/specific imports in favor of ext.* or targeted ext functions
  • Reordered Spring and utility imports for consistency
src/main/java/icu/samnyan/aqua/net/Fedy.kt
src/main/java/icu/samnyan/aqua/net/games/mai2/Maimai2.kt
src/main/java/icu/samnyan/aqua/sega/maimai2/Maimai2ServletController.kt
src/main/java/icu/samnyan/aqua/sega/chusan/ChusanController.kt
src/main/java/icu/samnyan/aqua/sega/ongeki/OngekiController.kt
src/main/java/icu/samnyan/aqua/net/games/ImportController.kt
Migrate JSON serialization utilities from util.jackson to util package
  • Moved BasicMapper and related serializers into icu.samnyan.aqua.sega.util
  • Updated imports in handlers and controllers to reference the new package
src/main/java/icu/samnyan/aqua/sega/util/BasicMapper.kt
src/main/java/icu/samnyan/aqua/sega/util/Serializers.kt
multiple handler and controller files
Introduce new CardMakerController and its advice to handle card maker APIs
  • Added Kotlin-based CardMakerController with game setting/connect/bookkeeping endpoints
  • Added CardMakerControllerAdvice for JSON request parsing
src/main/java/icu/samnyan/aqua/sega/cardmaker/CardMakerController.kt
src/main/java/icu/samnyan/aqua/sega/cardmaker/CardMakerControllerAdvice.kt
Add database migration to drop obsolete tables as part of codebase purge
  • Created V1000_60__drop_the_codebase.sql listing DROP TABLE statements for maimai, chuni, and version tables
src/main/resources/db/80/V1000_60__drop_the_codebase.sql
Remove legacy Java DIVA handlers and old cardmaker controllers
  • Deleted all Java-based DIVA server handlers and outdated cardmaker Java classes
  • Removed obsolete .gitlab-ci.yml entries and related Java artifacts
multiple Java files under src/main/java/icu/samnyan/aqua/sega/diva
various Java files under src/main/java/icu/samnyan/aqua/sega/cardmaker
Refactor CardService method signature for consistency
  • Removed nullable overload for getCardByExtId
  • Unified method to accept only non-null Long
src/main/java/icu/samnyan/aqua/sega/general/service/CardService.kt

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

大家好 - 我已审阅了您的更改 - 以下是一些反馈:

  • 这个 PR 非常大,几乎触及了整个代码库——考虑将其分解为更小、更集中的提交(例如,Kotlin 迁移、SQL 清理、Java 删除),以使审阅和验证更易于管理。
  • 您正在迁移到纯 Kotlin——不要忘记更新您的构建配置 (Gradle/Maven) 以删除 Java 源集、插件和依赖项,以便 CI 只编译 Kotlin 代码。
  • SQL 迁移删除了许多生产表——考虑在脚本中添加备份或条件检查,以防止部署过程中意外数据丢失。
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- This PR is very large and touches almost the entire codebase—consider breaking it into smaller, focused commits (e.g., Kotlin migration, SQL cleanup, Java removals) to make review and validation more manageable.
- You’re migrating to pure Kotlin—don’t forget to update your build configuration (Gradle/Maven) to remove Java source sets, plugins, and dependencies so CI only compiles Kotlin code.
- The SQL migration drops a lot of production tables—consider adding backup or conditional checks in the script to prevent accidental data loss during deployment.

## Individual Comments

### Comment 1
<location> `src/main/java/icu/samnyan/aqua/sega/general/filter/CompressRequestWrapper.kt:16` </location>
<code_context>
+    val input: ByteArrayInputStream = ByteArrayInputStream(input)
+    var filterInput: ServletInputStream? = null
+
+    override fun getInputStream(): ServletInputStream {
+        return filterInput ?: object : ServletInputStream() {
+            override fun isFinished() = false
</code_context>

<issue_to_address>
**issue (bug_risk):** isFinished and isReady always return false in ServletInputStream implementation.

This implementation may not work correctly with async or non-blocking IO. Please update these methods to accurately represent the input stream's state.
</issue_to_address>

### Comment 2
<location> `src/main/java/icu/samnyan/aqua/sega/cardmaker/CardMakerController.kt:70` </location>
<code_context>
+    )
+
+    @API("GetGameConnectApi")
+    fun getGameConnect(@ModelAttribute request: MutableMap<String, Any>): Any? {
+        val version = parsing { request["version"]!!.long } // Rom version
+        val session = TokenChecker.Companion.getCurrentSession()
</code_context>

<issue_to_address>
**issue (bug_risk):** Potential null dereference on request["version"] in getGameConnect.

Use safe access or a default value for request["version"] to prevent NullPointerException.
</issue_to_address>

### Comment 3
<location> `src/main/java/icu/samnyan/aqua/sega/cardmaker/CardMakerControllerAdvice.kt:26` </location>
<code_context>
+    @ModelAttribute
+    fun preHandle(request: HttpServletRequest): MutableMap<String, Any> {
+        val src = request.inputStream.readAllBytes()
+        val outputString = String(src, StandardCharsets.UTF_8).trim { it <= ' ' }
+        logger.info("Request ${request.requestURI}: $outputString")
+        val mapper = ObjectMapper()
</code_context>

<issue_to_address>
**suggestion (bug_risk):** Trimming with predicate 'it <= ' '' may remove valid whitespace from JSON.

Using this trim predicate may remove valid whitespace from JSON, leading to parsing errors. Please use standard trim() or ensure input validation is appropriate.

```suggestion
        val outputString = String(src, StandardCharsets.UTF_8).trim()
```
</issue_to_address>

### Comment 4
<location> `src/main/java/icu/samnyan/aqua/sega/cardmaker/CardMakerControllerAdvice.kt:28` </location>
<code_context>
+        val src = request.inputStream.readAllBytes()
+        val outputString = String(src, StandardCharsets.UTF_8).trim { it <= ' ' }
+        logger.info("Request ${request.requestURI}: $outputString")
+        val mapper = ObjectMapper()
+        return mapper.readValue(outputString, object : TypeReference<MutableMap<String, Any>>() {})
+    }
</code_context>

<issue_to_address>
**suggestion (performance):** ObjectMapper is instantiated per request, which may impact performance.

Reuse ObjectMapper as a singleton or bean to avoid unnecessary instantiation and improve performance.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Original comment in English

Hey there - I've reviewed your changes - here's some feedback:

  • This PR is very large and touches almost the entire codebase—consider breaking it into smaller, focused commits (e.g., Kotlin migration, SQL cleanup, Java removals) to make review and validation more manageable.
  • You’re migrating to pure Kotlin—don’t forget to update your build configuration (Gradle/Maven) to remove Java source sets, plugins, and dependencies so CI only compiles Kotlin code.
  • The SQL migration drops a lot of production tables—consider adding backup or conditional checks in the script to prevent accidental data loss during deployment.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- This PR is very large and touches almost the entire codebase—consider breaking it into smaller, focused commits (e.g., Kotlin migration, SQL cleanup, Java removals) to make review and validation more manageable.
- You’re migrating to pure Kotlin—don’t forget to update your build configuration (Gradle/Maven) to remove Java source sets, plugins, and dependencies so CI only compiles Kotlin code.
- The SQL migration drops a lot of production tables—consider adding backup or conditional checks in the script to prevent accidental data loss during deployment.

## Individual Comments

### Comment 1
<location> `src/main/java/icu/samnyan/aqua/sega/general/filter/CompressRequestWrapper.kt:16` </location>
<code_context>
+    val input: ByteArrayInputStream = ByteArrayInputStream(input)
+    var filterInput: ServletInputStream? = null
+
+    override fun getInputStream(): ServletInputStream {
+        return filterInput ?: object : ServletInputStream() {
+            override fun isFinished() = false
</code_context>

<issue_to_address>
**issue (bug_risk):** isFinished and isReady always return false in ServletInputStream implementation.

This implementation may not work correctly with async or non-blocking IO. Please update these methods to accurately represent the input stream's state.
</issue_to_address>

### Comment 2
<location> `src/main/java/icu/samnyan/aqua/sega/cardmaker/CardMakerController.kt:70` </location>
<code_context>
+    )
+
+    @API("GetGameConnectApi")
+    fun getGameConnect(@ModelAttribute request: MutableMap<String, Any>): Any? {
+        val version = parsing { request["version"]!!.long } // Rom version
+        val session = TokenChecker.Companion.getCurrentSession()
</code_context>

<issue_to_address>
**issue (bug_risk):** Potential null dereference on request["version"] in getGameConnect.

Use safe access or a default value for request["version"] to prevent NullPointerException.
</issue_to_address>

### Comment 3
<location> `src/main/java/icu/samnyan/aqua/sega/cardmaker/CardMakerControllerAdvice.kt:26` </location>
<code_context>
+    @ModelAttribute
+    fun preHandle(request: HttpServletRequest): MutableMap<String, Any> {
+        val src = request.inputStream.readAllBytes()
+        val outputString = String(src, StandardCharsets.UTF_8).trim { it <= ' ' }
+        logger.info("Request ${request.requestURI}: $outputString")
+        val mapper = ObjectMapper()
</code_context>

<issue_to_address>
**suggestion (bug_risk):** Trimming with predicate 'it <= ' '' may remove valid whitespace from JSON.

Using this trim predicate may remove valid whitespace from JSON, leading to parsing errors. Please use standard trim() or ensure input validation is appropriate.

```suggestion
        val outputString = String(src, StandardCharsets.UTF_8).trim()
```
</issue_to_address>

### Comment 4
<location> `src/main/java/icu/samnyan/aqua/sega/cardmaker/CardMakerControllerAdvice.kt:28` </location>
<code_context>
+        val src = request.inputStream.readAllBytes()
+        val outputString = String(src, StandardCharsets.UTF_8).trim { it <= ' ' }
+        logger.info("Request ${request.requestURI}: $outputString")
+        val mapper = ObjectMapper()
+        return mapper.readValue(outputString, object : TypeReference<MutableMap<String, Any>>() {})
+    }
</code_context>

<issue_to_address>
**suggestion (performance):** ObjectMapper is instantiated per request, which may impact performance.

Reuse ObjectMapper as a singleton or bean to avoid unnecessary instantiation and improve performance.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

val input: ByteArrayInputStream = ByteArrayInputStream(input)
var filterInput: ServletInputStream? = null

override fun getInputStream(): ServletInputStream {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): ServletInputStream 实现中 isFinished 和 isReady 始终返回 false。

此实现可能无法与异步或非阻塞 IO 正确配合。请更新这些方法以准确表示输入流的状态。

Original comment in English

issue (bug_risk): isFinished and isReady always return false in ServletInputStream implementation.

This implementation may not work correctly with async or non-blocking IO. Please update these methods to accurately represent the input stream's state.

)

@API("GetGameConnectApi")
fun getGameConnect(@ModelAttribute request: MutableMap<String, Any>): Any? {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): getGameConnect 中 request["version"] 可能存在空指针解引用。

请使用安全访问或为 request["version"] 设置默认值,以防止 NullPointerException。

Original comment in English

issue (bug_risk): Potential null dereference on request["version"] in getGameConnect.

Use safe access or a default value for request["version"] to prevent NullPointerException.

@ModelAttribute
fun preHandle(request: HttpServletRequest): MutableMap<String, Any> {
val src = request.inputStream.readAllBytes()
val outputString = String(src, StandardCharsets.UTF_8).trim { it <= ' ' }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): 使用谓词 'it <= ' '' 进行修剪可能会删除 JSON 中的有效空格。

使用此修剪谓词可能会删除 JSON 中的有效空格,从而导致解析错误。请使用标准的 trim() 或确保输入验证是适当的。

Suggested change
val outputString = String(src, StandardCharsets.UTF_8).trim { it <= ' ' }
val outputString = String(src, StandardCharsets.UTF_8).trim()
Original comment in English

suggestion (bug_risk): Trimming with predicate 'it <= ' '' may remove valid whitespace from JSON.

Using this trim predicate may remove valid whitespace from JSON, leading to parsing errors. Please use standard trim() or ensure input validation is appropriate.

Suggested change
val outputString = String(src, StandardCharsets.UTF_8).trim { it <= ' ' }
val outputString = String(src, StandardCharsets.UTF_8).trim()

@hykilpikonna
Copy link
Collaborator Author

TODO before merging:

  1. Make a backup of the finale and chunithm old data for people still using them

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants