diff --git a/build.gradle b/build.gradle index 21c034e18..dbdf8df28 100644 --- a/build.gradle +++ b/build.gradle @@ -47,5 +47,8 @@ dependencies { api 'net.kyori:text-serializer-legacy:3.0.3' api 'net.kyori:text-serializer-gson:3.0.3' api 'net.kyori:text-serializer-plain:3.0.3' + + // Pathfinding + implementation 'com.github.MadMartian:hydrazine-path-finding:1.02' } diff --git a/src/main/java/fr/themode/demo/commands/DimensionCommand.java b/src/main/java/fr/themode/demo/commands/DimensionCommand.java index 2cd0e973b..7eca98c89 100644 --- a/src/main/java/fr/themode/demo/commands/DimensionCommand.java +++ b/src/main/java/fr/themode/demo/commands/DimensionCommand.java @@ -2,6 +2,7 @@ package fr.themode.demo.commands; import net.minestom.server.MinecraftServer; import net.minestom.server.command.CommandProcessor; +import net.minestom.server.command.CommandSender; import net.minestom.server.entity.Player; import net.minestom.server.instance.Instance; import net.minestom.server.world.Dimension; @@ -20,22 +21,27 @@ public class DimensionCommand implements CommandProcessor { } @Override - public boolean process(Player player, String command, String[] args) { + public boolean process(CommandSender sender, String command, String[] args) { + + if (!(sender instanceof Player)) + return false; + Player player = (Player) sender; + Instance instance = player.getInstance(); Dimension targetDimension = Dimension.NETHER; - if(instance.getDimension() == Dimension.NETHER) { + if (instance.getDimension() == Dimension.NETHER) { targetDimension = Dimension.OVERWORLD; } Dimension finalTargetDimension = targetDimension; Optional targetInstance = MinecraftServer.getInstanceManager().getInstances().stream().filter(in -> in.getDimension() == finalTargetDimension).findFirst(); - if(targetInstance.isPresent()) { - player.sendMessage("You were in "+instance.getDimension()); + if (targetInstance.isPresent()) { + player.sendMessage("You were in " + instance.getDimension()); player.setInstance(targetInstance.get()); - player.sendMessage("You are now in "+targetDimension); + player.sendMessage("You are now in " + targetDimension); } else { - player.sendMessage("Could not find instance with dimension "+targetDimension); + player.sendMessage("Could not find instance with dimension " + targetDimension); } return true; diff --git a/src/main/java/fr/themode/demo/commands/GamemodeCommand.java b/src/main/java/fr/themode/demo/commands/GamemodeCommand.java index d90eb186f..77d8f4df4 100644 --- a/src/main/java/fr/themode/demo/commands/GamemodeCommand.java +++ b/src/main/java/fr/themode/demo/commands/GamemodeCommand.java @@ -4,6 +4,7 @@ import fr.themode.command.Arguments; import fr.themode.command.Command; import fr.themode.command.arguments.Argument; import fr.themode.command.arguments.ArgumentType; +import net.minestom.server.command.CommandSender; import net.minestom.server.entity.GameMode; import net.minestom.server.entity.Player; @@ -12,7 +13,7 @@ import java.util.Optional; /** * Command that make a player change gamemode */ -public class GamemodeCommand extends Command { +public class GamemodeCommand extends Command { public GamemodeCommand() { super("gamemode", "g", "gm"); @@ -35,11 +36,13 @@ public class GamemodeCommand extends Command { addSyntax(this::executeOnOther, player, mode); } - private void usage(Player player, Arguments arguments) { - player.sendMessage("Usage: /gamemode [player] "); + private void usage(CommandSender sender, Arguments arguments) { + sender.sendMessage("Usage: /gamemode [player] "); } - private void executeOnSelf(Player player, Arguments arguments) { + private void executeOnSelf(CommandSender sender, Arguments arguments) { + Player player = (Player) sender; + String gamemodeName = arguments.getWord("mode"); GameMode mode = GameMode.valueOf(gamemodeName.toUpperCase()); assert mode != null; // mode is not supposed to be null, because gamemodeName will be valid @@ -47,7 +50,9 @@ public class GamemodeCommand extends Command { player.sendMessage("You are now playing in " + gamemodeName); } - private void executeOnOther(Player player, Arguments arguments) { + private void executeOnOther(CommandSender sender, Arguments arguments) { + Player player = (Player) sender; + String gamemodeName = arguments.getWord("mode"); String targetName = arguments.getWord("player"); GameMode mode = GameMode.valueOf(gamemodeName.toUpperCase()); @@ -61,11 +66,15 @@ public class GamemodeCommand extends Command { } } - private void gameModeCallback(Player player, String gamemode, int error) { - player.sendMessage("'" + gamemode + "' is not a valid gamemode!"); + private void gameModeCallback(CommandSender sender, String gamemode, int error) { + sender.sendMessage("'" + gamemode + "' is not a valid gamemode!"); } - private boolean isAllowed(Player player) { - return true; // TODO: permissions + private boolean isAllowed(CommandSender sender) { + if (!(sender instanceof Player)) { + sender.sendMessage("The command is only available for player"); + return false; + } + return true; } } diff --git a/src/main/java/fr/themode/demo/commands/HealthCommand.java b/src/main/java/fr/themode/demo/commands/HealthCommand.java index be97c41a3..52dc7a26a 100644 --- a/src/main/java/fr/themode/demo/commands/HealthCommand.java +++ b/src/main/java/fr/themode/demo/commands/HealthCommand.java @@ -5,9 +5,10 @@ import fr.themode.command.Command; import fr.themode.command.arguments.Argument; import fr.themode.command.arguments.ArgumentType; import fr.themode.command.arguments.number.ArgumentNumber; +import net.minestom.server.command.CommandSender; import net.minestom.server.entity.Player; -public class HealthCommand extends Command { +public class HealthCommand extends Command { public HealthCommand() { super("health", "h", "healthbar"); @@ -27,39 +28,39 @@ public class HealthCommand extends Command { addSyntax(this::execute2, arg0, arg1); } - private boolean condition(Player player) { - boolean hasPerm = true; - if (!hasPerm) { - player.sendMessage("You do not have permission !"); + private boolean condition(CommandSender sender) { + if (!(sender instanceof Player)) { + sender.sendMessage("The command is only available for player"); return false; } return true; } - private void defaultExecutor(Player player, Arguments args) { - player.sendMessage("Correct usage: health [set/add] [number]"); + private void defaultExecutor(CommandSender sender, Arguments args) { + sender.sendMessage("Correct usage: health [set/add] [number]"); } - private void modeCallback(Player player, String value, int error) { - player.sendMessage("SYNTAX ERROR: '" + value + "' should be replaced by 'set' or 'add'"); + private void modeCallback(CommandSender sender, String value, int error) { + sender.sendMessage("SYNTAX ERROR: '" + value + "' should be replaced by 'set' or 'add'"); } - private void valueCallback(Player player, String value, int error) { + private void valueCallback(CommandSender sender, String value, int error) { switch (error) { case ArgumentNumber.NOT_NUMBER_ERROR: - player.sendMessage("SYNTAX ERROR: '" + value + "' isn't a number!"); + sender.sendMessage("SYNTAX ERROR: '" + value + "' isn't a number!"); break; case ArgumentNumber.RANGE_ERROR: - player.sendMessage("SYNTAX ERROR: " + value + " is not between 0 and 100"); + sender.sendMessage("SYNTAX ERROR: " + value + " is not between 0 and 100"); break; } } - private void execute(Player player, Arguments args) { - player.sendMessage("/health " + args.getWord("mode") + " [Integer]"); + private void execute(CommandSender sender, Arguments args) { + sender.sendMessage("/health " + args.getWord("mode") + " [Integer]"); } - private void execute2(Player player, Arguments args) { + private void execute2(CommandSender sender, Arguments args) { + Player player = (Player) sender; String mode = args.getWord("mode"); int value = args.getInteger("value"); diff --git a/src/main/java/fr/themode/demo/commands/SimpleCommand.java b/src/main/java/fr/themode/demo/commands/SimpleCommand.java index 4ff31d581..a262b866f 100644 --- a/src/main/java/fr/themode/demo/commands/SimpleCommand.java +++ b/src/main/java/fr/themode/demo/commands/SimpleCommand.java @@ -1,7 +1,17 @@ package fr.themode.demo.commands; +import com.extollit.gaming.ai.path.HydrazinePathFinder; +import com.extollit.gaming.ai.path.model.PathObject; +import com.extollit.linalg.immutable.Vec3i; +import fr.themode.demo.entity.ChickenCreature; import net.minestom.server.command.CommandProcessor; +import net.minestom.server.command.CommandSender; import net.minestom.server.entity.Player; +import net.minestom.server.entity.pathfinding.hydrazine.PFInstanceSpace; +import net.minestom.server.entity.pathfinding.hydrazine.PFPathingEntity; +import net.minestom.server.instance.Instance; + +import java.util.Iterator; public class SimpleCommand implements CommandProcessor { @Override @@ -15,7 +25,11 @@ public class SimpleCommand implements CommandProcessor { } @Override - public boolean process(Player player, String command, String[] args) { + public boolean process(CommandSender sender, String command, String[] args) { + + if (!(sender instanceof Player)) + return false; + Player player = (Player) sender; /*for (Player p : MinecraftServer.getConnectionManager().getOnlinePlayers()) { if (!(p instanceof FakePlayer)) @@ -35,8 +49,32 @@ public class SimpleCommand implements CommandProcessor { break; }*/ + /*for (EntityCreature entityCreature : player.getInstance().getCreatures()) { + entityCreature.setPathTo(player.getPosition().clone()); + //entityCreature.jump(1); + } + System.gc(); - player.sendMessage("Garbage collector called"); + player.sendMessage("Garbage collector called");*/ + + Instance instance = player.getInstance(); + + ChickenCreature chickenCreature = new ChickenCreature(player.getPosition()); + chickenCreature.setInstance(instance); + + PFPathingEntity pathingEntity = new PFPathingEntity(chickenCreature); + PFInstanceSpace instanceSpace = new PFInstanceSpace(instance); + + final HydrazinePathFinder pathFinder = new HydrazinePathFinder(pathingEntity, instanceSpace); + + final PathObject path = pathFinder.initiatePathTo(-10, 42, -10); + + for (Iterator it = path.iterator(); it.hasNext(); ) { + Vec3i ite = it.next(); + + System.out.println("test: " + ite); + + } return true; } diff --git a/src/main/java/net/minestom/server/command/CommandManager.java b/src/main/java/net/minestom/server/command/CommandManager.java index 420d161a7..f74b5ea9f 100644 --- a/src/main/java/net/minestom/server/command/CommandManager.java +++ b/src/main/java/net/minestom/server/command/CommandManager.java @@ -9,19 +9,33 @@ import net.minestom.server.network.packet.server.play.DeclareCommandsPacket; import net.minestom.server.utils.ArrayUtils; import net.minestom.server.utils.validate.Check; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; public class CommandManager { private String commandPrefix = "/"; - private CommandDispatcher dispatcher = new CommandDispatcher<>(); + private ConsoleSender consoleSender = new ConsoleSender(); + + private CommandDispatcher dispatcher = new CommandDispatcher<>(); private Map commandProcessorMap = new HashMap<>(); - public void register(Command command) { + public CommandManager() { + // Setup console thread + new Thread(() -> { + Scanner scanner = new Scanner(System.in); + while (true) { + String command = scanner.nextLine(); + if (!command.startsWith(commandPrefix)) + continue; + command = command.replaceFirst(commandPrefix, ""); + execute(consoleSender, command); + + } + }, "ConsoleCommand-Thread").start(); + } + + public void register(Command command) { this.dispatcher.register(command); } @@ -29,20 +43,24 @@ public class CommandManager { this.commandProcessorMap.put(commandProcessor.getCommandName().toLowerCase(), commandProcessor); } - public boolean execute(Player source, String command) { - Check.notNull(source, "Source cannot be null"); + public boolean execute(CommandSender sender, String command) { + Check.notNull(sender, "Source cannot be null"); Check.notNull(command, "Command string cannot be null"); - PlayerCommandEvent playerCommandEvent = new PlayerCommandEvent(source, command); - source.callEvent(PlayerCommandEvent.class, playerCommandEvent); + if (sender instanceof Player) { + Player player = (Player) sender; - if (playerCommandEvent.isCancelled()) - return false; + PlayerCommandEvent playerCommandEvent = new PlayerCommandEvent(player, command); + player.callEvent(PlayerCommandEvent.class, playerCommandEvent); - command = playerCommandEvent.getCommand(); + if (playerCommandEvent.isCancelled()) + return false; + + command = playerCommandEvent.getCommand(); + } try { - this.dispatcher.execute(source, command); + this.dispatcher.execute(sender, command); return true; } catch (NullPointerException e) { String[] splitted = command.split(" "); @@ -53,7 +71,7 @@ public class CommandManager { String[] args = command.substring(command.indexOf(" ") + 1).split(" "); - return commandProcessor.process(source, commandName, args); + return commandProcessor.process(sender, commandName, args); } } @@ -66,6 +84,10 @@ public class CommandManager { this.commandPrefix = commandPrefix; } + public ConsoleSender getConsoleSender() { + return consoleSender; + } + public DeclareCommandsPacket createDeclareCommandsPacket(Player player) { return buildPacket(player); } @@ -74,7 +96,7 @@ public class CommandManager { DeclareCommandsPacket declareCommandsPacket = new DeclareCommandsPacket(); List commands = new ArrayList<>(); - for (Command command : dispatcher.getCommands()) { + for (Command command : dispatcher.getCommands()) { CommandCondition commandCondition = command.getCondition(); if (commandCondition != null) { // Do not show command if return false diff --git a/src/main/java/net/minestom/server/command/CommandProcessor.java b/src/main/java/net/minestom/server/command/CommandProcessor.java index 8c500313d..a899bab0c 100644 --- a/src/main/java/net/minestom/server/command/CommandProcessor.java +++ b/src/main/java/net/minestom/server/command/CommandProcessor.java @@ -8,7 +8,7 @@ public interface CommandProcessor { String[] getAliases(); - boolean process(Player player, String command, String[] args); + boolean process(CommandSender sender, String command, String[] args); boolean hasAccess(Player player); } diff --git a/src/main/java/net/minestom/server/command/CommandSender.java b/src/main/java/net/minestom/server/command/CommandSender.java new file mode 100644 index 000000000..50f485262 --- /dev/null +++ b/src/main/java/net/minestom/server/command/CommandSender.java @@ -0,0 +1,13 @@ +package net.minestom.server.command; + +public interface CommandSender { + + void sendMessage(String message); + + default void sendMessage(String[] messages) { + for (String message : messages) { + sendMessage(message); + } + } + +} diff --git a/src/main/java/net/minestom/server/command/ConsoleSender.java b/src/main/java/net/minestom/server/command/ConsoleSender.java new file mode 100644 index 000000000..8d92332f6 --- /dev/null +++ b/src/main/java/net/minestom/server/command/ConsoleSender.java @@ -0,0 +1,8 @@ +package net.minestom.server.command; + +public class ConsoleSender implements CommandSender { + @Override + public void sendMessage(String message) { + System.out.println(message); + } +} diff --git a/src/main/java/net/minestom/server/entity/Player.java b/src/main/java/net/minestom/server/entity/Player.java index b806a2f43..e2ec8adb9 100644 --- a/src/main/java/net/minestom/server/entity/Player.java +++ b/src/main/java/net/minestom/server/entity/Player.java @@ -8,6 +8,7 @@ import net.minestom.server.bossbar.BossBar; import net.minestom.server.chat.Chat; import net.minestom.server.collision.BoundingBox; import net.minestom.server.command.CommandManager; +import net.minestom.server.command.CommandSender; import net.minestom.server.effects.Effects; import net.minestom.server.entity.damage.DamageType; import net.minestom.server.entity.vehicle.PlayerVehicleInformation; @@ -52,7 +53,7 @@ import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; -public class Player extends LivingEntity { +public class Player extends LivingEntity implements CommandSender { private long lastKeepAlive; private boolean answerKeepAlive; @@ -596,6 +597,7 @@ public class Player extends LivingEntity { } // Use legacy color formatting + @Override public void sendMessage(String message) { sendMessage(Chat.fromLegacyText(message)); }