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;
}
}引用的其他类
-
- 引用位置:
参数/返回值
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Commands.argument(), Commands.hasPermission(), Commands.literal()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
CompoundTagArgument.compoundTag(), CompoundTagArgument.getCompoundTag()
- 引用位置:
-
- 引用位置:
参数/方法调用 - 关联成员:
NbtPathArgument.NbtPath.isTooDeep(), NbtPathArgument.getPath(), NbtPathArgument.nbtPath()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
NbtTagArgument.getNbtTag(), NbtTagArgument.nbtTag()
- 引用位置:
-
- 引用位置:
参数/构造调用 - 关联成员:
CompoundTag()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
StringTag.valueOf()
- 引用位置:
-
- 引用位置:
参数/返回值
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Component.translatable(), Component.translatableEscape()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Mth.floor()
- 引用位置: