AdvancementCommands.java

net.minecraft.server.commands.AdvancementCommands

信息

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

    TODO

字段/常量

  • ERROR_NO_ACTION_PERFORMED

    • 类型: DynamicCommandExceptionType
    • 修饰符: private static final
    • 源码定位: L27
    • 说明:

      TODO

  • ERROR_CRITERION_NOT_FOUND

    • 类型: Dynamic2CommandExceptionType
    • 修饰符: private static final
    • 源码定位: L28
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.server.commands.AdvancementCommands.Action

    • 类型: enum
    • 修饰符: private static
    • 源码定位: L369
    • 说明:

      TODO

  • net.minecraft.server.commands.AdvancementCommands.Mode

    • 类型: enum
    • 修饰符: private static
    • 源码定位: L445
    • 说明:

      TODO

构造器

方法

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

public static void register(CommandDispatcher<CommandSourceStack> dispatcher) @ L32

  • 方法名:register
  • 源码定位:L32
  • 返回类型:void
  • 修饰符:public static

参数:

  • dispatcher: CommandDispatcher

说明:

TODO

private static int perform(CommandSourceStack source, Collection<ServerPlayer> players, AdvancementCommands.Action action, Collection<AdvancementHolder> advancements) @ L224

  • 方法名:perform
  • 源码定位:L224
  • 返回类型:int
  • 修饰符:private static

参数:

  • source: CommandSourceStack
  • players: Collection
  • action: AdvancementCommands.Action
  • advancements: Collection

说明:

TODO

private static int perform(CommandSourceStack source, Collection<ServerPlayer> players, AdvancementCommands.Action action, Collection<AdvancementHolder> advancements, boolean showAdvancements) @ L230

  • 方法名:perform
  • 源码定位:L230
  • 返回类型:int
  • 修饰符:private static

参数:

  • source: CommandSourceStack
  • players: Collection
  • action: AdvancementCommands.Action
  • advancements: Collection
  • showAdvancements: boolean

说明:

TODO

private static int performCriterion(CommandSourceStack source, Collection<ServerPlayer> players, AdvancementCommands.Action action, AdvancementHolder holder, String criterion) @ L295

  • 方法名:performCriterion
  • 源码定位:L295
  • 返回类型:int
  • 修饰符:private static

参数:

  • source: CommandSourceStack
  • players: Collection
  • action: AdvancementCommands.Action
  • holder: AdvancementHolder
  • criterion: String

说明:

TODO

private static List<AdvancementHolder> getAdvancements(CommandContext<CommandSourceStack> context, AdvancementHolder target, AdvancementCommands.Mode mode) @ L340

  • 方法名:getAdvancements
  • 源码定位:L340
  • 返回类型:List
  • 修饰符:private static

参数:

  • context: CommandContext
  • target: AdvancementHolder
  • mode: AdvancementCommands.Mode

说明:

TODO

private static void addChildren(AdvancementNode parent, List<AdvancementHolder> output) @ L362

  • 方法名:addChildren
  • 源码定位:L362
  • 返回类型:void
  • 修饰符:private static

参数:

  • parent: AdvancementNode
  • output: List

说明:

TODO

代码

public class AdvancementCommands {
    private static final DynamicCommandExceptionType ERROR_NO_ACTION_PERFORMED = new DynamicCommandExceptionType(msg -> (Component)msg);
    private static final Dynamic2CommandExceptionType ERROR_CRITERION_NOT_FOUND = new Dynamic2CommandExceptionType(
        (name, criterion) -> Component.translatableEscape("commands.advancement.criterionNotFound", name, criterion)
    );
 
    public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
        dispatcher.register(
            Commands.literal("advancement")
                .requires(Commands.hasPermission(Commands.LEVEL_GAMEMASTERS))
                .then(
                    Commands.literal("grant")
                        .then(
                            Commands.argument("targets", EntityArgument.players())
                                .then(
                                    Commands.literal("only")
                                        .then(
                                            Commands.argument("advancement", ResourceKeyArgument.key(Registries.ADVANCEMENT))
                                                .executes(
                                                    c -> perform(
                                                        c.getSource(),
                                                        EntityArgument.getPlayers(c, "targets"),
                                                        AdvancementCommands.Action.GRANT,
                                                        getAdvancements(c, ResourceKeyArgument.getAdvancement(c, "advancement"), AdvancementCommands.Mode.ONLY)
                                                    )
                                                )
                                                .then(
                                                    Commands.argument("criterion", StringArgumentType.greedyString())
                                                        .suggests(
                                                            (c, p) -> SharedSuggestionProvider.suggest(
                                                                ResourceKeyArgument.getAdvancement(c, "advancement").value().criteria().keySet(), p
                                                            )
                                                        )
                                                        .executes(
                                                            c -> performCriterion(
                                                                c.getSource(),
                                                                EntityArgument.getPlayers(c, "targets"),
                                                                AdvancementCommands.Action.GRANT,
                                                                ResourceKeyArgument.getAdvancement(c, "advancement"),
                                                                StringArgumentType.getString(c, "criterion")
                                                            )
                                                        )
                                                )
                                        )
                                )
                                .then(
                                    Commands.literal("from")
                                        .then(
                                            Commands.argument("advancement", ResourceKeyArgument.key(Registries.ADVANCEMENT))
                                                .executes(
                                                    c -> perform(
                                                        c.getSource(),
                                                        EntityArgument.getPlayers(c, "targets"),
                                                        AdvancementCommands.Action.GRANT,
                                                        getAdvancements(c, ResourceKeyArgument.getAdvancement(c, "advancement"), AdvancementCommands.Mode.FROM)
                                                    )
                                                )
                                        )
                                )
                                .then(
                                    Commands.literal("until")
                                        .then(
                                            Commands.argument("advancement", ResourceKeyArgument.key(Registries.ADVANCEMENT))
                                                .executes(
                                                    c -> perform(
                                                        c.getSource(),
                                                        EntityArgument.getPlayers(c, "targets"),
                                                        AdvancementCommands.Action.GRANT,
                                                        getAdvancements(c, ResourceKeyArgument.getAdvancement(c, "advancement"), AdvancementCommands.Mode.UNTIL)
                                                    )
                                                )
                                        )
                                )
                                .then(
                                    Commands.literal("through")
                                        .then(
                                            Commands.argument("advancement", ResourceKeyArgument.key(Registries.ADVANCEMENT))
                                                .executes(
                                                    c -> perform(
                                                        c.getSource(),
                                                        EntityArgument.getPlayers(c, "targets"),
                                                        AdvancementCommands.Action.GRANT,
                                                        getAdvancements(
                                                            c, ResourceKeyArgument.getAdvancement(c, "advancement"), AdvancementCommands.Mode.THROUGH
                                                        )
                                                    )
                                                )
                                        )
                                )
                                .then(
                                    Commands.literal("everything")
                                        .executes(
                                            c -> perform(
                                                c.getSource(),
                                                EntityArgument.getPlayers(c, "targets"),
                                                AdvancementCommands.Action.GRANT,
                                                c.getSource().getServer().getAdvancements().getAllAdvancements(),
                                                false
                                            )
                                        )
                                )
                        )
                )
                .then(
                    Commands.literal("revoke")
                        .then(
                            Commands.argument("targets", EntityArgument.players())
                                .then(
                                    Commands.literal("only")
                                        .then(
                                            Commands.argument("advancement", ResourceKeyArgument.key(Registries.ADVANCEMENT))
                                                .executes(
                                                    c -> perform(
                                                        c.getSource(),
                                                        EntityArgument.getPlayers(c, "targets"),
                                                        AdvancementCommands.Action.REVOKE,
                                                        getAdvancements(c, ResourceKeyArgument.getAdvancement(c, "advancement"), AdvancementCommands.Mode.ONLY)
                                                    )
                                                )
                                                .then(
                                                    Commands.argument("criterion", StringArgumentType.greedyString())
                                                        .suggests(
                                                            (c, p) -> SharedSuggestionProvider.suggest(
                                                                ResourceKeyArgument.getAdvancement(c, "advancement").value().criteria().keySet(), p
                                                            )
                                                        )
                                                        .executes(
                                                            c -> performCriterion(
                                                                c.getSource(),
                                                                EntityArgument.getPlayers(c, "targets"),
                                                                AdvancementCommands.Action.REVOKE,
                                                                ResourceKeyArgument.getAdvancement(c, "advancement"),
                                                                StringArgumentType.getString(c, "criterion")
                                                            )
                                                        )
                                                )
                                        )
                                )
                                .then(
                                    Commands.literal("from")
                                        .then(
                                            Commands.argument("advancement", ResourceKeyArgument.key(Registries.ADVANCEMENT))
                                                .executes(
                                                    c -> perform(
                                                        c.getSource(),
                                                        EntityArgument.getPlayers(c, "targets"),
                                                        AdvancementCommands.Action.REVOKE,
                                                        getAdvancements(c, ResourceKeyArgument.getAdvancement(c, "advancement"), AdvancementCommands.Mode.FROM)
                                                    )
                                                )
                                        )
                                )
                                .then(
                                    Commands.literal("until")
                                        .then(
                                            Commands.argument("advancement", ResourceKeyArgument.key(Registries.ADVANCEMENT))
                                                .executes(
                                                    c -> perform(
                                                        c.getSource(),
                                                        EntityArgument.getPlayers(c, "targets"),
                                                        AdvancementCommands.Action.REVOKE,
                                                        getAdvancements(c, ResourceKeyArgument.getAdvancement(c, "advancement"), AdvancementCommands.Mode.UNTIL)
                                                    )
                                                )
                                        )
                                )
                                .then(
                                    Commands.literal("through")
                                        .then(
                                            Commands.argument("advancement", ResourceKeyArgument.key(Registries.ADVANCEMENT))
                                                .executes(
                                                    c -> perform(
                                                        c.getSource(),
                                                        EntityArgument.getPlayers(c, "targets"),
                                                        AdvancementCommands.Action.REVOKE,
                                                        getAdvancements(
                                                            c, ResourceKeyArgument.getAdvancement(c, "advancement"), AdvancementCommands.Mode.THROUGH
                                                        )
                                                    )
                                                )
                                        )
                                )
                                .then(
                                    Commands.literal("everything")
                                        .executes(
                                            c -> perform(
                                                c.getSource(),
                                                EntityArgument.getPlayers(c, "targets"),
                                                AdvancementCommands.Action.REVOKE,
                                                c.getSource().getServer().getAdvancements().getAllAdvancements()
                                            )
                                        )
                                )
                        )
                )
        );
    }
 
    private static int perform(
        CommandSourceStack source, Collection<ServerPlayer> players, AdvancementCommands.Action action, Collection<AdvancementHolder> advancements
    ) throws CommandSyntaxException {
        return perform(source, players, action, advancements, true);
    }
 
    private static int perform(
        CommandSourceStack source,
        Collection<ServerPlayer> players,
        AdvancementCommands.Action action,
        Collection<AdvancementHolder> advancements,
        boolean showAdvancements
    ) throws CommandSyntaxException {
        int count = 0;
 
        for (ServerPlayer player : players) {
            count += action.perform(player, advancements, showAdvancements);
        }
 
        if (count == 0) {
            if (advancements.size() == 1) {
                if (players.size() == 1) {
                    throw ERROR_NO_ACTION_PERFORMED.create(
                        Component.translatable(
                            action.getKey() + ".one.to.one.failure",
                            Advancement.name(advancements.iterator().next()),
                            players.iterator().next().getDisplayName()
                        )
                    );
                } else {
                    throw ERROR_NO_ACTION_PERFORMED.create(
                        Component.translatable(action.getKey() + ".one.to.many.failure", Advancement.name(advancements.iterator().next()), players.size())
                    );
                }
            } else if (players.size() == 1) {
                throw ERROR_NO_ACTION_PERFORMED.create(
                    Component.translatable(action.getKey() + ".many.to.one.failure", advancements.size(), players.iterator().next().getDisplayName())
                );
            } else {
                throw ERROR_NO_ACTION_PERFORMED.create(Component.translatable(action.getKey() + ".many.to.many.failure", advancements.size(), players.size()));
            }
        } else {
            if (advancements.size() == 1) {
                if (players.size() == 1) {
                    source.sendSuccess(
                        () -> Component.translatable(
                            action.getKey() + ".one.to.one.success",
                            Advancement.name(advancements.iterator().next()),
                            players.iterator().next().getDisplayName()
                        ),
                        true
                    );
                } else {
                    source.sendSuccess(
                        () -> Component.translatable(action.getKey() + ".one.to.many.success", Advancement.name(advancements.iterator().next()), players.size()),
                        true
                    );
                }
            } else if (players.size() == 1) {
                source.sendSuccess(
                    () -> Component.translatable(action.getKey() + ".many.to.one.success", advancements.size(), players.iterator().next().getDisplayName()),
                    true
                );
            } else {
                source.sendSuccess(() -> Component.translatable(action.getKey() + ".many.to.many.success", advancements.size(), players.size()), true);
            }
 
            return count;
        }
    }
 
    private static int performCriterion(
        CommandSourceStack source, Collection<ServerPlayer> players, AdvancementCommands.Action action, AdvancementHolder holder, String criterion
    ) throws CommandSyntaxException {
        int count = 0;
        Advancement advancement = holder.value();
        if (!advancement.criteria().containsKey(criterion)) {
            throw ERROR_CRITERION_NOT_FOUND.create(Advancement.name(holder), criterion);
        } else {
            for (ServerPlayer player : players) {
                if (action.performCriterion(player, holder, criterion)) {
                    count++;
                }
            }
 
            if (count == 0) {
                if (players.size() == 1) {
                    throw ERROR_NO_ACTION_PERFORMED.create(
                        Component.translatable(
                            action.getKey() + ".criterion.to.one.failure", criterion, Advancement.name(holder), players.iterator().next().getDisplayName()
                        )
                    );
                } else {
                    throw ERROR_NO_ACTION_PERFORMED.create(
                        Component.translatable(action.getKey() + ".criterion.to.many.failure", criterion, Advancement.name(holder), players.size())
                    );
                }
            } else {
                if (players.size() == 1) {
                    source.sendSuccess(
                        () -> Component.translatable(
                            action.getKey() + ".criterion.to.one.success", criterion, Advancement.name(holder), players.iterator().next().getDisplayName()
                        ),
                        true
                    );
                } else {
                    source.sendSuccess(
                        () -> Component.translatable(action.getKey() + ".criterion.to.many.success", criterion, Advancement.name(holder), players.size()), true
                    );
                }
 
                return count;
            }
        }
    }
 
    private static List<AdvancementHolder> getAdvancements(CommandContext<CommandSourceStack> context, AdvancementHolder target, AdvancementCommands.Mode mode) {
        AdvancementTree advancementTree = context.getSource().getServer().getAdvancements().tree();
        AdvancementNode targetNode = advancementTree.get(target);
        if (targetNode == null) {
            return List.of(target);
        } else {
            List<AdvancementHolder> advancements = new ArrayList<>();
            if (mode.parents) {
                for (AdvancementNode parent = targetNode.parent(); parent != null; parent = parent.parent()) {
                    advancements.add(parent.holder());
                }
            }
 
            advancements.add(target);
            if (mode.children) {
                addChildren(targetNode, advancements);
            }
 
            return advancements;
        }
    }
 
    private static void addChildren(AdvancementNode parent, List<AdvancementHolder> output) {
        for (AdvancementNode child : parent.children()) {
            output.add(child.holder());
            addChildren(child, output);
        }
    }
 
    private static enum Action {
        GRANT("grant") {
            @Override
            protected boolean perform(ServerPlayer player, AdvancementHolder advancement) {
                AdvancementProgress progress = player.getAdvancements().getOrStartProgress(advancement);
                if (progress.isDone()) {
                    return false;
                } else {
                    for (String criterion : progress.getRemainingCriteria()) {
                        player.getAdvancements().award(advancement, criterion);
                    }
 
                    return true;
                }
            }
 
            @Override
            protected boolean performCriterion(ServerPlayer player, AdvancementHolder advancement, String criterion) {
                return player.getAdvancements().award(advancement, criterion);
            }
        },
        REVOKE("revoke") {
            @Override
            protected boolean perform(ServerPlayer player, AdvancementHolder advancement) {
                AdvancementProgress progress = player.getAdvancements().getOrStartProgress(advancement);
                if (!progress.hasProgress()) {
                    return false;
                } else {
                    for (String criterion : progress.getCompletedCriteria()) {
                        player.getAdvancements().revoke(advancement, criterion);
                    }
 
                    return true;
                }
            }
 
            @Override
            protected boolean performCriterion(ServerPlayer player, AdvancementHolder advancement, String criterion) {
                return player.getAdvancements().revoke(advancement, criterion);
            }
        };
 
        private final String key;
 
        private Action(String key) {
            this.key = "commands.advancement." + key;
        }
 
        public int perform(ServerPlayer player, Iterable<AdvancementHolder> advancements, boolean showAdvancements) {
            int count = 0;
            if (!showAdvancements) {
                player.getAdvancements().flushDirty(player, true);
            }
 
            for (AdvancementHolder advancement : advancements) {
                if (this.perform(player, advancement)) {
                    count++;
                }
            }
 
            if (!showAdvancements) {
                player.getAdvancements().flushDirty(player, false);
            }
 
            return count;
        }
 
        protected abstract boolean perform(ServerPlayer player, AdvancementHolder advancement);
 
        protected abstract boolean performCriterion(ServerPlayer player, AdvancementHolder advancement, String criterion);
 
        protected String getKey() {
            return this.key;
        }
    }
 
    private static enum Mode {
        ONLY(false, false),
        THROUGH(true, true),
        FROM(false, true),
        UNTIL(true, false),
        EVERYTHING(true, true);
 
        private final boolean parents;
        private final boolean children;
 
        private Mode(boolean parents, boolean children) {
            this.parents = parents;
            this.children = children;
        }
    }
}

引用的其他类

  • Advancement

    • 引用位置: 方法调用
    • 关联成员: Advancement.name()
  • AdvancementHolder

    • 引用位置: 参数/返回值
  • AdvancementNode

    • 引用位置: 参数
  • CommandSourceStack

    • 引用位置: 参数
  • Commands

    • 引用位置: 方法调用
    • 关联成员: Commands.argument(), Commands.hasPermission(), Commands.literal()
  • SharedSuggestionProvider

    • 引用位置: 方法调用
    • 关联成员: SharedSuggestionProvider.suggest()
  • EntityArgument

    • 引用位置: 方法调用
    • 关联成员: EntityArgument.getPlayers(), EntityArgument.players()
  • ResourceKeyArgument

    • 引用位置: 方法调用
    • 关联成员: ResourceKeyArgument.getAdvancement(), ResourceKeyArgument.key()
  • Component

    • 引用位置: 方法调用
    • 关联成员: Component.translatable(), Component.translatableEscape()
  • ServerPlayer

    • 引用位置: 参数