387 lines
16 KiB
Diff
387 lines
16 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: MrHua269 <wangxyper@163.com>
|
|
Date: Wed, 31 Jul 2024 12:05:39 +0800
|
|
Subject: [PATCH] Add a simple tpsbar
|
|
|
|
|
|
diff --git a/src/main/java/me/earthme/luminol/commands/TpsBarCommand.java b/src/main/java/me/earthme/luminol/commands/TpsBarCommand.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..01677f210fae53a108bfe194189cb4c233e9fa47
|
|
--- /dev/null
|
|
+++ b/src/main/java/me/earthme/luminol/commands/TpsBarCommand.java
|
|
@@ -0,0 +1,50 @@
|
|
+package me.earthme.luminol.commands;
|
|
+
|
|
+import me.earthme.luminol.config.modules.misc.TpsBarConfig;
|
|
+import me.earthme.luminol.functions.GlobalServerTpsBar;
|
|
+import net.kyori.adventure.text.Component;
|
|
+import net.kyori.adventure.text.format.TextColor;
|
|
+import net.kyori.adventure.util.RGBLike;
|
|
+import org.bukkit.ChatColor;
|
|
+import org.bukkit.Color;
|
|
+import org.bukkit.command.Command;
|
|
+import org.bukkit.command.CommandSender;
|
|
+import org.bukkit.entity.Player;
|
|
+import org.jetbrains.annotations.NotNull;
|
|
+
|
|
+public class TpsBarCommand extends Command {
|
|
+ public TpsBarCommand(@NotNull String name) {
|
|
+ super(name);
|
|
+ this.setPermission("luminol.commands.tpsbar");
|
|
+ this.setDescription("Show the tps and mspt through a bossbar");
|
|
+ this.setUsage("/tpsbar");
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) {
|
|
+ if (!testPermission(sender)){
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ if (!TpsBarConfig.tpsbarEnabled){
|
|
+ sender.sendMessage(Component.text("Tpsbar was already disabled!").color(TextColor.color(255,0,0)));
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ if (!(sender instanceof Player player)){
|
|
+ sender.sendMessage(Component.text("Only player can use this command!").color(TextColor.color(255,0,0)));
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ if (GlobalServerTpsBar.isPlayerVisible(player)) {
|
|
+ player.sendMessage(Component.text("Disabled tps bar").color(TextColor.color(0,255,0)));
|
|
+ GlobalServerTpsBar.setVisibilityForPlayer(player,false);
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ player.sendMessage(Component.text("Enabled tps bar").color(TextColor.color(0,255,0)));
|
|
+ GlobalServerTpsBar.setVisibilityForPlayer(player,true);
|
|
+
|
|
+ return true;
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/TpsBarConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/TpsBarConfig.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..aafb2f5052c7c8e5971a47308253badb3027093c
|
|
--- /dev/null
|
|
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/TpsBarConfig.java
|
|
@@ -0,0 +1,49 @@
|
|
+package me.earthme.luminol.config.modules.misc;
|
|
+
|
|
+import com.electronwill.nightconfig.core.file.CommentedFileConfig;
|
|
+import me.earthme.luminol.commands.TpsBarCommand;
|
|
+import me.earthme.luminol.config.*;
|
|
+import me.earthme.luminol.functions.GlobalServerTpsBar;
|
|
+import org.bukkit.Bukkit;
|
|
+
|
|
+import java.util.List;
|
|
+
|
|
+public class TpsBarConfig implements IConfigModule {
|
|
+ @ConfigInfo(baseName = "enabled")
|
|
+ public static boolean tpsbarEnabled = false;
|
|
+ @ConfigInfo(baseName = "format")
|
|
+ public static String tpsBarFormat = "<gray>TPS<yellow>:</yellow> <tps> MSPT<yellow>:</yellow> <mspt> Ping<yellow>:</yellow> <ping>ms";
|
|
+ @ConfigInfo(baseName = "tps_color_list")
|
|
+ public static List<String> tpsColors = List.of("GREEN","YELLOW","RED","PURPLE");
|
|
+ @ConfigInfo(baseName = "ping_color_list")
|
|
+ public static List<String> pingColors = List.of("GREEN","YELLOW","RED","PURPLE");
|
|
+ @ConfigInfo(baseName = "update_interval_ticks")
|
|
+ public static int updateInterval = 15;
|
|
+
|
|
+ @DoNotLoad
|
|
+ private static boolean inited = false;
|
|
+
|
|
+ @Override
|
|
+ public EnumConfigCategory getCategory() {
|
|
+ return EnumConfigCategory.MISC;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public String getBaseName() {
|
|
+ return "tpsbar";
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void onLoaded(CommentedFileConfig configInstance){
|
|
+ if (tpsbarEnabled){
|
|
+ GlobalServerTpsBar.init();
|
|
+ }else{
|
|
+ GlobalServerTpsBar.cancelBarUpdateTask();
|
|
+ }
|
|
+
|
|
+ if (!inited){
|
|
+ Bukkit.getCommandMap().register("tpsbar","luminol",new TpsBarCommand("tpsbar"));
|
|
+ inited = true;
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/me/earthme/luminol/functions/GlobalServerTpsBar.java b/src/main/java/me/earthme/luminol/functions/GlobalServerTpsBar.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..de2f03d6e771c09e8da2da454b7ec4a16c0a17ab
|
|
--- /dev/null
|
|
+++ b/src/main/java/me/earthme/luminol/functions/GlobalServerTpsBar.java
|
|
@@ -0,0 +1,214 @@
|
|
+package me.earthme.luminol.functions;
|
|
+
|
|
+import com.google.common.collect.Maps;
|
|
+import com.mojang.logging.LogUtils;
|
|
+import io.papermc.paper.threadedregions.ThreadedRegionizer;
|
|
+import io.papermc.paper.threadedregions.TickData;
|
|
+import io.papermc.paper.threadedregions.TickRegionScheduler;
|
|
+import io.papermc.paper.threadedregions.TickRegions;
|
|
+import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
|
|
+import me.earthme.luminol.config.modules.misc.TpsBarConfig;
|
|
+import me.earthme.luminol.utils.NullPlugin;
|
|
+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.tag.resolver.Placeholder;
|
|
+import org.bukkit.Bukkit;
|
|
+import org.bukkit.craftbukkit.entity.CraftPlayer;
|
|
+import org.bukkit.entity.Player;
|
|
+import org.jetbrains.annotations.NotNull;
|
|
+import org.slf4j.Logger;
|
|
+
|
|
+import java.util.*;
|
|
+
|
|
+public class GlobalServerTpsBar {
|
|
+ protected static final NullPlugin NULL_PLUGIN = new NullPlugin();
|
|
+ protected static final Map<UUID, BossBar> uuid2Bossbars = Maps.newConcurrentMap();
|
|
+ protected static final Map<UUID, ScheduledTask> scheduledTasks = new HashMap<>();
|
|
+
|
|
+ protected static volatile ScheduledTask scannerTask = null;
|
|
+ private static final Logger logger = LogUtils.getLogger();
|
|
+
|
|
+ public static void init(){
|
|
+ cancelBarUpdateTask();
|
|
+
|
|
+ scannerTask = Bukkit.getGlobalRegionScheduler().runAtFixedRate(NULL_PLUGIN, unused -> {
|
|
+ try {
|
|
+ update();
|
|
+ cleanUp();
|
|
+ }catch (Exception e){
|
|
+ logger.error(e.getLocalizedMessage());
|
|
+ }
|
|
+ }, 1, TpsBarConfig.updateInterval);
|
|
+ }
|
|
+
|
|
+ public static void cancelBarUpdateTask(){
|
|
+ if (scannerTask == null || scannerTask.isCancelled()){
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ scannerTask.cancel();
|
|
+
|
|
+ for (ScheduledTask task : scheduledTasks.values()) {
|
|
+ if (!task.isCancelled()) {
|
|
+ task.cancel();
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public static boolean isPlayerVisible(Player player){
|
|
+ return ((CraftPlayer) player).getHandle().isTpsBarVisible;
|
|
+ }
|
|
+
|
|
+ public static void setVisibilityForPlayer(Player target,boolean canSee){
|
|
+ ((CraftPlayer) target).getHandle().isTpsBarVisible = canSee;
|
|
+ }
|
|
+
|
|
+ private static void update(){
|
|
+ for (Player player : Bukkit.getOnlinePlayers()) {
|
|
+ scheduledTasks.computeIfAbsent(player.getUniqueId(), unused -> createBossBarForPlayer(player));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static void cleanUp() {
|
|
+ final List<UUID> toCleanUp = new ArrayList<>();
|
|
+
|
|
+ for (Map.Entry<UUID, ScheduledTask> toCheck : scheduledTasks.entrySet()) {
|
|
+ if (toCheck.getValue().isCancelled()) {
|
|
+ toCleanUp.add(toCheck.getKey());
|
|
+ }
|
|
+ }
|
|
+
|
|
+ for (UUID uuid : toCleanUp) {
|
|
+ scheduledTasks.remove(uuid);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public static ScheduledTask createBossBarForPlayer(@NotNull Player apiPlayer) {
|
|
+ final UUID playerUUID = apiPlayer.getUniqueId();
|
|
+
|
|
+ return apiPlayer.getScheduler().runAtFixedRate(NULL_PLUGIN, (n) -> {
|
|
+ if (!isPlayerVisible(apiPlayer)) {
|
|
+ final BossBar removed = uuid2Bossbars.remove(playerUUID);
|
|
+
|
|
+ if (removed != null) {
|
|
+ apiPlayer.hideBossBar(removed);
|
|
+ }
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ final ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> region = TickRegionScheduler.getCurrentRegion();
|
|
+ final TickData.TickReportData reportData = region.getData().getRegionSchedulingHandle().getTickReport5s(System.nanoTime());
|
|
+
|
|
+
|
|
+ BossBar targetBossbar = uuid2Bossbars.computeIfAbsent(
|
|
+ playerUUID,
|
|
+ unused -> BossBar.bossBar(Component.text(""),0.0F, BossBar.Color.valueOf(TpsBarConfig.tpsColors.get(3)), BossBar.Overlay.NOTCHED_20)
|
|
+ );
|
|
+
|
|
+ apiPlayer.showBossBar(targetBossbar);
|
|
+
|
|
+ if (reportData != null){
|
|
+ final TickData.SegmentData tpsData = reportData.tpsData().segmentAll();
|
|
+ final double mspt = reportData.timePerTickData().segmentAll().average() / 1.0E6;
|
|
+
|
|
+ updateTpsBar(tpsData.average(), mspt, targetBossbar, apiPlayer);
|
|
+ }
|
|
+ }, () -> {
|
|
+ final BossBar removed = uuid2Bossbars.remove(playerUUID); // Auto clean up it
|
|
+
|
|
+ if (removed != null) {
|
|
+ apiPlayer.hideBossBar(removed);
|
|
+ }
|
|
+ }, 1, TpsBarConfig.updateInterval);
|
|
+ }
|
|
+
|
|
+ private static void updateTpsBar(double tps, double mspt, @NotNull BossBar bar, @NotNull Player player){
|
|
+ bar.name(MiniMessage.miniMessage().deserialize(
|
|
+ TpsBarConfig.tpsBarFormat,
|
|
+ Placeholder.component("tps",getTpsComponent(tps)),
|
|
+ Placeholder.component("mspt",getMsptComponent(mspt)),
|
|
+ Placeholder.component("ping",getPingComponent(player.getPing()))
|
|
+ ));
|
|
+ bar.color(barColorFromTps(tps));
|
|
+ bar.progress((float) Math.min((float)1,Math.max(mspt / 50,0)));
|
|
+ }
|
|
+
|
|
+ private static @NotNull Component getPingComponent(int ping){
|
|
+ final BossBar.Color colorBukkit = barColorFromPing(ping);
|
|
+ final String colorString = colorBukkit.name();
|
|
+
|
|
+ final String content = "<%s><text></%s>";
|
|
+ final String replaced = String.format(content,colorString,colorString);
|
|
+
|
|
+ return MiniMessage.miniMessage().deserialize(replaced,Placeholder.parsed("text", String.valueOf(ping)));
|
|
+ }
|
|
+
|
|
+ private static BossBar.Color barColorFromPing(int ping){
|
|
+ if (ping == -1){
|
|
+ return BossBar.Color.valueOf(TpsBarConfig.pingColors.get(3));
|
|
+ }
|
|
+
|
|
+ if (ping <= 80){
|
|
+ return BossBar.Color.valueOf(TpsBarConfig.pingColors.get(0));
|
|
+ }
|
|
+
|
|
+ if (ping <= 160){
|
|
+ return BossBar.Color.valueOf(TpsBarConfig.pingColors.get(1));
|
|
+ }
|
|
+
|
|
+ return BossBar.Color.valueOf(TpsBarConfig.pingColors.get(2));
|
|
+ }
|
|
+
|
|
+ private static @NotNull Component getMsptComponent(double mspt){
|
|
+ final BossBar.Color colorBukkit = barColorFromMspt(mspt);
|
|
+ final String colorString = colorBukkit.name();
|
|
+
|
|
+ final String content = "<%s><text></%s>";
|
|
+ final String replaced = String.format(content,colorString,colorString);
|
|
+
|
|
+ return MiniMessage.miniMessage().deserialize(replaced,Placeholder.parsed("text", String.format("%.2f", mspt)));
|
|
+ }
|
|
+
|
|
+ private static BossBar.Color barColorFromMspt(double mspt){
|
|
+ if (mspt == -1){
|
|
+ return BossBar.Color.valueOf(TpsBarConfig.tpsColors.get(3));
|
|
+ }
|
|
+
|
|
+ if (mspt <= 25){
|
|
+ return BossBar.Color.valueOf(TpsBarConfig.tpsColors.get(0));
|
|
+ }
|
|
+
|
|
+ if (mspt <= 50){
|
|
+ return BossBar.Color.valueOf(TpsBarConfig.tpsColors.get(1));
|
|
+ }
|
|
+
|
|
+ return BossBar.Color.valueOf(TpsBarConfig.tpsColors.get(2));
|
|
+ }
|
|
+
|
|
+ private static @NotNull Component getTpsComponent(double tps){
|
|
+ final BossBar.Color colorBukkit = barColorFromTps(tps);
|
|
+ final String colorString = colorBukkit.name();
|
|
+
|
|
+ final String content = "<%s><text></%s>";
|
|
+ final String replaced = String.format(content,colorString,colorString);
|
|
+
|
|
+ return MiniMessage.miniMessage().deserialize(replaced,Placeholder.parsed("text", String.format("%.2f", tps)));
|
|
+ }
|
|
+
|
|
+ private static BossBar.Color barColorFromTps(double tps){
|
|
+ if (tps == -1){
|
|
+ return BossBar.Color.valueOf(TpsBarConfig.tpsColors.get(3));
|
|
+ }
|
|
+
|
|
+ if (tps >= 18){
|
|
+ return BossBar.Color.valueOf(TpsBarConfig.tpsColors.get(0));
|
|
+ }
|
|
+
|
|
+ if (tps >= 15){
|
|
+ return BossBar.Color.valueOf(TpsBarConfig.tpsColors.get(1));
|
|
+ }
|
|
+
|
|
+ return BossBar.Color.valueOf(TpsBarConfig.tpsColors.get(2));
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
|
index e3c8deea68ef49bcd07359e243a12afb57cbcf52..279bc6eede3a1ae77b810f0553efe36adeeefaa4 100644
|
|
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
|
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
|
@@ -802,6 +802,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
|
|
|
@Override
|
|
public void stopServer() {
|
|
+ me.earthme.luminol.functions.GlobalServerTpsBar.cancelBarUpdateTask(); //Luminol - Tpsbar
|
|
super.stopServer();
|
|
//Util.shutdownExecutors(); // Paper - moved into super
|
|
SkullBlockEntity.clear();
|
|
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
|
index 23f852ede94bce4d000c8fcaa8fba5d4800b533c..0752d13febc5f1831ae58f7216fba89e1290c780 100644
|
|
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
|
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
|
@@ -327,7 +327,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
|
|
public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent
|
|
public @Nullable String clientBrandName = null; // Paper - Brand support
|
|
public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event
|
|
-
|
|
+ public volatile boolean isTpsBarVisible = false; //Luminol - Tps bar
|
|
// Paper start - rewrite chunk system
|
|
private ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader;
|
|
private final ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.ViewDistanceHolder viewDistanceHolder = new ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.ViewDistanceHolder();
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
|
index b0e93050839ce00b057e3a9bf3bdf8dd5e0662cf..c39e9ea1ce46864623a6d15027ce337611e6b712 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
|
@@ -2414,6 +2414,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
|
handle.expToDrop = data.getInt("expToDrop");
|
|
handle.keepLevel = data.getBoolean("keepLevel");
|
|
}
|
|
+ //Luminol start - Tpsbar
|
|
+ getHandle().isTpsBarVisible = data.getBoolean("tpsbarVisible");
|
|
+ //Luminol end
|
|
}
|
|
}
|
|
|
|
@@ -2435,6 +2438,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
|
data.putLong("lastPlayed", System.currentTimeMillis());
|
|
data.putString("lastKnownName", handle.getScoreboardName());
|
|
|
|
+ //Luminol start - Tpsbar
|
|
+ data.putBoolean("tpsbarVisible",handle.isTpsBarVisible);
|
|
+ //Luminol end
|
|
// Paper start - persist for use in offline save data
|
|
if (!nbttagcompound.contains("Paper")) {
|
|
nbttagcompound.put("Paper", new CompoundTag());
|