From 3fa7a0ba4bbc86dcb800cc81e49bfb2795b54d2a Mon Sep 17 00:00:00 2001 From: TheMode Date: Tue, 23 Nov 2021 20:38:57 +0100 Subject: [PATCH] Deprecate unsafe casting methods Signed-off-by: TheMode --- .../server/command/CommandSender.java | 8 ++++ .../command/builder/condition/Conditions.java | 7 +++- .../server/utils/entity/EntityFinder.java | 34 +++++------------ src/test/java/demo/commands/BookCommand.java | 2 +- .../java/demo/commands/DimensionCommand.java | 2 +- src/test/java/demo/commands/FindCommand.java | 5 ++- .../java/demo/commands/GamemodeCommand.java | 38 +++++++++---------- .../java/demo/commands/LegacyCommand.java | 4 +- .../java/demo/commands/SetBlockCommand.java | 2 +- .../java/demo/commands/SummonCommand.java | 10 ++--- .../java/demo/commands/TeleportCommand.java | 6 +-- src/test/java/demo/commands/TitleCommand.java | 2 +- 12 files changed, 56 insertions(+), 64 deletions(-) diff --git a/src/main/java/net/minestom/server/command/CommandSender.java b/src/main/java/net/minestom/server/command/CommandSender.java index c58387679..a1136daea 100644 --- a/src/main/java/net/minestom/server/command/CommandSender.java +++ b/src/main/java/net/minestom/server/command/CommandSender.java @@ -36,18 +36,24 @@ public interface CommandSender extends PermissionHandler, Audience, TagHandler { /** * Gets if the sender is a {@link Player}. + *

+ * Consider using {@code instanceof} instead. * * @return true if 'this' is a player, false otherwise */ + @Deprecated default boolean isPlayer() { return false; } /** * Gets if the sender is a {@link ConsoleSender}. + *

+ * Consider using {@code instanceof} instead. * * @return true if 'this' is the console, false otherwise */ + @Deprecated default boolean isConsole() { return false; } @@ -59,6 +65,7 @@ public interface CommandSender extends PermissionHandler, Audience, TagHandler { * @throws ClassCastException if 'this' is not a player * @see #isPlayer() */ + @Deprecated default Player asPlayer() { throw new ClassCastException("CommandSender is not a Player"); } @@ -70,6 +77,7 @@ public interface CommandSender extends PermissionHandler, Audience, TagHandler { * @throws ClassCastException if 'this' is not a console sender * @see #isConsole() */ + @Deprecated default ConsoleSender asConsole() { throw new ClassCastException("CommandSender is not the ConsoleSender"); } diff --git a/src/main/java/net/minestom/server/command/builder/condition/Conditions.java b/src/main/java/net/minestom/server/command/builder/condition/Conditions.java index 92b281a47..2d8a9d329 100644 --- a/src/main/java/net/minestom/server/command/builder/condition/Conditions.java +++ b/src/main/java/net/minestom/server/command/builder/condition/Conditions.java @@ -3,20 +3,23 @@ package net.minestom.server.command.builder.condition; import net.kyori.adventure.text.Component; import net.minestom.server.command.CommandSender; +import net.minestom.server.command.ConsoleSender; +import net.minestom.server.entity.Player; /** * Common command conditions */ public class Conditions { public static boolean playerOnly(CommandSender sender, String commandString) { - if (!sender.isPlayer()) { + if (!(sender instanceof Player)) { sender.sendMessage(Component.text("The command is only available for players")); return false; } return true; } + public static boolean consoleOnly(CommandSender sender, String commandString) { - if (!sender.isConsole()) { + if (!(sender instanceof ConsoleSender)) { sender.sendMessage(Component.text("The command is only available form the console")); return false; } diff --git a/src/main/java/net/minestom/server/utils/entity/EntityFinder.java b/src/main/java/net/minestom/server/utils/entity/EntityFinder.java index ba9e928a8..83c7f3b16 100644 --- a/src/main/java/net/minestom/server/utils/entity/EntityFinder.java +++ b/src/main/java/net/minestom/server/utils/entity/EntityFinder.java @@ -242,12 +242,8 @@ public class EntityFinder { } public @NotNull List<@NotNull Entity> find(@NotNull CommandSender sender) { - if (sender.isPlayer()) { - Player player = sender.asPlayer(); - return find(player.getInstance(), player); - } else { - return find(null, null); - } + return sender instanceof Player player ? + find(player.getInstance(), player) : find(null, null); } /** @@ -260,37 +256,27 @@ public class EntityFinder { public @Nullable Player findFirstPlayer(@Nullable Instance instance, @Nullable Entity self) { final List entities = find(instance, self); for (Entity entity : entities) { - if (entity instanceof Player) { - return (Player) entity; + if (entity instanceof Player player) { + return player; } } return null; } public @Nullable Player findFirstPlayer(@NotNull CommandSender sender) { - if (sender.isPlayer()) { - final Player player = sender.asPlayer(); - return findFirstPlayer(player.getInstance(), player); - } else { - return findFirstPlayer(null, null); - } + return sender instanceof Player player ? + findFirstPlayer(player.getInstance(), player) : + findFirstPlayer(null, null); } public @Nullable Entity findFirstEntity(@Nullable Instance instance, @Nullable Entity self) { final List entities = find(instance, self); - for (Entity entity : entities) { - return entity; - } - return null; + return entities.isEmpty() ? null : entities.get(0); } public @Nullable Entity findFirstEntity(@NotNull CommandSender sender) { - if (sender.isPlayer()) { - final Player player = sender.asPlayer(); - return findFirstEntity(player.getInstance(), player); - } else { - return findFirstEntity(null, null); - } + return sender instanceof Player player ? + findFirstEntity(player.getInstance(), player) : findFirstEntity(null, null); } public enum TargetSelector { diff --git a/src/test/java/demo/commands/BookCommand.java b/src/test/java/demo/commands/BookCommand.java index 2f8cdc395..f554e9226 100644 --- a/src/test/java/demo/commands/BookCommand.java +++ b/src/test/java/demo/commands/BookCommand.java @@ -19,7 +19,7 @@ public class BookCommand extends Command { } private void execute(CommandSender sender, CommandContext context) { - Player player = sender.asPlayer(); + Player player = (Player) sender; player.openBook(Book.builder() .author(Component.text(player.getUsername())) diff --git a/src/test/java/demo/commands/DimensionCommand.java b/src/test/java/demo/commands/DimensionCommand.java index 7301fc0df..0bceb441f 100644 --- a/src/test/java/demo/commands/DimensionCommand.java +++ b/src/test/java/demo/commands/DimensionCommand.java @@ -15,7 +15,7 @@ public class DimensionCommand extends Command { setCondition(Conditions::playerOnly); addSyntax((sender, context) -> { - final Player player = sender.asPlayer(); + final Player player = (Player) sender; final Instance instance = player.getInstance(); final var instances = MinecraftServer.getInstanceManager().getInstances().stream().filter(instance1 -> !instance1.equals(instance)).toList(); if (instances.isEmpty()) { diff --git a/src/test/java/demo/commands/FindCommand.java b/src/test/java/demo/commands/FindCommand.java index e89cd5ac2..6837db323 100644 --- a/src/test/java/demo/commands/FindCommand.java +++ b/src/test/java/demo/commands/FindCommand.java @@ -8,7 +8,8 @@ import net.minestom.server.entity.Player; import java.util.Collection; -import static net.minestom.server.command.builder.arguments.ArgumentType.*; +import static net.minestom.server.command.builder.arguments.ArgumentType.Float; +import static net.minestom.server.command.builder.arguments.ArgumentType.Literal; public class FindCommand extends Command { public FindCommand() { @@ -22,7 +23,7 @@ public class FindCommand extends Command { } private void executorEntity(CommandSender sender, CommandContext context) { - Player player = sender.asPlayer(); + Player player = (Player) sender; float range = context.get("range"); Collection entities = player.getInstance().getNearbyEntities(player.getPosition(), range); diff --git a/src/test/java/demo/commands/GamemodeCommand.java b/src/test/java/demo/commands/GamemodeCommand.java index d2b952508..dc385b2be 100644 --- a/src/test/java/demo/commands/GamemodeCommand.java +++ b/src/test/java/demo/commands/GamemodeCommand.java @@ -19,7 +19,7 @@ import java.util.Locale; /** * Command that make a player change gamemode, made in * the style of the vanilla /gamemode command. - * + * * @see https://minecraft.fandom.com/wiki/Commands/gamemode */ public class GamemodeCommand extends Command { @@ -41,42 +41,42 @@ public class GamemodeCommand extends Command { //Upon invalid usage, print the correct usage of the command to the sender setDefaultExecutor((sender, context) -> { String commandName = context.getCommandName(); - + sender.sendMessage(Component.text("Usage: /" + commandName + " [targets]", NamedTextColor.RED), MessageType.SYSTEM); }); //Command Syntax for /gamemode addSyntax((sender, context) -> { //Limit execution to players only - if (!sender.isPlayer()) { + if (!(sender instanceof Player p)) { sender.sendMessage(Component.text("Please run this command in-game.", NamedTextColor.RED)); return; } - + //Check permission, this could be replaced with hasPermission - if (sender.asPlayer().getPermissionLevel() < 2) { + if (p.getPermissionLevel() < 2) { sender.sendMessage(Component.text("You don't have permission to use this command.", NamedTextColor.RED)); return; } - + GameMode mode = context.get(gamemode); - + //Set the gamemode for the sender - executeSelf(sender.asPlayer(), mode); + executeSelf(p, mode); }, gamemode); //Command Syntax for /gamemode [targets] addSyntax((sender, context) -> { //Check permission for players only //This allows the console to use this syntax too - if (sender.isPlayer() && sender.asPlayer().getPermissionLevel() < 2) { + if (sender instanceof Player p && p.getPermissionLevel() < 2) { sender.sendMessage(Component.text("You don't have permission to use this command.", NamedTextColor.RED)); return; } - + EntityFinder finder = context.get(player); GameMode mode = context.get(gamemode); - + //Set the gamemode for the targets executeOthers(sender, mode, finder.find(sender)); }, gamemode, player); @@ -89,22 +89,22 @@ public class GamemodeCommand extends Command { private void executeOthers(CommandSender sender, GameMode mode, List entities) { if (entities.size() == 0) { //If there are no players that could be modified, display an error message - if (sender.isPlayer()) sender.sendMessage(Component.translatable("argument.entity.notfound.player", NamedTextColor.RED), MessageType.SYSTEM); + if (sender instanceof Player) + sender.sendMessage(Component.translatable("argument.entity.notfound.player", NamedTextColor.RED), MessageType.SYSTEM); else sender.sendMessage(Component.text("No player was found", NamedTextColor.RED), MessageType.SYSTEM); } else for (Entity entity : entities) { - if (entity instanceof Player) { - Player p = (Player) entity; + if (entity instanceof Player p) { if (p == sender) { //If the player is the same as the sender, call //executeSelf to display one message instead of two - executeSelf(sender.asPlayer(), mode); + executeSelf((Player) sender, mode); } else { p.setGameMode(mode); - + String gamemodeString = "gameMode." + mode.name().toLowerCase(Locale.ROOT); Component gamemodeComponent = Component.translatable(gamemodeString); Component playerName = p.getDisplayName() == null ? p.getName() : p.getDisplayName(); - + //Send a message to the changed player and the sender p.sendMessage(Component.translatable("gameMode.changed", gamemodeComponent), MessageType.SYSTEM); sender.sendMessage(Component.translatable("commands.gamemode.success.other", playerName, gamemodeComponent), MessageType.SYSTEM); @@ -119,12 +119,12 @@ public class GamemodeCommand extends Command { */ private void executeSelf(Player sender, GameMode mode) { sender.setGameMode(mode); - + //The translation keys 'gameMode.survival', 'gameMode.creative', etc. //correspond to the translated game mode names. String gamemodeString = "gameMode." + mode.name().toLowerCase(Locale.ROOT); Component gamemodeComponent = Component.translatable(gamemodeString); - + //Send the translated message to the player. sender.sendMessage(Component.translatable("commands.gamemode.success.self", gamemodeComponent), MessageType.SYSTEM); } diff --git a/src/test/java/demo/commands/LegacyCommand.java b/src/test/java/demo/commands/LegacyCommand.java index 480a43905..b086562b5 100644 --- a/src/test/java/demo/commands/LegacyCommand.java +++ b/src/test/java/demo/commands/LegacyCommand.java @@ -1,6 +1,7 @@ package demo.commands; import net.minestom.server.command.CommandSender; +import net.minestom.server.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -11,8 +12,7 @@ public class LegacyCommand extends net.minestom.server.command.builder.SimpleCom @Override public boolean process(@NotNull CommandSender sender, @NotNull String command, @NotNull String[] args) { - if (!sender.isPlayer()) - return false; + if (!(sender instanceof Player)) return false; System.gc(); sender.sendMessage("Explicit GC"); diff --git a/src/test/java/demo/commands/SetBlockCommand.java b/src/test/java/demo/commands/SetBlockCommand.java index c1b8e226f..43aac1878 100644 --- a/src/test/java/demo/commands/SetBlockCommand.java +++ b/src/test/java/demo/commands/SetBlockCommand.java @@ -16,7 +16,7 @@ public class SetBlockCommand extends Command { final ArgumentBlockState block = BlockState("block"); addSyntax((sender, context) -> { - final Player player = sender.asPlayer(); + final Player player = (Player) sender; player.getInstance().setBlock(context.get(position).from(player), context.get(block)); }, position, block); } diff --git a/src/test/java/demo/commands/SummonCommand.java b/src/test/java/demo/commands/SummonCommand.java index 2ef48afa7..abd1b7c07 100644 --- a/src/test/java/demo/commands/SummonCommand.java +++ b/src/test/java/demo/commands/SummonCommand.java @@ -7,13 +7,9 @@ import net.minestom.server.command.builder.arguments.Argument; import net.minestom.server.command.builder.arguments.ArgumentEnum; import net.minestom.server.command.builder.arguments.ArgumentType; import net.minestom.server.command.builder.arguments.minecraft.registry.ArgumentEntityType; -import net.minestom.server.command.builder.arguments.relative.ArgumentRelativeVec3; import net.minestom.server.command.builder.condition.Conditions; import net.minestom.server.coordinate.Vec; -import net.minestom.server.entity.Entity; -import net.minestom.server.entity.EntityCreature; -import net.minestom.server.entity.EntityType; -import net.minestom.server.entity.LivingEntity; +import net.minestom.server.entity.*; import net.minestom.server.utils.location.RelativeVec; import org.jetbrains.annotations.NotNull; @@ -35,7 +31,7 @@ public class SummonCommand extends Command { )); entityClass = ArgumentType.Enum("class", EntityClass.class) .setFormat(ArgumentEnum.Format.LOWER_CASED) - .setDefaultValue(EntityClass.CREATURE);; + .setDefaultValue(EntityClass.CREATURE); addSyntax(this::execute, entity, pos, entityClass); setDefaultExecutor((sender, context) -> sender.sendMessage("Usage: /summon ")); } @@ -43,7 +39,7 @@ public class SummonCommand extends Command { private void execute(@NotNull CommandSender commandSender, @NotNull CommandContext commandContext) { final Entity entity = commandContext.get(entityClass).instantiate(commandContext.get(this.entity)); //noinspection ConstantConditions - One couldn't possibly execute a command without being in an instance - entity.setInstance(commandSender.asPlayer().getInstance(), commandContext.get(pos).fromSender(commandSender)); + entity.setInstance(((Player) commandSender).getInstance(), commandContext.get(pos).fromSender(commandSender)); } @SuppressWarnings("unused") diff --git a/src/test/java/demo/commands/TeleportCommand.java b/src/test/java/demo/commands/TeleportCommand.java index 49c9572aa..ff1b3ca83 100644 --- a/src/test/java/demo/commands/TeleportCommand.java +++ b/src/test/java/demo/commands/TeleportCommand.java @@ -7,7 +7,6 @@ import net.minestom.server.command.builder.Command; import net.minestom.server.command.builder.CommandContext; import net.minestom.server.command.builder.arguments.ArgumentType; import net.minestom.server.coordinate.Pos; -import net.minestom.server.coordinate.Vec; import net.minestom.server.entity.Player; import net.minestom.server.utils.location.RelativeVec; @@ -28,15 +27,14 @@ public class TeleportCommand extends Command { private void onPlayerTeleport(CommandSender sender, CommandContext context) { final String playerName = context.get("player"); Player pl = MinecraftServer.getConnectionManager().getPlayer(playerName); - if (pl != null && sender.isPlayer()) { - Player player = (Player) sender; + if (sender instanceof Player player) { player.teleport(pl.getPosition()); } sender.sendMessage(Component.text("Teleported to player " + playerName)); } private void onPositionTeleport(CommandSender sender, CommandContext context) { - final Player player = sender.asPlayer(); + final Player player = (Player) sender; final RelativeVec relativeVec = context.get("pos"); final Pos position = player.getPosition().withCoord(relativeVec.from(player)); diff --git a/src/test/java/demo/commands/TitleCommand.java b/src/test/java/demo/commands/TitleCommand.java index cda7bc3dc..b50002e70 100644 --- a/src/test/java/demo/commands/TitleCommand.java +++ b/src/test/java/demo/commands/TitleCommand.java @@ -21,7 +21,7 @@ public class TitleCommand extends Command { } private void handleTitle(CommandSender source, CommandContext context) { - Player player = source.asPlayer(); + Player player = (Player) source; String titleContent = context.get("content"); player.showTitle(Title.title(Component.text(titleContent), Component.empty(), Title.DEFAULT_TIMES));