Archiviert
1
0

Merge pull request 'Code cleanup, cache invalidation fixes' (#315) from userEloCleanup into master

Reviewed-on: SteamWar/BungeeCore#315
Reviewed-by: YoyoNow <jwsteam@nidido.de>
Dieser Commit ist enthalten in:
Lixfel 2022-03-16 15:05:04 +01:00
Commit aeb78d06c1

Datei anzeigen

@ -28,8 +28,7 @@ import java.util.Map;
import java.util.Optional; import java.util.Optional;
public class UserElo { public class UserElo {
private UserElo() { private UserElo() {}
}
public static final int ELO_DEFAULT = 1000; 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 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 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 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(?)"); 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) { public static int getEloOrDefault(int userID, String gameMode) {
@ -48,18 +48,14 @@ public class UserElo {
} }
public static Optional<Integer> getElo(int userID, String gameMode) { public static Optional<Integer> getElo(int userID, String gameMode) {
return gameModeUserEloCache.computeIfAbsent(gameMode, gm -> { return gameModeUserEloCache.computeIfAbsent(gameMode, gm -> new HashMap<>()).computeIfAbsent(userID, uid -> elo.select(rs -> {
return new HashMap<>(); if (rs.next())
}).computeIfAbsent(userID, uid -> { return Optional.of(rs.getInt("Elo"));
return elo.select(rs -> { return Optional.empty();
if (rs.next()) }, userID, gameMode, Season.getSeason()));
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 -> { return fightsOfSeason.select(rs -> {
if (rs.next()) if (rs.next())
return rs.getInt("Fights"); return rs.getInt("Fights");
@ -67,30 +63,24 @@ public class UserElo {
}, userID, gameMode, Season.getSeasonStart()); }, userID, gameMode, Season.getSeasonStart());
} }
public static int getMaxElo(String gameMode) { private static int getMaxElo(String gameMode) {
return maxEloCache.computeIfAbsent(gameMode, gm -> { return maxEloCache.computeIfAbsent(gameMode, gm -> maxElo.select(rs -> {
return maxElo.select(rs -> { if (rs.next())
if (rs.next()) return rs.getInt("MaxElo");
return rs.getInt("MaxElo"); return 0;
return 0; }, Season.getSeason(), gameMode));
}, Season.getSeason(), gameMode);
});
} }
public static void setElo(int userId, String gameMode, int elo) { public static void setElo(int userId, String gameMode, int elo) {
emblemCache.remove(userId); emblemCache.remove(userId);
Optional<Integer> previousElo = gameModeUserEloCache.computeIfAbsent(gameMode, gm -> new HashMap<>()).put(userId, Optional.of(elo));
int newElo = maxEloCache.compute(gameMode, (gm, max) -> { Optional<Integer> oldElo = Optional.ofNullable(gameModeUserEloCache.computeIfAbsent(gameMode, gm -> new HashMap<>()).put(userId, Optional.of(elo))).orElse(Optional.empty());
if (max == null || max < elo) { int maxElo = getMaxElo(gameMode);
emblemCache.clear(); if (elo > maxElo || (oldElo.isPresent() && oldElo.get() == maxElo)) {
return elo;
}
return max;
});
if (previousElo != null && previousElo.isPresent() && previousElo.get() == newElo) {
maxEloCache.remove(gameMode); maxEloCache.remove(gameMode);
emblemCache.clear(); emblemCache.clear();
} }
setElo.update(Season.getSeason(), gameMode, userId, elo); setElo.update(Season.getSeason(), gameMode, userId, elo);
} }
@ -103,86 +93,78 @@ public class UserElo {
} }
public static String getEmblem(SteamwarUser user) { public static String getEmblem(SteamwarUser user) {
if (emblemCache.containsKey(user.getId())) { return emblemCache.computeIfAbsent(user.getId(), userId -> {
return emblemCache.get(user.getId()); switch(
} ArenaMode.getAllModes().stream().filter(
ArenaMode::isRanked
int maxEmblemProgression = 0; ).filter(
int maxEloOfGameMode = 0; mode -> UserElo.getFightsOfSeason(user.getId(), mode.getSchemType()) >= 10
int maxEloOfPlayer = 0; ).map(
ArenaMode arenaMode = null; mode -> getProgression(user.getId(), mode.getSchemType())
for (ArenaMode mode : ArenaMode.getAllModes()) { ).max(Integer::compareTo).orElse(0)
if (!mode.isRanked()) continue; ) {
if (UserElo.getFightsOfSeason(user.getId(), mode.getSchemType()) < 10) continue; case 0:
return "";
Optional<Integer> currentElo = UserElo.getElo(user.getId(), mode.getSchemType()); case 1:
if (currentElo.isPresent()) { return "§7✧ ";
int currentMaxEloOfGameMode = UserElo.getMaxElo(mode.getSchemType()); case 2:
int progression = getProgression(currentElo.get(), currentMaxEloOfGameMode); return "§f✦ ";
if (progression > maxEmblemProgression) { case 3:
maxEmblemProgression = progression; return "§e✶ ";
maxEloOfGameMode = currentMaxEloOfGameMode; case 4:
maxEloOfPlayer = currentElo.get(); return "§a✷ ";
arenaMode = mode; 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) { public static String getEmblemProgression(ProxiedPlayer player, String gameMode, int userId) {
int fightsOfSeason = getFightsOfSeason(userId, gameMode); int fightsOfSeason = getFightsOfSeason(userId, gameMode);
if (fightsOfSeason < 10) { if (fightsOfSeason < 10)
return Message.parse("RANK_NEEDED_FIGHTS_LEFT", player, "§8✧ ✦ ✶ ✷ ✸ ✹ ❂", 10 - fightsOfSeason); return Message.parse("RANK_NEEDED_FIGHTS_LEFT", player, "§8✧ ✦ ✶ ✷ ✸ ✹ ❂", 10 - fightsOfSeason);
}
Optional<Integer> currentElo = UserElo.getElo(userId, gameMode); switch (getProgression(userId, gameMode)) {
if (!currentElo.isPresent()) return "§8✧ ✦ ✶ ✷ ✸ ✹ ❂";
int maxEloOfGameMode = UserElo.getMaxElo(gameMode);
int progression = getProgression(currentElo.get(), maxEloOfGameMode);
switch (progression) {
case 0: case 0:
return "§7✧ §8✦ ✶ ✷ ✸ ✹ ❂"; return "§8✧ ✦ ✶ ✷ ✸ ✹ ❂";
case 1: case 1:
return "§8✧ §f✦ §8✶ ✷ ✸ ✹ ❂"; return "§7✧ §8✦ ✶ ✷ ✸ ✹ ❂";
case 2: case 2:
return "§8✧ ✦ §e✶ §8✷ ✸ ✹ ❂"; return "§8✧ §f✦ §8✶ ✷ ✸ ✹ ❂";
case 3: case 3:
return "§8✧ ✦ ✶ §a✷ §8✸ ✹ ❂"; return "§8✧ ✦ §e✶ §8✷ ✸ ✹ ❂";
case 4: case 4:
return "§8✧ ✦ ✶ ✷ §b✸ §8✹ ❂"; return "§8✧ ✦ ✶ §a✷ §8✸ ✹ ❂";
case 5: case 5:
return "§8✧ ✦ ✶ ✷ ✸ §c✹ §8"; return "§8✧ ✦ ✶ ✷ §b✸ §8✹ ";
case 6: case 6:
return "§8✧ ✦ ✶ ✷ ✸ §c✹ §8❂";
case 7:
return "§8✧ ✦ ✶ ✷ ✸ ✹ §5❂"; 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) { private static int getProgression(int userId, String gameMode) {
if (maxEloOfPlayer > maxEloOfGameMode * 0.99) return 6; int elo = UserElo.getElo(userId, gameMode).orElse(0);
if (maxEloOfPlayer > maxEloOfGameMode * 0.97) return 5; if(elo == 0)
if (maxEloOfPlayer > maxEloOfGameMode * 0.94) return 4; return 0;
if (maxEloOfPlayer > maxEloOfGameMode * 0.88) return 3; int maxElo = UserElo.getMaxElo(gameMode);
if (maxEloOfPlayer > maxEloOfGameMode * 0.76) return 2;
if (maxEloOfPlayer > maxEloOfGameMode * 0.51) return 1; if (maxElo > elo * 0.99) return 7;
return 0; 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() { public static void clearCache() {