[+] Minimum working support for Ongeki Re:Fresh

pull/133/head
PenguinCaptain 2025-03-26 21:18:17 +08:00
parent f463aea3ef
commit d690b81681
No known key found for this signature in database
11 changed files with 194 additions and 20 deletions

View File

@ -4,7 +4,6 @@ package icu.samnyan.aqua.sega.ongeki.controller;
import com.fasterxml.jackson.core.JsonProcessingException;
import icu.samnyan.aqua.sega.ongeki.handler.impl.*;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@ -66,6 +65,7 @@ public class OngekiController {
private final GetClientBookkeepingHandler getClientBookkeepingHandler;
private final GetClientTestmodeHandler getClientTestmodeHandler;
private final GetGameMusicReleaseStateHandler getGameMusicReleaseStateHandler;
private final GetUserSkinHandler getUserSkinHandler;
@PostMapping("ExtendLockTimeApi")
public String extendLockTime(@ModelAttribute Map<String, Object> request) {
@ -277,6 +277,11 @@ public class OngekiController {
return getUserScenarioHandler.handle(request);
}
@PostMapping("GetUserSkinApi")
public String getUserSkin(@ModelAttribute Map<String, Object> request) throws JsonProcessingException {
return getUserSkinHandler.handle(request);
}
@PostMapping("GetUserStoryApi")
public String getUserStory(@ModelAttribute Map<String, Object> request) throws JsonProcessingException {
return getUserStoryHandler.handle(request);

View File

@ -66,6 +66,7 @@ public class GetUserPreviewHandler implements BaseHandler {
resp.setLevel(user.getLevel());
resp.setExp(user.getExp());
resp.setPlayerRating(user.getPlayerRating());
resp.setNewPlayerRating(user.getNewPlayerRating());
resp.setLastGameId(user.getLastGameId());

View File

@ -0,0 +1,65 @@
package icu.samnyan.aqua.sega.ongeki.handler.impl;
import com.fasterxml.jackson.core.JsonProcessingException;
import icu.samnyan.aqua.sega.general.BaseHandler;
import icu.samnyan.aqua.sega.ongeki.dao.userdata.UserDeckRepository;
import icu.samnyan.aqua.sega.ongeki.model.userdata.UserDeck;
import icu.samnyan.aqua.sega.util.jackson.BasicMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author samnyan (privateamusement@protonmail.com)
*/
@Component("OngekiGetUserSkinHandler")
public class GetUserSkinHandler implements BaseHandler {
private static final Logger logger = LoggerFactory.getLogger(GetUserSkinHandler.class);
private final BasicMapper mapper;
private final UserDeckRepository userDeckRepository;
@Autowired
public GetUserSkinHandler(BasicMapper mapper, UserDeckRepository userDeckRepository) {
this.mapper = mapper;
this.userDeckRepository = userDeckRepository;
}
@Override
public String handle(Map<String, ?> request) throws JsonProcessingException {
long userId = ((Number) request.get("userId")).longValue();
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("userId", userId);
// Get the list of user decks
List<UserDeck> deckList = userDeckRepository.findByUser_Card_ExtId(userId);
// Convert each UserDeck to UserSkin
List<Map<String, Object>> userSkinList = deckList.stream().map(deck -> {
Map<String, Object> skinMap = new LinkedHashMap<>();
skinMap.put("deckId", deck.getDeckId());
skinMap.put("isValid", false);
skinMap.put("cardId1", deck.getCardId1());
skinMap.put("cardId2", deck.getCardId2());
skinMap.put("cardId3", deck.getCardId3());
return skinMap;
}).collect(Collectors.toList());
resultMap.put("length", userSkinList.size());
resultMap.put("userSkinList", userSkinList);
String json = mapper.write(resultMap);
logger.info("Response: " + json);
return json;
}
}

View File

@ -1,11 +1,12 @@
package icu.samnyan.aqua.sega.ongeki.handler.impl;
import com.fasterxml.jackson.core.JsonProcessingException;
import icu.samnyan.aqua.sega.general.BaseHandler;
import icu.samnyan.aqua.sega.general.model.Card;
import icu.samnyan.aqua.sega.general.model.response.UserRecentRating;
import icu.samnyan.aqua.sega.general.service.CardService;
import icu.samnyan.aqua.sega.ongeki.dao.userdata.*;
import icu.samnyan.aqua.sega.general.BaseHandler;
import icu.samnyan.aqua.sega.ongeki.model.gamedata.OngekiFumenScore;
import icu.samnyan.aqua.sega.ongeki.model.request.UpsertUserAll;
import icu.samnyan.aqua.sega.ongeki.model.response.CodeResp;
import icu.samnyan.aqua.sega.ongeki.model.userdata.*;
@ -22,6 +23,7 @@ import java.util.Optional;
/**
* The handler for saving all data of a ONGEKI profile
*
* @author samnyan (privateamusement@protonmail.com)
*/
@Component("OngekiUserAllHandler")
@ -118,7 +120,7 @@ public class UpsertUserAllHandler implements BaseHandler {
}
// If new data exists, use new data. Otherwise, use old data
newUserData = !upsertUserAll.getUserData().isEmpty() ? upsertUserAll.getUserData().get(0) : userData;
newUserData = !upsertUserAll.getUserData().isEmpty() ? upsertUserAll.getUserData().getFirst() : userData;
newUserData.setId(userData.getId());
newUserData.setCard(userData.getCard());
@ -132,7 +134,7 @@ public class UpsertUserAllHandler implements BaseHandler {
// UserOption
UserOption newUserOption = upsertUserAll.getUserOption().get(0);
UserOption newUserOption = upsertUserAll.getUserOption().getFirst();
Optional<UserOption> userOptionOptional = userOptionRepository.findByUser(newUserData);
UserOption userOption = userOptionOptional.orElseGet(() -> new UserOption(newUserData));
@ -181,7 +183,7 @@ public class UpsertUserAllHandler implements BaseHandler {
// UserRecentRatingList
// This thing still need to save to solve the rating drop
this.saveGeneralData(upsertUserAll.getUserRecentRatingList(), newUserData, "recent_rating_list");
this.saveRecentRatingData(upsertUserAll.getUserRecentRatingList(), newUserData, "recent_rating_list");
/*
@ -190,33 +192,44 @@ public class UpsertUserAllHandler implements BaseHandler {
* into a csv format for convenience
*/
// UserBpBaseList (For calculating Battle point)
this.saveGeneralData(upsertUserAll.getUserBpBaseList(), newUserData, "battle_point_base");
this.saveRecentRatingData(upsertUserAll.getUserBpBaseList(), newUserData, "battle_point_base");
// This is the best rating of all charts. Best 30 + 10 after that.
// userRatingBaseBestList
this.saveGeneralData(upsertUserAll.getUserRatingBaseBestList(), newUserData, "rating_base_best");
this.saveRecentRatingData(upsertUserAll.getUserRatingBaseBestList(), newUserData, "rating_base_best");
// userRatingBaseNextList
this.saveGeneralData(upsertUserAll.getUserRatingBaseNextList(), newUserData, "rating_base_next");
this.saveRecentRatingData(upsertUserAll.getUserRatingBaseNextList(), newUserData, "rating_base_next");
// This is the best rating of new charts. Best 15 + 10 after that.
// New chart means same version
// userRatingBaseBestNewList
this.saveGeneralData(upsertUserAll.getUserRatingBaseBestNewList(), newUserData, "rating_base_new_best");
this.saveRecentRatingData(upsertUserAll.getUserRatingBaseBestNewList(), newUserData, "rating_base_new_best");
// userRatingBaseNextNewList
this.saveGeneralData(upsertUserAll.getUserRatingBaseNextNewList(), newUserData, "rating_base_new_next");
this.saveRecentRatingData(upsertUserAll.getUserRatingBaseNextNewList(), newUserData, "rating_base_new_next");
// This is the recent best
// userRatingBaseHotList
this.saveGeneralData(upsertUserAll.getUserRatingBaseHotList(), newUserData, "rating_base_hot_best");
this.saveRecentRatingData(upsertUserAll.getUserRatingBaseHotList(), newUserData, "rating_base_hot_best");
// userRatingBaseHotNextList
this.saveGeneralData(upsertUserAll.getUserRatingBaseHotNextList(), newUserData, "rating_base_hot_next");
this.saveRecentRatingData(upsertUserAll.getUserRatingBaseHotNextList(), newUserData, "rating_base_hot_next");
this.saveFumenScoreData(upsertUserAll.getUserNewRatingBaseBestList(), newUserData, "new_rating_base_best");
this.saveFumenScoreData(upsertUserAll.getUserNewRatingBaseNextBestList(), newUserData, "new_rating_base_next_best");
this.saveFumenScoreData(upsertUserAll.getUserNewRatingBaseBestNewList(), newUserData, "new_rating_base_new_best");
this.saveFumenScoreData(upsertUserAll.getUserNewRatingBaseNextBestNewList(), newUserData, "new_rating_base_new_next_best");
this.saveFumenScoreData(upsertUserAll.getUserNewRatingBasePScoreList(), newUserData, "new_rating_base_pscore");
this.saveFumenScoreData(upsertUserAll.getUserNewRatingBaseNextPScoreList(), newUserData, "new_rating_base_next_pscore");
// UserMusicDetailList
List<UserMusicDetail> userMusicDetailList = upsertUserAll.getUserMusicDetailList();
@ -339,16 +352,16 @@ public class UpsertUserAllHandler implements BaseHandler {
// UserMemoryChapterList
List<UserMemoryChapter> userMemoryChapterList = upsertUserAll.getUserMemoryChapterList();
if (userMemoryChapterList != null) {
List<UserMemoryChapter> newUserMemoryChapterList = new ArrayList<>();
for (UserMemoryChapter newUserMemoryChapter : userMemoryChapterList) {
int chapterId = newUserMemoryChapter.getChapterId();
Optional<UserMemoryChapter> chapterOptional = userMemoryChapterRepository.findByUserAndChapterId(newUserData, chapterId);
UserMemoryChapter userChapter = chapterOptional.orElseGet(() -> new UserMemoryChapter(newUserData));
newUserMemoryChapter.setId(userChapter.getId());
newUserMemoryChapter.setUser(newUserData);
newUserMemoryChapterList.add(newUserMemoryChapter);
@ -567,7 +580,7 @@ public class UpsertUserAllHandler implements BaseHandler {
}
private void saveGeneralData(List<UserRecentRating> itemList, UserData newUserData, String key) {
private void saveRecentRatingData(List<UserRecentRating> itemList, UserData newUserData, String key) {
StringBuilder sb = new StringBuilder();
// Convert to a string
for (UserRecentRating item :
@ -575,12 +588,34 @@ public class UpsertUserAllHandler implements BaseHandler {
sb.append(item.getMusicId()).append(":").append(item.getDifficultId()).append(":").append(item.getScore());
sb.append(",");
}
if (sb.length() > 0) {
if (!sb.isEmpty()) {
sb.deleteCharAt(sb.length() - 1);
}
saveGeneralData(newUserData, key, sb.toString());
}
private void saveFumenScoreData(List<OngekiFumenScore> itemList, UserData newUserData, String key) {
StringBuilder sb = new StringBuilder();
for (OngekiFumenScore item : itemList) {
sb.append(item.getMusicId()).append(":")
.append(item.getDifficultId()).append(":")
.append(item.getScore()).append(":")
.append(item.getPlatinumScoreStar()).append(":")
.append(item.getPlatinumScoreMax());
sb.append(",");
}
if (!sb.isEmpty()) {
sb.deleteCharAt(sb.length() - 1);
}
saveGeneralData(newUserData, key, sb.toString());
}
private void saveGeneralData(UserData newUserData, String key, String data) {
Optional<UserGeneralData> uOptional = userGeneralDataRepository.findByUserAndPropertyKey(newUserData, key);
UserGeneralData userGeneralData = uOptional.orElseGet(() -> new UserGeneralData(newUserData, key));
userGeneralData.setPropertyValue(sb.toString());
userGeneralData.setPropertyValue(data);
userGeneralDataRepository.save(userGeneralData);
}
}

View File

@ -0,0 +1,17 @@
package icu.samnyan.aqua.sega.ongeki.model.gamedata;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class OngekiFumenScore {
private int musicId;
private int difficultId;
private String romVersionCode;
private int score;
public int platinumScoreMax;
public int platinumScoreStar;
}

View File

@ -2,6 +2,7 @@ package icu.samnyan.aqua.sega.ongeki.model.request;
import com.fasterxml.jackson.annotation.JsonProperty;
import icu.samnyan.aqua.sega.general.model.response.UserRecentRating;
import icu.samnyan.aqua.sega.ongeki.model.gamedata.OngekiFumenScore;
import icu.samnyan.aqua.sega.ongeki.model.userdata.*;
import lombok.AllArgsConstructor;
import lombok.Data;
@ -47,6 +48,18 @@ public class UpsertUserAll implements Serializable {
private List<UserRecentRating> userRatingBaseHotNextList;
private List<OngekiFumenScore> userNewRatingBasePScoreList;
private List<OngekiFumenScore> userNewRatingBaseBestList;
private List<OngekiFumenScore> userNewRatingBaseBestNewList;
private List<OngekiFumenScore> userNewRatingBaseNextPScoreList;
private List<OngekiFumenScore> userNewRatingBaseNextBestList;
private List<OngekiFumenScore> userNewRatingBaseNextBestNewList;
private List<UserMusicDetail> userMusicDetailList;
private List<UserCharacter> userCharacterList;

View File

@ -22,6 +22,7 @@ public class GetUserPreviewResp {
private int level = 0;
private long exp = 0;
private long playerRating = 0;
private long newPlayerRating = 0;
private String lastGameId = "";
private String lastRomVersion = "";
private String lastDataVersion = "";

View File

@ -35,7 +35,6 @@ public class UserData implements Serializable, IUserData {
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "aime_card_id", unique = true)
private Card card;
// Access code in card
private String userName;
@ -57,10 +56,16 @@ public class UserData implements Serializable, IUserData {
private int medalCount;
private int shizukuCount;
private int playerRating;
private int highestRating;
private int newPlayerRating;
private int newHighestRating;
private int battlePoint;
private int bestBattlePoint;
@ -118,6 +123,18 @@ public class UserData implements Serializable, IUserData {
private long sumBattleLunaticHighScore;
private int sumPlatinumScoreStar;
private int sumBasicPlatinumScoreStar;
private int sumAdvancedPlatinumScoreStar;
private int sumExpertPlatinumScoreStar;
private int sumMasterPlatinumScoreStar;
private int sumLunaticPlatinumScoreStar;
private String eventWatchedDate;
private String cmEventWatchedDate;
@ -163,4 +180,4 @@ public class UserData implements Serializable, IUserData {
public long getTotalScore() {
return sumTechHighScore;
}
}
}

View File

@ -48,6 +48,8 @@ public class UserMusicDetail implements Serializable, IGenericUserMusic {
private int platinumScoreMax;
private int platinumScoreStar;
private int maxComboCount;
private int maxOverKill;

View File

@ -82,6 +82,8 @@ public class UserOption implements Serializable {
private int effectPos;
private int effectAttack;
private int judgeDisp;
private int judgePos;

View File

@ -0,0 +1,16 @@
-- ongeki_user_option
ALTER TABLE ongeki_user_option ADD COLUMN effect_attack INT NOT NULL DEFAULT 0;
-- ongeki_user_data
ALTER TABLE ongeki_user_data ADD COLUMN new_highest_rating INT NOT NULL DEFAULT 0;
ALTER TABLE ongeki_user_data ADD COLUMN new_player_rating INT NOT NULL DEFAULT 0;
ALTER TABLE ongeki_user_data ADD COLUMN shizuku_count INT NOT NULL DEFAULT 0;
ALTER TABLE ongeki_user_data ADD COLUMN sum_advanced_platinum_score_star INT NOT NULL DEFAULT 0;
ALTER TABLE ongeki_user_data ADD COLUMN sum_basic_platinum_score_star INT NOT NULL DEFAULT 0;
ALTER TABLE ongeki_user_data ADD COLUMN sum_expert_platinum_score_star INT NOT NULL DEFAULT 0;
ALTER TABLE ongeki_user_data ADD COLUMN sum_lunatic_platinum_score_star INT NOT NULL DEFAULT 0;
ALTER TABLE ongeki_user_data ADD COLUMN sum_master_platinum_score_star INT NOT NULL DEFAULT 0;
ALTER TABLE ongeki_user_data ADD COLUMN sum_platinum_score_star INT NOT NULL DEFAULT 0;
-- ongeki_user_music_detail
ALTER TABLE ongeki_user_music_detail ADD COLUMN platinum_score_star INT NOT NULL DEFAULT 0;