diff --git a/.gitignore b/.gitignore index 286a8cf6..9580e866 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +web/ + HELP.md target/ !.mvn/wrapper/maven-wrapper.jar diff --git a/config/application.properties b/config/application.properties index fb55e715..b66623ec 100644 --- a/config/application.properties +++ b/config/application.properties @@ -54,6 +54,10 @@ game.maimai2.splash-old-patch=false game.maimai2.userPhoto.enable=true ## Specify folder path that user portrait photo and its (.json) data save to. game.maimai2.userPhoto.picSavePath=data/userPhoto +## When uploading user portraits, limit the divMaxLength parameter. 1 divLength is about equal to the file size of 10kb. +## The default value is 32 (320kb), and the minimum value is 1 (10kb) +game.maimai2.userPhoto.divMaxLength=32 + ## Logging spring.servlet.multipart.max-file-size=10MB diff --git a/src/main/java/icu/samnyan/aqua/api/controller/sega/game/maimai2/ApiMaimai2PlayerDataController.java b/src/main/java/icu/samnyan/aqua/api/controller/sega/game/maimai2/ApiMaimai2PlayerDataController.java index 9904b5d3..66dfc5d3 100644 --- a/src/main/java/icu/samnyan/aqua/api/controller/sega/game/maimai2/ApiMaimai2PlayerDataController.java +++ b/src/main/java/icu/samnyan/aqua/api/controller/sega/game/maimai2/ApiMaimai2PlayerDataController.java @@ -12,6 +12,7 @@ import icu.samnyan.aqua.sega.general.model.Card; import icu.samnyan.aqua.sega.general.service.CardService; import icu.samnyan.aqua.sega.maimai2.dao.userdata.*; import icu.samnyan.aqua.sega.maimai2.model.userdata.*; +import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; @@ -83,6 +84,11 @@ public class ApiMaimai2PlayerDataController { this.userUdemaeRepository = userUdemaeRepository; } + @GetMapping("config/userPhoto/divMaxLength") + public long getConfigUserPhotoDivMaxLength(@Value("${game.maimai2.userPhoto.divMaxLength:32}") long divMaxLength) { + return divMaxLength; + } + @GetMapping("profile") public ProfileResp getProfile(@RequestParam long aimeId) { return mapper.convert(userDataRepository.findByCard_ExtId(aimeId).orElseThrow(), new TypeReference<>() { diff --git a/src/main/java/icu/samnyan/aqua/sega/maimai2/controller/Maimai2ServletController.java b/src/main/java/icu/samnyan/aqua/sega/maimai2/controller/Maimai2ServletController.java index 1d62afef..c7c9a5a3 100644 --- a/src/main/java/icu/samnyan/aqua/sega/maimai2/controller/Maimai2ServletController.java +++ b/src/main/java/icu/samnyan/aqua/sega/maimai2/controller/Maimai2ServletController.java @@ -3,10 +3,7 @@ package icu.samnyan.aqua.sega.maimai2.controller; import com.fasterxml.jackson.core.JsonProcessingException; import icu.samnyan.aqua.sega.maimai2.handler.impl.*; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import java.util.Map; @@ -14,7 +11,7 @@ import java.util.Map; * @author samnyan (privateamusement@protonmail.com) */ @RestController -@RequestMapping({"/Maimai2Servlet/Maimai2Servlet", "/Maimai2Servlet"}) // Workaround for endpoint mismatch, let's just accept both +@RequestMapping({"/Maimai2Servlet/Maimai2Servlet", "/Maimai2Servlet"}) public class Maimai2ServletController { private final GetGameSettingHandler getGameSettingHandler; @@ -229,6 +226,7 @@ public class Maimai2ServletController { return uploadUserPlaylogHandler.handle(request); } + @CrossOrigin//enable cors because aqua-viewer also use it. @PostMapping("UploadUserPortraitApi") public String uploadUserPortraitHandler(@ModelAttribute Map request) throws JsonProcessingException { return uploadUserPortraitHandler.handle(request); diff --git a/src/main/java/icu/samnyan/aqua/sega/maimai2/handler/impl/UploadUserPortraitHandler.java b/src/main/java/icu/samnyan/aqua/sega/maimai2/handler/impl/UploadUserPortraitHandler.java index 9b0074e4..fafd8f3c 100644 --- a/src/main/java/icu/samnyan/aqua/sega/maimai2/handler/impl/UploadUserPortraitHandler.java +++ b/src/main/java/icu/samnyan/aqua/sega/maimai2/handler/impl/UploadUserPortraitHandler.java @@ -27,13 +27,16 @@ public class UploadUserPortraitHandler implements BaseHandler { private final String picSavePath; private final boolean enable; + private final long divMaxLength; public UploadUserPortraitHandler(BasicMapper mapper, - @Value("${game.maimai2.userPhoto.enable:true}") boolean enable, - @Value("${game.maimai2.userPhoto.picSavePath:data/userPhoto}") String picSavePath) { + @Value("${game.maimai2.userPhoto.enable:true}") boolean enable, + @Value("${game.maimai2.userPhoto.picSavePath:data/userPhoto}") String picSavePath, + @Value("${game.maimai2.userPhoto.divMaxLength:32}") long divMaxLength) { this.mapper = mapper; this.picSavePath = picSavePath; this.enable = enable; + this.divMaxLength = divMaxLength; if (enable) { try { @@ -60,6 +63,11 @@ public class UploadUserPortraitHandler implements BaseHandler { int divLength = userPhoto.getDivLength(); String divData = userPhoto.getDivData(); + if (divLength > divMaxLength) { + logger.warn(String.format("stop user %d uploading photo data because divLength(%d) > divMaxLength(%d)", userId, divLength, divMaxLength)); + return "{\"returnCode\":-1,\"apiName\":\"com.sega.maimai2servlet.api.UploadUserPortraitApi\"}"; + } + try { var tmp_filename = Paths.get(picSavePath, userId + "-up.tmp"); if (divNumber == 0)