From 46499633d034b1888c6791ba617c9abbb96c01a1 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Wed, 16 Mar 2022 14:56:37 +0100 Subject: [PATCH] Code cleanup, cache invalidation fixes Signed-off-by: Lixfel --- src/de/steamwar/bungeecore/sql/UserElo.java | 168 +++++++++----------- 1 file changed, 75 insertions(+), 93 deletions(-) diff --git a/src/de/steamwar/bungeecore/sql/UserElo.java b/src/de/steamwar/bungeecore/sql/UserElo.java index 42632c87..ca263454 100644 --- a/src/de/steamwar/bungeecore/sql/UserElo.java +++ b/src/de/steamwar/bungeecore/sql/UserElo.java @@ -28,8 +28,7 @@ import java.util.Map; import java.util.Optional; public class UserElo { - private UserElo() { - } + private UserElo() {} public static final int ELO_DEFAULT = 1000; @@ -39,8 +38,9 @@ public class UserElo { private static final Statement elo = new Statement("SELECT Elo FROM UserElo WHERE UserID = ? AND GameMode = ? AND Season = ?"); private static final Statement setElo = new Statement("INSERT INTO UserElo (Season, GameMode, UserID, Elo) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE Elo = VALUES(Elo)"); - private static final Statement place = new Statement("SELECT COUNT(*) AS Place FROM UserElo WHERE GameMode = ? AND Elo > ? AND Season = ?"); private static final Statement maxElo = new Statement("SELECT MAX(Elo) AS MaxElo FROM UserElo WHERE Season = ? AND GameMode = ?"); + + private static final Statement place = new Statement("SELECT COUNT(*) AS Place FROM UserElo WHERE GameMode = ? AND Elo > ? AND Season = ?"); private static final Statement fightsOfSeason = new Statement("SELECT COUNT(*) AS Fights FROM FightPlayer INNER JOIN Fight F on FightPlayer.FightID = F.FightID WHERE UserID = ? AND GameMode = ? AND UNIX_TIMESTAMP(StartTime) + Duration >= UNIX_TIMESTAMP(?)"); public static int getEloOrDefault(int userID, String gameMode) { @@ -48,18 +48,14 @@ public class UserElo { } public static Optional getElo(int userID, String gameMode) { - return gameModeUserEloCache.computeIfAbsent(gameMode, gm -> { - return new HashMap<>(); - }).computeIfAbsent(userID, uid -> { - return elo.select(rs -> { - if (rs.next()) - return Optional.of(rs.getInt("Elo")); - return Optional.empty(); - }, userID, gameMode, Season.getSeason()); - }); + return gameModeUserEloCache.computeIfAbsent(gameMode, gm -> new HashMap<>()).computeIfAbsent(userID, uid -> elo.select(rs -> { + if (rs.next()) + return Optional.of(rs.getInt("Elo")); + return Optional.empty(); + }, userID, gameMode, Season.getSeason())); } - public static int getFightsOfSeason(int userID, String gameMode) { + private static int getFightsOfSeason(int userID, String gameMode) { return fightsOfSeason.select(rs -> { if (rs.next()) return rs.getInt("Fights"); @@ -67,30 +63,24 @@ public class UserElo { }, userID, gameMode, Season.getSeasonStart()); } - public static int getMaxElo(String gameMode) { - return maxEloCache.computeIfAbsent(gameMode, gm -> { - return maxElo.select(rs -> { - if (rs.next()) - return rs.getInt("MaxElo"); - return 0; - }, Season.getSeason(), gameMode); - }); + private static int getMaxElo(String gameMode) { + return maxEloCache.computeIfAbsent(gameMode, gm -> maxElo.select(rs -> { + if (rs.next()) + return rs.getInt("MaxElo"); + return 0; + }, Season.getSeason(), gameMode)); } public static void setElo(int userId, String gameMode, int elo) { emblemCache.remove(userId); - Optional previousElo = gameModeUserEloCache.computeIfAbsent(gameMode, gm -> new HashMap<>()).put(userId, Optional.of(elo)); - int newElo = maxEloCache.compute(gameMode, (gm, max) -> { - if (max == null || max < elo) { - emblemCache.clear(); - return elo; - } - return max; - }); - if (previousElo != null && previousElo.isPresent() && previousElo.get() == newElo) { + + Optional oldElo = Optional.ofNullable(gameModeUserEloCache.computeIfAbsent(gameMode, gm -> new HashMap<>()).put(userId, Optional.of(elo))).orElse(Optional.empty()); + int maxElo = getMaxElo(gameMode); + if (elo > maxElo || (oldElo.isPresent() && oldElo.get() == maxElo)) { maxEloCache.remove(gameMode); emblemCache.clear(); } + setElo.update(Season.getSeason(), gameMode, userId, elo); } @@ -103,86 +93,78 @@ public class UserElo { } public static String getEmblem(SteamwarUser user) { - if (emblemCache.containsKey(user.getId())) { - return emblemCache.get(user.getId()); - } - - int maxEmblemProgression = 0; - int maxEloOfGameMode = 0; - int maxEloOfPlayer = 0; - ArenaMode arenaMode = null; - for (ArenaMode mode : ArenaMode.getAllModes()) { - if (!mode.isRanked()) continue; - if (UserElo.getFightsOfSeason(user.getId(), mode.getSchemType()) < 10) continue; - - Optional currentElo = UserElo.getElo(user.getId(), mode.getSchemType()); - if (currentElo.isPresent()) { - int currentMaxEloOfGameMode = UserElo.getMaxElo(mode.getSchemType()); - int progression = getProgression(currentElo.get(), currentMaxEloOfGameMode); - if (progression > maxEmblemProgression) { - maxEmblemProgression = progression; - maxEloOfGameMode = currentMaxEloOfGameMode; - maxEloOfPlayer = currentElo.get(); - arenaMode = mode; - } + return emblemCache.computeIfAbsent(user.getId(), userId -> { + switch( + ArenaMode.getAllModes().stream().filter( + ArenaMode::isRanked + ).filter( + mode -> UserElo.getFightsOfSeason(user.getId(), mode.getSchemType()) >= 10 + ).map( + mode -> getProgression(user.getId(), mode.getSchemType()) + ).max(Integer::compareTo).orElse(0) + ) { + case 0: + return ""; + case 1: + return "§7✧ "; + case 2: + return "§f✦ "; + case 3: + return "§e✶ "; + case 4: + return "§a✷ "; + case 5: + return "§b✸ "; + case 6: + return "§c✹ "; + case 7: + return "§5❂ "; + default: + throw new SecurityException("Progression out of range"); } - } - - if (arenaMode == null) { - emblemCache.put(user.getId(), ""); - return ""; - } - String emblem = getEmblem(maxEloOfPlayer, maxEloOfGameMode); - emblemCache.put(user.getId(), emblem); - return emblem; - } - - private static String getEmblem(int maxEloOfPlayer, int maxEloOfGameMode) { - if (maxEloOfPlayer > maxEloOfGameMode * 0.99) return "§5❂ "; - if (maxEloOfPlayer > maxEloOfGameMode * 0.97) return "§c✹ "; - if (maxEloOfPlayer > maxEloOfGameMode * 0.94) return "§b✸ "; - if (maxEloOfPlayer > maxEloOfGameMode * 0.88) return "§a✷ "; - if (maxEloOfPlayer > maxEloOfGameMode * 0.76) return "§e✶ "; - if (maxEloOfPlayer > maxEloOfGameMode * 0.51) return "§f✦ "; - return "§7✧ "; + }); } public static String getEmblemProgression(ProxiedPlayer player, String gameMode, int userId) { int fightsOfSeason = getFightsOfSeason(userId, gameMode); - if (fightsOfSeason < 10) { + if (fightsOfSeason < 10) return Message.parse("RANK_NEEDED_FIGHTS_LEFT", player, "§8✧ ✦ ✶ ✷ ✸ ✹ ❂", 10 - fightsOfSeason); - } - Optional currentElo = UserElo.getElo(userId, gameMode); - if (!currentElo.isPresent()) return "§8✧ ✦ ✶ ✷ ✸ ✹ ❂"; - int maxEloOfGameMode = UserElo.getMaxElo(gameMode); - int progression = getProgression(currentElo.get(), maxEloOfGameMode); - switch (progression) { + + switch (getProgression(userId, gameMode)) { case 0: - return "§7✧ §8✦ ✶ ✷ ✸ ✹ ❂"; + return "§8✧ ✦ ✶ ✷ ✸ ✹ ❂"; case 1: - return "§8✧ §f✦ §8✶ ✷ ✸ ✹ ❂"; + return "§7✧ §8✦ ✶ ✷ ✸ ✹ ❂"; case 2: - return "§8✧ ✦ §e✶ §8✷ ✸ ✹ ❂"; + return "§8✧ §f✦ §8✶ ✷ ✸ ✹ ❂"; case 3: - return "§8✧ ✦ ✶ §a✷ §8✸ ✹ ❂"; + return "§8✧ ✦ §e✶ §8✷ ✸ ✹ ❂"; case 4: - return "§8✧ ✦ ✶ ✷ §b✸ §8✹ ❂"; + return "§8✧ ✦ ✶ §a✷ §8✸ ✹ ❂"; case 5: - return "§8✧ ✦ ✶ ✷ ✸ §c✹ §8❂"; + return "§8✧ ✦ ✶ ✷ §b✸ §8✹ ❂"; case 6: + return "§8✧ ✦ ✶ ✷ ✸ §c✹ §8❂"; + case 7: return "§8✧ ✦ ✶ ✷ ✸ ✹ §5❂"; + default: + throw new SecurityException("Progression is not in range"); } - throw new SecurityException("Progression is not in range"); } - private static int getProgression(int maxEloOfPlayer, int maxEloOfGameMode) { - if (maxEloOfPlayer > maxEloOfGameMode * 0.99) return 6; - if (maxEloOfPlayer > maxEloOfGameMode * 0.97) return 5; - if (maxEloOfPlayer > maxEloOfGameMode * 0.94) return 4; - if (maxEloOfPlayer > maxEloOfGameMode * 0.88) return 3; - if (maxEloOfPlayer > maxEloOfGameMode * 0.76) return 2; - if (maxEloOfPlayer > maxEloOfGameMode * 0.51) return 1; - return 0; + private static int getProgression(int userId, String gameMode) { + int elo = UserElo.getElo(userId, gameMode).orElse(0); + if(elo == 0) + return 0; + int maxElo = UserElo.getMaxElo(gameMode); + + if (maxElo > elo * 0.99) return 7; + if (maxElo > elo * 0.97) return 6; + if (maxElo > elo * 0.94) return 5; + if (maxElo > elo * 0.88) return 4; + if (maxElo > elo * 0.76) return 3; + if (maxElo > elo * 0.51) return 2; + return 1; } public static void clearCache() {