make chunk storage a map

This commit is contained in:
Sen 2025-05-21 15:31:50 +02:00
parent 5e2b36dc82
commit 2dd83c61dc
9 changed files with 144 additions and 328 deletions

View file

@ -985,7 +985,7 @@ public class Player extends NetHandler implements ICrafting, Executor, IPlayer
{
if (list.size() == 1)
{
this.sendPacket(new SPacketChunkData((Chunk)list.get(0), true, 0xffffffff, null));
this.sendPacket(new SPacketChunkData((Chunk)list.get(0), true, null));
}
else
{

View file

@ -14,6 +14,7 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterInputStream;
@ -375,18 +376,7 @@ public class Region {
chunk.setLightPopulated(tag.getBoolean("LightPopulated"));
chunk.setInhabited(tag.getLong("InhabitedTime"));
NBTTagList sects = tag.getTagList("Sections", 10);
int stor = 32;
int min = 0;
int max = stor - 1;
for(int n = 0; n < sects.tagCount(); ++n) {
NBTTagCompound sect = sects.getCompoundTagAt(n);
int y = sect.getInteger("Y");
min = y < min ? y : min;
max = y > max ? y : max;
}
BlockArray[] sections = new BlockArray[stor];
BlockArray[] down = min < 0 ? new BlockArray[-min] : null;
BlockArray[] up = max >= stor ? new BlockArray[1 + max - stor] : null;
BlockArray[] sections = new BlockArray[sects.tagCount()];
boolean light = !world.dimension.hasNoLight();
for(int n = 0; n < sects.tagCount(); ++n) {
@ -414,15 +404,10 @@ public class Region {
}
storage.update();
if(y >= 0 && y < stor)
sections[y] = storage;
else if(y < 0)
down[down.length + y] = storage;
else
up[y - stor] = storage;
sections[n] = storage;
}
chunk.setStorage(sections, down, up);
chunk.setStorage(sections);
if(tag.hasKey("Biomes", 7)) {
chunk.setBiomes(tag.getByteArray("Biomes"));
@ -509,59 +494,53 @@ public class Region {
tag.setBoolean("TerrainPopulated", chunk.isTerrainPopulated());
tag.setBoolean("LightPopulated", chunk.isLightPopulated());
tag.setLong("InhabitedTime", chunk.getInhabited());
BlockArray[] sections = chunk.getStorage();
BlockArray[] down = chunk.getStorageDown();
BlockArray[] up = chunk.getStorageUp();
Set<BlockArray> sections = chunk.getStorage();
NBTTagList sects = new NBTTagList();
boolean light = !world.dimension.hasNoLight();
for(BlockArray[] sec : new BlockArray[][] {sections, down, up}) {
if(sec == null)
continue;
for(BlockArray storage : sec) {
if(storage != null) {
NBTTagCompound sect = new NBTTagCompound();
sect.setInteger("Y", storage.getY() >> 4);
byte[] blocks = new byte[storage.getData().length];
NibbleArray data = new NibbleArray();
NibbleArray adddata = null;
for(int c = 0; c < storage.getData().length; ++c) {
char cd = storage.getData()[c];
int cx = c & 15;
int cy = c >> 8 & 15;
int cz = c >> 4 & 15;
if(cd >> 12 != 0) {
if(adddata == null) {
adddata = new NibbleArray();
}
adddata.set(cx, cy, cz, cd >> 12);
for(BlockArray storage : sections) {
if(storage != null) {
NBTTagCompound sect = new NBTTagCompound();
sect.setInteger("Y", storage.getY() >> 4);
byte[] blocks = new byte[storage.getData().length];
NibbleArray data = new NibbleArray();
NibbleArray adddata = null;
for(int c = 0; c < storage.getData().length; ++c) {
char cd = storage.getData()[c];
int cx = c & 15;
int cy = c >> 8 & 15;
int cz = c >> 4 & 15;
if(cd >> 12 != 0) {
if(adddata == null) {
adddata = new NibbleArray();
}
blocks[c] = (byte)(cd >> 4 & 255);
data.set(cx, cy, cz, cd & 15);
adddata.set(cx, cy, cz, cd >> 12);
}
sect.setByteArray("Blocks", blocks);
sect.setByteArray("Data", data.getData());
if(adddata != null) {
sect.setByteArray("Add", adddata.getData());
}
sect.setByteArray("BlockLight", storage.getBlocklight().getData());
if(light) {
sect.setByteArray("SkyLight", storage.getSkylight().getData());
}
else {
sect.setByteArray("SkyLight", new byte[storage.getBlocklight().getData().length]);
}
sects.appendTag(sect);
blocks[c] = (byte)(cd >> 4 & 255);
data.set(cx, cy, cz, cd & 15);
}
sect.setByteArray("Blocks", blocks);
sect.setByteArray("Data", data.getData());
if(adddata != null) {
sect.setByteArray("Add", adddata.getData());
}
sect.setByteArray("BlockLight", storage.getBlocklight().getData());
if(light) {
sect.setByteArray("SkyLight", storage.getSkylight().getData());
}
else {
sect.setByteArray("SkyLight", new byte[storage.getBlocklight().getData().length]);
}
sects.appendTag(sect);
}
}

View file

@ -146,6 +146,7 @@ public final class WorldServer extends AWorldServer {
private final IntHashMap<EntityTrackerEntry> trackMap = new IntHashMap();
private final Map<String, WorldSavedData> dataMap = Maps.<String, WorldSavedData>newHashMap();
private final List<WorldSavedData> dataList = Lists.<WorldSavedData>newArrayList();
private final List<BlockArray> toTick = Lists.newArrayList();
private final Biome[] biomes = new Biome[256];
private MapGenCaves caveGen;
@ -712,7 +713,8 @@ public final class WorldServer extends AWorldServer {
l2 = Config.randomTick;
if(l2 > 0) {
for(BlockArray extendedblockstorage : chunk.getStorage()) {
this.toTick.addAll(chunk.getStorage());
for(BlockArray extendedblockstorage : this.toTick) {
if(extendedblockstorage != null && extendedblockstorage.isTicked()) {
for(int j1 = 0; j1 < l2; ++j1) {
this.updateLCG = this.updateLCG * 3 + 1013904223;
@ -732,6 +734,7 @@ public final class WorldServer extends AWorldServer {
}
}
}
this.toTick.clear();
}
// this.profiler.end();
@ -2808,7 +2811,6 @@ public final class WorldServer extends AWorldServer {
private final ChunkPos position;
private int updates;
private int sections;
private long prevTime;
private boolean biomes;
@ -2837,7 +2839,7 @@ public final class WorldServer extends AWorldServer {
Chunk chunk = WorldServer.this.getChunk(this.position.x, this.position.z);
if(chunk.isPopulated()) {
player.connection.sendPacket(new SPacketChunkData(chunk, true, 0, new int[0]));
player.connection.sendPacket(new SPacketChunkData(chunk, true, new int[0]));
}
this.watching.remove(player);
@ -2866,7 +2868,6 @@ public final class WorldServer extends AWorldServer {
if(this.updates == 0)
WorldServer.this.toUpdate.add(this);
this.updates = 64;
this.sections = 0xffffffff;
this.biomes = true;
}
@ -2880,10 +2881,7 @@ public final class WorldServer extends AWorldServer {
WorldServer.this.toUpdate.add(this);
}
if(y >= 0 && y >> 4 < 32)
this.sections |= 1 << (y >> 4);
else
this.extend.add(y >> 4);
this.extend.add(y >> 4);
if(this.updates < 64) {
long pos = ((long)x & 4294967295L) << 36 | ((long)z & 4294967295L) << 32 | (y & 4294967295L);
@ -2933,7 +2931,7 @@ public final class WorldServer extends AWorldServer {
}
}
this.sendToAllPlayersWatchingChunk(new SPacketChunkData(WorldServer.this.getChunk(this.position.x, this.position.z),
this.biomes, this.sections, extend));
this.biomes, extend));
if(this.biomes) {
List<TileEntity> list = WorldServer.this.getTileEntitiesIn(x, Integer.MIN_VALUE, z, x + 16, Integer.MAX_VALUE, z + 16);
@ -2943,16 +2941,6 @@ public final class WorldServer extends AWorldServer {
}
}
else {
for(int cy = 0; cy < 32; ++cy) {
if((this.sections & 1 << cy) != 0) {
int y = cy << 4;
List<TileEntity> list = WorldServer.this.getTileEntitiesIn(x, y, z, x + 16, y + 16, z + 16);
for(int n = 0; n < list.size(); ++n) {
this.sendTileToAllPlayersWatchingChunk(list.get(n));
}
}
}
for(Integer cy : this.extend) {
int y = cy << 4;
List<TileEntity> list = WorldServer.this.getTileEntitiesIn(x, y, z, x + 16, y + 16, z + 16);
@ -2980,7 +2968,6 @@ public final class WorldServer extends AWorldServer {
}
this.updates = 0;
this.sections = 0;
this.extend.clear();
this.biomes = false;
}