From 78e37258ed153c6a53ed94dc024ae43262f56dfc Mon Sep 17 00:00:00 2001 From: themode Date: Sun, 21 Feb 2021 17:43:30 +0100 Subject: [PATCH] Improve ArgumentEntity to support entity UUID & pre-check for player name --- .../arguments/minecraft/ArgumentEntity.java | 27 +++++++++-- .../server/utils/entity/EntityFinder.java | 46 ++++++++++++------- 2 files changed, 52 insertions(+), 21 deletions(-) diff --git a/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentEntity.java b/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentEntity.java index fa1945051..ddd38516e 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentEntity.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentEntity.java @@ -1,10 +1,12 @@ package net.minestom.server.command.builder.arguments.minecraft; +import net.minestom.server.MinecraftServer; import net.minestom.server.command.builder.NodeMaker; import net.minestom.server.command.builder.arguments.Argument; import net.minestom.server.command.builder.exception.ArgumentSyntaxException; import net.minestom.server.entity.EntityType; import net.minestom.server.entity.GameMode; +import net.minestom.server.entity.Player; import net.minestom.server.network.packet.server.play.DeclareCommandsPacket; import net.minestom.server.registry.Registries; import net.minestom.server.utils.entity.EntityFinder; @@ -13,6 +15,7 @@ import org.jetbrains.annotations.NotNull; import java.util.Arrays; import java.util.List; +import java.util.UUID; /** * Represents the target selector argument. @@ -88,11 +91,25 @@ public class ArgumentEntity extends Argument { @NotNull public static EntityFinder staticParse(@NotNull String input, boolean onlySingleEntity, boolean onlyPlayers) throws ArgumentSyntaxException { - // Check for raw player name - if (input.length() <= 16 && !input.contains(SELECTOR_PREFIX)) { - return new EntityFinder() - .setTargetSelector(EntityFinder.TargetSelector.ALL_PLAYERS) - .setName(input, EntityFinder.ToggleableType.INCLUDE); + // Check for raw player name or UUID + if (!input.contains(SELECTOR_PREFIX)) { + + // Check if the input is a valid UUID + try { + UUID uuid = UUID.fromString(input); + return new EntityFinder() + .setTargetSelector(EntityFinder.TargetSelector.ALL_ENTITIES) + .setUuid(uuid); + } catch (IllegalArgumentException ignored) { + } + + // Check if the input is a valid player name + final Player player = MinecraftServer.getConnectionManager().getPlayer(input); + if (player != null) { + return new EntityFinder() + .setTargetSelector(EntityFinder.TargetSelector.ALL_PLAYERS) + .setName(input); + } } // The minimum size is always 2 (for the selector variable, ex: @p) 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 92e69d626..e753daa78 100644 --- a/src/main/java/net/minestom/server/utils/entity/EntityFinder.java +++ b/src/main/java/net/minestom/server/utils/entity/EntityFinder.java @@ -1,5 +1,6 @@ package net.minestom.server.utils.entity; +import it.unimi.dsi.fastutil.objects.Object2BooleanMap; import it.unimi.dsi.fastutil.objects.Object2BooleanOpenHashMap; import net.minestom.server.MinecraftServer; import net.minestom.server.command.CommandSender; @@ -38,7 +39,8 @@ public class EntityFinder { // By traits private Integer limit; private final ToggleableMap entityTypes = new ToggleableMap<>(); - private final ToggleableMap names = new ToggleableMap<>(); + private String name; + private UUID uuid; // Players specific private final ToggleableMap gameModes = new ToggleableMap<>(); @@ -79,8 +81,13 @@ public class EntityFinder { return this; } - public EntityFinder setName(@NotNull String name, @NotNull ToggleableType toggleableType) { - this.names.put(name, toggleableType.getValue()); + public EntityFinder setName(@NotNull String name) { + this.name = name; + return this; + } + + public EntityFinder setUuid(@NotNull UUID uuid) { + this.uuid = uuid; return this; } @@ -154,7 +161,6 @@ public class EntityFinder { // GameMode if (!gameModes.isEmpty()) { - final GameMode requirement = gameModes.requirement; result = result.stream().filter(entity -> { if (!(entity instanceof Player)) return false; @@ -176,15 +182,21 @@ public class EntityFinder { } // Name - if (!names.isEmpty()) { - // TODO entity name + if (name != null) { result = result.stream().filter(entity -> { if (!(entity instanceof Player)) return false; - return filterToggleableMap(entity, ((Player) entity).getUsername(), names); + return ((Player) entity).getUsername().equals(name); }).collect(Collectors.toList()); } + // UUID + if (uuid != null) { + result = result.stream() + .filter(entity -> entity.getUuid().equals(uuid)) + .collect(Collectors.toList()); + } + // Sort & limit if (entitySort != EntitySort.ARBITRARY || limit != null) { @@ -298,10 +310,6 @@ public class EntityFinder { } private static class ToggleableMap extends Object2BooleanOpenHashMap { - - @Nullable - private T requirement; - } @NotNull @@ -343,10 +351,16 @@ public class EntityFinder { if (!(entity instanceof Player)) return false; - final T requirement = map.requirement; - // true if the entity type has not been mentioned or if is accepted - return (!map.containsKey(value) && requirement == null) || - Objects.equals(requirement, value) || - map.getBoolean(value); + for (Object2BooleanMap.Entry entry : map.object2BooleanEntrySet()) { + final T key = entry.getKey(); + final boolean include = entry.getBooleanValue(); + + final boolean equals = Objects.equals(value, key); + if (include && !equals || !include && equals) { + return false; + } + } + + return true; } }