mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-24 09:01:54 +01:00
Basic testing framework (#594)
This commit is contained in:
parent
37bebff883
commit
91c06da68a
@ -21,5 +21,8 @@ tasks {
|
||||
}
|
||||
withType<Test> {
|
||||
useJUnitPlatform()
|
||||
// Present until tests all succeed without
|
||||
maxParallelForks = Runtime.getRuntime().availableProcessors()
|
||||
setForkEvery(1)
|
||||
}
|
||||
}
|
@ -1,15 +1,12 @@
|
||||
package net.minestom.server.instance;
|
||||
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.exception.ExceptionManager;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.instance.block.BlockHandler;
|
||||
import net.minestom.server.instance.block.BlockManager;
|
||||
import net.minestom.server.tag.Tag;
|
||||
import net.minestom.server.utils.NamespaceID;
|
||||
import net.minestom.server.utils.async.AsyncUtils;
|
||||
import net.minestom.server.world.biomes.Biome;
|
||||
import net.minestom.server.world.biomes.BiomeManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.mca.*;
|
||||
@ -30,9 +27,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class AnvilLoader implements IChunkLoader {
|
||||
private final static Logger LOGGER = LoggerFactory.getLogger(AnvilLoader.class);
|
||||
private static final BlockManager BLOCK_MANAGER = MinecraftServer.getBlockManager();
|
||||
private static final BiomeManager BIOME_MANAGER = MinecraftServer.getBiomeManager();
|
||||
private static final ExceptionManager EXCEPTION_MANAGER = MinecraftServer.getExceptionManager();
|
||||
private static final Biome BIOME = Biome.PLAINS;
|
||||
|
||||
private final Map<String, RegionFile> alreadyLoaded = new ConcurrentHashMap<>();
|
||||
@ -74,7 +68,7 @@ public class AnvilLoader implements IChunkLoader {
|
||||
try {
|
||||
return loadMCA(instance, chunkX, chunkZ);
|
||||
} catch (Exception e) {
|
||||
EXCEPTION_MANAGER.handleException(e);
|
||||
MinecraftServer.getExceptionManager().handleException(e);
|
||||
}
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
@ -119,7 +113,8 @@ public class AnvilLoader implements IChunkLoader {
|
||||
int finalZ = fileChunk.getZ() * Chunk.CHUNK_SIZE_Z + z;
|
||||
int finalY = section.getY() * Chunk.CHUNK_SECTION_SIZE + y;
|
||||
String biomeName = section.getBiome(x, y, z);
|
||||
Biome biome = biomeCache.computeIfAbsent(biomeName, n -> Objects.requireNonNullElse(BIOME_MANAGER.getByName(NamespaceID.from(n)), BIOME));
|
||||
Biome biome = biomeCache.computeIfAbsent(biomeName, n ->
|
||||
Objects.requireNonNullElse(MinecraftServer.getBiomeManager().getByName(NamespaceID.from(n)), BIOME));
|
||||
chunk.setBiome(finalX, finalY, finalZ, biome);
|
||||
}
|
||||
}
|
||||
@ -151,7 +146,7 @@ public class AnvilLoader implements IChunkLoader {
|
||||
}
|
||||
return new RegionFile(new RandomAccessFile(regionPath.toFile(), "rw"), regionX, regionZ, instance.getDimensionType().getMinY(), instance.getDimensionType().getMaxY()-1);
|
||||
} catch (IOException | AnvilException e) {
|
||||
EXCEPTION_MANAGER.handleException(e);
|
||||
MinecraftServer.getExceptionManager().handleException(e);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
@ -178,7 +173,7 @@ public class AnvilLoader implements IChunkLoader {
|
||||
|
||||
chunk.setBlock(x, y + yOffset, z, block);
|
||||
} catch (Exception e) {
|
||||
EXCEPTION_MANAGER.handleException(e);
|
||||
MinecraftServer.getExceptionManager().handleException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -199,7 +194,7 @@ public class AnvilLoader implements IChunkLoader {
|
||||
|
||||
final String tileEntityID = te.getString("id");
|
||||
if (tileEntityID != null) {
|
||||
final BlockHandler handler = BLOCK_MANAGER.getHandlerOrDummy(tileEntityID);
|
||||
final BlockHandler handler = MinecraftServer.getBlockManager().getHandlerOrDummy(tileEntityID);
|
||||
block = block.withHandler(handler);
|
||||
}
|
||||
// Remove anvil tags
|
||||
@ -254,7 +249,7 @@ public class AnvilLoader implements IChunkLoader {
|
||||
alreadyLoaded.put(n, mcaFile);
|
||||
} catch (AnvilException | IOException e) {
|
||||
LOGGER.error("Failed to save chunk " + chunkX + ", " + chunkZ, e);
|
||||
EXCEPTION_MANAGER.handleException(e);
|
||||
MinecraftServer.getExceptionManager().handleException(e);
|
||||
return AsyncUtils.VOID_FUTURE;
|
||||
}
|
||||
}
|
||||
@ -264,7 +259,7 @@ public class AnvilLoader implements IChunkLoader {
|
||||
column = mcaFile.getOrCreateChunk(chunkX, chunkZ);
|
||||
} catch (AnvilException | IOException e) {
|
||||
LOGGER.error("Failed to save chunk " + chunkX + ", " + chunkZ, e);
|
||||
EXCEPTION_MANAGER.handleException(e);
|
||||
MinecraftServer.getExceptionManager().handleException(e);
|
||||
return AsyncUtils.VOID_FUTURE;
|
||||
}
|
||||
save(chunk, column);
|
||||
@ -274,7 +269,7 @@ public class AnvilLoader implements IChunkLoader {
|
||||
mcaFile.forget(column);
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("Failed to save chunk " + chunkX + ", " + chunkZ, e);
|
||||
EXCEPTION_MANAGER.handleException(e);
|
||||
MinecraftServer.getExceptionManager().handleException(e);
|
||||
return AsyncUtils.VOID_FUTURE;
|
||||
}
|
||||
return AsyncUtils.VOID_FUTURE;
|
||||
|
@ -3,7 +3,6 @@ package net.minestom.server.instance;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArraySet;
|
||||
import net.kyori.adventure.identity.Identity;
|
||||
import net.kyori.adventure.pointer.Pointers;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.Tickable;
|
||||
import net.minestom.server.adventure.audience.PacketGroupingAudience;
|
||||
import net.minestom.server.coordinate.Point;
|
||||
@ -17,7 +16,6 @@ import net.minestom.server.event.GlobalHandles;
|
||||
import net.minestom.server.event.instance.InstanceTickEvent;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.instance.block.BlockHandler;
|
||||
import net.minestom.server.instance.block.BlockManager;
|
||||
import net.minestom.server.network.packet.server.play.BlockActionPacket;
|
||||
import net.minestom.server.network.packet.server.play.TimeUpdatePacket;
|
||||
import net.minestom.server.tag.Tag;
|
||||
@ -54,8 +52,6 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
public abstract class Instance implements Block.Getter, Block.Setter, Tickable, Schedulable, TagHandler, PacketGroupingAudience {
|
||||
|
||||
protected static final BlockManager BLOCK_MANAGER = MinecraftServer.getBlockManager();
|
||||
|
||||
private boolean registered;
|
||||
|
||||
private final DimensionType dimensionType;
|
||||
|
@ -124,7 +124,7 @@ public class InstanceContainer extends Instance {
|
||||
final BlockHandler previousHandler = previousBlock.handler();
|
||||
|
||||
// Change id based on neighbors
|
||||
final BlockPlacementRule blockPlacementRule = BLOCK_MANAGER.getBlockPlacementRule(block);
|
||||
final BlockPlacementRule blockPlacementRule = MinecraftServer.getBlockManager().getBlockPlacementRule(block);
|
||||
if (blockPlacementRule != null) {
|
||||
block = blockPlacementRule.blockUpdate(this, blockPosition, block);
|
||||
}
|
||||
@ -501,7 +501,7 @@ public class InstanceContainer extends Instance {
|
||||
if (chunk == null) continue;
|
||||
|
||||
final Block neighborBlock = chunk.getBlock(neighborX, neighborY, neighborZ);
|
||||
final BlockPlacementRule neighborBlockPlacementRule = BLOCK_MANAGER.getBlockPlacementRule(neighborBlock);
|
||||
final BlockPlacementRule neighborBlockPlacementRule = MinecraftServer.getBlockManager().getBlockPlacementRule(neighborBlock);
|
||||
if (neighborBlockPlacementRule == null) continue;
|
||||
|
||||
final Vec neighborPosition = new Vec(neighborX, neighborY, neighborZ);
|
||||
|
64
src/test/java/net/minestom/server/api/Env.java
Normal file
64
src/test/java/net/minestom/server/api/Env.java
Normal file
@ -0,0 +1,64 @@
|
||||
package net.minestom.server.api;
|
||||
|
||||
import net.minestom.server.ServerProcess;
|
||||
import net.minestom.server.coordinate.Pos;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.instance.Chunk;
|
||||
import net.minestom.server.instance.ChunkGenerator;
|
||||
import net.minestom.server.instance.ChunkPopulator;
|
||||
import net.minestom.server.instance.Instance;
|
||||
import net.minestom.server.instance.batch.ChunkBatch;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
public interface Env {
|
||||
@NotNull ServerProcess process();
|
||||
|
||||
@NotNull TestConnection createConnection();
|
||||
|
||||
default void tick() {
|
||||
process().ticker().tick(System.nanoTime());
|
||||
}
|
||||
|
||||
default boolean tickWhile(BooleanSupplier condition, Duration timeout) {
|
||||
var ticker = process().ticker();
|
||||
final long start = System.nanoTime();
|
||||
while (condition.getAsBoolean()) {
|
||||
final long tick = System.nanoTime();
|
||||
ticker.tick(tick);
|
||||
if (timeout != null && System.nanoTime() - start > timeout.toNanos()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
default @NotNull Player createPlayer(@NotNull Instance instance, @NotNull Pos pos) {
|
||||
return createConnection().connect(instance, pos).join();
|
||||
}
|
||||
|
||||
default @NotNull Instance createFlatInstance() {
|
||||
var instance = process().instance().createInstanceContainer();
|
||||
instance.setChunkGenerator(new ChunkGenerator() {
|
||||
@Override
|
||||
public void generateChunkData(@NotNull ChunkBatch batch, int chunkX, int chunkZ) {
|
||||
for (byte x = 0; x < Chunk.CHUNK_SIZE_X; x++)
|
||||
for (byte z = 0; z < Chunk.CHUNK_SIZE_Z; z++) {
|
||||
for (byte y = 0; y < 40; y++) {
|
||||
batch.setBlock(x, y, z, Block.STONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ChunkPopulator> getPopulators() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
return instance;
|
||||
}
|
||||
}
|
11
src/test/java/net/minestom/server/api/EnvBefore.java
Normal file
11
src/test/java/net/minestom/server/api/EnvBefore.java
Normal file
@ -0,0 +1,11 @@
|
||||
package net.minestom.server.api;
|
||||
|
||||
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
|
||||
final class EnvBefore implements BeforeEachCallback {
|
||||
@Override
|
||||
public void beforeEach(ExtensionContext context) {
|
||||
System.setProperty("minestom.viewable-packet", "false");
|
||||
}
|
||||
}
|
22
src/test/java/net/minestom/server/api/EnvImpl.java
Normal file
22
src/test/java/net/minestom/server/api/EnvImpl.java
Normal file
@ -0,0 +1,22 @@
|
||||
package net.minestom.server.api;
|
||||
|
||||
import net.minestom.server.ServerProcess;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
final class EnvImpl implements Env {
|
||||
private final ServerProcess process;
|
||||
|
||||
public EnvImpl(ServerProcess process) {
|
||||
this.process = process;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ServerProcess process() {
|
||||
return process;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull TestConnection createConnection() {
|
||||
return new TestConnectionImpl(this);
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package net.minestom.server.api;
|
||||
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.ParameterContext;
|
||||
import org.junit.jupiter.api.extension.ParameterResolutionException;
|
||||
import org.junit.jupiter.api.extension.support.TypeBasedParameterResolver;
|
||||
|
||||
final class EnvParameterResolver extends TypeBasedParameterResolver<Env> {
|
||||
@Override
|
||||
public Env resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
|
||||
throws ParameterResolutionException {
|
||||
return new EnvImpl(MinecraftServer.updateProcess());
|
||||
}
|
||||
}
|
15
src/test/java/net/minestom/server/api/EnvTest.java
Normal file
15
src/test/java/net/minestom/server/api/EnvTest.java
Normal file
@ -0,0 +1,15 @@
|
||||
package net.minestom.server.api;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@ExtendWith(EnvParameterResolver.class)
|
||||
@ExtendWith(EnvBefore.class)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface EnvTest {
|
||||
}
|
20
src/test/java/net/minestom/server/api/TestConnection.java
Normal file
20
src/test/java/net/minestom/server/api/TestConnection.java
Normal file
@ -0,0 +1,20 @@
|
||||
package net.minestom.server.api;
|
||||
|
||||
import net.minestom.server.coordinate.Pos;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.instance.Instance;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface TestConnection {
|
||||
@NotNull CompletableFuture<@NotNull Player> connect(@NotNull Instance instance, @NotNull Pos pos);
|
||||
|
||||
<T extends ServerPacket> @NotNull PacketTracker<T> trackIncoming(@NotNull Class<T> type);
|
||||
|
||||
interface PacketTracker<T> {
|
||||
@NotNull List<@NotNull T> collect();
|
||||
}
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
package net.minestom.server.api;
|
||||
|
||||
import net.minestom.server.ServerProcess;
|
||||
import net.minestom.server.coordinate.Pos;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.EventListener;
|
||||
import net.minestom.server.event.player.PlayerLoginEvent;
|
||||
import net.minestom.server.instance.Instance;
|
||||
import net.minestom.server.network.packet.server.SendablePacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.player.PlayerConnection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
final class TestConnectionImpl implements TestConnection {
|
||||
private final Env env;
|
||||
private final ServerProcess process;
|
||||
private final PlayerConnectionImpl playerConnection = new PlayerConnectionImpl();
|
||||
|
||||
private final List<TrackerImpl<ServerPacket>> incomingTrackers = new CopyOnWriteArrayList<>();
|
||||
|
||||
public TestConnectionImpl(Env env) {
|
||||
this.env = env;
|
||||
this.process = env.process();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull CompletableFuture<Player> connect(@NotNull Instance instance, @NotNull Pos pos) {
|
||||
AtomicReference<EventListener<PlayerLoginEvent>> listenerRef = new AtomicReference<>();
|
||||
var listener = EventListener.builder(PlayerLoginEvent.class)
|
||||
.handler(event -> {
|
||||
if (event.getPlayer().getPlayerConnection() == playerConnection) {
|
||||
event.setSpawningInstance(instance);
|
||||
event.getPlayer().setRespawnPoint(pos);
|
||||
process.eventHandler().removeListener(listenerRef.get());
|
||||
}
|
||||
}).build();
|
||||
listenerRef.set(listener);
|
||||
process.eventHandler().addListener(listener);
|
||||
|
||||
var player = new Player(UUID.randomUUID(), "RandName", playerConnection);
|
||||
process.connection().startPlayState(player, true);
|
||||
while (player.getInstance() != instance) { // TODO replace with proper future
|
||||
env.tick();
|
||||
}
|
||||
return CompletableFuture.completedFuture(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull <T extends ServerPacket> PacketTracker<T> trackIncoming(@NotNull Class<T> type) {
|
||||
var tracker = new TrackerImpl<>(type);
|
||||
this.incomingTrackers.add(TrackerImpl.class.cast(tracker));
|
||||
return tracker;
|
||||
}
|
||||
|
||||
final class PlayerConnectionImpl extends PlayerConnection {
|
||||
@Override
|
||||
public void sendPacket(@NotNull SendablePacket packet) {
|
||||
for (var tracker : incomingTrackers) {
|
||||
final var serverPacket = SendablePacket.extractServerPacket(packet);
|
||||
if (tracker.type.isAssignableFrom(serverPacket.getClass())) tracker.packets.add(serverPacket);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull SocketAddress getRemoteAddress() {
|
||||
return new InetSocketAddress("localhost", 25565);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
final class TrackerImpl<T extends ServerPacket> implements PacketTracker<T> {
|
||||
private final Class<T> type;
|
||||
private final List<T> packets = new CopyOnWriteArrayList<>();
|
||||
|
||||
public TrackerImpl(Class<T> type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<T> collect() {
|
||||
incomingTrackers.remove(this);
|
||||
return List.copyOf(packets);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package net.minestom.server.entity;
|
||||
|
||||
import net.minestom.server.api.Env;
|
||||
import net.minestom.server.api.EnvTest;
|
||||
import net.minestom.server.coordinate.Pos;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.play.JoinGamePacket;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@EnvTest
|
||||
public class EntityInstanceIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void entityJoin(Env env) {
|
||||
var instance = env.createFlatInstance();
|
||||
var entity = new Entity(EntityTypes.ZOMBIE);
|
||||
entity.setInstance(instance, new Pos(0, 42, 0)).join();
|
||||
assertEquals(instance, entity.getInstance());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void playerJoin(Env env) {
|
||||
var instance = env.createFlatInstance();
|
||||
var connection = env.createConnection();
|
||||
var player = connection.connect(instance, new Pos(0, 42, 0)).join();
|
||||
assertEquals(instance, player.getInstance());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void playerJoinPacket(Env env) {
|
||||
var instance = env.createFlatInstance();
|
||||
var connection = env.createConnection();
|
||||
var tracker = connection.trackIncoming(JoinGamePacket.class);
|
||||
var tracker2 = connection.trackIncoming(ServerPacket.class);
|
||||
var player = connection.connect(instance, new Pos(0, 40, 0)).join();
|
||||
assertEquals(instance, player.getInstance());
|
||||
assertEquals(new Pos(0, 40, 0), player.getPosition());
|
||||
|
||||
assertEquals(1, tracker.collect().size());
|
||||
assertTrue(tracker2.collect().size() > 1);
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
package net.minestom.server.entity;
|
||||
|
||||
import net.minestom.server.api.Env;
|
||||
import net.minestom.server.api.EnvTest;
|
||||
import net.minestom.server.coordinate.Pos;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.play.EntityTeleportPacket;
|
||||
import net.minestom.server.network.packet.server.play.PlayerPositionAndLookPacket;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
@EnvTest
|
||||
public class EntityTeleportIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void entityChunkTeleport(Env env) {
|
||||
var instance = env.createFlatInstance();
|
||||
var entity = new Entity(EntityTypes.ZOMBIE);
|
||||
entity.setInstance(instance, new Pos(0, 42, 0)).join();
|
||||
assertEquals(instance, entity.getInstance());
|
||||
assertEquals(new Pos(0, 42, 0), entity.getPosition());
|
||||
|
||||
entity.teleport(new Pos(1, 42, 1)).join();
|
||||
assertEquals(new Pos(1, 42, 1), entity.getPosition());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void entityTeleport(Env env) {
|
||||
var instance = env.createFlatInstance();
|
||||
var entity = new Entity(EntityTypes.ZOMBIE);
|
||||
entity.setInstance(instance, new Pos(0, 42, 0)).join();
|
||||
assertEquals(instance, entity.getInstance());
|
||||
assertEquals(new Pos(0, 42, 0), entity.getPosition());
|
||||
|
||||
entity.teleport(new Pos(52, 42, 52)).join();
|
||||
assertEquals(new Pos(52, 42, 52), entity.getPosition());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void playerChunkTeleport(Env env) {
|
||||
var instance = env.createFlatInstance();
|
||||
var connection = env.createConnection();
|
||||
var player = connection.connect(instance, new Pos(0, 40, 0)).join();
|
||||
assertEquals(instance, player.getInstance());
|
||||
assertEquals(new Pos(0, 40, 0), player.getPosition());
|
||||
|
||||
var viewerConnection = env.createConnection();
|
||||
viewerConnection.connect(instance, new Pos(0, 40, 0)).join();
|
||||
|
||||
var tracker = connection.trackIncoming(ServerPacket.class);
|
||||
var viewerTracker = viewerConnection.trackIncoming(ServerPacket.class);
|
||||
var teleportPosition = new Pos(1, 42, 1);
|
||||
player.teleport(teleportPosition).join();
|
||||
assertEquals(teleportPosition, player.getPosition());
|
||||
|
||||
// Verify received packet(s)
|
||||
{
|
||||
var packets = tracker.collect();
|
||||
assertEquals(1, packets.size());
|
||||
var packet = ((PlayerPositionAndLookPacket) packets.get(0));
|
||||
assertEquals(teleportPosition, packet.position());
|
||||
}
|
||||
|
||||
// Verify broadcast packet(s)
|
||||
{
|
||||
var packets = viewerTracker.collect();
|
||||
assertEquals(1, packets.size());
|
||||
var packet = ((EntityTeleportPacket) packets.get(0));
|
||||
assertEquals(player.getEntityId(), packet.entityId());
|
||||
assertEquals(teleportPosition, packet.position());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void playerTeleport(Env env) {
|
||||
var instance = env.createFlatInstance();
|
||||
var connection = env.createConnection();
|
||||
var player = connection.connect(instance, new Pos(0, 40, 0)).join();
|
||||
assertEquals(instance, player.getInstance());
|
||||
assertEquals(new Pos(0, 40, 0), player.getPosition());
|
||||
|
||||
var viewerConnection = env.createConnection();
|
||||
viewerConnection.connect(instance, new Pos(0, 40, 0)).join();
|
||||
|
||||
var teleportPosition = new Pos(4999, 42, 4999);
|
||||
player.teleport(teleportPosition).join();
|
||||
assertEquals(teleportPosition, player.getPosition());
|
||||
}
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
package net.minestom.server.entity;
|
||||
|
||||
import net.minestom.server.api.Env;
|
||||
import net.minestom.server.api.EnvTest;
|
||||
import net.minestom.server.coordinate.Pos;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@EnvTest
|
||||
public class EntityViewIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void emptyEntity(Env env) {
|
||||
var instance = env.createFlatInstance();
|
||||
var entity = new Entity(EntityType.ZOMBIE);
|
||||
entity.setInstance(instance, new Pos(0, 40, 42)).join();
|
||||
assertEquals(0, entity.getViewers().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyPlayer(Env env) {
|
||||
var instance = env.createFlatInstance();
|
||||
var player = env.createPlayer(instance, new Pos(0, 42, 0));
|
||||
assertEquals(0, player.getViewers().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multiPlayers(Env env) {
|
||||
var instance = env.createFlatInstance();
|
||||
var p1 = env.createPlayer(instance, new Pos(0, 42, 42));
|
||||
var p2 = env.createPlayer(instance, new Pos(0, 42, 42));
|
||||
|
||||
assertEquals(1, p1.getViewers().size());
|
||||
p1.getViewers().forEach(p -> assertEquals(p2, p));
|
||||
|
||||
assertEquals(1, p2.getViewers().size());
|
||||
p2.getViewers().forEach(p -> assertEquals(p1, p));
|
||||
|
||||
p2.remove();
|
||||
assertEquals(0, p1.getViewers().size());
|
||||
assertEquals(0, p2.getViewers().size());
|
||||
|
||||
var p3 = env.createPlayer(instance, new Pos(0, 42, 42));
|
||||
assertEquals(1, p1.getViewers().size());
|
||||
p1.getViewers().forEach(p -> assertEquals(p3, p));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void movements(Env env) {
|
||||
var instance = env.createFlatInstance();
|
||||
var p1 = env.createPlayer(instance, new Pos(0, 42, 0));
|
||||
var p2 = env.createPlayer(instance, new Pos(0, 42, 96));
|
||||
|
||||
assertEquals(0, p1.getViewers().size());
|
||||
assertEquals(0, p2.getViewers().size());
|
||||
|
||||
p2.teleport(new Pos(0, 42, 95)).join(); // Teleport in range (6 chunks)
|
||||
assertEquals(1, p1.getViewers().size());
|
||||
assertEquals(1, p2.getViewers().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void autoViewable(Env env) {
|
||||
var instance = env.createFlatInstance();
|
||||
var p1 = env.createPlayer(instance, new Pos(0, 42, 0));
|
||||
assertTrue(p1.isAutoViewable());
|
||||
p1.setAutoViewable(false);
|
||||
|
||||
var p2 = env.createPlayer(instance, new Pos(0, 42, 0));
|
||||
|
||||
assertEquals(0, p1.getViewers().size());
|
||||
assertEquals(1, p2.getViewers().size());
|
||||
|
||||
p1.setAutoViewable(true);
|
||||
assertEquals(1, p1.getViewers().size());
|
||||
assertEquals(1, p2.getViewers().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void viewableRule(Env env) {
|
||||
var instance = env.createFlatInstance();
|
||||
var p1 = env.createPlayer(instance, new Pos(0, 42, 0));
|
||||
p1.updateViewableRule(player -> player.getEntityId() == p1.getEntityId() + 1);
|
||||
|
||||
var p2 = env.createPlayer(instance, new Pos(0, 42, 0));
|
||||
|
||||
assertEquals(1, p1.getViewers().size());
|
||||
assertEquals(1, p2.getViewers().size());
|
||||
|
||||
p1.updateViewableRule(player -> false);
|
||||
|
||||
assertEquals(0, p1.getViewers().size());
|
||||
assertEquals(1, p2.getViewers().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void viewerRule(Env env) {
|
||||
var instance = env.createFlatInstance();
|
||||
var p1 = env.createPlayer(instance, new Pos(0, 42, 0));
|
||||
p1.updateViewerRule(player -> player.getEntityId() == p1.getEntityId() + 1);
|
||||
|
||||
var p2 = env.createPlayer(instance, new Pos(0, 42, 0));
|
||||
|
||||
assertEquals(1, p1.getViewers().size());
|
||||
assertEquals(1, p2.getViewers().size());
|
||||
|
||||
p1.updateViewerRule(player -> false);
|
||||
|
||||
assertEquals(1, p1.getViewers().size());
|
||||
assertEquals(0, p2.getViewers().size());
|
||||
}
|
||||
}
|
@ -1,9 +1,7 @@
|
||||
package net.minestom.server.inventory;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minestom.server.inventory.Inventory;
|
||||
import net.minestom.server.inventory.InventoryType;
|
||||
import net.minestom.server.inventory.TransactionOption;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.item.Material;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@ -12,6 +10,11 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class InventoryTest {
|
||||
|
||||
static {
|
||||
// Required to prevent initialization error during event call
|
||||
MinecraftServer.init();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreation() {
|
||||
Inventory inventory = new Inventory(InventoryType.CHEST_1_ROW, "title");
|
||||
|
Loading…
Reference in New Issue
Block a user