diff --git a/cloud-sponge/build.gradle.kts b/cloud-sponge/build.gradle.kts index db6e7f5c..33adb14d 100644 --- a/cloud-sponge/build.gradle.kts +++ b/cloud-sponge/build.gradle.kts @@ -9,12 +9,12 @@ dependencies { implementation(libs.cloud.brigadier) offlineLinkedJavadoc(project(":cloud-minecraft-modded-common")) implementation(project(":cloud-minecraft-modded-common")) - compileOnly("org.spongepowered:spongeapi:11.0.0-SNAPSHOT") - compileOnly("org.spongepowered:sponge:1.20.6-11.0.0-SNAPSHOT") + compileOnly("org.spongepowered:spongeapi:14.1.0-SNAPSHOT") + compileOnly("org.spongepowered:sponge:1.21.4-14.0.0-SNAPSHOT") } neoForge { enable { - neoFormVersion = "1.20.6-20240627.102356" + neoFormVersion = "1.21.4-20241203.161809" } } diff --git a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/CloudSpongeCommand.java b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/CloudSpongeCommand.java index 05119094..96ead523 100644 --- a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/CloudSpongeCommand.java +++ b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/CloudSpongeCommand.java @@ -45,6 +45,7 @@ import org.spongepowered.api.command.CommandResult; import org.spongepowered.api.command.parameter.ArgumentReader; import org.spongepowered.api.command.registrar.tree.CommandTreeNode; +import org.spongepowered.api.registry.RegistryHolder; import static net.kyori.adventure.text.Component.text; @@ -118,7 +119,7 @@ private CommandNode namedNode() { } @Override - public CommandTreeNode.Root commandTree() { + public CommandTreeNode.Root commandTree(final RegistryHolder holder) { final CommandTreeNode root = CommandTreeNode.root(); final CommandNode cloud = this.namedNode(); @@ -129,27 +130,27 @@ public CommandTreeNode.Root commandTree() { this.addRequirement(cloud, root); - this.addChildren(root, cloud); + this.addChildren(root, cloud, holder); return (CommandTreeNode.Root) root; } - private void addChildren(final CommandTreeNode node, final CommandNode cloud) { + private void addChildren(final CommandTreeNode node, final CommandNode cloud, final RegistryHolder holder) { for (final CommandNode child : cloud.children()) { final CommandComponent value = child.component(); final CommandTreeNode.Argument> treeNode; if (value.parser() instanceof LiteralParser) { treeNode = (CommandTreeNode.Argument>) CommandTreeNode.literal(); } else if (value.parser() instanceof AggregateParser aggregate) { - this.handleAggregate(node, child, aggregate); + this.handleAggregate(node, child, aggregate, holder); continue; } else { - treeNode = this.commandManager.parserMapper().mapComponent(value); + treeNode = this.commandManager.parserMapper().mapComponent(value, holder); } this.addRequirement(child, treeNode); if (canExecute(child)) { treeNode.executable(); } - this.addChildren(treeNode, child); + this.addChildren(treeNode, child, holder); node.child(value.name(), treeNode); } } @@ -157,13 +158,14 @@ private void addChildren(final CommandTreeNode node, final CommandNode clo private void handleAggregate( final CommandTreeNode node, final CommandNode child, - final AggregateParser compound + final AggregateParser compound, + final RegistryHolder holder ) { final CommandTreeNode.Argument> treeNode; final ArrayDeque>>> nodes = new ArrayDeque<>(); for (final CommandComponent component : compound.components()) { final String name = component.name(); - nodes.add(Pair.of(name, this.commandManager.parserMapper().mapParser(component.parser()))); + nodes.add(Pair.of(name, this.commandManager.parserMapper().mapParser(component.parser(), holder))); } Pair>> argument = null; while (!nodes.isEmpty()) { @@ -180,7 +182,7 @@ private void handleAggregate( this.addRequirement(child, argument.second()); } treeNode = argument.second(); - this.addChildren(treeNode, child); + this.addChildren(treeNode, child, holder); node.child(compound.components().get(0).toString(), treeNode); } diff --git a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/NodeSource.java b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/NodeSource.java index dcd55871..38d6f57c 100644 --- a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/NodeSource.java +++ b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/NodeSource.java @@ -25,6 +25,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.spongepowered.api.command.registrar.tree.CommandTreeNode; +import org.spongepowered.api.registry.RegistryHolder; /** * Implemented by {@link org.incendo.cloud.parser.ArgumentParser} which also supply a special {@link CommandTreeNode.Argument}. @@ -34,8 +35,9 @@ public interface NodeSource { /** * Get the node for this parser. * + * @param registryHolder registry holder * @return argument node */ - CommandTreeNode.@NonNull Argument> node(); + CommandTreeNode.@NonNull Argument> node(RegistryHolder registryHolder); } diff --git a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/SpongeCommandManager.java b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/SpongeCommandManager.java index fca8f492..2f86d7bd 100644 --- a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/SpongeCommandManager.java +++ b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/SpongeCommandManager.java @@ -72,6 +72,7 @@ import org.spongepowered.api.event.lifecycle.RegisterCommandEvent; import org.spongepowered.api.registry.DefaultedRegistryType; import org.spongepowered.api.registry.Registry; +import org.spongepowered.api.registry.RegistryHolder; import org.spongepowered.api.registry.RegistryType; import org.spongepowered.api.registry.RegistryTypes; import org.spongepowered.math.vector.Vector2d; @@ -115,7 +116,6 @@ public SpongeCommandManager( this.senderMapper = senderMapper; this.parserMapper = new SpongeParserMapper<>(); this.registerCommandPreProcessor(new SpongeCommandPreprocessor<>(this)); - this.registerParsers(); this.captionRegistry().registerProvider(new SpongeDefaultCaptionsProvider<>()); this.suggestionFactory = super.suggestionFactory().mapped(SpongeSuggestion::spongeSuggestion); @@ -137,19 +137,24 @@ private void checkLateCreation() { ); } - private void registerParsers() { + /** + * Register parsers + * + * @param registryHolder Register holder + */ + public void registerParsers(final RegistryHolder registryHolder) { this.parserRegistry() - .registerParser(ComponentParser.componentParser()) + .registerParser(ComponentParser.componentParser(registryHolder)) .registerParser(NamedTextColorParser.namedTextColorParser()) .registerParser(OperatorParser.operatorParser()) .registerParser(WorldParser.worldParser()) - .registerParser(ProtoItemStackParser.protoItemStackParser()) - .registerParser(ItemStackPredicateParser.itemStackPredicateParser()) + .registerParser(ProtoItemStackParser.protoItemStackParser(registryHolder)) + .registerParser(ItemStackPredicateParser.itemStackPredicateParser(registryHolder)) .registerParser(ResourceKeyParser.resourceKeyParser()) .registerParser(GameProfileParser.gameProfileParser()) .registerParser(GameProfileCollectionParser.gameProfileCollectionParser()) - .registerParser(BlockInputParser.blockInputParser()) - .registerParser(BlockPredicateParser.blockPredicateParser()) + .registerParser(BlockInputParser.blockInputParser(registryHolder)) + .registerParser(BlockPredicateParser.blockPredicateParser(registryHolder)) .registerParser(UserParser.userParser()) .registerParser(DataContainerParser.dataContainerParser()) .registerAnnotationMapper( diff --git a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/SpongeParserMapper.java b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/SpongeParserMapper.java index d816d6f7..cd2725a5 100644 --- a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/SpongeParserMapper.java +++ b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/SpongeParserMapper.java @@ -46,6 +46,7 @@ import org.incendo.cloud.parser.standard.UUIDParser; import org.spongepowered.api.command.registrar.tree.CommandTreeNode; import org.spongepowered.api.command.registrar.tree.CommandTreeNodeTypes; +import org.spongepowered.api.registry.RegistryHolder; import static java.util.Objects.requireNonNull; @@ -60,11 +61,12 @@ public final class SpongeParserMapper { private final Map, Mapping> mappers = new HashMap<>(); SpongeParserMapper() { - this.initStandardMappers(); + } - CommandTreeNode.Argument> mapComponent(final CommandComponent commandComponent) { - final CommandTreeNode.Argument> result = this.mapParser(commandComponent.parser()); + CommandTreeNode.Argument> mapComponent( + final CommandComponent commandComponent, final RegistryHolder holder) { + final CommandTreeNode.Argument> result = this.mapParser(commandComponent.parser(), holder); // final boolean customSuggestionsProvider = !DELEGATING_SUGGESTIONS_PROVIDER.isInstance(commandComponent.getSuggestionsProvider()); // todo: not exactly the same as in v1... final boolean customSuggestionsProvider = commandComponent.parser() != commandComponent.suggestionProvider(); @@ -75,13 +77,14 @@ CommandTreeNode.Argument> mapComponent(fin } @SuppressWarnings({"unchecked", "rawtypes"}) - CommandTreeNode.Argument> mapParser(final ArgumentParser argumentParser) { + CommandTreeNode.Argument> mapParser( + final ArgumentParser argumentParser, final RegistryHolder holder) { final CommandTreeNode.Argument> result; ArgumentParser parser = argumentParser; while (parser instanceof MappedArgumentParser) { parser = ((MappedArgumentParser) parser).baseParser(); } - final Mapping mapper = this.mappers.get(parser.getClass()); + final Mapping mapper = this.getOrCreateMappers(holder).get(parser.getClass()); if (mapper != null) { final CommandTreeNode.Argument> apply = (CommandTreeNode.Argument>) ((Function) mapper.mapper).apply(parser); @@ -91,43 +94,51 @@ CommandTreeNode.Argument> mapParser(final } result = apply; } else if (parser instanceof NodeSource) { - result = ((NodeSource) parser).node(); + result = ((NodeSource) parser).node(holder); } else { - result = CommandTreeNodeTypes.STRING.get().createNode().customCompletions().word(); + result = CommandTreeNodeTypes.STRING.get(holder).createNode().customCompletions().word(); } return result; } - private void initStandardMappers() { + private synchronized Map, Mapping> getOrCreateMappers(final RegistryHolder holder) { + if (this.mappers.isEmpty()) { + this.initStandardMappers(holder); + } + + return this.mappers; + } + + private void initStandardMappers(final RegistryHolder holder) { this.registerMapping(new TypeToken>() { }, builder -> builder.to(stringParser -> { final StringParser.StringMode mode = stringParser.stringMode(); if (mode == StringParser.StringMode.SINGLE) { - return CommandTreeNodeTypes.STRING.get().createNode().customCompletions().word(); + return CommandTreeNodeTypes.STRING.get(holder).createNode().customCompletions().word(); } else if (mode == StringParser.StringMode.QUOTED) { - return CommandTreeNodeTypes.STRING.get().createNode().customCompletions(); + return CommandTreeNodeTypes.STRING.get(holder).createNode().customCompletions(); } else if (mode == StringParser.StringMode.GREEDY || mode == StringParser.StringMode.GREEDY_FLAG_YIELDING) { - return CommandTreeNodeTypes.STRING.get().createNode().customCompletions().greedy(); + return CommandTreeNodeTypes.STRING.get(holder).createNode().customCompletions().greedy(); } throw new IllegalArgumentException("Unknown string mode '" + mode + "'!"); })); this.registerMapping(new TypeToken>() { }, builder -> builder.to(byteParser -> { - final CommandTreeNode.Range node = CommandTreeNodeTypes.INTEGER.get().createNode(); + final CommandTreeNode.Range node = CommandTreeNodeTypes.INTEGER.get(holder).createNode(); node.min((int) byteParser.range().minByte()); node.max((int) byteParser.range().maxByte()); return node; }).cloudSuggestions(true)); this.registerMapping(new TypeToken>() { }, builder -> builder.to(shortParser -> { - final CommandTreeNode.Range node = CommandTreeNodeTypes.INTEGER.get().createNode(); + final CommandTreeNode.Range node = CommandTreeNodeTypes.INTEGER.get(holder).createNode(); node.min((int) shortParser.range().minShort()); node.max((int) shortParser.range().maxShort()); return node; }).cloudSuggestions(true)); this.registerMapping(new TypeToken>() { }, builder -> builder.to(integerParser -> { - final CommandTreeNode.Range node = CommandTreeNodeTypes.INTEGER.get().createNode(); + final CommandTreeNode.Range node = CommandTreeNodeTypes.INTEGER.get(holder).createNode(); if (integerParser.hasMin()) { node.min(integerParser.range().minInt()); } @@ -138,7 +149,7 @@ private void initStandardMappers() { }).cloudSuggestions(true)); this.registerMapping(new TypeToken>() { }, builder -> builder.to(floatParser -> { - final CommandTreeNode.Range node = CommandTreeNodeTypes.FLOAT.get().createNode(); + final CommandTreeNode.Range node = CommandTreeNodeTypes.FLOAT.get(holder).createNode(); if (floatParser.hasMin()) { node.min(floatParser.range().minFloat()); } @@ -149,7 +160,7 @@ private void initStandardMappers() { }).cloudSuggestions(true)); this.registerMapping(new TypeToken>() { }, builder -> builder.to(doubleParser -> { - final CommandTreeNode.Range node = CommandTreeNodeTypes.DOUBLE.get().createNode(); + final CommandTreeNode.Range node = CommandTreeNodeTypes.DOUBLE.get(holder).createNode(); if (doubleParser.hasMin()) { node.min(doubleParser.range().minDouble()); } @@ -160,7 +171,7 @@ private void initStandardMappers() { }).cloudSuggestions(true)); this.registerMapping(new TypeToken>() { }, builder -> builder.to(longParser -> { - final CommandTreeNode.Range node = CommandTreeNodeTypes.LONG.get().createNode(); + final CommandTreeNode.Range node = CommandTreeNodeTypes.LONG.get(holder).createNode(); if (longParser.hasMin()) { node.min(longParser.range().minLong()); } @@ -171,19 +182,19 @@ private void initStandardMappers() { }).cloudSuggestions(true)); this.registerMapping(new TypeToken>() { }, builder -> builder.to(booleanParser -> { - return CommandTreeNodeTypes.BOOL.get().createNode(); + return CommandTreeNodeTypes.BOOL.get(holder).createNode(); })); this.registerMapping(new TypeToken>() { }, builder -> builder.to(flagArgumentParser -> { - return CommandTreeNodeTypes.STRING.get().createNode().customCompletions().greedy(); + return CommandTreeNodeTypes.STRING.get(holder).createNode().customCompletions().greedy(); })); this.registerMapping(new TypeToken>() { }, builder -> builder.to(stringArrayParser -> { - return CommandTreeNodeTypes.STRING.get().createNode().customCompletions().greedy(); + return CommandTreeNodeTypes.STRING.get(holder).createNode().customCompletions().greedy(); })); this.registerMapping(new TypeToken>() { }, builder -> builder.to(uuidParser -> { - return CommandTreeNodeTypes.UUID.get().createNode(); + return CommandTreeNodeTypes.UUID.get(holder).createNode(); })); } diff --git a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/SpongeRegistrationHandler.java b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/SpongeRegistrationHandler.java index acb25898..3529e0ae 100644 --- a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/SpongeRegistrationHandler.java +++ b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/SpongeRegistrationHandler.java @@ -58,6 +58,8 @@ final class SpongeRegistrationHandler implements CommandRegistrationHandler event) { this.commandManager.registrationCalled(); + this.commandManager.registerParsers(event.registryHolder()); + for (final CommandNode node : this.commandManager.commandTree().rootNodes()) { this.registerCommand(event, requireNonNull(node.component())); } diff --git a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/data/ProtoItemStack.java b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/data/ProtoItemStack.java index e8c14be3..20dae6fd 100644 --- a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/data/ProtoItemStack.java +++ b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/data/ProtoItemStack.java @@ -24,9 +24,7 @@ package org.incendo.cloud.sponge.data; import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.checker.nullness.qual.Nullable; import org.incendo.cloud.sponge.exception.ComponentMessageRuntimeException; -import org.spongepowered.api.data.persistence.DataContainer; import org.spongepowered.api.item.ItemType; import org.spongepowered.api.item.inventory.ItemStack; import org.spongepowered.api.item.inventory.ItemStackSnapshot; @@ -43,15 +41,6 @@ public interface ProtoItemStack { */ @NonNull ItemType itemType(); - /** - * Get any extra data besides the {@link ItemType} that may have been parsed. - * - *

Will return {@code null} if there is no extra data.

- * - * @return the extra data or {@code null} - */ - @Nullable DataContainer extraData(); - /** * Create a new {@link ItemStack} from the state of this {@link ProtoItemStack}. * diff --git a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/BlockInputParser.java b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/BlockInputParser.java index 52e7ff6d..95d0204d 100644 --- a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/BlockInputParser.java +++ b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/BlockInputParser.java @@ -26,6 +26,7 @@ import java.lang.reflect.Field; import java.util.Arrays; import java.util.concurrent.CompletableFuture; +import net.minecraft.commands.CommandBuildContext; import net.minecraft.commands.arguments.blocks.BlockStateArgument; import net.minecraft.nbt.CompoundTag; import net.minecraft.server.level.ServerLevel; @@ -34,7 +35,6 @@ import org.incendo.cloud.brigadier.parser.WrappedBrigadierParser; import org.incendo.cloud.context.CommandContext; import org.incendo.cloud.context.CommandInput; -import org.incendo.cloud.minecraft.modded.internal.ContextualArgumentTypeProvider; import org.incendo.cloud.parser.ArgumentParseResult; import org.incendo.cloud.parser.ArgumentParser; import org.incendo.cloud.parser.ParserDescriptor; @@ -46,6 +46,7 @@ import org.spongepowered.api.command.registrar.tree.CommandTreeNode; import org.spongepowered.api.command.registrar.tree.CommandTreeNodeTypes; import org.spongepowered.api.data.persistence.DataContainer; +import org.spongepowered.api.registry.RegistryHolder; import org.spongepowered.api.world.BlockChangeFlag; import org.spongepowered.api.world.BlockChangeFlags; import org.spongepowered.api.world.server.ServerLocation; @@ -68,21 +69,26 @@ */ public final class BlockInputParser implements NodeSource, ArgumentParser.FutureArgumentParser, SuggestionProvider { + private BlockInputParser(final RegistryHolder registryHolder) { + //todo: Use ContextualArgumentTypeProvider + this.mappedParser = new WrappedBrigadierParser( + BlockStateArgument.block((CommandBuildContext) registryHolder) + ).flatMapSuccess((ctx, blockInput) -> + ArgumentParseResult.successFuture(new BlockInputImpl(blockInput))); + } + /** * Creates a new {@link BlockInputParser}. * * @param command sender type + * @param registryHolder register holder * @return new parser */ - public static ParserDescriptor blockInputParser() { - return ParserDescriptor.of(new BlockInputParser<>(), BlockInput.class); + public static ParserDescriptor blockInputParser(final RegistryHolder registryHolder) { + return ParserDescriptor.of(new BlockInputParser<>(registryHolder), BlockInput.class); } - private final ArgumentParser mappedParser = - new WrappedBrigadierParser( - new ContextualArgumentTypeProvider<>(BlockStateArgument::block) - ).flatMapSuccess((ctx, blockInput) -> - ArgumentParseResult.successFuture(new BlockInputImpl(blockInput))); + private final ArgumentParser mappedParser; @Override public @NonNull CompletableFuture> parseFuture( @@ -101,8 +107,8 @@ public static ParserDescriptor blockInputParser() { } @Override - public CommandTreeNode.@NonNull Argument> node() { - return CommandTreeNodeTypes.BLOCK_STATE.get().createNode(); + public CommandTreeNode.@NonNull Argument> node(final RegistryHolder holder) { + return CommandTreeNodeTypes.BLOCK_STATE.get(holder).createNode(); } private static final class BlockInputImpl implements BlockInput { diff --git a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/BlockPredicateParser.java b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/BlockPredicateParser.java index fd840818..ea3b0c33 100644 --- a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/BlockPredicateParser.java +++ b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/BlockPredicateParser.java @@ -25,6 +25,7 @@ import java.util.concurrent.CompletableFuture; import java.util.function.Predicate; +import net.minecraft.commands.CommandBuildContext; import net.minecraft.commands.arguments.blocks.BlockPredicateArgument; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.block.state.pattern.BlockInWorld; @@ -32,7 +33,6 @@ import org.incendo.cloud.brigadier.parser.WrappedBrigadierParser; import org.incendo.cloud.context.CommandContext; import org.incendo.cloud.context.CommandInput; -import org.incendo.cloud.minecraft.modded.internal.ContextualArgumentTypeProvider; import org.incendo.cloud.parser.ArgumentParseResult; import org.incendo.cloud.parser.ArgumentParser; import org.incendo.cloud.parser.ParserDescriptor; @@ -42,6 +42,7 @@ import org.incendo.cloud.suggestion.SuggestionProvider; import org.spongepowered.api.command.registrar.tree.CommandTreeNode; import org.spongepowered.api.command.registrar.tree.CommandTreeNodeTypes; +import org.spongepowered.api.registry.RegistryHolder; import org.spongepowered.api.world.server.ServerLocation; import org.spongepowered.common.util.VecHelper; @@ -53,20 +54,25 @@ public final class BlockPredicateParser implements ArgumentParser.FutureArgumentParser, NodeSource, SuggestionProvider { + private BlockPredicateParser(final RegistryHolder registryHolder) { + //todo: Use ContextualArgumentTypeProvider + this.mappedParser = new WrappedBrigadierParser( + net.minecraft.commands.arguments.blocks.BlockPredicateArgument.blockPredicate((CommandBuildContext) registryHolder) + ).flatMapSuccess((ctx, result) -> ArgumentParseResult.successFuture(new BlockPredicateImpl(result))); + } + /** * Creates a new {@link BlockPredicateParser}. * * @param command sender type + * @param registryHolder register holder * @return new parser */ - public static ParserDescriptor blockPredicateParser() { - return ParserDescriptor.of(new BlockPredicateParser<>(), BlockPredicate.class); + public static ParserDescriptor blockPredicateParser(final RegistryHolder registryHolder) { + return ParserDescriptor.of(new BlockPredicateParser<>(registryHolder), BlockPredicate.class); } - private final ArgumentParser mappedParser = - new WrappedBrigadierParser( - new ContextualArgumentTypeProvider<>(net.minecraft.commands.arguments.blocks.BlockPredicateArgument::blockPredicate) - ).flatMapSuccess((ctx, result) -> ArgumentParseResult.successFuture(new BlockPredicateImpl(result))); + private final ArgumentParser mappedParser; @Override public @NonNull CompletableFuture<@NonNull ArgumentParseResult> parseFuture( @@ -85,8 +91,8 @@ public static ParserDescriptor blockPredicateParser() { } @Override - public CommandTreeNode.@NonNull Argument> node() { - return CommandTreeNodeTypes.BLOCK_PREDICATE.get().createNode(); + public CommandTreeNode.@NonNull Argument> node(final RegistryHolder holder) { + return CommandTreeNodeTypes.BLOCK_PREDICATE.get(holder).createNode(); } private record BlockPredicateImpl(Predicate predicate) implements BlockPredicate { diff --git a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/ComponentParser.java b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/ComponentParser.java index 4ccdde92..f6363dc1 100644 --- a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/ComponentParser.java +++ b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/ComponentParser.java @@ -25,12 +25,12 @@ import java.util.concurrent.CompletableFuture; import net.kyori.adventure.text.Component; +import net.minecraft.commands.CommandBuildContext; import net.minecraft.commands.arguments.ComponentArgument; import org.checkerframework.checker.nullness.qual.NonNull; import org.incendo.cloud.brigadier.parser.WrappedBrigadierParser; import org.incendo.cloud.context.CommandContext; import org.incendo.cloud.context.CommandInput; -import org.incendo.cloud.minecraft.modded.internal.ContextualArgumentTypeProvider; import org.incendo.cloud.parser.ArgumentParseResult; import org.incendo.cloud.parser.ArgumentParser; import org.incendo.cloud.parser.ParserDescriptor; @@ -39,6 +39,7 @@ import org.incendo.cloud.suggestion.SuggestionProvider; import org.spongepowered.api.command.registrar.tree.CommandTreeNode; import org.spongepowered.api.command.registrar.tree.CommandTreeNodeTypes; +import org.spongepowered.api.registry.RegistryHolder; import org.spongepowered.common.adventure.SpongeAdventure; /** @@ -48,21 +49,26 @@ */ public final class ComponentParser implements ArgumentParser.FutureArgumentParser, NodeSource, SuggestionProvider { + private ComponentParser(final RegistryHolder registryHolder) { + //todo: Use ContextualArgumentTypeProvider + this.mappedParser = new WrappedBrigadierParser( + ComponentArgument.textComponent((CommandBuildContext) registryHolder) + ).flatMapSuccess((ctx, component) -> + ArgumentParseResult.successFuture(SpongeAdventure.asAdventure(component))); + } + /** * Creates a new {@link ComponentParser}. * * @param command sender type + * @param registryHolder register holder * @return new parser */ - public static ParserDescriptor componentParser() { - return ParserDescriptor.of(new ComponentParser<>(), Component.class); + public static ParserDescriptor componentParser(final RegistryHolder registryHolder) { + return ParserDescriptor.of(new ComponentParser<>(registryHolder), Component.class); } - private final ArgumentParser mappedParser = - new WrappedBrigadierParser( - new ContextualArgumentTypeProvider<>(ComponentArgument::textComponent) - ).flatMapSuccess((ctx, component) -> - ArgumentParseResult.successFuture(SpongeAdventure.asAdventure(component))); + private final ArgumentParser mappedParser; @Override public @NonNull CompletableFuture> parseFuture( @@ -81,8 +87,8 @@ public static ParserDescriptor componentParser() { } @Override - public CommandTreeNode.@NonNull Argument> node() { - return CommandTreeNodeTypes.COMPONENT.get().createNode(); + public CommandTreeNode.@NonNull Argument> node(final RegistryHolder holder) { + return CommandTreeNodeTypes.COMPONENT.get(holder).createNode(); } } diff --git a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/DataContainerParser.java b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/DataContainerParser.java index 8b29fa1b..36c6fc26 100644 --- a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/DataContainerParser.java +++ b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/DataContainerParser.java @@ -39,6 +39,7 @@ import org.spongepowered.api.command.registrar.tree.CommandTreeNode; import org.spongepowered.api.command.registrar.tree.CommandTreeNodeTypes; import org.spongepowered.api.data.persistence.DataContainer; +import org.spongepowered.api.registry.RegistryHolder; import org.spongepowered.common.data.persistence.NBTTranslator; /** @@ -82,8 +83,8 @@ public static ParserDescriptor dataContainerParser() { } @Override - public CommandTreeNode.@NonNull Argument> node() { - return CommandTreeNodeTypes.NBT_COMPOUND_TAG.get().createNode(); + public CommandTreeNode.@NonNull Argument> node(final RegistryHolder holder) { + return CommandTreeNodeTypes.NBT_COMPOUND_TAG.get(holder).createNode(); } } diff --git a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/GameProfileCollectionParser.java b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/GameProfileCollectionParser.java index 44e4d646..812c0362 100644 --- a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/GameProfileCollectionParser.java +++ b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/GameProfileCollectionParser.java @@ -50,6 +50,7 @@ import org.spongepowered.api.command.registrar.tree.CommandTreeNodeTypes; import org.spongepowered.api.command.selector.Selector; import org.spongepowered.api.profile.GameProfile; +import org.spongepowered.api.registry.RegistryHolder; import org.spongepowered.common.profile.SpongeGameProfile; /** @@ -105,8 +106,8 @@ public static ParserDescriptor gameProfileCollecti } @Override - public CommandTreeNode.@NonNull Argument> node() { - return CommandTreeNodeTypes.GAME_PROFILE.get().createNode(); + public CommandTreeNode.@NonNull Argument> node(final RegistryHolder holder) { + return CommandTreeNodeTypes.GAME_PROFILE.get(holder).createNode(); } diff --git a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/GameProfileParser.java b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/GameProfileParser.java index becfea35..4343ed72 100644 --- a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/GameProfileParser.java +++ b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/GameProfileParser.java @@ -44,6 +44,7 @@ import org.spongepowered.api.command.registrar.tree.CommandTreeNodeTypes; import org.spongepowered.api.command.selector.Selector; import org.spongepowered.api.profile.GameProfile; +import org.spongepowered.api.registry.RegistryHolder; import org.spongepowered.common.profile.SpongeGameProfile; /** @@ -99,8 +100,8 @@ public static ParserDescriptor gameProfileParser() { } @Override - public CommandTreeNode.@NonNull Argument> node() { - return CommandTreeNodeTypes.GAME_PROFILE.get().createNode(); + public CommandTreeNode.@NonNull Argument> node(final RegistryHolder holder) { + return CommandTreeNodeTypes.GAME_PROFILE.get(holder).createNode(); } diff --git a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/ItemStackPredicateParser.java b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/ItemStackPredicateParser.java index 2b6df2d1..3d690ce5 100644 --- a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/ItemStackPredicateParser.java +++ b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/ItemStackPredicateParser.java @@ -25,12 +25,12 @@ import java.util.concurrent.CompletableFuture; import java.util.function.Predicate; +import net.minecraft.commands.CommandBuildContext; import net.minecraft.commands.arguments.item.ItemPredicateArgument; import org.checkerframework.checker.nullness.qual.NonNull; import org.incendo.cloud.brigadier.parser.WrappedBrigadierParser; import org.incendo.cloud.context.CommandContext; import org.incendo.cloud.context.CommandInput; -import org.incendo.cloud.minecraft.modded.internal.ContextualArgumentTypeProvider; import org.incendo.cloud.parser.ArgumentParseResult; import org.incendo.cloud.parser.ArgumentParser; import org.incendo.cloud.parser.ParserDescriptor; @@ -41,6 +41,7 @@ import org.spongepowered.api.command.registrar.tree.CommandTreeNode; import org.spongepowered.api.command.registrar.tree.CommandTreeNodeTypes; import org.spongepowered.api.item.inventory.ItemStack; +import org.spongepowered.api.registry.RegistryHolder; /** * An argument for parsing {@link ItemStackPredicate ItemStackPredicates}. @@ -50,20 +51,25 @@ public final class ItemStackPredicateParser implements ArgumentParser.FutureArgumentParser, NodeSource, SuggestionProvider { + private ItemStackPredicateParser(final RegistryHolder registryHolder) { + //todo: Use ContextualArgumentTypeProvider + this.mappedParser = new WrappedBrigadierParser( + ItemPredicateArgument.itemPredicate((CommandBuildContext) registryHolder) + ).flatMapSuccess((ctx, result) -> ArgumentParseResult.successFuture(new ItemStackPredicateImpl(result))); + } + /** * Creates a new {@link ItemStackPredicateParser}. * * @param command sender type + * @param registryHolder register holder * @return new parser */ - public static ParserDescriptor itemStackPredicateParser() { - return ParserDescriptor.of(new ItemStackPredicateParser<>(), ItemStackPredicate.class); + public static ParserDescriptor itemStackPredicateParser(final RegistryHolder registryHolder) { + return ParserDescriptor.of(new ItemStackPredicateParser<>(registryHolder), ItemStackPredicate.class); } - private final ArgumentParser mappedParser = - new WrappedBrigadierParser( - new ContextualArgumentTypeProvider<>(ItemPredicateArgument::itemPredicate) - ).flatMapSuccess((ctx, result) -> ArgumentParseResult.successFuture(new ItemStackPredicateImpl(result))); + private final ArgumentParser mappedParser; @Override public @NonNull CompletableFuture> parseFuture( @@ -82,8 +88,8 @@ public static ParserDescriptor itemStackPredicatePars } @Override - public CommandTreeNode.@NonNull Argument> node() { - return CommandTreeNodeTypes.ITEM_PREDICATE.get().createNode(); + public CommandTreeNode.@NonNull Argument> node(final RegistryHolder holder) { + return CommandTreeNodeTypes.ITEM_PREDICATE.get(holder).createNode(); } private record ItemStackPredicateImpl(Predicate predicate) implements ItemStackPredicate { diff --git a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/MultipleEntitySelectorParser.java b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/MultipleEntitySelectorParser.java index 2d4cf653..dcff0029 100644 --- a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/MultipleEntitySelectorParser.java +++ b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/MultipleEntitySelectorParser.java @@ -47,6 +47,7 @@ import org.spongepowered.api.command.registrar.tree.CommandTreeNodeTypes; import org.spongepowered.api.command.selector.Selector; import org.spongepowered.api.entity.Entity; +import org.spongepowered.api.registry.RegistryHolder; /** * Argument for selecting one or more {@link Entity Entities} using a {@link Selector}. @@ -102,8 +103,8 @@ public static ParserDescriptor multipleEntitySele } @Override - public CommandTreeNode.@NonNull Argument> node() { - return CommandTreeNodeTypes.ENTITY.get().createNode(); + public CommandTreeNode.@NonNull Argument> node(final RegistryHolder holder) { + return CommandTreeNodeTypes.ENTITY.get(holder).createNode(); } private static final class MultipleEntitySelectorImpl implements MultipleEntitySelector { diff --git a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/MultiplePlayerSelectorParser.java b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/MultiplePlayerSelectorParser.java index 2105705f..5ceafd29 100644 --- a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/MultiplePlayerSelectorParser.java +++ b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/MultiplePlayerSelectorParser.java @@ -48,6 +48,7 @@ import org.spongepowered.api.command.selector.Selector; import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.entity.living.player.server.ServerPlayer; +import org.spongepowered.api.registry.RegistryHolder; /** * Argument for selecting one or more {@link Player Players} using a {@link Selector}. @@ -102,8 +103,8 @@ public static ParserDescriptor multiplePlayerSele } @Override - public CommandTreeNode.@NonNull Argument> node() { - return CommandTreeNodeTypes.ENTITY.get().createNode().playersOnly(); + public CommandTreeNode.@NonNull Argument> node(final RegistryHolder holder) { + return CommandTreeNodeTypes.ENTITY.get(holder).createNode().playersOnly(); } private static final class MultiplePlayerSelectorImpl implements MultiplePlayerSelector { diff --git a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/NamedTextColorParser.java b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/NamedTextColorParser.java index 2d8646ee..f4ad3103 100644 --- a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/NamedTextColorParser.java +++ b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/NamedTextColorParser.java @@ -37,6 +37,7 @@ import org.incendo.cloud.suggestion.BlockingSuggestionProvider; import org.spongepowered.api.command.registrar.tree.CommandTreeNode; import org.spongepowered.api.command.registrar.tree.CommandTreeNodeTypes; +import org.spongepowered.api.registry.RegistryHolder; /** * An argument for parsing {@link NamedTextColor NamedTextColors}. @@ -77,8 +78,8 @@ public static ParserDescriptor namedTextColorParser() { } @Override - public CommandTreeNode.@NonNull Argument> node() { - return CommandTreeNodeTypes.COLOR.get().createNode(); + public CommandTreeNode.@NonNull Argument> node(final RegistryHolder holder) { + return CommandTreeNodeTypes.COLOR.get(holder).createNode(); } } diff --git a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/OperatorParser.java b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/OperatorParser.java index dca603d3..13e90194 100644 --- a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/OperatorParser.java +++ b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/OperatorParser.java @@ -38,6 +38,7 @@ import org.spongepowered.api.command.parameter.managed.operator.Operator; import org.spongepowered.api.command.registrar.tree.CommandTreeNode; import org.spongepowered.api.command.registrar.tree.CommandTreeNodeTypes; +import org.spongepowered.api.registry.RegistryHolder; import org.spongepowered.api.registry.RegistryTypes; /** @@ -98,8 +99,8 @@ public static ParserDescriptor operatorParser() { } @Override - public CommandTreeNode.@NonNull Argument> node() { - return CommandTreeNodeTypes.OPERATION.get().createNode(); + public CommandTreeNode.@NonNull Argument> node(final RegistryHolder holder) { + return CommandTreeNodeTypes.OPERATION.get(holder).createNode(); } } diff --git a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/ProtoItemStackParser.java b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/ProtoItemStackParser.java index d69b572b..62d0f05e 100644 --- a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/ProtoItemStackParser.java +++ b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/ProtoItemStackParser.java @@ -24,19 +24,15 @@ package org.incendo.cloud.sponge.parser; import com.mojang.brigadier.exceptions.CommandSyntaxException; -import java.lang.reflect.Field; -import java.util.Arrays; import java.util.concurrent.CompletableFuture; -import net.kyori.adventure.util.ComponentMessageThrowable; +import net.kyori.adventure.text.Component; +import net.minecraft.commands.CommandBuildContext; import net.minecraft.commands.arguments.item.ItemArgument; import net.minecraft.commands.arguments.item.ItemInput; -import net.minecraft.nbt.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.checker.nullness.qual.Nullable; import org.incendo.cloud.brigadier.parser.WrappedBrigadierParser; import org.incendo.cloud.context.CommandContext; import org.incendo.cloud.context.CommandInput; -import org.incendo.cloud.minecraft.modded.internal.ContextualArgumentTypeProvider; import org.incendo.cloud.parser.ArgumentParseResult; import org.incendo.cloud.parser.ArgumentParser; import org.incendo.cloud.parser.ParserDescriptor; @@ -47,11 +43,10 @@ import org.incendo.cloud.suggestion.SuggestionProvider; import org.spongepowered.api.command.registrar.tree.CommandTreeNode; import org.spongepowered.api.command.registrar.tree.CommandTreeNodeTypes; -import org.spongepowered.api.data.persistence.DataContainer; import org.spongepowered.api.item.ItemType; import org.spongepowered.api.item.inventory.ItemStack; import org.spongepowered.api.item.inventory.ItemStackSnapshot; -import org.spongepowered.common.data.persistence.NBTTranslator; +import org.spongepowered.api.registry.RegistryHolder; /** * An argument for parsing {@link ProtoItemStack ProtoItemStacks} from an {@link ItemType} identifier @@ -69,19 +64,24 @@ public final class ProtoItemStackParser implements NodeSource, ArgumentParser.FutureArgumentParser, SuggestionProvider { + private ProtoItemStackParser(final RegistryHolder registryHolder) { + //todo: Use ContextualArgumentTypeProvider + this.mappedParser = new WrappedBrigadierParser(ItemArgument.item((CommandBuildContext) registryHolder)) + .flatMapSuccess((ctx, itemInput) -> ArgumentParseResult.successFuture(new ProtoItemStackImpl(itemInput))); + } + /** * Creates a new {@link ProtoItemStackParser}. * * @param command sender type + * @param registryHolder register holder * @return new parser */ - public static ParserDescriptor protoItemStackParser() { - return ParserDescriptor.of(new ProtoItemStackParser<>(), ProtoItemStack.class); + public static ParserDescriptor protoItemStackParser(final RegistryHolder registryHolder) { + return ParserDescriptor.of(new ProtoItemStackParser<>(registryHolder), ProtoItemStack.class); } - private final ArgumentParser mappedParser = - new WrappedBrigadierParser(new ContextualArgumentTypeProvider<>(ItemArgument::item)) - .flatMapSuccess((ctx, itemInput) -> ArgumentParseResult.successFuture(new ProtoItemStackImpl(itemInput))); + private final ArgumentParser mappedParser; @Override public @NonNull CompletableFuture> parseFuture( @@ -100,34 +100,16 @@ public static ParserDescriptor protoItemStackParser() { } @Override - public CommandTreeNode.@NonNull Argument> node() { - return CommandTreeNodeTypes.ITEM_STACK.get().createNode(); + public CommandTreeNode.@NonNull Argument> node(final RegistryHolder holder) { + return CommandTreeNodeTypes.ITEM_STACK.get(holder).createNode(); } private static final class ProtoItemStackImpl implements ProtoItemStack { - // todo: use accessor - private static final Field COMPOUND_TAG_FIELD = - Arrays.stream(ItemInput.class.getDeclaredFields()) - .filter(f -> f.getType().equals(CompoundTag.class)) - .findFirst() - .orElseThrow(IllegalStateException::new); - - static { - COMPOUND_TAG_FIELD.setAccessible(true); - } - private final ItemInput itemInput; - private final @Nullable DataContainer extraData; ProtoItemStackImpl(final @NonNull ItemInput itemInput) { this.itemInput = itemInput; - try { - final CompoundTag tag = (CompoundTag) COMPOUND_TAG_FIELD.get(itemInput); - this.extraData = tag == null ? null : NBTTranslator.INSTANCE.translate(tag); - } catch (final IllegalAccessException ex) { - throw new RuntimeException(ex); - } } @Override @@ -135,11 +117,6 @@ private static final class ProtoItemStackImpl implements ProtoItemStack { return (ItemType) this.itemInput.getItem(); } - @Override - public @Nullable DataContainer extraData() { - return this.extraData; - } - @SuppressWarnings("ConstantConditions") @Override public @NonNull ItemStack createItemStack( @@ -149,7 +126,7 @@ private static final class ProtoItemStackImpl implements ProtoItemStack { try { return (ItemStack) (Object) this.itemInput.createItemStack(stackSize, respectMaximumStackSize); } catch (final CommandSyntaxException ex) { - throw new ComponentMessageRuntimeException(ComponentMessageThrowable.getMessage(ex), ex); + throw new ComponentMessageRuntimeException(Component.text(ex.getMessage())); } } @@ -158,7 +135,7 @@ private static final class ProtoItemStackImpl implements ProtoItemStack { final int stackSize, final boolean respectMaximumStackSize ) throws ComponentMessageRuntimeException { - return this.createItemStack(stackSize, respectMaximumStackSize).createSnapshot(); + return this.createItemStack(stackSize, respectMaximumStackSize).asImmutable(); } } diff --git a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/RegistryEntryParser.java b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/RegistryEntryParser.java index 3eb80252..638ac3f2 100644 --- a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/RegistryEntryParser.java +++ b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/RegistryEntryParser.java @@ -212,26 +212,26 @@ private Registry registry(final @NonNull CommandContext commandContext) { } @Override - public CommandTreeNode.@NonNull Argument> node() { + public CommandTreeNode.@NonNull Argument> node(final RegistryHolder holder) { if (this.registryType.equals(RegistryTypes.SOUND_TYPE)) { - return CommandTreeNodeTypes.RESOURCE_LOCATION.get().createNode() + return CommandTreeNodeTypes.RESOURCE_LOCATION.get(holder).createNode() .completions(CommandCompletionProviders.AVAILABLE_SOUNDS); //} else if (this.registryType.equals(RegistryTypes.BIOME)) { // return CommandTreeNodeTypes.RESOURCE_LOCATION.get().createNode() // .completions(CommandCompletionProviders.AVAILABLE_BIOMES); } else if (this.registryType.equals(RegistryTypes.ENTITY_TYPE)) { // return CommandTreeNodeTypes.ENTITY_SUMMON.get().createNode() - return CommandTreeNodeTypes.RESOURCE_LOCATION.get().createNode() + return CommandTreeNodeTypes.RESOURCE_LOCATION.get(holder).createNode() .completions(CommandCompletionProviders.SUMMONABLE_ENTITIES); //} else if (this.registryType.equals(RegistryTypes.ENCHANTMENT_TYPE)) { // return CommandTreeNodeTypes.ITEM_ENCHANTMENT.get().createNode(); //} else if (this.registryType.equals(RegistryTypes.POTION_EFFECT_TYPE)) { // return CommandTreeNodeTypes.MOB_EFFECT.get().createNode(); } else if (this.registryType.equals(RegistryTypes.WORLD_TYPE)) { - return CommandTreeNodeTypes.DIMENSION.get().createNode() + return CommandTreeNodeTypes.DIMENSION.get(holder).createNode() .customCompletions(); // Sponge adds custom types (?) } - return CommandTreeNodeTypes.RESOURCE_LOCATION.get().createNode().customCompletions(); + return CommandTreeNodeTypes.RESOURCE_LOCATION.get(holder).createNode().customCompletions(); } /** diff --git a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/ResourceKeyParser.java b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/ResourceKeyParser.java index 7723d478..c59d5ae3 100644 --- a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/ResourceKeyParser.java +++ b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/ResourceKeyParser.java @@ -33,6 +33,7 @@ import org.spongepowered.api.ResourceKey; import org.spongepowered.api.command.registrar.tree.CommandTreeNode; import org.spongepowered.api.command.registrar.tree.CommandTreeNodeTypes; +import org.spongepowered.api.registry.RegistryHolder; /** * Argument for parsing {@link ResourceKey ResourceKeys}. @@ -65,8 +66,8 @@ public static ParserDescriptor resourceKeyParser() { } @Override - public CommandTreeNode.@NonNull Argument> node() { - return CommandTreeNodeTypes.RESOURCE_LOCATION.get().createNode(); + public CommandTreeNode.@NonNull Argument> node(final RegistryHolder holder) { + return CommandTreeNodeTypes.RESOURCE_LOCATION.get(holder).createNode(); } } diff --git a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/SingleEntitySelectorParser.java b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/SingleEntitySelectorParser.java index 4ed76d7a..68a7c90f 100644 --- a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/SingleEntitySelectorParser.java +++ b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/SingleEntitySelectorParser.java @@ -44,6 +44,7 @@ import org.spongepowered.api.command.registrar.tree.CommandTreeNodeTypes; import org.spongepowered.api.command.selector.Selector; import org.spongepowered.api.entity.Entity; +import org.spongepowered.api.registry.RegistryHolder; /** * Argument for selecting a single {@link Entity} using a {@link Selector}. @@ -98,8 +99,8 @@ public static ParserDescriptor singleEntitySelector } @Override - public CommandTreeNode.@NonNull Argument> node() { - return CommandTreeNodeTypes.ENTITY.get().createNode().single(); + public CommandTreeNode.@NonNull Argument> node(final RegistryHolder holder) { + return CommandTreeNodeTypes.ENTITY.get(holder).createNode().single(); } private static final class SingleEntitySelectorImpl implements SingleEntitySelector { diff --git a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/SinglePlayerSelectorParser.java b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/SinglePlayerSelectorParser.java index 8ca517b1..d4015606 100644 --- a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/SinglePlayerSelectorParser.java +++ b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/SinglePlayerSelectorParser.java @@ -45,6 +45,7 @@ import org.spongepowered.api.command.selector.Selector; import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.entity.living.player.server.ServerPlayer; +import org.spongepowered.api.registry.RegistryHolder; /** * Argument for selecting a single {@link Player} using a {@link Selector}. @@ -100,8 +101,8 @@ public static ParserDescriptor singlePlayerSelector } @Override - public CommandTreeNode.@NonNull Argument> node() { - return CommandTreeNodeTypes.ENTITY.get().createNode().playersOnly().single(); + public CommandTreeNode.@NonNull Argument> node(final RegistryHolder holder) { + return CommandTreeNodeTypes.ENTITY.get(holder).createNode().playersOnly().single(); } diff --git a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/UserParser.java b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/UserParser.java index 6e480840..affb0f74 100644 --- a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/UserParser.java +++ b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/UserParser.java @@ -56,6 +56,7 @@ import org.spongepowered.api.entity.living.player.User; import org.spongepowered.api.entity.living.player.server.ServerPlayer; import org.spongepowered.api.profile.GameProfile; +import org.spongepowered.api.registry.RegistryHolder; import org.spongepowered.api.user.UserManager; /** @@ -166,8 +167,8 @@ public static ParserDescriptor userParser() { } @Override - public CommandTreeNode.@NonNull Argument> node() { - return CommandTreeNodeTypes.GAME_PROFILE.get().createNode().customCompletions(); + public CommandTreeNode.@NonNull Argument> node(final RegistryHolder holder) { + return CommandTreeNodeTypes.GAME_PROFILE.get(holder).createNode().customCompletions(); } /** diff --git a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/Vector2dParser.java b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/Vector2dParser.java index 95619dbc..e7d21866 100644 --- a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/Vector2dParser.java +++ b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/Vector2dParser.java @@ -39,6 +39,7 @@ import org.incendo.cloud.suggestion.Suggestion; import org.spongepowered.api.command.registrar.tree.CommandTreeNode; import org.spongepowered.api.command.registrar.tree.CommandTreeNodeTypes; +import org.spongepowered.api.registry.RegistryHolder; import org.spongepowered.math.vector.Vector2d; /** @@ -111,7 +112,7 @@ public Vector2dParser(final boolean centerIntegers) { } @Override - public CommandTreeNode.@NonNull Argument> node() { - return CommandTreeNodeTypes.VEC2.get().createNode(); + public CommandTreeNode.@NonNull Argument> node(final RegistryHolder holder) { + return CommandTreeNodeTypes.VEC2.get(holder).createNode(); } } diff --git a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/Vector2iParser.java b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/Vector2iParser.java index 89224a12..1b4b1ca5 100644 --- a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/Vector2iParser.java +++ b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/Vector2iParser.java @@ -41,6 +41,7 @@ import org.incendo.cloud.suggestion.SuggestionProvider; import org.spongepowered.api.command.registrar.tree.CommandTreeNode; import org.spongepowered.api.command.registrar.tree.CommandTreeNodeTypes; +import org.spongepowered.api.registry.RegistryHolder; import org.spongepowered.math.vector.Vector2i; /** @@ -95,8 +96,8 @@ public static ParserDescriptor vector2iParser() { } @Override - public CommandTreeNode.@NonNull Argument> node() { - return CommandTreeNodeTypes.COLUMN_POS.get().createNode(); + public CommandTreeNode.@NonNull Argument> node(final RegistryHolder holder) { + return CommandTreeNodeTypes.COLUMN_POS.get(holder).createNode(); } } diff --git a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/Vector3dParser.java b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/Vector3dParser.java index 0c7eff74..48b18109 100644 --- a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/Vector3dParser.java +++ b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/Vector3dParser.java @@ -38,6 +38,7 @@ import org.incendo.cloud.suggestion.Suggestion; import org.spongepowered.api.command.registrar.tree.CommandTreeNode; import org.spongepowered.api.command.registrar.tree.CommandTreeNodeTypes; +import org.spongepowered.api.registry.RegistryHolder; import org.spongepowered.common.util.VecHelper; import org.spongepowered.math.vector.Vector3d; @@ -111,8 +112,8 @@ public Vector3dParser(final boolean centerIntegers) { } @Override - public CommandTreeNode.@NonNull Argument> node() { - return CommandTreeNodeTypes.VEC3.get().createNode(); + public CommandTreeNode.@NonNull Argument> node(final RegistryHolder holder) { + return CommandTreeNodeTypes.VEC3.get(holder).createNode(); } } diff --git a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/Vector3iParser.java b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/Vector3iParser.java index 3bd5e6c2..dc5f3071 100644 --- a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/Vector3iParser.java +++ b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/Vector3iParser.java @@ -40,6 +40,7 @@ import org.incendo.cloud.suggestion.SuggestionProvider; import org.spongepowered.api.command.registrar.tree.CommandTreeNode; import org.spongepowered.api.command.registrar.tree.CommandTreeNodeTypes; +import org.spongepowered.api.registry.RegistryHolder; import org.spongepowered.common.util.VecHelper; import org.spongepowered.math.vector.Vector3i; @@ -93,8 +94,8 @@ public static ParserDescriptor vector3iParser() { } @Override - public CommandTreeNode.@NonNull Argument> node() { - return CommandTreeNodeTypes.BLOCK_POS.get().createNode(); + public CommandTreeNode.@NonNull Argument> node(final RegistryHolder holder) { + return CommandTreeNodeTypes.BLOCK_POS.get(holder).createNode(); } } diff --git a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/WorldParser.java b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/WorldParser.java index f6fc17e6..1de93668 100644 --- a/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/WorldParser.java +++ b/cloud-sponge/src/main/java/org/incendo/cloud/sponge/parser/WorldParser.java @@ -45,6 +45,7 @@ import org.spongepowered.api.Sponge; import org.spongepowered.api.command.registrar.tree.CommandTreeNode; import org.spongepowered.api.command.registrar.tree.CommandTreeNodeTypes; +import org.spongepowered.api.registry.RegistryHolder; import org.spongepowered.api.world.server.ServerWorld; import org.spongepowered.api.world.server.WorldManager; @@ -110,8 +111,8 @@ public static ParserDescriptor worldParser() { } @Override - public CommandTreeNode.@NonNull Argument> node() { - return CommandTreeNodeTypes.RESOURCE_LOCATION.get().createNode().customCompletions(); + public CommandTreeNode.@NonNull Argument> node(final RegistryHolder holder) { + return CommandTreeNodeTypes.RESOURCE_LOCATION.get(holder).createNode().customCompletions(); } } diff --git a/examples/example-sponge/build.gradle.kts b/examples/example-sponge/build.gradle.kts index e6419965..9def8d26 100644 --- a/examples/example-sponge/build.gradle.kts +++ b/examples/example-sponge/build.gradle.kts @@ -2,7 +2,7 @@ import org.spongepowered.gradle.plugin.config.PluginLoaders import org.spongepowered.plugin.metadata.model.PluginDependency plugins { - id("org.spongepowered.gradle.plugin") version "2.2.0" + id("org.spongepowered.gradle.plugin") version "2.3.1-SNAPSHOT" id("conventions.base") alias(libs.plugins.shadow) } @@ -14,7 +14,8 @@ dependencies { sponge { injectRepositories(false) - apiVersion("11.0.0-SNAPSHOT") + apiVersion("14.1.0-SNAPSHOT") + minecraftVersion("1.21.4") plugin("cloud-example-sponge") { loader { name(PluginLoaders.JAVA_PLAIN) @@ -23,7 +24,7 @@ sponge { displayName("Cloud example Sponge plugin") description("Plugin to demonstrate and test the Sponge implementation of cloud") license("MIT") - entrypoint("cloud.commandframework.examples.sponge.CloudExamplePlugin") + entrypoint("org.incendo.cloud.examples.sponge.CloudExamplePlugin") dependency("spongeapi") { loadOrder(PluginDependency.LoadOrder.AFTER) optional(false) @@ -35,24 +36,10 @@ tasks { assemble { dependsOn(shadowJar) } -} -configurations { - spongeRuntime { - resolutionStrategy { - cacheChangingModulesFor(1, "MINUTES") - eachDependency { - if (target.name == "spongevanilla") { - useVersion("1.20.+") - } - } + shadowJar { + dependencies { + exclude(dependency("io.leangen.geantyref:.*")) } } } - -afterEvaluate { - tasks.compileJava { - // TODO - sponge AP not compatible with J21 - options.compilerArgs.remove("-Werror") - } -} diff --git a/examples/example-sponge/src/main/java/org/incendo/cloud/examples/sponge/CloudExamplePlugin.java b/examples/example-sponge/src/main/java/org/incendo/cloud/examples/sponge/CloudExamplePlugin.java index 65ad974f..46876974 100644 --- a/examples/example-sponge/src/main/java/org/incendo/cloud/examples/sponge/CloudExamplePlugin.java +++ b/examples/example-sponge/src/main/java/org/incendo/cloud/examples/sponge/CloudExamplePlugin.java @@ -30,6 +30,7 @@ import io.leangen.geantyref.TypeToken; import java.util.List; import java.util.Optional; +import java.util.UUID; import java.util.function.Function; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; @@ -65,8 +66,9 @@ import org.spongepowered.api.entity.EntityType; import org.spongepowered.api.entity.EntityTypes; import org.spongepowered.api.entity.living.player.Player; -import org.spongepowered.api.entity.living.player.User; import org.spongepowered.api.entity.living.trader.Villager; +import org.spongepowered.api.event.Listener; +import org.spongepowered.api.event.lifecycle.RegisterCommandEvent; import org.spongepowered.api.item.enchantment.Enchantment; import org.spongepowered.api.item.enchantment.EnchantmentType; import org.spongepowered.api.item.inventory.ItemStack; @@ -146,11 +148,14 @@ public CloudExamplePlugin(final @NonNull Injector injector) { .defaultHandlers() .decorator(message -> Component.text().append(COMMAND_PREFIX, space(), message).build()) .registerTo(this.commandManager); + } - this.registerCommands(); + @Listener + public void onRegisterCommands(final RegisterCommandEvent event) { + this.registerCommands(event.registryHolder()); } - private void registerCommands() { + private void registerCommands(RegistryHolder registryHolder) { this.commandManager.command(this.commandManager.commandBuilder("cloud_test1") .permission("cloud.test1") .handler(ctx -> ctx.sender().audience().sendMessage(text("success")))); @@ -198,7 +203,7 @@ private void registerCommands() { return; } final ItemStack modified = ItemStack.builder() - .fromItemStack(result.polledItem().createStack()) + .fromItemStack(result.polledItem().asMutable()) .add(Keys.APPLIED_ENCHANTMENTS, List.of( Enchantment.of( ctx.get("enchantment_type"), @@ -283,9 +288,9 @@ private void registerCommands() { ctx.sender().audience().sendMessage(text(ctx.get("world").key().asString())); })); this.commandManager.command(cloud.literal("test_item") - .required("item", protoItemStackParser()) + .required("item", protoItemStackParser(registryHolder)) .literal("is") - .required("predicate", itemStackPredicateParser()) + .required("predicate", itemStackPredicateParser(registryHolder)) .handler(ctx -> { final ItemStack item = ctx.get("item").createItemStack(1, true); final ItemStackPredicate predicate = ctx.get("predicate"); @@ -367,7 +372,7 @@ private void registerCommands() { this.commandManager.command(cloud.literal("user") .required("user", userParser()) .handler(ctx -> { - ctx.sender().audience().sendMessage(text(ctx.get("user").toString())); + ctx.sender().audience().sendMessage(text(ctx.get("user").toString())); })); this.commandManager.command(cloud.literal("data") .required("data", dataContainerParser()) @@ -377,7 +382,7 @@ private void registerCommands() { this.commandManager.command(cloud.literal("setblock") .permission("cloud.setblock") .required("position", vector3iParser()) - .required("block", blockInputParser()) + .required("block", blockInputParser(registryHolder)) .handler(ctx -> { final Vector3i position = ctx.get("position"); final BlockInput input = ctx.get("block"); @@ -391,7 +396,7 @@ private void registerCommands() { } })); this.commandManager.command(cloud.literal("blockinput") - .required("block", blockInputParser()) + .required("block", blockInputParser(registryHolder)) .handler(ctx -> { final BlockInput input = ctx.get("block"); ctx.sender().audience().sendMessage(text( @@ -404,7 +409,7 @@ private void registerCommands() { .requiredArgumentPair( "itemstack", TypeToken.get(ItemStack.class), - "item", protoItemStackParser(), + "item", protoItemStackParser(registryHolder), "amount", integerParser(), (sender, proto, amount) -> { try { @@ -424,9 +429,9 @@ private void registerCommands() { // todo: cause.cause().root() returns DedicatedServer during permission checks? return cause.subject() instanceof Player; })) - .required("predicate", blockPredicateParser()) + .required("predicate", blockPredicateParser(registryHolder)) .required("radius", integerParser()) - .required("replacement", blockInputParser()) + .required("replacement", blockInputParser(registryHolder)) .handler(ctx -> { final BlockPredicate predicate = ctx.get("predicate"); final int radius = ctx.get("radius");