Rework async chunk api implementation
Firstly, the old methods all routed to the CompletableFuture method.
However, the CF method could not guarantee that if the caller
was off-main that the future would be "completed" on-main. Since
the callback methods used the CF one, this meant that the callback
methods did not guarantee that the callbacks were to be called on
the main thread.
Now, all methods route to getChunkAtAsync(x, z, gen, urgent, cb)
so that the methods with the callback are guaranteed to invoke
the callback on the main thread. The CF behavior remains unchanged;
it may still appear to complete on main if invoked off-main.
Secondly, remove the scheduleOnMain invocation in the async
chunk completion. This unnecessarily delays the callback
by 1 tick.
Thirdly, add getChunksAtAsync(minX, minZ, maxX, maxZ, ...) which
will load chunks within an area. This method is provided as a helper
as keeping all chunks loaded within an area can be complicated to
implement for plugins (due to the lacking ticket API), and is
already implemented internally anyways.
Fourthly, remove the ticket addition that occured with getChunkAt
and getChunkAtAsync. The ticket addition may delay the unloading
of the chunk unnecessarily. It also fixes a very rare timing bug
where the future/callback would be completed after the chunk
unloads.
2024-11-19 07:34:32 +01:00
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: AlexProgrammerDE <40795980+AlexProgrammerDE@users.noreply.github.com>
Date: Sat, 3 Oct 2020 08:27:40 +0200
Subject: [PATCH] Improve ServerGUI
- Added logo to server frame
- Show tps in the server stats
diff --git a/src/main/java/com/destroystokyo/paper/gui/RAMDetails.java b/src/main/java/com/destroystokyo/paper/gui/RAMDetails.java
index f93373d28d741e1f8a53e07b4e328ce9c4e1657f..12b327eea95e0de9e9c39b7d039badee8ec46508 100644
--- a/src/main/java/com/destroystokyo/paper/gui/RAMDetails.java
+++ b/src/main/java/com/destroystokyo/paper/gui/RAMDetails.java
@@ -58,9 +58,22 @@ public class RAMDetails extends JList<String> {
public void update() {
GraphData data = RAMGraph.DATA.peekLast();
Vector<String> vector = new Vector<>();
+
+ // Follows CraftServer#getTPS
+ double[] tps = new double[] {
+ server.tps1.getAverage(),
+ server.tps5.getAverage(),
+ server.tps15.getAverage()
+ };
+ String[] tpsAvg = new String[tps.length];
+
+ for ( int g = 0; g < tps.length; g++) {
+ tpsAvg[g] = format( tps[g] );
+ }
vector.add("Memory use: " + (data.getUsedMem() / 1024L / 1024L) + " mb (" + (data.getFree() * 100L / data.getMax()) + "% free)");
vector.add("Heap: " + (data.getTotal() / 1024L / 1024L) + " / " + (data.getMax() / 1024L / 1024L) + " mb");
vector.add("Avg tick: " + DECIMAL_FORMAT.format((double)this.server.getAverageTickTimeNanos() / (double) TimeUtil.NANOSECONDS_PER_MILLISECOND) + " ms");
+ vector.add("TPS from last 1m, 5m, 15m: " + String.join(", ", tpsAvg));
setListData(vector);
}
@@ -71,4 +84,8 @@ public class RAMDetails extends JList<String> {
}
return ((double) total / (double) tickTimes.length) * 1.0E-6D;
}
+
+ private static String format(double tps) {
+ return ( ( tps > 21.0 ) ? "*" : "" ) + Math.min( Math.round( tps * 100.0 ) / 100.0, 20.0 );
+ }
}
diff --git a/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java b/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java
index 8b570b0c3967a22c085f390110cb29cbd9c8feff..4d3fe4f56e0b264fa030409919caf52d5f421d46 100644
--- a/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java
+++ b/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java
@@ -59,6 +59,15 @@ public class MinecraftServerGui extends JComponent {
jframe.pack();
jframe.setLocationRelativeTo((Component) null);
jframe.setVisible(true);
+ jframe.setName("Minecraft server"); // Paper - Improve ServerGUI
+
+ // Paper start - Improve ServerGUI
+ try {
+ jframe.setIconImage(javax.imageio.ImageIO.read(Objects.requireNonNull(MinecraftServerGui.class.getClassLoader().getResourceAsStream("logo.png"))));
+ } catch (java.io.IOException ignore) {
+ }
+ // Paper end - Improve ServerGUI
+
jframe.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowevent) {
if (!servergui.isClosing.getAndSet(true)) {
diff --git a/src/main/java/net/minecraft/server/gui/StatsComponent.java b/src/main/java/net/minecraft/server/gui/StatsComponent.java
index 6e9c6d556ed55325e36d191fc9d1508c00879671..096c89bd01cec2abd151bf6fffc4847d1bcd548f 100644
--- a/src/main/java/net/minecraft/server/gui/StatsComponent.java
+++ b/src/main/java/net/minecraft/server/gui/StatsComponent.java
@@ -34,10 +34,19 @@ public class StatsComponent extends JComponent {
private void tick() {
long l = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
+ // Paper start - Improve ServerGUI
+ double[] tps = org.bukkit.Bukkit.getTPS();
+ String[] tpsAvg = new String[tps.length];
+
+ for ( int g = 0; g < tps.length; g++) {
+ tpsAvg[g] = format( tps[g] );
+ }
this.msgs[0] = "Memory use: " + l / 1024L / 1024L + " mb (" + Runtime.getRuntime().freeMemory() * 100L / Runtime.getRuntime().maxMemory() + "% free)";
this.msgs[1] = "Avg tick: "
+ DECIMAL_FORMAT.format((double)this.server.getAverageTickTimeNanos() / (double)TimeUtil.NANOSECONDS_PER_MILLISECOND)
+ " ms";
+ this.msgs[2] = "TPS from last 1m, 5m, 15m: " + String.join(", ", tpsAvg);
+ // Paper end - Improve ServerGUI
this.values[this.vp++ & 0xFF] = (int)(l * 100L / Runtime.getRuntime().maxMemory());
this.repaint();
}
@@ -66,4 +75,10 @@ public class StatsComponent extends JComponent {
public void close() {
this.timer.stop();
}
+
+ // Paper start - Improve ServerGUI
+ private static String format(double tps) {
+ return (( tps > 21.0 ) ? "*" : "") + Math.min(Math.round(tps * 100.0) / 100.0, 20.0); // only print * at 21, we commonly peak to 20.02 as the tick sleep is not accurate enough, stop the noise
+ }
+ // Paper end - Improve ServerGUI
}
diff --git a/src/main/resources/logo.png b/src/main/resources/logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..8b924977b7886df9ab8790b1e4ff9b1c04a2af45
GIT binary patch
literal 16900
2024-11-19 09:59:20 +01:00
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
LFIp>X81%mY^Bg|U
Rework async chunk api implementation
Firstly, the old methods all routed to the CompletableFuture method.
However, the CF method could not guarantee that if the caller
was off-main that the future would be "completed" on-main. Since
the callback methods used the CF one, this meant that the callback
methods did not guarantee that the callbacks were to be called on
the main thread.
Now, all methods route to getChunkAtAsync(x, z, gen, urgent, cb)
so that the methods with the callback are guaranteed to invoke
the callback on the main thread. The CF behavior remains unchanged;
it may still appear to complete on main if invoked off-main.
Secondly, remove the scheduleOnMain invocation in the async
chunk completion. This unnecessarily delays the callback
by 1 tick.
Thirdly, add getChunksAtAsync(minX, minZ, maxX, maxZ, ...) which
will load chunks within an area. This method is provided as a helper
as keeping all chunks loaded within an area can be complicated to
implement for plugins (due to the lacking ticket API), and is
already implemented internally anyways.
Fourthly, remove the ticket addition that occured with getChunkAt
and getChunkAtAsync. The ticket addition may delay the unloading
of the chunk unnecessarily. It also fixes a very rare timing bug
where the future/callback would be completed after the chunk
unloads.
2024-11-19 07:34:32 +01:00
literal 0
HcmV?d00001