Skip to content

Commit 10a4d8a

Browse files
committed
feat: config support for how many max channels a player can register
1 parent aae97dc commit 10a4d8a

File tree

6 files changed

+34
-13
lines changed

6 files changed

+34
-13
lines changed

api/src/main/java/com/velocitypowered/api/proxy/config/ProxyConfig.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,4 +203,11 @@ default boolean isKickOnCommandRateLimit() {
203203
default boolean isKickOnTabCompleteRateLimit() {
204204
return getKickAfterRateLimitedTabCompletes() > 0;
205205
}
206+
207+
/**
208+
* Get the channel register limit a client can register.
209+
*
210+
* @return the channel limit a client can register
211+
*/
212+
int getChannelRegisterLimit();
206213
}

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,11 @@ public int getKickAfterRateLimitedTabCompletes() {
375375
return advanced.getKickAfterRateLimitedTabCompletes();
376376
}
377377

378+
@Override
379+
public int getChannelRegisterLimit() {
380+
return advanced.getChannelRegisterLimit();
381+
}
382+
378383
@Override
379384
public boolean isForwardCommandsIfRateLimited() {
380385
return advanced.isForwardCommandsIfRateLimited();
@@ -773,6 +778,8 @@ private static class Advanced {
773778
private int tabCompleteRateLimit = 50;
774779
@Expose
775780
private int kickAfterRateLimitedTabCompletes = 10;
781+
@Expose
782+
private int channelRegisterLimit = 128;
776783

777784
private Advanced() {
778785
}
@@ -891,6 +898,10 @@ public int getKickAfterRateLimitedTabCompletes() {
891898
return kickAfterRateLimitedTabCompletes;
892899
}
893900

901+
public int getChannelRegisterLimit() {
902+
return channelRegisterLimit;
903+
}
904+
894905
@Override
895906
public String toString() {
896907
return "Advanced{"

proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -299,16 +299,16 @@ public boolean handle(PluginMessagePacket packet) {
299299
// Handling edge case when packet with FML client handshake (state COMPLETE)
300300
// arrives after JoinGame packet from destination server
301301
VelocityServerConnection serverConn =
302-
(player.getConnectedServer() == null
303-
&& packet.getChannel().equals(
304-
LegacyForgeConstants.FORGE_LEGACY_HANDSHAKE_CHANNEL))
305-
? player.getConnectionInFlight() : player.getConnectedServer();
302+
(player.getConnectedServer() == null
303+
&& packet.getChannel().equals(
304+
LegacyForgeConstants.FORGE_LEGACY_HANDSHAKE_CHANNEL))
305+
? player.getConnectionInFlight() : player.getConnectedServer();
306306

307307
MinecraftConnection backendConn = serverConn != null ? serverConn.getConnection() : null;
308308
if (serverConn != null && backendConn != null) {
309309
if (backendConn.getState() != StateRegistry.PLAY) {
310310
logger.warn("A plugin message was received while the backend server was not "
311-
+ "ready. Channel: {}. Packet discarded.", packet.getChannel());
311+
+ "ready. Channel: {}. Packet discarded.", packet.getChannel());
312312
} else if (PluginMessageUtil.isRegister(packet)) {
313313
List<String> channels = PluginMessageUtil.getChannels(packet);
314314
player.getClientsideChannels().addAll(channels);
@@ -321,8 +321,8 @@ public boolean handle(PluginMessagePacket packet) {
321321
}
322322
}
323323
server.getEventManager()
324-
.fireAndForget(
325-
new PlayerChannelRegisterEvent(player, ImmutableList.copyOf(channelIdentifiers)));
324+
.fireAndForget(
325+
new PlayerChannelRegisterEvent(player, ImmutableList.copyOf(channelIdentifiers)));
326326
backendConn.write(packet.retain());
327327
} else if (PluginMessageUtil.isUnregister(packet)) {
328328
player.getClientsideChannels().removeAll(PluginMessageUtil.getChannels(packet));
@@ -349,7 +349,7 @@ public boolean handle(PluginMessagePacket packet) {
349349
if (id == null) {
350350
// We don't have any plugins listening on this channel, process the packet now.
351351
if (!player.getPhase().consideredComplete() || !serverConn.getPhase()
352-
.consideredComplete()) {
352+
.consideredComplete()) {
353353
// The client is trying to send messages too early. This is primarily caused by mods,
354354
// but further aggravated by Velocity. To work around these issues, we will queue any
355355
// non-FML handshake messages to be sent once the FML handshake has completed or the
@@ -368,9 +368,9 @@ public boolean handle(PluginMessagePacket packet) {
368368
server.getEventManager().fire(event).thenAcceptAsync(pme -> {
369369
if (pme.getResult().isAllowed()) {
370370
PluginMessagePacket message = new PluginMessagePacket(packet.getChannel(),
371-
Unpooled.wrappedBuffer(copy));
371+
Unpooled.wrappedBuffer(copy));
372372
if (!player.getPhase().consideredComplete() || !serverConn.getPhase()
373-
.consideredComplete()) {
373+
.consideredComplete()) {
374374
// We're still processing the connection (see above), enqueue the packet for now.
375375
loginPluginMessages.add(message.retain());
376376
} else {

proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,6 @@
145145
public class ConnectedPlayer implements MinecraftConnectionAssociation, Player, KeyIdentifiable,
146146
VelocityInboundConnection {
147147

148-
private static final int MAX_CLIENTSIDE_PLUGIN_CHANNELS = 1024;
149148
private static final PlainTextComponentSerializer PASS_THRU_TRANSLATE =
150149
PlainTextComponentSerializer.builder().flattener(TranslatableMapper.FLATTENER).build();
151150
static final PermissionProvider DEFAULT_PERMISSIONS = s -> PermissionFunction.ALWAYS_UNDEFINED;
@@ -208,7 +207,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player,
208207
this.permissionFunction = PermissionFunction.ALWAYS_UNDEFINED;
209208
this.connectionPhase = connection.getType().getInitialClientPhase();
210209
this.onlineMode = onlineMode;
211-
this.clientsideChannels = CappedSet.create(MAX_CLIENTSIDE_PLUGIN_CHANNELS);
210+
this.clientsideChannels = CappedSet.create(server.getConfiguration().getChannelRegisterLimit());
212211

213212
if (connection.getProtocolVersion().noLessThan(ProtocolVersion.MINECRAFT_1_19_3)) {
214213
this.tabList = new VelocityTabList(this);

proxy/src/main/resources/com/velocitypowered/proxy/l10n/messages.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,5 @@ velocity.command.send-usage=/send <player> <server>
6464
# Kick
6565
velocity.kick.shutdown=Proxy shutting down.
6666
velocity.kick.command-rate-limit=You are sending too many commands too quickly.
67-
velocity.kick.tab-complete-rate-limit=You are sending too many tab complete requests too quickly.
67+
velocity.kick.tab-complete-rate-limit=You are sending too many tab complete requests too quickly.
68+
velocity.kick.channel-register-limit=You attempted to register too many channels.

proxy/src/main/resources/default-velocity.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,9 @@ tab-complete-rate-limit = 10
177177
# Setting this to 0 or lower will disable this feature.
178178
kick-after-rate-limited-tab-completes = 0
179179

180+
# How many channels a player can (un)register
181+
channel-register-limit = 128
182+
180183
[query]
181184
# Whether to enable responding to GameSpy 4 query responses or not.
182185
enabled = false

0 commit comments

Comments
 (0)