change storage format to short identifiers, fix bush update causing potential stack overflow on drop check

This commit is contained in:
Sen 2025-07-28 18:53:06 +02:00
parent b9753203ec
commit 7fb0edff33
Signed by: sen
GPG key ID: 3AC50A6F47D1B722
3 changed files with 56 additions and 56 deletions

View file

@ -60,7 +60,7 @@ public class BlockBush extends Block
if (!this.canBlockStay(worldIn, pos, state))
{
this.drop(worldIn, pos, state, 0);
worldIn.setState(pos, Blocks.air.getState(), 3);
worldIn.setState(pos, Blocks.air.getState(), 2); // avoid recursion
}
}

View file

@ -1589,7 +1589,7 @@ public abstract class Converter {
for(int i = 0; i < oldheight.length; ++i) {
height[i] = oldheight[i];
}
ntag.setIntArray("HeightMap", height);
ntag.setIntArray("H", height);
byte[] oldblks = tag.getByteArray("Blocks");
byte[] olddata = tag.getByteArray("Data");
byte[] oldsky = tag.getByteArray("SkyLight");
@ -1635,14 +1635,14 @@ public abstract class Converter {
sections.add(section);
}
}
ntag.setList("Sections", sections);
ntag.setList("S", sections);
}
else {
ntag.setIntArray("HeightMap", tag.getIntArray("HeightMap"));
ntag.setIntArray("H", tag.getIntArray("HeightMap"));
}
ntag.setBool("TerrainPopulated", true);
ntag.setBool("LightPopulated", tag.getByte("LightPopulated") != 0);
ntag.setBool("P", true);
ntag.setBool("L", tag.getByte("LightPopulated") != 0);
NbtTag[] ents = tag.getTagList("Entities");
List<TagObject> entities = Lists.newArrayList();
@ -1669,7 +1669,7 @@ public abstract class Converter {
entities.add(nent);
}
}
ntag.setList("Entities", entities);
ntag.setList("E", entities);
ents = tag.getTagList("TileEntities");
entities = Lists.newArrayList();
@ -1678,13 +1678,13 @@ public abstract class Converter {
Class<? extends TileEntity> mapped = TILE_MAP.get(trimColon(ent.getString("id")));
if(mapped != null) {
nent = convertTile(ent, mapped);
nent.setByte("x", (byte)(ent.getInt("x") & 15));
nent.setShort("y", (short)ent.getInt("y"));
nent.setByte("z", (byte)(ent.getInt("z") & 15));
nent.setByte("X", (byte)(ent.getInt("x") & 15));
nent.setShort("Y", (short)ent.getInt("y"));
nent.setByte("Z", (byte)(ent.getInt("z") & 15));
entities.add(nent);
}
}
ntag.setList("TileEntities", entities);
ntag.setList("B", entities);
NbtTag[] sects = tag.getTagList("Sections");
entities = Lists.newArrayList();
@ -1739,9 +1739,9 @@ public abstract class Converter {
TagObject nsect = new TagObject();
nsect.setInt("Y", y);
nsect.setByteArray("Data", newblks);
nsect.setByteArray("BlockLight", sect.getByteArray("BlockLight"));
nsect.setByteArray("SkyLight", sect.getByteArray("SkyLight"));
nsect.setByteArray("D", newblks);
nsect.setByteArray("B", sect.getByteArray("BlockLight"));
nsect.setByteArray("S", sect.getByteArray("SkyLight"));
entities.add(nsect);
}
@ -1749,7 +1749,7 @@ public abstract class Converter {
lastData = data;
lastAdd = adddata;
}
ntag.setList("Sections", entities);
ntag.setList("S", entities);
return ntag;
}

View file

@ -478,17 +478,17 @@ public class Region {
// return null;
// }
// tag = tag.getCompoundTag("Level");
if(!tag.hasList("Sections")) {
if(!tag.hasList("S")) {
Log.IO.warn("Chunk-Datei bei " + x + "," + z + " hat keine Block-Daten, überspringe");
return null;
}
int version = tag.getInt("Version");
int version = tag.getInt("V");
ChunkServer chunk = new ChunkServer(world, x, z);
chunk.setHeights(tag.getIntArray("HeightMap"));
chunk.setTerrainPopulated(tag.getBool("TerrainPopulated"));
chunk.setLightPopulated(tag.getBool("LightPopulated"));
chunk.setInhabited(tag.getLong("InhabitedTime"));
List<TagObject> sects = tag.getList("Sections");
chunk.setHeights(tag.getIntArray("H"));
chunk.setTerrainPopulated(tag.getBool("P"));
chunk.setLightPopulated(tag.getBool("L"));
chunk.setInhabited(tag.getLong("I"));
List<TagObject> sects = tag.getList("S");
BlockArray[] sections = new BlockArray[sects.size()];
boolean light = world.dimension.hasSkyLight();
@ -496,7 +496,7 @@ public class Region {
TagObject sect = sects.get(n);
int y = sect.getInt("Y");
BlockArray storage = new BlockArray(y << 4, light, y < 0 ? world.dimension.getFiller() : null);
byte[] blocks = sect.getByteArray("Data");
byte[] blocks = sect.getByteArray("D");
char[] seg = new char[blocks.length >> 1];
for(int c = 0; c < seg.length; ++c) {
@ -504,10 +504,10 @@ public class Region {
}
storage.setData(seg);
storage.setBlocklight(new NibbleArray(sect.getByteArray("BlockLight")));
storage.setBlocklight(new NibbleArray(sect.getByteArray("B")));
if(light) {
storage.setSkylight(new NibbleArray(sect.getByteArray("SkyLight")));
storage.setSkylight(new NibbleArray(sect.getByteArray("S")));
}
storage.update();
@ -516,7 +516,7 @@ public class Region {
chunk.setStorage(sections);
List<TagObject> entities = tag.getList("Entities");
List<TagObject> entities = tag.getList("E");
if(entities != null) {
for(int n = 0; n < entities.size(); ++n) {
@ -542,12 +542,12 @@ public class Region {
}
}
List<TagObject> tiles = tag.getList("TileEntities");
List<TagObject> tiles = tag.getList("B");
if(tiles != null) {
for(int n = 0; n < tiles.size(); ++n) {
TagObject tile = tiles.get(n);
BlockPos pos = new BlockPos(tile.getByte("x"), tile.getShort("y"), tile.getByte("z"));
BlockPos pos = new BlockPos(tile.getByte("X"), tile.getShort("Y"), tile.getByte("Z"));
if(pos.getX() < 0 || pos.getX() >= 16 || pos.getZ() < 0 || pos.getZ() >= 16 || pos.getY() < -World.MAX_SIZE_Y || pos.getY() >= World.MAX_SIZE_Y) {
Log.TICK.warn("Ignoriere Block-Objekt mit ungültigen Koordinaten %d, %d, %d in Chunk %d, %d", pos.getX(), pos.getY(), pos.getZ(), chunk.xPos, chunk.zPos);
continue;
@ -561,21 +561,21 @@ public class Region {
}
}
if(tag.hasList("TileTicks")) {
List<TagObject> ticks = tag.getList("TileTicks");
if(tag.hasList("T")) {
List<TagObject> ticks = tag.getList("T");
if(ticks != null) {
int invalid = 0;
for(int n = 0; n < ticks.size(); ++n) {
TagObject tick = ticks.get(n);
Block block = BlockRegistry.byName(tick.getString("i"));
Block block = BlockRegistry.byName(tick.getString("B"));
if(block != Blocks.air) { // FIX
world.scheduleBlockUpdate(new BlockPos(tick.getInt("x"), tick.getInt("y"), tick.getInt("z")), block,
tick.getInt("t"), tick.getInt("p"));
world.scheduleBlockUpdate(new BlockPos(tick.getInt("X"), tick.getInt("Y"), tick.getInt("Z")), block,
tick.getInt("T"), tick.getInt("P"));
}
else if(invalid++ < 10) {
Log.IO.warn("Unbekannter Block-Tick in Chunk " + x + "," + z + ": '" + tick.getString("i") + "'");
Log.IO.warn("Unbekannter Block-Tick in Chunk " + x + "," + z + ": '" + tick.getString("B") + "'");
}
}
if(invalid > 10) {
@ -589,11 +589,11 @@ public class Region {
public static TagObject writeChunk(WorldServer world, ChunkServer chunk) {
TagObject tag = new TagObject();
tag.setLong("LastUpdate", world.getTime());
tag.setIntArray("HeightMap", chunk.getHeights());
tag.setBool("TerrainPopulated", chunk.isTerrainPopulated());
tag.setBool("LightPopulated", chunk.isLightPopulated());
tag.setLong("InhabitedTime", chunk.getInhabited());
tag.setLong("U", world.getTime());
tag.setIntArray("H", chunk.getHeights());
tag.setBool("P", chunk.isTerrainPopulated());
tag.setBool("L", chunk.isLightPopulated());
tag.setLong("I", chunk.getInhabited());
Set<BlockArray> sections = chunk.getStorage();
List<TagObject> sects = Lists.newArrayList();
boolean light = world.dimension.hasSkyLight();
@ -610,22 +610,22 @@ public class Region {
blocks[(c << 1) | 1] = (byte)(cd & 255);
}
sect.setByteArray("Data", blocks);
sect.setByteArray("D", blocks);
sect.setByteArray("BlockLight", storage.getBlocklight().getData());
sect.setByteArray("B", storage.getBlocklight().getData());
if(light) {
sect.setByteArray("SkyLight", storage.getSkylight().getData());
sect.setByteArray("S", storage.getSkylight().getData());
}
else {
sect.setByteArray("SkyLight", new byte[storage.getBlocklight().getData().length]);
sect.setByteArray("S", new byte[storage.getBlocklight().getData().length]);
}
sects.add(sect);
}
}
tag.setList("Sections", sects);
tag.setList("S", sects);
chunk.setHasEntities(false);
List<TagObject> entities = Lists.newArrayList();
@ -640,19 +640,19 @@ public class Region {
}
}
tag.setList("Entities", entities);
tag.setList("E", entities);
List<TagObject> tiles = Lists.newArrayList();
for(TileEntity tileentity : chunk.getTiles().values()) {
TagObject tile = new TagObject();
tileentity.writeTags(tile);
tile.setByte("x", (byte)(tileentity.getPos().getX() & 15));
tile.setShort("y", (short)tileentity.getPos().getY());
tile.setByte("z", (byte)(tileentity.getPos().getZ() & 15));
tile.setByte("X", (byte)(tileentity.getPos().getX() & 15));
tile.setShort("Y", (short)tileentity.getPos().getY());
tile.setByte("Z", (byte)(tileentity.getPos().getZ() & 15));
tiles.add(tile);
}
tag.setList("TileEntities", tiles);
tag.setList("B", tiles);
List<NextTickListEntry> tics = world.getPendingBlockUpdates(chunk);
if(tics != null) {
@ -664,16 +664,16 @@ public class Region {
continue;
TagObject tick = new TagObject();
String res = BlockRegistry.getName(tic.getBlock());
tick.setString("i", res == null ? "" : res);
tick.setInt("x", tic.position.getX());
tick.setInt("y", tic.position.getY());
tick.setInt("z", tic.position.getZ());
tick.setInt("t", (int)(tic.scheduledTime - time));
tick.setInt("p", tic.priority);
tick.setString("B", res == null ? "" : res);
tick.setInt("X", tic.position.getX());
tick.setInt("Y", tic.position.getY());
tick.setInt("Z", tic.position.getZ());
tick.setInt("T", (int)(tic.scheduledTime - time));
tick.setInt("P", tic.priority);
ticks.add(tick);
}
tag.setList("TileTicks", ticks);
tag.setList("T", ticks);
}
return tag;