Merge rinsama/aqua : Ensure Chusan compatibility and add support for SunPlus

7a7076b1 - [chusan]Attempting to ensure compatibility with all known versions of Chusan, both before and after SunPlus
c8e1c5fb - fix BooleanStringIntDeserializer always returns false
50ceaf60 - Add Support for sunplus

Co-authored-by: Sanheiii <35133371+Sanheiii@users.noreply.github.com>
Co-authored-by: HoshimiRIN <admin@sakuramoe.dev>
pull/6/head
Azalea 2023-12-21 01:05:06 -05:00
commit 62e7d48f3c
10 changed files with 224 additions and 6 deletions

View File

@ -188,7 +188,7 @@ public class AllNetController {
return "http://" + addr + ":" + port + "/Maimai2Servlet/";
}
case "SDHD":
return "http://" + addr + ":" + port + "/ChusanServlet/";
return "http://" + addr + ":" + port + "/ChusanServlet/" + ver + "/";
case "SDED":
return "http://" + addr + ":" + port + "/CardMakerServlet/";
default:

View File

@ -12,7 +12,7 @@ import java.util.Map;
* @author samnyan (privateamusement@protonmail.com)
*/
@RestController
@RequestMapping({"/ChusanServlet/ChuniServlet", "/ChusanServlet"})
@RequestMapping({"/ChusanServlet/{version}/ChuniServlet", "/ChusanServlet/{version}"})
public class ChusanServletController {
private final GameLoginHandler gameLoginHandler;
@ -235,7 +235,8 @@ public class ChusanServletController {
}
@PostMapping("GetUserMusicApi")
String getUserMusic(@ModelAttribute Map<String, Object> request) throws JsonProcessingException {
String getUserMusic(@ModelAttribute Map<String, Object> request, @PathVariable String version) throws JsonProcessingException {
request.put("version", version);
return getUserMusicHandler.handle(request);
}

View File

@ -0,0 +1,84 @@
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;
}
}

View File

@ -0,0 +1,19 @@
package icu.samnyan.aqua.sega.chusan.dto;
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 UserMusicListItemForAncientChusan {
private int length;
private List<UserMusicDetailForAncientChusan> userMusicDetailList;
}

View File

@ -1,6 +1,8 @@
package icu.samnyan.aqua.sega.chusan.handler.impl;
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.chusan.handler.BaseHandler;
import icu.samnyan.aqua.sega.chusan.model.response.data.UserMusicListItem;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserMusicDetail;
@ -78,13 +80,51 @@ public class GetUserMusicHandler implements BaseHandler {
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", userMusicMap.values());
resultMap.put("userMusicList", isAncient ? userMusicMapForAncientChusan.values() : userMusicMap.values());
String json = mapper.write(resultMap);
logger.info("Response: " + json);

View File

@ -3,6 +3,8 @@ package icu.samnyan.aqua.sega.chusan.model.userdata;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import icu.samnyan.aqua.sega.chusan.util.BooleanToIntegerDeserializer;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@ -67,8 +69,9 @@ public class UserMusicDetail implements Serializable {
@JsonProperty("isAllJustice")
private boolean isAllJustice;
@JsonDeserialize(using = BooleanToIntegerDeserializer.class)
@JsonProperty("isSuccess")
private boolean isSuccess;
private int isSuccess;
private int fullChain;
@ -87,7 +90,7 @@ public class UserMusicDetail implements Serializable {
user = userData;
}
public UserMusicDetail(int musicId, int level, int playCount, int scoreMax, int missCount, int maxComboCount, boolean isFullCombo, boolean isAllJustice, boolean isSuccess, int fullChain, int maxChain, int scoreRank, boolean isLock, int theoryCount, int ext1) {
public UserMusicDetail(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;

View File

@ -0,0 +1,35 @@
package icu.samnyan.aqua.sega.chusan.util;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
import java.util.Locale;
public class BooleanToIntegerDeserializer extends JsonDeserializer<Integer> {
@Override
public Integer deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
return switch (p.getCurrentToken()) {
case VALUE_STRING -> {
String value = p.getValueAsString();
if (value.toLowerCase(Locale.ROOT).equals("true")) {
yield 1;
} else if (value.toLowerCase(Locale.ROOT).equals("false")) {
yield 0;
} else {
try {
yield Integer.parseInt(value);
} catch (NumberFormatException e) {
throw new UnsupportedOperationException("Cannot deserialize to integer field");
}
}
}
case VALUE_NUMBER_INT -> p.getIntValue();
case VALUE_TRUE -> 1;
case VALUE_FALSE -> 0;
default -> throw new UnsupportedOperationException("Cannot deserialize to integer field");
};
}
}

View File

@ -0,0 +1,2 @@
ALTER TABLE chusan_user_music_detail
MODIFY is_success INTEGER NOT NULL;

View File

@ -0,0 +1,2 @@
ALTER TABLE chusan_user_music_detail
MODIFY is_success INTEGER NOT NULL;

View File

@ -0,0 +1,32 @@
-- Step 1: Create a new table with the desired changes
CREATE TABLE temp_chusan_user_music_detail (
id INTEGER,
full_chain INTEGER NOT NULL,
is_all_justice BOOLEAN NOT NULL,
is_full_combo BOOLEAN NOT NULL,
is_lock BOOLEAN NOT NULL,
is_success INTEGER NOT NULL, -- Changed to INTEGER
level INTEGER NOT NULL,
max_chain INTEGER NOT NULL,
max_combo_count INTEGER NOT NULL,
miss_count INTEGER NOT NULL,
music_id INTEGER NOT NULL,
play_count INTEGER NOT NULL,
theory_count INTEGER,
ext1 INTEGER,
score_max INTEGER NOT NULL,
score_rank INTEGER NOT NULL,
user_id BIGINT REFERENCES chusan_user_data (id) ON DELETE CASCADE,
PRIMARY KEY (id),
CONSTRAINT chusan_user_music_detail_uq UNIQUE (level, music_id, user_id)
);
-- Step 2: Copy the data from the original table to the new table
INSERT INTO temp_chusan_user_music_detail
SELECT * FROM chusan_user_music_detail;
-- Step 3: Delete the original table
DROP TABLE chusan_user_music_detail;
-- Step 4: Rename the new table to the original table's name
ALTER TABLE temp_chusan_user_music_detail RENAME TO chusan_user_music_detail;