Last active
July 31, 2019 15:46
-
-
Save WouterG/94070d1a2de8e63ed711e8cc43889d17 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import net.md_5.bungee.api.ChatMessageType; | |
import net.md_5.bungee.api.chat.BaseComponent; | |
import net.md_5.bungee.api.chat.TextComponent; | |
import net.menoni.rd.RuntimeDebugger; | |
import net.menoni.rd.model.Debugger; | |
import org.bukkit.Bukkit; | |
import org.bukkit.ChatColor; | |
import org.bukkit.command.CommandSender; | |
import org.bukkit.entity.Player; | |
import org.bukkit.event.EventHandler; | |
import org.bukkit.event.Listener; | |
import org.bukkit.event.player.PlayerMoveEvent; | |
import org.bukkit.scheduler.BukkitTask; | |
import java.util.Map; | |
import java.util.UUID; | |
import java.util.concurrent.ConcurrentHashMap; | |
import java.util.function.Function; | |
public class Speedometer implements Debugger, Debugger.Stoppable, Listener, Runnable { | |
private static Player p; | |
private BukkitTask updateTaskIdle; | |
private Map<UUID, Long> lastUpdateMap = new ConcurrentHashMap<>(); | |
private static Map<Double, SpeedDef> speedDefs = new ConcurrentHashMap<>(); | |
private static SpeedDef defaultSpeedDef = new SpeedDef("Idle", ChatColor.WHITE); | |
private static long fastedSpeedUpdateTime = 0; | |
private static double fastestSpeedLast5Sec = 0.0d; | |
private static class SpeedDefRes { | |
private SpeedDef def; | |
private boolean over; | |
private boolean close; | |
public SpeedDefRes(SpeedDef def, boolean over, boolean close) { | |
this.def = def; | |
this.over = over; | |
this.close = close; | |
} | |
public SpeedDef getDef() { | |
return def; | |
} | |
public boolean isOver() { | |
return over; | |
} | |
public boolean isClose() { | |
return close; | |
} | |
} | |
private static class SpeedDef { | |
private String name; | |
private ChatColor color; | |
private Function<Player, Boolean> condition; | |
public SpeedDef(String name, ChatColor color) { | |
this.name = name; | |
this.color = color; | |
} | |
public SpeedDef(String name, ChatColor color, Function<Player, Boolean> condition) { | |
this.name = name; | |
this.color = color; | |
this.condition = condition; | |
} | |
public String getName() { | |
return name; | |
} | |
public void setName(String name) { | |
this.name = name; | |
} | |
public ChatColor getColor() { | |
return color; | |
} | |
public void setColor(ChatColor color) { | |
this.color = color; | |
} | |
public Function<Player, Boolean> getCondition() { | |
return condition; | |
} | |
public void setCondition(Function<Player, Boolean> condition) { | |
this.condition = condition; | |
} | |
} | |
@Override | |
public void debug(RuntimeDebugger plugin, CommandSender cs) { | |
if (!(cs instanceof Player)) { | |
cs.sendMessage("Need to be player"); | |
return; | |
} | |
this.initSpeedNames(); | |
this.p = (Player) cs; | |
this.updateTaskIdle = Bukkit.getScheduler().runTaskTimer(plugin, this, 4L, 4L); | |
} | |
private void initSpeedNames() { | |
speedDefs.put(0.0d, defaultSpeedDef); | |
speedDefs.put(1.31d, new SpeedDef("Sneaking", ChatColor.GRAY)); | |
speedDefs.put(4.317d, new SpeedDef("Walking", ChatColor.AQUA)); | |
speedDefs.put(5.612d, new SpeedDef("Sprinting", ChatColor.DARK_AQUA)); | |
speedDefs.put(7.0d, new SpeedDef("Minecart", ChatColor.GREEN)); | |
speedDefs.put(8.0d, new SpeedDef("Minecart", ChatColor.DARK_GREEN)); | |
speedDefs.put(11.314d, new SpeedDef("Diagonal Minecart", ChatColor.YELLOW)); | |
speedDefs.put(30.0d, new SpeedDef("0° Elytra Glide", ChatColor.GOLD)); | |
speedDefs.put(33.5d, new SpeedDef("Elytra Rocket Boost", ChatColor.RED)); | |
speedDefs.put(40.0d, new SpeedDef("Ice Boat", ChatColor.DARK_RED)); | |
speedDefs.put(70.0d, new SpeedDef("Blue Ice Boat", ChatColor.DARK_GRAY)); | |
speedDefs.put(67.3d, new SpeedDef("52° Elytra Turbo!", ChatColor.BLACK)); | |
} | |
@Override | |
public void stop() { | |
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) { | |
if (onlinePlayer.getUniqueId().equals(p.getUniqueId())) { | |
onlinePlayer.spigot().sendMessage(ChatMessageType.ACTION_BAR, new TextComponent("")); | |
} | |
} | |
this.updateTaskIdle.cancel(); | |
} | |
@Override | |
public void run() { | |
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) { | |
if (onlinePlayer.getUniqueId().equals(p.getUniqueId())) { | |
Long time = lastUpdateMap.get(onlinePlayer.getUniqueId()); | |
if (time != null && time + 500 > System.currentTimeMillis()) { | |
continue; | |
} | |
p.spigot().sendMessage(ChatMessageType.ACTION_BAR, buildMessage(0d)); | |
} | |
} | |
} | |
@EventHandler | |
public void onPlayerMove(PlayerMoveEvent event) { | |
if (p == null) { | |
return; | |
} | |
if (event.getFrom() == null || event.getTo() == null || event.getPlayer() == null) { | |
return; | |
} | |
// debug | |
if (!event.getPlayer().getUniqueId().equals(p.getUniqueId())) { | |
return; | |
} | |
double speed = getDistanceFast( | |
event.getFrom().getX(), | |
event.getFrom().getY(), | |
event.getFrom().getZ(), | |
event.getTo().getX(), | |
event.getTo().getY(), | |
event.getTo().getZ() | |
); | |
speed *= 20; // blocks per ticks -> seconds | |
event.getPlayer().spigot().sendMessage(ChatMessageType.ACTION_BAR, buildMessage(speed)); | |
lastUpdateMap.put(event.getPlayer().getUniqueId(), System.currentTimeMillis()); | |
} | |
private static SpeedDefRes getSpeedDef(double speed) { | |
double nearestKey = 0; | |
Double closestKey = null; | |
for (Double key : speedDefs.keySet()) { | |
if (key > nearestKey && key <= speed) { | |
nearestKey = key; | |
} | |
if (Math.abs(key - speed) < 0.25) { | |
closestKey = key; | |
} | |
} | |
SpeedDef def = speedDefs.get(nearestKey); | |
def = def == null ? defaultSpeedDef : def; | |
boolean over = false; | |
if (nearestKey < speed) { | |
over = true; | |
} | |
return new SpeedDefRes(def, over, closestKey != null); | |
} | |
public static BaseComponent buildMessage(double speed) { | |
if (fastedSpeedUpdateTime + 5000 < System.currentTimeMillis()) { | |
p.sendMessage("Fastest 5-sec speed: " + fastestSpeedLast5Sec); | |
fastestSpeedLast5Sec = 0; | |
fastedSpeedUpdateTime = System.currentTimeMillis(); | |
} | |
if (speed > fastestSpeedLast5Sec) { | |
fastestSpeedLast5Sec = speed; | |
} | |
SpeedDefRes speedDef = getSpeedDef(speed); | |
TextComponent base = new TextComponent("Speed: "); | |
base.setColor(ChatColor.YELLOW.asBungee()); | |
TextComponent speedPart = new TextComponent(String.format("%.3f", speed)); | |
speedPart.setColor(speedDef.getDef().getColor().asBungee()); | |
base.addExtra(speedPart); | |
TextComponent unitPart = new TextComponent(" b/s"); | |
unitPart.setColor(ChatColor.YELLOW.asBungee()); | |
base.addExtra(unitPart); | |
// if (speedDef.isClose()) { | |
// TextComponent namePart = new TextComponent(" " + speedDef.getDef().getName() + (speedDef.isOver() ? "+" : "")); | |
// namePart.setColor(ChatColor.YELLOW.asBungee()); | |
// base.addExtra(namePart); | |
// } | |
return base; | |
} | |
public static double getDistanceFast(double x1, double y1, double z1, double x2, double y2, double z2) { | |
double dx = (x1 - x2); | |
double dy = (y1 - y2); | |
double dz = (z1 - z2); | |
return Math.sqrt(dx*dx + dy*dy + dz*dz); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment