mirror of https://github.com/hykilpikonna/AquaDX
[O] Rewrite GetUserMusic
parent
fa1d69f1f9
commit
806e24b9f1
|
@ -10,6 +10,7 @@ import icu.samnyan.aqua.sega.chusan.model.response.data.MatchingMemberInfo
|
|||
import icu.samnyan.aqua.sega.chusan.model.response.data.MatchingWaitState
|
||||
import icu.samnyan.aqua.sega.chusan.model.response.data.UserEmoney
|
||||
import icu.samnyan.aqua.sega.chusan.model.userdata.UserCharge
|
||||
import icu.samnyan.aqua.sega.chusan.model.userdata.UserMusicDetail
|
||||
import icu.samnyan.aqua.sega.general.BaseHandler
|
||||
import icu.samnyan.aqua.sega.general.RequestContext
|
||||
import icu.samnyan.aqua.sega.general.SpecialHandler
|
||||
|
@ -33,8 +34,6 @@ import kotlin.reflect.full.declaredMemberProperties
|
|||
@API(value = ["/g/chu3/{version}/ChuniServlet", "/g/chu3/{version}"])
|
||||
class ChusanServletController(
|
||||
val gameLogin: GameLoginHandler,
|
||||
val getUserMusic: GetUserMusicHandler,
|
||||
val getUserRecentRating: GetUserRecentRatingHandler,
|
||||
val upsertUserAll: UpsertUserAllHandler,
|
||||
val cmGetUserCharacter: CMGetUserCharacterHandler,
|
||||
val cmUpsertUserGacha: CMUpsertUserGachaHandler,
|
||||
|
@ -50,10 +49,8 @@ class ChusanServletController(
|
|||
val log = LoggerFactory.getLogger(ChusanServletController::class.java)
|
||||
|
||||
// Below are code related to handling the handlers
|
||||
val externalHandlers = mutableListOf(
|
||||
"GameLoginApi", "GetUserMusicApi", "UpsertUserAllApi",
|
||||
"CMGetUserCharacterApi", "CMUpsertUserGachaApi",
|
||||
"CMUpsertUserPrintCancelApi", "CMUpsertUserPrintSubtractApi")
|
||||
val externalHandlers = mutableListOf("GameLoginApi", "UpsertUserAllApi", "CMGetUserCharacterApi",
|
||||
"CMUpsertUserGachaApi", "CMUpsertUserPrintCancelApi", "CMUpsertUserPrintSubtractApi")
|
||||
|
||||
val noopEndpoint = setOf("UpsertClientBookkeepingApi", "UpsertClientDevelopApi", "UpsertClientErrorApi",
|
||||
"UpsertClientSettingApi", "UpsertClientTestmodeApi", "CreateTokenApi", "RemoveTokenApi", "UpsertClientUploadApi",
|
||||
|
@ -263,6 +260,19 @@ fun ChusanServletController.init() {
|
|||
) + userDict
|
||||
}
|
||||
|
||||
"GetUserMusic" {
|
||||
// Compatibility: Older chusan uses boolean for isSuccess
|
||||
fun checkAncient(d: List<UserMusicDetail>) =
|
||||
data["version"]?.double?.let { if (it >= 2.15) d else d.map {
|
||||
d.toJson().jsonMap().toMutableMap().apply { this["isSuccess"] = this["isSuccess"].truthy }
|
||||
} } ?: d
|
||||
|
||||
val lst = db.userMusicDetail.findByUser_Card_ExtId(uid).groupBy { it.musicId }
|
||||
.mapValues { mapOf("length" to it.value.size, "userMusicDetailList" to checkAncient(it.value)) }
|
||||
|
||||
mapOf("userId" to uid, "length" to lst.size, "nextIndex" to -1, "userMusicList" to lst.values)
|
||||
}
|
||||
|
||||
"GetUserLoginBonus" api@ {
|
||||
if (!props.loginBonusEnable) return@api mapOf("userId" to uid, "length" to 0, "userLoginBonusList" to empty)
|
||||
|
||||
|
|
|
@ -1,84 +0,0 @@
|
|||
package icu.samnyan.aqua.sega.chusan.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@JsonPropertyOrder({
|
||||
"musicId",
|
||||
"level",
|
||||
"playCount",
|
||||
"scoreMax",
|
||||
"missCount",
|
||||
"maxComboCount",
|
||||
"isFullCombo",
|
||||
"isAllJustice",
|
||||
"isSuccess",
|
||||
"fullChain",
|
||||
"maxChain",
|
||||
"isLock",
|
||||
"theoryCount",
|
||||
"ext1"
|
||||
})
|
||||
public class UserMusicDetailForAncientChusan implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private int musicId;
|
||||
|
||||
private int level;
|
||||
|
||||
private int playCount;
|
||||
|
||||
private int scoreMax;
|
||||
|
||||
private int missCount;
|
||||
|
||||
private int maxComboCount;
|
||||
|
||||
@JsonProperty("isFullCombo")
|
||||
private boolean isFullCombo;
|
||||
|
||||
@JsonProperty("isAllJustice")
|
||||
private boolean isAllJustice;
|
||||
|
||||
@JsonProperty("isSuccess")
|
||||
private boolean isSuccess;
|
||||
|
||||
private int fullChain;
|
||||
|
||||
private int maxChain;
|
||||
|
||||
private int scoreRank;
|
||||
|
||||
@JsonProperty("isLock")
|
||||
private boolean isLock;
|
||||
|
||||
private int theoryCount;
|
||||
|
||||
private int ext1;
|
||||
|
||||
public UserMusicDetailForAncientChusan(int musicId, int level, int playCount, int scoreMax, int missCount, int maxComboCount, boolean isFullCombo, boolean isAllJustice, int isSuccess, int fullChain, int maxChain, int scoreRank, boolean isLock, int theoryCount, int ext1) {
|
||||
this.musicId = musicId;
|
||||
this.level = level;
|
||||
this.playCount = playCount;
|
||||
this.scoreMax = scoreMax;
|
||||
this.missCount = missCount;
|
||||
this.maxComboCount = maxComboCount;
|
||||
this.isFullCombo = isFullCombo;
|
||||
this.isAllJustice = isAllJustice;
|
||||
this.isSuccess = isSuccess > 0;
|
||||
this.fullChain = fullChain;
|
||||
this.maxChain = maxChain;
|
||||
this.scoreRank = scoreRank;
|
||||
this.isLock = isLock;
|
||||
this.theoryCount = theoryCount;
|
||||
this.ext1 = ext1;
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
package icu.samnyan.aqua.sega.chusan.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author samnyan (privateamusement@protonmail.com)
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class UserMusicListItemForAncientChusan {
|
||||
private int length;
|
||||
private List<UserMusicDetailForAncientChusan> userMusicDetailList;
|
||||
}
|
|
@ -1,136 +0,0 @@
|
|||
package icu.samnyan.aqua.sega.chusan.handler;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import icu.samnyan.aqua.sega.chusan.dto.UserMusicDetailForAncientChusan;
|
||||
import icu.samnyan.aqua.sega.chusan.dto.UserMusicListItemForAncientChusan;
|
||||
import icu.samnyan.aqua.sega.general.BaseHandler;
|
||||
import icu.samnyan.aqua.sega.chusan.model.response.data.UserMusicListItem;
|
||||
import icu.samnyan.aqua.sega.chusan.model.userdata.UserMusicDetail;
|
||||
import icu.samnyan.aqua.sega.chusan.service.UserMusicDetailService;
|
||||
import icu.samnyan.aqua.sega.util.jackson.StringMapper;
|
||||
import icu.samnyan.aqua.spring.data.OffsetPageRequest;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Response:
|
||||
*
|
||||
* @author samnyan (privateamusement@protonmail.com)
|
||||
*/
|
||||
@Component("ChusanGetUserMusicHandler")
|
||||
public class GetUserMusicHandler implements BaseHandler {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(GetUserMusicHandler.class);
|
||||
|
||||
private final StringMapper mapper;
|
||||
|
||||
private final UserMusicDetailService userMusicDetailService;
|
||||
|
||||
@Autowired
|
||||
public GetUserMusicHandler(StringMapper mapper, UserMusicDetailService userMusicDetailService) {
|
||||
this.mapper = mapper;
|
||||
this.userMusicDetailService = userMusicDetailService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String handle(Map<String, ?> request) throws JsonProcessingException {
|
||||
String userId = (String) request.get("userId");
|
||||
int currentIndex = Integer.parseInt((String) request.get("nextIndex"));
|
||||
int maxCount = Integer.parseInt((String) request.get("maxCount"));
|
||||
if(currentIndex < 0) {
|
||||
currentIndex = 0;
|
||||
}
|
||||
|
||||
Page<UserMusicDetail> dbPage = userMusicDetailService
|
||||
.getByUserId(userId, OffsetPageRequest.of(currentIndex, maxCount, Sort.by("musicId")));
|
||||
|
||||
|
||||
// Convert to result format
|
||||
// Result Map
|
||||
Map<Integer, UserMusicListItem> userMusicMap = new LinkedHashMap<>();
|
||||
|
||||
dbPage.getContent().forEach(userMusicDetail -> {
|
||||
UserMusicListItem list;
|
||||
if (userMusicMap.containsKey(userMusicDetail.getMusicId())) {
|
||||
list = userMusicMap.get(userMusicDetail.getMusicId());
|
||||
} else {
|
||||
list = new UserMusicListItem(0, new ArrayList<>());
|
||||
userMusicMap.put(userMusicDetail.getMusicId(), list);
|
||||
}
|
||||
list.getUserMusicDetailList().add(userMusicDetail);
|
||||
list.setLength(list.getUserMusicDetailList().size());
|
||||
});
|
||||
|
||||
// Remove the last music id if the result length is the same as maxCount,
|
||||
// to prevent a music id split across multiple page, which will cause some
|
||||
// problem with the game.
|
||||
int lastListSize = 0;
|
||||
if(dbPage.getNumberOfElements() >= maxCount) {
|
||||
// Get last key
|
||||
int lastMusicId = userMusicMap.keySet().stream().reduce((a, b) -> b).orElseThrow();
|
||||
List<UserMusicDetail> lastList = userMusicMap.get(lastMusicId).getUserMusicDetailList();
|
||||
lastListSize = lastList.size();
|
||||
// Remove last one from map
|
||||
userMusicMap.remove(lastMusicId);
|
||||
}
|
||||
|
||||
String version = (String) request.get("version");
|
||||
Map<Integer, UserMusicListItemForAncientChusan> userMusicMapForAncientChusan = new LinkedHashMap<>();
|
||||
boolean isAncient = false;
|
||||
try {
|
||||
if (Double.parseDouble(version) < 2.15){
|
||||
userMusicMap.forEach((k, v) -> {
|
||||
UserMusicListItemForAncientChusan list = new UserMusicListItemForAncientChusan();
|
||||
list.setLength(v.getLength());
|
||||
List<UserMusicDetailForAncientChusan> userMusicDetailForAncientChusanList = new ArrayList<>();
|
||||
v.getUserMusicDetailList().forEach(userMusicDetail -> {
|
||||
UserMusicDetailForAncientChusan userMusicDetailForAncientChusan = new UserMusicDetailForAncientChusan(
|
||||
userMusicDetail.getMusicId(),
|
||||
userMusicDetail.getLevel(),
|
||||
userMusicDetail.getPlayCount(),
|
||||
userMusicDetail.getScoreMax(),
|
||||
userMusicDetail.getMissCount(),
|
||||
userMusicDetail.getMaxComboCount(),
|
||||
userMusicDetail.isFullCombo(),
|
||||
userMusicDetail.isAllJustice(),
|
||||
userMusicDetail.getIsSuccess(),
|
||||
userMusicDetail.getFullChain(),
|
||||
userMusicDetail.getMaxChain(),
|
||||
userMusicDetail.getScoreRank(),
|
||||
userMusicDetail.isLock(),
|
||||
userMusicDetail.getTheoryCount(),
|
||||
userMusicDetail.getExt1()
|
||||
);
|
||||
userMusicDetailForAncientChusanList.add(userMusicDetailForAncientChusan);
|
||||
});
|
||||
list.setUserMusicDetailList(userMusicDetailForAncientChusanList);
|
||||
userMusicMapForAncientChusan.put(k, list);
|
||||
});
|
||||
isAncient = true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Error when handling ancient version of chusan", e);
|
||||
}
|
||||
|
||||
long nextIndex = currentIndex + dbPage.getNumberOfElements() - lastListSize;
|
||||
|
||||
Map<String, Object> resultMap = new LinkedHashMap<>();
|
||||
resultMap.put("userId", userId);
|
||||
resultMap.put("length", userMusicMap.size());
|
||||
resultMap.put("nextIndex", dbPage.getNumberOfElements() < maxCount ? -1 : nextIndex);
|
||||
resultMap.put("userMusicList", isAncient ? userMusicMapForAncientChusan.values() : userMusicMap.values());
|
||||
|
||||
String json = mapper.write(resultMap);
|
||||
logger.info("Response: " + json);
|
||||
return json;
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
package icu.samnyan.aqua.sega.chusan.model.response.data;
|
||||
|
||||
import icu.samnyan.aqua.sega.chusan.model.userdata.UserMusicDetail;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author samnyan (privateamusement@protonmail.com)
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class UserMusicListItem {
|
||||
private int length;
|
||||
private List<UserMusicDetail> userMusicDetailList;
|
||||
}
|
Loading…
Reference in New Issue