mirror of
https://github.com/PaperMC/Paper.git
synced 2025-01-09 17:57:34 +01:00
SPIGOT-6814: (Chunk) PersistentData is lost after restart
By: DerFrZocker <derrieple@gmail.com>
This commit is contained in:
parent
95ab0e27a8
commit
6b0484122e
@ -18,7 +18,7 @@
|
||||
this.gameEventDispatcherSections = new Int2ObjectOpenHashMap();
|
||||
HeightMap.Type[] aheightmap_type = HeightMap.Type.values();
|
||||
int j = aheightmap_type.length;
|
||||
@@ -110,8 +110,22 @@
|
||||
@@ -110,8 +110,20 @@
|
||||
this.postLoad = chunk_c;
|
||||
this.blockTicks = levelchunkticks;
|
||||
this.fluidTicks = levelchunkticks1;
|
||||
@ -34,22 +34,24 @@
|
||||
+ public boolean mustNotSave;
|
||||
+ public boolean needsDecoration;
|
||||
+
|
||||
+ private static final org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry();
|
||||
+ public final org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer persistentDataContainer = new org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer(DATA_TYPE_REGISTRY);
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
public Chunk(WorldServer worldserver, ProtoChunk protochunk, @Nullable Chunk.c chunk_c) {
|
||||
this(worldserver, protochunk.getPos(), protochunk.getUpgradeData(), protochunk.unpackBlockTicks(), protochunk.unpackFluidTicks(), protochunk.getInhabitedTime(), protochunk.getSections(), chunk_c, protochunk.getBlendingData());
|
||||
Iterator iterator = protochunk.getBlockEntities().values().iterator();
|
||||
@@ -142,6 +156,7 @@
|
||||
@@ -142,6 +154,11 @@
|
||||
|
||||
this.setLightCorrect(protochunk.isLightCorrect());
|
||||
this.unsaved = true;
|
||||
+ this.needsDecoration = true; // CraftBukkit
|
||||
+ // CraftBukkit start
|
||||
+ this.persistentDataContainer = protochunk.persistentDataContainer; // SPIGOT-6814: copy PDC to account for 1.17 to 1.18 chunk upgrading.
|
||||
+ this.persistentDataContainer.setCallback(() -> setUnsaved(true)); // SPIGOT-6814: Handle cases were only persistentData is saved
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -238,9 +253,16 @@
|
||||
@@ -238,9 +255,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,7 +68,7 @@
|
||||
int i = blockposition.getY();
|
||||
ChunkSection chunksection = this.getSection(this.getSectionIndex(i));
|
||||
boolean flag1 = chunksection.hasOnlyAir();
|
||||
@@ -279,7 +301,8 @@
|
||||
@@ -279,7 +303,8 @@
|
||||
if (!chunksection.getBlockState(j, k, l).is(block)) {
|
||||
return null;
|
||||
} else {
|
||||
@ -76,7 +78,7 @@
|
||||
iblockdata.onPlace(this.level, blockposition, iblockdata1, flag);
|
||||
}
|
||||
|
||||
@@ -324,7 +347,12 @@
|
||||
@@ -324,7 +349,12 @@
|
||||
|
||||
@Nullable
|
||||
public TileEntity getBlockEntity(BlockPosition blockposition, Chunk.EnumTileEntityState chunk_enumtileentitystate) {
|
||||
@ -90,7 +92,7 @@
|
||||
|
||||
if (tileentity == null) {
|
||||
NBTTagCompound nbttagcompound = (NBTTagCompound) this.pendingBlockEntities.remove(blockposition);
|
||||
@@ -395,6 +423,13 @@
|
||||
@@ -395,6 +425,13 @@
|
||||
tileentity1.setRemoved();
|
||||
}
|
||||
|
||||
@ -104,7 +106,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -424,6 +459,12 @@
|
||||
@@ -424,6 +461,12 @@
|
||||
if (this.isInLevel()) {
|
||||
TileEntity tileentity = (TileEntity) this.blockEntities.remove(blockposition);
|
||||
|
||||
@ -117,7 +119,7 @@
|
||||
if (tileentity != null) {
|
||||
this.removeGameEventListener(tileentity);
|
||||
tileentity.setRemoved();
|
||||
@@ -471,6 +512,55 @@
|
||||
@@ -471,6 +514,55 @@
|
||||
|
||||
}
|
||||
|
||||
@ -173,7 +175,7 @@
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
@@ -659,7 +749,7 @@
|
||||
@@ -659,7 +751,7 @@
|
||||
|
||||
private <T extends TileEntity> void updateBlockEntityTicker(T t0) {
|
||||
IBlockData iblockdata = t0.getBlockState();
|
||||
@ -182,7 +184,7 @@
|
||||
|
||||
if (blockentityticker == null) {
|
||||
this.removeBlockEntityTicker(t0.getBlockPos());
|
||||
@@ -752,7 +842,7 @@
|
||||
@@ -752,7 +844,7 @@
|
||||
private boolean loggedInvalidBlockState;
|
||||
|
||||
a(TileEntity tileentity, BlockEntityTicker blockentityticker) {
|
||||
@ -191,7 +193,7 @@
|
||||
this.ticker = blockentityticker;
|
||||
}
|
||||
|
||||
@@ -775,7 +865,7 @@
|
||||
@@ -775,7 +867,7 @@
|
||||
this.loggedInvalidBlockState = true;
|
||||
Chunk.LOGGER.warn("Block entity {} @ {} state {} invalid for ticking:", new org.apache.logging.log4j.util.Supplier[]{this::getType, this::getPos, () -> {
|
||||
return iblockdata;
|
||||
|
@ -1,18 +1,31 @@
|
||||
--- a/net/minecraft/world/level/chunk/IChunkAccess.java
|
||||
+++ b/net/minecraft/world/level/chunk/IChunkAccess.java
|
||||
@@ -94,7 +94,11 @@
|
||||
@@ -77,6 +77,11 @@
|
||||
protected final LevelHeightAccessor levelHeightAccessor;
|
||||
protected final ChunkSection[] sections;
|
||||
|
||||
+ // CraftBukkit start - SPIGOT-6814: move to IChunkAccess to account for 1.17 to 1.18 chunk upgrading.
|
||||
+ private static final org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry();
|
||||
+ public org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer persistentDataContainer = new org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer(DATA_TYPE_REGISTRY);
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
public IChunkAccess(ChunkCoordIntPair chunkcoordintpair, ChunkConverter chunkconverter, LevelHeightAccessor levelheightaccessor, IRegistry<BiomeBase> iregistry, long i, @Nullable ChunkSection[] achunksection, @Nullable BlendingData blendingdata) {
|
||||
this.chunkPos = chunkcoordintpair;
|
||||
this.upgradeData = chunkconverter;
|
||||
@@ -94,7 +99,12 @@
|
||||
}
|
||||
|
||||
replaceMissingSections(levelheightaccessor, iregistry, this.sections);
|
||||
+ // CraftBukkit start
|
||||
+ this.biomeRegistry = iregistry;
|
||||
+ this.persistentDataContainer.setCallback(() -> setUnsaved(true)); // CraftBukkit - SPIGOT-6814: Handle cases were only persistentData is saved
|
||||
}
|
||||
+ public final IRegistry<BiomeBase> biomeRegistry;
|
||||
+ // CraftBukkit end
|
||||
|
||||
private static void replaceMissingSections(LevelHeightAccessor levelheightaccessor, IRegistry<BiomeBase> iregistry, ChunkSection[] achunksection) {
|
||||
for (int i = 0; i < achunksection.length; ++i) {
|
||||
@@ -394,6 +398,27 @@
|
||||
@@ -394,6 +404,27 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,7 +53,7 @@
|
||||
public void fillBiomesFromNoise(BiomeResolver biomeresolver, Climate.Sampler climate_sampler) {
|
||||
ChunkCoordIntPair chunkcoordintpair = this.getPos();
|
||||
int i = QuartPos.fromBlock(chunkcoordintpair.getMinBlockX());
|
||||
@@ -425,8 +450,10 @@
|
||||
@@ -425,8 +456,10 @@
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -52,7 +65,7 @@
|
||||
private final SerializableTickContainer<Block> blocks;
|
||||
private final SerializableTickContainer<FluidType> fluids;
|
||||
|
||||
@@ -442,5 +469,7 @@
|
||||
@@ -442,5 +475,7 @@
|
||||
public SerializableTickContainer<FluidType> fluids() {
|
||||
return this.fluids;
|
||||
}
|
||||
|
@ -9,7 +9,21 @@
|
||||
|
||||
Objects.requireNonNull(protochunk);
|
||||
optional.ifPresent(protochunk::setBelowZeroRetrogen);
|
||||
@@ -321,7 +321,7 @@
|
||||
@@ -219,6 +219,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ // CraftBukkit start - load chunk persistent data from nbt - SPIGOT-6814: Already load PDC here to account for 1.17 to 1.18 chunk upgrading.
|
||||
+ net.minecraft.nbt.NBTBase persistentBase = nbttagcompound.get("ChunkBukkitValues");
|
||||
+ if (persistentBase instanceof NBTTagCompound) {
|
||||
+ ((IChunkAccess) object).persistentDataContainer.putAll((NBTTagCompound) persistentBase);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
((IChunkAccess) object).setLightCorrect(flag);
|
||||
NBTTagCompound nbttagcompound2 = nbttagcompound.getCompound("Heightmaps");
|
||||
EnumSet<HeightMap.Type> enumset = EnumSet.noneOf(HeightMap.Type.class);
|
||||
@@ -321,7 +328,7 @@
|
||||
nbttagcompound.putLong("InhabitedTime", ichunkaccess.getInhabitedTime());
|
||||
nbttagcompound.putString("Status", ichunkaccess.getStatus().getName());
|
||||
BlendingData blendingdata = ichunkaccess.getBlendingData();
|
||||
@ -18,28 +32,15 @@
|
||||
Logger logger;
|
||||
|
||||
if (blendingdata != null) {
|
||||
@@ -452,6 +452,11 @@
|
||||
@@ -452,6 +459,11 @@
|
||||
|
||||
nbttagcompound.put("Heightmaps", nbttagcompound3);
|
||||
nbttagcompound.put("structures", packStructureData(StructurePieceSerializationContext.fromLevel(worldserver), chunkcoordintpair, ichunkaccess.getAllStarts(), ichunkaccess.getAllReferences()));
|
||||
+ // CraftBukkit start - store chunk persistent data in nbt
|
||||
+ if (ichunkaccess instanceof Chunk && !((Chunk) ichunkaccess).persistentDataContainer.isEmpty()) {
|
||||
+ nbttagcompound.put("ChunkBukkitValues", ((Chunk) ichunkaccess).persistentDataContainer.toTagCompound());
|
||||
+ if (!ichunkaccess.persistentDataContainer.isEmpty()) { // SPIGOT-6814: Always save PDC to account for 1.17 to 1.18 chunk upgrading.
|
||||
+ nbttagcompound.put("ChunkBukkitValues", ichunkaccess.persistentDataContainer.toTagCompound());
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
return nbttagcompound;
|
||||
}
|
||||
|
||||
@@ -498,6 +503,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ // CraftBukkit start - load chunk persistent data from nbt
|
||||
+ net.minecraft.nbt.NBTBase persistentBase = nbttagcompound.get("ChunkBukkitValues");
|
||||
+ if (persistentBase instanceof NBTTagCompound) {
|
||||
+ chunk.persistentDataContainer.putAll((NBTTagCompound) persistentBase);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -17,9 +17,11 @@ import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
public final class CraftPersistentDataContainer implements PersistentDataContainer {
|
||||
|
||||
private static final Callback EMPTY = () -> { };
|
||||
private final Map<String, NBTBase> customDataTags = new HashMap<>();
|
||||
private final CraftPersistentDataTypeRegistry registry;
|
||||
private final CraftPersistentDataAdapterContext adapterContext;
|
||||
private Callback callback = EMPTY;
|
||||
|
||||
public CraftPersistentDataContainer(Map<String, NBTBase> customTags, CraftPersistentDataTypeRegistry registry) {
|
||||
this(registry);
|
||||
@ -31,6 +33,15 @@ public final class CraftPersistentDataContainer implements PersistentDataContain
|
||||
this.adapterContext = new CraftPersistentDataAdapterContext(this.registry);
|
||||
}
|
||||
|
||||
public void setCallback(Callback callback) {
|
||||
if (callback == null) {
|
||||
this.callback = EMPTY;
|
||||
return;
|
||||
}
|
||||
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, Z> void set(NamespacedKey key, PersistentDataType<T, Z> type, Z value) {
|
||||
Validate.notNull(key, "The provided key for the custom value was null");
|
||||
@ -38,6 +49,7 @@ public final class CraftPersistentDataContainer implements PersistentDataContain
|
||||
Validate.notNull(value, "The provided value for the custom value was null");
|
||||
|
||||
this.customDataTags.put(key.toString(), registry.wrap(type.getPrimitiveType(), type.toPrimitive(value, adapterContext)));
|
||||
callback.onValueChange();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -91,6 +103,7 @@ public final class CraftPersistentDataContainer implements PersistentDataContain
|
||||
Validate.notNull(key, "The provided key for the custom value was null");
|
||||
|
||||
this.customDataTags.remove(key.toString());
|
||||
callback.onValueChange();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -125,16 +138,19 @@ public final class CraftPersistentDataContainer implements PersistentDataContain
|
||||
|
||||
public void put(String key, NBTBase base) {
|
||||
this.customDataTags.put(key, base);
|
||||
callback.onValueChange();
|
||||
}
|
||||
|
||||
public void putAll(Map<String, NBTBase> map) {
|
||||
this.customDataTags.putAll(map);
|
||||
callback.onValueChange();
|
||||
}
|
||||
|
||||
public void putAll(NBTTagCompound compound) {
|
||||
for (String key : compound.getAllKeys()) {
|
||||
this.customDataTags.put(key, compound.get(key));
|
||||
}
|
||||
callback.onValueChange();
|
||||
}
|
||||
|
||||
public Map<String, NBTBase> getRaw() {
|
||||
@ -155,4 +171,9 @@ public final class CraftPersistentDataContainer implements PersistentDataContain
|
||||
public Map<String, Object> serialize() {
|
||||
return (Map<String, Object>) CraftNBTTagConfigSerializer.serialize(toTagCompound());
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Callback {
|
||||
void onValueChange();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user