mirror of
https://github.com/Minestom/Minestom.git
synced 2024-11-07 11:20:09 +01:00
Custom blocks also use a PaletteStorage object, removed StaticChunk since memory is not an issue anymore
This commit is contained in:
parent
4dfe01ea2f
commit
93bae25085
@ -12,7 +12,6 @@ import net.minestom.server.entity.pathfinding.PFBlockDescription;
|
|||||||
import net.minestom.server.instance.block.CustomBlock;
|
import net.minestom.server.instance.block.CustomBlock;
|
||||||
import net.minestom.server.instance.palette.PaletteStorage;
|
import net.minestom.server.instance.palette.PaletteStorage;
|
||||||
import net.minestom.server.network.packet.server.play.ChunkDataPacket;
|
import net.minestom.server.network.packet.server.play.ChunkDataPacket;
|
||||||
import net.minestom.server.utils.ArrayUtils;
|
|
||||||
import net.minestom.server.utils.BlockPosition;
|
import net.minestom.server.utils.BlockPosition;
|
||||||
import net.minestom.server.utils.binary.BinaryReader;
|
import net.minestom.server.utils.binary.BinaryReader;
|
||||||
import net.minestom.server.utils.binary.BinaryWriter;
|
import net.minestom.server.utils.binary.BinaryWriter;
|
||||||
@ -42,12 +41,9 @@ public class DynamicChunk extends Chunk {
|
|||||||
*/
|
*/
|
||||||
private static final int DATA_FORMAT_VERSION = 1;
|
private static final int DATA_FORMAT_VERSION = 1;
|
||||||
|
|
||||||
// blocks id based on coordinate, see Chunk#getBlockIndex
|
// WARNING: not thread-safe
|
||||||
// WARNING: those arrays are NOT thread-safe
|
|
||||||
// and modifying them can cause issue with block data, update, block entity and the cached chunk packet
|
|
||||||
//protected final short[] blocksStateId = new short[CHUNK_SIZE_X * CHUNK_SIZE_Y * CHUNK_SIZE_Z];
|
|
||||||
protected PaletteStorage blockPalette = new PaletteStorage(15);
|
protected PaletteStorage blockPalette = new PaletteStorage(15);
|
||||||
protected final short[] customBlocksId = new short[CHUNK_SIZE_X * CHUNK_SIZE_Y * CHUNK_SIZE_Z];
|
protected PaletteStorage customBlockPalette = new PaletteStorage(15);
|
||||||
|
|
||||||
// Used to get all blocks with data (no null)
|
// Used to get all blocks with data (no null)
|
||||||
// Key is still chunk coordinates (see #getBlockIndex)
|
// Key is still chunk coordinates (see #getBlockIndex)
|
||||||
@ -82,13 +78,13 @@ public class DynamicChunk extends Chunk {
|
|||||||
final boolean hasBlock = blockStateId != 0 || customBlockId != 0;
|
final boolean hasBlock = blockStateId != 0 || customBlockId != 0;
|
||||||
if (hasBlock) {
|
if (hasBlock) {
|
||||||
this.blockPalette.setBlockAt(x, y, z, blockStateId);
|
this.blockPalette.setBlockAt(x, y, z, blockStateId);
|
||||||
this.customBlocksId[index] = customBlockId;
|
this.customBlockPalette.setBlockAt(x, y, z, customBlockId);
|
||||||
} else {
|
} else {
|
||||||
// Block has been deleted, clear cache and return
|
// Block has been deleted, clear cache and return
|
||||||
|
|
||||||
this.blockPalette.setBlockAt(x, y, z, (short) 0);
|
this.blockPalette.setBlockAt(x, y, z, (short) 0);
|
||||||
//this.blocksStateId[index] = 0; // Set to air
|
//this.blocksStateId[index] = 0; // Set to air
|
||||||
this.customBlocksId[index] = 0; // Remove custom block
|
this.customBlockPalette.setBlockAt(x, y, z, (short) 0); // Remove custom block
|
||||||
|
|
||||||
this.blocksData.remove(index);
|
this.blocksData.remove(index);
|
||||||
|
|
||||||
@ -158,15 +154,13 @@ public class DynamicChunk extends Chunk {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public short getCustomBlockId(int x, int y, int z) {
|
public short getCustomBlockId(int x, int y, int z) {
|
||||||
final int index = getBlockIndex(x, y, z);
|
return customBlockPalette.getBlockAt(x, y, z);
|
||||||
return customBlocksId[index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void refreshBlockValue(int x, int y, int z, short blockStateId, short customBlockId) {
|
protected void refreshBlockValue(int x, int y, int z, short blockStateId, short customBlockId) {
|
||||||
final int blockIndex = getBlockIndex(x, y, z);
|
|
||||||
this.blockPalette.setBlockAt(x, y, z, blockStateId);
|
this.blockPalette.setBlockAt(x, y, z, blockStateId);
|
||||||
this.customBlocksId[blockIndex] = customBlockId;
|
this.customBlockPalette.setBlockAt(x, y, z, customBlockId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -243,7 +237,7 @@ public class DynamicChunk extends Chunk {
|
|||||||
final int index = getBlockIndex(x, y, z);
|
final int index = getBlockIndex(x, y, z);
|
||||||
|
|
||||||
final short blockStateId = blockPalette.getBlockAt(x, y, z);
|
final short blockStateId = blockPalette.getBlockAt(x, y, z);
|
||||||
final short customBlockId = customBlocksId[index];
|
final short customBlockId = customBlockPalette.getBlockAt(x, y, z);
|
||||||
|
|
||||||
// No block at the position
|
// No block at the position
|
||||||
if (blockStateId == 0 && customBlockId == 0)
|
if (blockStateId == 0 && customBlockId == 0)
|
||||||
@ -381,7 +375,7 @@ public class DynamicChunk extends Chunk {
|
|||||||
fullDataPacket.chunkX = chunkX;
|
fullDataPacket.chunkX = chunkX;
|
||||||
fullDataPacket.chunkZ = chunkZ;
|
fullDataPacket.chunkZ = chunkZ;
|
||||||
fullDataPacket.paletteStorage = blockPalette.copy();
|
fullDataPacket.paletteStorage = blockPalette.copy();
|
||||||
fullDataPacket.customBlocksId = customBlocksId.clone();
|
fullDataPacket.customBlockPaletteStorage = customBlockPalette.copy();
|
||||||
fullDataPacket.blockEntities = new HashSet<>(blockEntities);
|
fullDataPacket.blockEntities = new HashSet<>(blockEntities);
|
||||||
fullDataPacket.blocksData = new Int2ObjectOpenHashMap<>(blocksData);
|
fullDataPacket.blocksData = new Int2ObjectOpenHashMap<>(blocksData);
|
||||||
return fullDataPacket;
|
return fullDataPacket;
|
||||||
@ -392,7 +386,7 @@ public class DynamicChunk extends Chunk {
|
|||||||
public Chunk copy(int chunkX, int chunkZ) {
|
public Chunk copy(int chunkX, int chunkZ) {
|
||||||
DynamicChunk dynamicChunk = new DynamicChunk(biomes.clone(), chunkX, chunkZ);
|
DynamicChunk dynamicChunk = new DynamicChunk(biomes.clone(), chunkX, chunkZ);
|
||||||
dynamicChunk.blockPalette = blockPalette.copy();
|
dynamicChunk.blockPalette = blockPalette.copy();
|
||||||
ArrayUtils.copyToDestination(customBlocksId, dynamicChunk.customBlocksId);
|
dynamicChunk.customBlockPalette = customBlockPalette.copy();
|
||||||
dynamicChunk.blocksData.putAll(blocksData);
|
dynamicChunk.blocksData.putAll(blocksData);
|
||||||
dynamicChunk.updatableBlocks.addAll(updatableBlocks);
|
dynamicChunk.updatableBlocks.addAll(updatableBlocks);
|
||||||
dynamicChunk.updatableBlocksLastUpdate.putAll(updatableBlocksLastUpdate);
|
dynamicChunk.updatableBlocksLastUpdate.putAll(updatableBlocksLastUpdate);
|
||||||
|
@ -581,7 +581,7 @@ public class InstanceContainer extends Instance {
|
|||||||
* @throws NullPointerException if {@code chunkSupplier} is null
|
* @throws NullPointerException if {@code chunkSupplier} is null
|
||||||
*/
|
*/
|
||||||
public void setChunkSupplier(@NotNull ChunkSupplier chunkSupplier) {
|
public void setChunkSupplier(@NotNull ChunkSupplier chunkSupplier) {
|
||||||
Check.notNull(chunkSupplier, "The chunk supplier cannot be null, you can use a StaticChunk for a lightweight implementation");
|
Check.notNull(chunkSupplier, "The chunk supplier cannot be null!");
|
||||||
this.chunkSupplier = chunkSupplier;
|
this.chunkSupplier = chunkSupplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,127 +0,0 @@
|
|||||||
package net.minestom.server.instance;
|
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
|
||||||
import net.minestom.server.data.Data;
|
|
||||||
import net.minestom.server.instance.block.BlockProvider;
|
|
||||||
import net.minestom.server.network.packet.server.play.ChunkDataPacket;
|
|
||||||
import net.minestom.server.utils.binary.BinaryReader;
|
|
||||||
import net.minestom.server.utils.callback.OptionalCallback;
|
|
||||||
import net.minestom.server.utils.chunk.ChunkCallback;
|
|
||||||
import net.minestom.server.utils.chunk.ChunkUtils;
|
|
||||||
import net.minestom.server.world.biomes.Biome;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a {@link Chunk} which does not store any block, it makes use of a {@link BlockProvider}
|
|
||||||
* instead to use less memory.
|
|
||||||
* <p>
|
|
||||||
* Can be used for very simple chunks such as flat or others with not any random factor.
|
|
||||||
* <p>
|
|
||||||
* WARNING: adding blocks or anything to this chunk would not work, it is static.
|
|
||||||
*/
|
|
||||||
public class StaticChunk extends Chunk {
|
|
||||||
|
|
||||||
protected final BlockProvider blockProvider;
|
|
||||||
|
|
||||||
public StaticChunk(@Nullable Biome[] biomes, int chunkX, int chunkZ,
|
|
||||||
@NotNull BlockProvider blockProvider) {
|
|
||||||
super(biomes, chunkX, chunkZ, false);
|
|
||||||
this.blockProvider = blockProvider;
|
|
||||||
setReadOnly(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void UNSAFE_setBlock(int x, int y, int z, short blockStateId, short customBlockId, @Nullable Data data, boolean updatable) {
|
|
||||||
//noop
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tick(long time, @NotNull Instance instance) {
|
|
||||||
//noop
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public short getBlockStateId(int x, int y, int z) {
|
|
||||||
return blockProvider.getBlockStateId(x, y, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public short getCustomBlockId(int x, int y, int z) {
|
|
||||||
//noop
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void refreshBlockValue(int x, int y, int z, short blockStateId, short customId) {
|
|
||||||
//noop
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void refreshBlockStateId(int x, int y, int z, short blockStateId) {
|
|
||||||
//noop
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Data getBlockData(int index) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setBlockData(int x, int y, int z, Data data) {
|
|
||||||
//noop
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public Set<Integer> getBlockEntities() {
|
|
||||||
return new HashSet<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getSerializedData() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void readChunk(@NotNull BinaryReader reader, @Nullable ChunkCallback callback) {
|
|
||||||
OptionalCallback.execute(callback, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
protected ChunkDataPacket createFreshPacket() {
|
|
||||||
ChunkDataPacket fullDataPacket = new ChunkDataPacket();
|
|
||||||
fullDataPacket.biomes = biomes.clone();
|
|
||||||
fullDataPacket.chunkX = chunkX;
|
|
||||||
fullDataPacket.chunkZ = chunkZ;
|
|
||||||
short[] blocksStateId = new short[CHUNK_SIZE_X * CHUNK_SIZE_Y * CHUNK_SIZE_Z];
|
|
||||||
for (int i = 0; i < blocksStateId.length; i++) {
|
|
||||||
final int x = ChunkUtils.blockIndexToChunkPositionX(i);
|
|
||||||
final int y = ChunkUtils.blockIndexToChunkPositionY(i);
|
|
||||||
final int z = ChunkUtils.blockIndexToChunkPositionZ(i);
|
|
||||||
blocksStateId[i] = blockProvider.getBlockStateId(x, y, z);
|
|
||||||
}
|
|
||||||
//fullDataPacket.blocksStateId = blocksStateId;
|
|
||||||
fullDataPacket.customBlocksId = new short[0];
|
|
||||||
fullDataPacket.blockEntities = new HashSet<>();
|
|
||||||
fullDataPacket.blocksData = new Int2ObjectOpenHashMap<>();
|
|
||||||
return fullDataPacket;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public Chunk copy(int chunkX, int chunkZ) {
|
|
||||||
StaticChunk staticChunk = new StaticChunk(biomes.clone(), chunkX, chunkZ, blockProvider);
|
|
||||||
// Prevent re-writing the whole packet since it is static anyway
|
|
||||||
/*final ByteBuf packetBuffer = getFullDataPacket();
|
|
||||||
if (packetBuffer != null) {
|
|
||||||
staticChunk.setFullDataPacket(packetBuffer);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
return staticChunk;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package net.minestom.server.instance.block;
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface BlockProvider {
|
|
||||||
short getBlockStateId(int x, int y, int z);
|
|
||||||
}
|
|
@ -33,6 +33,10 @@ public class PaletteStorage {
|
|||||||
final int section = y / CHUNK_SECTION_SIZE;
|
final int section = y / CHUNK_SECTION_SIZE;
|
||||||
|
|
||||||
if (sectionBlocks[section].length == 0) {
|
if (sectionBlocks[section].length == 0) {
|
||||||
|
if (blockId == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
sectionBlocks[section] = new long[getSize()];
|
sectionBlocks[section] = new long[getSize()];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,18 +99,18 @@ public class PaletteStorage {
|
|||||||
|
|
||||||
long finalValue;
|
long finalValue;
|
||||||
|
|
||||||
System.out.println("index " + index);
|
/*System.out.println("index " + index);
|
||||||
System.out.println("bitIndex " + bitIndex);
|
System.out.println("bitIndex " + bitIndex);
|
||||||
System.out.println("test1 " + binary(value));
|
System.out.println("test1 " + binary(value));
|
||||||
System.out.println("test2 " + binary(mask));
|
System.out.println("test2 " + binary(mask));*/
|
||||||
|
|
||||||
{
|
{
|
||||||
mask = mask >> bitIndex << bitIndex;
|
mask = mask >> bitIndex << bitIndex;
|
||||||
System.out.println("test3 " + binary(mask));
|
//System.out.println("test3 " + binary(mask));
|
||||||
finalValue = value & mask >> bitIndex;
|
finalValue = value & mask >> bitIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("final " + binary(finalValue));
|
//System.out.println("final " + binary(finalValue));
|
||||||
|
|
||||||
|
|
||||||
/*System.out.println("data " + index + " " + bitIndex + " " + sectionIndex);
|
/*System.out.println("data " + index + " " + bitIndex + " " + sectionIndex);
|
||||||
|
@ -29,7 +29,7 @@ public class ChunkDataPacket implements ServerPacket {
|
|||||||
public int chunkX, chunkZ;
|
public int chunkX, chunkZ;
|
||||||
|
|
||||||
public PaletteStorage paletteStorage;
|
public PaletteStorage paletteStorage;
|
||||||
public short[] customBlocksId;
|
public PaletteStorage customBlockPaletteStorage;
|
||||||
|
|
||||||
public Set<Integer> blockEntities;
|
public Set<Integer> blockEntities;
|
||||||
public Int2ObjectMap<Data> blocksData;
|
public Int2ObjectMap<Data> blocksData;
|
||||||
@ -106,12 +106,14 @@ public class ChunkDataPacket implements ServerPacket {
|
|||||||
.setInt("y", blockPosition.getY())
|
.setInt("y", blockPosition.getY())
|
||||||
.setInt("z", blockPosition.getZ());
|
.setInt("z", blockPosition.getZ());
|
||||||
|
|
||||||
final short customBlockId = customBlocksId[index];
|
if (customBlockPaletteStorage != null) {
|
||||||
|
final short customBlockId = customBlockPaletteStorage.getBlockAt(blockPosition.getX(), blockPosition.getY(), blockPosition.getZ());
|
||||||
final CustomBlock customBlock = BLOCK_MANAGER.getCustomBlock(customBlockId);
|
final CustomBlock customBlock = BLOCK_MANAGER.getCustomBlock(customBlockId);
|
||||||
if (customBlock != null) {
|
if (customBlock != null) {
|
||||||
final Data data = blocksData.get(index);
|
final Data data = blocksData.get(index);
|
||||||
customBlock.writeBlockEntity(blockPosition, data, nbt);
|
customBlock.writeBlockEntity(blockPosition, data, nbt);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
writer.writeNBT("", nbt);
|
writer.writeNBT("", nbt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user