summaryrefslogtreecommitdiffhomepage
path: root/patches/server/0373-Add-tick-times-API-and-mspt-command.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/server/0373-Add-tick-times-API-and-mspt-command.patch')
-rw-r--r--patches/server/0373-Add-tick-times-API-and-mspt-command.patch207
1 files changed, 207 insertions, 0 deletions
diff --git a/patches/server/0373-Add-tick-times-API-and-mspt-command.patch b/patches/server/0373-Add-tick-times-API-and-mspt-command.patch
new file mode 100644
index 0000000000..812faa072a
--- /dev/null
+++ b/patches/server/0373-Add-tick-times-API-and-mspt-command.patch
@@ -0,0 +1,207 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: William Blake Galbreath <[email protected]>
+Date: Sun, 5 Apr 2020 22:23:14 -0500
+Subject: [PATCH] Add tick times API and /mspt command
+
+
+diff --git a/src/main/java/io/papermc/paper/command/MSPTCommand.java b/src/main/java/io/papermc/paper/command/MSPTCommand.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..8b5293b0c696ef21d0101493ffa41b60bf0bc86b
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/command/MSPTCommand.java
+@@ -0,0 +1,102 @@
++package io.papermc.paper.command;
++
++import net.kyori.adventure.text.Component;
++import net.minecraft.server.MinecraftServer;
++import org.bukkit.Location;
++import org.bukkit.command.Command;
++import org.bukkit.command.CommandSender;
++
++import java.text.DecimalFormat;
++import java.util.ArrayList;
++import java.util.Arrays;
++import java.util.Collections;
++import java.util.List;
++import org.checkerframework.checker.nullness.qual.NonNull;
++import org.checkerframework.framework.qual.DefaultQualifier;
++
++import static net.kyori.adventure.text.Component.text;
++import static net.kyori.adventure.text.format.NamedTextColor.GOLD;
++import static net.kyori.adventure.text.format.NamedTextColor.GRAY;
++import static net.kyori.adventure.text.format.NamedTextColor.GREEN;
++import static net.kyori.adventure.text.format.NamedTextColor.RED;
++import static net.kyori.adventure.text.format.NamedTextColor.YELLOW;
++
++@DefaultQualifier(NonNull.class)
++public final class MSPTCommand extends Command {
++ private static final DecimalFormat DF = new DecimalFormat("########0.0");
++ private static final Component SLASH = text("/");
++
++ public MSPTCommand(final String name) {
++ super(name);
++ this.description = "View server tick times";
++ this.usageMessage = "/mspt";
++ this.setPermission("bukkit.command.mspt");
++ }
++
++ @Override
++ public List<String> tabComplete(CommandSender sender, String alias, String[] args, Location location) throws IllegalArgumentException {
++ return Collections.emptyList();
++ }
++
++ @Override
++ public boolean execute(CommandSender sender, String commandLabel, String[] args) {
++ if (!testPermission(sender)) return true;
++
++ MinecraftServer server = MinecraftServer.getServer();
++
++ List<Component> times = new ArrayList<>();
++ times.addAll(eval(server.tickTimes5s.getTimes()));
++ times.addAll(eval(server.tickTimes10s.getTimes()));
++ times.addAll(eval(server.tickTimes60s.getTimes()));
++
++ sender.sendMessage(text().content("Server tick times ").color(GOLD)
++ .append(text().color(YELLOW)
++ .append(
++ text("("),
++ text("avg", GRAY),
++ text("/"),
++ text("min", GRAY),
++ text("/"),
++ text("max", GRAY),
++ text(")")
++ )
++ ).append(
++ text(" from last 5s"),
++ text(",", GRAY),
++ text(" 10s"),
++ text(",", GRAY),
++ text(" 1m"),
++ text(":", YELLOW)
++ )
++ );
++ sender.sendMessage(text().content("◴ ").color(GOLD)
++ .append(text().color(GRAY)
++ .append(
++ times.get(0), SLASH, times.get(1), SLASH, times.get(2), text(", ", YELLOW),
++ times.get(3), SLASH, times.get(4), SLASH, times.get(5), text(", ", YELLOW),
++ times.get(6), SLASH, times.get(7), SLASH, times.get(8)
++ )
++ )
++ );
++ return true;
++ }
++
++ private static List<Component> eval(long[] times) {
++ long min = Integer.MAX_VALUE;
++ long max = 0L;
++ long total = 0L;
++ for (long value : times) {
++ if (value > 0L && value < min) min = value;
++ if (value > max) max = value;
++ total += value;
++ }
++ double avgD = ((double) total / (double) times.length) * 1.0E-6D;
++ double minD = ((double) min) * 1.0E-6D;
++ double maxD = ((double) max) * 1.0E-6D;
++ return Arrays.asList(getColor(avgD), getColor(minD), getColor(maxD));
++ }
++
++ private static Component getColor(double avg) {
++ return text(DF.format(avg), avg >= 50 ? RED : avg >= 40 ? YELLOW : GREEN);
++ }
++}
+diff --git a/src/main/java/io/papermc/paper/command/PaperCommands.java b/src/main/java/io/papermc/paper/command/PaperCommands.java
+index 6a00f3d38da8107825ab1d405f337fd077b09f72..d31b5ed47cffc61c90c926a0cd2005b72ebddfc5 100644
+--- a/src/main/java/io/papermc/paper/command/PaperCommands.java
++++ b/src/main/java/io/papermc/paper/command/PaperCommands.java
+@@ -17,6 +17,7 @@ public final class PaperCommands {
+ private static final Map<String, Command> COMMANDS = new HashMap<>();
+ static {
+ COMMANDS.put("paper", new PaperCommand("paper"));
++ COMMANDS.put("mspt", new MSPTCommand("mspt"));
+ }
+
+ public static void registerCommands(final MinecraftServer server) {
+diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
+index b04c5433a1e2cdfe69c5b5cbe77b867ebd55c126..d8166025ddd229c065e8c4c3082549f1716c0384 100644
+--- a/src/main/java/net/minecraft/server/MinecraftServer.java
++++ b/src/main/java/net/minecraft/server/MinecraftServer.java
+@@ -237,6 +237,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+ @Nullable private net.kyori.adventure.text.Component cachedMotd; // Paper
+ private int playerIdleTimeout;
+ public final long[] tickTimes;
++ // Paper start
++ public final TickTimes tickTimes5s = new TickTimes(100);
++ public final TickTimes tickTimes10s = new TickTimes(200);
++ public final TickTimes tickTimes60s = new TickTimes(1200);
++ // Paper end
+ @Nullable
+ private KeyPair keyPair;
+ @Nullable
+@@ -1360,6 +1365,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+ this.averageTickTime = this.averageTickTime * 0.8F + (float) l / 1000000.0F * 0.19999999F;
+ long i1 = Util.getNanos();
+
++ // Paper start
++ tickTimes5s.add(this.tickCount, l);
++ tickTimes10s.add(this.tickCount, l);
++ tickTimes60s.add(this.tickCount, l);
++ // Paper end
++
+ this.frameTimer.logFrameDuration(i1 - i);
+ this.profiler.pop();
+ org.spigotmc.WatchdogThread.tick(); // Spigot
+@@ -2529,4 +2540,30 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+ public static record ServerResourcePackInfo(String url, String hash, boolean isRequired, @Nullable Component prompt) {
+
+ }
++
++ // Paper start
++ public static class TickTimes {
++ private final long[] times;
++
++ public TickTimes(int length) {
++ times = new long[length];
++ }
++
++ void add(int index, long time) {
++ times[index % times.length] = time;
++ }
++
++ public long[] getTimes() {
++ return times.clone();
++ }
++
++ public double getAverage() {
++ long total = 0L;
++ for (long value : times) {
++ total += value;
++ }
++ return ((double) total / (double) times.length) * 1.0E-6D;
++ }
++ }
++ // Paper end
+ }
+diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+index 08dad640ae4315d0746587d91deb4709231c2bcc..1043271c20d092e3133855335eaf75d9d533d984 100644
+--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
++++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+@@ -2478,6 +2478,16 @@ public final class CraftServer implements Server {
+ net.minecraft.server.MinecraftServer.getServer().tps15.getAverage()
+ };
+ }
++
++ @Override
++ public long[] getTickTimes() {
++ return getServer().tickTimes5s.getTimes();
++ }
++
++ @Override
++ public double getAverageTickTime() {
++ return getServer().tickTimes5s.getAverage();
++ }
+ // Paper end
+
+ // Spigot start