From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 12 Dec 2020 21:19:05 -0600 Subject: [PATCH] Implement TPSBar diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java index a5712108fbbe5ddc61cdfd390f667ab013ba609d..73953ea69776bfe1dcb1504cd14a0f003f1b5766 100644 --- a/src/main/java/net/minecraft/commands/Commands.java +++ b/src/main/java/net/minecraft/commands/Commands.java @@ -201,6 +201,7 @@ public class Commands { net.pl3x.purpur.command.CreditsCommand.register(this.dispatcher); // Purpur net.pl3x.purpur.command.DemoCommand.register(this.dispatcher); // Purpur net.pl3x.purpur.command.PingCommand.register(this.dispatcher); // Purpur + net.pl3x.purpur.command.TPSBarCommand.register(this.dispatcher); // Purpur } if (environment.includeIntegrated) { diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index 214b25f57f15e2127b92ec88117c36d4b2096477..652e596c37bf8d865c954b31ad7d2562b9e95c46 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -1119,6 +1119,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop dispatcher) { + dispatcher.register(Commands.literal("tpsbar") + .requires(listener -> listener.hasPermission(2)) + .executes(context -> execute(context.getSource(), context.getSource().getPlayerOrException())) + ).setPermission("bukkit.command.tpsbar"); + } + + private static int execute(CommandSourceStack source, ServerPlayer player) { + if (player != null) { + TPSBarTask.togglePlayer(player.getBukkitEntity()); + return 1; + } + return 0; + } +} diff --git a/src/main/java/net/pl3x/purpur/task/TPSBarTask.java b/src/main/java/net/pl3x/purpur/task/TPSBarTask.java new file mode 100644 index 0000000000000000000000000000000000000000..12ba7e8a31de9610ca2468a59a28d3f963c5b8f3 --- /dev/null +++ b/src/main/java/net/pl3x/purpur/task/TPSBarTask.java @@ -0,0 +1,183 @@ +package net.pl3x.purpur.task; + +import net.kyori.adventure.bossbar.BossBar; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.Template; +import net.pl3x.purpur.PurpurConfig; +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.scheduler.MinecraftInternalPlugin; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.UUID; + +public class TPSBarTask extends BukkitRunnable { + private static TPSBarTask instance; + private final Map bossbars = new HashMap<>(); + private double tps = 20.0D; + private double mspt = 0.0D; + + private static TPSBarTask instance() { + if (instance == null) { + instance = new TPSBarTask(); + } + return instance; + } + + @Override + public void run() { + this.tps = Math.max(Math.min(Bukkit.getTPS()[0], 20.0D), 0.0D); + this.mspt = Bukkit.getAverageTickTime(); + + Iterator> iter = bossbars.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry entry = iter.next(); + Player player = Bukkit.getPlayer(entry.getKey()); + if (player == null) { + iter.remove(); + continue; + } + updateBossBar(entry.getValue(), player); + } + } + + private void updateBossBar(BossBar bossbar, Player player) { + bossbar.progress(getBossBarProgress()); + bossbar.color(getBossBarColor()); + bossbar.name(MiniMessage.get().parse(PurpurConfig.commandTPSBarTitle, + Template.of("tps", getTPSColor()), + Template.of("mspt", getMSPTColor()), + Template.of("ping", getPingColor(player.getPing())) + )); + } + + private float getBossBarProgress() { + if (PurpurConfig.commandTPSBarProgressFillMode == FillMode.MSPT) { + return Math.max(Math.min((float) mspt / 50.0F, 1.0F), 0.0F); + } else { + return Math.max(Math.min((float) tps / 20.0F, 1.0F), 0.0F); + } + } + + private BossBar.Color getBossBarColor() { + if (isGood(PurpurConfig.commandTPSBarProgressFillMode)) { + return PurpurConfig.commandTPSBarProgressColorGood; + } else if (isMedium(PurpurConfig.commandTPSBarProgressFillMode)) { + return PurpurConfig.commandTPSBarProgressColorMedium; + } else { + return PurpurConfig.commandTPSBarProgressColorLow; + } + } + + private boolean isGood(FillMode mode) { + return isGood(mode, 0); + } + + private boolean isGood(FillMode mode, int ping) { + if (mode == FillMode.MSPT) { + return mspt < 40; + } else if (mode == FillMode.TPS) { + return tps >= 19; + } else if (mode == FillMode.PING) { + return ping < 100; + } else { + return false; + } + } + + private boolean isMedium(FillMode mode) { + return isMedium(mode, 0); + } + + private boolean isMedium(FillMode mode, int ping) { + if (mode == FillMode.MSPT) { + return mspt < 50; + } else if (mode == FillMode.TPS) { + return tps >= 15; + } else if (mode == FillMode.PING) { + return ping < 200; + } else { + return false; + } + } + + private Component getTPSColor() { + String color; + if (isGood(FillMode.TPS)) { + color = PurpurConfig.commandTPSBarTextColorGood; + } else if (isMedium(FillMode.TPS)) { + color = PurpurConfig.commandTPSBarTextColorMedium; + } else { + color = PurpurConfig.commandTPSBarTextColorLow; + } + return MiniMessage.get().parse(color, Template.of("text", String.format("%.2f", tps))); + } + + private Component getMSPTColor() { + String color; + if (isGood(FillMode.MSPT)) { + color = PurpurConfig.commandTPSBarTextColorGood; + } else if (isMedium(FillMode.MSPT)) { + color = PurpurConfig.commandTPSBarTextColorMedium; + } else { + color = PurpurConfig.commandTPSBarTextColorLow; + } + return MiniMessage.get().parse(color, Template.of("text", String.format("%.2f", mspt))); + } + + private Component getPingColor(int ping) { + String color; + if (isGood(FillMode.PING, ping)) { + color = PurpurConfig.commandTPSBarTextColorGood; + } else if (isMedium(FillMode.PING, ping)) { + color = PurpurConfig.commandTPSBarTextColorMedium; + } else { + color = PurpurConfig.commandTPSBarTextColorLow; + } + return MiniMessage.get().parse(color, Template.of("text", String.format("%s", ping))); + } + + @Override + public void cancel() { + super.cancel(); + this.bossbars.clear(); + } + + public static void removePlayer(Player player) { + BossBar bossbar = instance().bossbars.remove(player.getUniqueId()); + if (bossbar != null) { + player.hideBossBar(bossbar); + } + } + + public static void togglePlayer(Player player) { + BossBar bossbar = instance().bossbars.remove(player.getUniqueId()); + if (bossbar != null) { + player.hideBossBar(bossbar); + } else { + bossbar = BossBar.bossBar(Component.text(""), 0.0F, instance().getBossBarColor(), PurpurConfig.commandTPSBarProgressOverlay); + instance().bossbars.put(player.getUniqueId(), bossbar); + instance().updateBossBar(bossbar, player); + player.showBossBar(bossbar); + } + } + + public static void start() { + stop(); + instance().runTaskTimerAsynchronously(new MinecraftInternalPlugin(), 20L, 20L); + } + + public static void stop() { + if (instance != null) { + instance.cancel(); + } + } + + public enum FillMode { + TPS, MSPT, PING + } +}