mirror of https://github.com/Minestom/Minestom.git
210 lines
7.6 KiB
Java
210 lines
7.6 KiB
Java
package net.minestom.server.instance;
|
|
|
|
import net.minestom.testing.Env;
|
|
import net.minestom.testing.EnvTest;
|
|
import net.minestom.server.instance.block.Block;
|
|
import net.minestom.server.utils.NamespaceID;
|
|
import net.minestom.server.utils.binary.BinaryWriter;
|
|
import net.minestom.server.world.biomes.Biome;
|
|
import org.junit.jupiter.api.AfterAll;
|
|
import org.junit.jupiter.api.Assertions;
|
|
import org.junit.jupiter.api.BeforeAll;
|
|
import org.junit.jupiter.api.Test;
|
|
|
|
import java.io.IOException;
|
|
import java.nio.file.*;
|
|
import java.nio.file.attribute.BasicFileAttributes;
|
|
import java.util.function.Consumer;
|
|
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
|
|
@EnvTest
|
|
public class AnvilLoaderIntegrationTest {
|
|
|
|
private static final Path testRoot = Path.of("src", "test", "resources", "net", "minestom", "server", "instance", "anvil_loader");
|
|
private static final Path worldFolder = Path.of("integration_test_world");
|
|
|
|
|
|
@BeforeAll
|
|
public static void prepareTest() throws IOException {
|
|
// https://stackoverflow.com/a/60621544
|
|
Files.walkFileTree(testRoot, new SimpleFileVisitor<>() {
|
|
|
|
@Override
|
|
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
|
|
throws IOException {
|
|
Files.createDirectories(worldFolder.resolve(testRoot.relativize(dir)));
|
|
return FileVisitResult.CONTINUE;
|
|
}
|
|
|
|
@Override
|
|
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
|
|
throws IOException {
|
|
Files.copy(file, worldFolder.resolve(testRoot.relativize(file)), StandardCopyOption.REPLACE_EXISTING);
|
|
return FileVisitResult.CONTINUE;
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
public void loadHouse(Env env) {
|
|
// load a world that contains only a basic house and make sure it is loaded properly
|
|
|
|
AnvilLoader chunkLoader = new AnvilLoader(worldFolder) {
|
|
// Force loads inside current thread
|
|
@Override
|
|
public boolean supportsParallelLoading() {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean supportsParallelSaving() {
|
|
return false;
|
|
}
|
|
};
|
|
Instance instance = env.createFlatInstance(chunkLoader);
|
|
|
|
Consumer<Chunk> checkChunk = chunk -> {
|
|
synchronized (chunk) {
|
|
assertEquals(-4, chunk.getMinSection());
|
|
assertEquals(20, chunk.getMaxSection());
|
|
|
|
// TODO: skylight
|
|
// TODO: block light
|
|
for (int y = 0; y < 16; y++) {
|
|
for (int x = 0; x < 16; x++) {
|
|
for (int z = 0; z < 16; z++) {
|
|
Biome b = chunk.getBiome(x, y, z);
|
|
assertEquals(NamespaceID.from("minecraft:plains"), b.name());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
for (int x = -2; x < 2; x++) {
|
|
for (int z = -2; z < 2; z++) {
|
|
checkChunk.accept(instance.loadChunk(x, z).join()); // this is a test so we don't care too much about waiting for each chunk
|
|
}
|
|
}
|
|
|
|
// wooden house with nylium ground. Open world inside MC to check out
|
|
|
|
// center of world
|
|
assertEquals(Block.BEDROCK, instance.getBlock(0, 0, 0));
|
|
// nylium stripes in front and back of house
|
|
for (int z = -4; z <= 0; z++) {
|
|
assertEquals(Block.WARPED_NYLIUM, instance.getBlock(4, 0, z));
|
|
assertEquals(Block.WARPED_NYLIUM, instance.getBlock(-3, 0, z));
|
|
assertEquals(Block.WARPED_NYLIUM, instance.getBlock(-4, 0, z));
|
|
}
|
|
|
|
// side walls
|
|
for (int x = -2; x <= 3; x++) {
|
|
if(x != 0) { // bedrock block at center
|
|
assertEquals(Block.NETHERRACK, instance.getBlock(x, 0, 0));
|
|
}
|
|
assertEquals(Block.NETHERRACK, instance.getBlock(x, 0, -4));
|
|
|
|
assertEquals(Block.OAK_PLANKS, instance.getBlock(x, 1, 0));
|
|
assertEquals(Block.OAK_PLANKS, instance.getBlock(x, 1, -4));
|
|
assertEquals(Block.OAK_PLANKS, instance.getBlock(x, 2, 0));
|
|
assertEquals(Block.OAK_PLANKS, instance.getBlock(x, 2, -4));
|
|
}
|
|
|
|
// back wall
|
|
for (int z = -4; z <= 0; z++) {
|
|
assertEquals(Block.NETHERRACK, instance.getBlock(-2, 0, z));
|
|
|
|
assertEquals(Block.OAK_PLANKS, instance.getBlock(-2, 1, z));
|
|
assertEquals(Block.OAK_PLANKS, instance.getBlock(-2, 2, z));
|
|
}
|
|
|
|
// door
|
|
Block baseDoor = Block.ACACIA_DOOR
|
|
.withProperty("facing", "west")
|
|
.withProperty("hinge", "left")
|
|
.withProperty("open", "false")
|
|
.withProperty("powered", "false")
|
|
;
|
|
Block bottomDoorPart = baseDoor.withProperty("half", "lower");
|
|
Block topDoorPart = baseDoor.withProperty("half", "upper");
|
|
assertEquals(bottomDoorPart, instance.getBlock(3, 1, -3));
|
|
assertEquals(topDoorPart, instance.getBlock(3, 2, -3));
|
|
|
|
// light blocks
|
|
Block endRod = Block.END_ROD.withProperty("facing", "up");
|
|
assertEquals(endRod, instance.getBlock(-1, 1, -1));
|
|
assertEquals(Block.TORCH, instance.getBlock(-1, 2, -1));
|
|
|
|
// flower pot
|
|
assertEquals(Block.OAK_PLANKS, instance.getBlock(-1, 1, -3));
|
|
assertEquals(Block.POTTED_POPPY, instance.getBlock(-1, 2, -3));
|
|
|
|
env.destroyInstance(instance);
|
|
}
|
|
|
|
@Test
|
|
public void loadAndSaveChunk(Env env) throws InterruptedException {
|
|
Instance instance = env.createFlatInstance(new AnvilLoader(worldFolder) {
|
|
// Force loads inside current thread
|
|
@Override
|
|
public boolean supportsParallelLoading() {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean supportsParallelSaving() {
|
|
return false;
|
|
}
|
|
});
|
|
Chunk originalChunk = instance.loadChunk(0,0).join();
|
|
|
|
synchronized (originalChunk) {
|
|
instance.saveChunkToStorage(originalChunk);
|
|
instance.unloadChunk(originalChunk);
|
|
while(originalChunk.isLoaded()) {
|
|
Thread.sleep(1);
|
|
}
|
|
}
|
|
|
|
Chunk reloadedChunk = instance.loadChunk(0,0).join();
|
|
for(int section = reloadedChunk.getMinSection(); section < reloadedChunk.getMaxSection(); section++) {
|
|
Section originalSection = originalChunk.getSection(section);
|
|
Section reloadedSection = reloadedChunk.getSection(section);
|
|
|
|
// easiest equality check to write is a memory compare on written output
|
|
BinaryWriter originalWriter = new BinaryWriter();
|
|
BinaryWriter reloadedWriter = new BinaryWriter();
|
|
originalSection.write(originalWriter);
|
|
reloadedSection.write(reloadedWriter);
|
|
|
|
Assertions.assertArrayEquals(originalWriter.toByteArray(), reloadedWriter.toByteArray());
|
|
}
|
|
|
|
env.destroyInstance(instance);
|
|
}
|
|
|
|
@AfterAll
|
|
public static void cleanupTest() throws IOException {
|
|
Files.walkFileTree(worldFolder, new SimpleFileVisitor<>() {
|
|
|
|
@Override
|
|
public FileVisitResult postVisitDirectory(Path dir, IOException e)
|
|
throws IOException {
|
|
Files.delete(dir);
|
|
return FileVisitResult.CONTINUE;
|
|
}
|
|
|
|
@Override
|
|
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
|
|
throws IOException {
|
|
Files.delete(file);
|
|
return FileVisitResult.CONTINUE;
|
|
}
|
|
});
|
|
}
|
|
}
|