Archived
0

renamed: Chunk --> ChunkSection

This commit is contained in:
Forwolk
2018-08-04 20:43:07 +03:00
parent aa001b5fe2
commit be98784668
17 changed files with 75 additions and 468 deletions

View File

@@ -1,127 +0,0 @@
package mc.world.generated_world.chunk;
import lombok.Getter;
import mc.core.block.Block;
import mc.core.block.BlockType;
import mc.core.exception.ResourceUnloadedException;
import mc.core.world.Biome;
import mc.core.world.Chunk;
import mc.core.world.Region;
import mc.core.world.World;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import static mc.world.generated_world.WorldConstants.WORLD_CHUNK_SIZE;
public class ChunkImpl implements Chunk{
@Getter
private final int x;
@Getter
private final int y;
@Getter
private final int z;
private final Block[][][] blocks = new Block[WORLD_CHUNK_SIZE][WORLD_CHUNK_SIZE][WORLD_CHUNK_SIZE];
private final transient Reference<Region> region;
public ChunkImpl(int x, int y, int z, Region region) {
this.x = x;
this.y = y;
this.z = z;
this.region = new WeakReference<>(region);
}
@Override
public int getBlockType(int x, int y, int z) {
return blocks[x][y][z].getId();
}
@Override
public void setBlockType(int x, int y, int z, int type) {
}
@Override
public int getBlockMetadata(int x, int y, int z) {
return 0;
}
@Override
public void setBlockMetadata(int x, int y, int z, int metadata) {
}
@Override
public int getBlockLight(int x, int y, int z) {
return 15;
}
@Override
public void setBlockLight(int x, int y, int z, int lightLevel) {
}
@Override
public int getSkyLight(int x, int y, int z) {
return 15;
}
@Override
public void setSkyLight(int x, int y, int z, int lightLevel) {
}
@Override
public int getAddition(int x, int y, int z) {
return 0;
}
@Override
public void setAddition(int x, int y, int z, int value) {
}
@Override
public Biome getBiome(int x, int z) {
return getRegion().getBiomeAt(x + this.x * WORLD_CHUNK_SIZE,z + this.z * WORLD_CHUNK_SIZE);
}
@Override
public void setBiome(int x, int z, Biome biome) {
getRegion().setBiome(x + this.x * WORLD_CHUNK_SIZE,z + this.z * WORLD_CHUNK_SIZE, biome);
}
@Override
public void setBlock(int x, int y, int z, Block block) {
if (block.getBlockType() == BlockType.AIR) {
blocks[x][y][z] = null;
return;
}
blocks[x][y][z] = block;
}
@Override
public Block getBlock(int x, int y, int z) {
Block block = blocks[x][y][z];
if (block == null) {
return Block.airBlock(x, y, z);
}
return blocks[x][y][z];
}
@Override
public Region getRegion() {
if (region == null) {
return null;
}
if (region.get() == null) {
throw new ResourceUnloadedException("Region is unloaded");
}
return region.get();
}
@Override
public World getWorld() {
return getRegion().getWorld();
}
}

View File

@@ -1,146 +0,0 @@
package mc.world.generated_world.chunk;
import mc.core.block.Block;
import mc.core.world.Biome;
import mc.core.world.Chunk;
import mc.core.world.Region;
import mc.core.world.World;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ChunkProxy implements Chunk {
private final Chunk chunk;
private volatile transient long lastUsage = System.currentTimeMillis();
private final transient ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
public ChunkProxy(Chunk chunk) {
this.chunk = chunk;
}
public long getLastUsage() {
synchronized (chunk) {
return lastUsage;
}
}
private final void use () {
synchronized (chunk) {
lastUsage = System.currentTimeMillis();
}
}
@Override
public int getBlockType(int x, int y, int z) {
use();
return chunk.getBlockType(x, y, z);
}
@Override
public void setBlockType(int x, int y, int z, int type) {
use();
chunk.setBlockType(x, y, z, type);
}
@Override
public int getBlockMetadata(int x, int y, int z) {
use();
return chunk.getBlockMetadata(x, y, z);
}
@Override
public void setBlockMetadata(int x, int y, int z, int metadata) {
use();
chunk.setBlockMetadata(x, y, z, metadata);
}
@Override
public int getBlockLight(int x, int y, int z) {
use();
return chunk.getBlockLight(x, y, z);
}
@Override
public void setBlockLight(int x, int y, int z, int lightLevel) {
use();
chunk.setBlockLight(x, y, z, lightLevel);
}
@Override
public int getSkyLight(int x, int y, int z) {
use();
return chunk.getSkyLight(x, y, z);
}
@Override
public void setSkyLight(int x, int y, int z, int lightLevel) {
use();
chunk.setSkyLight(x, y, z, lightLevel);
}
@Override
public int getAddition(int x, int y, int z) {
use();
return chunk.getAddition(x, y, z);
}
@Override
public void setAddition(int x, int y, int z, int value) {
use();
chunk.setAddition(x, y, z, value);
}
@Override
public Biome getBiome(int x, int z) {
use();
return chunk.getBiome(x, z);
}
@Override
public void setBiome(int x, int z, Biome biome) {
use();
chunk.setBiome(x, z, biome);
}
@Override
public int getX() {
use();
return chunk.getX();
}
@Override
public int getY() {
use();
return chunk.getY();
}
@Override
public int getZ() {
use();
return chunk.getZ();
}
@Override
public void setBlock(int x, int y, int z, Block block) {
use();
chunk.setBlock(x, y, z, block);
}
@Override
public Block getBlock(int x, int y, int z) {
use();
return chunk.getBlock(x, y, z);
}
@Override
public Region getRegion() {
use();
return chunk.getRegion();
}
@Override
public World getWorld() {
use();
return chunk.getWorld();
}
}

View File

@@ -25,7 +25,7 @@ public class InMemoryCacheChunkLoader implements ChunkLoader {
@Autowired
private ChunkReader chunkReader;
@Autowired
private Serializer<Chunk> chunkSerializer;
private Serializer<ChunkSection> chunkSerializer;
@Autowired
private RegionReaderWriter regionReaderWritter;
@@ -44,14 +44,14 @@ public class InMemoryCacheChunkLoader implements ChunkLoader {
}
@Override
public Optional<Chunk> loadChunk(int x, int y, int z) {
public Optional<ChunkSection> loadChunk(int x, int y, int z) {
File file = getChuckFile(x, y, z);
if (!file.exists()) {
return Optional.empty();
} else {
try {
Chunk chunk = chunkReader.read(world.getRegion(x / WORLD_CHUNK_SIZE, z / WORLD_CHUNK_SIZE), x, y, z);
return Optional.of(chunk);
ChunkSection chunkSection = chunkReader.read(world.getRegion(x / WORLD_CHUNK_SIZE, z / WORLD_CHUNK_SIZE), x, y, z);
return Optional.of(chunkSection);
} catch (IOException e) {
log.error("Error occurred while reading chunk file: " + file.getAbsolutePath(), e);
return Optional.empty();
@@ -60,12 +60,12 @@ public class InMemoryCacheChunkLoader implements ChunkLoader {
}
@Override
public Chunk loadOrGenerateChunk(int x, int y, int z) {
public ChunkSection loadOrGenerateChunk(int x, int y, int z) {
int regX = x / WORLD_CHUNK_SIZE;
int regZ = z / WORLD_CHUNK_SIZE;
File regionFile = new File(worldFolder, MessageFormat.format(REGION_FILE_NAME_TEMPLATE, regX, regZ));
Region region;
Chunk chunk;
ChunkSection chunkSection;
if (!regionFile.exists()) {
log.debug("Region [{}, {}] not found. Generating!", regX, regZ);
regionFile.mkdirs();
@@ -76,17 +76,17 @@ public class InMemoryCacheChunkLoader implements ChunkLoader {
log.error("Error occurred while writting biome file", e);
}
saveRegion(region);
chunk = region.getChunkAt(x % WORLD_CHUNK_SIZE, y % WORLD_CHUNK_SIZE, z % WORLD_CHUNK_SIZE);
chunkSection = region.getChunkAt(x % WORLD_CHUNK_SIZE, y % WORLD_CHUNK_SIZE, z % WORLD_CHUNK_SIZE);
} else {
try {
region = regionReaderWritter.read(regX, regZ, world);
chunk = chunkReader.read(region, x, y, z);
chunkSection = chunkReader.read(region, x, y, z);
} catch (IOException e) {
log.error("Error occurred while reading chunk file", e);
log.error("Error occurred while reading chunkSection file", e);
return null;
}
}
return chunk;
return chunkSection;
}
private void saveRegion (Region region) {

View File

@@ -8,7 +8,6 @@ import mc.core.world.*;
import mc.world.generated_world.region.RegionImpl;
import mc.world.generated_world.serialization.ChunkSerializer;
import mc.world.generated_world.serialization.RegionReaderWriter;
import mc.world.generated_world.serialization.WorldReaderWriter;
import mc.world.generated_world.world.CubicWorld;
import mc.world.generated_world.world.Temperature;
import mc.world.generated_world.world.Wetness;
@@ -306,37 +305,37 @@ public class SeedBasedWorldGenerator implements WorldGenerator {
region.setBiome(x, z, biomes[x][z]);
if (heightMap[x][z] < WORLD_SEA_LEVEL) {
for (int y = 0; y < WORLD_SEA_LEVEL; y ++) {
Chunk chunk = region.getChunkAt(x / 16, y / 16, z / 16);
ChunkSection chunkSection = region.getChunkAt(x / 16, y / 16, z / 16);
if (y == 0) {
chunk.setBlock(x % 16, y % 16, z % 16, blockFactory.create(BlockType.BEDROCK, 0));
chunkSection.setBlock(x % 16, y % 16, z % 16, blockFactory.create(BlockType.BEDROCK, 0));
continue;
}
if (y < heightMap[x][z]) {
if (y < heightMap[x][z] - grassMap[x][z]) {
chunk.setBlock(x % 16, y % 16, z % 16, blockFactory.create(BlockType.STONE, 0));
chunkSection.setBlock(x % 16, y % 16, z % 16, blockFactory.create(BlockType.STONE, 0));
} else {
chunk.setBlock(x % 16, y % 16, z % 16, blockFactory.create(BlockType.SAND, 0));
chunkSection.setBlock(x % 16, y % 16, z % 16, blockFactory.create(BlockType.SAND, 0));
}
} else {
chunk.setBlock(x % 16, y % 16, z % 16, blockFactory.create(BlockType.WATER, 0));
chunkSection.setBlock(x % 16, y % 16, z % 16, blockFactory.create(BlockType.WATER, 0));
}
}
} else {
for (int y = 0; y < heightMap[x][z]; y++) {
Chunk chunk = region.getChunkAt(x / 16, y / 16, z / 16);
ChunkSection chunkSection = region.getChunkAt(x / 16, y / 16, z / 16);
if (y == 0) {
chunk.setBlock(x % 16, y % 16, z % 16, blockFactory.create(BlockType.BEDROCK, 0));
chunkSection.setBlock(x % 16, y % 16, z % 16, blockFactory.create(BlockType.BEDROCK, 0));
continue;
}
if (y < heightMap[x][z] - grassMap[x][z]) {
chunk.setBlock(x % 16, y % 16, z % 16, blockFactory.create(BlockType.STONE, 0));
chunkSection.setBlock(x % 16, y % 16, z % 16, blockFactory.create(BlockType.STONE, 0));
} else {
if (biomes[x][z] == Biome.DESERT || biomes[x][z] == Biome.DESERT_HILLS) {
chunk.setBlock(x % 16, y % 16, z % 16, blockFactory.create(BlockType.SAND, 0));
chunkSection.setBlock(x % 16, y % 16, z % 16, blockFactory.create(BlockType.SAND, 0));
} else if (biomes[x][z] == Biome.TAIGA || biomes[x][z] == Biome.TAIGA_HILLS) {
chunk.setBlock(x % 16, y % 16, z % 16, blockFactory.create(BlockType.DIRT, 0));
chunkSection.setBlock(x % 16, y % 16, z % 16, blockFactory.create(BlockType.DIRT, 0));
} else {
chunk.setBlock(x % 16, y % 16, z % 16, blockFactory.create(BlockType.GRASS, 0));
chunkSection.setBlock(x % 16, y % 16, z % 16, blockFactory.create(BlockType.GRASS, 0));
}
}
}

View File

@@ -6,8 +6,8 @@ import mc.core.exception.ResourceUnloadedException;
import mc.core.serialization.IRegionReaderWriter;
import mc.core.serialization.Serializer;
import mc.core.world.*;
import mc.world.generated_world.chunk.ChunkImpl;
import mc.world.generated_world.chunk.ChunkProxy;
import mc.world.generated_world.chunk.ChunkSectionImpl;
import mc.world.generated_world.chunk.ChunkSectionProxy;
import mc.world.generated_world.chunk.InMemoryCacheChunkLoader;
import org.springframework.beans.factory.annotation.Autowired;
@@ -26,7 +26,7 @@ public class RegionImpl implements Region{
private final int x;
@Getter
private final int z;
private final ChunkProxy[][][] chunks = new ChunkProxy[WORLD_REGION_SIZE/WORLD_CHUNK_SIZE][WORLD_REGION_SIZE/WORLD_CHUNK_SIZE][WORLD_REGION_SIZE/WORLD_CHUNK_SIZE];
private final ChunkSectionProxy[][][] chunks = new ChunkSectionProxy[WORLD_REGION_SIZE/WORLD_CHUNK_SIZE][WORLD_REGION_SIZE/WORLD_CHUNK_SIZE][WORLD_REGION_SIZE/WORLD_CHUNK_SIZE];
private final Biome[][] biomes = new Biome[WORLD_REGION_SIZE][WORLD_REGION_SIZE];
private final transient Reference<World> world;
@Autowired
@@ -39,27 +39,27 @@ public class RegionImpl implements Region{
}
@Override
public Chunk getChunkAt(int x, int y, int z) {
public ChunkSection getChunkAt(int x, int y, int z) {
if (x < 0 || y < 0 || z < 0 || x >= 16 || y >= 16 || z >= 16) {
throw new RuntimeException(MessageFormat.format("Invalid chunk coordinates [{0} {1} {2}]", x, y, z));
throw new RuntimeException(MessageFormat.format("Invalid chunkSection coordinates [{0} {1} {2}]", x, y, z));
}
if (chunkLoader == null) {
chunkLoader = new InMemoryCacheChunkLoader(getWorld());
}
Chunk chunk = chunks[x][y][z];
if (chunk == null) {
chunk = chunkLoader.loadChunk(x + this.x * WORLD_REGION_SIZE, y, this.z * WORLD_REGION_SIZE).orElse(new ChunkImpl(x, y, z, this));
chunks[x][y][z] = new ChunkProxy(chunk);
ChunkSection chunkSection = chunks[x][y][z];
if (chunkSection == null) {
chunkSection = chunkLoader.loadChunk(x + this.x * WORLD_REGION_SIZE, y, this.z * WORLD_REGION_SIZE).orElse(new ChunkSectionImpl(x, y, z, this));
chunks[x][y][z] = new ChunkSectionProxy(chunkSection);
}
return chunk;
return chunkSection;
}
@Override
public void setChunk(int x, int y, int z, Chunk chunk) {
public void setChunk(int x, int y, int z, ChunkSection chunkSection) {
if (x < 0 || y < 0 || z < 0 || x >= 16 || y >= 16 || z >= 16) {
throw new RuntimeException(MessageFormat.format("Invalid chunk coordinates [{0} {1} {2}]", x, y, z));
throw new RuntimeException(MessageFormat.format("Invalid chunkSection coordinates [{0} {1} {2}]", x, y, z));
}
chunks[x][y][z] = new ChunkProxy(chunk);
chunks[x][y][z] = new ChunkSectionProxy(chunkSection);
}
@Override
@@ -90,7 +90,7 @@ public class RegionImpl implements Region{
}
@Override
public void save(Serializer<Chunk> chunkSerializer, IRegionReaderWriter regionReaderWriter) throws IOException {
public void save(Serializer<ChunkSection> chunkSerializer, IRegionReaderWriter regionReaderWriter) throws IOException {
String worldPath = System.getProperty("worlds.folder", "worlds");
File worldFile = new File(worldPath, getWorld().getWorldId().toString());
File regionFile = new File(worldFile, MessageFormat.format(REGION_FILE_NAME_TEMPLATE, this.getX(), this.getZ()));
@@ -101,8 +101,8 @@ public class RegionImpl implements Region{
for (int x = 0; x < WORLD_CHUNK_SIZE; x ++) {
for (int z = 0; z < WORLD_CHUNK_SIZE; z ++) {
for (int y = 0; y < WORLD_CHUNK_SIZE; y++) {
Chunk chunk = this.getChunkAt(x, y, z);
byte[] chunkBytes = chunkSerializer.serialize(chunk);
ChunkSection chunkSection = this.getChunkAt(x, y, z);
byte[] chunkBytes = chunkSerializer.serialize(chunkSection);
if (chunkBytes.length > 0) {
File chunkFile = new File(regionFile, MessageFormat.format(CHUNK_FILE_NAME_TEMPLATE, x, y, z));
try (FileOutputStream fileOutputStream = new FileOutputStream(chunkFile)) {

View File

@@ -5,7 +5,7 @@ import mc.core.block.BlockFactory;
import mc.core.block.BlockType;
import mc.core.serialization.Deserializer;
import mc.core.serialization.Serializer;
import mc.core.world.Chunk;
import mc.core.world.ChunkSection;
/**
* Prototype
@@ -13,20 +13,20 @@ import mc.core.world.Chunk;
public class BlockSerializerDeserializer implements Serializer<Block>, Deserializer<Block> {
private BlockFactory blockFactory;
private Chunk chunk;
private ChunkSection chunkSection;
public BlockSerializerDeserializer(BlockFactory blockFactory, Chunk chunk) {
public BlockSerializerDeserializer(BlockFactory blockFactory, ChunkSection chunkSection) {
this.blockFactory = blockFactory;
this.chunk = chunk;
this.chunkSection = chunkSection;
}
@Override
public Block deserialize(byte[] bytes) {
int id = bytes[0] + 128;
int meta = bytes[1] >> 4;
int x = (bytes[1] & 0xf) + chunk.getX() * 16;
int y = bytes[2] >> 4 + chunk.getY() * 16;
int z = (bytes[2] & 0xf) + chunk.getZ() * 16;
int x = (bytes[1] & 0xf) + chunkSection.getX() * 16;
int y = bytes[2] >> 4 + chunkSection.getY() * 16;
int z = (bytes[2] & 0xf) + chunkSection.getZ() * 16;
BlockType type = BlockType.values()[id];
Block block = blockFactory.create(type, meta);
block.getLocation().setX(x);

View File

@@ -4,9 +4,9 @@ import mc.core.Location;
import mc.core.block.Block;
import mc.core.serialization.Deserializer;
import mc.core.serialization.IChunkReader;
import mc.core.world.Chunk;
import mc.core.world.ChunkSection;
import mc.core.world.Region;
import mc.world.generated_world.chunk.ChunkImpl;
import mc.world.generated_world.chunk.ChunkSectionImpl;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.File;
@@ -27,14 +27,14 @@ public class ChunkReader implements IChunkReader{
}
@Override
public Chunk read (Region region, int x, int y, int z) throws IOException {
public ChunkSection read (Region region, int x, int y, int z) throws IOException {
x %= WORLD_REGION_SIZE;
y %= WORLD_REGION_SIZE;
z %= WORLD_REGION_SIZE;
File chunkFile = new File(new File(worldFolder, MessageFormat.format(REGION_FILE_NAME_TEMPLATE, region.getX(), region.getZ())), MessageFormat.format(CHUNK_FILE_NAME_TEMPLATE, x, y, z));
byte[] chunkBytes = Files.readAllBytes(Paths.get(chunkFile.toURI()));
int blocks = (chunkBytes.length) / 3;
Chunk chunk = new ChunkImpl(x, y, z, region);
ChunkSection chunkSection = new ChunkSectionImpl(x, y, z, region);
for (int i = 0; i < blocks; i ++) {
byte[] blockBytes = new byte[3];
blockBytes[0] = chunkBytes[3 * i];
@@ -42,8 +42,8 @@ public class ChunkReader implements IChunkReader{
blockBytes[2] = chunkBytes[2 + 3 * i];
Block block = blockDeserializer.deserialize(blockBytes);
Location blockLocation = block.getLocation();
chunk.setBlock(blockLocation.getBlockX(), blockLocation.getBlockY(), blockLocation.getBlockZ(), block);
chunkSection.setBlock(blockLocation.getBlockX(), blockLocation.getBlockY(), blockLocation.getBlockZ(), block);
}
return chunk;
return chunkSection;
}
}

View File

@@ -5,7 +5,7 @@ import mc.core.block.Block;
import mc.core.block.BlockFactory;
import mc.core.block.BlockType;
import mc.core.serialization.Serializer;
import mc.core.world.Chunk;
import mc.core.world.ChunkSection;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.ByteArrayOutputStream;
@@ -14,20 +14,20 @@ import java.io.IOException;
import static mc.world.generated_world.WorldConstants.WORLD_CHUNK_SIZE;
@Slf4j
public class ChunkSerializer implements Serializer<Chunk> {
public class ChunkSerializer implements Serializer<ChunkSection> {
@Autowired
private Serializer<Block> blockSerializer;
@Override
public byte[] serialize(Chunk chunk) {
Serializer<Block> blockSerializer = new BlockSerializerDeserializer(new BlockFactory(), chunk);
public byte[] serialize(ChunkSection chunkSection) {
Serializer<Block> blockSerializer = new BlockSerializerDeserializer(new BlockFactory(), chunkSection);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Block current;
for (int x = 0; x < WORLD_CHUNK_SIZE; x ++) {
for (int y = 0; y < WORLD_CHUNK_SIZE; y ++) {
for (int z = 0; z < WORLD_CHUNK_SIZE; z ++) {
current = chunk.getBlock(x, y, z);
current = chunkSection.getBlock(x, y, z);
if (current != null && current.getBlockType() != BlockType.AIR) {
try {
baos.write(blockSerializer.serialize(current));

View File

@@ -8,7 +8,7 @@ import mc.core.Location;
import mc.core.WarpPosition;
import mc.core.block.BlockType;
import mc.core.player.Look;
import mc.core.world.Chunk;
import mc.core.world.ChunkSection;
import mc.core.world.IWorldType;
import mc.core.world.Region;
import mc.core.world.World;
@@ -68,8 +68,8 @@ public class CubicWorld implements World {
log.warn("Spawn location is not defined. Trying to select best location");
warpPosition = new WarpPosition(Location.startPointLocation(), new Look(0, 0));
for (int y = WORLD_MAX_HEIGHT; y > 0; y --) {
Chunk chunk = getChunk(0,y / WORLD_CHUNK_SIZE, 0);
if (chunk.getBlock(0, y, 0).getBlockType() != BlockType.AIR) {
ChunkSection chunkSection = getChunk(0,y / WORLD_CHUNK_SIZE, 0);
if (chunkSection.getBlock(0, y, 0).getBlockType() != BlockType.AIR) {
warpPosition = new WarpPosition(new Location(0, y + 1, 0), new Look(0, 0));
break;
}
@@ -89,12 +89,12 @@ public class CubicWorld implements World {
}
@Override
public Chunk getChunk(int x, int y, int z) {
public ChunkSection getChunk(int x, int y, int z) {
return null;
}
@Override
public void setChunk(int x, int y, int z, Chunk chunk) {
public void setChunk(int x, int y, int z, ChunkSection chunkSection) {
}