diff --git a/README.md b/README.md index 053d8a24..a099a9ee 100644 --- a/README.md +++ b/README.md @@ -32,15 +32,15 @@ Multipurpose game server for ALL.Net games. > [!WARNING] > CHUNITHM pre-NEW!! and maimai pre-DX are no longer supported after February 6th, 2026 and all associated data will be removed. -| Game | Latest Ver. | Initial Ver. | Notes | -|------------------------|---------------------|---------------------|-------------------------------------------------------------| -| SDHD: CHUNITHM | 2.45 (X-VERSE-X) | 2.00 (NEW) | | -| SDEZ: maimai DX | 1.65 (CiRCLE PLUS) | 1.00 (DX) | Missing circle (teams) support | -| SDGA: maimai DX (Intl) | 1.60 (CiRCLE) | 1.00 (DX) | Thanks [@Clansty](https://github.com/clansty) | -| SDED: Card Maker | 1.39 | N/A | Thanks [@Becods](https://github.com/Becods) | -| SDDT: O.N.G.E.K.I. | 1.50 (Re:Fresh) | N/A | Thanks [@PenguinCaptain](https://github.com/PenguinCaptain) | -| SBZV: Project DIVA | 7.10 | N/A | No web interface provided | -| SDFE: Wacca | 3.07 (Reverse) | N/A | Later versions are EOS patches, network will not work | +| Game | Latest Ver. | Initial Ver. | Notes | Web UI | Data Import | +|------------------------|---------------------|---------------------|-------------------------------------------------------------|--------|-------------| +| SDHD: CHUNITHM | 2.45 (X-VERSE-X) | 2.00 (NEW) | | ✅ | ❗ | +| SDEZ: maimai DX | 1.65 (CiRCLE PLUS) | 1.00 (DX) | Missing circle (teams) support | ✅ | ✅ | +| SDGA: maimai DX (Intl) | 1.60 (CiRCLE) | 1.00 (DX) | Thanks [@Clansty](https://github.com/clansty) | ✅ | ✅ | +| SDED: Card Maker | 1.39 | N/A | Thanks [@Becods](https://github.com/Becods) | ❌ | ❌ | +| SDDT: O.N.G.E.K.I. | 1.50 (Re:Fresh) | N/A | Thanks [@PenguinCaptain](https://github.com/PenguinCaptain) | ✅ | ❌ | +| SBZV: Project DIVA | 7.10 | N/A | Minimal support | ❌ | ❌ | +| SDFE: Wacca | 3.07 (Reverse) | N/A | Later versions are EOS patches, network will not work | ✅ | ❌ | diff --git a/config/devtainer/Dockerfile b/config/devtainer/Dockerfile index 7458b109..2e9ae629 100644 --- a/config/devtainer/Dockerfile +++ b/config/devtainer/Dockerfile @@ -1,7 +1,7 @@ FROM archlinux:latest RUN pacman -Syu --noconfirm \ - && pacman -S --noconfirm openssh sudo jdk21-openjdk wget which procps-ng zsh git curlie micro ripgrep python3 exa \ + && pacman -S --noconfirm openssh sudo jdk21-openjdk wget which procps-ng zsh git curlie micro ripgrep python3 exa diffutils \ && rm -rf /var/cache/pacman/pkg/* \ && mkdir -p /var/run/sshd \ && chsh -s /bin/zsh root \ diff --git a/docs/dev/testing.md b/docs/dev/testing.md new file mode 100644 index 00000000..6c12e7c9 --- /dev/null +++ b/docs/dev/testing.md @@ -0,0 +1,5 @@ + + +``` +gradle test -PrunTests --tests Mai2Test +``` \ No newline at end of file diff --git a/planet/src/main/kotlin/aquadx/sega/chusan/handler/ChusanApis.kt b/planet/src/main/kotlin/aquadx/sega/chusan/handler/ChusanApis.kt index ea4c9f10..76746e44 100644 --- a/planet/src/main/kotlin/aquadx/sega/chusan/handler/ChusanApis.kt +++ b/planet/src/main/kotlin/aquadx/sega/chusan/handler/ChusanApis.kt @@ -377,7 +377,7 @@ fun ChusanController.chusanInit() { } // Static - "GetGameEvent" static { db.gameEvent.findByEnable(true).let { mapOf("type" to 1, "length" to it.size, "gameEventList" to it) } } + "GetGameEvent" static { db.gameEvent.findAll().let { mapOf("type" to 1, "length" to it.size, "gameEventList" to it) } } "GetGameCharge" static { db.gameCharge.findAll().let { mapOf("length" to it.size, "gameChargeList" to it) } } "GetGameGacha" static { db.gameGacha.findAll().let { mapOf("length" to it.size, "gameGachaList" to it, "registIdList" to empty) } } "GetGameMapAreaCondition" static { ChusanData.mapAreaCondition } diff --git a/planet/src/main/kotlin/aquadx/sega/maimai2/Maimai2Apis.kt b/planet/src/main/kotlin/aquadx/sega/maimai2/Maimai2Apis.kt index 1597c002..be058888 100644 --- a/planet/src/main/kotlin/aquadx/sega/maimai2/Maimai2Apis.kt +++ b/planet/src/main/kotlin/aquadx/sega/maimai2/Maimai2Apis.kt @@ -53,7 +53,7 @@ fun Maimai2ServletController.initApis() { } // Maimai only request for event type 1 - "GetGameEvent" static { mapOf("type" to 1, "gameEventList" to db.gameEvent.findByEnable(true)) } + "GetGameEvent" static { mapOf("type" to 1, "gameEventList" to db.gameEvent.findAll()) } "GetGameCharge" static { db.gameCharge.findAll().let { mapOf("length" to it.size, "gameChargeList" to it) } } "GetUserOption" { mapOf( diff --git a/planet/src/main/kotlin/aquadx/sega/ongeki/OngekiRepos.kt b/planet/src/main/kotlin/aquadx/sega/ongeki/OngekiRepos.kt index 5fbc0293..94f441ca 100644 --- a/planet/src/main/kotlin/aquadx/sega/ongeki/OngekiRepos.kt +++ b/planet/src/main/kotlin/aquadx/sega/ongeki/OngekiRepos.kt @@ -45,6 +45,7 @@ import org.springframework.data.domain.Pageable import org.springframework.data.jpa.repository.Query import org.springframework.data.repository.NoRepositoryBean import org.springframework.stereotype.Component + import java.util.* diff --git a/planet/src/test/kotlin/test/Mai2Test.kt b/planet/src/test/kotlin/test/Mai2Test.kt index 59bb654b..d80d7bdd 100644 --- a/planet/src/test/kotlin/test/Mai2Test.kt +++ b/planet/src/test/kotlin/test/Mai2Test.kt @@ -13,7 +13,7 @@ class Mai2Test : StringSpec({ var userId = 0L suspend fun post(url: String, body: String): Pair> { - val resp = HTTP.post("$HOST/gs/$CLIENT_ID/mai2/$url") { + val resp = HTTP.post("$HOST/g/mai2/$url") { contentType(ContentType.Application.Json) setBody(body) } @@ -31,20 +31,23 @@ class Mai2Test : StringSpec({ "GetGameSettingApi" { println("UserID: $userId") post("GetGameSettingApi", """{"placeId":291,"clientId":"$CLIENT_ID"}""").let { (_, result) -> - result shouldBe """{"gameSetting":{"requestInterval":10,"rebootStartTime":"2099-01-01 23:59:00.0","rebootEndTime":"2099-01-01 23:59:00.0","movieUploadLimit":10000,"movieStatus":0,"movieServerUri":"","deliverServerUri":"","oldServerUri":"","usbDlServerUri":"","rebootInterval":0,"isMaintenance":false},"isAouAccession":true}""".jsonMap() + val gs = result["gameSetting"] as Map<*, *> + gs["requestInterval"] shouldBe 10 + result["isAouAccession"] shouldBe true } } "GetGameRankingApi" { post("GetGameRankingApi", """{"type":1}""").let { (_, result) -> - result shouldBe """{"type":"1","gameRankingList":[]}""".jsonMap() + result["type"] shouldBe 1 + assert(result["gameRankingList"] is List<*>) } } "GetGameEventApi" { post("GetGameEventApi", """{"type":1,"isAllEvent":true}""").let { (_, result) -> result.keys shouldBe setOf("type", "gameEventList") - ((result["gameEventList"] as List<*>).first() as Map<*, *>).keys shouldBe setOf("id", "type", "startDate", "endDate") + ((result["gameEventList"] as List<*>).first() as Map<*, *>).keys shouldBe setOf("id", "type", "startDate", "endDate", "enable", "disableArea") } } @@ -56,13 +59,13 @@ class Mai2Test : StringSpec({ "GetGameChargeApi" { post("GetGameChargeApi", """{"isAll":false}""").let { (_, result) -> - result shouldBe """{"length":5,"gameChargeList":[{"orderId":1,"chargeId":2,"price":1,"startDate":"2019-01-01 00:00:00.000000","endDate":"2099-01-01 00:00:00.000000"},{"orderId":2,"chargeId":3,"price":2,"startDate":"2019-01-01 00:00:00.000000","endDate":"2099-01-01 00:00:00.000000"},{"orderId":3,"chargeId":4,"price":3,"startDate":"2019-01-01 00:00:00.000000","endDate":"2099-01-01 00:00:00.000000"},{"orderId":4,"chargeId":5,"price":4,"startDate":"2019-01-01 00:00:00.000000","endDate":"2099-01-01 00:00:00.000000"},{"orderId":5,"chargeId":6,"price":5,"startDate":"2019-01-01 00:00:00.000000","endDate":"2099-01-01 00:00:00.000000"}]}""".jsonMap() + result shouldBe """{"length":5,"gameChargeList":[{"chargeId":0,"orderId":0,"price":1,"startDate":"2019-01-01 00:00:00.000000","endDate":"2099-01-01 00:00:00.000000"},{"chargeId":0,"orderId":0,"price":2,"startDate":"2019-01-01 00:00:00.000000","endDate":"2099-01-01 00:00:00.000000"},{"chargeId":0,"orderId":0,"price":3,"startDate":"2019-01-01 00:00:00.000000","endDate":"2099-01-01 00:00:00.000000"},{"chargeId":0,"orderId":0,"price":4,"startDate":"2019-01-01 00:00:00.000000","endDate":"2099-01-01 00:00:00.000000"},{"chargeId":0,"orderId":0,"price":5,"startDate":"2019-01-01 00:00:00.000000","endDate":"2099-01-01 00:00:00.000000"}]}""".jsonMap() } } "GetGameNgMusicIdApi" { post("GetGameNgMusicIdApi", """{}""").let { (_, result) -> - result shouldBe """{"length":0,"musicIdList":[]}""".jsonMap() + result shouldBe """{"length":0,"musicIdList":[],"ngMusicDataList":[]}""".jsonMap() } } @@ -115,13 +118,16 @@ class Mai2Test : StringSpec({ "GetUserDataApi" { post("GetUserDataApi", """{"userId":$userId}""").let { (_, result) -> - result shouldBe """{"userId":$userId,"userData":{"userName":"AZA☆","friendCode":"","isNetMember":1,"nameplateId":0,"iconId":11,"trophyId":0,"plateId":1,"titleId":11,"partnerId":1,"frameId":1,"selectMapId":400001,"totalAwake":0,"gradeRating":0,"musicRating":271,"playerRating":271,"highestRating":271,"gradeRank":0,"classRank":0,"courseRank":0,"charaSlot":[101,400101,105,104,103],"charaLockSlot":[0,0,0,0,0],"contentBit":2169888,"playCount":1,"eventWatchedDate":"2024-03-27 05:45:15.0","lastGameId":"SDEZ","lastRomVersion":"1.41.00","lastDataVersion":"1.40.08","lastLoginDate":"2024-03-27 05:45:15.0","lastPlayDate":"2024-03-27 05:56:54.0","lastPlayCredit":1,"lastPlayMode":0,"lastPlaceId":291,"lastPlaceName":"","lastAllNetId":0,"lastRegionId":1,"lastRegionName":"W","lastClientId":"$CLIENT_ID","lastCountryCode":"JPN","lastSelectEMoney":0,"lastSelectTicket":0,"lastSelectCourse":0,"lastCountCourse":0,"firstGameId":"SDEZ","firstRomVersion":"1.41.00","firstDataVersion":"1.40.08","firstPlayDate":"2024-03-27 05:45:15.0","compatibleCmVersion":"1.40.00","dailyBonusDate":"1970-01-01 09:00:00.0","dailyCourseBonusDate":"1970-01-01 09:00:00.0","lastPairLoginDate":"1970-01-01 09:00:00.0","lastTrialPlayDate":"1970-01-01 09:00:00.0","playVsCount":0,"playSyncCount":0,"winCount":0,"helpCount":0,"comboCount":0,"totalDeluxscore":1725,"totalBasicDeluxscore":0,"totalAdvancedDeluxscore":0,"totalExpertDeluxscore":1725,"totalMasterDeluxscore":0,"totalReMasterDeluxscore":0,"totalHiscore":0,"totalBasicHighscore":0,"totalAdvancedHighscore":0,"totalExpertHighscore":0,"totalMasterHighscore":0,"totalReMasterHighscore":0,"totalSync":0,"totalBasicSync":0,"totalAdvancedSync":0,"totalExpertSync":0,"totalMasterSync":0,"totalReMasterSync":0,"totalAchievement":997456,"totalBasicAchievement":0,"totalAdvancedAchievement":0,"totalExpertAchievement":997456,"totalMasterAchievement":0,"totalReMasterAchievement":0,"playerOldRating":271,"playerNewRating":0,"banState":0,"dateTime":1711485182,"cmLastEmoneyBrand":2,"cmLastEmoneyCredit":69,"mapStock":0,"currentPlayCount":1,"renameCredit":0,"accessCode":"$ACCESS_CODE"},"banState":0}""".jsonMap() + val userData = result["userData"] as Map<*, *> + userData["userName"] shouldBe "AZA☆" + userData["playerRating"] shouldBe 271 + result["banState"] shouldBe 0 } } "GetUserCardApi" { post("GetUserCardApi", """{"userId":$userId,"nextIndex":0,"maxCount":20}""").let { (_, result) -> - result shouldBe """{"userId":$userId,"nextIndex":0,"userCardList":[]}""".jsonMap() + result shouldBe """{"userId":$userId,"nextIndex":0,"length":0,"userCardList":[]}""".jsonMap() } } @@ -191,63 +197,63 @@ class Mai2Test : StringSpec({ "GetUserCourseApi" { post("GetUserCourseApi", """{"userId":$userId,"nextIndex":0}""").let { (_, result) -> - result shouldBe """{"userId":$userId,"nextIndex":0,"userCourseList":[]}""".jsonMap() + result shouldBe """{"userId":$userId,"nextIndex":0,"length":0,"userCourseList":[]}""".jsonMap() } } "GetUserChargeApi" { post("GetUserChargeApi", """{"userId":$userId}""").let { (_, result) -> - result shouldBe """{"userId":$userId,"length":0,"userChargeList":[]}""".jsonMap() + result shouldBe """{"userId":$userId,"nextIndex":0,"length":0,"userChargeList":[]}""".jsonMap() } } "GetUserFavoriteApi" { post("GetUserFavoriteApi", """{"userId":$userId,"itemKind":1}""").let { (_, result) -> - result shouldBe """{"userId":$userId,"userFavoriteData":[]}""".jsonMap() + result shouldBe """{"userId":$userId}""".jsonMap() } post("GetUserFavoriteApi", """{"userId":$userId,"itemKind":2}""").let { (_, result) -> - result shouldBe """{"userId":$userId,"userFavoriteData":[]}""".jsonMap() + result shouldBe """{"userId":$userId}""".jsonMap() } post("GetUserFavoriteApi", """{"userId":$userId,"itemKind":3}""").let { (_, result) -> - result shouldBe """{"userId":$userId,"userFavoriteData":[]}""".jsonMap() + result shouldBe """{"userId":$userId}""".jsonMap() } post("GetUserFavoriteApi", """{"userId":$userId,"itemKind":4}""").let { (_, result) -> - result shouldBe """{"userId":$userId,"userFavoriteData":[]}""".jsonMap() + result shouldBe """{"userId":$userId}""".jsonMap() } post("GetUserFavoriteApi", """{"userId":$userId,"itemKind":5}""").let { (_, result) -> - result shouldBe """{"userId":$userId,"userFavoriteData":[]}""".jsonMap() + result shouldBe """{"userId":$userId}""".jsonMap() } } "GetUserGhostApi" { post("GetUserGhostApi", """{"userId":$userId}""").let { (_, result) -> - result shouldBe """{"userId":$userId,"userGhostList":[]}""".jsonMap() + result shouldBe """{"userId":$userId,"nextIndex":0,"length":0,"userGhostList":[]}""".jsonMap() } } "GetUserMapApi" { post("GetUserMapApi", """{"userId":$userId,"nextIndex":0,"maxCount":20}""").let { (_, result) -> - result shouldBe """{"userId":$userId,"nextIndex":0,"userMapList":[{"mapId":1,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":2,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":3,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":4,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":5,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":6,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":150001,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":150002,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":150003,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":150004,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":150005,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":350001,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":350003,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":350004,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":350006,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":350007,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":400001,"distance":14000,"isLock":false,"isClear":false,"isComplete":false},{"mapId":400002,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":400003,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":400004,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":400005,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":400006,"distance":0,"isLock":false,"isClear":false,"isComplete":false}]}""".jsonMap() + result shouldBe """{"userId":$userId,"nextIndex":0,"length":22,"userMapList":[{"mapId":1,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":2,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":3,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":4,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":5,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":6,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":150001,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":150002,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":150003,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":150004,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":150005,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":350001,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":350003,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":350004,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":350006,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":350007,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":400001,"distance":14000,"isLock":false,"isClear":false,"isComplete":false},{"mapId":400002,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":400003,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":400004,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":400005,"distance":0,"isLock":false,"isClear":false,"isComplete":false},{"mapId":400006,"distance":0,"isLock":false,"isClear":false,"isComplete":false}]}""".jsonMap() } } "GetUserLoginBonusApi" { post("GetUserLoginBonusApi", """{"userId":$userId,"nextIndex":0,"maxCount":20}""").let { (_, result) -> - result shouldBe """{"userId":$userId,"nextIndex":0,"userLoginBonusList":[{"bonusId":38,"point":1,"isCurrent":true,"isComplete":false}]}""".jsonMap() + result shouldBe """{"userId":$userId,"nextIndex":0,"length":1,"userLoginBonusList":[{"bonusId":38,"point":1,"isCurrent":false,"isComplete":false}]}""".jsonMap() } } "GetUserRegionApi" { post("GetUserRegionApi", """{"userId":$userId}""").let { (_, result) -> - result shouldBe """{"userId":$userId,"length":0,"userRegionList":[]}""".jsonMap() + result shouldBe """{"userId":$userId,"length":1,"userRegionList":[{"regionId":1,"playCount":1}]}""".jsonMap() } } @@ -283,7 +289,7 @@ class Mai2Test : StringSpec({ "GetUserMusicApi" { post("GetUserMusicApi", """{"userId":$userId,"nextIndex":0,"maxCount":50}""").let { (_, result) -> - result shouldBe """{"userId":$userId,"nextIndex":0,"userMusicList":[{"userMusicDetailList":[{"musicId":11479,"level":2,"playCount":1,"achievement":997456,"comboStatus":1,"syncStatus":0,"deluxscoreMax":1725,"scoreRank":11,"extNum1":0}]}]}""".jsonMap() + result shouldBe """{"userId":$userId,"nextIndex":0,"length":1,"userMusicList":[{"userMusicDetailList":[{"musicId":11479,"level":2,"playCount":1,"achievement":997456,"comboStatus":1,"syncStatus":0,"deluxscoreMax":1725,"scoreRank":11,"extNum1":0}]}]}""".jsonMap() } } @@ -310,7 +316,7 @@ class Mai2Test : StringSpec({ "GetUserFriendSeasonRankingApi" { post("GetUserFriendSeasonRankingApi", """{"userId":$userId,"nextIndex":0,"maxCount":20}""").let { (_, result) -> - result shouldBe """{"userId":$userId,"nextIndex":0,"userFriendSeasonRankingList":[]}""".jsonMap() + result shouldBe """{"userId":$userId,"nextIndex":0,"length":0,"userFriendSeasonRankingList":[]}""".jsonMap() } } diff --git a/planet/src/test/kotlin/test/WaccaTest.kt b/planet/src/test/kotlin/test/WaccaTest.kt index 21c7eb58..6eb95113 100644 --- a/planet/src/test/kotlin/test/WaccaTest.kt +++ b/planet/src/test/kotlin/test/WaccaTest.kt @@ -17,7 +17,7 @@ class WaccaTest : StringSpec({ data class PostResp(val resp: HttpResponse, val res: List) suspend fun post(url: String, par: String): PostResp { requestNo++ - val resp = HTTP.post("$HOST/gs/$CLIENT_ID/wacca/api/$url") { + val resp = HTTP.post("$HOST/g/wacca/api/$url") { contentType(ContentType.Application.Json) setBody("""{"requestNo": ${requestNo++},"appVersion": "$version","boardId": "$BOARD_ID","chipId": "$FULL_CLIENT_ID","params": $par}""") } diff --git a/src/main/java/icu/samnyan/aqua/sega/chusan/ChusanController.kt b/src/main/java/icu/samnyan/aqua/sega/chusan/ChusanController.kt deleted file mode 100644 index a9cb4b9c..00000000 --- a/src/main/java/icu/samnyan/aqua/sega/chusan/ChusanController.kt +++ /dev/null @@ -1,92 +0,0 @@ -package aquadx.sega.chusan - -import ext.* -import aquadx.net.db.AquaUserServices -import aquadx.net.games.chu3.Chusan -import aquadx.net.utils.simpleDescribe -import aquadx.sega.allnet.TokenChecker -import aquadx.sega.chusan.handler.chusanInit -import aquadx.sega.chusan.model.Chu3Repos -import aquadx.sega.general.GameMusicPopularity -import aquadx.sega.general.MeowApi -import aquadx.sega.general.RequestContext -import aquadx.sega.general.service.CardService -import aquadx.sega.util.BasicMapper -import aquadx.sega.util.StringMapper -import aquadx.spring.Metrics -import jakarta.servlet.http.HttpServletRequest -import org.slf4j.LoggerFactory -import org.springframework.web.bind.annotation.RestController - -/** - * @author samnyan (privateamusement@protonmail.com) - */ -@Suppress("unused") -@RestController -@API(value = ["/g/chu3/{version}/ChuniServlet", "/g/chu3/{version}"]) -class ChusanController( - val mapper: StringMapper, - val cmMapper: BasicMapper, - val db: Chu3Repos, - val us: AquaUserServices, - val cardService: CardService, - val versionHelper: ChusanVersionHelper, - val props: ChusanProps, - val pop: GameMusicPopularity, - val chusan: Chusan -): MeowApi({ api, resp -> - if (resp is String) resp - else (if ("CM" in api || api == "GetUserItemApi" ) cmMapper else mapper).write(resp) -}) { - val log = LoggerFactory.getLogger(ChusanController::class.java) - - val noopEndpoint = setOf("UpsertClientBookkeepingApi", "UpsertClientDevelopApi", "UpsertClientErrorApi", - "UpsertClientSettingApi", "UpsertClientTestmodeApi", "CreateTokenApi", "RemoveTokenApi", "UpsertClientUploadApi", - "PrinterLoginApi", "PrinterLogoutApi", "Ping", "GameLogoutApi", "RemoveMatchingMemberApi", - "UpsertClientPlayTimeApi", "UpsertClientGameStartApi", "UpsertClientGameEndApi") - - init { chusanInit() } - val handlers = initH - - @API("/{endpoint}", "/MatchingServer/{endpoint}") - fun handle(@PV endpoint: Str, @RB data: MutableMap, @PV version: Str, req: HttpServletRequest): Any { - val ctx = RequestContext(req, data) - var api = endpoint - data["version"] = version - - // Export version - if (api.endsWith("C3Exp")) { - api = api.removeSuffix("C3Exp") - data["c3exp"] = true - } - - if (api.startsWith("CM") && api !in handlers) api = api.removePrefix("CM") - val token = TokenChecker.tokenShort() - log.info("$token : $api < ${data.toJson()}") - - val noop = """{"returnCode":"1","apiName":"$api"}""" - if (api !in noopEndpoint && !handlers.containsKey(api)) { - log.warn("$token : $api > not found") - return noop - } - - // Only record the counter metrics if the API is known. - Metrics.counter("aquadx_chusan_api_call", "api" to api).increment() - if (api in noopEndpoint) { - log.info("$token : $api > no-op") - return noop - } - - return try { - Metrics.timer("aquadx_chusan_api_latency", "api" to api).recordCallable { - serialize(api, handlers[api]!!(ctx) ?: noop).also { - if (api !in setOf("GetUserItemApi", "GetGameEventApi")) - log.info("$token : $api > ${it.truncate(500)}") - } - } - } catch (e: Exception) { - Metrics.counter("aquadx_chusan_api_error", "api" to api, "error" to e.simpleDescribe()).increment() - throw e - } - } -}