Merge branch 'proto_1.12.2' into world-loader-anvil
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package com.flowpowered.nbt;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public enum TagType {
|
||||
@@ -13,6 +14,7 @@ public enum TagType {
|
||||
TAG_DOUBLE(DoubleTag.class, "TAG_Double", 6),
|
||||
TAG_BYTE_ARRAY(ByteArrayTag.class, "TAG_Byte_Array", 7),
|
||||
TAG_STRING(StringTag.class, "TAG_String", 8),
|
||||
@SuppressWarnings("unchecked")
|
||||
TAG_LIST((Class) ListTag.class, "TAG_List", 9),
|
||||
// Java generics, y u so suck
|
||||
TAG_COMPOUND(CompoundTag.class, "TAG_Compound", 10),
|
||||
|
||||
@@ -24,20 +24,20 @@ public class AnvilBlock implements Block {
|
||||
|
||||
@Override
|
||||
public void setLight(int light) {
|
||||
|
||||
// nope...
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockType getBlockType() {
|
||||
public BlockType getType() {
|
||||
final byte id = chunkSection.getBlocks().get((location.getY() << 8) + (location.getZ() << 4) + location.getX());
|
||||
final int meta = chunkSection.getBlocksMeta().get(location);
|
||||
BlockType type = BlockType.getByIdMeta(id & 0xFF, meta);
|
||||
if (type.equals(BlockType.BEDROCK) && id != 7) {
|
||||
log.warn("ChunkSection: {},{},{} | Block: {}",
|
||||
chunkSection.getX(),
|
||||
chunkSection.getY(),
|
||||
chunkSection.getZ(),
|
||||
location.toString());
|
||||
chunkSection.getParent().getX(),
|
||||
chunkSection.getY(),
|
||||
chunkSection.getParent().getZ(),
|
||||
location.toString());
|
||||
}
|
||||
return type;
|
||||
}
|
||||
@@ -45,17 +45,21 @@ public class AnvilBlock implements Block {
|
||||
@Override
|
||||
public BlockLocation getLocation() {
|
||||
if (globalLocation == null) {
|
||||
globalLocation = location.toGlobal(chunkSection);
|
||||
globalLocation = new BlockLocation(
|
||||
(chunkSection.getParent().getX() << 4) + location.getX(),
|
||||
(chunkSection.getY() << 4) + location.getY(),
|
||||
(chunkSection.getParent().getZ() << 4) + location.getZ()
|
||||
);
|
||||
}
|
||||
return globalLocation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getNBTData() {
|
||||
CompoundTag compoundTag = chunkSection.getParent().getNbtByGlobalXYZ(
|
||||
(chunkSection.getX() << 4) + location.getX(),
|
||||
CompoundTag compoundTag = ((AnvilChunk)chunkSection.getParent()).getNbtByGlobalXYZ(
|
||||
(chunkSection.getParent().getX() << 4) + location.getX(),
|
||||
(chunkSection.getY() << 4) + location.getY(),
|
||||
(chunkSection.getZ() << 4) + location.getZ()
|
||||
(chunkSection.getParent().getZ() << 4) + location.getZ()
|
||||
);
|
||||
|
||||
compoundTag.getValue().remove("Items");
|
||||
@@ -68,7 +72,7 @@ public class AnvilBlock implements Block {
|
||||
public String toString() {
|
||||
return "AnvilBlock{" +
|
||||
"location=" + getLocation() +
|
||||
", type=" + getBlockType() +
|
||||
", type=" + getType() +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
package mc.world.anvil;
|
||||
|
||||
import com.flowpowered.nbt.*;
|
||||
import com.flowpowered.nbt.ByteArrayTag;
|
||||
import com.flowpowered.nbt.ByteTag;
|
||||
import com.flowpowered.nbt.CompoundMap;
|
||||
import com.flowpowered.nbt.CompoundTag;
|
||||
import com.flowpowered.nbt.IntTag;
|
||||
import com.flowpowered.nbt.ListTag;
|
||||
import gnu.trove.list.TByteList;
|
||||
import gnu.trove.list.array.TByteArrayList;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import mc.core.utils.NibbleArray;
|
||||
import mc.core.world.Biome;
|
||||
import mc.core.world.block.Block;
|
||||
import mc.core.world.chunk.Chunk;
|
||||
import mc.core.world.chunk.ChunkSection;
|
||||
|
||||
@@ -75,12 +81,57 @@ public class AnvilChunk implements Chunk {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getBiomeLocal(int x, int z) {
|
||||
public Block getBlock(int x, int y, int z) {
|
||||
final int height = y >> 4;
|
||||
return sections.get(height).getBlock(
|
||||
x - getX() << 4,
|
||||
y - height << 4,
|
||||
z - getZ() << 4
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlock(Block block) {
|
||||
// nope...
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSkyLight(int x, int y, int z) {
|
||||
final int height = y >> 4;
|
||||
return sections.get(height).getSkyLight(
|
||||
x - getX() << 4,
|
||||
y - height << 4,
|
||||
z - getZ() << 4
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSkyLight(int x, int y, int z, int lightLevel) {
|
||||
// nope...
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAddition(int x, int y, int z) {
|
||||
final int height = y >> 4;
|
||||
return sections.get(height).getAddition(
|
||||
x - getX() << 4,
|
||||
y - height << 4,
|
||||
z - getZ() << 4
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAddition(int x, int y, int z, int value) {
|
||||
// nope...
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getBiome(int x, int z) {
|
||||
return Biome.getById( biomes.get( z << 4 | x) & 255 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBiomeLocal(int x, int z, Biome biome) {
|
||||
public void setBiome(int x, int z, Biome biome) {
|
||||
// nope...
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,12 +6,13 @@ import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import mc.core.utils.NibbleArray;
|
||||
import mc.core.world.block.Block;
|
||||
import mc.core.world.chunk.Chunk;
|
||||
import mc.core.world.chunk.ChunkSection;
|
||||
|
||||
@Getter
|
||||
public class AnvilChunkSection implements ChunkSection {
|
||||
@Setter
|
||||
private AnvilChunk parent;
|
||||
private Chunk parent;
|
||||
|
||||
@Setter
|
||||
private int y;
|
||||
@@ -25,33 +26,23 @@ public class AnvilChunkSection implements ChunkSection {
|
||||
private NibbleArray skyLight;
|
||||
|
||||
@Override
|
||||
public int getX() {
|
||||
return parent.getX();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getZ() {
|
||||
return parent.getZ();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getBlockLocal(int x, int y, int z) {
|
||||
public Block getBlock(int x, int y, int z) {
|
||||
return new AnvilBlock(this, x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlock(Block block) {
|
||||
|
||||
// nope...
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSkyLightLocal(int x, int y, int z) {
|
||||
public int getSkyLight(int x, int y, int z) {
|
||||
return skyLight.get(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSkyLightLocal(int x, int y, int z, int lightLevel) {
|
||||
|
||||
public void setSkyLight(int x, int y, int z, int lightLevel) {
|
||||
// nope...
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -61,6 +52,6 @@ public class AnvilChunkSection implements ChunkSection {
|
||||
|
||||
@Override
|
||||
public void setAddition(int x, int y, int z, int value) {
|
||||
|
||||
// nope...
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,19 +45,19 @@ class RegionTest {
|
||||
for (int y = 0; y < 16; y++) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
Block block = chunkSection.getBlockLocal(x, y, z);
|
||||
Block block = chunkSection.getBlock(x, y, z);
|
||||
String msg = String.format("coords: %d %d %d", x, y, z);
|
||||
|
||||
if (y == 0) {
|
||||
// @formatter:off
|
||||
if (x == 0 && z == 0) assertEquals(BlockType.STONE, block.getBlockType(), msg);
|
||||
else if (x == 15 && z == 0) assertEquals(BlockType.GRANITE, block.getBlockType(), msg);
|
||||
else if (x == 0 && z == 15) assertEquals(BlockType.POLISHED_GRANITE, block.getBlockType(), msg);
|
||||
else if (x == 15 && z == 15) assertEquals(BlockType.DIORITE, block.getBlockType(), msg);
|
||||
else assertEquals(BlockType.BEDROCK, block.getBlockType(), msg);
|
||||
if (x == 0 && z == 0) assertEquals(BlockType.STONE, block.getType(), msg);
|
||||
else if (x == 15 && z == 0) assertEquals(BlockType.GRANITE, block.getType(), msg);
|
||||
else if (x == 0 && z == 15) assertEquals(BlockType.POLISHED_GRANITE, block.getType(), msg);
|
||||
else if (x == 15 && z == 15) assertEquals(BlockType.DIORITE, block.getType(), msg);
|
||||
else assertEquals(BlockType.BEDROCK, block.getType(), msg);
|
||||
// @formatter:on
|
||||
} else {
|
||||
assertEquals(BlockType.STONE, block.getBlockType(), msg);
|
||||
assertEquals(BlockType.STONE, block.getType(), msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -69,7 +69,7 @@ class RegionTest {
|
||||
compoundMap.put(new IntTag("x", block.getLocation().getX()));
|
||||
compoundMap.put(new IntTag("y", block.getLocation().getY()));
|
||||
compoundMap.put(new IntTag("z", block.getLocation().getZ()));
|
||||
compoundMap.put(new StringTag("id", block.getBlockType().getNamedId()));
|
||||
compoundMap.put(new StringTag("id", block.getType().getNamedId()));
|
||||
|
||||
return new CompoundTag("", compoundMap);
|
||||
}
|
||||
@@ -78,30 +78,30 @@ class RegionTest {
|
||||
for (int y = 0; y < 16; y++) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
Block block = chunkSection.getBlockLocal(x, y, z);
|
||||
Block block = chunkSection.getBlock(x, y, z);
|
||||
String msg = String.format("coords: %d %d %d", x, y, z);
|
||||
|
||||
// @formatter:off
|
||||
if (y == 0) assertEquals(BlockType.DIRT, block.getBlockType(), msg);
|
||||
else if (y == 1) assertEquals(BlockType.GRASS, block.getBlockType(), msg);
|
||||
if (y == 0) assertEquals(BlockType.DIRT, block.getType(), msg);
|
||||
else if (y == 1) assertEquals(BlockType.GRASS, block.getType(), msg);
|
||||
else if (y == 2) {
|
||||
if ((x == 2 || x == 4 || x == 5) && z == 1) {
|
||||
assertEquals(BlockType.CHEST_NORTH, block.getBlockType(), msg);
|
||||
assertEquals(BlockType.CHEST_NORTH, block.getType(), msg);
|
||||
assertEquals(createExceptedNBT(block), block.getNBTData());
|
||||
} else if ((x == 2 || x == 3 || x == 5) && z == 6) {
|
||||
assertEquals(BlockType.CHEST_SOUTH, block.getBlockType(), msg);
|
||||
assertEquals(BlockType.CHEST_SOUTH, block.getType(), msg);
|
||||
assertEquals(createExceptedNBT(block), block.getNBTData());
|
||||
} else if (x == 1 && (z == 2 || z == 3 || z == 5)) {
|
||||
assertEquals(BlockType.CHEST_WEST, block.getBlockType(), msg);
|
||||
assertEquals(BlockType.CHEST_WEST, block.getType(), msg);
|
||||
assertEquals(createExceptedNBT(block), block.getNBTData());
|
||||
} else if (x == 6 && (z == 2 || z == 4 || z == 5)) {
|
||||
assertEquals(BlockType.CHEST_EAST, block.getBlockType(), msg);
|
||||
assertEquals(BlockType.CHEST_EAST, block.getType(), msg);
|
||||
assertEquals(createExceptedNBT(block), block.getNBTData());
|
||||
} else {
|
||||
assertEquals(BlockType.AIR, block.getBlockType(), msg);
|
||||
assertEquals(BlockType.AIR, block.getType(), msg);
|
||||
}
|
||||
}
|
||||
else assertEquals(BlockType.AIR, block.getBlockType(), msg);
|
||||
else assertEquals(BlockType.AIR, block.getType(), msg);
|
||||
// @formatter:on
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
maven {
|
||||
url "https://plugins.gradle.org/m2/"
|
||||
}
|
||||
maven { url "https://plugins.gradle.org/m2/" }
|
||||
}
|
||||
dependencies {
|
||||
classpath (group: 'org.sonarsource.scanner.gradle', name: 'sonarqube-gradle-plugin', version: '2.6.2')
|
||||
@@ -63,6 +61,8 @@ subprojects {
|
||||
/* Lombok */
|
||||
annotationProcessor (group: 'org.projectlombok', name: 'lombok', version: lombok_version)
|
||||
compile (group: 'org.projectlombok', name: 'lombok', version: lombok_version)
|
||||
testAnnotationProcessor (group: 'org.projectlombok', name: 'lombok', version: lombok_version)
|
||||
testCompile (group: 'org.projectlombok', name: 'lombok', version: lombok_version)
|
||||
|
||||
/* Testing */
|
||||
testImplementation (group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: junit_version)
|
||||
|
||||
@@ -24,11 +24,11 @@ public class CoreEventListener {
|
||||
log.trace("(GameLoop) playerMoveEventHandler()");
|
||||
|
||||
Chunk chunk;
|
||||
chunk = event.getPlayer().getWorld().getChunk(event.getOldLocation()); // Old chunk
|
||||
chunk = event.getPlayer().getWorld().getChunk(event.getOldLocation().toBlockLocation()); // Old chunk
|
||||
if (chunk == null) return;
|
||||
int ccX = chunk.getX();
|
||||
int ccZ = chunk.getZ();
|
||||
chunk = event.getPlayer().getWorld().getChunk(event.getNewLocation()); // Next chunk
|
||||
chunk = event.getPlayer().getWorld().getChunk(event.getNewLocation().toBlockLocation()); // Next chunk
|
||||
if (chunk == null) return;
|
||||
int ncX = chunk.getX();
|
||||
int ncZ = chunk.getZ();
|
||||
|
||||
@@ -3,7 +3,7 @@ package mc.core;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.lang.Nullable;
|
||||
import mc.core.world.block.BlockLocation;
|
||||
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@@ -44,6 +44,10 @@ public class EntityLocation implements Cloneable {
|
||||
return (int) Math.floor(z);
|
||||
}
|
||||
|
||||
public BlockLocation toBlockLocation() {
|
||||
return new BlockLocation(getBlockX(), getBlockY(), getBlockZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityLocation clone() {
|
||||
try {
|
||||
|
||||
@@ -1,36 +1,42 @@
|
||||
package mc.core.world;
|
||||
|
||||
import mc.core.EntityLocation;
|
||||
import mc.core.world.block.Block;
|
||||
import mc.core.world.block.BlockLocation;
|
||||
import mc.core.world.chunk.Chunk;
|
||||
|
||||
public interface World {
|
||||
String getName();
|
||||
WorldType getWorldType();
|
||||
WorldType getType();
|
||||
|
||||
EntityLocation getSpawn();
|
||||
|
||||
void setSpawn(EntityLocation location);
|
||||
|
||||
default void setSpawn(double x, double y, double z, float yaw, float pitch) {
|
||||
setSpawn(new EntityLocation(x, y, z, yaw, pitch));
|
||||
}
|
||||
|
||||
default void setSpawn(double x, double y, double z) {
|
||||
setSpawn(x, y, z, 0f, 0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить чанк по координатам
|
||||
* @param x глобальный X
|
||||
* @param z глобальный Z
|
||||
* Получить чанк по его координатам
|
||||
* @param x chunk X
|
||||
* @param z chunk Z
|
||||
* @return {@link mc.core.world.chunk.Chunk}
|
||||
*/
|
||||
Chunk getChunk(int x, int z);
|
||||
|
||||
/**
|
||||
* Получить чанк по глобальным координатам блока
|
||||
* @param location {@link BlockLocation}
|
||||
* @return {@link Chunk}
|
||||
*/
|
||||
default Chunk getChunk(BlockLocation location) {
|
||||
return getChunk(location.getX() >> 4, location.getZ() >> 4);
|
||||
}
|
||||
default Chunk getChunk(EntityLocation location) {
|
||||
return getChunk(location.getBlockX() >> 4, location.getBlockZ() >> 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Установить чанк по координатам
|
||||
@@ -39,4 +45,19 @@ public interface World {
|
||||
* @param chunk {@link mc.core.world.chunk.Chunk}
|
||||
*/
|
||||
void setChunk(int x, int z, Chunk chunk);
|
||||
|
||||
/**
|
||||
* Получить блок по его координатам
|
||||
* @param x X
|
||||
* @param y Y
|
||||
* @param z Z
|
||||
* @return {@link Block}
|
||||
*/
|
||||
Block getBlock(int x, int y, int z);
|
||||
|
||||
default Block getBlock(BlockLocation location) {
|
||||
return getBlock(location.getX(), location.getY(), location.getZ());
|
||||
}
|
||||
|
||||
void setBlock(Block block);
|
||||
}
|
||||
|
||||
@@ -3,17 +3,15 @@ package mc.core.world.block;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
public abstract class AbstractBlock implements Block {
|
||||
@Getter
|
||||
@Setter
|
||||
private BlockLocation location;
|
||||
@Getter
|
||||
private int light = 0;
|
||||
@Getter
|
||||
private final BlockType blockType;
|
||||
private final BlockType type;
|
||||
|
||||
protected AbstractBlock(BlockType type) {
|
||||
this.blockType = type;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -5,7 +5,7 @@ import com.flowpowered.nbt.CompoundTag;
|
||||
public interface Block {
|
||||
int getLight();
|
||||
void setLight(int light);
|
||||
BlockType getBlockType();
|
||||
BlockType getType();
|
||||
BlockLocation getLocation();
|
||||
|
||||
default CompoundTag getNBTData() {
|
||||
|
||||
@@ -3,7 +3,6 @@ package mc.core.world.block;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import mc.core.world.chunk.ChunkSection;
|
||||
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@@ -21,22 +20,6 @@ public class BlockLocation implements Cloneable {
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public BlockLocation toGlobal(ChunkSection chunkSection) {
|
||||
return new BlockLocation(
|
||||
(chunkSection.getX() << 4) + x,
|
||||
(chunkSection.getY() << 4) + y,
|
||||
(chunkSection.getZ() << 4) + z
|
||||
);
|
||||
}
|
||||
|
||||
public BlockLocation toLocal() {
|
||||
return new BlockLocation(
|
||||
x - (x >> 4 << 4),
|
||||
y - (y >> 4 << 4),
|
||||
z - (z >> 4 << 4)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockLocation clone() {
|
||||
try {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package mc.core.world.chunk;
|
||||
|
||||
import mc.core.world.Biome;
|
||||
import mc.core.world.block.Block;
|
||||
|
||||
/* 16x256x16 */
|
||||
public interface Chunk {
|
||||
@@ -31,38 +32,34 @@ public interface Chunk {
|
||||
void setChunkSection(int height, ChunkSection chunkSection);
|
||||
|
||||
/**
|
||||
* Получиь данные по биому
|
||||
* @param x глобальный X
|
||||
* @param z глобальный Z
|
||||
* @return
|
||||
* Получить блок по глобальным координатам секции чанка
|
||||
* @param x global X
|
||||
* @param y global Y
|
||||
* @param z global Z
|
||||
* @return {@link Block}
|
||||
*/
|
||||
default Biome getBiome(int x, int z) {
|
||||
return getBiomeLocal(x >> 4, z >> 4);
|
||||
}
|
||||
Block getBlock(int x, int y, int z);
|
||||
void setBlock(Block block);
|
||||
|
||||
int getSkyLight(int x, int y, int z);
|
||||
void setSkyLight(int x, int y, int z, int lightLevel);
|
||||
|
||||
int getAddition(int x, int y, int z);
|
||||
void setAddition(int x, int y, int z, int value);
|
||||
|
||||
/**
|
||||
* Получиь данные по биому
|
||||
* @param x локальный X (0-15)
|
||||
* @param z локальный Z (0-15)
|
||||
* @return
|
||||
* Получить тип биома по глобальным координатам
|
||||
* @param x global X
|
||||
* @param z global Z
|
||||
* @return {@link mc.core.world.Biome}
|
||||
*/
|
||||
Biome getBiomeLocal(int x, int z);
|
||||
Biome getBiome(int x, int z);
|
||||
|
||||
/**
|
||||
* Указать данные по биому
|
||||
* @param x глобальный X
|
||||
* @param z глобальный Z
|
||||
* @param x global X
|
||||
* @param z global Z
|
||||
* @param biome {@link mc.core.world.Biome}
|
||||
*/
|
||||
default void setBiome(int x, int z, Biome biome) {
|
||||
setBiomeLocal(x >> 4, z >> 4, biome);
|
||||
}
|
||||
|
||||
/**
|
||||
* Указать данные по биому
|
||||
* @param x локальный X (0-15)
|
||||
* @param z локальный Z (0-15)
|
||||
* @param biome {@link mc.core.world.Biome}
|
||||
*/
|
||||
void setBiomeLocal(int x, int z, Biome biome);
|
||||
void setBiome(int x, int z, Biome biome);
|
||||
}
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
package mc.core.world.chunk;
|
||||
|
||||
import mc.core.world.Biome;
|
||||
import mc.core.world.block.Block;
|
||||
|
||||
/* 16x16x16 */
|
||||
/**
|
||||
* Секция чанка размером 16x16x16 блоков
|
||||
*/
|
||||
public interface ChunkSection {
|
||||
/**
|
||||
* Глобальная координата X
|
||||
* @return
|
||||
*/
|
||||
int getX();
|
||||
Chunk getParent();
|
||||
void setParent(Chunk chunk);
|
||||
|
||||
/**
|
||||
* Высота
|
||||
@@ -18,30 +16,13 @@ public interface ChunkSection {
|
||||
int getY();
|
||||
|
||||
/**
|
||||
* Глобальная координата Z
|
||||
* @return
|
||||
* Получить блок по локальным координатам секции чанка
|
||||
* @param localX local X (0-15)
|
||||
* @param localY local Y (0-15)
|
||||
* @param localZ local Z (0-15)
|
||||
* @return {@link Block}
|
||||
*/
|
||||
int getZ();
|
||||
|
||||
/**
|
||||
* Получить блок
|
||||
* @param x глобальный X
|
||||
* @param y глобальный Y
|
||||
* @param z глобальный Z
|
||||
* @return {@link mc.core.world.block.Block}
|
||||
*/
|
||||
default Block getBlock(int x, int y, int z) {
|
||||
return getBlockLocal(x >> 4, y >> 4, z >> 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить блок
|
||||
* @param x локальный X (0-15)
|
||||
* @param y локальный Y (0-15)
|
||||
* @param z локальный Z (0-15)
|
||||
* @return {@link mc.core.world.block.Block}
|
||||
*/
|
||||
Block getBlockLocal(int x, int y, int z);
|
||||
Block getBlock(int localX, int localY, int localZ);
|
||||
|
||||
/**
|
||||
* Установить блок
|
||||
@@ -51,44 +32,22 @@ public interface ChunkSection {
|
||||
|
||||
/**
|
||||
* Получить данные о естественной подсветке
|
||||
* @param x глобальный X
|
||||
* @param y глобальный Y
|
||||
* @param z глобальный Z
|
||||
* @param localX локальный X (0-15)
|
||||
* @param localY локальный Y (0-15)
|
||||
* @param localZ локальный Z (0-15)
|
||||
* @return integer значение 0-15, где 0 - это света нет, а 15 - получает прямой солнечный свет
|
||||
*/
|
||||
default int getSkyLight(int x, int y, int z) {
|
||||
return getSkyLightLocal(x >> 4, y >> 4, z >> 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить данные о естественной подсветке
|
||||
* @param x локальный X (0-15)
|
||||
* @param y локальный Y (0-15)
|
||||
* @param z локальный Z (0-15)
|
||||
* @return integer значение 0-15, где 0 - это света нет, а 15 - получает прямой солнечный свет
|
||||
*/
|
||||
int getSkyLightLocal(int x, int y, int z);
|
||||
int getSkyLight(int localX, int localY, int localZ);
|
||||
|
||||
/**
|
||||
* Указать данные о естественной подсветке
|
||||
* @param x глобальный X
|
||||
* @param y глобальный Y
|
||||
* @param z глобальный Z
|
||||
* @param localX локальный X (0-15)
|
||||
* @param localY локальный Y (0-15)
|
||||
* @param localZ локальный Z (0-15)
|
||||
* @param lightLevel значение 0-15, где 0 - это света нет, а 15 - получает прямой солнечный свет
|
||||
*/
|
||||
default void setSkyLight(int x, int y, int z, int lightLevel) {
|
||||
setSkyLightLocal(x >> 4, y >> 4, z >> 4, lightLevel);
|
||||
}
|
||||
void setSkyLight(int localX, int localY, int localZ, int lightLevel);
|
||||
|
||||
/**
|
||||
* Указать данные о естественной подсветке
|
||||
* @param x локальный X (0-15)
|
||||
* @param y локальный Y (0-15)
|
||||
* @param z локальный Z (0-15)
|
||||
* @param lightLevel значение 0-15, где 0 - это света нет, а 15 - получает прямой солнечный свет
|
||||
*/
|
||||
void setSkyLightLocal(int x, int y, int z, int lightLevel);
|
||||
|
||||
int getAddition(int x, int y, int z);
|
||||
void setAddition(int x, int y, int z, int value);
|
||||
int getAddition(int localX, int localY, int localZ);
|
||||
void setAddition(int localX, int localY, int localZ, int value);
|
||||
}
|
||||
|
||||
@@ -27,28 +27,28 @@ public class ByteArrayOutputNetStream extends NetOutputStream_p340 {
|
||||
|
||||
@Override
|
||||
public void writeShort(int value) {
|
||||
baos.write((byte) value >>> 8);
|
||||
baos.write((byte) (value >>> 8));
|
||||
baos.write((byte) value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeInt(int value) {
|
||||
baos.write((byte)((int)(value >>> 24)));
|
||||
baos.write((byte)((int)(value >>> 16)));
|
||||
baos.write((byte)((int)(value >>> 8)));
|
||||
baos.write((byte)((int)(value)));
|
||||
baos.write((value >>> 24) & 0xFF);
|
||||
baos.write((value >>> 16) & 0xFF);
|
||||
baos.write((value >>> 8) & 0xFF);
|
||||
baos.write(value & 0xFF);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeLong(long value) {
|
||||
baos.write((byte)((int)(value >>> 56)));
|
||||
baos.write((byte)((int)(value >>> 48)));
|
||||
baos.write((byte)((int)(value >>> 40)));
|
||||
baos.write((byte)((int)(value >>> 32)));
|
||||
baos.write((byte)((int)(value >>> 24)));
|
||||
baos.write((byte)((int)(value >>> 16)));
|
||||
baos.write((byte)((int)(value >>> 8)));
|
||||
baos.write((byte)((int)(value)));
|
||||
baos.write((int) ((value >>> 56) & 0xFF));
|
||||
baos.write((int) ((value >>> 48) & 0xFF));
|
||||
baos.write((int) ((value >>> 40) & 0xFF));
|
||||
baos.write((int) ((value >>> 32) & 0xFF));
|
||||
baos.write((int) ((value >>> 24) & 0xFF));
|
||||
baos.write((int) ((value >>> 16) & 0xFF));
|
||||
baos.write((int) ((value >>> 8) & 0xFF));
|
||||
baos.write((int) (value & 0xFF));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -155,11 +155,11 @@ public class ChunkDataPacket implements SCPacket {
|
||||
for (int y = 0; y < 16; y++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
Block block = chunkSection.getBlockLocal(x, y, z);
|
||||
Block block = chunkSection.getBlock(x, y, z);
|
||||
|
||||
palettedChunkSection.addBlock(
|
||||
block,
|
||||
chunkSection.getSkyLightLocal(x, y, z)
|
||||
chunkSection.getSkyLight(x, y, z)
|
||||
);
|
||||
|
||||
CompoundTag nbt = block.getNBTData();
|
||||
@@ -168,7 +168,10 @@ public class ChunkDataPacket implements SCPacket {
|
||||
}
|
||||
|
||||
if (biomeWrite) {
|
||||
biomes.writeByte(chunk.getBiomeLocal(x, z).getId());
|
||||
biomes.writeByte(chunk.getBiome(
|
||||
chunk.getX() << 4 + x,
|
||||
chunk.getZ() << 4 + z
|
||||
).getId());
|
||||
if (x == 15 && z == 15) {
|
||||
biomeWrite = false;
|
||||
}
|
||||
@@ -235,8 +238,12 @@ public class ChunkDataPacket implements SCPacket {
|
||||
}
|
||||
|
||||
void addBlock(Block block, int skyLight) {
|
||||
BlockLocation location = block.getLocation().toLocal();
|
||||
blocks[coordsToIndex(location)] = addBlockType(block.getBlockType());
|
||||
BlockLocation location = new BlockLocation(
|
||||
block.getLocation().getX() - (block.getLocation().getX() >> 4) << 4,
|
||||
block.getLocation().getY() - (block.getLocation().getY() >> 4) << 4,
|
||||
block.getLocation().getZ() - (block.getLocation().getZ() >> 4) << 4
|
||||
);
|
||||
blocks[coordsToIndex(location)] = addBlockType(block.getType());
|
||||
blockLight.set(location, block.getLight());
|
||||
this.skyLight.set(location, skyLight);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package mc.core.network.proto_1_12_2.packets;
|
||||
package mc.core.network.proto_1_12_2;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import mc.core.network.proto_1_12_2.NetInputStream_p340;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
@@ -10,7 +9,7 @@ import java.io.IOException;
|
||||
public class ByteArrayInputNetStream extends NetInputStream_p340 {
|
||||
private ByteArrayInputStream bais;
|
||||
|
||||
ByteArrayInputNetStream(byte[] buff) {
|
||||
public ByteArrayInputNetStream(byte[] buff) {
|
||||
bais = new ByteArrayInputStream(buff);
|
||||
}
|
||||
|
||||
@@ -45,12 +44,12 @@ public class ByteArrayInputNetStream extends NetInputStream_p340 {
|
||||
|
||||
@Override
|
||||
public int readUnsignedShort() {
|
||||
return 0;
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public short readShort() {
|
||||
return 0;
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -65,7 +64,7 @@ public class ByteArrayInputNetStream extends NetInputStream_p340 {
|
||||
|
||||
@Override
|
||||
public long readLong() {
|
||||
return 0;
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -75,11 +74,11 @@ public class ByteArrayInputNetStream extends NetInputStream_p340 {
|
||||
|
||||
@Override
|
||||
public double readDouble() {
|
||||
return 0;
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void skipBytes(int count) {
|
||||
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package mc.core.network.proto_1_12_2;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Random;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class ByteArrayInputNetStreamTest {
|
||||
private Random random;
|
||||
|
||||
@BeforeEach
|
||||
void before() {
|
||||
random = new Random(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReadBoolean() {
|
||||
ByteArrayOutputNetStream byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.writeBoolean(true);
|
||||
|
||||
ByteArrayInputNetStream byteArrayInputNetStream = new ByteArrayInputNetStream(byteArrayOutputNetStream.toByteArray());
|
||||
|
||||
assertTrue(byteArrayInputNetStream.readBoolean());
|
||||
|
||||
byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.writeBoolean(false);
|
||||
|
||||
byteArrayInputNetStream = new ByteArrayInputNetStream(byteArrayOutputNetStream.toByteArray());
|
||||
|
||||
assertFalse(byteArrayInputNetStream.readBoolean());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReadByte() throws IOException {
|
||||
final byte[] bytes = new byte[1];
|
||||
random.nextBytes(bytes);
|
||||
|
||||
ByteArrayOutputNetStream byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.writeByte(bytes[0]);
|
||||
|
||||
ByteArrayInputNetStream byteArrayInputNetStream = new ByteArrayInputNetStream(byteArrayOutputNetStream.toByteArray());
|
||||
|
||||
assertEquals(bytes[0], byteArrayInputNetStream.readByte());
|
||||
|
||||
byteArrayInputNetStream = new ByteArrayInputNetStream(byteArrayOutputNetStream.toByteArray());
|
||||
|
||||
assertEquals(bytes[0], byteArrayInputNetStream.read());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReadBytes() throws IOException {
|
||||
final byte[] expectedBytes = new byte[10];
|
||||
random.nextBytes(expectedBytes);
|
||||
|
||||
ByteArrayOutputNetStream byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.writeBytes(expectedBytes);
|
||||
|
||||
ByteArrayInputNetStream byteArrayInputNetStream = new ByteArrayInputNetStream(byteArrayOutputNetStream.toByteArray());
|
||||
byte[] actualBytes = new byte[10];
|
||||
byteArrayInputNetStream.readBytes(actualBytes);
|
||||
|
||||
assertArrayEquals(expectedBytes, actualBytes);
|
||||
|
||||
byteArrayInputNetStream = new ByteArrayInputNetStream(byteArrayOutputNetStream.toByteArray());
|
||||
actualBytes = new byte[10];
|
||||
int r = byteArrayInputNetStream.read(actualBytes);
|
||||
|
||||
assertArrayEquals(expectedBytes, actualBytes);
|
||||
assertEquals(expectedBytes.length, r);
|
||||
|
||||
byteArrayInputNetStream = new ByteArrayInputNetStream(byteArrayOutputNetStream.toByteArray());
|
||||
actualBytes = new byte[10];
|
||||
byteArrayInputNetStream.readBytes(actualBytes, 2, 5);
|
||||
byte[] nibbleExpectedBytes = new byte[10];
|
||||
System.arraycopy(expectedBytes, 0, nibbleExpectedBytes, 2, 5);
|
||||
|
||||
assertArrayEquals(nibbleExpectedBytes, actualBytes);
|
||||
|
||||
byteArrayInputNetStream = new ByteArrayInputNetStream(byteArrayOutputNetStream.toByteArray());
|
||||
actualBytes = new byte[10];
|
||||
r = byteArrayInputNetStream.read(actualBytes, 2, 5);
|
||||
nibbleExpectedBytes = new byte[10];
|
||||
System.arraycopy(expectedBytes, 0, nibbleExpectedBytes, 2, 5);
|
||||
|
||||
assertArrayEquals(nibbleExpectedBytes, actualBytes);
|
||||
assertEquals(5, r);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReadUnsignedByte() {
|
||||
ByteArrayOutputNetStream byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.writeUnsignedByte(30);
|
||||
|
||||
ByteArrayInputNetStream byteArrayInputNetStream = new ByteArrayInputNetStream(byteArrayOutputNetStream.toByteArray());
|
||||
|
||||
assertEquals(30, byteArrayInputNetStream.readUnsignedByte());
|
||||
|
||||
byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.writeUnsignedByte(130);
|
||||
|
||||
byteArrayInputNetStream = new ByteArrayInputNetStream(byteArrayOutputNetStream.toByteArray());
|
||||
|
||||
assertEquals(130, byteArrayInputNetStream.readUnsignedByte());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReadInt() {
|
||||
final int integerDig = random.nextInt();
|
||||
|
||||
ByteArrayOutputNetStream byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.writeInt(integerDig);
|
||||
|
||||
ByteArrayInputNetStream byteArrayInputNetStream = new ByteArrayInputNetStream(byteArrayOutputNetStream.toByteArray());
|
||||
|
||||
assertEquals(integerDig, byteArrayInputNetStream.readInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
void readFloat() {
|
||||
final float floatDig = random.nextFloat();
|
||||
|
||||
ByteArrayOutputNetStream byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.writeFloat(floatDig);
|
||||
|
||||
ByteArrayInputNetStream byteArrayInputNetStream = new ByteArrayInputNetStream(byteArrayOutputNetStream.toByteArray());
|
||||
|
||||
assertEquals(floatDig, byteArrayInputNetStream.readFloat());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,259 @@
|
||||
package mc.core.network.proto_1_12_2;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
|
||||
class ByteArrayOutputNetStreamTest {
|
||||
private Random random;
|
||||
|
||||
@BeforeEach
|
||||
void before() {
|
||||
random = new Random(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWriteBoolean() {
|
||||
ByteArrayOutputNetStream byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.writeBoolean(true);
|
||||
|
||||
assertArrayEquals(new byte[]{0x01}, byteArrayOutputNetStream.toByteArray());
|
||||
|
||||
byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.writeBoolean(false);
|
||||
|
||||
assertArrayEquals(new byte[]{0x00}, byteArrayOutputNetStream.toByteArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWriteByte() throws IOException {
|
||||
final byte[] bytes = new byte[1];
|
||||
random.nextBytes(bytes);
|
||||
|
||||
ByteArrayOutputNetStream byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.writeByte(bytes[0]);
|
||||
|
||||
assertArrayEquals(bytes, byteArrayOutputNetStream.toByteArray());
|
||||
|
||||
byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.write(bytes[0]);
|
||||
|
||||
assertArrayEquals(bytes, byteArrayOutputNetStream.toByteArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWriteUnsignedByte() {
|
||||
final byte[] bytes = new byte[1];
|
||||
random.nextBytes(bytes);
|
||||
|
||||
ByteArrayOutputNetStream byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.writeUnsignedByte(bytes[0]);
|
||||
|
||||
assertArrayEquals(bytes, byteArrayOutputNetStream.toByteArray());
|
||||
|
||||
byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.writeUnsignedByte(0xFF);
|
||||
|
||||
assertArrayEquals(new byte[]{(byte) 0xFF}, byteArrayOutputNetStream.toByteArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWriteBytes() throws IOException {
|
||||
final byte[] expectedBytes = new byte[10];
|
||||
random.nextBytes(expectedBytes);
|
||||
|
||||
ByteArrayOutputNetStream byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.writeBytes(expectedBytes);
|
||||
|
||||
assertArrayEquals(expectedBytes, byteArrayOutputNetStream.toByteArray());
|
||||
|
||||
byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.write(expectedBytes);
|
||||
|
||||
assertArrayEquals(expectedBytes, byteArrayOutputNetStream.toByteArray());
|
||||
|
||||
byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.writeBytes(expectedBytes, 2, 5);
|
||||
byte[] nibbleExpectedBytes = new byte[5];
|
||||
System.arraycopy(expectedBytes, 2, nibbleExpectedBytes, 0, 5);
|
||||
|
||||
assertArrayEquals(nibbleExpectedBytes, byteArrayOutputNetStream.toByteArray());
|
||||
|
||||
byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.write(expectedBytes, 2, 5);
|
||||
nibbleExpectedBytes = new byte[5];
|
||||
System.arraycopy(expectedBytes, 2, nibbleExpectedBytes, 0, 5);
|
||||
|
||||
assertArrayEquals(nibbleExpectedBytes, byteArrayOutputNetStream.toByteArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWriteShort() {
|
||||
int smallInt;
|
||||
do {
|
||||
smallInt = random.nextInt();
|
||||
} while (smallInt > Short.MAX_VALUE || smallInt < Short.MIN_VALUE);
|
||||
|
||||
ByteArrayOutputNetStream byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.writeShort(smallInt);
|
||||
|
||||
assertArrayEquals(new byte[]{ (byte) (smallInt >>> 8),
|
||||
(byte) smallInt },
|
||||
byteArrayOutputNetStream.toByteArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWriteInt() {
|
||||
final int integerDig = random.nextInt();
|
||||
|
||||
ByteArrayOutputNetStream byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.writeInt(integerDig);
|
||||
|
||||
assertArrayEquals(new byte[]{ (byte) ((integerDig >>> 24) & 0xFF),
|
||||
(byte) ((integerDig >>> 16) & 0xFF),
|
||||
(byte) ((integerDig >>> 8) & 0xFF),
|
||||
(byte) (integerDig & 0xFF) },
|
||||
byteArrayOutputNetStream.toByteArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWriteLong() {
|
||||
final long longDig = random.nextLong();
|
||||
|
||||
ByteArrayOutputNetStream byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.writeLong(longDig);
|
||||
|
||||
assertArrayEquals(new byte[]{ (byte) ((longDig >>> 56) & 0xFF),
|
||||
(byte) ((longDig >>> 48) & 0xFF),
|
||||
(byte) ((longDig >>> 40) & 0xFF),
|
||||
(byte) ((longDig >>> 32) & 0xFF),
|
||||
(byte) ((longDig >>> 24) & 0xFF),
|
||||
(byte) ((longDig >>> 16) & 0xFF),
|
||||
(byte) ((longDig >>> 8) & 0xFF),
|
||||
(byte) (longDig & 0xFF) },
|
||||
byteArrayOutputNetStream.toByteArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWriteFloat() {
|
||||
final float floatDig = random.nextFloat();
|
||||
|
||||
ByteArrayOutputNetStream byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.writeFloat(floatDig);
|
||||
final int floatBits = Float.floatToIntBits(floatDig);
|
||||
|
||||
assertArrayEquals(new byte[]{ (byte) ((floatBits >>> 24) & 0xFF),
|
||||
(byte) ((floatBits >>> 16) & 0xFF),
|
||||
(byte) ((floatBits >>> 8) & 0xFF),
|
||||
(byte) (floatBits & 0xFF) },
|
||||
byteArrayOutputNetStream.toByteArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWriteDouble() {
|
||||
final double doubleDig = random.nextDouble();
|
||||
|
||||
ByteArrayOutputNetStream byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.writeDouble(doubleDig);
|
||||
final long doubleBits = Double.doubleToLongBits(doubleDig);
|
||||
|
||||
assertArrayEquals(new byte[]{ (byte) ((doubleBits >>> 56) & 0xFF),
|
||||
(byte) ((doubleBits >>> 48) & 0xFF),
|
||||
(byte) ((doubleBits >>> 40) & 0xFF),
|
||||
(byte) ((doubleBits >>> 32) & 0xFF),
|
||||
(byte) ((doubleBits >>> 24) & 0xFF),
|
||||
(byte) ((doubleBits >>> 16) & 0xFF),
|
||||
(byte) ((doubleBits >>> 8) & 0xFF),
|
||||
(byte) (doubleBits & 0xFF) },
|
||||
byteArrayOutputNetStream.toByteArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWriteVarInt() {
|
||||
final int b1Int = 120;
|
||||
ByteArrayOutputNetStream byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.writeVarInt(b1Int);
|
||||
|
||||
assertArrayEquals(new byte[]{ 0x78 },
|
||||
byteArrayOutputNetStream.toByteArray());
|
||||
|
||||
final int b2Int = 12000;
|
||||
byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.writeVarInt(b2Int);
|
||||
|
||||
assertArrayEquals(new byte[]{ (byte) 0xE0, 0x5D },
|
||||
byteArrayOutputNetStream.toByteArray());
|
||||
|
||||
final int b3Int = 120000;
|
||||
byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.writeVarInt(b3Int);
|
||||
|
||||
assertArrayEquals(new byte[]{ (byte) 0xC0, (byte) 0xA9, 0x07 },
|
||||
byteArrayOutputNetStream.toByteArray());
|
||||
|
||||
final int b4Int = 120000000;
|
||||
byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.writeVarInt(b4Int);
|
||||
|
||||
assertArrayEquals(new byte[]{ (byte) 0x80, (byte) 0x9C, (byte) 0x9C, (byte) 0x39 },
|
||||
byteArrayOutputNetStream.toByteArray());
|
||||
|
||||
final int b5Int = 1200000000;
|
||||
byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.writeVarInt(b5Int);
|
||||
|
||||
assertArrayEquals(new byte[]{ (byte) 0x80, (byte) 0x98, (byte) 0x9A, (byte) 0xBC, 0x04 },
|
||||
byteArrayOutputNetStream.toByteArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWriteString() {
|
||||
final String string = "Hello? Есть тут кто?";
|
||||
|
||||
ByteArrayOutputNetStream byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.writeString(string);
|
||||
|
||||
final byte[] strBytes = string.getBytes(StandardCharsets.UTF_8);
|
||||
final byte[] bytes = new byte[strBytes.length + 1];
|
||||
bytes[0] = (byte) string.length(); // здесь считается, что размер поместится в один байт
|
||||
System.arraycopy(strBytes, 0, bytes, 1, strBytes.length);
|
||||
|
||||
assertArrayEquals(bytes, byteArrayOutputNetStream.toByteArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWriteUUID() {
|
||||
final UUID uuid = UUID.randomUUID();
|
||||
|
||||
ByteArrayOutputNetStream byteArrayOutputNetStream = new ByteArrayOutputNetStream();
|
||||
byteArrayOutputNetStream.writeUUID(uuid);
|
||||
|
||||
final long mostSignificantBits = uuid.getMostSignificantBits();
|
||||
final long leastSignificantBits = uuid.getLeastSignificantBits();
|
||||
|
||||
assertArrayEquals(new byte[]{ (byte) ((mostSignificantBits >>> 56) & 0xFF),
|
||||
(byte) ((mostSignificantBits >>> 48) & 0xFF),
|
||||
(byte) ((mostSignificantBits >>> 40) & 0xFF),
|
||||
(byte) ((mostSignificantBits >>> 32) & 0xFF),
|
||||
(byte) ((mostSignificantBits >>> 24) & 0xFF),
|
||||
(byte) ((mostSignificantBits >>> 16) & 0xFF),
|
||||
(byte) ((mostSignificantBits >>> 8) & 0xFF),
|
||||
(byte) (mostSignificantBits & 0xFF),
|
||||
|
||||
(byte) ((leastSignificantBits >>> 56) & 0xFF),
|
||||
(byte) ((leastSignificantBits >>> 48) & 0xFF),
|
||||
(byte) ((leastSignificantBits >>> 40) & 0xFF),
|
||||
(byte) ((leastSignificantBits >>> 32) & 0xFF),
|
||||
(byte) ((leastSignificantBits >>> 24) & 0xFF),
|
||||
(byte) ((leastSignificantBits >>> 16) & 0xFF),
|
||||
(byte) ((leastSignificantBits >>> 8) & 0xFF),
|
||||
(byte) (leastSignificantBits & 0xFF) },
|
||||
byteArrayOutputNetStream.toByteArray());
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
package mc.core.network.proto_1_12_2.packets;
|
||||
|
||||
import mc.core.network.proto_1_12_2.ByteArrayOutputNetStream;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
class ByteArrayInputNetStreamTest {
|
||||
private Random rnd = new Random();
|
||||
|
||||
@Test
|
||||
void readByte() {
|
||||
final byte b0 = (byte) rnd.nextInt();
|
||||
ByteArrayOutputNetStream netStream = new ByteArrayOutputNetStream();
|
||||
netStream.writeByte(b0);
|
||||
byte[] buffer = netStream.toByteArray();
|
||||
|
||||
ByteArrayInputNetStream netInputStream = new ByteArrayInputNetStream(buffer);
|
||||
byte b1 = netInputStream.readByte();
|
||||
assertEquals(b0, b1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void readInt() {
|
||||
final int i0 = rnd.nextInt();
|
||||
ByteArrayOutputNetStream netStream = new ByteArrayOutputNetStream();
|
||||
netStream.writeInt(i0);
|
||||
byte[] buffer = netStream.toByteArray();
|
||||
|
||||
ByteArrayInputNetStream netInputStream = new ByteArrayInputNetStream(buffer);
|
||||
int i1 = netInputStream.readInt();
|
||||
assertEquals(i0, i1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void readFloat() {
|
||||
final float f0 = rnd.nextFloat();
|
||||
ByteArrayOutputNetStream netStream = new ByteArrayOutputNetStream();
|
||||
netStream.writeFloat(f0);
|
||||
byte[] buffer = netStream.toByteArray();
|
||||
|
||||
ByteArrayInputNetStream netInputStream = new ByteArrayInputNetStream(buffer);
|
||||
float f1 = netInputStream.readFloat();
|
||||
assertEquals(f0, f1, 0.00001f);
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import mc.core.world.chunk.Chunk;
|
||||
import mc.core.world.chunk.ChunkSection;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -18,6 +19,7 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@Disabled //FIXME
|
||||
class ChunkDataPacketTest {
|
||||
private static DumbChunkData expectedDumbChunkData;
|
||||
private static DumbChunkData actualDumbChunkData;
|
||||
@@ -35,7 +37,7 @@ class ChunkDataPacketTest {
|
||||
final Chunk chunk = mock(Chunk.class);
|
||||
when(chunk.getX()).thenReturn(0);
|
||||
when(chunk.getZ()).thenReturn(0);
|
||||
when(chunk.getBiomeLocal(anyInt(), anyInt())).thenReturn(Biome.PLAINS);
|
||||
when(chunk.getBiome(anyInt(), anyInt())).thenReturn(Biome.PLAINS);
|
||||
when(chunk.getChunkSection(0)).thenReturn(chunkSection0);
|
||||
when(chunk.getChunkSection(1)).thenReturn(chunkSection1);
|
||||
|
||||
@@ -45,7 +47,7 @@ class ChunkDataPacketTest {
|
||||
private static void verifyMock(Chunk chunk) {
|
||||
verify(chunk).getX();
|
||||
verify(chunk).getZ();
|
||||
verify(chunk, times(256)).getBiomeLocal(anyInt(), anyInt());
|
||||
verify(chunk, times(256)).getBiome(anyInt(), anyInt());
|
||||
verify(chunk, atLeast(2)).getChunkSection(anyInt());
|
||||
}
|
||||
|
||||
@@ -69,7 +71,7 @@ class ChunkDataPacketTest {
|
||||
@BeforeAll
|
||||
static void beforeClassTest() throws IOException {
|
||||
setupExpectedData();
|
||||
setupActualData();
|
||||
setupActualData(); // FIXME тест валится здесь
|
||||
}
|
||||
|
||||
private static Block createChestBlock(BlockType type, int x, int y, int z, int height) {
|
||||
@@ -97,11 +99,11 @@ class ChunkDataPacketTest {
|
||||
|
||||
private static ChunkSection createChunkSection(int height) {
|
||||
final ChunkSection chunkSection = mock(ChunkSection.class);
|
||||
when(chunkSection.getSkyLightLocal(anyInt(), anyInt(), anyInt())).thenReturn(0);
|
||||
when(chunkSection.getSkyLight(anyInt(), anyInt(), anyInt())).thenReturn(0);
|
||||
when(chunkSection.getY()).thenReturn(height);
|
||||
|
||||
if (height == 0) {
|
||||
when(chunkSection.getBlockLocal(anyInt(), anyInt(), anyInt())).thenAnswer(invocation -> {
|
||||
when(chunkSection.getBlock(anyInt(), anyInt(), anyInt())).thenAnswer(invocation -> {
|
||||
Object[] args = invocation.getArguments();
|
||||
final int x = (int) args[0];
|
||||
final int y = (int) args[1];
|
||||
@@ -122,7 +124,7 @@ class ChunkDataPacketTest {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
when(chunkSection.getBlockLocal(anyInt(), anyInt(), anyInt())).thenAnswer(invocation -> {
|
||||
when(chunkSection.getBlock(anyInt(), anyInt(), anyInt())).thenAnswer(invocation -> {
|
||||
Object[] args = invocation.getArguments();
|
||||
final int x = (int) args[0];
|
||||
final int y = (int) args[1];
|
||||
@@ -225,10 +227,10 @@ class ChunkDataPacketTest {
|
||||
private void testLight(DumbChunkSection expected, DumbChunkSection actual, int numberSection) {
|
||||
// Block light
|
||||
assertArrayEquals(expected.getBlockLight(), actual.getBlockLight(),
|
||||
String.format("[%d] Block light", numberSection));
|
||||
String.format("[%d] Block light", numberSection));
|
||||
|
||||
// Sky light
|
||||
assertArrayEquals(expected.getSkyLight(), actual.getSkyLight(),
|
||||
String.format("[%d] Sky light", numberSection));
|
||||
String.format("[%d] Sky light", numberSection));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,236 @@
|
||||
package mc.core.network.proto_1_12_2.packets;
|
||||
|
||||
import com.flowpowered.nbt.*;
|
||||
import mc.core.network.proto_1_12_2.ByteArrayOutputNetStream;
|
||||
import mc.core.network.proto_1_12_2.packets.DumbChunkData.DumbChunkSection;
|
||||
import mc.core.world.Biome;
|
||||
import mc.core.world.block.*;
|
||||
import mc.core.world.chunk.Chunk;
|
||||
import mc.core.world.chunk.ChunkSection;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@Disabled //FIXME
|
||||
class ChunkDataPacketTest {
|
||||
private static DumbChunkData expectedDumbChunkData;
|
||||
private static DumbChunkData actualDumbChunkData;
|
||||
|
||||
private static void setupExpectedData() throws IOException {
|
||||
InputStream inputStream = ChunkDataPacketTest.class.getResourceAsStream("ChunkDataPacket.bin");
|
||||
assertNotNull(inputStream);
|
||||
expectedDumbChunkData = DumbChunkData.ReadFromNetInputStream(IOUtils.toByteArray(inputStream));
|
||||
}
|
||||
|
||||
private static Chunk createMockChunk() {
|
||||
final ChunkSection chunkSection0 = createChunkSection(0);
|
||||
final ChunkSection chunkSection1 = createChunkSection(1);
|
||||
|
||||
final Chunk chunk = mock(Chunk.class);
|
||||
when(chunk.getX()).thenReturn(0);
|
||||
when(chunk.getZ()).thenReturn(0);
|
||||
when(chunk.getBiome(anyInt(), anyInt())).thenReturn(Biome.PLAINS);
|
||||
when(chunk.getChunkSection(0)).thenReturn(chunkSection0);
|
||||
when(chunk.getChunkSection(1)).thenReturn(chunkSection1);
|
||||
|
||||
return chunk;
|
||||
}
|
||||
|
||||
private static void verifyMock(Chunk chunk) {
|
||||
verify(chunk).getX();
|
||||
verify(chunk).getZ();
|
||||
verify(chunk, times(256)).getBiome(anyInt(), anyInt());
|
||||
verify(chunk, atLeast(2)).getChunkSection(anyInt());
|
||||
}
|
||||
|
||||
private static void setupActualData() {
|
||||
Chunk chunk = createMockChunk();
|
||||
|
||||
ChunkDataPacket packet = new ChunkDataPacket();
|
||||
packet.setX(chunk.getX());
|
||||
packet.setZ(chunk.getZ());
|
||||
packet.setChunk(chunk);
|
||||
packet.setInitChunk(true);
|
||||
|
||||
ByteArrayOutputNetStream netStream = new ByteArrayOutputNetStream();
|
||||
packet.writeSelf(netStream);
|
||||
|
||||
verifyMock(chunk);
|
||||
|
||||
actualDumbChunkData = DumbChunkData.ReadFromNetInputStream(netStream.toByteArray());
|
||||
}
|
||||
|
||||
@BeforeAll
|
||||
static void beforeClassTest() throws IOException {
|
||||
setupExpectedData();
|
||||
setupActualData(); // FIXME тест валится здесь
|
||||
}
|
||||
|
||||
private static Block createChestBlock(BlockType type, int x, int y, int z, int height) {
|
||||
final BlockLocation location = new BlockLocation(x, y, z);
|
||||
|
||||
final CompoundMap compoundMap = new CompoundMap();
|
||||
compoundMap.put(new IntTag("x", x));
|
||||
compoundMap.put(new IntTag("y", (height << 4) + y));
|
||||
compoundMap.put(new IntTag("z", z));
|
||||
compoundMap.put(new StringTag("id", type.getNamedId()));
|
||||
final CompoundTag compoundTag = new CompoundTag("", compoundMap);
|
||||
|
||||
return new AbstractBlock(type) {
|
||||
@Override
|
||||
public BlockLocation getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getNBTData() {
|
||||
return compoundTag;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static ChunkSection createChunkSection(int height) {
|
||||
final ChunkSection chunkSection = mock(ChunkSection.class);
|
||||
when(chunkSection.getSkyLight(anyInt(), anyInt(), anyInt())).thenReturn(0);
|
||||
when(chunkSection.getY()).thenReturn(height);
|
||||
|
||||
if (height == 0) {
|
||||
when(chunkSection.getBlock(anyInt(), anyInt(), anyInt())).thenAnswer(invocation -> {
|
||||
Object[] args = invocation.getArguments();
|
||||
final int x = (int) args[0];
|
||||
final int y = (int) args[1];
|
||||
final int z = (int) args[2];
|
||||
|
||||
BlockFactory blockFactory = new BlockFactory();
|
||||
|
||||
if (y == 0) {
|
||||
// @formatter:off
|
||||
if (x == 0 && z == 0) return blockFactory.create(BlockType.STONE, x, y, z);
|
||||
else if (x == 15 && z == 0) return blockFactory.create(BlockType.GRANITE, x, y, z);
|
||||
else if (x == 0 && z == 15) return blockFactory.create(BlockType.POLISHED_GRANITE, x, y, z);
|
||||
else if (x == 15 && z == 15) return blockFactory.create(BlockType.DIORITE, x, y, z);
|
||||
else return blockFactory.create(BlockType.BEDROCK, x, y, z);
|
||||
// @formatter:on
|
||||
} else {
|
||||
return blockFactory.create(BlockType.STONE, x, y, z);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
when(chunkSection.getBlock(anyInt(), anyInt(), anyInt())).thenAnswer(invocation -> {
|
||||
Object[] args = invocation.getArguments();
|
||||
final int x = (int) args[0];
|
||||
final int y = (int) args[1];
|
||||
final int z = (int) args[2];
|
||||
|
||||
BlockFactory blockFactory = new BlockFactory();
|
||||
|
||||
// @formatter:off
|
||||
if (y == 0) return blockFactory.create(BlockType.DIRT, x, y, z);
|
||||
else if (y == 1) return blockFactory.create(BlockType.GRASS, x, y, z);
|
||||
else if (y == 2) {
|
||||
if ((x == 2 || x == 4 || x == 5) && z == 1)
|
||||
return createChestBlock(BlockType.CHEST_NORTH, x, y, z, height);
|
||||
else if ((x == 2 || x == 3 || x == 5) && z == 6)
|
||||
return createChestBlock(BlockType.CHEST_SOUTH, x, y, z, height);
|
||||
else if (x == 1 && (z == 2 || z == 3 || z == 5))
|
||||
return createChestBlock(BlockType.CHEST_WEST, x, y, z, height);
|
||||
else if (x == 6 && (z == 2 || z == 4 || z == 5))
|
||||
return createChestBlock(BlockType.CHEST_EAST, x, y, z, height);
|
||||
else
|
||||
return blockFactory.create(BlockType.AIR, x, y, z);
|
||||
}
|
||||
else return blockFactory.create(BlockType.AIR, x, y, z);
|
||||
// @formatter:on
|
||||
});
|
||||
}
|
||||
|
||||
return chunkSection;
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGeneral() {
|
||||
assertEquals(expectedDumbChunkData.getX(), actualDumbChunkData.getX());
|
||||
assertEquals(expectedDumbChunkData.getZ(), actualDumbChunkData.getZ());
|
||||
assertEquals(expectedDumbChunkData.isInitChunk(), actualDumbChunkData.isInitChunk());
|
||||
assertEquals(expectedDumbChunkData.getBitMask(), actualDumbChunkData.getBitMask());
|
||||
assertArrayEquals(expectedDumbChunkData.getBiomes(), actualDumbChunkData.getBiomes());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNBT() {
|
||||
assertEquals(expectedDumbChunkData.getNumberNBT(), actualDumbChunkData.getNumberNBT());
|
||||
assertEquals(expectedDumbChunkData.getNbt().size(), actualDumbChunkData.getNbt().size());
|
||||
|
||||
for (Tag<?> tag : actualDumbChunkData.getNbt()) {
|
||||
assertTrue(expectedDumbChunkData.getNbt().contains(tag));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testData() {
|
||||
assertEquals(expectedDumbChunkData.getData().length, actualDumbChunkData.getData().length);
|
||||
|
||||
for (int numberSection = 0; numberSection < expectedDumbChunkData.getData().length; numberSection++) {
|
||||
final DumbChunkSection expectedDumbChunkSection = expectedDumbChunkData.getData()[numberSection];
|
||||
final DumbChunkSection actualDumbChunkSection = actualDumbChunkData.getData()[numberSection];
|
||||
|
||||
// Palette
|
||||
testPalette(expectedDumbChunkSection, actualDumbChunkSection, numberSection);
|
||||
|
||||
// Data
|
||||
testDataBlock(expectedDumbChunkSection, actualDumbChunkSection, numberSection);
|
||||
|
||||
// Block and Sky light
|
||||
// DISABLE //
|
||||
//testLight(expectedDumbChunkSection, actualDumbChunkSection, numberSection);
|
||||
}
|
||||
}
|
||||
|
||||
private void testPalette(DumbChunkSection expected, DumbChunkSection actual, int numberSection) {
|
||||
assertEquals(expected.getBitsPerBlock(), actual.getBitsPerBlock());
|
||||
|
||||
if (expected.getPalette().size() > actual.getPalette().size()) {
|
||||
for (int j = 0; j < actual.getPalette().size(); j++) {
|
||||
assertTrue(expected.getPalette().contains(
|
||||
actual.getPalette().get(j)
|
||||
), String.format("[%d] Palette not contains %s", numberSection, actual.getPalette().get(j)));
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < expected.getPalette().size(); j++) {
|
||||
assertTrue(actual.getPalette().contains(
|
||||
expected.getPalette().get(j)
|
||||
), String.format("[%d] Palette not contains %s", numberSection, actual.getPalette().get(j)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void testDataBlock(DumbChunkSection expected, DumbChunkSection actual, int numberSection) {
|
||||
assertEquals(expected.getData().size(), actual.getData().size());
|
||||
|
||||
for (int j = 0; j < expected.getData().size(); j++) {
|
||||
assertEquals(
|
||||
expected.getData().get(j),
|
||||
actual.getData().get(j),
|
||||
String.format("[%d] Data (blocks)", numberSection)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void testLight(DumbChunkSection expected, DumbChunkSection actual, int numberSection) {
|
||||
// Block light
|
||||
assertArrayEquals(expected.getBlockLight(), actual.getBlockLight(),
|
||||
String.format("[%d] Block light", numberSection));
|
||||
|
||||
// Sky light
|
||||
assertArrayEquals(expected.getSkyLight(), actual.getSkyLight(),
|
||||
String.format("[%d] Sky light", numberSection));
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import com.flowpowered.nbt.Tag;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import mc.core.network.proto_1_12_2.ByteArrayInputNetStream;
|
||||
import mc.core.world.block.BlockType;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package mc.core.network.proto_1_12_2.packets;
|
||||
|
||||
import mc.core.network.proto_1_12_2.ByteArrayInputNetStream;
|
||||
import mc.core.network.proto_1_12_2.ByteArrayOutputNetStream;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -73,7 +73,7 @@ public class LoginHandler extends AbstractStateHandler implements LoginStateHand
|
||||
pkt1.setMode(PlayerMode.CREATIVE); //TODO перенести в Config
|
||||
pkt1.setDimension(0/*Overworld*/); //TODO перенести в World
|
||||
pkt1.setDifficulty(0/*Peaceful*/); //TODO перенести в Config
|
||||
pkt1.setLevelType(world.getWorldType().getName());
|
||||
pkt1.setLevelType(world.getType().getName());
|
||||
channel.write(pkt1);
|
||||
|
||||
// Spawn Position
|
||||
@@ -110,9 +110,9 @@ public class LoginHandler extends AbstractStateHandler implements LoginStateHand
|
||||
playerData.setPing(0);
|
||||
playerData.setHasDisplayName(true);
|
||||
playerData.setDisplayName(Text.builder()
|
||||
.append(Text.of(TextColor.RED, TextStyle.BOLD, player.getName().substring(0,1)))
|
||||
.append(Text.of(TextColor.WHITE, player.getName().substring(1)))
|
||||
.build()
|
||||
.append(Text.of(TextColor.RED, TextStyle.BOLD, player.getName().substring(0,1)))
|
||||
.append(Text.of(TextColor.WHITE, player.getName().substring(1)))
|
||||
.build()
|
||||
);
|
||||
pkt5.getListPlayers().add(playerData);
|
||||
channel.writeAndFlush(pkt5);
|
||||
|
||||
@@ -4,6 +4,7 @@ import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import mc.core.world.Biome;
|
||||
import mc.core.world.block.Block;
|
||||
import mc.core.world.chunk.Chunk;
|
||||
import mc.core.world.chunk.ChunkSection;
|
||||
|
||||
@@ -13,7 +14,6 @@ public class SimpleChunk implements Chunk {
|
||||
@Getter
|
||||
private final int x, z;
|
||||
private ChunkSection chunkSection;
|
||||
private final Biome biome = Biome.PLAINS;
|
||||
|
||||
@Override
|
||||
public ChunkSection getChunkSection(int height) {
|
||||
@@ -23,15 +23,57 @@ public class SimpleChunk implements Chunk {
|
||||
@Override
|
||||
public void setChunkSection(int height, ChunkSection chunkSection) {
|
||||
this.chunkSection = chunkSection;
|
||||
this.chunkSection.setParent(this);
|
||||
}
|
||||
|
||||
public Block getBlock(int x, int y, int z) {
|
||||
return chunkSection.getBlock(
|
||||
x - (x >> 4) << 4,
|
||||
y - (y >> 4) << 4,
|
||||
z - (z >> 4) << 4
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getBiomeLocal(int x, int z) {
|
||||
return biome;
|
||||
public void setBlock(Block block) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBiomeLocal(int x, int z, Biome biome) {
|
||||
public int getSkyLight(int x, int y, int z) {
|
||||
return chunkSection.getSkyLight(
|
||||
x - (x >> 4) << 4,
|
||||
y - (y >> 4) << 4,
|
||||
z - (z >> 4) << 4
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSkyLight(int x, int y, int z, int lightLevel) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAddition(int x, int y, int z) {
|
||||
return chunkSection.getAddition(
|
||||
x - (x >> 4) << 4,
|
||||
y - (y >> 4) << 4,
|
||||
z - (z >> 4) << 4
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAddition(int x, int y, int z, int value) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getBiome(int x, int z) {
|
||||
return Biome.PLAINS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBiome(int x, int z, Biome biome) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
package mc.world.simple;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import mc.core.world.block.Block;
|
||||
import mc.core.world.block.BlockFactory;
|
||||
import mc.core.world.block.BlockType;
|
||||
import mc.core.world.chunk.Chunk;
|
||||
import mc.core.world.chunk.ChunkSection;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SimpleChunkSection implements ChunkSection {
|
||||
@Getter
|
||||
@Setter
|
||||
private Chunk parent;
|
||||
private final BlockFactory blockFactory = new BlockFactory();
|
||||
private final List<BlockType> layersBlock;
|
||||
|
||||
@@ -16,27 +22,22 @@ public class SimpleChunkSection implements ChunkSection {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSkyLightLocal(int x, int y, int z) {
|
||||
if (y <= 3) return 0;
|
||||
public int getSkyLight(int localX, int localY, int localZ) {
|
||||
if (localY <= 3) return 0;
|
||||
else return 15;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSkyLightLocal(int x, int y, int z, int lightLevel) {
|
||||
public void setSkyLight(int localX, int localY, int localZ, int lightLevel) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAddition(int x, int y, int z) {
|
||||
public int getAddition(int localX, int localY, int localZ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAddition(int x, int y, int z, int value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getX() {
|
||||
return 0;
|
||||
public void setAddition(int localX, int localY, int localZ, int value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -44,31 +45,26 @@ public class SimpleChunkSection implements ChunkSection {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getZ() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlock(Block block) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getBlockLocal(int x, int y, int z) {
|
||||
if (x < 0) x = 0;
|
||||
else if (x > 15) x = 15;
|
||||
if (y < 0) y = 0;
|
||||
else if (y > 15) y = 15;
|
||||
if (z < 0) z = 0;
|
||||
else if (z > 15) z = 15;
|
||||
public Block getBlock(int localX, int localY, int localZ) {
|
||||
if (localX < 0) localX = 0;
|
||||
else if (localX > 15) localX = 15;
|
||||
if (localY < 0) localY = 0;
|
||||
else if (localY > 15) localY = 15;
|
||||
if (localZ < 0) localZ = 0;
|
||||
else if (localZ > 15) localZ = 15;
|
||||
|
||||
if (y >= layersBlock.size()) {
|
||||
return blockFactory.create(BlockType.AIR, x, y, z);
|
||||
if (localY >= layersBlock.size()) {
|
||||
return blockFactory.create(BlockType.AIR, localX, localY, localZ);
|
||||
}
|
||||
|
||||
BlockType blockType = layersBlock.get(y);
|
||||
if (blockType == null) return blockFactory.create(BlockType.AIR, x, y, z);
|
||||
BlockType blockType = layersBlock.get(localY);
|
||||
if (blockType == null) return blockFactory.create(BlockType.AIR, localX, localY, localZ);
|
||||
|
||||
return blockFactory.create(blockType, x, y, z);
|
||||
return blockFactory.create(blockType, localX, localY, localZ);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import mc.core.EntityLocation;
|
||||
import mc.core.world.World;
|
||||
import mc.core.world.WorldType;
|
||||
import mc.core.world.block.Block;
|
||||
import mc.core.world.chunk.Chunk;
|
||||
import mc.core.world.chunk.ChunkProvider;
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
@@ -19,7 +20,7 @@ public class SimpleWorld implements World, BeanNameAware {
|
||||
@Getter
|
||||
private String name;
|
||||
@Getter
|
||||
private final WorldType worldType = WorldType.FLAT;
|
||||
private final WorldType type = WorldType.FLAT;
|
||||
private EntityLocation spawn;
|
||||
@Setter
|
||||
private ChunkProvider chunkProvider;
|
||||
@@ -49,6 +50,16 @@ public class SimpleWorld implements World, BeanNameAware {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getBlock(int x, int y, int z) {
|
||||
return chunkProvider.getChunk(x >> 4, z >> 4).getBlock(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlock(Block block) {
|
||||
// nope...
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanName(@Nonnull String name) {
|
||||
this.name = name;
|
||||
|
||||
@@ -35,9 +35,9 @@ class SimpleChunkSectionTest {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
Block block = chunkSection.getBlock(x, y, z);
|
||||
if (y > layersBlock.size()-1) {
|
||||
assertEquals(block.getBlockType(), BlockType.AIR);
|
||||
assertEquals(block.getType(), BlockType.AIR);
|
||||
} else {
|
||||
assertEquals(block.getBlockType(), layersBlock.get(y));
|
||||
assertEquals(block.getType(), layersBlock.get(y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user