net/minecraft/network/protocol/game/

This commit is contained in:
Owen1212055
2024-12-14 12:57:42 -05:00
parent e50b519542
commit 822b963d3f
19 changed files with 153 additions and 164 deletions

View File

@@ -0,0 +1,11 @@
--- a/net/minecraft/network/protocol/game/ClientboundBlockEntityDataPacket.java
+++ b/net/minecraft/network/protocol/game/ClientboundBlockEntityDataPacket.java
@@ -29,7 +_,7 @@
public static ClientboundBlockEntityDataPacket create(BlockEntity blockEntity, BiFunction<BlockEntity, RegistryAccess, CompoundTag> dataGetter) {
RegistryAccess registryAccess = blockEntity.getLevel().registryAccess();
- return new ClientboundBlockEntityDataPacket(blockEntity.getBlockPos(), blockEntity.getType(), dataGetter.apply(blockEntity, registryAccess));
+ return new ClientboundBlockEntityDataPacket(blockEntity.getBlockPos(), blockEntity.getType(), blockEntity.sanitizeSentNbt(dataGetter.apply(blockEntity, registryAccess))); // Paper - Sanitize sent data
}
public static ClientboundBlockEntityDataPacket create(BlockEntity blockEntity) {

View File

@@ -0,0 +1,23 @@
--- a/net/minecraft/network/protocol/game/ClientboundContainerSetContentPacket.java
+++ b/net/minecraft/network/protocol/game/ClientboundContainerSetContentPacket.java
@@ -35,6 +_,20 @@
this.items = ItemStack.OPTIONAL_LIST_STREAM_CODEC.decode(buffer);
this.carriedItem = ItemStack.OPTIONAL_STREAM_CODEC.decode(buffer);
}
+ // Paper start - Handle large packets disconnecting client
+ @Override
+ public boolean hasLargePacketFallback() {
+ return true;
+ }
+
+ @Override
+ public boolean packetTooLarge(net.minecraft.network.Connection manager) {
+ for (int i = 0 ; i < this.items.size() ; i++) {
+ manager.send(new ClientboundContainerSetSlotPacket(this.containerId, this.stateId, i, this.items.get(i)));
+ }
+ return true;
+ }
+ // Paper end - Handle large packets disconnecting client
private void write(RegistryFriendlyByteBuf buffer) {
buffer.writeContainerId(this.containerId);

View File

@@ -0,0 +1,15 @@
--- a/net/minecraft/network/protocol/game/ClientboundInitializeBorderPacket.java
+++ b/net/minecraft/network/protocol/game/ClientboundInitializeBorderPacket.java
@@ -31,8 +_,10 @@
}
public ClientboundInitializeBorderPacket(WorldBorder worldBorder) {
- this.newCenterX = worldBorder.getCenterX();
- this.newCenterZ = worldBorder.getCenterZ();
+ // CraftBukkit start - multiply out nether border
+ this.newCenterX = worldBorder.getCenterX() * worldBorder.world.dimensionType().coordinateScale();
+ this.newCenterZ = worldBorder.getCenterZ() * worldBorder.world.dimensionType().coordinateScale();
+ // CraftBukkit end
this.oldSize = worldBorder.getSize();
this.newSize = worldBorder.getLerpTarget();
this.lerpTime = worldBorder.getLerpRemainingTime();

View File

@@ -0,0 +1,19 @@
--- a/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
+++ b/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
@@ -52,7 +_,7 @@
throw new RuntimeException("Can't read heightmap in packet for [" + x + ", " + z + "]");
} else {
int varInt = buffer.readVarInt();
- if (varInt > 2097152) {
+ if (varInt > 2097152) { // Paper - diff on change - if this changes, update PacketEncoder
throw new RuntimeException("Chunk Packet trying to allocate too much memory on read.");
} else {
this.buffer = new byte[varInt];
@@ -154,6 +_,7 @@
CompoundTag updateTag = blockEntity.getUpdateTag(blockEntity.getLevel().registryAccess());
BlockPos blockPos = blockEntity.getBlockPos();
int i = SectionPos.sectionRelative(blockPos.getX()) << 4 | SectionPos.sectionRelative(blockPos.getZ());
+ blockEntity.sanitizeSentNbt(updateTag); // Paper - Sanitize sent data
return new ClientboundLevelChunkPacketData.BlockEntityInfo(i, blockPos.getY(), blockEntity.getType(), updateTag.isEmpty() ? null : updateTag);
}
}

View File

@@ -0,0 +1,113 @@
--- a/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java
+++ b/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java
@@ -38,6 +_,17 @@
this.actions = EnumSet.of(action);
this.entries = List.of(new ClientboundPlayerInfoUpdatePacket.Entry(player));
}
+ // Paper start - Add Listing API for Player
+ public ClientboundPlayerInfoUpdatePacket(EnumSet<ClientboundPlayerInfoUpdatePacket.Action> actions, List<ClientboundPlayerInfoUpdatePacket.Entry> entries) {
+ this.actions = actions;
+ this.entries = entries;
+ }
+
+ public ClientboundPlayerInfoUpdatePacket(EnumSet<ClientboundPlayerInfoUpdatePacket.Action> actions, ClientboundPlayerInfoUpdatePacket.Entry entry) {
+ this.actions = actions;
+ this.entries = List.of(entry);
+ }
+ // Paper end - Add Listing API for Player
public static ClientboundPlayerInfoUpdatePacket createPlayerInitializing(Collection<ServerPlayer> players) {
EnumSet<ClientboundPlayerInfoUpdatePacket.Action> set = EnumSet.of(
@@ -52,6 +_,46 @@
);
return new ClientboundPlayerInfoUpdatePacket(set, players);
}
+ // Paper start - Add Listing API for Player
+ public static ClientboundPlayerInfoUpdatePacket createPlayerInitializing(Collection<ServerPlayer> players, ServerPlayer forPlayer) {
+ final EnumSet<ClientboundPlayerInfoUpdatePacket.Action> enumSet = EnumSet.of(
+ ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER,
+ ClientboundPlayerInfoUpdatePacket.Action.INITIALIZE_CHAT,
+ ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE,
+ ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LISTED,
+ ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LATENCY,
+ ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME,
+ ClientboundPlayerInfoUpdatePacket.Action.UPDATE_HAT,
+ ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LIST_ORDER
+ );
+ final List<ClientboundPlayerInfoUpdatePacket.Entry> entries = new java.util.ArrayList<>(players.size());
+ final org.bukkit.craftbukkit.entity.CraftPlayer bukkitEntity = forPlayer.getBukkitEntity();
+ for (final ServerPlayer player : players) {
+ entries.add(new ClientboundPlayerInfoUpdatePacket.Entry(player, bukkitEntity.isListed(player.getBukkitEntity())));
+ }
+ return new ClientboundPlayerInfoUpdatePacket(enumSet, entries);
+ }
+
+ public static ClientboundPlayerInfoUpdatePacket createSinglePlayerInitializing(ServerPlayer player, boolean listed) {
+ final EnumSet<ClientboundPlayerInfoUpdatePacket.Action> enumSet = EnumSet.of(
+ ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER,
+ ClientboundPlayerInfoUpdatePacket.Action.INITIALIZE_CHAT,
+ ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE,
+ ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LISTED,
+ ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LATENCY,
+ ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME,
+ ClientboundPlayerInfoUpdatePacket.Action.UPDATE_HAT,
+ ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LIST_ORDER
+ );
+ final List<ClientboundPlayerInfoUpdatePacket.Entry> entries = List.of(new Entry(player, listed));
+ return new ClientboundPlayerInfoUpdatePacket(enumSet, entries);
+ }
+
+ public static ClientboundPlayerInfoUpdatePacket updateListed(UUID playerInfoId, boolean listed) {
+ EnumSet<ClientboundPlayerInfoUpdatePacket.Action> enumSet = EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LISTED);
+ return new ClientboundPlayerInfoUpdatePacket(enumSet, new ClientboundPlayerInfoUpdatePacket.Entry(playerInfoId, listed));
+ }
+ // Paper end - Add Listing API for Player
private ClientboundPlayerInfoUpdatePacket(RegistryFriendlyByteBuf buffer) {
this.actions = buffer.readEnumSet(ClientboundPlayerInfoUpdatePacket.Action.class);
@@ -116,7 +_,15 @@
}),
INITIALIZE_CHAT(
(entryBuilder, buffer) -> entryBuilder.chatSession = buffer.readNullable(RemoteChatSession.Data::read),
- (buffer, entry) -> buffer.writeNullable(entry.chatSession, RemoteChatSession.Data::write)
+ // Paper start - Prevent causing expired keys from impacting new joins
+ (buf, entry) -> {
+ RemoteChatSession.Data chatSession = entry.chatSession;
+ if (chatSession != null && chatSession.profilePublicKey().hasExpired()) {
+ chatSession = null;
+ }
+ buf.writeNullable(chatSession, RemoteChatSession.Data::write);
+ }
+ // Paper end - Prevent causing expired keys from impacting new joins
),
UPDATE_GAME_MODE(
(entryBuilder, buffer) -> entryBuilder.gameMode = GameType.byId(buffer.readVarInt()),
@@ -160,10 +_,15 @@
@Nullable RemoteChatSession.Data chatSession
) {
Entry(ServerPlayer player) {
+ // Paper start - Add Listing API for Player
+ this(player, true);
+ }
+ Entry(ServerPlayer player, boolean listed) {
this(
+ // Paper end - Add Listing API for Player
player.getUUID(),
player.getGameProfile(),
- true,
+ listed, // Paper - Add Listing API for Player
player.connection.latency(),
player.gameMode.getGameModeForPlayer(),
player.getTabListDisplayName(),
@@ -172,6 +_,11 @@
Optionull.map(player.getChatSession(), RemoteChatSession::asData)
);
}
+ // Paper start - Add Listing API for Player
+ Entry(UUID profileId, boolean listed) {
+ this(profileId, null, listed, 0, GameType.DEFAULT_MODE, null, true, 0, null);
+ }
+ // Paper end - Add Listing API for Player
}
static class EntryBuilder {

View File

@@ -0,0 +1,29 @@
--- a/net/minecraft/network/protocol/game/ClientboundSectionBlocksUpdatePacket.java
+++ b/net/minecraft/network/protocol/game/ClientboundSectionBlocksUpdatePacket.java
@@ -30,10 +_,25 @@
for (short s : positions) {
this.positions[i] = s;
- this.states[i] = section.getBlockState(SectionPos.sectionRelativeX(s), SectionPos.sectionRelativeY(s), SectionPos.sectionRelativeZ(s));
+ this.states[i] = (section != null) ? section.getBlockState(SectionPos.sectionRelativeX(s), SectionPos.sectionRelativeY(s), SectionPos.sectionRelativeZ(s)) : net.minecraft.world.level.block.Blocks.AIR.defaultBlockState(); // CraftBukkit - SPIGOT-6076, Mojang bug when empty chunk section notified
i++;
}
}
+ // CraftBukkit start - Add constructor
+ public ClientboundSectionBlocksUpdatePacket(SectionPos sectionposition, ShortSet shortset, BlockState[] states) {
+ this.sectionPos = sectionposition;
+ this.positions = shortset.toShortArray();
+ this.states = states;
+ }
+ // CraftBukkit end
+ // Paper start - Multi Block Change API
+ public ClientboundSectionBlocksUpdatePacket(SectionPos sectionPos, it.unimi.dsi.fastutil.shorts.Short2ObjectMap<BlockState> blockChanges) {
+ this.sectionPos = sectionPos;
+ this.positions = blockChanges.keySet().toShortArray();
+ this.states = blockChanges.values().toArray(new BlockState[0]);
+ }
+ // Paper end - Multi Block Change API
+
private ClientboundSectionBlocksUpdatePacket(FriendlyByteBuf buffer) {
this.sectionPos = SectionPos.of(buffer.readLong());

View File

@@ -0,0 +1,15 @@
--- a/net/minecraft/network/protocol/game/ClientboundSetBorderCenterPacket.java
+++ b/net/minecraft/network/protocol/game/ClientboundSetBorderCenterPacket.java
@@ -14,8 +_,10 @@
private final double newCenterZ;
public ClientboundSetBorderCenterPacket(WorldBorder worldBorder) {
- this.newCenterX = worldBorder.getCenterX();
- this.newCenterZ = worldBorder.getCenterZ();
+ // CraftBukkit start - multiply out nether border
+ this.newCenterX = worldBorder.getCenterX() * (worldBorder.world != null ? worldBorder.world.dimensionType().coordinateScale() : 1.0);
+ this.newCenterZ = worldBorder.getCenterZ() * (worldBorder.world != null ? worldBorder.world.dimensionType().coordinateScale() : 1.0);
+ // CraftBukkit end
}
private ClientboundSetBorderCenterPacket(FriendlyByteBuf buffer) {

View File

@@ -0,0 +1,14 @@
--- a/net/minecraft/network/protocol/game/ClientboundSetEntityDataPacket.java
+++ b/net/minecraft/network/protocol/game/ClientboundSetEntityDataPacket.java
@@ -19,9 +_,11 @@
}
private static void pack(List<SynchedEntityData.DataValue<?>> dataValues, RegistryFriendlyByteBuf buffer) {
+ try (io.papermc.paper.util.DataSanitizationUtil.DataSanitizer ignored = io.papermc.paper.util.DataSanitizationUtil.start(true)) { // Paper - data sanitization
for (SynchedEntityData.DataValue<?> dataValue : dataValues) {
dataValue.write(buffer);
}
+ } // Paper - data sanitization
buffer.writeByte(255);
}

View File

@@ -0,0 +1,32 @@
--- a/net/minecraft/network/protocol/game/ClientboundSetEquipmentPacket.java
+++ b/net/minecraft/network/protocol/game/ClientboundSetEquipmentPacket.java
@@ -19,6 +_,13 @@
private final List<Pair<EquipmentSlot, ItemStack>> slots;
public ClientboundSetEquipmentPacket(int entity, List<Pair<EquipmentSlot, ItemStack>> slots) {
+ // Paper start - data sanitization
+ this(entity, slots, false);
+ }
+ private boolean sanitize;
+ public ClientboundSetEquipmentPacket(int entity, List<Pair<EquipmentSlot, ItemStack>> slots, boolean sanitize) {
+ this.sanitize = sanitize;
+ // Paper end - data sanitization
this.entity = entity;
this.slots = slots;
}
@@ -40,6 +_,7 @@
buffer.writeVarInt(this.entity);
int size = this.slots.size();
+ try (io.papermc.paper.util.DataSanitizationUtil.DataSanitizer ignored = io.papermc.paper.util.DataSanitizationUtil.start(this.sanitize)) { // Paper - data sanitization
for (int i = 0; i < size; i++) {
Pair<EquipmentSlot, ItemStack> pair = this.slots.get(i);
EquipmentSlot equipmentSlot = pair.getFirst();
@@ -48,6 +_,7 @@
buffer.writeByte(flag ? ordinal | -128 : ordinal);
ItemStack.OPTIONAL_STREAM_CODEC.encode(buffer, pair.getSecond());
}
+ } // Paper - data sanitization
}
@Override

View File

@@ -0,0 +1,23 @@
--- a/net/minecraft/network/protocol/game/ClientboundSetPlayerTeamPacket.java
+++ b/net/minecraft/network/protocol/game/ClientboundSetPlayerTeamPacket.java
@@ -30,6 +_,11 @@
private final Collection<String> players;
private final Optional<ClientboundSetPlayerTeamPacket.Parameters> parameters;
+ // Paper start - Multiple Entries with Scoreboards
+ public static ClientboundSetPlayerTeamPacket createMultiplePlayerPacket(PlayerTeam team, Collection<String> players, ClientboundSetPlayerTeamPacket.Action operation) {
+ return new ClientboundSetPlayerTeamPacket(team.getName(), operation == ClientboundSetPlayerTeamPacket.Action.ADD ? 3 : 4, Optional.empty(), players);
+ }
+ // Paper end - Multiple Entries with Scoreboards
private ClientboundSetPlayerTeamPacket(String name, int method, Optional<ClientboundSetPlayerTeamPacket.Parameters> parameters, Collection<String> players) {
this.name = name;
this.method = method;
@@ -198,7 +_,7 @@
ComponentSerialization.TRUSTED_STREAM_CODEC.encode(buffer, this.displayName);
buffer.writeByte(this.options);
buffer.writeUtf(this.nametagVisibility);
- buffer.writeUtf(this.collisionRule);
+ buffer.writeUtf(!io.papermc.paper.configuration.GlobalConfiguration.get().collisions.enablePlayerCollisions ? "never" : this.collisionRule); // Paper - Configurable player collision
buffer.writeEnum(this.color);
ComponentSerialization.TRUSTED_STREAM_CODEC.encode(buffer, this.playerPrefix);
ComponentSerialization.TRUSTED_STREAM_CODEC.encode(buffer, this.playerSuffix);

View File

@@ -0,0 +1,24 @@
--- a/net/minecraft/network/protocol/game/ClientboundSystemChatPacket.java
+++ b/net/minecraft/network/protocol/game/ClientboundSystemChatPacket.java
@@ -1,3 +_,4 @@
+// mc-dev import
package net.minecraft.network.protocol.game;
import net.minecraft.network.RegistryFriendlyByteBuf;
@@ -16,6 +_,16 @@
ClientboundSystemChatPacket::overlay,
ClientboundSystemChatPacket::new
);
+ // Spigot start
+ public ClientboundSystemChatPacket(net.md_5.bungee.api.chat.BaseComponent[] content, boolean overlay) {
+ this(org.bukkit.craftbukkit.util.CraftChatMessage.fromJSON(net.md_5.bungee.chat.ComponentSerializer.toString(content)), overlay);
+ }
+ // Spigot end
+ // Paper start
+ public ClientboundSystemChatPacket(net.kyori.adventure.text.Component content, boolean overlay) {
+ this(io.papermc.paper.adventure.PaperAdventure.asVanilla(content), overlay);
+ }
+ // Paper end
@Override
public PacketType<ClientboundSystemChatPacket> type() {

View File

@@ -0,0 +1,11 @@
--- a/net/minecraft/network/protocol/game/ServerboundCommandSuggestionPacket.java
+++ b/net/minecraft/network/protocol/game/ServerboundCommandSuggestionPacket.java
@@ -19,7 +_,7 @@
private ServerboundCommandSuggestionPacket(FriendlyByteBuf buffer) {
this.id = buffer.readVarInt();
- this.command = buffer.readUtf(32500);
+ this.command = buffer.readUtf(2048); // Paper
}
private void write(FriendlyByteBuf buffer) {

View File

@@ -0,0 +1,18 @@
--- a/net/minecraft/network/protocol/game/ServerboundInteractPacket.java
+++ b/net/minecraft/network/protocol/game/ServerboundInteractPacket.java
@@ -145,6 +_,15 @@
buffer.writeEnum(this.hand);
}
}
+ // Paper start - PlayerUseUnknownEntityEvent
+ public int getEntityId() {
+ return this.entityId;
+ }
+
+ public boolean isAttack() {
+ return this.action.getType() == ActionType.ATTACK;
+ }
+ // Paper end - PlayerUseUnknownEntityEvent
static class InteractionAtLocationAction implements ServerboundInteractPacket.Action {
private final InteractionHand hand;

View File

@@ -0,0 +1,23 @@
--- a/net/minecraft/network/protocol/game/ServerboundUseItemOnPacket.java
+++ b/net/minecraft/network/protocol/game/ServerboundUseItemOnPacket.java
@@ -1,3 +_,4 @@
+// mc-dev import
package net.minecraft.network.protocol.game;
import net.minecraft.network.FriendlyByteBuf;
@@ -14,6 +_,7 @@
private final BlockHitResult blockHit;
private final InteractionHand hand;
private final int sequence;
+ public long timestamp; // Spigot
public ServerboundUseItemOnPacket(InteractionHand hand, BlockHitResult blockHit, int sequence) {
this.hand = hand;
@@ -22,6 +_,7 @@
}
private ServerboundUseItemOnPacket(FriendlyByteBuf buffer) {
+ this.timestamp = System.currentTimeMillis(); // Spigot
this.hand = buffer.readEnum(InteractionHand.class);
this.blockHit = buffer.readBlockHitResult();
this.sequence = buffer.readVarInt();

View File

@@ -0,0 +1,23 @@
--- a/net/minecraft/network/protocol/game/ServerboundUseItemPacket.java
+++ b/net/minecraft/network/protocol/game/ServerboundUseItemPacket.java
@@ -1,3 +_,4 @@
+// mc-dev import
package net.minecraft.network.protocol.game;
import net.minecraft.network.FriendlyByteBuf;
@@ -14,6 +_,7 @@
private final int sequence;
private final float yRot;
private final float xRot;
+ public long timestamp; // Spigot
public ServerboundUseItemPacket(InteractionHand hand, int sequence, float yRot, float xRot) {
this.hand = hand;
@@ -23,6 +_,7 @@
}
private ServerboundUseItemPacket(FriendlyByteBuf buffer) {
+ this.timestamp = System.currentTimeMillis(); // Spigot
this.hand = buffer.readEnum(InteractionHand.class);
this.sequence = buffer.readVarInt();
this.yRot = buffer.readFloat();

View File

@@ -0,0 +1,22 @@
--- a/net/minecraft/network/protocol/game/VecDeltaCodec.java
+++ b/net/minecraft/network/protocol/game/VecDeltaCodec.java
@@ -5,16 +_,16 @@
public class VecDeltaCodec {
private static final double TRUNCATION_STEPS = 4096.0;
- private Vec3 base = Vec3.ZERO;
+ public Vec3 base = Vec3.ZERO; // Paper
@VisibleForTesting
static long encode(double value) {
- return Math.round(value * 4096.0);
+ return Math.round(value * 4096.0); // Paper - Fix MC-4; diff on change
}
@VisibleForTesting
static double decode(long value) {
- return value / 4096.0;
+ return value / 4096.0; // Paper - Fix MC-4; diff on change
}
public Vec3 decode(long x, long y, long z) {