More FakePlayerController features + fix with chunks and player food bar

This commit is contained in:
Felix Cravic 2020-05-25 13:46:48 +02:00
parent 6254ec93e9
commit e8a2c54485
17 changed files with 135 additions and 37 deletions

View File

@ -35,13 +35,10 @@ import net.minestom.server.utils.time.UpdateOption;
import net.minestom.server.world.Dimension;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
public class PlayerInit {
private static Random random = new Random();
private static volatile InstanceContainer instanceContainer;
private static volatile InstanceContainer netherTest;
@ -154,7 +151,7 @@ public class PlayerInit {
//ChickenCreature chickenCreature = new ChickenCreature(player.getPosition());
//chickenCreature.setInstance(player.getInstance());
FakePlayer fakePlayer = new FakePlayer(UUID.randomUUID(), "test");
FakePlayer fakePlayer = new FakePlayer(UUID.randomUUID(), "test", true);
FakePlayerController controller = fakePlayer.getController();
controller.sendChatMessage("I am a bot!");
@ -209,8 +206,8 @@ public class PlayerInit {
});
player.addEventCallback(PlayerSpawnEvent.class, event -> {
player.setGameMode(GameMode.CREATIVE);
player.teleport(new Position(random.nextInt(5), 70, random.nextInt(5)));
player.setGameMode(GameMode.SURVIVAL);
player.teleport(new Position(0, 70, 0));
player.setGlowing(true);

View File

@ -1,11 +1,14 @@
package fr.themode.demo.commands;
import net.minestom.server.MinecraftServer;
import net.minestom.server.command.CommandProcessor;
import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.Player;
import net.minestom.server.instance.Instance;
import net.minestom.server.utils.MathUtils;
import net.minestom.server.entity.fakeplayer.FakePlayer;
import net.minestom.server.entity.fakeplayer.FakePlayerController;
import net.minestom.server.timer.TaskRunnable;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.time.TimeUnit;
import net.minestom.server.utils.time.UpdateOption;
public class SimpleCommand implements CommandProcessor {
@Override
@ -20,16 +23,25 @@ public class SimpleCommand implements CommandProcessor {
@Override
public boolean process(Player player, String command, String[] args) {
player.sendMessage("Everyone come at you!");
player.setFireForDuration(1000, TimeUnit.MILLISECOND);
Instance instance = player.getInstance();
for (Player p : MinecraftServer.getConnectionManager().getOnlinePlayers()) {
if (!(p instanceof FakePlayer))
continue;
FakePlayer fakePlayer = (FakePlayer) p;
FakePlayerController controller = fakePlayer.getController();
BlockPosition blockPosition = new BlockPosition(0, 39, 0);
controller.startDigging(blockPosition);
for (EntityCreature creature : instance.getCreatures()) {
creature.setPathTo(player.getPosition());
MinecraftServer.getSchedulerManager().addDelayedTask(new TaskRunnable() {
@Override
public void run() {
controller.stopDigging(blockPosition);
}
}, new UpdateOption(15, TimeUnit.TICK));
}
player.sendMessage("Direction: " + MathUtils.getHorizontalDirection(player.getPosition().getYaw()));
//System.gc();
//player.sendMessage("Garbage collector called");
return true;
}

View File

@ -20,6 +20,7 @@ import net.minestom.server.network.packet.PacketWriter;
import net.minestom.server.network.packet.server.play.*;
import net.minestom.server.utils.Vector;
import net.minestom.server.utils.*;
import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.utils.player.PlayerUtils;
import net.minestom.server.utils.time.TimeUnit;
import net.minestom.server.utils.validate.Check;

View File

@ -8,9 +8,9 @@ import net.minestom.server.item.ItemStack;
import net.minestom.server.network.packet.server.play.*;
import net.minestom.server.network.player.PlayerConnection;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.ChunkUtils;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.Vector;
import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.utils.item.ItemStackUtils;
import net.minestom.server.utils.time.TimeUnit;

View File

@ -35,7 +35,11 @@ import net.minestom.server.scoreboard.Team;
import net.minestom.server.sound.Sound;
import net.minestom.server.sound.SoundCategory;
import net.minestom.server.stat.PlayerStatistic;
import net.minestom.server.utils.*;
import net.minestom.server.utils.ArrayUtils;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.MathUtils;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.utils.validate.Check;
import net.minestom.server.world.Dimension;
import net.minestom.server.world.LevelType;
@ -139,6 +143,8 @@ public class Player extends LivingEntity {
refreshHealth();
refreshAbilities();
sendUpdateHealthPacket();
this.settings = new PlayerSettings();
this.inventory = new PlayerInventory(this);
@ -235,6 +241,10 @@ public class Player extends LivingEntity {
// Recipes end
}
/**
* Used to initialize the player connection
* mostly used by {@link net.minestom.server.entity.fakeplayer.FakePlayer}
*/
protected void playerConnectionInit() {
}

View File

@ -1,6 +1,7 @@
package net.minestom.server.entity.fakeplayer;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Player;
import net.minestom.server.inventory.Inventory;
import net.minestom.server.inventory.InventoryModifier;
import net.minestom.server.inventory.PlayerInventory;
@ -10,6 +11,7 @@ import net.minestom.server.network.packet.client.play.*;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.play.KeepAlivePacket;
import net.minestom.server.network.packet.server.play.PlayerPositionAndLookPacket;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.inventory.PlayerInventoryUtils;
/**
@ -68,6 +70,10 @@ public class FakePlayerController {
addToQueue(pluginMessagePacket);
}
public void sendPluginMessage(String channel, String message) {
sendPluginMessage(channel, message.getBytes());
}
public void attackEntity(Entity entity) {
ClientInteractEntityPacket interactEntityPacket = new ClientInteractEntityPacket();
interactEntityPacket.targetId = entity.getEntityId();
@ -75,6 +81,54 @@ public class FakePlayerController {
addToQueue(interactEntityPacket);
}
public void respawn() {
ClientStatusPacket statusPacket = new ClientStatusPacket();
statusPacket.action = ClientStatusPacket.Action.PERFORM_RESPAWN;
addToQueue(statusPacket);
}
public void setHeldItem(short slot) {
ClientHeldItemChangePacket heldItemChangePacket = new ClientHeldItemChangePacket();
heldItemChangePacket.slot = slot;
addToQueue(heldItemChangePacket);
}
public void sendArmAnimation(Player.Hand hand) {
ClientAnimationPacket animationPacket = new ClientAnimationPacket();
animationPacket.hand = hand;
addToQueue(animationPacket);
}
public void useItem(Player.Hand hand) {
ClientUseItemPacket useItemPacket = new ClientUseItemPacket();
useItemPacket.hand = hand;
addToQueue(useItemPacket);
}
public void rotate(float yaw, float pitch) {
ClientPlayerRotationPacket playerRotationPacket = new ClientPlayerRotationPacket();
playerRotationPacket.yaw = yaw;
playerRotationPacket.pitch = pitch;
playerRotationPacket.onGround = fakePlayer.isOnGround();
addToQueue(playerRotationPacket);
}
public void startDigging(BlockPosition blockPosition) {
ClientPlayerDiggingPacket playerDiggingPacket = new ClientPlayerDiggingPacket();
playerDiggingPacket.status = ClientPlayerDiggingPacket.Status.STARTED_DIGGING;
playerDiggingPacket.blockPosition = blockPosition;
playerDiggingPacket.blockFace = ClientPlayerDiggingPacket.BlockFace.BOTTOM; // TODO not hardcode
addToQueue(playerDiggingPacket);
}
public void stopDigging(BlockPosition blockPosition) {
ClientPlayerDiggingPacket playerDiggingPacket = new ClientPlayerDiggingPacket();
playerDiggingPacket.status = ClientPlayerDiggingPacket.Status.CANCELLED_DIGGING;
playerDiggingPacket.blockPosition = blockPosition;
playerDiggingPacket.blockFace = ClientPlayerDiggingPacket.BlockFace.BOTTOM; // TODO not hardcode
addToQueue(playerDiggingPacket);
}
/**
* Make the player receives a packet
* WARNING: pretty much unsafe, used internally to redirect packets here,

View File

@ -20,8 +20,8 @@ import net.minestom.server.network.packet.server.play.BlockActionPacket;
import net.minestom.server.network.packet.server.play.ChunkDataPacket;
import net.minestom.server.storage.StorageFolder;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.ChunkUtils;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.utils.player.PlayerUtils;
import net.minestom.server.utils.time.TimeUnit;
import net.minestom.server.world.Dimension;

View File

@ -19,9 +19,9 @@ import net.minestom.server.particle.ParticleCreator;
import net.minestom.server.storage.StorageFolder;
import net.minestom.server.timer.TaskRunnable;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.ChunkUtils;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.SerializerUtils;
import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.utils.player.PlayerUtils;
import net.minestom.server.utils.time.TimeUnit;
import net.minestom.server.utils.time.UpdateOption;
@ -293,7 +293,8 @@ public class InstanceContainer extends Instance {
@Override
public Chunk getChunk(int chunkX, int chunkZ) {
return chunks.get(ChunkUtils.getChunkIndex(chunkX, chunkZ));
Chunk chunk = chunks.get(ChunkUtils.getChunkIndex(chunkX, chunkZ));
return ChunkUtils.isChunkUnloaded(this, chunk) ? null : chunk;
}
@Override

View File

@ -21,7 +21,7 @@ import net.minestom.server.item.StackingRule;
import net.minestom.server.network.packet.client.play.ClientPlayerBlockPlacementPacket;
import net.minestom.server.network.packet.client.play.ClientPlayerDiggingPacket;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.ChunkUtils;
import net.minestom.server.utils.chunk.ChunkUtils;
import java.util.Set;

View File

@ -26,15 +26,16 @@ public class PlayerDiggingListener {
PlayerInventory playerInventory = player.getInventory();
ItemStack mainHand = playerInventory.getItemInMainHand();
ItemStack offHand = playerInventory.getItemInOffHand();
Instance instance = player.getInstance();
switch (status) {
case STARTED_DIGGING:
if (player.getGameMode() == GameMode.CREATIVE) {
Instance instance = player.getInstance();
if (instance != null) {
instance.breakBlock(player, blockPosition);
}
} else if (player.getGameMode() == GameMode.SURVIVAL) {
Instance instance = player.getInstance();
if (instance != null) {
CustomBlock customBlock = instance.getCustomBlock(blockPosition.getX(), blockPosition.getY(), blockPosition.getZ());
if (customBlock != null) {
@ -58,6 +59,9 @@ public class PlayerDiggingListener {
removeEffect(player);
}
instance.breakBlock(player, blockPosition);
sendAcknowledgePacket(player, blockPosition, customBlock.getBlockId(),
ClientPlayerDiggingPacket.Status.FINISHED_DIGGING, true);
} else {
player.resetTargetBlock();
removeEffect(player);
@ -73,16 +77,23 @@ public class PlayerDiggingListener {
case CANCELLED_DIGGING:
player.resetTargetBlock();
removeEffect(player);
final short blockId = instance.getBlockId(blockPosition);
sendAcknowledgePacket(player, blockPosition, blockId,
ClientPlayerDiggingPacket.Status.CANCELLED_DIGGING, true);
break;
case FINISHED_DIGGING:
if (player.getCustomBlockTarget() != null) {
player.resetTargetBlock();
removeEffect(player);
} else {
Instance instance = player.getInstance();
final short id = instance.getBlockId(blockPosition);
if (instance != null) {
instance.breakBlock(player, blockPosition);
}
sendAcknowledgePacket(player, blockPosition, id,
ClientPlayerDiggingPacket.Status.FINISHED_DIGGING, true);
}
break;
case DROP_ITEM_STACK:

View File

@ -2,12 +2,12 @@ package net.minestom.server.listener;
import net.minestom.server.entity.Player;
import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.network.packet.client.play.ClientPlayerLookPacket;
import net.minestom.server.network.packet.client.play.ClientPlayerPacket;
import net.minestom.server.network.packet.client.play.ClientPlayerPositionAndLookPacket;
import net.minestom.server.network.packet.client.play.ClientPlayerPositionAndRotationPacket;
import net.minestom.server.network.packet.client.play.ClientPlayerPositionPacket;
import net.minestom.server.utils.ChunkUtils;
import net.minestom.server.network.packet.client.play.ClientPlayerRotationPacket;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.chunk.ChunkUtils;
import java.util.function.Consumer;
@ -17,7 +17,7 @@ public class PlayerPositionListener {
player.refreshOnGround(packet.onGround);
}
public static void playerLookListener(ClientPlayerLookPacket packet, Player player) {
public static void playerLookListener(ClientPlayerRotationPacket packet, Player player) {
Position playerPosition = player.getPosition();
float x = playerPosition.getX();
float y = playerPosition.getY();
@ -45,7 +45,7 @@ public class PlayerPositionListener {
});
}
public static void playerPositionAndLookListener(ClientPlayerPositionAndLookPacket packet, Player player) {
public static void playerPositionAndLookListener(ClientPlayerPositionAndRotationPacket packet, Player player) {
float x = (float) packet.x;
float y = (float) packet.y;
float z = (float) packet.z;

View File

@ -28,9 +28,9 @@ public class PacketListenerManager {
addListener(ClientVehicleMovePacket.class, PlayerVehicleListener::vehicleMoveListener);
addListener(ClientSteerBoatPacket.class, PlayerVehicleListener::boatSteerListener);
addListener(ClientPlayerPacket.class, PlayerPositionListener::playerPacketListener);
addListener(ClientPlayerLookPacket.class, PlayerPositionListener::playerLookListener);
addListener(ClientPlayerRotationPacket.class, PlayerPositionListener::playerLookListener);
addListener(ClientPlayerPositionPacket.class, PlayerPositionListener::playerPositionListener);
addListener(ClientPlayerPositionAndLookPacket.class, PlayerPositionListener::playerPositionAndLookListener);
addListener(ClientPlayerPositionAndRotationPacket.class, PlayerPositionListener::playerPositionAndLookListener);
addListener(ClientPlayerDiggingPacket.class, PlayerDiggingListener::playerDiggingListener);
addListener(ClientAnimationPacket.class, AnimationListener::animationListener);
addListener(ClientInteractEntityPacket.class, UseEntityListener::useEntityListener);

View File

@ -20,8 +20,8 @@ public class ClientPlayPacketsHandler extends ClientPacketsHandler {
// 0x10 packet not used server-side
register(0x11, ClientPlayerPositionPacket::new);
register(0x12, ClientPlayerPositionAndLookPacket::new);
register(0x13, ClientPlayerLookPacket::new);
register(0x12, ClientPlayerPositionAndRotationPacket::new);
register(0x13, ClientPlayerRotationPacket::new);
register(0x14, ClientPlayerPacket::new);
register(0x15, ClientVehicleMovePacket::new);
register(0x16, ClientSteerBoatPacket::new);

View File

@ -3,7 +3,7 @@ package net.minestom.server.network.packet.client.play;
import net.minestom.server.network.packet.PacketReader;
import net.minestom.server.network.packet.client.ClientPlayPacket;
public class ClientPlayerPositionAndLookPacket extends ClientPlayPacket {
public class ClientPlayerPositionAndRotationPacket extends ClientPlayPacket {
public double x, y, z;
public float yaw, pitch;

View File

@ -3,7 +3,7 @@ package net.minestom.server.network.packet.client.play;
import net.minestom.server.network.packet.PacketReader;
import net.minestom.server.network.packet.client.ClientPlayPacket;
public class ClientPlayerLookPacket extends ClientPlayPacket {
public class ClientPlayerRotationPacket extends ClientPlayPacket {
public float yaw, pitch;
public boolean onGround;

View File

@ -5,6 +5,7 @@ import net.minestom.server.entity.Entity;
import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block;
import net.minestom.server.utils.chunk.ChunkUtils;
public class EntityUtils {

View File

@ -1,10 +1,21 @@
package net.minestom.server.utils;
package net.minestom.server.utils.chunk;
import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.Instance;
import net.minestom.server.utils.MathUtils;
import net.minestom.server.utils.Position;
public class ChunkUtils {
/**
* @param instance the instance where {@code chunk} is
* @param chunk the chunk to check
* @return true if the chunk is unloaded, false otherwise
*/
public static boolean isChunkUnloaded(Instance instance, Chunk chunk) {
return chunk == null || !chunk.isLoaded();
}
/**
* @param instance the instance to check
* @param x instance X coordinate
@ -16,7 +27,7 @@ public class ChunkUtils {
int chunkZ = getChunkCoordinate((int) z);
Chunk chunk = instance.getChunk(chunkX, chunkZ);
return chunk == null || !chunk.isLoaded();
return isChunkUnloaded(instance, chunk);
}
/**