forked from SteamWar/SteamWar
163 lines
5.8 KiB
Java
163 lines
5.8 KiB
Java
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<REntity> entities = new ArrayList<>();
|
|
private final Map<Integer, REntityServer> 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> 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<REntity> 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<Leaderboard> 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();
|
|
}
|
|
}
|