diff --git a/src/main/java/icu/samnyan/aqua/sega/diva/dao/userdata/PlayerCustomizeRepository.java b/src/main/java/icu/samnyan/aqua/sega/diva/dao/userdata/PlayerCustomizeRepository.java index a0c280b5..3cdbd162 100644 --- a/src/main/java/icu/samnyan/aqua/sega/diva/dao/userdata/PlayerCustomizeRepository.java +++ b/src/main/java/icu/samnyan/aqua/sega/diva/dao/userdata/PlayerCustomizeRepository.java @@ -8,6 +8,7 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import java.util.List; +import java.util.Optional; /** * @author samnyan (privateamusement@protonmail.com) @@ -17,4 +18,6 @@ public interface PlayerCustomizeRepository extends JpaRepository findByPdId(PlayerProfile profile); Page findByPdId_PdId(int pdId, Pageable page); + + Optional findByPdIdAndCustomizeId(PlayerProfile currentProfile, int parseInt); } diff --git a/src/main/java/icu/samnyan/aqua/sega/diva/dao/userdata/PlayerInventoryRepository.java b/src/main/java/icu/samnyan/aqua/sega/diva/dao/userdata/PlayerInventoryRepository.java new file mode 100644 index 00000000..2b1180c3 --- /dev/null +++ b/src/main/java/icu/samnyan/aqua/sega/diva/dao/userdata/PlayerInventoryRepository.java @@ -0,0 +1,16 @@ +package icu.samnyan.aqua.sega.diva.dao.userdata; + +import icu.samnyan.aqua.sega.diva.model.userdata.PlayerInventory; +import icu.samnyan.aqua.sega.diva.model.userdata.PlayerProfile; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +/** + * @author samnyan (privateamusement@protonmail.com) + */ +@Repository +public interface PlayerInventoryRepository extends JpaRepository { + Optional findByPdIdAndTypeAndValue(PlayerProfile profile, String type, String value); +} diff --git a/src/main/java/icu/samnyan/aqua/sega/diva/handler/ingame/StageResultHandler.java b/src/main/java/icu/samnyan/aqua/sega/diva/handler/ingame/StageResultHandler.java index a10d8e40..26621601 100644 --- a/src/main/java/icu/samnyan/aqua/sega/diva/handler/ingame/StageResultHandler.java +++ b/src/main/java/icu/samnyan/aqua/sega/diva/handler/ingame/StageResultHandler.java @@ -1,19 +1,15 @@ package icu.samnyan.aqua.sega.diva.handler.ingame; -import icu.samnyan.aqua.sega.diva.dao.userdata.GameSessionRepository; -import icu.samnyan.aqua.sega.diva.dao.userdata.PlayLogRepository; -import icu.samnyan.aqua.sega.diva.dao.userdata.PlayerProfileRepository; -import icu.samnyan.aqua.sega.diva.dao.userdata.PlayerPvRecordRepository; +import icu.samnyan.aqua.sega.diva.dao.gamedata.ContestRepository; +import icu.samnyan.aqua.sega.diva.dao.userdata.*; import icu.samnyan.aqua.sega.diva.exception.ProfileNotFoundException; import icu.samnyan.aqua.sega.diva.exception.SessionNotFoundException; import icu.samnyan.aqua.sega.diva.handler.BaseHandler; import icu.samnyan.aqua.sega.diva.model.common.*; +import icu.samnyan.aqua.sega.diva.model.gamedata.Contest; import icu.samnyan.aqua.sega.diva.model.request.ingame.StageResultRequest; import icu.samnyan.aqua.sega.diva.model.response.ingame.StageResultResponse; -import icu.samnyan.aqua.sega.diva.model.userdata.GameSession; -import icu.samnyan.aqua.sega.diva.model.userdata.PlayLog; -import icu.samnyan.aqua.sega.diva.model.userdata.PlayerProfile; -import icu.samnyan.aqua.sega.diva.model.userdata.PlayerPvRecord; +import icu.samnyan.aqua.sega.diva.model.userdata.*; import icu.samnyan.aqua.sega.diva.util.DivaCalculator; import icu.samnyan.aqua.sega.diva.util.DivaMapper; import org.apache.commons.lang3.StringUtils; @@ -22,8 +18,7 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import java.time.LocalDateTime; -import java.util.LinkedList; -import java.util.List; +import java.util.*; import static icu.samnyan.aqua.sega.diva.model.common.Const.NULL_QUEST; @@ -39,15 +34,25 @@ public class StageResultHandler extends BaseHandler { private final PlayerPvRecordRepository pvRecordRepository; private final PlayerProfileRepository profileRepository; private final PlayLogRepository playLogRepository; + private final ContestRepository contestRepository; + private final PlayerContestRepository playerContestRepository; + private final PlayerCustomizeRepository playerCustomizeRepository; + private final PlayerInventoryRepository playerInventoryRepository; private final DivaCalculator divaCalculator; - public StageResultHandler(DivaMapper mapper, GameSessionRepository gameSessionRepository, PlayerPvRecordRepository pvRecordRepository, PlayerProfileRepository profileRepository, PlayLogRepository playLogRepository, DivaCalculator divaCalculator) { + private PlayerProfile currentProfile = null; + + public StageResultHandler(DivaMapper mapper, GameSessionRepository gameSessionRepository, PlayerPvRecordRepository pvRecordRepository, PlayerProfileRepository profileRepository, PlayLogRepository playLogRepository, ContestRepository contestRepository, PlayerContestRepository playerContestRepository, PlayerCustomizeRepository playerCustomizeRepository, PlayerInventoryRepository playerInventoryRepository, DivaCalculator divaCalculator) { super(mapper); this.gameSessionRepository = gameSessionRepository; this.pvRecordRepository = pvRecordRepository; this.profileRepository = profileRepository; this.playLogRepository = playLogRepository; + this.contestRepository = contestRepository; + this.playerContestRepository = playerContestRepository; + this.playerCustomizeRepository = playerCustomizeRepository; + this.playerInventoryRepository = playerInventoryRepository; this.divaCalculator = divaCalculator; } @@ -57,56 +62,140 @@ public class StageResultHandler extends BaseHandler { PlayerProfile profile = profileRepository.findByPdId(request.getPd_id()).orElseThrow(ProfileNotFoundException::new); GameSession session = gameSessionRepository.findByPdId(profile).orElseThrow(SessionNotFoundException::new); + currentProfile = profile; // Get the last played index int[] pvIds = request.getStg_ply_pv_id(); - int stageIndex = session.getStageIndex(); + int[] stageArr = request.getStg_ply_pv_id(); + int stageIndex = 0; + if (stageArr[0] != -1) { + stageIndex = 0; + } + if (stageArr[1] != -1) { + stageIndex = 1; + } + if (stageArr[2] != -1) { + stageIndex = 2; + } + if (stageArr[3] != -1) { + stageIndex = 3; + } + // Convert to play log object + PlayLog log = getLog(request, profile, stageIndex); + logger.debug("Stage Result Object: {}", log.toString()); - // Convert to play log object - PlayLog log = getLog(request, profile, stageIndex); - logger.debug("Stage Result Object: {}", log.toString()); + PlayerPvRecord record = pvRecordRepository.findByPdIdAndPvIdAndEditionAndDifficulty(profile, log.getPvId(), log.getEdition(), log.getDifficulty()) + .orElseGet(() -> new PlayerPvRecord(profile, log.getPvId(), log.getEdition(), log.getDifficulty())); - PlayerPvRecord record = pvRecordRepository.findByPdIdAndPvIdAndEditionAndDifficulty(profile, log.getPvId(), log.getEdition(), log.getDifficulty()) - .orElseGet(() -> new PlayerPvRecord(profile, log.getPvId(), log.getEdition(), log.getDifficulty())); + // Not save personal record in no fail mode + if (request.getGame_type() != 1) { + // Only update personal record when using rhythm game option + if (log.getRhythmGameOptions().equals("0,0,0")) { + // Update pvRecord field + record.setMaxScore(Math.max(record.getMaxScore(), log.getScore())); + record.setMaxAttain(Math.max(record.getMaxAttain(), log.getAttainPoint())); - // Not save personal record in no fail mode - if(request.getGame_type() != 1) { - // Only update personal record when using rhythm game option - if (log.getRhythmGameOptions().equals("0,0,0")) { - // Update pvRecord field - record.setMaxScore(Math.max(record.getMaxScore(), log.getScore())); - record.setMaxAttain(Math.max(record.getMaxAttain(), log.getAttainPoint())); + if (record.getResult().getValue() < log.getClearResult().getValue()) { + record.setResult(log.getClearResult()); + } + } + } - if (record.getResult().getValue() < log.getClearResult().getValue()) { - record.setResult(log.getClearResult()); + String[] updateRgo = log.getRhythmGameOptions().split(","); + String[] oldRgo = record.getRgoPlayed().split(","); + for (int i = 0; i < updateRgo.length; i++) { + if (updateRgo[i].equals("1")) { + oldRgo[i] = "1"; + } + } + record.setRgoPlayed(StringUtils.join(oldRgo, ",")); + + session.setVp(session.getVp() + log.getVp()); + session.setLastPvId(log.getPvId()); + session.setLastUpdateTime(LocalDateTime.now()); + + LevelInfo levelInfo = divaCalculator.getLevelInfo(profile); + session.setOldLevelNumber(session.getLevelNumber()); + session.setOldLevelExp(session.getLevelExp()); + session.setLevelNumber(levelInfo.getLevelNumber()); + session.setLevelExp(levelInfo.getLevelExp()); + + session.setStageResultIndex(stageIndex); + + // Calculate reward + // Contest reward + String contestSpecifier = String.join(",", request.getCr_sp()); + String[] contestRewardType = {"-1", "-1", "-1"}; + String[] contestRewardValue = {"-1", "-1", "-1"}; + String[] contestRewardString1 = {"***", "***", "***"}; + String[] contestRewardString2 = {"***", "***", "***"}; + int contestEntryRewardType = -1; + int contestEntryRewardValue = -1; + String contestEntryRewardString1 = "***"; + String contestEntryRewardString2 = "***"; + int contestId = request.getCr_cid(); + if (contestId != -1) { + List progress = getContestProgress(request.getCr_sp()); + contestSpecifier = getContestSpecifier(progress); + + // Check if the contest info exist + Optional contestOptional = contestRepository.findById(contestId); + if (contestOptional.isPresent()) { + Contest contest = contestOptional.get(); + Optional playerContestOptional = playerContestRepository.findByPdIdAndContestId(profile, contestId); + + // Contest Entry Reward + // Check if this is first stage + if (progress.size() == 1 && playerContestOptional.isEmpty()) { + if (StringUtils.isNotBlank(contest.getContestEntryReward())) { + // Check if this is first time play this contest + String reward = contest.getContestEntryReward(); + String[] rewardValue = reward.split(":"); + + contestEntryRewardType = Integer.parseInt(rewardValue[0]); + contestEntryRewardValue = Integer.parseInt(rewardValue[1]); + contestEntryRewardString1 = rewardValue[2]; + contestEntryRewardString2 = rewardValue[3]; } } - } - String[] updateRgo = log.getRhythmGameOptions().split(","); - String[] oldRgo = record.getRgoPlayed().split(","); - for (int i = 0; i < updateRgo.length; i++) { - if (updateRgo[i].equals("1")) { - oldRgo[i] = "1"; + // Only if this is the first time reach this value + int previousValue = progress.stream().limit(progress.size() - 1).mapToInt(ContestProgress::getScores).sum(); + int currentValue = progress.stream().mapToInt(ContestProgress::getScores).sum(); + + // Bronze Reward + Map bronze = updateReward(currentValue, previousValue, contest.getBronzeBorders(), contest.getBronzeContestReward()); + if (bronze != null) { + contestRewardType[0] = bronze.get("type"); + contestRewardValue[0] = bronze.get("value"); + contestRewardString1[0] = bronze.get("string1"); + contestRewardString2[2] = bronze.get("string2"); } + + // Silver Reward + Map silver = updateReward(currentValue, previousValue, contest.getSliverBorders(), contest.getSliverContestReward()); + if (silver != null) { + contestRewardType[1] = silver.get("type"); + contestRewardValue[1] = silver.get("value"); + contestRewardString1[1] = silver.get("string1"); + contestRewardString2[2] = silver.get("string2"); + } + + // Gold Reward + Map gold = updateReward(currentValue, previousValue, contest.getGoldBorders(), contest.getGoldContestReward()); + if (gold != null) { + contestRewardType[2] = gold.get("type"); + contestRewardValue[2] = gold.get("value"); + contestRewardString1[2] = gold.get("string1"); + contestRewardString2[2] = gold.get("string2"); + } + } - record.setRgoPlayed(StringUtils.join(oldRgo, ",")); + } - session.setVp(session.getVp() + log.getVp()); - session.setLastPvId(log.getPvId()); - session.setLastUpdateTime(LocalDateTime.now()); - - LevelInfo levelInfo = divaCalculator.getLevelInfo(profile); - session.setOldLevelNumber(session.getLevelNumber()); - session.setOldLevelExp(session.getLevelExp()); - session.setLevelNumber(levelInfo.getLevelNumber()); - session.setLevelExp(levelInfo.getLevelExp()); - - session.setStageResultIndex(stageIndex); - - pvRecordRepository.save(record); - playLogRepository.save(log); - gameSessionRepository.save(session); + pvRecordRepository.save(record); + playLogRepository.save(log); + gameSessionRepository.save(session); response = new StageResultResponse( @@ -125,15 +214,15 @@ public class StageResultHandler extends BaseHandler { 0, request.getCr_cid(), request.getCr_tv(), - getContestSpecifier(request.getCr_sp()), - "-1,-1,-1", - "-1,-1,-1", - "***,***,***", - "***,***,***", - -1, - -1, - "***", - "***", + contestSpecifier, + String.join(",", contestRewardType), + String.join(",", contestRewardValue), + String.join(",", contestRewardString1), + String.join(",", contestRewardString2), + contestEntryRewardType, + contestEntryRewardValue, + contestEntryRewardString1, + contestEntryRewardString2, "xxx,xxx,xxx,xxx,xxx", "-1,-1,-1,-1,-1", "xxx,xxx,xxx,xxx,xxx", @@ -226,14 +315,102 @@ public class StageResultHandler extends BaseHandler { return sb.toString(); } - private String getContestSpecifier(String[] arr) { + private List getContestProgress(String[] arr) { + List result = new LinkedList<>(); + for (int i = 0; i < arr.length; i = i + 6) { + if (!arr[i].equals("-1")) { + result.add(new ContestProgress( + Integer.parseInt(arr[i]), + Integer.parseInt(arr[i + 1]), + Integer.parseInt(arr[i + 2]), + Integer.parseInt(arr[i + 3]), + Integer.parseInt(arr[i + 4]), + Integer.parseInt(arr[i + 5]) + )); + } + } + return result; + } + + private String getContestSpecifier(List progresses) { List result = new LinkedList<>(); - for (int i = 0; i < arr.length; i++) { - if ((i % 6) != 0) result.add(arr[i]); + for (ContestProgress x : progresses) { + result.add(String.valueOf(x.getHardness())); + result.add(String.valueOf(x.getEdition())); + result.add(String.valueOf(x.getStars())); + result.add(String.valueOf(x.getScores())); + result.add(String.valueOf(x.getVersion())); } while (result.size() < 60) { result.add("-1"); } return String.join(",", result); } + + private Map updateReward(int currentValue, int previousValue, int borders, String reward) { + if (currentValue > borders && previousValue < borders) { + if (StringUtils.isNotBlank(reward)) { + String[] rewardValue = reward.split(":"); + Map result = new HashMap<>(); + switch (rewardValue[0]) { + case "-1": + return null; + case "0": { + result.put("type", rewardValue[0]); + result.put("value", rewardValue[1]); + result.put("string1", "***"); + result.put("string2", "***"); + break; + } + case "1": { + if (playerInventoryRepository.findByPdIdAndTypeAndValue(currentProfile, "SKIN", rewardValue[1]).isPresent()) { + result.put("type", "-1"); + result.put("value", "-1"); + result.put("string1", "***"); + result.put("string2", "***"); + } else { + playerInventoryRepository.save(new PlayerInventory(null, currentProfile, rewardValue[1], "SKIN")); + result.put("type", rewardValue[0]); + result.put("value", rewardValue[1]); + result.put("string1", rewardValue[2]); + result.put("string2", rewardValue[3]); + } + break; + } + case "2": { + if (playerInventoryRepository.findByPdIdAndTypeAndValue(currentProfile, "PLATE", rewardValue[1]).isPresent()) { + result.put("type", "-1"); + result.put("value", "-1"); + result.put("string1", "***"); + result.put("string2", "***"); + } else { + playerInventoryRepository.save(new PlayerInventory(null, currentProfile, rewardValue[1], "PLATE")); + result.put("type", rewardValue[0]); + result.put("value", rewardValue[1]); + result.put("string1", rewardValue[2]); + result.put("string2", rewardValue[3]); + } + break; + } + case "3": { + if (playerCustomizeRepository.findByPdIdAndCustomizeId(currentProfile, Integer.parseInt(rewardValue[1])).isPresent()) { + result.put("type", "-1"); + result.put("value", "-1"); + result.put("string1", "***"); + result.put("string2", "***"); + } else { + playerCustomizeRepository.save(new PlayerCustomize(currentProfile, Integer.parseInt(rewardValue[1]))); + result.put("type", rewardValue[0]); + result.put("value", rewardValue[1]); + result.put("string1", rewardValue[2]); + result.put("string2", rewardValue[3]); + } + break; + } + } + return result; + } + } + return null; + } } diff --git a/src/main/java/icu/samnyan/aqua/sega/diva/handler/user/EndHandler.java b/src/main/java/icu/samnyan/aqua/sega/diva/handler/user/EndHandler.java index f6f824f2..0fea81c5 100644 --- a/src/main/java/icu/samnyan/aqua/sega/diva/handler/user/EndHandler.java +++ b/src/main/java/icu/samnyan/aqua/sega/diva/handler/user/EndHandler.java @@ -93,27 +93,7 @@ public class EndHandler extends BaseHandler { profile.setContestNowPlayingSpecifier(getDummyString("-1", 60)); } } - - int savedIndex = session.getStageResultIndex(); - int[] stageArr = request.getStg_ply_pv_id(); - int stageIndex = 0; - if(stageArr[0] != -1) { - stageIndex = 0; - } - if(stageArr[1] != -1) { - stageIndex = 1; - } - if(stageArr[2] != -1) { - stageIndex = 2; - } - if(stageArr[3] != -1) { - stageIndex = 3; - } - if(stageIndex != savedIndex) { - logger.error("Some stage not saved"); - } - - + playerProfileService.save(profile); gameSessionRepository.delete(session); diff --git a/src/main/java/icu/samnyan/aqua/sega/diva/model/common/ContestProgress.java b/src/main/java/icu/samnyan/aqua/sega/diva/model/common/ContestProgress.java new file mode 100644 index 00000000..c68d231b --- /dev/null +++ b/src/main/java/icu/samnyan/aqua/sega/diva/model/common/ContestProgress.java @@ -0,0 +1,20 @@ +package icu.samnyan.aqua.sega.diva.model.common; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +/** + * @author samnyan (privateamusement@protonmail.com) + */ +@Getter +@Setter +@AllArgsConstructor +public class ContestProgress { + int pvId; + int hardness; + int edition; + int stars; + int scores; + int version; +} diff --git a/src/main/java/icu/samnyan/aqua/sega/diva/model/gamedata/Contest.java b/src/main/java/icu/samnyan/aqua/sega/diva/model/gamedata/Contest.java index c9fb6fed..58a73332 100644 --- a/src/main/java/icu/samnyan/aqua/sega/diva/model/gamedata/Contest.java +++ b/src/main/java/icu/samnyan/aqua/sega/diva/model/gamedata/Contest.java @@ -8,6 +8,7 @@ import icu.samnyan.aqua.sega.util.URIEncoder; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; import javax.persistence.*; import java.io.Serializable; @@ -47,14 +48,13 @@ public class Contest implements Serializable { private int stars; - private int minComplexity; + private int minComplexity; // Only use when Pv difficulty list is not set. private int maxComplexity; private int stages; - @Enumerated(EnumType.STRING) - private ContestStageLimit stageLimit; + private String stageLimit; @Enumerated(EnumType.STRING) private ContestNormaType normaType; @@ -65,161 +65,90 @@ public class Contest implements Serializable { private int goldBorders = 0; + // Pv List format: "pv_id_start:pv_id_end,pv_id_start:pv_id_end,pv_id_start:pv_id_end" more than 20 group will be ignore, put in -1 for empty end + private String pvList; + + // Pv difficulty list format: "pv_difficulty:min_complexity:max_complexity" + private String pvDiffList; + + // ContestReward format: + // Reward Type: (-1 None, 0 VP, 1 Skin, 2 Callsign, 3 Customize) + // Format: "rewardType:reward:string1:string2" string1 and 2 should be urlencoded and must exist. use *** aka %2A%2A%2A as placeholder + private String bronzeContestReward; + + private String sliverContestReward; + + private String goldContestReward; + + // ContestReward format: "rewardType:reward:string1:string2" + private String contestEntryReward; + public String getString() { List list = new LinkedList<>(); - list.add(this.id); - list.add(DivaDateTimeUtil.format(this.startTime)); - list.add(DivaDateTimeUtil.format(this.endTime)); - list.add(URIEncoder.encode(this.name)); - list.add(URIEncoder.encode(this.description)); - list.add(this.league.getValue()); - list.add(this.stars); - list.add(this.stages); - list.add(this.stageLimit.getValue()); + list.add(this.id); // Contest ID + list.add(DivaDateTimeUtil.format(this.startTime)); // Start time + list.add(DivaDateTimeUtil.format(this.endTime)); // End time + list.add(URIEncoder.encode(this.name)); // Contest name + list.add(URIEncoder.encode(this.description)); // Contest description + list.add(this.league.getValue()); // Contest league + list.add(this.stars); // Contest starts + list.add(this.stages); // Contest stage, 1~9 + list.add(this.stageLimit); // list_lump_num ( 0 will be all stage same. > 1 will became stage max defined chart? ) list.add(this.normaType.getValue()); list.add(this.bronzeBorders); list.add(this.sliverBorders); list.add(this.goldBorders); - list.add(-1); - list.add(-2); - list.add(this.minComplexity); - list.add(this.maxComplexity); - list.add(-1); - list.add(-2); - list.add("7fffffffffffffffffffffffffffffff"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("7fffffffffffffffffffffffffffffff"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("7fffffffffffffffffffffffffffffff"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("7fffffffffffffffffffffffffffffff"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("7fffffffffffffffffffffffffffffff"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("7fffffffffffffffffffffffffffffff"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("7fffffffffffffffffffffffffffffff"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("7fffffffffffffffffffffffffffffff"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("7fffffffffffffffffffffffffffffff"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("7fffffffffffffffffffffffffffffff"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("7fffffffffffffffffffffffffffffff"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("7fffffffffffffffffffffffffffffff"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("7fffffffffffffffffffffffffffffff"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("7fffffffffffffffffffffffffffffff"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("7fffffffffffffffffffffffffffffff"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("7fffffffffffffffffffffffffffffff"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("7fffffffffffffffffffffffffffffff"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("7fffffffffffffffffffffffffffffff"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("7fffffffffffffffffffffffffffffff"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("-2"); - list.add("7fffffffffffffffffffffffffffffff"); + for (int i = 1; i <= 20; i++) { + // format is "pv_range_start,pv_range_end,min_complexity,max_complexity,difficulty,unknown" + if (StringUtils.isBlank(pvList) || !pvList.contains(":")) { + list.add(-1); + list.add(-1); + if (i == 1) { + list.add(this.minComplexity); + list.add(this.maxComplexity); + } else { + list.add(-2); + list.add(-2); + } + list.add(-1); + list.add(-2); + list.add("7fffffffffffffffffffffffffffffff"); + } else { + String[] groups = pvList.split(","); + if (groups.length < i) { + list.add(-1); + list.add(-1); + list.add(-2); + list.add(-2); + list.add(-1); + list.add(-2); + list.add("7fffffffffffffffffffffffffffffff"); + } else { + String[] ids = groups[i - 1].split(":"); + list.add(ids[0]); + list.add(ids[1]); + if(StringUtils.isBlank(pvDiffList) || !pvDiffList.contains(":")) { + list.add(this.minComplexity); + list.add(this.maxComplexity); + list.add(-1); + } else { + String[] diffList = pvDiffList.split(","); + if(diffList.length < i) { + list.add(this.minComplexity); + list.add(this.maxComplexity); + list.add(-1); + } else { + String[] diff = diffList[i-1].split(":"); + list.add(diff[1]); + list.add(diff[2]); + list.add(diff[0]); + } + } + list.add(-2); + list.add("7fffffffffffffffffffffffffffffff"); + } + } + } return list.stream().map(Object::toString).collect(Collectors.joining(",")); } } diff --git a/src/main/java/icu/samnyan/aqua/sega/diva/model/userdata/PlayerInventory.java b/src/main/java/icu/samnyan/aqua/sega/diva/model/userdata/PlayerInventory.java new file mode 100644 index 00000000..78a34003 --- /dev/null +++ b/src/main/java/icu/samnyan/aqua/sega/diva/model/userdata/PlayerInventory.java @@ -0,0 +1,36 @@ +package icu.samnyan.aqua.sega.diva.model.userdata; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import java.io.Serializable; + +/** + * @author samnyan (privateamusement@protonmail.com) + */ +@Entity(name = "DivaPlayerInventory") +@Table(name = "diva_player_inventory", uniqueConstraints = {@UniqueConstraint(columnNames = {"pd_id", "value", "type"})}) +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PlayerInventory implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne + @JoinColumn(name = "pd_id") + @JsonIgnore + private PlayerProfile pdId; + + private String value; + + // Type: (1: Skin, 2: Call sign plate, 3: Call sign) + private String type; +} diff --git a/src/main/resources/db/migration/mysql/V11__add_pv_diff_and_reward_to_contest.sql b/src/main/resources/db/migration/mysql/V11__add_pv_diff_and_reward_to_contest.sql new file mode 100644 index 00000000..bfb823d7 --- /dev/null +++ b/src/main/resources/db/migration/mysql/V11__add_pv_diff_and_reward_to_contest.sql @@ -0,0 +1,33 @@ +ALTER TABLE `diva_contest` + ADD COLUMN `pv_list` varchar(255) DEFAULT NULL; + +UPDATE `diva_contest` SET `stage_limit`='0'; + +ALTER TABLE `diva_contest` + ADD COLUMN `pv_diff_list` varchar(255) DEFAULT NULL; + +ALTER TABLE `diva_contest` + ADD COLUMN `bronze_contest_reward` varchar(255) DEFAULT NULL, + ADD COLUMN `sliver_contest_reward` varchar(255) DEFAULT NULL, + ADD COLUMN `gold_contest_reward` varchar(255) DEFAULT NULL, + ADD COLUMN `contest_entry_reward` varchar(255) DEFAULT NULL; + +CREATE TABLE `diva_player_inventory` +( + `id` bigint(20) NOT NULL, + `type` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `value` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `pd_id` bigint(20) DEFAULT NULL +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 + COLLATE = utf8mb4_unicode_ci; + +ALTER TABLE `diva_player_inventory` + ADD PRIMARY KEY (`id`), + ADD UNIQUE KEY `UK1bace6j9oebd80bqw7hfad3c` (`pd_id`, `type`, `value`); + +ALTER TABLE `diva_player_inventory` + MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT; + +ALTER TABLE `diva_player_inventory` + ADD CONSTRAINT `FK4328de6j9oebd899qw7hbxh6s` FOREIGN KEY (`pd_id`) REFERENCES `diva_player_profile` (`id`); \ No newline at end of file diff --git a/src/main/resources/db/migration/sqlite/V11__add_pv_diff_and_reward_to_contest.sql b/src/main/resources/db/migration/sqlite/V11__add_pv_diff_and_reward_to_contest.sql new file mode 100644 index 00000000..e1924812 --- /dev/null +++ b/src/main/resources/db/migration/sqlite/V11__add_pv_diff_and_reward_to_contest.sql @@ -0,0 +1,81 @@ +CREATE TABLE diva_contest_new +( + id INTEGER, + bronze_borders INTEGER NOT NULL, + description VARCHAR(255), + enable BOOLEAN NOT NULL, + end_time DATETIME, + gold_borders INTEGER NOT NULL, + league VARCHAR(255), + max_complexity INTEGER NOT NULL, + min_complexity INTEGER NOT NULL, + name VARCHAR(255), + norma_type VARCHAR(255), + sliver_borders INTEGER NOT NULL, + stage_limit VARCHAR(255), + stages INTEGER NOT NULL, + stars INTEGER NOT NULL, + start_time DATETIME, + pv_list VARCHAR(255), + pv_diff_list VARCHAR(255), + bronze_contest_reward VARCHAR(255), + sliver_contest_reward VARCHAR(255), + gold_contest_reward VARCHAR(255), + contest_entry_reward VARCHAR(255), + PRIMARY KEY ( + id + ) +); + +INSERT INTO diva_contest_new (id, + bronze_borders, + description, + enable, + end_time, + gold_borders, + league, + max_complexity, + min_complexity, + name, + norma_type, + sliver_borders, + stage_limit, + stages, + stars, + start_time) +SELECT id, + bronze_borders, + description, + enable, + end_time, + gold_borders, + league, + max_complexity, + min_complexity, + name, + norma_type, + sliver_borders, + '0', + stages, + stars, + start_time +FROM diva_contest; + +DROP TABLE diva_contest; +ALTER TABLE diva_contest_new RENAME TO diva_contest; + +CREATE TABLE diva_player_inventory +( + id INTEGER, + type VARCHAR(255), + value VARCHAR(255), + pd_id BIGINT REFERENCES diva_player_profile (id) ON DELETE CASCADE, + PRIMARY KEY ( + id + ), + CONSTRAINT diva_player_inventory_uq UNIQUE ( + type, + value, + pd_id + ) +); \ No newline at end of file