api: change how scores are stored
Some checks failed
Deploy API / docker (17, 3.8.5) (push) Failing after 34s

This commit is contained in:
Lee 2024-08-02 17:36:24 +01:00
parent 4697cd4aec
commit 96f62d9a01
10 changed files with 118 additions and 30 deletions

@ -1,7 +1,6 @@
package cc.fascinated.controller; package cc.fascinated.controller;
import cc.fascinated.exception.impl.BadRequestException; import cc.fascinated.exception.impl.BadRequestException;
import cc.fascinated.model.user.User;
import cc.fascinated.model.user.UserDTO; import cc.fascinated.model.user.UserDTO;
import cc.fascinated.services.UserService; import cc.fascinated.services.UserService;
import lombok.NonNull; import lombok.NonNull;

@ -11,6 +11,7 @@ import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Document;
import java.util.Date; import java.util.Date;
import java.util.List;
/** /**
* @author Fascinated (fascinated7) * @author Fascinated (fascinated7)
@ -76,7 +77,7 @@ public class Score {
* e.g. 500pp * e.g. 500pp
* </p> * </p>
*/ */
private double pp; private Double pp;
/** /**
* The score of the score. * The score of the score.
@ -91,15 +92,65 @@ public class Score {
/** /**
* The number of misses in the score. * The number of misses in the score.
*/ */
private final int misses; private final Integer misses;
/** /**
* The number of bad cuts in the score. * The number of bad cuts in the score.
*/ */
private final int badCuts; private final Integer badCuts;
/**
* The score history for map the score was set on.
*/
private List<Score> previousScores;
/** /**
* The timestamp of when the score was set. * The timestamp of when the score was set.
*/ */
private final Date timestamp; private final Date timestamp;
/**
* Gets the misses of the score.
*
* @return the misses
*/
public Integer getMisses() {
return misses == null ? 0 : misses;
}
/**
* Gets the bad cuts of the score.
*
* @return the bad cuts
*/
public Integer getBadCuts() {
return badCuts == null ? 0 : badCuts;
}
/**
* Gets the weight of the score.
*
* @return the weight
*/
public Double getPp() {
return pp == null ? 0 : pp;
}
/**
* Gets the modifiers of the score.
*
* @return the modifiers
*/
public String[] getModifiers() {
return modifiers == null ? new String[0] : modifiers;
}
/**
* Gets the previous scores of the score.
*
* @return the previous scores
*/
public List<Score> getPreviousScores() {
return previousScores == null ? List.of() : previousScores;
}
} }

@ -5,6 +5,7 @@ import cc.fascinated.platform.Platform;
import lombok.Getter; import lombok.Getter;
import java.util.Date; import java.util.Date;
import java.util.List;
/** /**
* @author Fascinated (fascinated7) * @author Fascinated (fascinated7)
@ -14,7 +15,7 @@ public class ScoreSaberScore extends Score {
/** /**
* The weight of the score. * The weight of the score.
*/ */
private final double weight; private final Double weight;
/** /**
* The multiplier of the score. * The multiplier of the score.
@ -26,6 +27,16 @@ public class ScoreSaberScore extends Score {
*/ */
private final int maxCombo; private final int maxCombo;
public ScoreSaberScore(long id, String playerId, Platform.Platforms platform, String platformScoreId, String leaderboardId, int rank,
double accuracy, Double pp, int score, String[] modifiers, Integer misses, Integer badCuts, List<Score> previousScores,
Date timestamp, Double weight, double multiplier, int maxCombo) {
super(id, playerId, platform, platformScoreId, leaderboardId, rank, accuracy, pp, score, modifiers, misses,
badCuts, previousScores, timestamp);
this.weight = weight;
this.multiplier = multiplier;
this.maxCombo = maxCombo;
}
/** /**
* Gets the modified score. * Gets the modified score.
* *
@ -38,12 +49,12 @@ public class ScoreSaberScore extends Score {
return (int) (getScore() * multiplier); return (int) (getScore() * multiplier);
} }
public ScoreSaberScore(long id, String playerId, Platform.Platforms platform, String platformScoreId, String leaderboardId, int rank, /**
double accuracy, double pp, int score, String[] modifiers, int misses, int badCuts, Date timestamp, * Gets the weight of the score.
double weight, double multiplier, int maxCombo) { *
super(id, playerId, platform, platformScoreId, leaderboardId, rank, accuracy, pp, score, modifiers, misses, badCuts, timestamp); * @return the weight of the score
this.weight = weight; */
this.multiplier = multiplier; public Double getWeight() {
this.maxCombo = maxCombo; return weight == null ? 0 : weight;
} }
} }

@ -1,12 +1,13 @@
package cc.fascinated.model.score.impl.scoresaber; package cc.fascinated.model.score.impl.scoresaber;
import cc.fascinated.model.leaderboard.Leaderboard; import cc.fascinated.model.leaderboard.Leaderboard;
import cc.fascinated.model.user.User; import cc.fascinated.model.score.Score;
import cc.fascinated.model.user.UserDTO; import cc.fascinated.model.user.UserDTO;
import cc.fascinated.platform.Platform; import cc.fascinated.platform.Platform;
import lombok.Getter; import lombok.Getter;
import java.util.Date; import java.util.Date;
import java.util.List;
/** /**
* @author Fascinated (fascinated7) * @author Fascinated (fascinated7)
@ -24,10 +25,10 @@ public class ScoreSaberScoreResponse extends ScoreSaberScore {
private final Leaderboard leaderboard; private final Leaderboard leaderboard;
public ScoreSaberScoreResponse(long id, String playerId, Platform.Platforms platform, String platformScoreId, String leaderboardId, int rank, public ScoreSaberScoreResponse(long id, String playerId, Platform.Platforms platform, String platformScoreId, String leaderboardId, int rank,
double accuracy, double pp, int score, String[] modifiers, int misses, int badCuts, Date timestamp, double accuracy, double pp, int score, String[] modifiers, int misses, int badCuts, List<Score> previousScores,
double weight, double multiplier, int maxCombo, UserDTO user, Leaderboard leaderboard) { Date timestamp, double weight, double multiplier, int maxCombo, UserDTO user, Leaderboard leaderboard) {
super(id, playerId, platform, platformScoreId, leaderboardId, rank, accuracy, pp, score, modifiers, misses, badCuts, super(id, playerId, platform, platformScoreId, leaderboardId, rank, accuracy, pp, score, modifiers, misses, badCuts,
timestamp, weight, multiplier, maxCombo); previousScores, timestamp, weight, multiplier, maxCombo);
this.user = user; this.user = user;
this.leaderboard = leaderboard; this.leaderboard = leaderboard;
} }

@ -2,7 +2,6 @@ package cc.fascinated.model.user;
import cc.fascinated.common.DateUtils; import cc.fascinated.common.DateUtils;
import cc.fascinated.model.token.ScoreSaberAccountToken; import cc.fascinated.model.token.ScoreSaberAccountToken;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;

@ -1,6 +1,5 @@
package cc.fascinated.model.user; package cc.fascinated.model.user;
import cc.fascinated.common.DateUtils;
import cc.fascinated.model.user.statistic.Statistic; import cc.fascinated.model.user.statistic.Statistic;
import cc.fascinated.platform.Platform; import cc.fascinated.platform.Platform;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;

@ -1,11 +1,7 @@
package cc.fascinated.model.user; package cc.fascinated.model.user;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import java.util.UUID; import java.util.UUID;

@ -33,9 +33,6 @@ import java.util.Map;
public class ScoreSaberPlatform extends Platform { public class ScoreSaberPlatform extends Platform {
/** /**
* The base multiplier for stars. * The base multiplier for stars.
* <p>
* The ScoreSaber star multiplier.
* </p>
*/ */
private final double starMultiplier = 42.117208413; private final double starMultiplier = 42.117208413;

@ -40,6 +40,21 @@ public interface ScoreRepository extends MongoRepository<Score, String> {
}) })
List<Score> getRankedScores(@NonNull Platform.Platforms platform); List<Score> getRankedScores(@NonNull Platform.Platforms platform);
/**
* Gets a score from a platform and leaderboard id.
*
* @param platform the platform to get the score from
* @param playerId the player id to get the score from
* @param leaderboardId the leaderboard id to get the score from
* @return the score
*/
@Aggregation(pipeline = {
"{ $match: { platform: ?0, leaderboardId: ?1, playerId: ?2 } }",
"{ $sort: { pp: -1 } }",
"{ $limit: 1 }"
})
Score findScore(@NonNull Platform.Platforms platform, @NonNull String playerId, @NonNull String leaderboardId);
/** /**
* Updates a scores pp value. * Updates a scores pp value.
* *

@ -21,6 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator;
import java.util.List; import java.util.List;
/** /**
@ -94,6 +95,7 @@ public class ScoreService {
score.getModifiers(), score.getModifiers(),
score.getMisses(), score.getMisses(),
score.getBadCuts(), score.getBadCuts(),
score.getPreviousScores(),
score.getTimestamp(), score.getTimestamp(),
scoreSaberScore.getWeight(), scoreSaberScore.getWeight(),
scoreSaberScore.getMultiplier(), scoreSaberScore.getMultiplier(),
@ -144,6 +146,23 @@ public class ScoreService {
ScoreSaberScoreToken score = token.getScore(); ScoreSaberScoreToken score = token.getScore();
User user = userService.getUser(score.getLeaderboardPlayerInfo().getId()); User user = userService.getUser(score.getLeaderboardPlayerInfo().getId());
Score previousScore = this.scoreRepository.findScore(Platform.Platforms.SCORESABER, user.getSteamId(), leaderboard.getId());
List<Score> previousScores = new ArrayList<>();
if (previousScore != null) { // There is a previous score
if (previousScore.getPreviousScores() != null) {
previousScores.addAll(previousScore.getPreviousScores()); // Add the previous scores
}
previousScore.setPreviousScores(null); // Clear the previous scores
previousScores.add(previousScore); // Add the previous score
// Sort previous scores by timestamp (newest -> oldest)
previousScores.sort(Comparator.comparing(Score::getTimestamp).reversed());
}
// There are no previous scores, so set it to null to save data
if (previousScores.isEmpty()) {
previousScores = null;
}
double accuracy = leaderboard.getMaxScore() != 0 ? ((double) score.getBaseScore() / leaderboard.getMaxScore()) * 100 : 0; double accuracy = leaderboard.getMaxScore() != 0 ? ((double) score.getBaseScore() / leaderboard.getMaxScore()) * 100 : 0;
if (accuracy == 0) { if (accuracy == 0) {
log.warn("[Scoresaber] Leaderboard '{}' has a max score of 0, unable to calculate accuracy :(", leaderboard.getId()); log.warn("[Scoresaber] Leaderboard '{}' has a max score of 0, unable to calculate accuracy :(", leaderboard.getId());
@ -159,13 +178,14 @@ public class ScoreService {
leaderboard.getId(), leaderboard.getId(),
score.getRank(), score.getRank(),
accuracy, accuracy,
pp, pp == 0 ? null : pp, // no pp, set to null to save data
score.getBaseScore(), score.getBaseScore(),
modifiers, modifiers.length == 0 ? null : modifiers, // no modifiers, set to null to save data
score.getMissedNotes(), score.getMissedNotes() == 0 ? null : score.getMissedNotes(), // no misses, set to null to save data
score.getBadCuts(), score.getBadCuts() == 0 ? null : score.getBadCuts(), // no bad cuts, set to null to save data
previousScores,
DateUtils.getDateFromString(score.getTimeSet()), DateUtils.getDateFromString(score.getTimeSet()),
score.getWeight(), score.getWeight() == 0 ? null : score.getWeight(), // no weight, set to null to save data
score.getMultiplier(), score.getMultiplier(),
score.getMaxCombo() score.getMaxCombo()
); );