EntitySelector.java

net.minecraft.commands.arguments.selector.EntitySelector

信息

  • 全限定名:net.minecraft.commands.arguments.selector.EntitySelector
  • 类型:public class
  • 包:net.minecraft.commands.arguments.selector
  • 源码路径:src/main/java/net/minecraft/commands/arguments/selector/EntitySelector.java
  • 起始行号:L30
  • 职责:

    TODO

字段/常量

  • INFINITE

    • 类型: int
    • 修饰符: public static final
    • 源码定位: L31
    • 说明:

      TODO

  • ORDER_ARBITRARY

    • 类型: BiConsumer<Vec3,List<?extends Entity>>
    • 修饰符: public static final
    • 源码定位: L32
    • 说明:

      TODO

  • ANY_TYPE

    • 类型: EntityTypeTest<Entity,?>
    • 修饰符: private static final public public
    • 源码定位: L33
    • 说明:

      TODO

  • COMPILABLE_CODEC

    • 类型: Codec<CompilableString<EntitySelector>>
    • 修饰符: public static final protected protected
    • 源码定位: L43
    • 说明:

      TODO

  • maxResults

    • 类型: int
    • 修饰符: private final
    • 源码定位: L55
    • 说明:

      TODO

  • includesEntities

    • 类型: boolean
    • 修饰符: private final
    • 源码定位: L56
    • 说明:

      TODO

  • worldLimited

    • 类型: boolean
    • 修饰符: private final
    • 源码定位: L57
    • 说明:

      TODO

  • contextFreePredicates

    • 类型: List<Predicate<Entity>>
    • 修饰符: private final
    • 源码定位: L58
    • 说明:

      TODO

  • range

    • 类型: MinMaxBounds.Doubles
    • 修饰符: private final
    • 源码定位: L59
    • 说明:

      TODO

  • position

    • 类型: Function<Vec3,Vec3>
    • 修饰符: private final
    • 源码定位: L60
    • 说明:

      TODO

  • aabb

    • 类型: AABB
    • 修饰符: private final
    • 源码定位: L61
    • 说明:

      TODO

  • order

    • 类型: BiConsumer<Vec3,List<?extends Entity>>
    • 修饰符: private final
    • 源码定位: L62
    • 说明:

      TODO

  • currentEntity

    • 类型: boolean
    • 修饰符: private final
    • 源码定位: L63
    • 说明:

      TODO

  • playerName

    • 类型: String
    • 修饰符: private final
    • 源码定位: L64
    • 说明:

      TODO

  • entityUUID

    • 类型: UUID
    • 修饰符: private final
    • 源码定位: L65
    • 说明:

      TODO

  • type

    • 类型: EntityTypeTest<Entity,?>
    • 修饰符: private final
    • 源码定位: L66
    • 说明:

      TODO

  • usesSelector

    • 类型: boolean
    • 修饰符: private final
    • 源码定位: L67
    • 说明:

      TODO

内部类/嵌套类型

构造器

public EntitySelector(int maxResults, boolean includesEntities, boolean worldLimited, List<Predicate<Entity>> contextFreePredicates, MinMaxBounds.Doubles range, Function<Vec3,Vec3> position, AABB aabb, BiConsumer<Vec3,List<?extends Entity>> order, boolean currentEntity, String playerName, UUID entityUUID, EntityType<?> type, boolean usesSelector) @ L69

  • 构造器名:EntitySelector
  • 源码定位:L69
  • 修饰符:public

参数:

  • maxResults: int
  • includesEntities: boolean
  • worldLimited: boolean
  • contextFreePredicates: List<Predicate>
  • range: MinMaxBounds.Doubles
  • position: Function<Vec3,Vec3>
  • aabb: AABB
  • order: BiConsumer<Vec3,List<?extends Entity>>
  • currentEntity: boolean
  • playerName: String
  • entityUUID: UUID
  • type: EntityType<?>
  • usesSelector: boolean

说明:

TODO

方法

下面的方法块按源码顺序生成。

public int getMaxResults() @ L99

  • 方法名:getMaxResults
  • 源码定位:L99
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public boolean includesEntities() @ L103

  • 方法名:includesEntities
  • 源码定位:L103
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public boolean isSelfSelector() @ L107

  • 方法名:isSelfSelector
  • 源码定位:L107
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public boolean isWorldLimited() @ L111

  • 方法名:isWorldLimited
  • 源码定位:L111
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public boolean usesSelector() @ L115

  • 方法名:usesSelector
  • 源码定位:L115
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

private void checkPermissions(CommandSourceStack sender) @ L119

  • 方法名:checkPermissions
  • 源码定位:L119
  • 返回类型:void
  • 修饰符:private

参数:

  • sender: CommandSourceStack

说明:

TODO

public Entity findSingleEntity(CommandSourceStack sender) @ L125

  • 方法名:findSingleEntity
  • 源码定位:L125
  • 返回类型:Entity
  • 修饰符:public

参数:

  • sender: CommandSourceStack

说明:

TODO

public List<?extends Entity> findEntities(CommandSourceStack sender) @ L137

  • 方法名:findEntities
  • 源码定位:L137
  • 返回类型:List<?extends Entity>
  • 修饰符:public

参数:

  • sender: CommandSourceStack

说明:

TODO

private void addEntities(List<Entity> result, ServerLevel level, AABB absoluteAABB, Predicate<Entity> predicate) @ L178

  • 方法名:addEntities
  • 源码定位:L178
  • 返回类型:void
  • 修饰符:private

参数:

  • result: List
  • level: ServerLevel
  • absoluteAABB: AABB
  • predicate: Predicate

说明:

TODO

private int getResultLimit() @ L189

  • 方法名:getResultLimit
  • 源码定位:L189
  • 返回类型:int
  • 修饰符:private

参数:

说明:

TODO

public ServerPlayer findSinglePlayer(CommandSourceStack sender) @ L193

  • 方法名:findSinglePlayer
  • 源码定位:L193
  • 返回类型:ServerPlayer
  • 修饰符:public

参数:

  • sender: CommandSourceStack

说明:

TODO

public List<ServerPlayer> findPlayers(CommandSourceStack sender) @ L203

  • 方法名:findPlayers
  • 源码定位:L203
  • 返回类型:List
  • 修饰符:public

参数:

  • sender: CommandSourceStack

说明:

TODO

private AABB getAbsoluteAabb(Vec3 pos) @ L240

  • 方法名:getAbsoluteAabb
  • 源码定位:L240
  • 返回类型:AABB
  • 修饰符:private

参数:

  • pos: Vec3

说明:

TODO

private Predicate<Entity> getPredicate(Vec3 pos, AABB absoluteAabb, FeatureFlagSet enabledFeatures) @ L244

  • 方法名:getPredicate
  • 源码定位:L244
  • 返回类型:Predicate
  • 修饰符:private

参数:

  • pos: Vec3
  • absoluteAabb: AABB
  • enabledFeatures: FeatureFlagSet

说明:

TODO

private <T extends Entity> List<T> sortAndLimit(Vec3 pos, List<T> result) @ L273

  • 方法名:sortAndLimit
  • 源码定位:L273
  • 返回类型: List
  • 修饰符:private

参数:

  • pos: Vec3
  • result: List

说明:

TODO

public static Component joinNames(List<?extends Entity> entities) @ L281

  • 方法名:joinNames
  • 源码定位:L281
  • 返回类型:Component
  • 修饰符:public static

参数:

  • entities: List<?extends Entity>

说明:

TODO

代码

public class EntitySelector {
    public static final int INFINITE = Integer.MAX_VALUE;
    public static final BiConsumer<Vec3, List<? extends Entity>> ORDER_ARBITRARY = (p, c) -> {};
    private static final EntityTypeTest<Entity, ?> ANY_TYPE = new EntityTypeTest<Entity, Entity>() {
        public Entity tryCast(Entity entity) {
            return entity;
        }
 
        @Override
        public Class<? extends Entity> getBaseClass() {
            return Entity.class;
        }
    };
    public static final Codec<CompilableString<EntitySelector>> COMPILABLE_CODEC = CompilableString.codec(
        new CompilableString.CommandParserHelper<EntitySelector>() {
            protected EntitySelector parse(StringReader reader) throws CommandSyntaxException {
                return new EntitySelectorParser(reader, true).parse();
            }
 
            @Override
            protected String errorMessage(String original, CommandSyntaxException exception) {
                return "Invalid selector component: " + original + ": " + exception.getMessage();
            }
        }
    );
    private final int maxResults;
    private final boolean includesEntities;
    private final boolean worldLimited;
    private final List<Predicate<Entity>> contextFreePredicates;
    private final MinMaxBounds.@Nullable Doubles range;
    private final Function<Vec3, Vec3> position;
    private final @Nullable AABB aabb;
    private final BiConsumer<Vec3, List<? extends Entity>> order;
    private final boolean currentEntity;
    private final @Nullable String playerName;
    private final @Nullable UUID entityUUID;
    private final EntityTypeTest<Entity, ?> type;
    private final boolean usesSelector;
 
    public EntitySelector(
        int maxResults,
        boolean includesEntities,
        boolean worldLimited,
        List<Predicate<Entity>> contextFreePredicates,
        MinMaxBounds.@Nullable Doubles range,
        Function<Vec3, Vec3> position,
        @Nullable AABB aabb,
        BiConsumer<Vec3, List<? extends Entity>> order,
        boolean currentEntity,
        @Nullable String playerName,
        @Nullable UUID entityUUID,
        @Nullable EntityType<?> type,
        boolean usesSelector
    ) {
        this.maxResults = maxResults;
        this.includesEntities = includesEntities;
        this.worldLimited = worldLimited;
        this.contextFreePredicates = contextFreePredicates;
        this.range = range;
        this.position = position;
        this.aabb = aabb;
        this.order = order;
        this.currentEntity = currentEntity;
        this.playerName = playerName;
        this.entityUUID = entityUUID;
        this.type = (EntityTypeTest<Entity, ?>)(type == null ? ANY_TYPE : type);
        this.usesSelector = usesSelector;
    }
 
    public int getMaxResults() {
        return this.maxResults;
    }
 
    public boolean includesEntities() {
        return this.includesEntities;
    }
 
    public boolean isSelfSelector() {
        return this.currentEntity;
    }
 
    public boolean isWorldLimited() {
        return this.worldLimited;
    }
 
    public boolean usesSelector() {
        return this.usesSelector;
    }
 
    private void checkPermissions(CommandSourceStack sender) throws CommandSyntaxException {
        if (this.usesSelector && !sender.permissions().hasPermission(Permissions.COMMANDS_ENTITY_SELECTORS)) {
            throw EntityArgument.ERROR_SELECTORS_NOT_ALLOWED.create();
        }
    }
 
    public Entity findSingleEntity(CommandSourceStack sender) throws CommandSyntaxException {
        this.checkPermissions(sender);
        List<? extends Entity> entities = this.findEntities(sender);
        if (entities.isEmpty()) {
            throw EntityArgument.NO_ENTITIES_FOUND.create();
        } else if (entities.size() > 1) {
            throw EntityArgument.ERROR_NOT_SINGLE_ENTITY.create();
        } else {
            return entities.get(0);
        }
    }
 
    public List<? extends Entity> findEntities(CommandSourceStack sender) throws CommandSyntaxException {
        this.checkPermissions(sender);
        if (!this.includesEntities) {
            return this.findPlayers(sender);
        } else if (this.playerName != null) {
            ServerPlayer result = sender.getServer().getPlayerList().getPlayerByName(this.playerName);
            return result == null ? List.of() : List.of(result);
        } else if (this.entityUUID != null) {
            for (ServerLevel level : sender.getServer().getAllLevels()) {
                Entity entity = level.getEntity(this.entityUUID);
                if (entity != null) {
                    if (entity.getType().isEnabled(sender.enabledFeatures())) {
                        return List.of(entity);
                    }
                    break;
                }
            }
 
            return List.of();
        } else {
            Vec3 pos = this.position.apply(sender.getPosition());
            AABB absoluteAabb = this.getAbsoluteAabb(pos);
            if (this.currentEntity) {
                Predicate<Entity> predicate = this.getPredicate(pos, absoluteAabb, null);
                return sender.getEntity() != null && predicate.test(sender.getEntity()) ? List.of(sender.getEntity()) : List.of();
            } else {
                Predicate<Entity> predicate = this.getPredicate(pos, absoluteAabb, sender.enabledFeatures());
                List<Entity> result = new ObjectArrayList<>();
                if (this.isWorldLimited()) {
                    this.addEntities(result, sender.getLevel(), absoluteAabb, predicate);
                } else {
                    for (ServerLevel levelx : sender.getServer().getAllLevels()) {
                        this.addEntities(result, levelx, absoluteAabb, predicate);
                    }
                }
 
                return this.sortAndLimit(pos, result);
            }
        }
    }
 
    private void addEntities(List<Entity> result, ServerLevel level, @Nullable AABB absoluteAABB, Predicate<Entity> predicate) {
        int limit = this.getResultLimit();
        if (result.size() < limit) {
            if (absoluteAABB != null) {
                level.getEntities(this.type, absoluteAABB, predicate, result, limit);
            } else {
                level.getEntities(this.type, predicate, result, limit);
            }
        }
    }
 
    private int getResultLimit() {
        return this.order == ORDER_ARBITRARY ? this.maxResults : Integer.MAX_VALUE;
    }
 
    public ServerPlayer findSinglePlayer(CommandSourceStack sender) throws CommandSyntaxException {
        this.checkPermissions(sender);
        List<ServerPlayer> players = this.findPlayers(sender);
        if (players.size() != 1) {
            throw EntityArgument.NO_PLAYERS_FOUND.create();
        } else {
            return players.get(0);
        }
    }
 
    public List<ServerPlayer> findPlayers(CommandSourceStack sender) throws CommandSyntaxException {
        this.checkPermissions(sender);
        if (this.playerName != null) {
            ServerPlayer result = sender.getServer().getPlayerList().getPlayerByName(this.playerName);
            return result == null ? List.of() : List.of(result);
        } else if (this.entityUUID != null) {
            ServerPlayer result = sender.getServer().getPlayerList().getPlayer(this.entityUUID);
            return result == null ? List.of() : List.of(result);
        } else {
            Vec3 pos = this.position.apply(sender.getPosition());
            AABB absoluteAabb = this.getAbsoluteAabb(pos);
            Predicate<Entity> predicate = this.getPredicate(pos, absoluteAabb, null);
            if (this.currentEntity) {
                return sender.getEntity() instanceof ServerPlayer player && predicate.test(player) ? List.of(player) : List.of();
            } else {
                int limit = this.getResultLimit();
                List<ServerPlayer> result;
                if (this.isWorldLimited()) {
                    result = sender.getLevel().getPlayers(predicate, limit);
                } else {
                    result = new ObjectArrayList<>();
 
                    for (ServerPlayer player : sender.getServer().getPlayerList().getPlayers()) {
                        if (predicate.test(player)) {
                            result.add(player);
                            if (result.size() >= limit) {
                                return result;
                            }
                        }
                    }
                }
 
                return this.sortAndLimit(pos, result);
            }
        }
    }
 
    private @Nullable AABB getAbsoluteAabb(Vec3 pos) {
        return this.aabb != null ? this.aabb.move(pos) : null;
    }
 
    private Predicate<Entity> getPredicate(Vec3 pos, @Nullable AABB absoluteAabb, @Nullable FeatureFlagSet enabledFeatures) {
        boolean filterFeatures = enabledFeatures != null;
        boolean filterAabb = absoluteAabb != null;
        boolean filterRange = this.range != null;
        int extraCount = (filterFeatures ? 1 : 0) + (filterAabb ? 1 : 0) + (filterRange ? 1 : 0);
        List<Predicate<Entity>> completePredicates;
        if (extraCount == 0) {
            completePredicates = this.contextFreePredicates;
        } else {
            List<Predicate<Entity>> predicates = new ObjectArrayList<>(this.contextFreePredicates.size() + extraCount);
            predicates.addAll(this.contextFreePredicates);
            if (filterFeatures) {
                predicates.add(e -> e.getType().isEnabled(enabledFeatures));
            }
 
            if (filterAabb) {
                predicates.add(e -> absoluteAabb.intersects(e.getBoundingBox()));
            }
 
            if (filterRange) {
                predicates.add(e -> this.range.matchesSqr(e.distanceToSqr(pos)));
            }
 
            completePredicates = predicates;
        }
 
        return Util.allOf(completePredicates);
    }
 
    private <T extends Entity> List<T> sortAndLimit(Vec3 pos, List<T> result) {
        if (result.size() > 1) {
            this.order.accept(pos, result);
        }
 
        return result.subList(0, Math.min(this.maxResults, result.size()));
    }
 
    public static Component joinNames(List<? extends Entity> entities) {
        return ComponentUtils.formatList(entities, Entity::getDisplayName);
    }
}

引用的其他类