Skip to content

Commit 9b1798d

Browse files
authored
Simplify custom payload handling (#12347)
1 parent c467df9 commit 9b1798d

File tree

5 files changed

+57
-53
lines changed

5 files changed

+57
-53
lines changed

build-data/paper.at

+1-1
Original file line numberDiff line numberDiff line change
@@ -491,8 +491,8 @@ public net.minecraft.world.inventory.AnvilMenu repairItemCountCost
491491
public net.minecraft.world.inventory.BrewingStandMenu brewingStandData
492492
public net.minecraft.world.inventory.CraftingMenu access
493493
public net.minecraft.world.inventory.DispenserMenu dispenser
494-
public net.minecraft.world.inventory.HorseInventoryMenu horse
495494
public net.minecraft.world.inventory.HorseInventoryMenu SLOT_BODY_ARMOR
495+
public net.minecraft.world.inventory.HorseInventoryMenu horse
496496
public net.minecraft.world.inventory.MerchantContainer selectionHint
497497
public net.minecraft.world.inventory.Slot slot
498498
public net.minecraft.world.item.AdventureModePredicate predicates
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,26 @@
11
--- a/net/minecraft/network/protocol/common/custom/DiscardedPayload.java
22
+++ b/net/minecraft/network/protocol/common/custom/DiscardedPayload.java
3-
@@ -4,13 +_,14 @@
3+
@@ -4,13 +_,19 @@
44
import net.minecraft.network.codec.StreamCodec;
55
import net.minecraft.resources.ResourceLocation;
66

77
-public record DiscardedPayload(ResourceLocation id) implements CustomPacketPayload {
8-
+public record DiscardedPayload(ResourceLocation id, io.netty.buffer.ByteBuf data) implements CustomPacketPayload { // CraftBukkit - store data
8+
+public record DiscardedPayload(ResourceLocation id, byte[] data) implements CustomPacketPayload { // Paper - store data
99
public static <T extends FriendlyByteBuf> StreamCodec<T, DiscardedPayload> codec(ResourceLocation id, int maxSize) {
1010
- return CustomPacketPayload.codec((value, output) -> {}, buffer -> {
1111
+ return CustomPacketPayload.codec((value, output) -> {
12-
+ output.writeBytes(value.data); // CraftBukkit - serialize
12+
+ // Paper start
13+
+ // Always write data
14+
+ output.writeBytes(value.data);
1315
+ }, buffer -> {
1416
int i = buffer.readableBytes();
1517
if (i >= 0 && i <= maxSize) {
1618
- buffer.skipBytes(i);
1719
- return new DiscardedPayload(id);
18-
+ return new DiscardedPayload(id, buffer.readBytes(i)); // CraftBukkit
20+
+ final byte[] data = new byte[i];
21+
+ buffer.readBytes(data);
22+
+ return new DiscardedPayload(id, data);
23+
+ // Paper end
1924
} else {
2025
throw new IllegalArgumentException("Payload may not be larger than " + maxSize + " bytes");
2126
}

paper-server/patches/sources/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch

+45-41
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@
9595
}
9696
}
9797

98-
@@ -88,30 +_,119 @@
98+
@@ -88,30 +_,123 @@
9999
public void handlePong(ServerboundPongPacket packet) {
100100
}
101101

@@ -105,64 +105,68 @@
105105
@Override
106106
public void handleCustomPayload(ServerboundCustomPayloadPacket packet) {
107107
- }
108-
+ // CraftBukkit start
109-
+ // Paper start - Brand support
108+
+ // Paper start
110109
+ if (packet.payload() instanceof net.minecraft.network.protocol.common.custom.BrandPayload(String brand)) {
111110
+ this.player.clientBrandName = brand;
112111
+ }
113-
+ // Paper end - Brand support
112+
+
114113
+ if (!(packet.payload() instanceof final net.minecraft.network.protocol.common.custom.DiscardedPayload discardedPayload)) {
115114
+ return;
116115
+ }
116+
+
117117
+ PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
118-
+ net.minecraft.resources.ResourceLocation identifier = packet.payload().type().id();
119-
+ io.netty.buffer.ByteBuf payload = discardedPayload.data();
120118
+
121-
+ if (identifier.equals(ServerCommonPacketListenerImpl.CUSTOM_REGISTER)) {
122-
+ try {
123-
+ String channels = payload.toString(com.google.common.base.Charsets.UTF_8);
124-
+ for (String channel : channels.split("\0")) {
125-
+ this.getCraftPlayer().addChannel(channel);
119+
+ final net.minecraft.resources.ResourceLocation identifier = packet.payload().type().id();
120+
+ final byte[] data = discardedPayload.data();
121+
+ try {
122+
+ final boolean registerChannel = ServerCommonPacketListenerImpl.CUSTOM_REGISTER.equals(identifier);
123+
+ if (registerChannel || ServerCommonPacketListenerImpl.CUSTOM_UNREGISTER.equals(identifier)) {
124+
+ // Strings separated by zeros instead of length prefixes
125+
+ int startIndex = 0;
126+
+ for (int i = 0; i < data.length; i++) {
127+
+ final byte b = data[i];
128+
+ if (b != 0) {
129+
+ continue;
130+
+ }
131+
+
132+
+ readChannelIdentifier(data, startIndex, i, registerChannel);
133+
+ startIndex = i + 1;
126134
+ }
127-
+ } catch (Exception ex) {
128-
+ ServerGamePacketListenerImpl.LOGGER.error("Couldn't register custom payload", ex);
129-
+ this.disconnect(Component.literal("Invalid payload REGISTER!"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PAYLOAD); // Paper - kick event cause
135+
+
136+
+ // Read the last one
137+
+ readChannelIdentifier(data, startIndex, data.length, registerChannel);
138+
+ return;
130139
+ }
131-
+ } else if (identifier.equals(ServerCommonPacketListenerImpl.CUSTOM_UNREGISTER)) {
132-
+ try {
133-
+ String channels = payload.toString(com.google.common.base.Charsets.UTF_8);
134-
+ for (String channel : channels.split("\0")) {
135-
+ this.getCraftPlayer().removeChannel(channel);
136-
+ }
137-
+ } catch (Exception ex) {
138-
+ ServerGamePacketListenerImpl.LOGGER.error("Couldn't unregister custom payload", ex);
139-
+ this.disconnect(Component.literal("Invalid payload UNREGISTER!"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PAYLOAD); // Paper - kick event cause
140+
+
141+
+ if (identifier.equals(MINECRAFT_BRAND)) {
142+
+ this.player.clientBrandName = new net.minecraft.network.FriendlyByteBuf(io.netty.buffer.Unpooled.wrappedBuffer(data)).readUtf(256);
140143
+ }
144+
+
145+
+ this.cserver.getMessenger().dispatchIncomingMessage(this.player.getBukkitEntity(), identifier.toString(), data);
146+
+ } catch (final Exception e) {
147+
+ ServerGamePacketListenerImpl.LOGGER.error("Couldn't handle custom payload on channel {}", identifier, e);
148+
+ this.disconnect(Component.literal("Invalid custom payload payload!"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PAYLOAD); // Paper - kick event cause
149+
+ }
150+
+ }
151+
+
152+
+ private void readChannelIdentifier(final byte[] data, final int from, final int to, final boolean register) {
153+
+ final int length = to - from;
154+
+ if (length == 0) {
155+
+ return;
156+
+ }
157+
+
158+
+ final String channel = new String(data, from, length, java.nio.charset.StandardCharsets.US_ASCII);
159+
+ if (register) {
160+
+ this.getCraftPlayer().addChannel(channel);
141161
+ } else {
142-
+ try {
143-
+ byte[] data = new byte[payload.readableBytes()];
144-
+ payload.readBytes(data);
145-
+ // Paper start - Brand support; Retain this incase upstream decides to 'break' the new mechanism in favour of backwards compat...
146-
+ if (identifier.equals(MINECRAFT_BRAND)) {
147-
+ try {
148-
+ this.player.clientBrandName = new net.minecraft.network.FriendlyByteBuf(io.netty.buffer.Unpooled.copiedBuffer(data)).readUtf(256);
149-
+ } catch (StringIndexOutOfBoundsException ex) {
150-
+ this.player.clientBrandName = "illegal";
151-
+ }
152-
+ }
153-
+ // Paper end - Brand support
154-
+ this.cserver.getMessenger().dispatchIncomingMessage(this.player.getBukkitEntity(), identifier.toString(), data);
155-
+ } catch (Exception ex) {
156-
+ ServerGamePacketListenerImpl.LOGGER.error("Couldn't dispatch custom payload", ex);
157-
+ this.disconnect(Component.literal("Invalid custom payload!"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PAYLOAD); // Paper - kick event cause
158-
+ }
162+
+ this.getCraftPlayer().removeChannel(channel);
159163
+ }
160164
+ }
161165
+
162166
+ public final boolean isDisconnected() {
163167
+ return (!this.player.joining && !this.connection.isConnected()) || this.processedDisconnect; // Paper - Fix duplication bugs
164168
+ }
165-
+ // CraftBukkit end
169+
+ // Paper end
166170

167171
@Override
168172
public void handleResourcePackResponse(ServerboundResourcePackPacket packet) {

paper-server/patches/sources/net/minecraft/world/inventory/HorseInventoryMenu.java.patch

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
--- a/net/minecraft/world/inventory/HorseInventoryMenu.java
22
+++ b/net/minecraft/world/inventory/HorseInventoryMenu.java
33
@@ -19,9 +_,23 @@
4-
private final AbstractHorse horse;
4+
public final AbstractHorse horse;
55
public static final int SLOT_BODY_ARMOR = 1;
66
private static final int SLOT_HORSE_INVENTORY_START = 2;
77
+ // CraftBukkit start

paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java

+1-6
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import com.google.common.io.BaseEncoding;
77
import com.mojang.authlib.GameProfile;
88
import com.mojang.datafixers.util.Pair;
9-
import io.netty.buffer.Unpooled;
109
import io.papermc.paper.FeatureHooks;
1110
import io.papermc.paper.configuration.GlobalConfiguration;
1211
import io.papermc.paper.entity.LookAnchor;
@@ -103,7 +102,6 @@
103102
import net.minecraft.sounds.SoundEvent;
104103
import net.minecraft.world.entity.Entity;
105104
import net.minecraft.world.entity.ai.attributes.AttributeInstance;
106-
import net.minecraft.world.entity.ai.attributes.AttributeMap;
107105
import net.minecraft.world.entity.ai.attributes.Attributes;
108106
import net.minecraft.world.entity.item.ItemEntity;
109107
import net.minecraft.world.food.FoodData;
@@ -174,7 +172,6 @@
174172
import org.bukkit.craftbukkit.map.RenderData;
175173
import org.bukkit.craftbukkit.potion.CraftPotionEffectType;
176174
import org.bukkit.craftbukkit.potion.CraftPotionUtil;
177-
import org.bukkit.craftbukkit.profile.CraftPlayerProfile;
178175
import org.bukkit.craftbukkit.scoreboard.CraftScoreboard;
179176
import org.bukkit.craftbukkit.util.CraftChatMessage;
180177
import org.bukkit.craftbukkit.util.CraftLocation;
@@ -189,7 +186,6 @@
189186
import org.bukkit.event.player.PlayerHideEntityEvent;
190187
import org.bukkit.event.player.PlayerRegisterChannelEvent;
191188
import org.bukkit.event.player.PlayerShowEntityEvent;
192-
import org.bukkit.event.player.PlayerSpawnChangeEvent;
193189
import org.bukkit.event.player.PlayerTeleportEvent;
194190
import org.bukkit.event.player.PlayerUnregisterChannelEvent;
195191
import org.bukkit.inventory.EquipmentSlot;
@@ -202,7 +198,6 @@
202198
import org.bukkit.plugin.messaging.StandardMessenger;
203199
import org.bukkit.potion.PotionEffect;
204200
import org.bukkit.potion.PotionEffectType;
205-
import org.bukkit.profile.PlayerProfile;
206201
import org.bukkit.scoreboard.Scoreboard;
207202
import org.jetbrains.annotations.NotNull;
208203

@@ -2463,7 +2458,7 @@ public void sendPluginMessage(Plugin source, String channel, byte[] message) {
24632458
}
24642459

24652460
private void sendCustomPayload(ResourceLocation id, byte[] message) {
2466-
ClientboundCustomPayloadPacket packet = new ClientboundCustomPayloadPacket(new DiscardedPayload(id, Unpooled.wrappedBuffer(message)));
2461+
ClientboundCustomPayloadPacket packet = new ClientboundCustomPayloadPacket(new DiscardedPayload(id, message));
24672462
this.getHandle().connection.send(packet);
24682463
}
24692464

0 commit comments

Comments
 (0)