From ce780b2edbd621c8e8a2edc7092bf259c37d207c Mon Sep 17 00:00:00 2001 From: samnyan <205-NeumPhis@users.noreply.dev.s-ul.eu> Date: Thu, 23 Jan 2020 15:31:32 +0800 Subject: [PATCH] [DIVA] Add stage result index to prevent multiple result being sent by client, fix #3 --- .../handler/card/CardProcedureHandler.java | 1 + .../handler/ingame/StageResultHandler.java | 70 ++++++++++--------- .../handler/ingame/StageStartHandler.java | 9 ++- .../diva/handler/user/PreStartHandler.java | 1 + .../sega/diva/model/userdata/GameSession.java | 5 +- ...7__add_diva_session_stage_result_index.sql | 4 ++ ...7__add_diva_session_stage_result_index.sql | 23 ++++++ 7 files changed, 77 insertions(+), 36 deletions(-) create mode 100644 src/main/resources/db/migration/mysql/V7__add_diva_session_stage_result_index.sql create mode 100644 src/main/resources/db/migration/sqlite/V7__add_diva_session_stage_result_index.sql diff --git a/src/main/java/icu/samnyan/aqua/sega/diva/handler/card/CardProcedureHandler.java b/src/main/java/icu/samnyan/aqua/sega/diva/handler/card/CardProcedureHandler.java index 2e3fd0bc..af78032b 100644 --- a/src/main/java/icu/samnyan/aqua/sega/diva/handler/card/CardProcedureHandler.java +++ b/src/main/java/icu/samnyan/aqua/sega/diva/handler/card/CardProcedureHandler.java @@ -70,6 +70,7 @@ public class CardProcedureHandler extends BaseHandler { LocalDateTime.now(), -1, -1, + -1, profile.getLevel(), profile.getLevelExp(), profile.getLevel(), 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 c30fdc11..5a6ab672 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 @@ -61,44 +61,50 @@ public class StageResultHandler extends BaseHandler { int[] pvIds = request.getStg_ply_pv_id(); int stageIndex = session.getStageIndex(); - // Convert to play log object - PlayLog log = getLog(request, profile, stageIndex); - logger.debug("Stage Result Object: {}", log.toString()); + // Only save to database when stage index is larger than stage result index to prevent duplicate request. + if(stageIndex > session.getStageResultIndex()) { - PlayerPvRecord record = pvRecordRepository.findByPdIdAndPvIdAndEditionAndDifficulty(profile, log.getPvId(), log.getEdition(), log.getDifficulty()) - .orElseGet(() -> new PlayerPvRecord(profile, log.getPvId(), log.getEdition(), log.getDifficulty())); + // Convert to play log object + PlayLog log = getLog(request, profile, stageIndex); + logger.debug("Stage Result Object: {}", log.toString()); - // Update pvRecord field - record.setMaxScore(Math.max(record.getMaxScore(), log.getScore())); - record.setMaxAttain(Math.max(record.getMaxAttain(), log.getAttainPoint())); + PlayerPvRecord record = pvRecordRepository.findByPdIdAndPvIdAndEditionAndDifficulty(profile, log.getPvId(), log.getEdition(), log.getDifficulty()) + .orElseGet(() -> new PlayerPvRecord(profile, log.getPvId(), log.getEdition(), log.getDifficulty())); - if (record.getResult().getValue() < log.getClearResult().getValue()) { - record.setResult(log.getClearResult()); - } + // Update pvRecord field + record.setMaxScore(Math.max(record.getMaxScore(), log.getScore())); + record.setMaxAttain(Math.max(record.getMaxAttain(), log.getAttainPoint())); - 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"; + 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(session.getStageResultIndex() + 1); + + pvRecordRepository.save(record); + playLogRepository.save(log); + gameSessionRepository.save(session); + } - 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()); - - pvRecordRepository.save(record); - playLogRepository.save(log); - gameSessionRepository.save(session); -// profileRepository.save(profile); // Profile save move to session end response = new StageResultResponse( request.getCmd(), diff --git a/src/main/java/icu/samnyan/aqua/sega/diva/handler/ingame/StageStartHandler.java b/src/main/java/icu/samnyan/aqua/sega/diva/handler/ingame/StageStartHandler.java index 4a1da24f..02b3293f 100644 --- a/src/main/java/icu/samnyan/aqua/sega/diva/handler/ingame/StageStartHandler.java +++ b/src/main/java/icu/samnyan/aqua/sega/diva/handler/ingame/StageStartHandler.java @@ -36,9 +36,12 @@ public class StageStartHandler extends BaseHandler { PlayerProfile profile = profileRepository.findByPdId(request.getPd_id()).orElseThrow(ProfileNotFoundException::new); GameSession session = gameSessionRepository.findByPdId(profile).orElseThrow(SessionNotFoundException::new); - session.setStageIndex(session.getStageIndex() + 1); - - gameSessionRepository.save(session); + if(session.getStageResultIndex() <= session.getStageIndex()) { + session.setStageIndex(session.getStageIndex() + 1); + gameSessionRepository.save(session); + } else { + logger.warn("Stage index is greater than stage result index. Maybe due to duplicated request."); + } } BaseResponse response = new BaseResponse( diff --git a/src/main/java/icu/samnyan/aqua/sega/diva/handler/user/PreStartHandler.java b/src/main/java/icu/samnyan/aqua/sega/diva/handler/user/PreStartHandler.java index ca97e721..4ccb5864 100644 --- a/src/main/java/icu/samnyan/aqua/sega/diva/handler/user/PreStartHandler.java +++ b/src/main/java/icu/samnyan/aqua/sega/diva/handler/user/PreStartHandler.java @@ -83,6 +83,7 @@ public class PreStartHandler extends BaseHandler { LocalDateTime.now(), -1, -1, + -1, profile.getLevel(), profile.getLevelExp(), profile.getLevel(), diff --git a/src/main/java/icu/samnyan/aqua/sega/diva/model/userdata/GameSession.java b/src/main/java/icu/samnyan/aqua/sega/diva/model/userdata/GameSession.java index 5ec7ea96..ddfa58d0 100644 --- a/src/main/java/icu/samnyan/aqua/sega/diva/model/userdata/GameSession.java +++ b/src/main/java/icu/samnyan/aqua/sega/diva/model/userdata/GameSession.java @@ -40,6 +40,8 @@ public class GameSession implements Serializable { private Integer stageIndex; + private Integer stageResultIndex; + private Integer lastPvId; private Integer levelNumber; @@ -52,13 +54,14 @@ public class GameSession implements Serializable { private Integer vp; - public GameSession(int acceptId, PlayerProfile pdId, StartMode startMode, LocalDateTime startTime, LocalDateTime lastUpdateTime, Integer stageIndex, Integer lastPvId, Integer levelNumber, Integer levelExp, Integer oldLevelNumber, Integer oldLevelExp, Integer vp) { + public GameSession(int acceptId, PlayerProfile pdId, StartMode startMode, LocalDateTime startTime, LocalDateTime lastUpdateTime, Integer stageIndex, Integer stageResultIndex, Integer lastPvId, Integer levelNumber, Integer levelExp, Integer oldLevelNumber, Integer oldLevelExp, Integer vp) { this.acceptId = acceptId; this.pdId = pdId; this.startMode = startMode; this.startTime = startTime; this.lastUpdateTime = lastUpdateTime; this.stageIndex = stageIndex; + this.stageResultIndex = stageResultIndex; this.lastPvId = lastPvId; this.levelNumber = levelNumber; this.levelExp = levelExp; diff --git a/src/main/resources/db/migration/mysql/V7__add_diva_session_stage_result_index.sql b/src/main/resources/db/migration/mysql/V7__add_diva_session_stage_result_index.sql new file mode 100644 index 00000000..02070a17 --- /dev/null +++ b/src/main/resources/db/migration/mysql/V7__add_diva_session_stage_result_index.sql @@ -0,0 +1,4 @@ +TRUNCATE TABLE `diva_game_session`; + +ALTER TABLE `diva_game_session` + ADD `stage_result_index` int(11) DEFAULT NULL; \ No newline at end of file diff --git a/src/main/resources/db/migration/sqlite/V7__add_diva_session_stage_result_index.sql b/src/main/resources/db/migration/sqlite/V7__add_diva_session_stage_result_index.sql new file mode 100644 index 00000000..79c45303 --- /dev/null +++ b/src/main/resources/db/migration/sqlite/V7__add_diva_session_stage_result_index.sql @@ -0,0 +1,23 @@ +DROP TABLE diva_game_session; + +CREATE TABLE diva_game_session +( + id INTEGER, + accept_id INTEGER NOT NULL, + last_pv_id INTEGER, + last_update_time DATETIME, + level_exp INTEGER, + level_number INTEGER, + old_level_exp INTEGER, + old_level_number INTEGER, + stage_index INTEGER, + stage_result_index INTEGER, + start_mode VARCHAR(255), + start_time DATETIME, + vp INTEGER, + pd_id BIGINT UNIQUE + REFERENCES diva_player_profile (id) ON DELETE CASCADE, + PRIMARY KEY ( + id + ) +); \ No newline at end of file