DataCommands.java

net.minecraft.server.commands.data.DataCommands

信息

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

    TODO

字段/常量

  • ERROR_MERGE_UNCHANGED

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

      TODO

  • ERROR_GET_NOT_NUMBER

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

      TODO

  • ERROR_GET_NON_EXISTENT

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

      TODO

  • ERROR_MULTIPLE_TAGS

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

      TODO

  • ERROR_EXPECTED_OBJECT

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

      TODO

  • ERROR_EXPECTED_VALUE

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

      TODO

  • ERROR_INVALID_SUBSTRING

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

      TODO

  • ALL_PROVIDERS

    • 类型: List<Function<String,DataCommands.DataProvider>>
    • 修饰符: public static final
    • 源码定位: L55
    • 说明:

      TODO

  • TARGET_PROVIDERS

    • 类型: List<DataCommands.DataProvider>
    • 修饰符: public static final
    • 源码定位: L58
    • 说明:

      TODO

  • SOURCE_PROVIDERS

    • 类型: List<DataCommands.DataProvider>
    • 修饰符: public static final
    • 源码定位: L61
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.server.commands.data.DataCommands.DataManipulator

    • 类型: interface
    • 修饰符: private
    • 源码定位: L396
    • 说明:

      TODO

  • net.minecraft.server.commands.data.DataCommands.DataManipulatorDecorator

    • 类型: interface
    • 修饰符: private
    • 源码定位: L401
    • 说明:

      TODO

  • net.minecraft.server.commands.data.DataCommands.DataProvider

    • 类型: interface
    • 修饰符: public
    • 源码定位: L405
    • 说明:

      TODO

  • net.minecraft.server.commands.data.DataCommands.StringProcessor

    • 类型: interface
    • 修饰符: private
    • 源码定位: L414
    • 说明:

      TODO

构造器

方法

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

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

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

参数:

  • dispatcher: CommandDispatcher

说明:

TODO

private static String getAsText(Tag tag) @ L166

  • 方法名:getAsText
  • 源码定位:L166
  • 返回类型:String
  • 修饰符:private static

参数:

  • tag: Tag

说明:

TODO

private static List<Tag> stringifyTagList(List<Tag> source, DataCommands.StringProcessor stringProcessor) @ L174

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

参数:

  • source: List
  • stringProcessor: DataCommands.StringProcessor

说明:

TODO

private static ArgumentBuilder<CommandSourceStack,?> decorateModification(BiConsumer<ArgumentBuilder<CommandSourceStack,?>,DataCommands.DataManipulatorDecorator> nodeSupplier) @ L185

  • 方法名:decorateModification
  • 源码定位:L185
  • 返回类型:ArgumentBuilder<CommandSourceStack,?>
  • 修饰符:private static

参数:

  • nodeSupplier: BiConsumer<ArgumentBuilder<CommandSourceStack,?>,DataCommands.DataManipulatorDecorator>

说明:

TODO

private static String validatedSubstring(String input, int start, int end) @ L273

  • 方法名:validatedSubstring
  • 源码定位:L273
  • 返回类型:String
  • 修饰符:private static

参数:

  • input: String
  • start: int
  • end: int

说明:

TODO

private static String substring(String input, int start, int end) @ L281

  • 方法名:substring
  • 源码定位:L281
  • 返回类型:String
  • 修饰符:private static

参数:

  • input: String
  • start: int
  • end: int

说明:

TODO

private static String substring(String input, int start) @ L288

  • 方法名:substring
  • 源码定位:L288
  • 返回类型:String
  • 修饰符:private static

参数:

  • input: String
  • start: int

说明:

TODO

private static int getOffset(int index, int length) @ L293

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

参数:

  • index: int
  • length: int

说明:

TODO

private static List<Tag> getSingletonSource(CommandContext<CommandSourceStack> context, DataCommands.DataProvider sourceProvider) @ L297

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

参数:

  • context: CommandContext
  • sourceProvider: DataCommands.DataProvider

说明:

TODO

private static List<Tag> resolveSourcePath(CommandContext<CommandSourceStack> context, DataCommands.DataProvider sourceProvider) @ L302

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

参数:

  • context: CommandContext
  • sourceProvider: DataCommands.DataProvider

说明:

TODO

private static int manipulateData(CommandContext<CommandSourceStack> context, DataCommands.DataProvider targetProvider, DataCommands.DataManipulator manipulator, List<Tag> source) @ L308

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

参数:

  • context: CommandContext
  • targetProvider: DataCommands.DataProvider
  • manipulator: DataCommands.DataManipulator
  • source: List

说明:

TODO

private static int removeData(CommandSourceStack source, DataAccessor accessor, NbtPathArgument.NbtPath path) @ L324

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

参数:

  • source: CommandSourceStack
  • accessor: DataAccessor
  • path: NbtPathArgument.NbtPath

说明:

TODO

public static Tag getSingleTag(NbtPathArgument.NbtPath path, DataAccessor accessor) @ L336

  • 方法名:getSingleTag
  • 源码定位:L336
  • 返回类型:Tag
  • 修饰符:public static

参数:

  • path: NbtPathArgument.NbtPath
  • accessor: DataAccessor

说明:

TODO

private static int getData(CommandSourceStack source, DataAccessor accessor, NbtPathArgument.NbtPath path) @ L347

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

参数:

  • source: CommandSourceStack
  • accessor: DataAccessor
  • path: NbtPathArgument.NbtPath

说明:

TODO

private static int getNumeric(CommandSourceStack source, DataAccessor accessor, NbtPathArgument.NbtPath path, double scale) @ L362

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

参数:

  • source: CommandSourceStack
  • accessor: DataAccessor
  • path: NbtPathArgument.NbtPath
  • scale: double

说明:

TODO

private static int getData(CommandSourceStack source, DataAccessor accessor) @ L373

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

参数:

  • source: CommandSourceStack
  • accessor: DataAccessor

说明:

TODO

private static int mergeData(CommandSourceStack source, DataAccessor accessor, CompoundTag nbt) @ L379

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

参数:

  • source: CommandSourceStack
  • accessor: DataAccessor
  • nbt: CompoundTag

说明:

TODO

代码

public class DataCommands {
    private static final SimpleCommandExceptionType ERROR_MERGE_UNCHANGED = new SimpleCommandExceptionType(Component.translatable("commands.data.merge.failed"));
    private static final DynamicCommandExceptionType ERROR_GET_NOT_NUMBER = new DynamicCommandExceptionType(
        path -> Component.translatableEscape("commands.data.get.invalid", path)
    );
    private static final DynamicCommandExceptionType ERROR_GET_NON_EXISTENT = new DynamicCommandExceptionType(
        path -> Component.translatableEscape("commands.data.get.unknown", path)
    );
    private static final SimpleCommandExceptionType ERROR_MULTIPLE_TAGS = new SimpleCommandExceptionType(Component.translatable("commands.data.get.multiple"));
    private static final DynamicCommandExceptionType ERROR_EXPECTED_OBJECT = new DynamicCommandExceptionType(
        node -> Component.translatableEscape("commands.data.modify.expected_object", node)
    );
    private static final DynamicCommandExceptionType ERROR_EXPECTED_VALUE = new DynamicCommandExceptionType(
        node -> Component.translatableEscape("commands.data.modify.expected_value", node)
    );
    private static final Dynamic2CommandExceptionType ERROR_INVALID_SUBSTRING = new Dynamic2CommandExceptionType(
        (start, end) -> Component.translatableEscape("commands.data.modify.invalid_substring", start, end)
    );
    public static final List<Function<String, DataCommands.DataProvider>> ALL_PROVIDERS = ImmutableList.of(
        EntityDataAccessor.PROVIDER, BlockDataAccessor.PROVIDER, StorageDataAccessor.PROVIDER
    );
    public static final List<DataCommands.DataProvider> TARGET_PROVIDERS = ALL_PROVIDERS.stream()
        .map(f -> f.apply("target"))
        .collect(ImmutableList.toImmutableList());
    public static final List<DataCommands.DataProvider> SOURCE_PROVIDERS = ALL_PROVIDERS.stream()
        .map(f -> f.apply("source"))
        .collect(ImmutableList.toImmutableList());
 
    public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
        LiteralArgumentBuilder<CommandSourceStack> root = Commands.literal("data").requires(Commands.hasPermission(Commands.LEVEL_GAMEMASTERS));
 
        for (DataCommands.DataProvider targetProvider : TARGET_PROVIDERS) {
            root.then(
                    targetProvider.wrap(
                        Commands.literal("merge"),
                        p -> p.then(
                            Commands.argument("nbt", CompoundTagArgument.compoundTag())
                                .executes(c -> mergeData(c.getSource(), targetProvider.access(c), CompoundTagArgument.getCompoundTag(c, "nbt")))
                        )
                    )
                )
                .then(
                    targetProvider.wrap(
                        Commands.literal("get"),
                        p -> p.executes(c -> getData(c.getSource(), targetProvider.access(c)))
                            .then(
                                Commands.argument("path", NbtPathArgument.nbtPath())
                                    .executes(c -> getData(c.getSource(), targetProvider.access(c), NbtPathArgument.getPath(c, "path")))
                                    .then(
                                        Commands.argument("scale", DoubleArgumentType.doubleArg())
                                            .executes(
                                                c -> getNumeric(
                                                    c.getSource(),
                                                    targetProvider.access(c),
                                                    NbtPathArgument.getPath(c, "path"),
                                                    DoubleArgumentType.getDouble(c, "scale")
                                                )
                                            )
                                    )
                            )
                    )
                )
                .then(
                    targetProvider.wrap(
                        Commands.literal("remove"),
                        p -> p.then(
                            Commands.argument("path", NbtPathArgument.nbtPath())
                                .executes(c -> removeData(c.getSource(), targetProvider.access(c), NbtPathArgument.getPath(c, "path")))
                        )
                    )
                )
                .then(
                    decorateModification(
                        (parent, rest) -> parent.then(
                                Commands.literal("insert")
                                    .then(
                                        Commands.argument("index", IntegerArgumentType.integer())
                                            .then(
                                                rest.create(
                                                    (context, target, targetPath, source) -> targetPath.insert(
                                                        IntegerArgumentType.getInteger(context, "index"), target, source
                                                    )
                                                )
                                            )
                                    )
                            )
                            .then(Commands.literal("prepend").then(rest.create((context, target, targetPath, source) -> targetPath.insert(0, target, source))))
                            .then(Commands.literal("append").then(rest.create((context, target, targetPath, source) -> targetPath.insert(-1, target, source))))
                            .then(
                                Commands.literal("set")
                                    .then(rest.create((context, target, targetPath, source) -> targetPath.set(target, Iterables.getLast(source))))
                            )
                            .then(Commands.literal("merge").then(rest.create((context, target, targetPath, source) -> {
                                CompoundTag combinedSources = new CompoundTag();
 
                                for (Tag sourceTag : source) {
                                    if (NbtPathArgument.NbtPath.isTooDeep(sourceTag, 0)) {
                                        throw NbtPathArgument.ERROR_DATA_TOO_DEEP.create();
                                    }
 
                                    if (!(sourceTag instanceof CompoundTag tag)) {
                                        throw ERROR_EXPECTED_OBJECT.create(sourceTag);
                                    }
 
                                    combinedSources.merge(tag);
                                }
 
                                Collection<Tag> targets = targetPath.getOrCreate(target, CompoundTag::new);
                                int changedCount = 0;
 
                                for (Tag targetTag : targets) {
                                    if (!(targetTag instanceof CompoundTag targetObject)) {
                                        throw ERROR_EXPECTED_OBJECT.create(targetTag);
                                    }
 
                                    CompoundTag originalTarget = targetObject.copy();
                                    targetObject.merge(combinedSources);
                                    changedCount += originalTarget.equals(targetObject) ? 0 : 1;
                                }
 
                                return changedCount;
                            })))
                    )
                );
        }
 
        dispatcher.register(root);
    }
 
    private static String getAsText(Tag tag) throws CommandSyntaxException {
        return switch (tag) {
            case StringTag(String var7) -> var7;
            case PrimitiveTag primitiveTag -> primitiveTag.toString();
            default -> throw ERROR_EXPECTED_VALUE.create(tag);
        };
    }
 
    private static List<Tag> stringifyTagList(List<Tag> source, DataCommands.StringProcessor stringProcessor) throws CommandSyntaxException {
        List<Tag> result = new ArrayList<>(source.size());
 
        for (Tag tag : source) {
            String text = getAsText(tag);
            result.add(StringTag.valueOf(stringProcessor.process(text)));
        }
 
        return result;
    }
 
    private static ArgumentBuilder<CommandSourceStack, ?> decorateModification(
        BiConsumer<ArgumentBuilder<CommandSourceStack, ?>, DataCommands.DataManipulatorDecorator> nodeSupplier
    ) {
        LiteralArgumentBuilder<CommandSourceStack> modify = Commands.literal("modify");
 
        for (DataCommands.DataProvider targetProvider : TARGET_PROVIDERS) {
            targetProvider.wrap(
                modify,
                t -> {
                    ArgumentBuilder<CommandSourceStack, ?> targetPathNode = Commands.argument("targetPath", NbtPathArgument.nbtPath());
 
                    for (DataCommands.DataProvider sourceProvider : SOURCE_PROVIDERS) {
                        nodeSupplier.accept(
                            targetPathNode,
                            manipulator -> sourceProvider.wrap(
                                Commands.literal("from"),
                                s -> s.executes(c -> manipulateData(c, targetProvider, manipulator, getSingletonSource(c, sourceProvider)))
                                    .then(
                                        Commands.argument("sourcePath", NbtPathArgument.nbtPath())
                                            .executes(c -> manipulateData(c, targetProvider, manipulator, resolveSourcePath(c, sourceProvider)))
                                    )
                            )
                        );
                        nodeSupplier.accept(
                            targetPathNode,
                            manipulator -> sourceProvider.wrap(
                                Commands.literal("string"),
                                s -> s.executes(
                                        c -> manipulateData(c, targetProvider, manipulator, stringifyTagList(getSingletonSource(c, sourceProvider), str -> str))
                                    )
                                    .then(
                                        Commands.argument("sourcePath", NbtPathArgument.nbtPath())
                                            .executes(
                                                c -> manipulateData(
                                                    c, targetProvider, manipulator, stringifyTagList(resolveSourcePath(c, sourceProvider), str -> str)
                                                )
                                            )
                                            .then(
                                                Commands.argument("start", IntegerArgumentType.integer())
                                                    .executes(
                                                        c -> manipulateData(
                                                            c,
                                                            targetProvider,
                                                            manipulator,
                                                            stringifyTagList(
                                                                resolveSourcePath(c, sourceProvider),
                                                                str -> substring(str, IntegerArgumentType.getInteger(c, "start"))
                                                            )
                                                        )
                                                    )
                                                    .then(
                                                        Commands.argument("end", IntegerArgumentType.integer())
                                                            .executes(
                                                                c -> manipulateData(
                                                                    c,
                                                                    targetProvider,
                                                                    manipulator,
                                                                    stringifyTagList(
                                                                        resolveSourcePath(c, sourceProvider),
                                                                        str -> substring(
                                                                            str,
                                                                            IntegerArgumentType.getInteger(c, "start"),
                                                                            IntegerArgumentType.getInteger(c, "end")
                                                                        )
                                                                    )
                                                                )
                                                            )
                                                    )
                                            )
                                    )
                            )
                        );
                    }
 
                    nodeSupplier.accept(
                        targetPathNode, manipulator -> Commands.literal("value").then(Commands.argument("value", NbtTagArgument.nbtTag()).executes(c -> {
                            List<Tag> source = Collections.singletonList(NbtTagArgument.getNbtTag(c, "value"));
                            return manipulateData(c, targetProvider, manipulator, source);
                        }))
                    );
                    return t.then(targetPathNode);
                }
            );
        }
 
        return modify;
    }
 
    private static String validatedSubstring(String input, int start, int end) throws CommandSyntaxException {
        if (start >= 0 && end <= input.length() && start <= end) {
            return input.substring(start, end);
        } else {
            throw ERROR_INVALID_SUBSTRING.create(start, end);
        }
    }
 
    private static String substring(String input, int start, int end) throws CommandSyntaxException {
        int length = input.length();
        int absoluteStart = getOffset(start, length);
        int absoluteEnd = getOffset(end, length);
        return validatedSubstring(input, absoluteStart, absoluteEnd);
    }
 
    private static String substring(String input, int start) throws CommandSyntaxException {
        int length = input.length();
        return validatedSubstring(input, getOffset(start, length), length);
    }
 
    private static int getOffset(int index, int length) {
        return index >= 0 ? index : length + index;
    }
 
    private static List<Tag> getSingletonSource(CommandContext<CommandSourceStack> context, DataCommands.DataProvider sourceProvider) throws CommandSyntaxException {
        DataAccessor source = sourceProvider.access(context);
        return Collections.singletonList(source.getData());
    }
 
    private static List<Tag> resolveSourcePath(CommandContext<CommandSourceStack> context, DataCommands.DataProvider sourceProvider) throws CommandSyntaxException {
        DataAccessor source = sourceProvider.access(context);
        NbtPathArgument.NbtPath sourcePath = NbtPathArgument.getPath(context, "sourcePath");
        return sourcePath.get(source.getData());
    }
 
    private static int manipulateData(
        CommandContext<CommandSourceStack> context, DataCommands.DataProvider targetProvider, DataCommands.DataManipulator manipulator, List<Tag> source
    ) throws CommandSyntaxException {
        DataAccessor target = targetProvider.access(context);
        NbtPathArgument.NbtPath targetPath = NbtPathArgument.getPath(context, "targetPath");
        CompoundTag targetData = target.getData();
        int result = manipulator.modify(context, targetData, targetPath, source);
        if (result == 0) {
            throw ERROR_MERGE_UNCHANGED.create();
        } else {
            target.setData(targetData);
            context.getSource().sendSuccess(() -> target.getModifiedSuccess(), true);
            return result;
        }
    }
 
    private static int removeData(CommandSourceStack source, DataAccessor accessor, NbtPathArgument.NbtPath path) throws CommandSyntaxException {
        CompoundTag result = accessor.getData();
        int count = path.remove(result);
        if (count == 0) {
            throw ERROR_MERGE_UNCHANGED.create();
        } else {
            accessor.setData(result);
            source.sendSuccess(() -> accessor.getModifiedSuccess(), true);
            return count;
        }
    }
 
    public static Tag getSingleTag(NbtPathArgument.NbtPath path, DataAccessor accessor) throws CommandSyntaxException {
        Collection<Tag> tags = path.get(accessor.getData());
        Iterator<Tag> iterator = tags.iterator();
        Tag result = iterator.next();
        if (iterator.hasNext()) {
            throw ERROR_MULTIPLE_TAGS.create();
        } else {
            return result;
        }
    }
 
    private static int getData(CommandSourceStack source, DataAccessor accessor, NbtPathArgument.NbtPath path) throws CommandSyntaxException {
        Tag tag = getSingleTag(path, accessor);
 
        int result = switch (tag) {
            case NumericTag numericTag -> Mth.floor(numericTag.doubleValue());
            case CollectionTag collectionTag -> collectionTag.size();
            case CompoundTag compoundTag -> compoundTag.size();
            case StringTag(String var14) -> var14.length();
            case EndTag ignored -> throw ERROR_GET_NON_EXISTENT.create(path.toString());
            default -> throw new MatchException(null, null);
        };
        source.sendSuccess(() -> accessor.getPrintSuccess(tag), false);
        return result;
    }
 
    private static int getNumeric(CommandSourceStack source, DataAccessor accessor, NbtPathArgument.NbtPath path, double scale) throws CommandSyntaxException {
        Tag tag = getSingleTag(path, accessor);
        if (!(tag instanceof NumericTag)) {
            throw ERROR_GET_NOT_NUMBER.create(path.toString());
        } else {
            int result = Mth.floor(((NumericTag)tag).doubleValue() * scale);
            source.sendSuccess(() -> accessor.getPrintSuccess(path, scale, result), false);
            return result;
        }
    }
 
    private static int getData(CommandSourceStack source, DataAccessor accessor) throws CommandSyntaxException {
        CompoundTag data = accessor.getData();
        source.sendSuccess(() -> accessor.getPrintSuccess(data), false);
        return 1;
    }
 
    private static int mergeData(CommandSourceStack source, DataAccessor accessor, CompoundTag nbt) throws CommandSyntaxException {
        CompoundTag old = accessor.getData();
        if (NbtPathArgument.NbtPath.isTooDeep(nbt, 0)) {
            throw NbtPathArgument.ERROR_DATA_TOO_DEEP.create();
        } else {
            CompoundTag result = old.copy().merge(nbt);
            if (old.equals(result)) {
                throw ERROR_MERGE_UNCHANGED.create();
            } else {
                accessor.setData(result);
                source.sendSuccess(() -> accessor.getModifiedSuccess(), true);
                return 1;
            }
        }
    }
 
    @FunctionalInterface
    private interface DataManipulator {
        int modify(CommandContext<CommandSourceStack> context, CompoundTag targetData, NbtPathArgument.NbtPath targetPath, List<Tag> source) throws CommandSyntaxException;
    }
 
    @FunctionalInterface
    private interface DataManipulatorDecorator {
        ArgumentBuilder<CommandSourceStack, ?> create(DataCommands.DataManipulator manipulator);
    }
 
    public interface DataProvider {
        DataAccessor access(CommandContext<CommandSourceStack> context) throws CommandSyntaxException;
 
        ArgumentBuilder<CommandSourceStack, ?> wrap(
            ArgumentBuilder<CommandSourceStack, ?> parent, Function<ArgumentBuilder<CommandSourceStack, ?>, ArgumentBuilder<CommandSourceStack, ?>> function
        );
    }
 
    @FunctionalInterface
    private interface StringProcessor {
        String process(String string) throws CommandSyntaxException;
    }
}

引用的其他类

  • CommandSourceStack

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

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

    • 引用位置: 方法调用
    • 关联成员: CompoundTagArgument.compoundTag(), CompoundTagArgument.getCompoundTag()
  • NbtPathArgument

    • 引用位置: 参数/方法调用
    • 关联成员: NbtPathArgument.NbtPath.isTooDeep(), NbtPathArgument.getPath(), NbtPathArgument.nbtPath()
  • NbtTagArgument

    • 引用位置: 方法调用
    • 关联成员: NbtTagArgument.getNbtTag(), NbtTagArgument.nbtTag()
  • CompoundTag

    • 引用位置: 参数/构造调用
    • 关联成员: CompoundTag()
  • StringTag

    • 引用位置: 方法调用
    • 关联成员: StringTag.valueOf()
  • Tag

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

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

    • 引用位置: 参数
  • Mth

    • 引用位置: 方法调用
    • 关联成员: Mth.floor()