mirror of
https://github.com/PaperMC/Paper.git
synced 2025-01-19 06:42:02 +01:00
Guard against serializing mismatching chunk coordinate
Should help if something dumb happens
This commit is contained in:
parent
2eb4908754
commit
c33f47103e
@ -134,3 +134,24 @@
|
|||||||
CompoundTag nbttagcompound1 = new CompoundTag();
|
CompoundTag nbttagcompound1 = new CompoundTag();
|
||||||
|
|
||||||
nbttagcompound1.putString("dimension", worldKey.location().toString());
|
nbttagcompound1.putString("dimension", worldKey.location().toString());
|
||||||
|
@@ -108,8 +172,19 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompletableFuture<Void> write(ChunkPos chunkPos, Supplier<CompoundTag> nbtSupplier) {
|
||||||
|
+ // Paper start - guard against possible chunk pos desync
|
||||||
|
+ final Supplier<CompoundTag> guardedPosCheck = () -> {
|
||||||
|
+ CompoundTag nbt = nbtSupplier.get();
|
||||||
|
+ if (nbt != null && !chunkPos.equals(SerializableChunkData.getChunkCoordinate(nbt))) {
|
||||||
|
+ final String world = (ChunkStorage.this instanceof net.minecraft.server.level.ChunkMap) ? ((net.minecraft.server.level.ChunkMap) ChunkStorage.this).level.getWorld().getName() : null;
|
||||||
|
+ throw new IllegalArgumentException("Chunk coordinate and serialized data do not have matching coordinates, trying to serialize coordinate " + chunkPos
|
||||||
|
+ + " but compound says coordinate is " + SerializableChunkData.getChunkCoordinate(nbt) + (world == null ? " for an unknown world" : (" for world: " + world)));
|
||||||
|
+ }
|
||||||
|
+ return nbt;
|
||||||
|
+ };
|
||||||
|
+ // Paper end - guard against possible chunk pos desync
|
||||||
|
this.handleLegacyStructureIndex(chunkPos);
|
||||||
|
- return this.worker.store(chunkPos, nbtSupplier);
|
||||||
|
+ return this.worker.store(chunkPos, guardedPosCheck); // Paper - guard against possible chunk pos desync
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void handleLegacyStructureIndex(ChunkPos chunkPos) {
|
||||||
|
@ -10,7 +10,34 @@
|
|||||||
|
|
||||||
public static final Codec<PalettedContainer<BlockState>> BLOCK_STATE_CODEC = PalettedContainer.codecRW(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState());
|
public static final Codec<PalettedContainer<BlockState>> BLOCK_STATE_CODEC = PalettedContainer.codecRW(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState());
|
||||||
private static final Logger LOGGER = LogUtils.getLogger();
|
private static final Logger LOGGER = LogUtils.getLogger();
|
||||||
@@ -110,7 +111,7 @@
|
@@ -90,13 +91,25 @@
|
||||||
|
public static final String SECTIONS_TAG = "sections";
|
||||||
|
public static final String BLOCK_LIGHT_TAG = "BlockLight";
|
||||||
|
public static final String SKY_LIGHT_TAG = "SkyLight";
|
||||||
|
+ // Paper start - guard against serializing mismatching coordinates
|
||||||
|
+ // TODO Note: This needs to be re-checked each update
|
||||||
|
+ public static ChunkPos getChunkCoordinate(final CompoundTag chunkData) {
|
||||||
|
+ final int dataVersion = ChunkStorage.getVersion(chunkData);
|
||||||
|
+ if (dataVersion < 2842) { // Level tag is removed after this version
|
||||||
|
+ final CompoundTag levelData = chunkData.getCompound("Level");
|
||||||
|
+ return new ChunkPos(levelData.getInt("xPos"), levelData.getInt("zPos"));
|
||||||
|
+ } else {
|
||||||
|
+ return new ChunkPos(chunkData.getInt("xPos"), chunkData.getInt("zPos"));
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ // Paper end - guard against serializing mismatching coordinates
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static SerializableChunkData parse(LevelHeightAccessor world, RegistryAccess registryManager, CompoundTag nbt) {
|
||||||
|
if (!nbt.contains("Status", 8)) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
- ChunkPos chunkcoordintpair = new ChunkPos(nbt.getInt("xPos"), nbt.getInt("zPos"));
|
||||||
|
+ ChunkPos chunkcoordintpair = new ChunkPos(nbt.getInt("xPos"), nbt.getInt("zPos")); // Paper - guard against serializing mismatching coordinates; diff on change, see ChunkSerializer#getChunkCoordinate
|
||||||
|
long i = nbt.getLong("LastUpdate");
|
||||||
|
long j = nbt.getLong("InhabitedTime");
|
||||||
|
ChunkStatus chunkstatus = ChunkStatus.byName(nbt.getString("Status"));
|
||||||
|
@@ -110,7 +123,7 @@
|
||||||
dataresult = BlendingData.Packed.CODEC.parse(NbtOps.INSTANCE, nbt.getCompound("blending_data"));
|
dataresult = BlendingData.Packed.CODEC.parse(NbtOps.INSTANCE, nbt.getCompound("blending_data"));
|
||||||
logger = SerializableChunkData.LOGGER;
|
logger = SerializableChunkData.LOGGER;
|
||||||
Objects.requireNonNull(logger);
|
Objects.requireNonNull(logger);
|
||||||
@ -19,7 +46,7 @@
|
|||||||
} else {
|
} else {
|
||||||
blendingdata_d = null;
|
blendingdata_d = null;
|
||||||
}
|
}
|
||||||
@@ -121,7 +122,7 @@
|
@@ -121,7 +134,7 @@
|
||||||
dataresult = BelowZeroRetrogen.CODEC.parse(NbtOps.INSTANCE, nbt.getCompound("below_zero_retrogen"));
|
dataresult = BelowZeroRetrogen.CODEC.parse(NbtOps.INSTANCE, nbt.getCompound("below_zero_retrogen"));
|
||||||
logger = SerializableChunkData.LOGGER;
|
logger = SerializableChunkData.LOGGER;
|
||||||
Objects.requireNonNull(logger);
|
Objects.requireNonNull(logger);
|
||||||
@ -28,7 +55,7 @@
|
|||||||
} else {
|
} else {
|
||||||
belowzeroretrogen = null;
|
belowzeroretrogen = null;
|
||||||
}
|
}
|
||||||
@@ -178,7 +179,7 @@
|
@@ -178,7 +191,7 @@
|
||||||
ListTag nbttaglist2 = nbt.getList("sections", 10);
|
ListTag nbttaglist2 = nbt.getList("sections", 10);
|
||||||
List<SerializableChunkData.SectionData> list4 = new ArrayList(nbttaglist2.size());
|
List<SerializableChunkData.SectionData> list4 = new ArrayList(nbttaglist2.size());
|
||||||
Registry<Biome> iregistry = registryManager.lookupOrThrow(Registries.BIOME);
|
Registry<Biome> iregistry = registryManager.lookupOrThrow(Registries.BIOME);
|
||||||
@ -37,7 +64,7 @@
|
|||||||
|
|
||||||
for (int i1 = 0; i1 < nbttaglist2.size(); ++i1) {
|
for (int i1 = 0; i1 < nbttaglist2.size(); ++i1) {
|
||||||
CompoundTag nbttagcompound3 = nbttaglist2.getCompound(i1);
|
CompoundTag nbttagcompound3 = nbttaglist2.getCompound(i1);
|
||||||
@@ -196,17 +197,17 @@
|
@@ -196,17 +209,17 @@
|
||||||
datapaletteblock = new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES);
|
datapaletteblock = new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +85,7 @@
|
|||||||
} else {
|
} else {
|
||||||
chunksection = null;
|
chunksection = null;
|
||||||
}
|
}
|
||||||
@@ -217,7 +218,8 @@
|
@@ -217,7 +230,8 @@
|
||||||
list4.add(new SerializableChunkData.SectionData(b0, chunksection, nibblearray, nibblearray1));
|
list4.add(new SerializableChunkData.SectionData(b0, chunksection, nibblearray, nibblearray1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,34 +95,34 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,6 +291,12 @@
|
@@ -287,7 +301,13 @@
|
||||||
|
if (this.chunkStatus.isOrAfter(ChunkStatus.INITIALIZE_LIGHT)) {
|
||||||
|
protochunk.setLightEngine(levellightengine);
|
||||||
}
|
}
|
||||||
}
|
+ }
|
||||||
|
+
|
||||||
+ // CraftBukkit start - load chunk persistent data from nbt - SPIGOT-6814: Already load PDC here to account for 1.17 to 1.18 chunk upgrading.
|
+ // CraftBukkit start - load chunk persistent data from nbt - SPIGOT-6814: Already load PDC here to account for 1.17 to 1.18 chunk upgrading.
|
||||||
+ if (this.persistentDataContainer instanceof CompoundTag) {
|
+ if (this.persistentDataContainer instanceof CompoundTag) {
|
||||||
+ ((ChunkAccess) object).persistentDataContainer.putAll((CompoundTag) this.persistentDataContainer);
|
+ ((ChunkAccess) object).persistentDataContainer.putAll((CompoundTag) this.persistentDataContainer);
|
||||||
+ }
|
}
|
||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
+
|
|
||||||
((ChunkAccess) object).setLightCorrect(this.lightCorrect);
|
((ChunkAccess) object).setLightCorrect(this.lightCorrect);
|
||||||
EnumSet<Heightmap.Types> enumset = EnumSet.noneOf(Heightmap.Types.class);
|
EnumSet<Heightmap.Types> enumset = EnumSet.noneOf(Heightmap.Types.class);
|
||||||
Iterator iterator1 = ((ChunkAccess) object).getPersistedStatus().heightmapsAfter().iterator();
|
@@ -348,6 +368,12 @@
|
||||||
@@ -346,7 +354,13 @@
|
|
||||||
|
|
||||||
private static Codec<PalettedContainerRO<Holder<Biome>>> makeBiomeCodec(Registry<Biome> biomeRegistry) {
|
|
||||||
return PalettedContainer.codecRO(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.getOrThrow(Biomes.PLAINS));
|
return PalettedContainer.codecRO(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.getOrThrow(Biomes.PLAINS));
|
||||||
+ }
|
}
|
||||||
+
|
|
||||||
+ // CraftBukkit start - read/write
|
+ // CraftBukkit start - read/write
|
||||||
+ private static Codec<PalettedContainer<Holder<Biome>>> makeBiomeCodecRW(Registry<Biome> iregistry) {
|
+ private static Codec<PalettedContainer<Holder<Biome>>> makeBiomeCodecRW(Registry<Biome> iregistry) {
|
||||||
+ return PalettedContainer.codecRW(iregistry.asHolderIdMap(), iregistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, iregistry.getOrThrow(Biomes.PLAINS));
|
+ return PalettedContainer.codecRW(iregistry.asHolderIdMap(), iregistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, iregistry.getOrThrow(Biomes.PLAINS));
|
||||||
}
|
+ }
|
||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
|
+
|
||||||
public static SerializableChunkData copyOf(ServerLevel world, ChunkAccess chunk) {
|
public static SerializableChunkData copyOf(ServerLevel world, ChunkAccess chunk) {
|
||||||
if (!chunk.canBeSerialized()) {
|
if (!chunk.canBeSerialized()) {
|
||||||
@@ -419,7 +433,14 @@
|
throw new IllegalArgumentException("Chunk can't be serialized: " + String.valueOf(chunk));
|
||||||
|
@@ -419,7 +445,14 @@
|
||||||
});
|
});
|
||||||
CompoundTag nbttagcompound1 = packStructureData(StructurePieceSerializationContext.fromLevel(world), chunkcoordintpair, chunk.getAllStarts(), chunk.getAllReferences());
|
CompoundTag nbttagcompound1 = packStructureData(StructurePieceSerializationContext.fromLevel(world), chunkcoordintpair, chunk.getAllStarts(), chunk.getAllReferences());
|
||||||
|
|
||||||
@ -111,7 +138,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -432,7 +453,7 @@
|
@@ -432,7 +465,7 @@
|
||||||
nbttagcompound.putLong("LastUpdate", this.lastUpdateTime);
|
nbttagcompound.putLong("LastUpdate", this.lastUpdateTime);
|
||||||
nbttagcompound.putLong("InhabitedTime", this.inhabitedTime);
|
nbttagcompound.putLong("InhabitedTime", this.inhabitedTime);
|
||||||
nbttagcompound.putString("Status", BuiltInRegistries.CHUNK_STATUS.getKey(this.chunkStatus).toString());
|
nbttagcompound.putString("Status", BuiltInRegistries.CHUNK_STATUS.getKey(this.chunkStatus).toString());
|
||||||
@ -120,7 +147,7 @@
|
|||||||
Logger logger;
|
Logger logger;
|
||||||
|
|
||||||
if (this.blendingData != null) {
|
if (this.blendingData != null) {
|
||||||
@@ -513,6 +534,11 @@
|
@@ -513,6 +546,11 @@
|
||||||
});
|
});
|
||||||
nbttagcompound.put("Heightmaps", nbttagcompound2);
|
nbttagcompound.put("Heightmaps", nbttagcompound2);
|
||||||
nbttagcompound.put("structures", this.structureData);
|
nbttagcompound.put("structures", this.structureData);
|
||||||
@ -132,7 +159,7 @@
|
|||||||
return nbttagcompound;
|
return nbttagcompound;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -623,6 +649,12 @@
|
@@ -623,6 +661,12 @@
|
||||||
StructureStart structurestart = StructureStart.loadStaticStart(context, nbttagcompound1.getCompound(s), worldSeed);
|
StructureStart structurestart = StructureStart.loadStaticStart(context, nbttagcompound1.getCompound(s), worldSeed);
|
||||||
|
|
||||||
if (structurestart != null) {
|
if (structurestart != null) {
|
||||||
|
Loading…
Reference in New Issue
Block a user