[DIVA] Add stage result index to prevent multiple result being sent by client, fix #3

pull/1/head
samnyan 2020-01-23 15:31:32 +08:00
parent b70ec89902
commit ce780b2edb
7 changed files with 77 additions and 36 deletions

View File

@ -70,6 +70,7 @@ public class CardProcedureHandler extends BaseHandler {
LocalDateTime.now(),
-1,
-1,
-1,
profile.getLevel(),
profile.getLevelExp(),
profile.getLevel(),

View File

@ -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(),

View File

@ -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(

View File

@ -83,6 +83,7 @@ public class PreStartHandler extends BaseHandler {
LocalDateTime.now(),
-1,
-1,
-1,
profile.getLevel(),
profile.getLevelExp(),
profile.getLevel(),

View File

@ -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;

View File

@ -0,0 +1,4 @@
TRUNCATE TABLE `diva_game_session`;
ALTER TABLE `diva_game_session`
ADD `stage_result_index` int(11) DEFAULT NULL;

View File

@ -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
)
);