Add Leaderboard to BoatRace #31
@ -4,6 +4,7 @@ import de.steamwar.entity.REntity;
|
|||||||
import de.steamwar.entity.REntityServer;
|
import de.steamwar.entity.REntityServer;
|
||||||
import de.steamwar.entity.RPlayer;
|
import de.steamwar.entity.RPlayer;
|
||||||
import de.steamwar.lobby.LobbySystem;
|
import de.steamwar.lobby.LobbySystem;
|
||||||
|
import de.steamwar.lobby.util.Leaderboard;
|
||||||
import de.steamwar.sql.UserConfig;
|
import de.steamwar.sql.UserConfig;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@ -24,6 +25,8 @@ import org.bukkit.scheduler.BukkitTask;
|
|||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
import static de.steamwar.lobby.util.Leaderboard.renderTime;
|
||||||
|
|
||||||
public class BoatRace implements EventListener, Listener {
|
public class BoatRace implements EventListener, Listener {
|
||||||
|
|
||||||
private static final double MIN_HEIGHT = 4.3;
|
private static final double MIN_HEIGHT = 4.3;
|
||||||
@ -31,17 +34,20 @@ public class BoatRace implements EventListener, Listener {
|
|||||||
public static final REntityServer boatNpcServer;
|
public static final REntityServer boatNpcServer;
|
||||||
|
|
||||||
private static boolean oneNotStarted = false;
|
private static boolean oneNotStarted = false;
|
||||||
|
private static final Leaderboard leaderboard;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
boatNpcServer = new REntityServer();
|
boatNpcServer = new REntityServer();
|
||||||
new REntity(boatNpcServer, EntityType.VILLAGER, BoatRacePositions.NPC);
|
REntity starter = new REntity(boatNpcServer, EntityType.VILLAGER, BoatRacePositions.NPC);
|
||||||
boatNpcServer.setCallback((player, rEntity, entityAction) -> {
|
boatNpcServer.setCallback((player, rEntity, entityAction) -> {
|
||||||
|
if (rEntity != starter) return;
|
||||||
Bukkit.getWorlds().get(0).getEntities().stream().filter(entity -> entity.getType() == EntityType.ENDER_CRYSTAL).forEach(Entity::remove);
|
Bukkit.getWorlds().get(0).getEntities().stream().filter(entity -> entity.getType() == EntityType.ENDER_CRYSTAL).forEach(Entity::remove);
|
||||||
if (entityAction == REntityServer.EntityAction.INTERACT && !oneNotStarted) {
|
if (entityAction == REntityServer.EntityAction.INTERACT && !oneNotStarted) {
|
||||||
oneNotStarted = true;
|
oneNotStarted = true;
|
||||||
new BoatRace(player);
|
new BoatRace(player);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
leaderboard = new Leaderboard(boatNpcServer, "lobby@boatrace", BoatRacePositions.LEADERBOARD, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Player player;
|
private final Player player;
|
||||||
@ -101,6 +107,7 @@ public class BoatRace implements EventListener, Listener {
|
|||||||
if (time < best) {
|
if (time < best) {
|
||||||
LobbySystem.getMessage().send("BOAT_RACE_NEW_BEST", player);
|
LobbySystem.getMessage().send("BOAT_RACE_NEW_BEST", player);
|
||||||
UserConfig.updatePlayerConfig(player.getUniqueId(), "lobby@boatrace", String.valueOf(time));
|
UserConfig.updatePlayerConfig(player.getUniqueId(), "lobby@boatrace", String.valueOf(time));
|
||||||
|
leaderboard.update();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 1);
|
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 1);
|
||||||
@ -148,12 +155,4 @@ public class BoatRace implements EventListener, Listener {
|
|||||||
|
|
||||||
return p.getLocation().getX() >= x1 && p.getLocation().getY() >= y1 && p.getLocation().getZ() >= z1 && p.getLocation().getX() <= x2 && p.getLocation().getY() <= y2 && p.getLocation().getZ() <= z2;
|
return p.getLocation().getX() >= x1 && p.getLocation().getY() >= y1 && p.getLocation().getZ() >= z1 && p.getLocation().getX() <= x2 && p.getLocation().getY() <= y2 && p.getLocation().getZ() <= z2;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String renderTime(long time) {
|
|
||||||
return String.format(
|
|
||||||
"%d:%02d.%03d",
|
|
||||||
time / 60000,
|
|
||||||
(time / 1000) % 60,
|
|
||||||
time % 1000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
89
src/de/steamwar/lobby/util/Leaderboard.java
Normale Datei
89
src/de/steamwar/lobby/util/Leaderboard.java
Normale Datei
@ -0,0 +1,89 @@
|
|||||||
|
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.SteamwarUser;
|
||||||
|
import de.steamwar.sql.internal.Statement;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class Leaderboard {
|
||||||
|
|
||||||
|
private static final Statement LEADERBOARD = new Statement("SELECT User, CAST(Value as integer) AS Time from UserConfig WHERE Config = ? ORDER BY CAST(Value as integer) LIMIT ?");
|
||||||
|
|
||||||
|
private final REntityServer server;
|
||||||
|
private final String configKey;
|
||||||
|
private final Location location;
|
||||||
|
private final int best;
|
||||||
|
private final List<REntity> entities;
|
||||||
|
|
||||||
|
public Leaderboard(REntityServer server, String configKey, Location location, int best) {
|
||||||
|
this.server = server;
|
||||||
|
this.configKey = configKey;
|
||||||
|
this.location = location;
|
||||||
|
this.best = best;
|
||||||
|
entities = new ArrayList<>(best + 2);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update() {
|
||||||
|
entities.forEach(REntity::die);
|
||||||
|
entities.clear();
|
||||||
|
List<LeaderboardEntry> leaderboard = getLeaderboard();
|
||||||
|
long bestTime = leaderboard.get(0).time;
|
||||||
|
for (int i = 0; i <= best; i++) {
|
||||||
|
if (best - i >= leaderboard.size()) continue;
|
||||||
|
LeaderboardEntry entry = leaderboard.get(best - i);
|
||||||
|
RArmorStand entity = new RArmorStand(server, location.clone().add(0, i * 0.32, 0), RArmorStand.Size.MARKER);
|
||||||
|
SteamwarUser user = SteamwarUser.get(entry.user);
|
||||||
|
if (i == best) {
|
||||||
|
entity.setDisplayName("§6§l" + user.getUserName() + " §8• §6§l" + renderTime(entry.time));
|
||||||
|
} else if (i <= best - 1 && i > best - 3) {
|
||||||
|
entity.setDisplayName("§e" + user.getUserName() + " §8• §e" + renderTime(entry.time) + " §8• §e+" + renderShortTime(entry.time - bestTime));
|
||||||
|
} else {
|
||||||
|
entity.setDisplayName("§7" + user.getUserName() + " §8• §7" + renderTime(entry.time) + " §8• §7+" + renderShortTime(entry.time - bestTime));
|
||||||
|
}
|
||||||
|
entity.setInvisible(true);
|
||||||
|
entities.add(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<LeaderboardEntry> getLeaderboard() {
|
||||||
|
return LEADERBOARD.select(resultSet -> {
|
||||||
|
List<LeaderboardEntry> leaderboard = new ArrayList<>();
|
||||||
|
while (resultSet.next()) {
|
||||||
|
leaderboard.add(new LeaderboardEntry(resultSet.getInt("User"), resultSet.getLong("Time")));
|
||||||
|
}
|
||||||
|
return leaderboard;
|
||||||
|
}, configKey, best);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
private class LeaderboardEntry {
|
||||||
|
|
||||||
|
private final int user;
|
||||||
|
private final long time;
|
||||||
|
}
|
||||||
|
}
|
In neuem Issue referenzieren
Einen Benutzer sperren