Skip to content

Commit 0af0f55

Browse files
authored
fix: reimplement entity restore (//restore -e) (#3250)
- fixes #3224
1 parent 5ecc34e commit 0af0f55

File tree

4 files changed

+63
-8
lines changed

4 files changed

+63
-8
lines changed

worldedit-core/src/main/java/com/sk89q/worldedit/util/io/ForwardSeekableInputStream.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ public long skip(long n) throws IOException {
9191

9292
public void seek(long n) throws IOException {
9393
long diff = n - position;
94-
LOGGER.error("Seek to {} from {} using {}", n, position, diff);
9594

9695
if (diff < 0) {
9796
throw new IOException("Can't seek backwards");

worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk17.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,11 @@ public List<BaseEntity> getEntities() throws DataException {
294294
*/
295295
private void populateEntities() {
296296
entities = new ArrayList<>();
297-
LinListTag<LinCompoundTag> tags = rootTag.findListTag(
297+
LinCompoundTag entityTag;
298+
if (entityTagSupplier == null || (entityTag = entityTagSupplier.get()) == null) {
299+
return;
300+
}
301+
LinListTag<LinCompoundTag> tags = entityTag.findListTag(
298302
"Entities", LinTagType.compoundTag()
299303
);
300304
if (tags == null) {

worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk18.java

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,41 +25,52 @@
2525
import com.sk89q.jnbt.LongArrayTag;
2626
import com.sk89q.jnbt.NBTUtils;
2727
import com.sk89q.jnbt.Tag;
28+
import com.sk89q.worldedit.entity.BaseEntity;
2829
import com.sk89q.worldedit.math.BlockVector3;
2930
import com.sk89q.worldedit.registry.state.Property;
31+
import com.sk89q.worldedit.util.concurrency.LazyReference;
3032
import com.sk89q.worldedit.world.DataException;
3133
import com.sk89q.worldedit.world.block.BaseBlock;
3234
import com.sk89q.worldedit.world.block.BlockState;
3335
import com.sk89q.worldedit.world.block.BlockType;
3436
import com.sk89q.worldedit.world.block.BlockTypes;
37+
import com.sk89q.worldedit.world.entity.EntityTypes;
3538
import com.sk89q.worldedit.world.storage.InvalidFormatException;
3639
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
40+
import org.enginehub.linbus.tree.LinCompoundTag;
41+
import org.enginehub.linbus.tree.LinListTag;
42+
import org.enginehub.linbus.tree.LinTagType;
3743

3844
import javax.annotation.Nullable;
45+
import java.util.ArrayList;
3946
import java.util.HashMap;
4047
import java.util.List;
4148
import java.util.Map;
49+
import java.util.function.Supplier;
4250

4351
/**
4452
* The chunk format for Minecraft 1.18 and newer
4553
*/
4654
public class AnvilChunk18 implements Chunk {
4755

4856
private final CompoundTag rootTag;
57+
private final Supplier<LinCompoundTag> entityTagSupplier;
4958
private final Int2ObjectOpenHashMap<BlockState[]> blocks;
5059
private final int rootX;
5160
private final int rootZ;
5261

5362
private Map<BlockVector3, Map<String, Tag<?, ?>>> tileEntities;
63+
private List<BaseEntity> entities;
5464

5565
/**
5666
* Construct the chunk with a compound tag.
5767
*
5868
* @param tag the tag to read
5969
* @throws DataException on a data error
6070
*/
61-
public AnvilChunk18(CompoundTag tag) throws DataException {
71+
public AnvilChunk18(CompoundTag tag, Supplier<LinCompoundTag> entityTag) throws DataException {
6272
rootTag = tag;
73+
entityTagSupplier = entityTag;
6374

6475
rootX = NBTUtils.getChildTag(rootTag.getValue(), "xPos", IntTag.class).getValue();
6576
rootZ = NBTUtils.getChildTag(rootTag.getValue(), "zPos", IntTag.class).getValue();
@@ -105,7 +116,7 @@ public AnvilChunk18(CompoundTag tag) throws DataException {
105116
try {
106117
blockState = getBlockStateWith(blockState, property, value);
107118
} catch (IllegalArgumentException e) {
108-
throw new InvalidFormatException("Invalid block state for " + blockState.getBlockType().getId() + ", " + property.getName() + ": " + value);
119+
throw new InvalidFormatException("Invalid block state for " + blockState.getBlockType().id() + ", " + property.getName() + ": " + value);
109120
}
110121
}
111122
}
@@ -197,9 +208,9 @@ private CompoundTag getBlockTileEntity(BlockVector3 position) throws DataExcepti
197208

198209
@Override
199210
public BaseBlock getBlock(BlockVector3 position) throws DataException {
200-
int x = position.getX() - rootX * 16;
201-
int y = position.getY();
202-
int z = position.getZ() - rootZ * 16;
211+
int x = position.x() - rootX * 16;
212+
int y = position.y();
213+
int z = position.z() - rootZ * 16;
203214

204215
int section = y >> 4;
205216
int yIndex = y & 0x0F;
@@ -219,4 +230,37 @@ public BaseBlock getBlock(BlockVector3 position) throws DataException {
219230
return state.toBaseBlock();
220231
}
221232

233+
@Override
234+
public List<BaseEntity> getEntities() throws DataException {
235+
if (entities == null) {
236+
populateEntities();
237+
}
238+
return entities;
239+
}
240+
241+
/**
242+
* Used to load the biomes.
243+
*/
244+
private void populateEntities() {
245+
entities = new ArrayList<>();
246+
LinCompoundTag entityTag;
247+
if (entityTagSupplier == null || (entityTag = entityTagSupplier.get()) == null) {
248+
return;
249+
}
250+
LinListTag<LinCompoundTag> tags = entityTag.findListTag(
251+
"Entities", LinTagType.compoundTag()
252+
);
253+
if (tags == null) {
254+
return;
255+
}
256+
257+
for (LinCompoundTag tag : tags.value()) {
258+
entities.add(new BaseEntity(
259+
EntityTypes.get(tag.getTag("id", LinTagType.stringTag()).value()),
260+
LazyReference.computed(tag)
261+
));
262+
}
263+
264+
}
265+
222266
}

worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/ChunkStoreHelper.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,15 @@ public static Chunk getChunk(CompoundTag rootTag, Supplier<CompoundTag> entities
104104
}
105105

106106
if (dataVersion >= Constants.DATA_VERSION_MC_1_18) {
107-
return new AnvilChunk18(rootTag);
107+
return new AnvilChunk18(
108+
rootTag, () -> {
109+
CompoundTag compoundTag = entitiesTag.get();
110+
if (compoundTag == null) {
111+
return null;
112+
}
113+
return compoundTag.toLinTag();
114+
}
115+
);
108116
}
109117

110118
Map<String, Tag<?, ?>> children = rootTag.getValue();

0 commit comments

Comments
 (0)