2020-05-06 11:48:49 +02:00
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
2018-03-23 04:19:59 +01:00
|
|
|
From: Minecrell <minecrell@minecrell.net>
|
|
|
|
Date: Wed, 11 Oct 2017 15:56:26 +0200
|
|
|
|
Subject: [PATCH] Implement extended PaperServerListPingEvent
|
|
|
|
|
|
|
|
|
|
|
|
diff --git a/src/main/java/com/destroystokyo/paper/network/PaperServerListPingEventImpl.java b/src/main/java/com/destroystokyo/paper/network/PaperServerListPingEventImpl.java
|
|
|
|
new file mode 100644
|
2020-05-06 11:48:49 +02:00
|
|
|
index 0000000000000000000000000000000000000000..c1a8e295b66501e0580bcfc041bca51e69109062
|
2018-03-23 04:19:59 +01:00
|
|
|
--- /dev/null
|
|
|
|
+++ b/src/main/java/com/destroystokyo/paper/network/PaperServerListPingEventImpl.java
|
|
|
|
@@ -0,0 +1,31 @@
|
|
|
|
+package com.destroystokyo.paper.network;
|
|
|
|
+
|
|
|
|
+import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
|
|
|
|
+import net.minecraft.server.EntityPlayer;
|
|
|
|
+import net.minecraft.server.MinecraftServer;
|
|
|
|
+import org.bukkit.entity.Player;
|
|
|
|
+import org.bukkit.util.CachedServerIcon;
|
|
|
|
+
|
|
|
|
+import javax.annotation.Nullable;
|
|
|
|
+
|
|
|
|
+class PaperServerListPingEventImpl extends PaperServerListPingEvent {
|
|
|
|
+
|
|
|
|
+ private final MinecraftServer server;
|
|
|
|
+
|
|
|
|
+ PaperServerListPingEventImpl(MinecraftServer server, StatusClient client, int protocolVersion, @Nullable CachedServerIcon icon) {
|
|
|
|
+ super(client, server.getMotd(), server.getPlayerCount(), server.getMaxPlayers(),
|
|
|
|
+ server.getServerModName() + ' ' + server.getVersion(), protocolVersion, icon);
|
|
|
|
+ this.server = server;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ protected final Object[] getOnlinePlayers() {
|
|
|
|
+ return this.server.getPlayerList().players.toArray();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ protected final Player getBukkitPlayer(Object player) {
|
|
|
|
+ return ((EntityPlayer) player).getBukkitEntity();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
diff --git a/src/main/java/com/destroystokyo/paper/network/PaperStatusClient.java b/src/main/java/com/destroystokyo/paper/network/PaperStatusClient.java
|
|
|
|
new file mode 100644
|
2020-05-06 11:48:49 +02:00
|
|
|
index 0000000000000000000000000000000000000000..a2a409e635dde08f7c53e67164b967a000511e94
|
2018-03-23 04:19:59 +01:00
|
|
|
--- /dev/null
|
|
|
|
+++ b/src/main/java/com/destroystokyo/paper/network/PaperStatusClient.java
|
|
|
|
@@ -0,0 +1,11 @@
|
|
|
|
+package com.destroystokyo.paper.network;
|
|
|
|
+
|
|
|
|
+import net.minecraft.server.NetworkManager;
|
|
|
|
+
|
|
|
|
+class PaperStatusClient extends PaperNetworkClient implements StatusClient {
|
|
|
|
+
|
|
|
|
+ PaperStatusClient(NetworkManager networkManager) {
|
|
|
|
+ super(networkManager);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
diff --git a/src/main/java/com/destroystokyo/paper/network/StandardPaperServerListPingEventImpl.java b/src/main/java/com/destroystokyo/paper/network/StandardPaperServerListPingEventImpl.java
|
|
|
|
new file mode 100644
|
2020-05-06 11:48:49 +02:00
|
|
|
index 0000000000000000000000000000000000000000..a85466bc7e0a8aa54b9eff14077fe6c992ae2902
|
2018-03-23 04:19:59 +01:00
|
|
|
--- /dev/null
|
|
|
|
+++ b/src/main/java/com/destroystokyo/paper/network/StandardPaperServerListPingEventImpl.java
|
|
|
|
@@ -0,0 +1,112 @@
|
|
|
|
+package com.destroystokyo.paper.network;
|
|
|
|
+
|
|
|
|
+import com.destroystokyo.paper.profile.CraftPlayerProfile;
|
|
|
|
+import com.destroystokyo.paper.profile.PlayerProfile;
|
|
|
|
+import com.google.common.base.MoreObjects;
|
|
|
|
+import com.google.common.base.Strings;
|
|
|
|
+import com.mojang.authlib.GameProfile;
|
|
|
|
+import net.minecraft.server.ChatComponentText;
|
|
|
|
+import net.minecraft.server.MinecraftServer;
|
|
|
|
+import net.minecraft.server.NetworkManager;
|
|
|
|
+import net.minecraft.server.PacketStatusOutServerInfo;
|
|
|
|
+import net.minecraft.server.ServerPing;
|
|
|
|
+
|
|
|
|
+import java.util.List;
|
|
|
|
+import java.util.UUID;
|
|
|
|
+
|
|
|
|
+import javax.annotation.Nonnull;
|
|
|
|
+
|
|
|
|
+public final class StandardPaperServerListPingEventImpl extends PaperServerListPingEventImpl {
|
|
|
|
+
|
|
|
|
+ private static final GameProfile[] EMPTY_PROFILES = new GameProfile[0];
|
|
|
|
+ private static final UUID FAKE_UUID = new UUID(0, 0);
|
|
|
|
+
|
|
|
|
+ private GameProfile[] originalSample;
|
|
|
|
+
|
|
|
|
+ private StandardPaperServerListPingEventImpl(MinecraftServer server, NetworkManager networkManager, ServerPing ping) {
|
2019-02-06 20:15:46 +01:00
|
|
|
+ super(server, new PaperStatusClient(networkManager), ping.getServerData() != null ? ping.getServerData().getProtocolVersion() : -1, server.server.getServerIcon());
|
2018-09-23 05:55:30 +02:00
|
|
|
+ this.originalSample = ping.getPlayers() == null ? null : ping.getPlayers().getSample(); // GH-1473 - pre-tick race condition NPE
|
2018-03-23 04:19:59 +01:00
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Nonnull
|
|
|
|
+ @Override
|
|
|
|
+ public List<PlayerProfile> getPlayerSample() {
|
|
|
|
+ List<PlayerProfile> sample = super.getPlayerSample();
|
|
|
|
+
|
|
|
|
+ if (this.originalSample != null) {
|
|
|
|
+ for (GameProfile profile : this.originalSample) {
|
2018-03-23 04:32:55 +01:00
|
|
|
+ sample.add(CraftPlayerProfile.asBukkitCopy(profile));
|
2018-03-23 04:19:59 +01:00
|
|
|
+ }
|
|
|
|
+ this.originalSample = null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return sample;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private GameProfile[] getPlayerSampleHandle() {
|
|
|
|
+ if (this.originalSample != null) {
|
|
|
|
+ return this.originalSample;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ List<PlayerProfile> entries = super.getPlayerSample();
|
|
|
|
+ if (entries.isEmpty()) {
|
|
|
|
+ return EMPTY_PROFILES;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ GameProfile[] profiles = new GameProfile[entries.size()];
|
|
|
|
+ for (int i = 0; i < profiles.length; i++) {
|
|
|
|
+ /*
|
|
|
|
+ * Avoid null UUIDs/names since that will make the response invalid
|
|
|
|
+ * on the client.
|
|
|
|
+ * Instead, fall back to a fake/empty UUID and an empty string as name.
|
|
|
|
+ * This can be used to create custom lines in the player list that do not
|
|
|
|
+ * refer to a specific player.
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+ PlayerProfile profile = entries.get(i);
|
|
|
|
+ if (profile.getId() != null && profile.getName() != null) {
|
|
|
|
+ profiles[i] = CraftPlayerProfile.asAuthlib(profile);
|
|
|
|
+ } else {
|
|
|
|
+ profiles[i] = new GameProfile(MoreObjects.firstNonNull(profile.getId(), FAKE_UUID), Strings.nullToEmpty(profile.getName()));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return profiles;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @SuppressWarnings("deprecation")
|
|
|
|
+ public static void processRequest(MinecraftServer server, NetworkManager networkManager) {
|
|
|
|
+ StandardPaperServerListPingEventImpl event = new StandardPaperServerListPingEventImpl(server, networkManager, server.getServerPing());
|
|
|
|
+ server.server.getPluginManager().callEvent(event);
|
|
|
|
+
|
|
|
|
+ // Close connection immediately if event is cancelled
|
|
|
|
+ if (event.isCancelled()) {
|
|
|
|
+ networkManager.close(null);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Setup response
|
|
|
|
+ ServerPing ping = new ServerPing();
|
|
|
|
+
|
|
|
|
+ // Description
|
|
|
|
+ ping.setMOTD(new ChatComponentText(event.getMotd()));
|
|
|
|
+
|
|
|
|
+ // Players
|
|
|
|
+ if (!event.shouldHidePlayers()) {
|
|
|
|
+ ping.setPlayerSample(new ServerPing.ServerPingPlayerSample(event.getMaxPlayers(), event.getNumPlayers()));
|
|
|
|
+ ping.getPlayers().setSample(event.getPlayerSampleHandle());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Version
|
|
|
|
+ ping.setServerInfo(new ServerPing.ServerData(event.getVersion(), event.getProtocolVersion()));
|
|
|
|
+
|
|
|
|
+ // Favicon
|
|
|
|
+ if (event.getServerIcon() != null) {
|
|
|
|
+ ping.setFavicon(event.getServerIcon().getData());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Send response
|
|
|
|
+ networkManager.sendPacket(new PacketStatusOutServerInfo(ping));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
2020-05-06 11:48:49 +02:00
|
|
|
index 1f2793967045d0bea59e62d9d9d39b03dbdef6c8..c502aedb8dc4e7a5d7ba9d16a200c20ca3d24cd4 100644
|
2018-03-23 04:19:59 +01:00
|
|
|
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
2019-07-20 06:01:24 +02:00
|
|
|
@@ -1,6 +1,9 @@
|
2018-08-26 20:11:49 +02:00
|
|
|
package net.minecraft.server;
|
|
|
|
|
2019-07-20 06:01:24 +02:00
|
|
|
import com.google.common.base.Splitter;
|
2019-06-25 03:47:58 +02:00
|
|
|
+import co.aikar.timings.Timings;
|
2018-08-26 20:11:49 +02:00
|
|
|
+import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
|
2019-06-25 03:47:58 +02:00
|
|
|
+import com.google.common.base.Stopwatch;
|
2018-08-26 20:11:49 +02:00
|
|
|
import com.google.common.collect.Lists;
|
|
|
|
import com.google.common.collect.Maps;
|
2019-06-25 03:47:58 +02:00
|
|
|
import com.google.gson.JsonElement;
|
Improve mid tick chunk loading, Fix Oversleep, other improvements
Process loads outside of any canSleep check. Original intent was to
only apply those restrictions to generations but realized I had some
checks higher up the call chain.
Reworked the back off strategy to just run every 1 millisecond per world,
and to apply the per tick limit to generations only.
This guarantees that your chunk will load with at most around 1ms delay.
Additionally, fire midTick processing in a few more places, notably the
oversleep section so we can keep processing loads here too which has
a large up to 50ms window...
Speaking of oversleep, we had a bug in our implementation changes for
Timings that caused oversleep to not sleep the correct amount.
Because we now moved it into the NEXT tick instead of THIS tick, the
value of nextTick had already been increased to +50ms, resulting in
the risk of sleeping more than it should, but, more importantly, this
caused every task that was trying to NOT run during oversleep to actually
run during oversleep.
This is now fixed.
Another small tweak is to the /tps command, to no longer show the star when
TPS is right at 20.
Due to ineffeciencies in the sleep precision, TPS is commonly 20.02.
This causes the star to show up almost constantly, so now only show it if
we actually hit a real "catchup".
This commit also improves the changes to the CallbackExecutor, in that
it now is also recursion safe.
It was possible that the executor could run tasks out of desired order
if the executor task scheduled more executor tasks.
We solve this by ensuring new additions do not enter the currently iterated queue.
Each depth level will have its own queue.
Fixes #3220
2020-04-26 05:47:29 +02:00
|
|
|
@@ -1092,7 +1095,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
|
2019-07-20 06:01:24 +02:00
|
|
|
if (i - this.Z >= 5000000000L) {
|
|
|
|
this.Z = i;
|
2019-04-28 19:59:47 +02:00
|
|
|
this.serverPing.setPlayerSample(new ServerPing.ServerPingPlayerSample(this.getMaxPlayers(), this.getPlayerCount()));
|
2018-12-17 06:18:06 +01:00
|
|
|
- GameProfile[] agameprofile = new GameProfile[Math.min(this.getPlayerCount(), 12)];
|
|
|
|
+ GameProfile[] agameprofile = new GameProfile[Math.min(this.getPlayerCount(), org.spigotmc.SpigotConfig.playerSample)]; // Paper
|
2019-07-20 06:01:24 +02:00
|
|
|
int j = MathHelper.nextInt(this.q, 0, this.getPlayerCount() - agameprofile.length);
|
2018-03-23 04:19:59 +01:00
|
|
|
|
|
|
|
for (int k = 0; k < agameprofile.length; ++k) {
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/PacketStatusListener.java b/src/main/java/net/minecraft/server/PacketStatusListener.java
|
2020-05-06 11:48:49 +02:00
|
|
|
index 658ea609cb4927b29a3d5303006f2adf2847e06b..4bb21c48bd50353370ec3c3546a00a5d20e4b9d8 100644
|
2018-03-23 04:19:59 +01:00
|
|
|
--- a/src/main/java/net/minecraft/server/PacketStatusListener.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/PacketStatusListener.java
|
2019-07-20 06:01:24 +02:00
|
|
|
@@ -37,6 +37,8 @@ public class PacketStatusListener implements PacketStatusInListener {
|
2018-03-23 04:19:59 +01:00
|
|
|
this.networkManager.close(PacketStatusListener.a);
|
|
|
|
} else {
|
|
|
|
this.d = true;
|
|
|
|
+ // Paper start - Replace everything
|
|
|
|
+ /*
|
|
|
|
// CraftBukkit start
|
|
|
|
// this.networkManager.sendPacket(new PacketStatusOutServerInfo(this.minecraftServer.getServerPing()));
|
|
|
|
final Object[] players = minecraftServer.getPlayerList().players.toArray();
|
2019-07-20 06:01:24 +02:00
|
|
|
@@ -132,6 +134,9 @@ public class PacketStatusListener implements PacketStatusInListener {
|
2018-03-23 04:19:59 +01:00
|
|
|
ping.setServerInfo(new ServerPing.ServerData(minecraftServer.getServerModName() + " " + minecraftServer.getVersion(), version));
|
|
|
|
|
|
|
|
this.networkManager.sendPacket(new PacketStatusOutServerInfo(ping));
|
|
|
|
+ */
|
|
|
|
+ com.destroystokyo.paper.network.StandardPaperServerListPingEventImpl.processRequest(this.minecraftServer, this.networkManager);
|
|
|
|
+ // Paper end
|
|
|
|
}
|
|
|
|
// CraftBukkit end
|
|
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/ServerPing.java b/src/main/java/net/minecraft/server/ServerPing.java
|
2020-05-06 11:48:49 +02:00
|
|
|
index aa125a52dcdf4f137cfe17c5dc808b17d5e9de0b..ea52e89bd965afbd74f15b0e2974657319c28e4a 100644
|
2018-03-23 04:19:59 +01:00
|
|
|
--- a/src/main/java/net/minecraft/server/ServerPing.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/ServerPing.java
|
|
|
|
@@ -29,6 +29,7 @@ public class ServerPing {
|
|
|
|
this.a = ichatbasecomponent;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ public ServerPingPlayerSample getPlayers() { return b(); } // Paper - OBFHELPER
|
|
|
|
public ServerPing.ServerPingPlayerSample b() {
|
|
|
|
return this.b;
|
|
|
|
}
|
2019-01-01 04:15:55 +01:00
|
|
|
@@ -160,10 +161,12 @@ public class ServerPing {
|
2018-03-23 04:19:59 +01:00
|
|
|
return this.b;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ public GameProfile[] getSample() { return c(); } // Paper - OBFHELPER
|
|
|
|
public GameProfile[] c() {
|
|
|
|
return this.c;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ public void setSample(GameProfile[] sample) { a(sample); } // Paper - OBFHELPER
|
|
|
|
public void a(GameProfile[] agameprofile) {
|
|
|
|
this.c = agameprofile;
|
|
|
|
}
|
2018-03-30 18:53:15 +02:00
|
|
|
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
|
2020-05-06 11:48:49 +02:00
|
|
|
index 6d77bbc5aa98ec7c3977b1d36b13c96cc6582e01..1cf214eaca80feae283f6524605976022f856116 100644
|
2018-03-30 18:53:15 +02:00
|
|
|
--- a/src/main/java/org/spigotmc/SpigotConfig.java
|
|
|
|
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
|
2019-08-05 18:35:40 +02:00
|
|
|
@@ -285,7 +285,7 @@ public class SpigotConfig
|
2018-03-30 18:53:15 +02:00
|
|
|
public static int playerSample;
|
|
|
|
private static void playerSample()
|
|
|
|
{
|
|
|
|
- playerSample = getInt( "settings.sample-count", 12 );
|
2019-04-28 19:59:47 +02:00
|
|
|
+ playerSample = Math.max( getInt( "settings.sample-count", 12 ), 0 ); // Paper - Avoid negative counts
|
2018-03-30 18:53:15 +02:00
|
|
|
Bukkit.getLogger().log( Level.INFO, "Server Ping Player Sample Count: {0}", playerSample ); // Paper - Use logger
|
|
|
|
}
|
|
|
|
|