PaperMC/patches/server/0321-Add-tick-times-API-and-mspt-command.patch
Spottedleaf da9d110d5b Remove chunk save reattempt patch
This patch does not appear to be doing anything useful, and may
hide errors.

Currently, the save logic does not run through this path either
so it did not do anything.

Additionally, properly implement support for handling
RegionFileSizeException in Moonrise.
2024-11-28 18:27:59 -08:00

208 lines
8.4 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
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 72f2e81b9905a0d57ed8e2a88578f62d5235c456..7b58b2d6297800c2dcdbf7539e5ab8e7703f39f1 100644
--- a/src/main/java/io/papermc/paper/command/PaperCommands.java
+++ b/src/main/java/io/papermc/paper/command/PaperCommands.java
@@ -18,6 +18,7 @@ public final class PaperCommands {
static {
COMMANDS.put("paper", new PaperCommand("paper"));
COMMANDS.put("callback", new CallbackCommand("callback"));
+ 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 59bd596a140b4b389c5b73adaab94323759abfc2..e07b25d5e633d2dcc6e9850afd7b8aa0287ec6bc 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -263,6 +263,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
private int playerIdleTimeout;
private final long[] tickTimesNanos;
private long aggregatedTickTimesNanos;
+ // Paper start - Add tick times API and /mspt command
+ public final TickTimes tickTimes5s = new TickTimes(100);
+ public final TickTimes tickTimes10s = new TickTimes(200);
+ public final TickTimes tickTimes60s = new TickTimes(1200);
+ // Paper end - Add tick times API and /mspt command
@Nullable
private KeyPair keyPair;
@Nullable
@@ -1511,6 +1516,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.aggregatedTickTimesNanos += k;
this.tickTimesNanos[l] = k;
this.smoothedTickTimeMillis = this.smoothedTickTimeMillis * 0.8F + (float) k / (float) TimeUtil.NANOSECONDS_PER_MILLISECOND * 0.19999999F;
+ // Paper start - Add tick times API and /mspt command
+ this.tickTimes5s.add(this.tickCount, k);
+ this.tickTimes10s.add(this.tickCount, k);
+ this.tickTimes60s.add(this.tickCount, k);
+ // Paper end - Add tick times API and /mspt command
this.logTickMethodTime(i);
gameprofilerfiller.pop();
}
@@ -2901,4 +2911,30 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public static record ServerResourcePackInfo(UUID id, String url, String hash, boolean isRequired, @Nullable Component prompt) {
}
+
+ // Paper start - Add tick times API and /mspt command
+ 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 - Add tick times API and /mspt command
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 6558fc8c8fc85b3f1e0d77fdc7a2b3937bf3d885..1b80d12515141fb6a6b33475a086d85d437e60a5 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -2714,6 +2714,18 @@ public final class CraftServer implements Server {
return CraftMagicNumbers.INSTANCE;
}
+ // Paper start
+ @Override
+ public long[] getTickTimes() {
+ return this.getServer().tickTimes5s.getTimes();
+ }
+
+ @Override
+ public double getAverageTickTime() {
+ return this.getServer().tickTimes5s.getAverage();
+ }
+ // Paper end
+
// Spigot start
private final org.bukkit.Server.Spigot spigot = new org.bukkit.Server.Spigot()
{