From 2dd83c61dc3fdd22e8747e478aef16a09db46a25 Mon Sep 17 00:00:00 2001 From: Sen Date: Wed, 21 May 2025 15:31:50 +0200 Subject: [PATCH] make chunk storage a map --- client/src/client/network/ClientPlayer.java | 6 +- client/src/client/world/EmptyChunk.java | 2 +- .../src/common/packet/SPacketChunkData.java | 64 ++--- .../common/packet/SPacketMapChunkBulk.java | 13 +- common/src/common/world/BlockArray.java | 8 + common/src/common/world/Chunk.java | 239 +++++------------- server/src/server/network/Player.java | 2 +- server/src/server/world/Region.java | 111 ++++---- server/src/server/world/WorldServer.java | 27 +- 9 files changed, 144 insertions(+), 328 deletions(-) diff --git a/client/src/client/network/ClientPlayer.java b/client/src/client/network/ClientPlayer.java index ebea694..3a6b688 100755 --- a/client/src/client/network/ClientPlayer.java +++ b/client/src/client/network/ClientPlayer.java @@ -756,7 +756,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer if (packetIn.hasBiomes()) { - if (packetIn.getExtractedSize() == 0) + if (packetIn.getExtractedExtend().length == 0) { this.clientWorldController.doPreChunk(packetIn.getChunkX(), packetIn.getChunkZ(), false); return; @@ -767,7 +767,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer // this.clientWorldController.invalidateBlockReceiveRegion(packetIn.getChunkX() << 4, 0, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, 512, (packetIn.getChunkZ() << 4) + 15); Chunk chunk = this.clientWorldController.getChunk(packetIn.getChunkX(), packetIn.getChunkZ()); - chunk.setData(packetIn.getExtractedDataBytes(), packetIn.getExtractedSize(), packetIn.getExtractedExtend(), packetIn.hasBiomes()); + chunk.setData(packetIn.getExtractedDataBytes(), packetIn.getExtractedExtend(), packetIn.hasBiomes()); this.clientWorldController.markBlockRangeForRenderUpdate(packetIn.getChunkX() << 4, -World.MAX_SIZE_Y, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, World.MAX_SIZE_Y, (packetIn.getChunkZ() << 4) + 15); if (!packetIn.hasBiomes() || this.clientWorldController.dimension.hasNoLight()) // TODO: check @@ -1413,7 +1413,7 @@ public class ClientPlayer extends NetHandler implements IClientPlayer this.clientWorldController.doPreChunk(j, k, true); // this.clientWorldController.invalidateBlockReceiveRegion(j << 4, 0, k << 4, (j << 4) + 15, 512, (k << 4) + 15); Chunk chunk = this.clientWorldController.getChunk(j, k); - chunk.setData(packetIn.getChunkBytes(i), packetIn.getChunkSize(i), packetIn.getChunkExtend(i), true); + chunk.setData(packetIn.getChunkBytes(i), packetIn.getChunkExtend(i), true); this.clientWorldController.markBlockRangeForRenderUpdate(j << 4, -World.MAX_SIZE_Y, k << 4, (j << 4) + 15, World.MAX_SIZE_Y, (k << 4) + 15); if (this.clientWorldController.dimension.hasNoLight()) // TODO: check diff --git a/client/src/client/world/EmptyChunk.java b/client/src/client/world/EmptyChunk.java index c60a7ee..24ded26 100755 --- a/client/src/client/world/EmptyChunk.java +++ b/client/src/client/world/EmptyChunk.java @@ -105,7 +105,7 @@ public class EmptyChunk extends Chunk { return true; } - public void setData(byte[] data, int update, int[] extend, boolean biomes) { + public void setData(byte[] data, int[] extend, boolean biomes) { } public Biome getBiome(BlockPos pos, BiomeGenerator gen) { diff --git a/common/src/common/packet/SPacketChunkData.java b/common/src/common/packet/SPacketChunkData.java index e7d94bc..ee87912 100755 --- a/common/src/common/packet/SPacketChunkData.java +++ b/common/src/common/packet/SPacketChunkData.java @@ -2,6 +2,7 @@ package common.packet; import java.io.IOException; import java.util.List; +import java.util.Set; import common.collect.Lists; import common.network.IClientPlayer; @@ -21,12 +22,12 @@ public class SPacketChunkData implements Packet { } - public SPacketChunkData(Chunk chunkIn, boolean biomes, int segUpdate, int[] extend) + public SPacketChunkData(Chunk chunkIn, boolean biomes, int[] extend) { this.chunkX = chunkIn.xPos; this.chunkZ = chunkIn.zPos; this.biomes = biomes; - this.extractedData = getExtractedData(chunkIn, biomes, !chunkIn.getWorld().dimension.hasNoLight(), segUpdate, extend); + this.extractedData = getExtractedData(chunkIn, biomes, !chunkIn.getWorld().dimension.hasNoLight(), extend); } /** @@ -38,7 +39,6 @@ public class SPacketChunkData implements Packet this.chunkZ = buf.readInt(); this.biomes = buf.readBoolean(); this.extractedData = new SPacketChunkData.Extracted(); - this.extractedData.dataSize = buf.readInt(); this.extractedData.data = buf.readByteArray(); this.extractedData.extend = new int[buf.readVarIntFromBuffer()]; for(int z = 0; z < this.extractedData.extend.length; z++) { @@ -54,7 +54,6 @@ public class SPacketChunkData implements Packet buf.writeInt(this.chunkX); buf.writeInt(this.chunkZ); buf.writeBoolean(this.biomes); - buf.writeInt(this.extractedData.dataSize); buf.writeByteArray(this.extractedData.data); buf.writeVarIntToBuffer(this.extractedData.extend.length); for(int z = 0; z < this.extractedData.extend.length; z++) { @@ -84,55 +83,32 @@ public class SPacketChunkData implements Packet return i + j + k + l; } - public static SPacketChunkData.Extracted getExtractedData(Chunk chunk, boolean biomes, boolean overworld, int segUpdate, int[] extend) + public static SPacketChunkData.Extracted getExtractedData(Chunk chunk, boolean biomes, boolean overworld, int[] extend) { - BlockArray[] aextendedblockstorage = chunk.getStorage(); - BlockArray[] down = chunk.getStorageDown(); - BlockArray[] up = chunk.getStorageUp(); + Set aextendedblockstorage = chunk.getStorage(); SPacketChunkData.Extracted s21packetchunkdata$extracted = new SPacketChunkData.Extracted(); List list = Lists.newArrayList(); - - for (int i = 0; i < aextendedblockstorage.length; ++i) - { - BlockArray extendedblockstorage = aextendedblockstorage[i]; - - if (extendedblockstorage != null && (!biomes || !extendedblockstorage.isEmpty()) && (segUpdate & 1 << i) != 0) - { - s21packetchunkdata$extracted.dataSize |= 1 << i; - list.add(extendedblockstorage); - } - } - int epos = list.size(); + if(extend == null) { - if(down != null) { - for(BlockArray arr : down) { - if(arr != null && (!biomes || !arr.isEmpty())) - list.add(arr); - } - } - if(up != null) { - for(BlockArray arr : up) { - if(arr != null && (!biomes || !arr.isEmpty())) - list.add(arr); - } - } + for(BlockArray arr : aextendedblockstorage) { + if(arr != null && (!biomes || !arr.isEmpty())) + list.add(arr); + } } else { for(int cy : extend) { - if(cy < 0 || cy >= aextendedblockstorage.length) { - BlockArray arr = chunk.getArray(cy); - if(arr != null && (!biomes || !arr.isEmpty())) - list.add(arr); - } + BlockArray arr = chunk.getArray(cy); + if(arr != null && (!biomes || !arr.isEmpty())) + list.add(arr); } } - extend = new int[list.size() - epos]; + extend = new int[list.size()]; for(int z = 0; z < extend.length; z++) { - extend[z] = list.get(z + epos).getY() >> 4; + extend[z] = list.get(z).getY() >> 4; } s21packetchunkdata$extracted.extend = extend; - s21packetchunkdata$extracted.data = new byte[getSize(Integer.bitCount(s21packetchunkdata$extracted.dataSize) + extend.length, overworld, biomes)]; + s21packetchunkdata$extracted.data = new byte[getSize(extend.length, overworld, biomes)]; int j = 0; for (BlockArray extendedblockstorage1 : list) @@ -182,12 +158,7 @@ public class SPacketChunkData implements Packet { return this.chunkZ; } - - public int getExtractedSize() - { - return this.extractedData.dataSize; - } - + public int[] getExtractedExtend() { return this.extractedData.extend; @@ -201,7 +172,6 @@ public class SPacketChunkData implements Packet public static class Extracted { public byte[] data; - public int dataSize; public int[] extend; } } diff --git a/common/src/common/packet/SPacketMapChunkBulk.java b/common/src/common/packet/SPacketMapChunkBulk.java index f83bc61..4c7c4bb 100755 --- a/common/src/common/packet/SPacketMapChunkBulk.java +++ b/common/src/common/packet/SPacketMapChunkBulk.java @@ -30,7 +30,7 @@ public class SPacketMapChunkBulk implements Packet for (int j = 0; j < i; ++j) { Chunk chunk = (Chunk)chunks.get(j); - SPacketChunkData.Extracted s21packetchunkdata$extracted = SPacketChunkData.getExtractedData(chunk, true, this.isOverworld, 0xffffffff, null); + SPacketChunkData.Extracted s21packetchunkdata$extracted = SPacketChunkData.getExtractedData(chunk, true, this.isOverworld, null); this.xPositions[j] = chunk.xPos; this.zPositions[j] = chunk.zPos; this.chunksData[j] = s21packetchunkdata$extracted; @@ -53,12 +53,11 @@ public class SPacketMapChunkBulk implements Packet this.xPositions[j] = buf.readInt(); this.zPositions[j] = buf.readInt(); this.chunksData[j] = new SPacketChunkData.Extracted(); - this.chunksData[j].dataSize = buf.readInt(); this.chunksData[j].extend = new int[buf.readVarIntFromBuffer()]; for(int z = 0; z < this.chunksData[j].extend.length; z++) { this.chunksData[j].extend[z] = buf.readVarIntFromBuffer(); } - this.chunksData[j].data = new byte[SPacketChunkData.getSize(Integer.bitCount(this.chunksData[j].dataSize) + this.chunksData[j].extend.length, this.isOverworld, true)]; + this.chunksData[j].data = new byte[SPacketChunkData.getSize(this.chunksData[j].extend.length, this.isOverworld, true)]; } for (int k = 0; k < i; ++k) @@ -79,7 +78,6 @@ public class SPacketMapChunkBulk implements Packet { buf.writeInt(this.xPositions[i]); buf.writeInt(this.zPositions[i]); - buf.writeInt(this.chunksData[i].dataSize); buf.writeVarIntToBuffer(this.chunksData[i].extend.length); for(int z = 0; z < this.chunksData[i].extend.length; z++) { buf.writeVarIntToBuffer(this.chunksData[i].extend[z]); @@ -119,12 +117,7 @@ public class SPacketMapChunkBulk implements Packet { return this.chunksData[p_149256_1_].data; } - - public int getChunkSize(int p_179754_1_) - { - return this.chunksData[p_179754_1_].dataSize; - } - + public int[] getChunkExtend(int index) { return this.chunksData[index].extend; diff --git a/common/src/common/world/BlockArray.java b/common/src/common/world/BlockArray.java index effebfe..12dd515 100755 --- a/common/src/common/world/BlockArray.java +++ b/common/src/common/world/BlockArray.java @@ -127,4 +127,12 @@ public class BlockArray { public void setSkylight(NibbleArray data) { this.skylight = data; } + + public int hashCode() { + return this.yBase >> 4; + } + + public boolean equals(Object other) { + return other instanceof BlockArray && ((BlockArray)other).yBase == this.yBase; + } } diff --git a/common/src/common/world/Chunk.java b/common/src/common/world/Chunk.java index c4cfd85..6e6156c 100755 --- a/common/src/common/world/Chunk.java +++ b/common/src/common/world/Chunk.java @@ -3,6 +3,7 @@ package common.world; import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.function.Predicate; @@ -10,6 +11,7 @@ import common.biome.Biome; import common.block.Block; import common.block.ITileEntityProvider; import common.collect.Maps; +import common.collect.Sets; import common.entity.Entity; import common.init.BlockRegistry; import common.init.Blocks; @@ -23,6 +25,7 @@ import common.util.ChunkPos; import common.util.ClassInheritanceMultiMap; import common.util.ExtMath; import common.util.Facing; +import common.util.IntHashMap; import common.util.NibbleArray; import common.worldgen.BiomeGenerator; import common.worldgen.DebugStates; @@ -33,7 +36,8 @@ public class Chunk { private final World world; private final State filler; private final Block fillerBlock; - private final BlockArray[] blocks = new BlockArray[32]; + private final IntHashMap blocks = new IntHashMap(); + private final Set blockList = Sets.newHashSet(); private final byte[] biomes = new byte[256]; private final int[] precHeight = new int[256]; private final boolean[] updateSky = new boolean[256]; @@ -55,8 +59,6 @@ public class Chunk { private int top = Integer.MIN_VALUE; private long lastSave; private long inhabited; - private BlockArray[] extendDown; - private BlockArray[] extendUp; public Chunk(World world, int x, int z) { this.world = world; @@ -80,37 +82,49 @@ public class Chunk { State state = BlockRegistry.STATEMAP.getByValue(data[bx << 4 | bz | by << 8]); if(state != null && state.getBlock().getMaterial() != Material.air) { int y = by >> 4; - if(this.blocks[y] == null) - this.blocks[y] = new BlockArray(y << 4, sky, null); - this.blocks[y].set(bx, by & 15, bz, state); + BlockArray arr = this.getArray(y); + if(arr == null) { + arr = new BlockArray(y << 4, sky, null); + this.setArray(arr); + } + arr.set(bx, by & 15, bz, state); } } } } if(base != null) { - if(this.blocks[0] == null) - this.blocks[0] = new BlockArray(0, sky, null); + BlockArray arr = this.getArray(0); + if(arr == null) { + arr = new BlockArray(0, sky, null); + this.setArray(arr); + } for(int bx = 0; bx < 16; ++bx) { for(int bz = 0; bz < 16; ++bz) { for(int by = 0; by < 5; ++by) { if(by <= rand.zrange(5)) - this.blocks[0].set(bx, by, bz, base); + arr.set(bx, by, bz, base); } } } } if(ceil != null) { int y = (height - 1) >> 4; - if(this.blocks[y] == null) - this.blocks[y] = new BlockArray(y << 4, sky, null); + BlockArray arr = this.getArray(y); + if(arr == null) { + arr = new BlockArray(y << 4, sky, null); + this.setArray(arr); + } y = (height - 5) >> 4; - if(this.blocks[y] == null) - this.blocks[y] = new BlockArray(y << 4, sky, null); + arr = this.getArray(y); + if(arr == null) { + arr = new BlockArray(y << 4, sky, null); + this.setArray(arr); + } for(int bx = 0; bx < 16; ++bx) { for(int bz = 0; bz < 16; ++bz) { for(int by = height - 1; by >= height - 5; --by) { if(by >= (height - 1) - rand.zrange(5)) - this.blocks[by >> 4].set(bx, by & 15, bz, ceil); + this.getArray(by >> 4).set(bx, by & 15, bz, ceil); } } } @@ -133,47 +147,7 @@ public class Chunk { public int getHeight(int x, int z) { return this.height[z << 4 | x]; } - - private int findTopSegment() { - if(this.extendUp != null) { - for(int y = this.extendUp.length - 1; y >= 0; --y) { - if(this.extendUp[y] != null) - return this.extendUp[y].getY(); - } - } - for(int y = this.blocks.length - 1; y >= 0; --y) { - if(this.blocks[y] != null) - return this.blocks[y].getY(); - } - if(this.extendDown != null) { - for(int y = this.extendDown.length - 1; y >= 0; --y) { - if(this.extendDown[y] != null) - return this.extendDown[y].getY(); - } - } - return Integer.MIN_VALUE; - } - - private int findBottomSegment() { - if(this.extendDown != null) { - for(int y = 0; y < this.extendDown.length; ++y) { - if(this.extendDown[y] != null) - return this.extendDown[y].getY(); - } - } - for(int y = 0; y < this.blocks.length; ++y) { - if(this.blocks[y] != null) - return this.blocks[y].getY(); - } - if(this.extendUp != null) { - for(int y = 0; y < this.extendUp.length; ++y) { - if(this.extendUp[y] != null) - return this.extendUp[y].getY(); - } - } - return Integer.MAX_VALUE; - } - + public int getTopSegment() { return this.top; } @@ -182,50 +156,28 @@ public class Chunk { return this.bottom; } - public BlockArray[] getStorage() { - return this.blocks; - } - - public BlockArray[] getStorageDown() { - return this.extendDown; - } - - public BlockArray[] getStorageUp() { - return this.extendUp; + public Set getStorage() { + return this.blockList; } public BlockArray getArray(int y) { - return y >= 0 && y < this.blocks.length ? this.blocks[y] : (y < 0 ? (this.extendDown == null || -y > this.extendDown.length ? null : this.extendDown[this.extendDown.length + y]) : (this.extendUp == null || y - this.blocks.length >= this.extendUp.length ? null : this.extendUp[y - this.blocks.length])); + return this.blocks.lookup(y); } - private void setArray(int y, BlockArray array) { - if(y >= 0 && y < this.blocks.length) { - this.blocks[y] = array; - } - else if(y < 0) { - if(this.extendDown == null) { - this.extendDown = new BlockArray[-y]; - } - else if(this.extendDown.length < -y) { - BlockArray[] extendDown = this.extendDown; - this.extendDown = new BlockArray[-y]; - System.arraycopy(extendDown, 0, this.extendDown, -y - extendDown.length, extendDown.length); - } - this.extendDown[this.extendDown.length + y] = array; - } - else { - if(this.extendUp == null) { - this.extendUp = new BlockArray[1 + y - this.blocks.length]; - } - else if(this.extendUp.length <= y - this.blocks.length) { - BlockArray[] extendUp = this.extendUp; - this.extendUp = new BlockArray[1 + y - this.blocks.length]; - System.arraycopy(extendUp, 0, this.extendUp, 0, extendUp.length); - } - this.extendUp[y - this.blocks.length] = array; - } - this.bottom = this.findBottomSegment(); - this.top = this.findTopSegment(); + private void setArray(BlockArray array) { + int y = array.getY() >> 4; + this.blocks.addKey(y, array); + this.blockList.add(array); + y <<= 4; + this.bottom = y < this.bottom ? y : this.bottom; + this.top = y > this.top ? y : this.top; + } + + private void clearArrays() { + this.blocks.clearMap(); + this.blockList.clear(); + this.bottom = Integer.MAX_VALUE; + this.top = Integer.MIN_VALUE; } protected void genHeights() { @@ -475,19 +427,8 @@ public class Chunk { } private Block getBlock0(int x, int y, int z) { - if(y >= 0 && y >> 4 < this.blocks.length) { - BlockArray stor = this.blocks[y >> 4]; - return stor != null ? stor.getBlock(x, y & 15, z) : Blocks.air; - } - else if(y < 0 && this.extendDown != null && -(y >> 4) <= this.extendDown.length) { - BlockArray stor = this.extendDown[this.extendDown.length + (y >> 4)]; - return stor != null ? stor.getBlock(x, y & 15, z) : this.fillerBlock; - } - else if(y >> 4 >= this.blocks.length && this.extendUp != null && (y >> 4) - this.blocks.length < this.extendUp.length) { - BlockArray stor = this.extendUp[(y >> 4) - this.blocks.length]; - return stor != null ? stor.getBlock(x, y & 15, z) : Blocks.air; - } - return y < 0 ? this.fillerBlock : Blocks.air; + BlockArray stor = this.getArray(y >> 4); + return stor != null ? stor.getBlock(x, y & 15, z) : (y < 0 ? this.fillerBlock : Blocks.air); } public State getState(BlockPos pos) { @@ -496,19 +437,8 @@ public class Chunk { return state == null ? Blocks.air.getState() : state; } - if(pos.getY() >= 0 && pos.getY() >> 4 < this.blocks.length) { - BlockArray stor = this.blocks[pos.getY() >> 4]; - return stor != null ? stor.get(pos.getX() & 15, pos.getY() & 15, pos.getZ() & 15) : Blocks.air.getState(); - } - else if(pos.getY() < 0 && this.extendDown != null && -(pos.getY() >> 4) <= this.extendDown.length) { - BlockArray stor = this.extendDown[this.extendDown.length + (pos.getY() >> 4)]; - return stor != null ? stor.get(pos.getX() & 15, pos.getY() & 15, pos.getZ() & 15) : this.filler; - } - else if(pos.getY() >> 4 >= this.blocks.length && this.extendUp != null && (pos.getY() >> 4) - this.blocks.length < this.extendUp.length) { - BlockArray stor = this.extendUp[(pos.getY() >> 4) - this.blocks.length]; - return stor != null ? stor.get(pos.getX() & 15, pos.getY() & 15, pos.getZ() & 15) : Blocks.air.getState(); - } - return pos.getY() < 0 ? this.filler : Blocks.air.getState(); + BlockArray stor = this.getArray(pos.getY() >> 4); + return stor != null ? stor.get(pos.getX() & 15, pos.getY() & 15, pos.getZ() & 15) : (pos.getY() < 0 ? this.filler : Blocks.air.getState()); } public Block getBlock(BlockPos pos) { @@ -543,7 +473,7 @@ public class Chunk { } stor = new BlockArray(y >> 4 << 4, !this.world.dimension.hasNoLight(), y < 0 ? this.filler : null); - this.setArray(y >> 4, stor); + this.setArray(stor); up = y >= h; } @@ -632,7 +562,7 @@ public class Chunk { if(stor == null) { stor = new BlockArray(y >> 4 << 4, !this.world.dimension.hasNoLight(), y < 0 ? this.filler : null); - this.setArray(y >> 4, stor); + this.setArray(stor); this.genSkyLight(); } @@ -948,52 +878,24 @@ public class Chunk { return true; } - public void setStorage(BlockArray[] arrays, BlockArray[] down, BlockArray[] up) { - if(this.blocks.length != arrays.length) { - Log.JNI.warn("Konnte Sektionen des Chunks nicht setzen, Länge des Arrays ist " + arrays.length + " statt " - + this.blocks.length); - } - else { - for(int n = 0; n < this.blocks.length; ++n) { - this.blocks[n] = arrays[n]; - } - this.extendDown = down; - this.extendUp = up; - this.bottom = this.findBottomSegment(); - this.top = this.findTopSegment(); + public void setStorage(BlockArray[] data) { + for(BlockArray arr : data) { + this.setArray(arr); } } - public void setData(byte[] data, int update, int[] extend, boolean biomes) { + public void setData(byte[] data, int[] extend, boolean biomes) { int pos = 0; boolean sky = !this.world.dimension.hasNoLight(); - - for(int n = 0; n < this.blocks.length; ++n) { - if((update & 1 << n) != 0) { - if(this.blocks[n] == null) { - this.blocks[n] = new BlockArray(n << 4, sky, null); - } - - char[] blocks = this.blocks[n].getData(); - - for(int k = 0; k < blocks.length; ++k) { - blocks[k] = (char)((data[pos + 1] & 255) << 8 | data[pos] & 255); - pos += 2; - } - } - else if(biomes && this.blocks[n] != null) { - this.blocks[n] = null; - } - } + if(biomes) { - this.extendDown = null; - this.extendUp = null; + this.clearArrays(); } for(int cy : extend) { BlockArray arr = this.getArray(cy); if(arr == null) { arr = new BlockArray(cy << 4, sky, null); - this.setArray(cy, arr); + this.setArray(arr); } char[] blocks = arr.getData(); @@ -1004,13 +906,6 @@ public class Chunk { } } - for(int n = 0; n < this.blocks.length; ++n) { - if((update & 1 << n) != 0 && this.blocks[n] != null) { - NibbleArray light = this.blocks[n].getBlocklight(); - System.arraycopy(data, pos, light.getData(), 0, light.getData().length); - pos += light.getData().length; - } - } for(int cy : extend) { BlockArray arr = this.getArray(cy); if(arr != null) { @@ -1021,13 +916,6 @@ public class Chunk { } if(sky) { - for(int n = 0; n < this.blocks.length; ++n) { - if((update & 1 << n) != 0 && this.blocks[n] != null) { - NibbleArray slight = this.blocks[n].getSkylight(); - System.arraycopy(data, pos, slight.getData(), 0, slight.getData().length); - pos += slight.getData().length; - } - } for(int cy : extend) { BlockArray arr = this.getArray(cy); if(arr != null) { @@ -1040,17 +928,8 @@ public class Chunk { if(biomes) { System.arraycopy(data, pos, this.biomes, 0, this.biomes.length); -// int unk = pos + this.biomes.length; } - this.bottom = this.findBottomSegment(); - this.top = this.findTopSegment(); - - for(int n = 0; n < this.blocks.length; ++n) { - if(this.blocks[n] != null && (update & 1 << n) != 0) { - this.blocks[n].update(); - } - } for(int cy : extend) { BlockArray arr = this.getArray(cy); if(arr != null) { diff --git a/server/src/server/network/Player.java b/server/src/server/network/Player.java index 3377336..a185bbc 100755 --- a/server/src/server/network/Player.java +++ b/server/src/server/network/Player.java @@ -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 { diff --git a/server/src/server/world/Region.java b/server/src/server/world/Region.java index 41e874d..0753655 100755 --- a/server/src/server/world/Region.java +++ b/server/src/server/world/Region.java @@ -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 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); } } diff --git a/server/src/server/world/WorldServer.java b/server/src/server/world/WorldServer.java index e22fba9..53672f3 100755 --- a/server/src/server/world/WorldServer.java +++ b/server/src/server/world/WorldServer.java @@ -146,6 +146,7 @@ public final class WorldServer extends AWorldServer { private final IntHashMap trackMap = new IntHashMap(); private final Map dataMap = Maps.newHashMap(); private final List dataList = Lists.newArrayList(); + private final List 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 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 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 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; }