package de.steamwar.lobby.util; import de.steamwar.entity.RArmorStand; import de.steamwar.entity.REntity; import de.steamwar.entity.REntityServer; import de.steamwar.lobby.LobbySystem; import de.steamwar.sql.Leaderboard; import de.steamwar.sql.SteamwarUser; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class LeaderboardManager implements Listener { private final REntityServer server; private final String configKey; private final Location location; private long bestTime; private final List entities = new ArrayList<>(); private final Map playerPlacements = new HashMap<>(); public LeaderboardManager(REntityServer server, String configKey, Location location) { this.server = server; this.configKey = configKey; this.location = location; Bukkit.getPluginManager().registerEvents(this, LobbySystem.getPlugin()); update(); } public void update() { entities.forEach(REntity::die); entities.clear(); List leaderboard = getLeaderboard(); if (leaderboard.isEmpty()) return; bestTime = leaderboard.get(0).getTime(); for (int i = 0; i < leaderboard.size(); i++) { Leaderboard entry = leaderboard.get(i); RArmorStand entity = new RArmorStand(server, location.clone().add(0, (leaderboard.size() - i - 1) * 0.32, 0), RArmorStand.Size.MARKER); SteamwarUser user = SteamwarUser.get(entry.getUserId()); String color = "§7"; if (i == 0) { color = "§6§l"; } else if (i < 3) { color = "§e"; } entity.setDisplayName(calcName(user, color, i + 1, entry.getTime())); entity.setInvisible(true); entities.add(entity); } Bukkit.getOnlinePlayers().forEach(player -> { updatePlayerPlacement(player, SteamwarUser.get(player.getUniqueId())); }); } private void updatePlayerPlacement(Player player, SteamwarUser steamwarUser) { if (server.getEntities().isEmpty()) return; int placement = getPlayerPlacement(steamwarUser); if (placement < 5) { REntityServer entityServer = playerPlacements.remove(steamwarUser.getId()); if (entityServer == null) return; entityServer.getEntities().forEach(rEntity -> rEntity.hide(true)); return; } REntityServer entityServer = playerPlacements.computeIfAbsent(steamwarUser.getId(), ignore -> { REntityServer server = new REntityServer(); server.addPlayer(player); return server; }); List entities = entityServer.getEntities(); RArmorStand entity; if (entities.isEmpty()) { entity = new RArmorStand(entityServer, location.clone().add(0, -2 * 0.32, 0), RArmorStand.Size.MARKER); entity.setInvisible(true); } else { entity = (RArmorStand) entities.get(0); entity.hide(false); } long time = getPlayerTime(steamwarUser); entity.setDisplayName(calcName(steamwarUser, "§f", placement, time)); } private String calcName(SteamwarUser user, String color, int placement, long time) { StringBuilder st = new StringBuilder(); st.append(color); if (placement == Integer.MAX_VALUE) { st.append("???").append(". ").append(user.getUserName()); } else { st.append(placement).append(". ").append(user.getUserName()); } st.append(" §8• ").append(color); if (placement == Integer.MAX_VALUE) { st.append("??:??,???"); } else { st.append(renderTime(time)); } if (time != bestTime && placement != Integer.MAX_VALUE) { st.append(" §8• "); st.append(color).append("+").append(renderShortTime(time - bestTime)); } return st.toString(); } private boolean isNewBestTime(long time) { return time < bestTime; } public void updateBestTime(SteamwarUser user, long time) { Leaderboard.upsert(user.getId(), configKey, time, isNewBestTime(time)); update(); } private List getLeaderboard() { return Leaderboard.getLeaderboard(configKey); } public long getPlayerTime(SteamwarUser user) { Leaderboard lb = Leaderboard.getPlayerTime(user, configKey); if(lb != null) return lb.getTime(); return 0; } private int getPlayerPlacement(SteamwarUser user) { return Leaderboard.getPlayerPlacement(user, configKey); } public static String renderTime(long time) { return String.format( "%d:%02d.%03d", time / 60000, (time / 1000) % 60, time % 1000); } public static String renderShortTime(long time) { return String.format( "%d.%03d", time / 1000, time % 1000); } @EventHandler public void onPlayerJoin(PlayerJoinEvent event) { SteamwarUser steamwarUser = SteamwarUser.get(event.getPlayer().getUniqueId()); updatePlayerPlacement(event.getPlayer(), steamwarUser); } @EventHandler public void onPlayerQuit(PlayerQuitEvent event) { SteamwarUser steamwarUser = SteamwarUser.get(event.getPlayer().getUniqueId()); REntityServer entityServer = playerPlacements.remove(steamwarUser.getId()); if (entityServer == null) return; entityServer.close(); } }