Skip to content

Commit 7c98b75

Browse files
Cancel sign editor open packet for invalid positions in 1.21.2->1.21 (#1099)
1 parent 7d39bcc commit 7c98b75

File tree

4 files changed

+170
-3
lines changed

4 files changed

+170
-3
lines changed

common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/Protocol1_21_2To1_21.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.ItemTagStorage;
3030
import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.PlayerStorage;
3131
import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.RecipeStorage;
32+
import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.SignStorage;
3233
import com.viaversion.viaversion.api.connection.UserConnection;
3334
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_20_5;
3435
import com.viaversion.viaversion.api.minecraft.item.data.ChatType;
@@ -159,6 +160,7 @@ public void init(final UserConnection user) {
159160
user.put(new ItemTagStorage());
160161
user.put(new RecipeStorage(this));
161162
user.put(new PlayerStorage());
163+
user.put(new SignStorage());
162164
}
163165

164166
@Override

common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/rewriter/BlockItemPacketRewriter1_21_2.java

Lines changed: 116 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,20 @@
2626
import com.viaversion.viabackwards.protocol.v1_21_2to1_21.Protocol1_21_2To1_21;
2727
import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.InventoryStateIdStorage;
2828
import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.RecipeStorage;
29+
import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.SignStorage;
2930
import com.viaversion.viaversion.api.connection.UserConnection;
3031
import com.viaversion.viaversion.api.data.MappingData;
32+
import com.viaversion.viaversion.api.data.entity.EntityTracker;
33+
import com.viaversion.viaversion.api.minecraft.BlockChangeRecord;
34+
import com.viaversion.viaversion.api.minecraft.BlockPosition;
3135
import com.viaversion.viaversion.api.minecraft.Holder;
3236
import com.viaversion.viaversion.api.minecraft.HolderSet;
3337
import com.viaversion.viaversion.api.minecraft.Particle;
3438
import com.viaversion.viaversion.api.minecraft.SoundEvent;
39+
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
40+
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
41+
import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
42+
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
3543
import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer;
3644
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
3745
import com.viaversion.viaversion.api.minecraft.item.Item;
@@ -48,6 +56,7 @@
4856
import com.viaversion.viaversion.api.minecraft.item.data.Repairable;
4957
import com.viaversion.viaversion.api.minecraft.item.data.UseCooldown;
5058
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
59+
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
5160
import com.viaversion.viaversion.api.type.Types;
5261
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_20_2;
5362
import com.viaversion.viaversion.api.type.types.version.VersionedTypes;
@@ -75,17 +84,117 @@ public BlockItemPacketRewriter1_21_2(final Protocol1_21_2To1_21 protocol) {
7584
public void registerPackets() {
7685
final BlockRewriter<ClientboundPacket1_21_2> blockRewriter = BlockRewriter.for1_20_2(protocol);
7786
blockRewriter.registerBlockEvent(ClientboundPackets1_21_2.BLOCK_EVENT);
78-
blockRewriter.registerBlockUpdate(ClientboundPackets1_21_2.BLOCK_UPDATE);
79-
blockRewriter.registerSectionBlocksUpdate1_20(ClientboundPackets1_21_2.SECTION_BLOCKS_UPDATE);
8087
blockRewriter.registerLevelEvent1_21(ClientboundPackets1_21_2.LEVEL_EVENT, 2001);
81-
blockRewriter.registerLevelChunk1_19(ClientboundPackets1_21_2.LEVEL_CHUNK_WITH_LIGHT, ChunkType1_20_2::new);
8288
blockRewriter.registerBlockEntityData(ClientboundPackets1_21_2.BLOCK_ENTITY_DATA);
8389

8490
registerAdvancements1_20_3(ClientboundPackets1_21_2.UPDATE_ADVANCEMENTS);
8591
registerSetEquipment(ClientboundPackets1_21_2.SET_EQUIPMENT);
8692
registerMerchantOffers1_20_5(ClientboundPackets1_21_2.MERCHANT_OFFERS);
8793
registerSetCreativeModeSlot(ServerboundPackets1_20_5.SET_CREATIVE_MODE_SLOT);
8894

95+
protocol.registerClientbound(ClientboundPackets1_21_2.LEVEL_CHUNK_WITH_LIGHT, wrapper -> {
96+
final Chunk chunk = blockRewriter.handleChunk1_19(wrapper, ChunkType1_20_2::new);
97+
blockRewriter.handleBlockEntities(null, chunk, wrapper.user());
98+
99+
if (!wrapper.user().getProtocolInfo().protocolVersion().equalTo(ProtocolVersion.v1_21)) {
100+
return;
101+
}
102+
103+
final EntityTracker tracker = wrapper.user().getEntityTracker(Protocol1_21_2To1_21.class);
104+
105+
final SignStorage storage = wrapper.user().get(SignStorage.class);
106+
storage.removeSigns(chunk.getX(), chunk.getZ());
107+
108+
for (int i = 0; i < chunk.getSections().length; i++) {
109+
final ChunkSection section = chunk.getSections()[i];
110+
111+
final DataPalette blockPalette = section.palette(PaletteType.BLOCKS);
112+
113+
boolean containsSign = false;
114+
for (int idx = 0; idx < blockPalette.size(); idx++) {
115+
if (signBlockState(blockPalette.idByIndex(idx))) {
116+
containsSign = true;
117+
break;
118+
}
119+
}
120+
121+
if (!containsSign) {
122+
continue;
123+
}
124+
125+
for (int idx = 0; idx < ChunkSection.SIZE; idx++) {
126+
if (!signBlockState(blockPalette.idAt(idx))) {
127+
continue;
128+
}
129+
130+
storage.addSign(new BlockPosition(
131+
ChunkSection.xFromIndex(idx) + (chunk.getX() << 4),
132+
ChunkSection.yFromIndex(idx) + tracker.currentMinY() + (i << 4),
133+
ChunkSection.zFromIndex(idx) + (chunk.getZ() << 4)
134+
));
135+
}
136+
}
137+
});
138+
139+
protocol.registerClientbound(ClientboundPackets1_21_2.BLOCK_UPDATE, wrapper -> {
140+
final BlockPosition position = wrapper.passthrough(Types.BLOCK_POSITION1_14);
141+
142+
final int blockId = wrapper.read(Types.VAR_INT);
143+
final int mappedBlockId = protocol.getMappingData().getNewBlockStateId(blockId);
144+
wrapper.write(Types.VAR_INT, mappedBlockId);
145+
146+
if (!wrapper.user().getProtocolInfo().protocolVersion().equalTo(ProtocolVersion.v1_21)) {
147+
return;
148+
}
149+
150+
final SignStorage storage = wrapper.user().get(SignStorage.class);
151+
storage.removeSign(position);
152+
if (signBlockState(mappedBlockId)) {
153+
storage.addSign(position);
154+
}
155+
});
156+
157+
protocol.registerClientbound(ClientboundPackets1_21_2.SECTION_BLOCKS_UPDATE, wrapper -> {
158+
final long position = wrapper.passthrough(Types.LONG);
159+
160+
final int chunkX = (int) (position >> 42);
161+
final int chunkY = (int) (position << 44 >> 44);
162+
final int chunkZ = (int) (position << 22 >> 42);
163+
164+
final SignStorage signStorage = wrapper.user().get(SignStorage.class);
165+
166+
final boolean equalToV1_21 = wrapper.user().getProtocolInfo().protocolVersion().equalTo(ProtocolVersion.v1_21);
167+
168+
for (final BlockChangeRecord record : wrapper.passthrough(Types.VAR_LONG_BLOCK_CHANGE_ARRAY)) {
169+
record.setBlockId(protocol.getMappingData().getNewBlockStateId(record.getBlockId()));
170+
171+
if (!equalToV1_21) {
172+
continue;
173+
}
174+
175+
final int x = record.getSectionX() + (chunkX << 4);
176+
final int y = record.getSectionY() + (chunkY << 4);
177+
final int z = record.getSectionZ() + (chunkZ << 4);
178+
final BlockPosition pos = new BlockPosition(x, y, z);
179+
if (signBlockState(record.getBlockId())) {
180+
signStorage.addSign(pos);
181+
} else {
182+
signStorage.removeSign(pos);
183+
}
184+
}
185+
});
186+
187+
protocol.registerClientbound(ClientboundPackets1_21_2.OPEN_SIGN_EDITOR, wrapper -> {
188+
if (!wrapper.user().getProtocolInfo().protocolVersion().equalTo(ProtocolVersion.v1_21)) {
189+
return;
190+
}
191+
192+
final BlockPosition position = wrapper.passthrough(Types.BLOCK_POSITION1_14);
193+
if (!wrapper.user().get(SignStorage.class).isSign(position)) {
194+
wrapper.cancel();
195+
}
196+
});
197+
89198
protocol.registerClientbound(ClientboundPackets1_21_2.COOLDOWN, wrapper -> {
90199
final MappingData mappingData = protocol.getMappingData();
91200
final String itemIdentifier = wrapper.read(Types.STRING);
@@ -297,6 +406,10 @@ private void byteToVarInt(final PacketWrapper wrapper) {
297406
wrapper.write(Types.VAR_INT, (int) containerId);
298407
}
299408

409+
private boolean signBlockState(final int blockStateId) {
410+
return (blockStateId >= 4302 && blockStateId <= 4589) || (blockStateId >= 4762 && blockStateId <= 5625);
411+
}
412+
300413
@Override
301414
public Item handleItemToClient(final UserConnection connection, Item item) {
302415
backupInconvertibleData(item);

common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/rewriter/EntityPacketRewriter1_21_2.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import com.viaversion.viabackwards.api.rewriters.EntityRewriter;
2828
import com.viaversion.viabackwards.protocol.v1_21_2to1_21.Protocol1_21_2To1_21;
2929
import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.PlayerStorage;
30+
import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.SignStorage;
31+
import com.viaversion.viaversion.api.data.entity.EntityTracker;
3032
import com.viaversion.viaversion.api.minecraft.Holder;
3133
import com.viaversion.viaversion.api.minecraft.Particle;
3234
import com.viaversion.viaversion.api.minecraft.RegistryEntry;
@@ -173,6 +175,11 @@ public void register() {
173175
wrapper.passthrough(Types.VAR_INT); // Portal cooldown
174176

175177
wrapper.read(Types.VAR_INT); // Sea level
178+
179+
final EntityTracker tracker = tracker(wrapper.user());
180+
if (tracker.currentWorld() != null && !tracker.currentWorld().equals(world)) {
181+
wrapper.user().put(new SignStorage());
182+
}
176183
trackWorldDataByKey1_20_5(wrapper.user(), dimensionId, world);
177184
});
178185

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
3+
* Copyright (C) 2016-2025 ViaVersion and contributors
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
package com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage;
19+
20+
import com.viaversion.viaversion.api.connection.StorableObject;
21+
import com.viaversion.viaversion.api.minecraft.BlockPosition;
22+
import java.util.HashSet;
23+
import java.util.Set;
24+
25+
public final class SignStorage implements StorableObject {
26+
27+
private final Set<BlockPosition> signs = new HashSet<>();
28+
29+
public void addSign(final BlockPosition position) {
30+
signs.add(position);
31+
}
32+
33+
public boolean isSign(final BlockPosition position) {
34+
return signs.contains(position);
35+
}
36+
37+
public void removeSign(final BlockPosition position) {
38+
signs.remove(position);
39+
}
40+
41+
public void removeSigns(final int chunkX, final int chunkZ) {
42+
signs.removeIf(pos -> pos.x() >> 4 == chunkX && pos.z() >> 4 == chunkZ);
43+
}
44+
45+
}

0 commit comments

Comments
 (0)