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
2021-02-22 10:53:53 +01:00
index 0000000000000000000000000000000000000000..39b236a6319b1f44fbe28bbe43f064be3073e725
2018-03-23 04:19:59 +01:00
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/network/StandardPaperServerListPingEventImpl.java
2021-02-22 10:53:53 +01:00
@@ -0,0 +1,110 @@
2018-03-23 04:19:59 +01:00
+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;
2021-02-22 10:53:53 +01:00
+import io.papermc.paper.adventure.AdventureComponent;
+import java.util.List;
+import java.util.UUID;
+import javax.annotation.Nonnull;
2018-03-23 04:19:59 +01:00
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.server.NetworkManager;
+import net.minecraft.server.PacketStatusOutServerInfo;
+import net.minecraft.server.ServerPing;
+
+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
2021-02-22 10:53:53 +01:00
+ ping.setMOTD(new AdventureComponent(event.motd()));
2018-03-23 04:19:59 +01:00
+
+ // 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
2021-02-16 18:08:29 +01:00
index ee009052eb10125bbaca95b5fda306adbd8a9995..88b45c8b4f58ee83d625408eae08aa329c87a6d4 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
2020-06-25 15:11:48 +02:00
@@ -2,6 +2,9 @@ package net.minecraft.server;
2018-08-26 20:11:49 +02:00
2019-07-20 06:01:24 +02:00
import com.google.common.base.Splitter;
2020-06-25 15:11:48 +02:00
import com.google.common.collect.ImmutableList;
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;
2020-06-25 15:11:48 +02:00
import com.google.common.collect.Sets;
2020-11-07 01:19:04 +01:00
@@ -1119,7 +1122,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
2020-06-25 15:11:48 +02:00
if (i - this.T >= 5000000000L) {
this.T = 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
2020-06-25 15:11:48 +02:00
int j = MathHelper.nextInt(this.r, 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
2021-02-21 20:45:33 +01:00
index 7875d4c08969b3adc6f95504686cc9fe99e3f29a..d0fad346dd4511722f958a8c0bda67492184fb62 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
2020-06-30 07:20:29 +02:00
@@ -35,6 +35,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();
2020-06-30 07:20:29 +02:00
@@ -130,6 +132,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
}
2021-02-22 10:53:53 +01:00
diff --git a/src/main/java/net/minecraft/server/PacketStatusOutServerInfo.java b/src/main/java/net/minecraft/server/PacketStatusOutServerInfo.java
index 50d5fb62efa7c89c7a73ccf072a0e7e433bcc650..f81ed6cd2029bbd8bbf1ddac10851da31273e8dd 100644
--- a/src/main/java/net/minecraft/server/PacketStatusOutServerInfo.java
+++ b/src/main/java/net/minecraft/server/PacketStatusOutServerInfo.java
@@ -2,11 +2,14 @@ package net.minecraft.server;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
+import io.papermc.paper.adventure.AdventureComponent; // Paper
import java.io.IOException;
public class PacketStatusOutServerInfo implements Packet<PacketStatusOutListener> {
- private static final Gson a = (new GsonBuilder()).registerTypeAdapter(ServerPing.ServerData.class, new ServerPing.ServerData.Serializer()).registerTypeAdapter(ServerPing.ServerPingPlayerSample.class, new ServerPing.ServerPingPlayerSample.Serializer()).registerTypeAdapter(ServerPing.class, new ServerPing.Serializer()).registerTypeHierarchyAdapter(IChatBaseComponent.class, new IChatBaseComponent.ChatSerializer()).registerTypeHierarchyAdapter(ChatModifier.class, new ChatModifier.ChatModifierSerializer()).registerTypeAdapterFactory(new ChatTypeAdapterFactory()).create();
+ private static final Gson a = (new GsonBuilder()).registerTypeAdapter(ServerPing.ServerData.class, new ServerPing.ServerData.Serializer()).registerTypeAdapter(ServerPing.ServerPingPlayerSample.class, new ServerPing.ServerPingPlayerSample.Serializer()).registerTypeAdapter(ServerPing.class, new ServerPing.Serializer()).registerTypeHierarchyAdapter(IChatBaseComponent.class, new IChatBaseComponent.ChatSerializer()).registerTypeHierarchyAdapter(ChatModifier.class, new ChatModifier.ChatModifierSerializer()).registerTypeAdapterFactory(new ChatTypeAdapterFactory())
+ .registerTypeAdapter(AdventureComponent.class, new AdventureComponent.Serializer())
+ .create();
private ServerPing b;
public PacketStatusOutServerInfo() {}
2018-03-23 04:19:59 +01:00
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-11-09 02:05:27 +01:00
index bf00d6d263b692e8a597694c689768f177835fde..b830bfefd2984f012de0e3877592e5198a2a02ea 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
2020-11-09 02:05:27 +01:00
@@ -289,7 +289,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
}