diff --git a/API/src/main/java/cc/fascinated/controller/UserController.java b/API/src/main/java/cc/fascinated/controller/UserController.java index e2f9f5b..53e8ce6 100644 --- a/API/src/main/java/cc/fascinated/controller/UserController.java +++ b/API/src/main/java/cc/fascinated/controller/UserController.java @@ -1,7 +1,6 @@ package cc.fascinated.controller; import cc.fascinated.exception.impl.BadRequestException; -import cc.fascinated.model.user.User; import cc.fascinated.model.user.UserDTO; import cc.fascinated.services.UserService; import lombok.NonNull; diff --git a/API/src/main/java/cc/fascinated/model/score/Score.java b/API/src/main/java/cc/fascinated/model/score/Score.java index b927666..f8b2930 100644 --- a/API/src/main/java/cc/fascinated/model/score/Score.java +++ b/API/src/main/java/cc/fascinated/model/score/Score.java @@ -11,6 +11,7 @@ import org.springframework.data.mongodb.core.index.Indexed; import org.springframework.data.mongodb.core.mapping.Document; import java.util.Date; +import java.util.List; /** * @author Fascinated (fascinated7) @@ -76,7 +77,7 @@ public class Score { * e.g. 500pp *

*/ - private double pp; + private Double pp; /** * The score of the score. @@ -91,15 +92,65 @@ public class Score { /** * The number of misses in the score. */ - private final int misses; + private final Integer misses; /** * 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 previousScores; /** * The timestamp of when the score was set. */ 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 getPreviousScores() { + return previousScores == null ? List.of() : previousScores; + } } diff --git a/API/src/main/java/cc/fascinated/model/score/impl/scoresaber/ScoreSaberScore.java b/API/src/main/java/cc/fascinated/model/score/impl/scoresaber/ScoreSaberScore.java index 8905f45..b0f4fc1 100644 --- a/API/src/main/java/cc/fascinated/model/score/impl/scoresaber/ScoreSaberScore.java +++ b/API/src/main/java/cc/fascinated/model/score/impl/scoresaber/ScoreSaberScore.java @@ -5,6 +5,7 @@ import cc.fascinated.platform.Platform; import lombok.Getter; import java.util.Date; +import java.util.List; /** * @author Fascinated (fascinated7) @@ -14,7 +15,7 @@ public class ScoreSaberScore extends Score { /** * The weight of the score. */ - private final double weight; + private final Double weight; /** * The multiplier of the score. @@ -26,6 +27,16 @@ public class ScoreSaberScore extends Score { */ 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 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. * @@ -38,12 +49,12 @@ public class ScoreSaberScore extends Score { 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, - double weight, double multiplier, int maxCombo) { - super(id, playerId, platform, platformScoreId, leaderboardId, rank, accuracy, pp, score, modifiers, misses, badCuts, timestamp); - this.weight = weight; - this.multiplier = multiplier; - this.maxCombo = maxCombo; + /** + * Gets the weight of the score. + * + * @return the weight of the score + */ + public Double getWeight() { + return weight == null ? 0 : weight; } } diff --git a/API/src/main/java/cc/fascinated/model/score/impl/scoresaber/ScoreSaberScoreResponse.java b/API/src/main/java/cc/fascinated/model/score/impl/scoresaber/ScoreSaberScoreResponse.java index 200af92..6f5759c 100644 --- a/API/src/main/java/cc/fascinated/model/score/impl/scoresaber/ScoreSaberScoreResponse.java +++ b/API/src/main/java/cc/fascinated/model/score/impl/scoresaber/ScoreSaberScoreResponse.java @@ -1,12 +1,13 @@ package cc.fascinated.model.score.impl.scoresaber; 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.platform.Platform; import lombok.Getter; import java.util.Date; +import java.util.List; /** * @author Fascinated (fascinated7) @@ -24,10 +25,10 @@ public class ScoreSaberScoreResponse extends ScoreSaberScore { private final Leaderboard leaderboard; 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 weight, double multiplier, int maxCombo, UserDTO user, Leaderboard leaderboard) { + double accuracy, double pp, int score, String[] modifiers, int misses, int badCuts, List previousScores, + 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, - timestamp, weight, multiplier, maxCombo); + previousScores, timestamp, weight, multiplier, maxCombo); this.user = user; this.leaderboard = leaderboard; } diff --git a/API/src/main/java/cc/fascinated/model/user/ScoreSaberAccount.java b/API/src/main/java/cc/fascinated/model/user/ScoreSaberAccount.java index c44d99d..86c77c6 100644 --- a/API/src/main/java/cc/fascinated/model/user/ScoreSaberAccount.java +++ b/API/src/main/java/cc/fascinated/model/user/ScoreSaberAccount.java @@ -2,7 +2,6 @@ package cc.fascinated.model.user; import cc.fascinated.common.DateUtils; import cc.fascinated.model.token.ScoreSaberAccountToken; -import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/API/src/main/java/cc/fascinated/model/user/User.java b/API/src/main/java/cc/fascinated/model/user/User.java index 2fbaa3a..f8fda70 100644 --- a/API/src/main/java/cc/fascinated/model/user/User.java +++ b/API/src/main/java/cc/fascinated/model/user/User.java @@ -1,6 +1,5 @@ package cc.fascinated.model.user; -import cc.fascinated.common.DateUtils; import cc.fascinated.model.user.statistic.Statistic; import cc.fascinated.platform.Platform; import com.fasterxml.jackson.annotation.JsonIgnore; diff --git a/API/src/main/java/cc/fascinated/model/user/UserDTO.java b/API/src/main/java/cc/fascinated/model/user/UserDTO.java index ce326e6..3bd8849 100644 --- a/API/src/main/java/cc/fascinated/model/user/UserDTO.java +++ b/API/src/main/java/cc/fascinated/model/user/UserDTO.java @@ -1,11 +1,7 @@ package cc.fascinated.model.user; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; import lombok.Getter; -import org.springframework.data.annotation.Id; -import org.springframework.data.mongodb.core.index.Indexed; import java.util.UUID; diff --git a/API/src/main/java/cc/fascinated/platform/impl/ScoreSaberPlatform.java b/API/src/main/java/cc/fascinated/platform/impl/ScoreSaberPlatform.java index 51d4341..bb058cb 100644 --- a/API/src/main/java/cc/fascinated/platform/impl/ScoreSaberPlatform.java +++ b/API/src/main/java/cc/fascinated/platform/impl/ScoreSaberPlatform.java @@ -33,9 +33,6 @@ import java.util.Map; public class ScoreSaberPlatform extends Platform { /** * The base multiplier for stars. - *

- * The ScoreSaber star multiplier. - *

*/ private final double starMultiplier = 42.117208413; diff --git a/API/src/main/java/cc/fascinated/repository/ScoreRepository.java b/API/src/main/java/cc/fascinated/repository/ScoreRepository.java index bb57a75..1dcc19c 100644 --- a/API/src/main/java/cc/fascinated/repository/ScoreRepository.java +++ b/API/src/main/java/cc/fascinated/repository/ScoreRepository.java @@ -40,6 +40,21 @@ public interface ScoreRepository extends MongoRepository { }) List 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. * diff --git a/API/src/main/java/cc/fascinated/services/ScoreService.java b/API/src/main/java/cc/fascinated/services/ScoreService.java index 1f5f25a..055fc0b 100644 --- a/API/src/main/java/cc/fascinated/services/ScoreService.java +++ b/API/src/main/java/cc/fascinated/services/ScoreService.java @@ -21,6 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; /** @@ -94,6 +95,7 @@ public class ScoreService { score.getModifiers(), score.getMisses(), score.getBadCuts(), + score.getPreviousScores(), score.getTimestamp(), scoreSaberScore.getWeight(), scoreSaberScore.getMultiplier(), @@ -144,6 +146,23 @@ public class ScoreService { ScoreSaberScoreToken score = token.getScore(); User user = userService.getUser(score.getLeaderboardPlayerInfo().getId()); + Score previousScore = this.scoreRepository.findScore(Platform.Platforms.SCORESABER, user.getSteamId(), leaderboard.getId()); + List 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; if (accuracy == 0) { 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(), score.getRank(), accuracy, - pp, + pp == 0 ? null : pp, // no pp, set to null to save data score.getBaseScore(), - modifiers, - score.getMissedNotes(), - score.getBadCuts(), + modifiers.length == 0 ? null : modifiers, // no modifiers, set to null to save data + score.getMissedNotes() == 0 ? null : score.getMissedNotes(), // no misses, set to null to save data + score.getBadCuts() == 0 ? null : score.getBadCuts(), // no bad cuts, set to null to save data + previousScores, DateUtils.getDateFromString(score.getTimeSet()), - score.getWeight(), + score.getWeight() == 0 ? null : score.getWeight(), // no weight, set to null to save data score.getMultiplier(), score.getMaxCombo() );