Skip to content

Commit 148c2ca

Browse files
Add support for the legacy ping passthrough options too.
1 parent b3c131f commit 148c2ca

File tree

3 files changed

+156
-61
lines changed

3 files changed

+156
-61
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright (C) 2018-2023 Velocity Contributors
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
*/
17+
18+
package com.velocitypowered.proxy.config;
19+
20+
/**
21+
* Legacy modes for ping passthrough.
22+
*/
23+
public enum LegacyPingPassthroughMode {
24+
DISABLED,
25+
MODS,
26+
DESCRIPTION,
27+
ALL
28+
}

proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ public class VelocityConfiguration implements ProxyConfig {
7878
private boolean onlineModeKickExistingPlayers = false;
7979
@Expose
8080
private PingPassthroughMode pingPassthrough = new PingPassthroughMode(false, false, false, false, false);
81+
@Expose
82+
private LegacyPingPassthroughMode legacyPingPassthrough = LegacyPingPassthroughMode.DISABLED;
8183
private final Servers servers;
8284
private final ForcedHosts forcedHosts;
8385
@Expose
@@ -105,8 +107,9 @@ private VelocityConfiguration(String bind, String motd, int showMaxPlayers, bool
105107
boolean preventClientProxyConnections, boolean announceForge,
106108
PlayerInfoForwarding playerInfoForwardingMode, byte[] forwardingSecret,
107109
boolean onlineModeKickExistingPlayers, PingPassthroughMode pingPassthrough,
108-
boolean enablePlayerAddressLogging, Servers servers, ForcedHosts forcedHosts,
109-
Advanced advanced, Query query, Metrics metrics, boolean forceKeyAuthentication) {
110+
LegacyPingPassthroughMode legacyPingPassthrough, boolean enablePlayerAddressLogging,
111+
Servers servers, ForcedHosts forcedHosts, Advanced advanced, Query query,
112+
Metrics metrics, boolean forceKeyAuthentication) {
110113
this.bind = bind;
111114
this.motd = motd;
112115
this.showMaxPlayers = showMaxPlayers;
@@ -117,6 +120,7 @@ private VelocityConfiguration(String bind, String motd, int showMaxPlayers, bool
117120
this.forwardingSecret = forwardingSecret;
118121
this.onlineModeKickExistingPlayers = onlineModeKickExistingPlayers;
119122
this.pingPassthrough = pingPassthrough;
123+
this.legacyPingPassthrough = legacyPingPassthrough;
120124
this.enablePlayerAddressLogging = enablePlayerAddressLogging;
121125
this.servers = servers;
122126
this.forcedHosts = forcedHosts;
@@ -371,6 +375,10 @@ public PingPassthroughMode getPingPassthrough() {
371375
return pingPassthrough;
372376
}
373377

378+
public LegacyPingPassthroughMode getLegacyPingPassthrough() {
379+
return legacyPingPassthrough;
380+
}
381+
374382
public boolean isPlayerAddressLoggingEnabled() {
375383
return enablePlayerAddressLogging;
376384
}
@@ -500,8 +508,8 @@ public static VelocityConfiguration read(Path path) throws IOException {
500508
final CommentedConfig metricsConfig = config.get("metrics");
501509
final PlayerInfoForwarding forwardingMode = config.getEnumOrElse(
502510
"player-info-forwarding-mode", PlayerInfoForwarding.NONE);
503-
// final PingPassthroughMode pingPassthroughMode = config.getEnumOrElse("ping-passthrough",
504-
// PingPassthroughMode.DISABLED);
511+
final LegacyPingPassthroughMode legacyPingPassthrough = config.getEnumOrElse("ping-passthrough",
512+
LegacyPingPassthroughMode.DISABLED);
505513
final PingPassthroughMode pingPassthrough = new PingPassthroughMode(
506514
config.getOrElse("ping-passthrough-version", false),
507515
config.getOrElse("ping-passthrough-players", false),
@@ -538,6 +546,7 @@ public static VelocityConfiguration read(Path path) throws IOException {
538546
forwardingSecret,
539547
kickExisting,
540548
pingPassthrough,
549+
legacyPingPassthrough,
541550
enablePlayerAddressLogging,
542551
new Servers(serversConfig),
543552
new ForcedHosts(forcedHostsConfig),

proxy/src/main/java/com/velocitypowered/proxy/connection/util/ServerListPingHandler.java

Lines changed: 115 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import com.velocitypowered.api.util.Favicon;
2727
import com.velocitypowered.api.util.ModInfo;
2828
import com.velocitypowered.proxy.VelocityServer;
29+
import com.velocitypowered.proxy.config.LegacyPingPassthroughMode;
2930
import com.velocitypowered.proxy.config.PingPassthroughMode;
3031
import com.velocitypowered.proxy.config.VelocityConfiguration;
3132
import com.velocitypowered.proxy.server.VelocityRegisteredServer;
@@ -64,7 +65,8 @@ private ServerPing constructLocalPing(ProtocolVersion version) {
6465
}
6566

6667
private CompletableFuture<ServerPing> attemptPingPassthrough(VelocityInboundConnection connection,
67-
PingPassthroughMode mode, List<String> servers, ProtocolVersion responseProtocolVersion) {
68+
PingPassthroughMode mode, LegacyPingPassthroughMode legacyMode,
69+
List<String> servers, ProtocolVersion responseProtocolVersion) {
6870
ServerPing fallback = constructLocalPing(connection.getProtocolVersion());
6971
List<CompletableFuture<ServerPing>> pings = new ArrayList<>();
7072
for (String s : servers) {
@@ -82,62 +84,117 @@ private CompletableFuture<ServerPing> attemptPingPassthrough(VelocityInboundConn
8284

8385
CompletableFuture<List<ServerPing>> pingResponses = CompletableFutures.successfulAsList(pings,
8486
(ex) -> fallback);
85-
return pingResponses.thenApply(responses -> {
86-
// Find the first non-fallback. If it includes a modlist, add it too.
87-
for (ServerPing response : responses) {
88-
if (response == fallback) {
89-
continue;
87+
if (mode.enabled()) {
88+
return pingResponses.thenApply(responses -> {
89+
// Find the first non-fallback. If it includes a modlist, add it too.
90+
for (ServerPing response : responses) {
91+
if (response == fallback) {
92+
continue;
93+
}
94+
95+
if (response.getDescriptionComponent() == null) {
96+
continue;
97+
}
98+
99+
ServerPing.Version version;
100+
if (mode.version) {
101+
version = response.getVersion();
102+
} else {
103+
version = fallback.getVersion();
104+
}
105+
106+
ServerPing.Players players;
107+
if (mode.players) {
108+
players = response.getPlayers().orElse(null);
109+
} else {
110+
players = fallback.getPlayers().orElse(null);
111+
}
112+
113+
net.kyori.adventure.text.Component description;
114+
if (mode.description) {
115+
description = response.getDescriptionComponent();
116+
} else {
117+
description = fallback.getDescriptionComponent();
118+
}
119+
120+
Favicon favicon;
121+
if (mode.favicon) {
122+
favicon = response.getFavicon().orElse(null);
123+
} else {
124+
favicon = fallback.getFavicon().orElse(null);
125+
}
126+
127+
ModInfo modinfo;
128+
if (mode.modinfo) {
129+
modinfo = response.getModinfo().orElse(null);
130+
} else {
131+
modinfo = fallback.getModinfo().orElse(null);
132+
}
133+
134+
return new ServerPing(
135+
version,
136+
players,
137+
description,
138+
favicon,
139+
modinfo
140+
);
90141
}
91-
92-
if (response.getDescriptionComponent() == null) {
93-
continue;
94-
}
95-
96-
ServerPing.Version version;
97-
if (mode.version) {
98-
version = response.getVersion();
99-
} else {
100-
version = fallback.getVersion();
101-
}
102-
103-
ServerPing.Players players;
104-
if (mode.players) {
105-
players = response.getPlayers().orElse(null);
106-
} else {
107-
players = fallback.getPlayers().orElse(null);
108-
}
109-
110-
net.kyori.adventure.text.Component description;
111-
if (mode.description) {
112-
description = response.getDescriptionComponent();
113-
} else {
114-
description = fallback.getDescriptionComponent();
115-
}
116-
117-
Favicon favicon;
118-
if (mode.favicon) {
119-
favicon = response.getFavicon().orElse(null);
120-
} else {
121-
favicon = fallback.getFavicon().orElse(null);
122-
}
123-
124-
ModInfo modinfo;
125-
if (mode.modinfo) {
126-
modinfo = response.getModinfo().orElse(null);
127-
} else {
128-
modinfo = fallback.getModinfo().orElse(null);
129-
}
130-
131-
return new ServerPing(
132-
version,
133-
players,
134-
description,
135-
favicon,
136-
modinfo
137-
);
142+
return fallback;
143+
});
144+
} else {
145+
switch (legacyMode) {
146+
case ALL:
147+
return pingResponses.thenApply(responses -> {
148+
// Find the first non-fallback
149+
for (ServerPing response : responses) {
150+
if (response == fallback) {
151+
continue;
152+
}
153+
return response;
154+
}
155+
return fallback;
156+
});
157+
case MODS:
158+
return pingResponses.thenApply(responses -> {
159+
// Find the first non-fallback that contains a mod list
160+
for (ServerPing response : responses) {
161+
if (response == fallback) {
162+
continue;
163+
}
164+
Optional<ModInfo> modInfo = response.getModinfo();
165+
if (modInfo.isPresent()) {
166+
return fallback.asBuilder().mods(modInfo.get()).build();
167+
}
168+
}
169+
return fallback;
170+
});
171+
case DESCRIPTION:
172+
return pingResponses.thenApply(responses -> {
173+
// Find the first non-fallback. If it includes a modlist, add it too.
174+
for (ServerPing response : responses) {
175+
if (response == fallback) {
176+
continue;
177+
}
178+
179+
if (response.getDescriptionComponent() == null) {
180+
continue;
181+
}
182+
183+
return new ServerPing(
184+
fallback.getVersion(),
185+
fallback.getPlayers().orElse(null),
186+
response.getDescriptionComponent(),
187+
fallback.getFavicon().orElse(null),
188+
response.getModinfo().orElse(null)
189+
);
190+
}
191+
return fallback;
192+
});
193+
// Not possible, but covered for completeness.
194+
default:
195+
return CompletableFuture.completedFuture(fallback);
138196
}
139-
return fallback;
140-
});
197+
}
141198
}
142199

143200
/**
@@ -151,16 +208,17 @@ public CompletableFuture<ServerPing> getInitialPing(VelocityInboundConnection co
151208
ProtocolVersion shownVersion = connection.getProtocolVersion().isSupported()
152209
? connection.getProtocolVersion() : ProtocolVersion.MAXIMUM_VERSION;
153210
PingPassthroughMode passthroughMode = configuration.getPingPassthrough();
211+
LegacyPingPassthroughMode legacyPassthroughMode = configuration.getLegacyPingPassthrough();
154212

155-
if (!passthroughMode.enabled()) {
213+
if (!passthroughMode.enabled() && legacyPassthroughMode == LegacyPingPassthroughMode.DISABLED) {
156214
return CompletableFuture.completedFuture(constructLocalPing(shownVersion));
157215
} else {
158216
String virtualHostStr = connection.getVirtualHost().map(InetSocketAddress::getHostString)
159217
.map(str -> str.toLowerCase(Locale.ROOT))
160218
.orElse("");
161219
List<String> serversToTry = server.getConfiguration().getForcedHosts().getOrDefault(
162220
virtualHostStr, server.getConfiguration().getAttemptConnectionOrder());
163-
return attemptPingPassthrough(connection, passthroughMode, serversToTry, shownVersion);
221+
return attemptPingPassthrough(connection, passthroughMode, legacyPassthroughMode, serversToTry, shownVersion);
164222
}
165223
}
166224
}

0 commit comments

Comments
 (0)