Skip to content

Commit 2a306f5

Browse files
author
Brody Beckwith
authored
Add Multi Block Change API (#7333)
1 parent 128691a commit 2a306f5

File tree

2 files changed

+112
-0
lines changed

2 files changed

+112
-0
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2+
From: Brody Beckwith <brody@beckwith.dev>
3+
Date: Fri, 14 Jan 2022 00:40:42 -0500
4+
Subject: [PATCH] Multi Block Change API
5+
6+
7+
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
8+
index 7eda2ba17e39b8183e572c1cefa8afffbf17afcb..fb8bd05a0204740ec323e9b657916de6ccbf6f90 100644
9+
--- a/src/main/java/org/bukkit/entity/Player.java
10+
+++ b/src/main/java/org/bukkit/entity/Player.java
11+
@@ -584,6 +584,27 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
12+
*/
13+
public void sendBlockDamage(@NotNull Location loc, float progress);
14+
15+
+ // Paper start
16+
+ /**
17+
+ * Send multiple block changes. This fakes a multi block change packet for each
18+
+ * chunk section that a block change occurs. This will not actually change the world in any way.
19+
+ *
20+
+ * @param blockChanges A map of the locations you want to change to their new block data
21+
+ */
22+
+ public default void sendMultiBlockChange(@NotNull java.util.Map<Location, BlockData> blockChanges) {
23+
+ sendMultiBlockChange(blockChanges, false);
24+
+ }
25+
+
26+
+ /**
27+
+ * Send multiple block changes. This fakes a multi block change packet for each
28+
+ * chunk section that a block change occurs. This will not actually change the world in any way.
29+
+ *
30+
+ * @param blockChanges A map of the locations you want to change to their new block data
31+
+ * @param suppressLightUpdates Whether to suppress light updates or not
32+
+ */
33+
+ public void sendMultiBlockChange(@NotNull java.util.Map<Location, BlockData> blockChanges, boolean suppressLightUpdates);
34+
+ // Paper end
35+
+
36+
/**
37+
* Send the equipment change of an entity. This fakes the equipment change
38+
* of an entity for a user. This will not actually change the inventory of
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2+
From: Brody Beckwith <brody@beckwith.dev>
3+
Date: Fri, 14 Jan 2022 00:41:11 -0500
4+
Subject: [PATCH] Multi Block Change API Implementation
5+
6+
7+
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundSectionBlocksUpdatePacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundSectionBlocksUpdatePacket.java
8+
index 82ea4fabd5732052a286d50bcff8bbcc2c4aa7d7..652bea6868a03a5315965f79c76172fb9dbb93fb 100644
9+
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundSectionBlocksUpdatePacket.java
10+
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundSectionBlocksUpdatePacket.java
11+
@@ -54,6 +54,15 @@ public class ClientboundSectionBlocksUpdatePacket implements Packet<ClientGamePa
12+
13+
}
14+
15+
+ // Paper start
16+
+ public ClientboundSectionBlocksUpdatePacket(SectionPos sectionPos, it.unimi.dsi.fastutil.shorts.Short2ObjectMap<BlockState> blockChanges, boolean suppressLightUpdates) {
17+
+ this.sectionPos = sectionPos;
18+
+ this.positions = blockChanges.keySet().toShortArray();
19+
+ this.states = blockChanges.values().toArray(new BlockState[0]);
20+
+ this.suppressLightUpdates = suppressLightUpdates;
21+
+ }
22+
+ // Paper end
23+
+
24+
@Override
25+
public void write(FriendlyByteBuf buf) {
26+
buf.writeLong(this.sectionPos.asLong());
27+
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
28+
index 148e1985017f6955267b5c970730645394d700f6..43d96760828e4c9683398f3f6925701d003556e4 100644
29+
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
30+
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
31+
@@ -30,6 +30,7 @@ import javax.annotation.Nullable;
32+
import net.minecraft.Util;
33+
import net.minecraft.advancements.AdvancementProgress;
34+
import net.minecraft.core.BlockPos;
35+
+import net.minecraft.core.SectionPos; // Paper
36+
import net.minecraft.nbt.CompoundTag;
37+
import net.minecraft.network.FriendlyByteBuf;
38+
import net.minecraft.network.chat.ChatType;
39+
@@ -836,6 +837,35 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
40+
this.getHandle().connection.send(packet);
41+
}
42+
43+
+ // Paper start
44+
+ @Override
45+
+ public void sendMultiBlockChange(Map<Location, BlockData> blockChanges, boolean suppressLightUpdates) {
46+
+ if (this.getHandle().connection == null) return;
47+
+
48+
+ Map<SectionPos, it.unimi.dsi.fastutil.shorts.Short2ObjectMap<net.minecraft.world.level.block.state.BlockState>> sectionMap = new HashMap<>();
49+
+
50+
+ for (Map.Entry<Location, BlockData> entry : blockChanges.entrySet()) {
51+
+ Location location = entry.getKey();
52+
+ if (!location.getWorld().equals(this.getWorld())) continue;
53+
+
54+
+ BlockData blockData = entry.getValue();
55+
+ BlockPos blockPos = new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ());
56+
+ SectionPos sectionPos = SectionPos.of(blockPos);
57+
+
58+
+ it.unimi.dsi.fastutil.shorts.Short2ObjectMap<net.minecraft.world.level.block.state.BlockState> sectionData = sectionMap.computeIfAbsent(sectionPos, key -> new it.unimi.dsi.fastutil.shorts.Short2ObjectArrayMap<>());
59+
+ sectionData.put(SectionPos.sectionRelativePos(blockPos), ((CraftBlockData) blockData).getState());
60+
+ }
61+
+
62+
+ for (Map.Entry<SectionPos, it.unimi.dsi.fastutil.shorts.Short2ObjectMap<net.minecraft.world.level.block.state.BlockState>> entry : sectionMap.entrySet()) {
63+
+ SectionPos sectionPos = entry.getKey();
64+
+ it.unimi.dsi.fastutil.shorts.Short2ObjectMap<net.minecraft.world.level.block.state.BlockState> blockData = entry.getValue();
65+
+
66+
+ net.minecraft.network.protocol.game.ClientboundSectionBlocksUpdatePacket packet = new net.minecraft.network.protocol.game.ClientboundSectionBlocksUpdatePacket(sectionPos, blockData, suppressLightUpdates);
67+
+ this.getHandle().connection.send(packet);
68+
+ }
69+
+ }
70+
+ // Paper end
71+
+
72+
@Override
73+
public void sendBlockDamage(Location loc, float progress) {
74+
Preconditions.checkArgument(loc != null, "loc must not be null");

0 commit comments

Comments
 (0)