Skip to content
This repository was archived by the owner on Dec 29, 2023. It is now read-only.

Commit eef22db

Browse files
committed
Fix ClassClassException in PaperServerListPingEvent and support PaperLegacyStatusClient
1 parent 6f7b82e commit eef22db

File tree

1 file changed

+297
-0
lines changed

1 file changed

+297
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,297 @@
1+
From 8502036c65b7ca9e7e0ecdecfd323b3210dafef7 Mon Sep 17 00:00:00 2001
2+
From: Peridot <[email protected]>
3+
Date: Thu, 22 Sep 2022 22:22:11 +0200
4+
Subject: [PATCH] Fix ClassClassException in PaperServerListPingEvent and
5+
support PaperLegacyStatusClient
6+
7+
8+
diff --git a/src/main/java/com/destroystokyo/paper/network/PaperLegacyStatusClient.java b/src/main/java/com/destroystokyo/paper/network/PaperLegacyStatusClient.java
9+
new file mode 100644
10+
index 000000000..532c75160
11+
--- /dev/null
12+
+++ b/src/main/java/com/destroystokyo/paper/network/PaperLegacyStatusClient.java
13+
@@ -0,0 +1,71 @@
14+
+package com.destroystokyo.paper.network;
15+
+
16+
+import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
17+
+import java.net.InetSocketAddress;
18+
+import javax.annotation.Nullable;
19+
+import net.minecraft.server.MinecraftServer;
20+
+import org.apache.commons.lang3.StringUtils;
21+
+import org.bukkit.ChatColor;
22+
+
23+
+public final class PaperLegacyStatusClient implements StatusClient {
24+
+
25+
+ private final InetSocketAddress address;
26+
+ private final int protocolVersion;
27+
+ @Nullable private final InetSocketAddress virtualHost;
28+
+
29+
+ private PaperLegacyStatusClient(InetSocketAddress address, int protocolVersion, @Nullable InetSocketAddress virtualHost) {
30+
+ this.address = address;
31+
+ this.protocolVersion = protocolVersion;
32+
+ this.virtualHost = virtualHost;
33+
+ }
34+
+
35+
+ @Override
36+
+ public InetSocketAddress getAddress() {
37+
+ return this.address;
38+
+ }
39+
+
40+
+ @Override
41+
+ public int getProtocolVersion() {
42+
+ return this.protocolVersion;
43+
+ }
44+
+
45+
+ @Nullable
46+
+ @Override
47+
+ public InetSocketAddress getVirtualHost() {
48+
+ return this.virtualHost;
49+
+ }
50+
+
51+
+ @Override
52+
+ public boolean isLegacy() {
53+
+ return true;
54+
+ }
55+
+
56+
+ public static PaperServerListPingEvent processRequest(MinecraftServer server,
57+
+ InetSocketAddress address, int protocolVersion, @Nullable InetSocketAddress virtualHost) {
58+
+
59+
+ PaperServerListPingEvent event = new PaperServerListPingEventImpl(server,
60+
+ new PaperLegacyStatusClient(address, protocolVersion, virtualHost), Byte.MAX_VALUE, null);
61+
+ server.server.getPluginManager().callEvent(event);
62+
+
63+
+ if (event.isCancelled()) {
64+
+ return null;
65+
+ }
66+
+
67+
+ return event;
68+
+ }
69+
+
70+
+ public static String getMotd(PaperServerListPingEvent event) {
71+
+ return getFirstLine(event.getMotd());
72+
+ }
73+
+
74+
+ public static String getUnformattedMotd(PaperServerListPingEvent event) {
75+
+ // Strip color codes and all other occurrences of the color char (because it's used as delimiter)
76+
+ return getFirstLine(StringUtils.remove(ChatColor.stripColor(event.getMotd()), ChatColor.COLOR_CHAR));
77+
+ }
78+
+
79+
+ private static String getFirstLine(String s) {
80+
+ int pos = s.indexOf('\n');
81+
+ return pos >= 0 ? s.substring(0, pos) : s;
82+
+ }
83+
+
84+
+}
85+
diff --git a/src/main/java/com/destroystokyo/paper/network/PaperServerListPingEventImpl.java b/src/main/java/com/destroystokyo/paper/network/PaperServerListPingEventImpl.java
86+
index 146e0d9d1..c9c6b66ca 100644
87+
--- a/src/main/java/com/destroystokyo/paper/network/PaperServerListPingEventImpl.java
88+
+++ b/src/main/java/com/destroystokyo/paper/network/PaperServerListPingEventImpl.java
89+
@@ -2,8 +2,11 @@ package com.destroystokyo.paper.network;
90+
91+
import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
92+
import javax.annotation.Nullable;
93+
+import net.minecraft.server.EntityPlayer;
94+
import net.minecraft.server.MinecraftServer;
95+
+import org.bukkit.entity.Player;
96+
import org.bukkit.util.CachedServerIcon;
97+
+import org.jetbrains.annotations.NotNull;
98+
99+
class PaperServerListPingEventImpl extends PaperServerListPingEvent {
100+
101+
@@ -20,4 +23,9 @@ class PaperServerListPingEventImpl extends PaperServerListPingEvent {
102+
return this.server.getPlayerList().players.toArray();
103+
}
104+
105+
+ @Override
106+
+ protected final Player getBukkitPlayer(Object player) {
107+
+ return ((EntityPlayer) player).getBukkitEntity();
108+
+ }
109+
+
110+
}
111+
diff --git a/src/main/java/com/destroystokyo/paper/network/StandardPaperServerListPingEventImpl.java b/src/main/java/com/destroystokyo/paper/network/StandardPaperServerListPingEventImpl.java
112+
index 55ef52139..c7007dced 100644
113+
--- a/src/main/java/com/destroystokyo/paper/network/StandardPaperServerListPingEventImpl.java
114+
+++ b/src/main/java/com/destroystokyo/paper/network/StandardPaperServerListPingEventImpl.java
115+
@@ -24,8 +24,21 @@ public final class StandardPaperServerListPingEventImpl extends PaperServerListP
116+
117+
private GameProfile[] originalSample;
118+
119+
- private StandardPaperServerListPingEventImpl(MinecraftServer server, NetworkManager networkManager) {
120+
- super(server, new PaperStatusClient(networkManager), 47 /* 1.8.x protocol */, server.server.getServerIcon());
121+
+ private StandardPaperServerListPingEventImpl(MinecraftServer server, NetworkManager networkManager, ServerPing ping) {
122+
+ super(server, new PaperStatusClient(networkManager), ping.getVersion() != null ? ping.getVersion().getProtocol(): -1, server.server.getServerIcon());
123+
+
124+
+ List<GameProfile> profiles = server.getPlayerList().players
125+
+ .stream()
126+
+ .map(EntityPlayer::getProfile)
127+
+ .collect(Collectors.toList());
128+
+ // Spigot Start
129+
+ if (!profiles.isEmpty()) {
130+
+ profiles = profiles.subList(0, Math.min(profiles.size(), TitaniumConfig.get().spigot.settings.sampleCount)); // Cap the sample to n (or less) displayed players, ie: Vanilla behaviour
131+
+ java.util.Collections.shuffle(profiles); // This sucks, its inefficient but we have no simple way of doing it differently
132+
+ }
133+
+ // Spigot End
134+
+
135+
+ this.originalSample = profiles.toArray(new GameProfile[0]);
136+
}
137+
138+
@Nonnull
139+
@@ -76,23 +89,7 @@ public final class StandardPaperServerListPingEventImpl extends PaperServerListP
140+
141+
@SuppressWarnings("deprecation")
142+
public static void processRequest(MinecraftServer server, NetworkManager networkManager) {
143+
- StandardPaperServerListPingEventImpl event = new StandardPaperServerListPingEventImpl(server, networkManager);
144+
-
145+
- List<PlayerProfile> profiles = server.getPlayerList().players
146+
- .stream()
147+
- .map(EntityPlayer::getProfile)
148+
- .map(profile -> server.server.createProfile(profile.getId(), profile.getName()))
149+
- .collect(Collectors.toList());
150+
-
151+
- // Spigot Start
152+
- if ( !profiles.isEmpty() ) {
153+
- java.util.Collections.shuffle( profiles ); // This sucks, its inefficient but we have no simple way of doing it differently
154+
- profiles = profiles.subList( 0, Math.min( profiles.size(), TitaniumConfig.get().spigot.settings.sampleCount ) ); // Cap the sample to n (or less) displayed players, ie: Vanilla behaviour
155+
- }
156+
- // Spigot End
157+
-
158+
- event.setPlayerSample(profiles);
159+
-
160+
+ StandardPaperServerListPingEventImpl event = new StandardPaperServerListPingEventImpl(server, networkManager, server.r);
161+
server.server.getPluginManager().callEvent(event);
162+
163+
// Close connection immediately if event is cancelled
164+
@@ -107,8 +104,8 @@ public final class StandardPaperServerListPingEventImpl extends PaperServerListP
165+
166+
// Players
167+
if (!event.shouldHidePlayers()) {
168+
- ping.setPlayerSample(new ServerPing.ServerPingPlayerSample(event.getMaxPlayers(), profiles.size()));
169+
- ping.b().a(event.getPlayerSampleHandle());
170+
+ ping.setPlayerSample(new ServerPing.ServerPingPlayerSample(event.getMaxPlayers(), event.getNumPlayers()));
171+
+ ping.getPlayers().setSample(event.getPlayerSampleHandle());
172+
}
173+
174+
// Version
175+
diff --git a/src/main/java/net/minecraft/server/LegacyPingHandler.java b/src/main/java/net/minecraft/server/LegacyPingHandler.java
176+
index 48acf6364..69398687c 100644
177+
--- a/src/main/java/net/minecraft/server/LegacyPingHandler.java
178+
+++ b/src/main/java/net/minecraft/server/LegacyPingHandler.java
179+
@@ -8,6 +8,7 @@ import io.netty.channel.ChannelHandlerContext;
180+
import io.netty.channel.ChannelInboundHandlerAdapter;
181+
import java.net.InetSocketAddress;
182+
import java.nio.charset.StandardCharsets;
183+
+import java.util.Locale;
184+
import org.apache.logging.log4j.LogManager;
185+
import org.apache.logging.log4j.Logger;
186+
187+
@@ -43,11 +44,19 @@ public class LegacyPingHandler extends ChannelInboundHandlerAdapter {
188+
MinecraftServer minecraftserver = this.b.d();
189+
int i = bytebuf.readableBytes();
190+
String s;
191+
+ com.destroystokyo.paper.event.server.PaperServerListPingEvent event; // Paper
192+
193+
switch (i) {
194+
case 0:
195+
- LegacyPingHandler.a.debug("Ping: (<1.3.x) from {}:{}", new Object[] { inetsocketaddress.getAddress(), Integer.valueOf(inetsocketaddress.getPort())});
196+
- s = String.format("%s\u00a7%d\u00a7%d", new Object[] { minecraftserver.getMotd(), Integer.valueOf(minecraftserver.I()), Integer.valueOf(minecraftserver.J())});
197+
+ LegacyPingHandler.a.debug("Ping: (<1.3.x) from {}:{}", new Object[] { inetsocketaddress.getAddress(), inetsocketaddress.getPort()});
198+
+ // Paper start - Call PaperServerListPingEvent and use results
199+
+ event = com.destroystokyo.paper.network.PaperLegacyStatusClient.processRequest(minecraftserver, inetsocketaddress, 39, null);
200+
+ if (event == null) {
201+
+ channelhandlercontext.close();
202+
+ break;
203+
+ }
204+
+ s = String.format(Locale.ROOT, "%s\u00a7%d\u00a7%d", com.destroystokyo.paper.network.PaperLegacyStatusClient.getUnformattedMotd(event), event.getNumPlayers(), event.getMaxPlayers());
205+
+ // Paper end
206+
this.a(channelhandlercontext, this.a(s));
207+
break;
208+
209+
@@ -56,8 +65,15 @@ public class LegacyPingHandler extends ChannelInboundHandlerAdapter {
210+
return;
211+
}
212+
213+
- LegacyPingHandler.a.debug("Ping: (1.4-1.5.x) from {}:{}", new Object[] { inetsocketaddress.getAddress(), Integer.valueOf(inetsocketaddress.getPort())});
214+
- s = String.format("\u00a71\u0000%d\u0000%s\u0000%s\u0000%d\u0000%d", new Object[] { Integer.valueOf(127), minecraftserver.getVersion(), minecraftserver.getMotd(), Integer.valueOf(minecraftserver.I()), Integer.valueOf(minecraftserver.J())});
215+
+ LegacyPingHandler.a.debug("Ping: (1.4-1.5.x) from {}:{}", new Object[] { inetsocketaddress.getAddress(), inetsocketaddress.getPort()});
216+
+ // Paper start - Call PaperServerListPingEvent and use results
217+
+ event = com.destroystokyo.paper.network.PaperLegacyStatusClient.processRequest(minecraftserver, inetsocketaddress, 127, null); // Paper
218+
+ if (event == null) {
219+
+ channelhandlercontext.close();
220+
+ break;
221+
+ }
222+
+ s = String.format(Locale.ROOT, "\u00a71\u0000%d\u0000%s\u0000%s\u0000%d\u0000%d", event.getProtocolVersion(), minecraftserver.getVersion(), event.getMotd(), event.getNumPlayers(), event.getMaxPlayers()); // CraftBukkit
223+
+ // Paper end
224+
this.a(channelhandlercontext, this.a(s));
225+
break;
226+
227+
@@ -170,8 +186,16 @@ public class LegacyPingHandler extends ChannelInboundHandlerAdapter {
228+
229+
a.debug("Ping: (1.6) from {}", ctx.channel().remoteAddress());
230+
231+
- String response = String.format("\u00a71\u0000%d\u0000%s\u0000%s\u0000%d\u0000%d",
232+
- Byte.MAX_VALUE, server.getVersion(), server.getMotd(), server.getPlayerList().getPlayerCount(), server.getPlayerList().getMaxPlayers());
233+
+ InetSocketAddress virtualHost = com.destroystokyo.paper.network.PaperNetworkClient.prepareVirtualHost(host, port);
234+
+ com.destroystokyo.paper.event.server.PaperServerListPingEvent event = com.destroystokyo.paper.network.PaperLegacyStatusClient.processRequest(
235+
+ server, (InetSocketAddress) ctx.channel().remoteAddress(), protocolVersion, virtualHost);
236+
+ if (event == null) {
237+
+ ctx.close();
238+
+ return;
239+
+ }
240+
+
241+
+ String response = String.format("\u00a71\u0000%d\u0000%s\u0000%s\u0000%d\u0000%d", event.getProtocolVersion(), event.getVersion(),
242+
+ com.destroystokyo.paper.network.PaperLegacyStatusClient.getMotd(event), event.getNumPlayers(), event.getMaxPlayers());
243+
this.a(ctx, this.a(response));
244+
}
245+
246+
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
247+
index 33d15698e..3498ebe0d 100644
248+
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
249+
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
250+
@@ -64,7 +64,7 @@ public abstract class MinecraftServer extends ReentrantIAsyncHandler<TasksPerTic
251+
protected final ICommandHandler b;
252+
public final MethodProfiler methodProfiler = new MethodProfiler();
253+
private ServerConnection q; // Spigot
254+
- private final ServerPing r = new ServerPing();
255+
+ public final ServerPing r = new ServerPing(); // Titanium - make public
256+
private final Random s = new Random();
257+
private String serverIp;
258+
private int u = -1;
259+
diff --git a/src/main/java/net/minecraft/server/ServerPing.java b/src/main/java/net/minecraft/server/ServerPing.java
260+
index eeb810044..8f20df13a 100644
261+
--- a/src/main/java/net/minecraft/server/ServerPing.java
262+
+++ b/src/main/java/net/minecraft/server/ServerPing.java
263+
@@ -29,6 +29,7 @@ public class ServerPing {
264+
this.a = ichatbasecomponent;
265+
}
266+
267+
+ public ServerPing.ServerPingPlayerSample getPlayers() { return this.b(); } // Titanium - OBFHELPER
268+
public ServerPing.ServerPingPlayerSample b() {
269+
return this.b;
270+
}
271+
@@ -37,6 +38,7 @@ public class ServerPing {
272+
this.b = serverping_serverpingplayersample;
273+
}
274+
275+
+ public ServerPing.ServerData getVersion() { return this.c(); } // Titanium - OBFHELPER
276+
public ServerPing.ServerData c() {
277+
return this.c;
278+
}
279+
@@ -125,6 +127,7 @@ public class ServerPing {
280+
return this.a;
281+
}
282+
283+
+ public int getProtocol() { return this.b(); } // Titanium - OBFHELPER
284+
public int b() {
285+
return this.b;
286+
}
287+
@@ -180,6 +183,7 @@ public class ServerPing {
288+
return this.c;
289+
}
290+
291+
+ public void setSample(GameProfile[] sample) { this.a(sample); } // Titanium - OBFHELPER
292+
public void a(GameProfile[] agameprofile) {
293+
this.c = agameprofile;
294+
}
295+
--
296+
2.36.0.windows.1
297+

0 commit comments

Comments
 (0)