XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEServerManager

【Java】我的世界XFE服务器管理器

公开
关注 0 Fork 0 Star 0
UTF-8
package com.xfestudio.xfeservermanager.api.command;

import com.xfestudio.xfeservermanager.api.util.ApiChecks;
import java.util.Set;

/** Semantic facts extracted from one parsed selector argument. */
public record SelectorFact(
        String argumentName,
        String rawExpression,
        SelectorType selectorType,
        Integer limit,
        DistanceRange distance,
        SelectorSort sort,
        Set<String> includedEntityTypes,
        Set<String> excludedEntityTypes,
        Set<String> tags,
        boolean hasNbtFilter,
        boolean hasPredicateFilter,
        int resolvedTargetCount,
        Set<String> resolvedEntityTypes
) {
    public static final int UNKNOWN_TARGET_COUNT = -1;

    public SelectorFact {
        argumentName = ApiChecks.notBlank(argumentName, "argumentName");
        rawExpression = ApiChecks.notBlank(rawExpression, "rawExpression");
        if (selectorType == null) {
            throw new NullPointerException("selectorType");
        }
        if (limit != null && limit < 1) {
            throw new IllegalArgumentException("limit must be positive when present");
        }
        if (sort == null) {
            throw new NullPointerException("sort");
        }
        includedEntityTypes = ApiChecks.immutableLowercaseSet(includedEntityTypes, "includedEntityTypes");
        excludedEntityTypes = ApiChecks.immutableLowercaseSet(excludedEntityTypes, "excludedEntityTypes");
        tags = ApiChecks.immutableLowercaseSet(tags, "tags");
        if (resolvedTargetCount < UNKNOWN_TARGET_COUNT) {
            throw new IllegalArgumentException("resolvedTargetCount must be -1 or non-negative");
        }
        resolvedEntityTypes = ApiChecks.immutableLowercaseSet(resolvedEntityTypes, "resolvedEntityTypes");
    }

    public boolean hasExplicitEntityTypeFilter() {
        return !includedEntityTypes.isEmpty() || !excludedEntityTypes.isEmpty();
    }

    public Set<String> effectiveEntityTypes() {
        if (!resolvedEntityTypes.isEmpty()) {
            return resolvedEntityTypes;
        }
        if (!includedEntityTypes.isEmpty()) {
            // A type tag is a set, not a concrete registry id. Without platform-side
            // expansion it must remain unknown so a deny-list cannot be bypassed by
            // spelling the same entity through #namespace:tag.
            return includedEntityTypes.stream()
                    .filter(value -> !value.startsWith("#"))
                    .collect(java.util.stream.Collectors.toUnmodifiableSet());
        }
        if (selectorType == SelectorType.ALL_PLAYERS
                || selectorType == SelectorType.NEAREST_PLAYER
                || selectorType == SelectorType.RANDOM_PLAYER) {
            return Set.of("minecraft:player");
        }
        return Set.of();
    }

    public boolean resolutionSucceeded() {
        return resolvedTargetCount != UNKNOWN_TARGET_COUNT;
    }
}