fix: create new biome paletted container when writing (#2791)

- resizing a paletted container copy alters the original paletted container
 - copy is not clone
 - fixes #2790
This commit is contained in:
Jordan 2024-06-20 20:49:16 +02:00 committed by GitHub
parent d69dc97958
commit 705df34c12
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 95 additions and 120 deletions

View File

@ -824,7 +824,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
nmsChunk.mustNotSave = false; nmsChunk.mustNotSave = false;
nmsChunk.setUnsaved(true); nmsChunk.setUnsaved(true);
// send to player // send to player
if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING) { if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING || finalMask == 0 && biomes != null) {
this.send(); this.send();
} }
if (finalizer != null) { if (finalizer != null) {
@ -1109,31 +1109,21 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) {
return null; return null;
} }
PalettedContainer<Holder<Biome>> biomeData; PalettedContainer<Holder<Biome>> biomeData = data.recreate();
if (data instanceof PalettedContainer<Holder<Biome>> palettedContainer) {
biomeData = palettedContainer.copy();
} else {
LOGGER.warn(
"Cannot correctly set biomes to world, existing biomes may be lost. Expected class " +
"type {} but got {}",
PalettedContainer.class.getSimpleName(),
data.getClass().getSimpleName()
);
biomeData = data.recreate();
}
for (int y = 0, index = 0; y < 4; y++) { for (int y = 0, index = 0; y < 4; y++) {
for (int z = 0; z < 4; z++) { for (int z = 0; z < 4; z++) {
for (int x = 0; x < 4; x++, index++) { for (int x = 0; x < 4; x++, index++) {
BiomeType biomeType = sectionBiomes[index]; BiomeType biomeType = sectionBiomes[index];
if (biomeType == null) { if (biomeType == null) {
continue; biomeData.set(x, y, z, data.get(x, y, z));
} else {
biomeData.set(
x,
y,
z,
biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType))
);
} }
biomeData.set(
x,
y,
z,
biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType))
);
} }
} }
} }

View File

@ -45,7 +45,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
private final int maxHeight; private final int maxHeight;
final ServerLevel serverLevel; final ServerLevel serverLevel;
final LevelChunk levelChunk; final LevelChunk levelChunk;
private PalettedContainer<Holder<Biome>>[] biomes = null; private Holder<Biome>[][] biomes = null;
protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) {
this.levelChunk = levelChunk; this.levelChunk = levelChunk;
@ -144,7 +144,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
@Override @Override
public BiomeType getBiomeType(int x, int y, int z) { public BiomeType getBiomeType(int x, int y, int z) {
Holder<Biome> biome = biomes[(y >> 4) - getMinSectionPosition()].get(x >> 2, (y & 15) >> 2, z >> 2); Holder<Biome> biome = biomes[(y >> 4) - getMinSectionPosition()][(y & 12) << 2 | (z & 12) | (x & 12) >> 2];
return PaperweightPlatformAdapter.adapt(biome, serverLevel); return PaperweightPlatformAdapter.adapt(biome, serverLevel);
} }
@ -173,10 +173,15 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
protected void storeBiomes(int layer, PalettedContainerRO<Holder<Biome>> biomeData) { protected void storeBiomes(int layer, PalettedContainerRO<Holder<Biome>> biomeData) {
if (biomes == null) { if (biomes == null) {
biomes = new PalettedContainer[getSectionCount()]; biomes = new Holder[getSectionCount()][];
}
if (biomes[layer] == null) {
biomes[layer] = new Holder[64];
} }
if (biomeData instanceof PalettedContainer<Holder<Biome>> palettedContainer) { if (biomeData instanceof PalettedContainer<Holder<Biome>> palettedContainer) {
biomes[layer] = palettedContainer.copy(); for (int i = 0; i < 64; i++) {
biomes[layer][i] = palettedContainer.get(i);
}
} else { } else {
LOGGER.error( LOGGER.error(
"Cannot correctly save biomes to history. Expected class type {} but got {}", "Cannot correctly save biomes to history. Expected class type {} but got {}",

View File

@ -822,7 +822,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
nmsChunk.mustNotSave = false; nmsChunk.mustNotSave = false;
nmsChunk.setUnsaved(true); nmsChunk.setUnsaved(true);
// send to player // send to player
if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING) { if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING || finalMask == 0 && biomes != null) {
this.send(); this.send();
} }
if (finalizer != null) { if (finalizer != null) {
@ -1106,31 +1106,21 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) {
return null; return null;
} }
PalettedContainer<Holder<Biome>> biomeData; PalettedContainer<Holder<Biome>> biomeData = data.recreate();
if (data instanceof PalettedContainer<Holder<Biome>> palettedContainer) {
biomeData = palettedContainer.copy();
} else {
LOGGER.warn(
"Cannot correctly set biomes to world, existing biomes may be lost. Expected class " +
"type {} but got {}",
PalettedContainer.class.getSimpleName(),
data.getClass().getSimpleName()
);
biomeData = data.recreate();
}
for (int y = 0, index = 0; y < 4; y++) { for (int y = 0, index = 0; y < 4; y++) {
for (int z = 0; z < 4; z++) { for (int z = 0; z < 4; z++) {
for (int x = 0; x < 4; x++, index++) { for (int x = 0; x < 4; x++, index++) {
BiomeType biomeType = sectionBiomes[index]; BiomeType biomeType = sectionBiomes[index];
if (biomeType == null) { if (biomeType == null) {
continue; biomeData.set(x, y, z, data.get(x, y, z));
} else {
biomeData.set(
x,
y,
z,
biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType))
);
} }
biomeData.set(
x,
y,
z,
biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType))
);
} }
} }
} }

View File

@ -45,7 +45,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
private final int maxHeight; private final int maxHeight;
final ServerLevel serverLevel; final ServerLevel serverLevel;
final LevelChunk levelChunk; final LevelChunk levelChunk;
private PalettedContainer<Holder<Biome>>[] biomes = null; private Holder<Biome>[][] biomes = null;
protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) {
this.levelChunk = levelChunk; this.levelChunk = levelChunk;
@ -144,7 +144,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
@Override @Override
public BiomeType getBiomeType(int x, int y, int z) { public BiomeType getBiomeType(int x, int y, int z) {
Holder<Biome> biome = biomes[(y >> 4) - getMinSectionPosition()].get(x >> 2, (y & 15) >> 2, z >> 2); Holder<Biome> biome = biomes[(y >> 4) - getMinSectionPosition()][(y & 12) << 2 | (z & 12) | (x & 12) >> 2];
return PaperweightPlatformAdapter.adapt(biome, serverLevel); return PaperweightPlatformAdapter.adapt(biome, serverLevel);
} }
@ -173,10 +173,15 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
protected void storeBiomes(int layer, PalettedContainerRO<Holder<Biome>> biomeData) { protected void storeBiomes(int layer, PalettedContainerRO<Holder<Biome>> biomeData) {
if (biomes == null) { if (biomes == null) {
biomes = new PalettedContainer[getSectionCount()]; biomes = new Holder[getSectionCount()][];
}
if (biomes[layer] == null) {
biomes[layer] = new Holder[64];
} }
if (biomeData instanceof PalettedContainer<Holder<Biome>> palettedContainer) { if (biomeData instanceof PalettedContainer<Holder<Biome>> palettedContainer) {
biomes[layer] = palettedContainer.copy(); for (int i = 0; i < 64; i++) {
biomes[layer][i] = palettedContainer.get(i);
}
} else { } else {
LOGGER.error( LOGGER.error(
"Cannot correctly save biomes to history. Expected class type {} but got {}", "Cannot correctly save biomes to history. Expected class type {} but got {}",

View File

@ -830,7 +830,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
nmsChunk.mustNotSave = false; nmsChunk.mustNotSave = false;
nmsChunk.setUnsaved(true); nmsChunk.setUnsaved(true);
// send to player // send to player
if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING) { if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING || finalMask == 0 && biomes != null) {
this.send(); this.send();
} }
if (finalizer != null) { if (finalizer != null) {
@ -1114,31 +1114,21 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) {
return null; return null;
} }
PalettedContainer<Holder<Biome>> biomeData; PalettedContainer<Holder<Biome>> biomeData = data.recreate();
if (data instanceof PalettedContainer<Holder<Biome>> palettedContainer) {
biomeData = palettedContainer.copy();
} else {
LOGGER.warn(
"Cannot correctly set biomes to world, existing biomes may be lost. Expected class " +
"type {} but got {}",
PalettedContainer.class.getSimpleName(),
data.getClass().getSimpleName()
);
biomeData = data.recreate();
}
for (int y = 0, index = 0; y < 4; y++) { for (int y = 0, index = 0; y < 4; y++) {
for (int z = 0; z < 4; z++) { for (int z = 0; z < 4; z++) {
for (int x = 0; x < 4; x++, index++) { for (int x = 0; x < 4; x++, index++) {
BiomeType biomeType = sectionBiomes[index]; BiomeType biomeType = sectionBiomes[index];
if (biomeType == null) { if (biomeType == null) {
continue; biomeData.set(x, y, z, data.get(x, y, z));
} else {
biomeData.set(
x,
y,
z,
biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType))
);
} }
biomeData.set(
x,
y,
z,
biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType))
);
} }
} }
} }

View File

@ -45,7 +45,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
private final int maxHeight; private final int maxHeight;
final ServerLevel serverLevel; final ServerLevel serverLevel;
final LevelChunk levelChunk; final LevelChunk levelChunk;
private PalettedContainer<Holder<Biome>>[] biomes = null; private Holder<Biome>[][] biomes = null;
protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) {
this.levelChunk = levelChunk; this.levelChunk = levelChunk;
@ -144,7 +144,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
@Override @Override
public BiomeType getBiomeType(int x, int y, int z) { public BiomeType getBiomeType(int x, int y, int z) {
Holder<Biome> biome = biomes[(y >> 4) - getMinSectionPosition()].get(x >> 2, (y & 15) >> 2, z >> 2); Holder<Biome> biome = biomes[(y >> 4) - getMinSectionPosition()][(y & 12) << 2 | (z & 12) | (x & 12) >> 2];
return PaperweightPlatformAdapter.adapt(biome, serverLevel); return PaperweightPlatformAdapter.adapt(biome, serverLevel);
} }
@ -173,10 +173,15 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
protected void storeBiomes(int layer, PalettedContainerRO<Holder<Biome>> biomeData) { protected void storeBiomes(int layer, PalettedContainerRO<Holder<Biome>> biomeData) {
if (biomes == null) { if (biomes == null) {
biomes = new PalettedContainer[getSectionCount()]; biomes = new Holder[getSectionCount()][];
}
if (biomes[layer] == null) {
biomes[layer] = new Holder[64];
} }
if (biomeData instanceof PalettedContainer<Holder<Biome>> palettedContainer) { if (biomeData instanceof PalettedContainer<Holder<Biome>> palettedContainer) {
biomes[layer] = palettedContainer.copy(); for (int i = 0; i < 64; i++) {
biomes[layer][i] = palettedContainer.get(i);
}
} else { } else {
LOGGER.error( LOGGER.error(
"Cannot correctly save biomes to history. Expected class type {} but got {}", "Cannot correctly save biomes to history. Expected class type {} but got {}",

View File

@ -829,7 +829,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
nmsChunk.mustNotSave = false; nmsChunk.mustNotSave = false;
nmsChunk.setUnsaved(true); nmsChunk.setUnsaved(true);
// send to player // send to player
if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING) { if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING || finalMask == 0 && biomes != null) {
this.send(); this.send();
} }
if (finalizer != null) { if (finalizer != null) {
@ -1111,31 +1111,21 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) {
return null; return null;
} }
PalettedContainer<Holder<Biome>> biomeData; PalettedContainer<Holder<Biome>> biomeData = data.recreate();
if (data instanceof PalettedContainer<Holder<Biome>> palettedContainer) {
biomeData = palettedContainer.copy();
} else {
LOGGER.warn(
"Cannot correctly set biomes to world, existing biomes may be lost. Expected class " +
"type {} but got {}",
PalettedContainer.class.getSimpleName(),
data.getClass().getSimpleName()
);
biomeData = data.recreate();
}
for (int y = 0, index = 0; y < 4; y++) { for (int y = 0, index = 0; y < 4; y++) {
for (int z = 0; z < 4; z++) { for (int z = 0; z < 4; z++) {
for (int x = 0; x < 4; x++, index++) { for (int x = 0; x < 4; x++, index++) {
BiomeType biomeType = sectionBiomes[index]; BiomeType biomeType = sectionBiomes[index];
if (biomeType == null) { if (biomeType == null) {
continue; biomeData.set(x, y, z, data.get(x, y, z));
} else {
biomeData.set(
x,
y,
z,
biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType))
);
} }
biomeData.set(
x,
y,
z,
biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType))
);
} }
} }
} }

View File

@ -45,7 +45,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
private final int maxHeight; private final int maxHeight;
final ServerLevel serverLevel; final ServerLevel serverLevel;
final LevelChunk levelChunk; final LevelChunk levelChunk;
private PalettedContainer<Holder<Biome>>[] biomes = null; private Holder<Biome>[][] biomes = null;
protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) {
this.levelChunk = levelChunk; this.levelChunk = levelChunk;
@ -144,7 +144,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
@Override @Override
public BiomeType getBiomeType(int x, int y, int z) { public BiomeType getBiomeType(int x, int y, int z) {
Holder<Biome> biome = biomes[(y >> 4) - getMinSectionPosition()].get(x >> 2, (y & 15) >> 2, z >> 2); Holder<Biome> biome = biomes[(y >> 4) - getMinSectionPosition()][(y & 12) << 2 | (z & 12) | (x & 12) >> 2];
return PaperweightPlatformAdapter.adapt(biome, serverLevel); return PaperweightPlatformAdapter.adapt(biome, serverLevel);
} }
@ -173,10 +173,15 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
protected void storeBiomes(int layer, PalettedContainerRO<Holder<Biome>> biomeData) { protected void storeBiomes(int layer, PalettedContainerRO<Holder<Biome>> biomeData) {
if (biomes == null) { if (biomes == null) {
biomes = new PalettedContainer[getSectionCount()]; biomes = new Holder[getSectionCount()][];
}
if (biomes[layer] == null) {
biomes[layer] = new Holder[64];
} }
if (biomeData instanceof PalettedContainer<Holder<Biome>> palettedContainer) { if (biomeData instanceof PalettedContainer<Holder<Biome>> palettedContainer) {
biomes[layer] = palettedContainer.copy(); for (int i = 0; i < 64; i++) {
biomes[layer][i] = palettedContainer.get(i);
}
} else { } else {
LOGGER.error( LOGGER.error(
"Cannot correctly save biomes to history. Expected class type {} but got {}", "Cannot correctly save biomes to history. Expected class type {} but got {}",

View File

@ -830,7 +830,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
nmsChunk.mustNotSave = false; nmsChunk.mustNotSave = false;
nmsChunk.setUnsaved(true); nmsChunk.setUnsaved(true);
// send to player // send to player
if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING) { if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING || finalMask == 0 && biomes != null) {
this.send(); this.send();
} }
if (finalizer != null) { if (finalizer != null) {
@ -1114,31 +1114,21 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) {
return null; return null;
} }
PalettedContainer<Holder<Biome>> biomeData; PalettedContainer<Holder<Biome>> biomeData = data.recreate();
if (data instanceof PalettedContainer<Holder<Biome>> palettedContainer) {
biomeData = palettedContainer.copy();
} else {
LOGGER.warn(
"Cannot correctly set biomes to world, existing biomes may be lost. Expected class " +
"type {} but got {}",
PalettedContainer.class.getSimpleName(),
data.getClass().getSimpleName()
);
biomeData = data.recreate();
}
for (int y = 0, index = 0; y < 4; y++) { for (int y = 0, index = 0; y < 4; y++) {
for (int z = 0; z < 4; z++) { for (int z = 0; z < 4; z++) {
for (int x = 0; x < 4; x++, index++) { for (int x = 0; x < 4; x++, index++) {
BiomeType biomeType = sectionBiomes[index]; BiomeType biomeType = sectionBiomes[index];
if (biomeType == null) { if (biomeType == null) {
continue; biomeData.set(x, y, z, data.get(x, y, z));
} else {
biomeData.set(
x,
y,
z,
biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType))
);
} }
biomeData.set(
x,
y,
z,
biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType))
);
} }
} }
} }

View File

@ -46,7 +46,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
private final int maxHeight; private final int maxHeight;
final ServerLevel serverLevel; final ServerLevel serverLevel;
final LevelChunk levelChunk; final LevelChunk levelChunk;
private PalettedContainer<Holder<Biome>>[] biomes = null; private Holder<Biome>[][] biomes = null;
protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) {
this.levelChunk = levelChunk; this.levelChunk = levelChunk;
@ -145,7 +145,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
@Override @Override
public BiomeType getBiomeType(int x, int y, int z) { public BiomeType getBiomeType(int x, int y, int z) {
Holder<Biome> biome = biomes[(y >> 4) - getMinSectionPosition()].get(x >> 2, (y & 15) >> 2, z >> 2); Holder<Biome> biome = biomes[(y >> 4) - getMinSectionPosition()][(y & 12) << 2 | (z & 12) | (x & 12) >> 2];
return PaperweightPlatformAdapter.adapt(biome, serverLevel); return PaperweightPlatformAdapter.adapt(biome, serverLevel);
} }
@ -174,10 +174,15 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
protected void storeBiomes(int layer, PalettedContainerRO<Holder<Biome>> biomeData) { protected void storeBiomes(int layer, PalettedContainerRO<Holder<Biome>> biomeData) {
if (biomes == null) { if (biomes == null) {
biomes = new PalettedContainer[getSectionCount()]; biomes = new Holder[getSectionCount()][];
}
if (biomes[layer] == null) {
biomes[layer] = new Holder[64];
} }
if (biomeData instanceof PalettedContainer<Holder<Biome>> palettedContainer) { if (biomeData instanceof PalettedContainer<Holder<Biome>> palettedContainer) {
biomes[layer] = palettedContainer.copy(); for (int i = 0; i < 64; i++) {
biomes[layer][i] = palettedContainer.get(i);
}
} else { } else {
LOGGER.error( LOGGER.error(
"Cannot correctly save biomes to history. Expected class type {} but got {}", "Cannot correctly save biomes to history. Expected class type {} but got {}",