From b51bc94b8d01a1094fdeaf48e9a00fa56a2e0274 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Wed, 17 Jan 2024 20:11:01 -0700 Subject: [PATCH] Add method for ItemInput parser and fix ResourceLocationParser name --- .../fabric/testmod/FabricExample.java | 318 +++++++++--------- ...ument.java => ResourceLocationParser.java} | 6 +- .../modded/parser/VanillaArgumentParsers.java | 12 + 3 files changed, 175 insertions(+), 161 deletions(-) rename cloud-minecraft-modded-common/src/main/java/cloud/commandframework/minecraft/modded/parser/{ResourceLocationArgument.java => ResourceLocationParser.java} (91%) diff --git a/cloud-fabric/src/testmod/java/cloud/commandframework/fabric/testmod/FabricExample.java b/cloud-fabric/src/testmod/java/cloud/commandframework/fabric/testmod/FabricExample.java index 4e90da7c..20f3c340 100644 --- a/cloud-fabric/src/testmod/java/cloud/commandframework/fabric/testmod/FabricExample.java +++ b/cloud-fabric/src/testmod/java/cloud/commandframework/fabric/testmod/FabricExample.java @@ -40,7 +40,6 @@ import cloud.commandframework.minecraft.modded.data.MultiplePlayerSelector; import cloud.commandframework.minecraft.modded.parser.NamedColorParser; import cloud.commandframework.minecraft.modded.parser.RegistryEntryParser; -import cloud.commandframework.minecraft.modded.parser.VanillaArgumentParsers; import com.mojang.brigadier.exceptions.CommandSyntaxException; import java.util.Collection; import java.util.Comparator; @@ -53,7 +52,6 @@ import net.fabricmc.loader.api.metadata.Person; import net.minecraft.ChatFormatting; import net.minecraft.commands.CommandSourceStack; -import net.minecraft.commands.arguments.item.ItemArgument; import net.minecraft.commands.arguments.item.ItemInput; import net.minecraft.core.registries.Registries; import net.minecraft.network.chat.ClickEvent; @@ -69,6 +67,10 @@ import static cloud.commandframework.arguments.standard.IntegerParser.integerParser; import static cloud.commandframework.arguments.standard.StringParser.stringParser; +import static cloud.commandframework.minecraft.modded.parser.VanillaArgumentParsers.columnPosParser; +import static cloud.commandframework.minecraft.modded.parser.VanillaArgumentParsers.itemInput; +import static cloud.commandframework.minecraft.modded.parser.VanillaArgumentParsers.multiplePlayerSelectorParser; +import static cloud.commandframework.minecraft.modded.parser.VanillaArgumentParsers.vec3Parser; public final class FabricExample implements ModInitializer { @@ -76,7 +78,7 @@ public final class FabricExample implements ModInitializer { public void onInitialize() { // Create a commands manager. We'll use native command source types for this. final FabricServerCommandManager manager = - FabricServerCommandManager.createNative(ExecutionCoordinator.simpleCoordinator()); + FabricServerCommandManager.createNative(ExecutionCoordinator.simpleCoordinator()); final Command.Builder base = manager.commandBuilder("cloudtest"); @@ -84,114 +86,114 @@ public void onInitialize() { final CloudKey hugs = CloudKey.of("hugs", Integer.class); manager.command(base - .literal("hugs") - .required(name, stringParser()) - .optional(hugs, integerParser(), DefaultValue.constant(1)) - .handler(ctx -> { - ctx.sender().sendSuccess(() -> Component.literal("Hello, ") - .append(ctx.get(name)) - .append(", hope you're doing well!") - .withStyle(style -> style.withColor(TextColor.fromRgb(0xAA22BB))), false); + .literal("hugs") + .required(name, stringParser()) + .optional(hugs, integerParser(), DefaultValue.constant(1)) + .handler(ctx -> { + ctx.sender().sendSuccess(() -> Component.literal("Hello, ") + .append(ctx.get(name)) + .append(", hope you're doing well!") + .withStyle(style -> style.withColor(TextColor.fromRgb(0xAA22BB))), false); - ctx.sender().sendSuccess(() -> Component.literal("Cloud would like to give you ") - .append(Component.literal(String.valueOf(ctx.get(hugs))) - .withStyle(style -> style.withColor(TextColor.fromRgb(0xFAB3DA)))) - .append(" hug(s) <3") - .withStyle(style -> style.withBold(true)), false); - })); + ctx.sender().sendSuccess(() -> Component.literal("Cloud would like to give you ") + .append(Component.literal(String.valueOf(ctx.get(hugs))) + .withStyle(style -> style.withColor(TextColor.fromRgb(0xFAB3DA)))) + .append(" hug(s) <3") + .withStyle(style -> style.withBold(true)), false); + })); final ParserDescriptor biomeArgument = RegistryEntryParser.registryEntryParser( - Registries.BIOME, - Biome.class + Registries.BIOME, + Biome.class ); manager.command(base - .literal("land") - .required("biome", biomeArgument) - .handler(ctx -> { - ctx.sender().sendSuccess(() -> Component.literal("Yes, the biome ") - .append(Component.literal( - ctx.sender().registryAccess() - .registryOrThrow(Registries.BIOME) - .getKey(ctx.get("biome")).toString()) - .withStyle(ChatFormatting.DARK_PURPLE, ChatFormatting.BOLD)) - .append(Component.literal(" is pretty cool")) - .withStyle(style -> style.withColor(0x884433)), false); - }) + .literal("land") + .required("biome", biomeArgument) + .handler(ctx -> { + ctx.sender().sendSuccess(() -> Component.literal("Yes, the biome ") + .append(Component.literal( + ctx.sender().registryAccess() + .registryOrThrow(Registries.BIOME) + .getKey(ctx.get("biome")).toString()) + .withStyle(ChatFormatting.DARK_PURPLE, ChatFormatting.BOLD)) + .append(Component.literal(" is pretty cool")) + .withStyle(style -> style.withColor(0x884433)), false); + }) ); final CloudKey playersKey = CloudKey.of("players", MultiplePlayerSelector.class); final CloudKey textColorKey = CloudKey.of("color", ChatFormatting.class); manager.command(base.literal("wave") - .required(playersKey, VanillaArgumentParsers.multiplePlayerSelectorParser()) - .required(textColorKey, NamedColorParser.namedColorParser()) - .handler(ctx -> { - final MultiplePlayerSelector selector = ctx.get(playersKey); - final Collection selected = selector.values(); - selected.forEach(selectedPlayer -> - selectedPlayer.sendSystemMessage( - Component.literal("Wave from ") - .withStyle(style -> style.withColor(ctx.get(textColorKey))) - .append(ctx.sender().getDisplayName()) - )); - ctx.sender().sendSuccess( - () -> Component.literal(String.format("Waved at %d players (%s)", selected.size(), - selector.inputString() - )), - false - ); - })); + .required(playersKey, multiplePlayerSelectorParser()) + .required(textColorKey, NamedColorParser.namedColorParser()) + .handler(ctx -> { + final MultiplePlayerSelector selector = ctx.get(playersKey); + final Collection selected = selector.values(); + selected.forEach(selectedPlayer -> + selectedPlayer.sendSystemMessage( + Component.literal("Wave from ") + .withStyle(style -> style.withColor(ctx.get(textColorKey))) + .append(ctx.sender().getDisplayName()) + )); + ctx.sender().sendSuccess( + () -> Component.literal(String.format("Waved at %d players (%s)", selected.size(), + selector.inputString() + )), + false + ); + })); manager.command(base.literal("give") - .permission("cloud.give") - .required("targets", VanillaArgumentParsers.multiplePlayerSelectorParser()) - .required("item", VanillaArgumentParsers.contextualParser(ItemArgument::item, ItemInput.class)) - .optional("amount", integerParser(1), DefaultValue.constant(1)) - .handler(ctx -> { - final ItemInput item = ctx.get("item"); - final MultiplePlayerSelector targets = ctx.get("targets"); - final int amount = ctx.get("amount"); - GiveCommandAccess.giveItem( - ctx.sender(), - item, - targets.values(), - amount - ); - })); + .permission("cloud.give") + .required("targets", multiplePlayerSelectorParser()) + .required("item", itemInput()) + .optional("amount", integerParser(1), DefaultValue.constant(1)) + .handler(ctx -> { + final ItemInput item = ctx.get("item"); + final MultiplePlayerSelector targets = ctx.get("targets"); + final int amount = ctx.get("amount"); + GiveCommandAccess.giveItem( + ctx.sender(), + item, + targets.values(), + amount + ); + })); final Command.Builder mods = base.literal("mods").permission("cloud.mods"); manager.command(mods.handler(ctx -> { final List modList = FabricLoader.getInstance().getAllMods().stream() - .map(ModContainer::getMetadata) - .sorted(Comparator.comparing(ModMetadata::getId)) - .toList(); + .map(ModContainer::getMetadata) + .sorted(Comparator.comparing(ModMetadata::getId)) + .toList(); final MutableComponent text = Component.literal(""); text.append(Component.literal("Loaded Mods") - .withStyle(style -> style.withColor(ChatFormatting.BLUE).applyFormat(ChatFormatting.BOLD))); + .withStyle(style -> style.withColor(ChatFormatting.BLUE).applyFormat(ChatFormatting.BOLD))); text.append(Component.literal(String.format(" (%s)\n", modList.size())) - .withStyle(style -> style.withColor(ChatFormatting.GRAY).applyFormat(ChatFormatting.ITALIC))); + .withStyle(style -> style.withColor(ChatFormatting.GRAY).applyFormat(ChatFormatting.ITALIC))); for (final ModMetadata mod : modList) { text.append( - Component.literal("") - .withStyle(style -> style.withColor(ChatFormatting.WHITE) - .withClickEvent(new ClickEvent( - ClickEvent.Action.SUGGEST_COMMAND, - String.format("/cloudtest mods %s", mod.getId()) - )) - .withHoverEvent(new HoverEvent( - HoverEvent.Action.SHOW_TEXT, - Component.literal("Click for more info") - ))) - .append(Component - .literal(mod.getName()) - .withStyle(style -> style.withColor(ChatFormatting.GREEN))) - .append(Component.literal(String.format(" (%s) ", mod.getId())) - .withStyle(style -> style - .withColor(ChatFormatting.GRAY) - .applyFormat(ChatFormatting.ITALIC))) - .append(Component.literal(String.format("v%s", mod.getVersion()))) + Component.literal("") + .withStyle(style -> style.withColor(ChatFormatting.WHITE) + .withClickEvent(new ClickEvent( + ClickEvent.Action.SUGGEST_COMMAND, + String.format("/cloudtest mods %s", mod.getId()) + )) + .withHoverEvent(new HoverEvent( + HoverEvent.Action.SHOW_TEXT, + Component.literal("Click for more info") + ))) + .append(Component + .literal(mod.getName()) + .withStyle(style -> style.withColor(ChatFormatting.GREEN))) + .append(Component.literal(String.format(" (%s) ", mod.getId())) + .withStyle(style -> style + .withColor(ChatFormatting.GRAY) + .applyFormat(ChatFormatting.ITALIC))) + .append(Component.literal(String.format("v%s", mod.getVersion()))) ); if (modList.indexOf(mod) != modList.size() - 1) { text.append(Component.literal(", ").withStyle(style -> style.withColor(ChatFormatting.GRAY))); @@ -201,83 +203,83 @@ public void onInitialize() { })); final TypedCommandComponent modMetadata = manager.componentBuilder( - ModMetadata.class, - "mod" - ) - .suggestionProvider(SuggestionProvider.blocking((ctx, input) -> FabricLoader - .getInstance() - .getAllMods() - .stream() - .map(ModContainer::getMetadata) - .map(ModMetadata::getId) - .map(Suggestion::simple) - .collect(Collectors.toList()))) - .parser((commandContext, commandInput) -> { - final ModMetadata meta = FabricLoader.getInstance().getModContainer(commandInput.readString()) - .map(ModContainer::getMetadata) - .orElse(null); - if (meta != null) { - return ArgumentParseResult.success(meta); - } - return ArgumentParseResult.failure(new IllegalArgumentException(String.format( - "No mod with id '%s'", - commandInput.peek() - ))); - }) - .build(); + ModMetadata.class, + "mod" + ) + .suggestionProvider(SuggestionProvider.blocking((ctx, input) -> FabricLoader + .getInstance() + .getAllMods() + .stream() + .map(ModContainer::getMetadata) + .map(ModMetadata::getId) + .map(Suggestion::simple) + .collect(Collectors.toList()))) + .parser((commandContext, commandInput) -> { + final ModMetadata meta = FabricLoader.getInstance().getModContainer(commandInput.readString()) + .map(ModContainer::getMetadata) + .orElse(null); + if (meta != null) { + return ArgumentParseResult.success(meta); + } + return ArgumentParseResult.failure(new IllegalArgumentException(String.format( + "No mod with id '%s'", + commandInput.peek() + ))); + }) + .build(); manager.command(mods.argument(modMetadata) - .handler(ctx -> { - final ModMetadata meta = ctx.get(modMetadata); - final MutableComponent text = Component.literal("") - .append(Component.literal(meta.getName()) - .withStyle(style -> style.withColor(ChatFormatting.BLUE).applyFormat(ChatFormatting.BOLD))) - .append(Component.literal("\n modid: " + meta.getId())) - .append(Component.literal("\n version: " + meta.getVersion())) - .append(Component.literal("\n type: " + meta.getType())); + .handler(ctx -> { + final ModMetadata meta = ctx.get(modMetadata); + final MutableComponent text = Component.literal("") + .append(Component.literal(meta.getName()) + .withStyle(style -> style.withColor(ChatFormatting.BLUE).applyFormat(ChatFormatting.BOLD))) + .append(Component.literal("\n modid: " + meta.getId())) + .append(Component.literal("\n version: " + meta.getVersion())) + .append(Component.literal("\n type: " + meta.getType())); - if (!meta.getDescription().isEmpty()) { - text.append(Component.literal("\n description: " + meta.getDescription())); - } - if (!meta.getAuthors().isEmpty()) { - text.append(Component.literal("\n authors: " + meta.getAuthors().stream() - .map(Person::getName) - .collect(Collectors.joining(", ")))); - } - if (!meta.getLicense().isEmpty()) { - text.append(Component.literal("\n license: " + String.join(", ", meta.getLicense()))); - } - ctx.sender().sendSuccess( - () -> text, - false - ); - })); + if (!meta.getDescription().isEmpty()) { + text.append(Component.literal("\n description: " + meta.getDescription())); + } + if (!meta.getAuthors().isEmpty()) { + text.append(Component.literal("\n authors: " + meta.getAuthors().stream() + .map(Person::getName) + .collect(Collectors.joining(", ")))); + } + if (!meta.getLicense().isEmpty()) { + text.append(Component.literal("\n license: " + String.join(", ", meta.getLicense()))); + } + ctx.sender().sendSuccess( + () -> text, + false + ); + })); manager.command(base.literal("teleport") - .permission("cloud.teleport") - .required("targets", VanillaArgumentParsers.multiplePlayerSelectorParser()) - .required("location", VanillaArgumentParsers.vec3Parser(false)) - .handler(ctx -> { - final MultipleEntitySelector selector = ctx.get("targets"); - final Vec3 location = ctx.get("location").position(); - selector.values().forEach(target -> - target.teleportToWithTicket(location.x(), location.y(), location.z())); - })); + .permission("cloud.teleport") + .required("targets", multiplePlayerSelectorParser()) + .required("location", vec3Parser(false)) + .handler(ctx -> { + final MultipleEntitySelector selector = ctx.get("targets"); + final Vec3 location = ctx.get("location").position(); + selector.values().forEach(target -> + target.teleportToWithTicket(location.x(), location.y(), location.z())); + })); manager.command(base.literal("gotochunk") - .permission("cloud.gotochunk") - .required("chunk_position", VanillaArgumentParsers.columnPosParser()) - .handler(ctx -> { - final ServerPlayer player; - try { - player = ctx.sender().getPlayerOrException(); - } catch (final CommandSyntaxException e) { - ctx.sender().sendSuccess(() -> ComponentUtils.fromMessage(e.getRawMessage()), false); - return; - } - final Vec3 vec = ctx.get("chunk_position").position(); - final ChunkPos pos = new ChunkPos((int) vec.x(), (int) vec.z()); - player.teleportToWithTicket(pos.getMinBlockX(), 128, pos.getMinBlockZ()); - })); + .permission("cloud.gotochunk") + .required("chunk_position", columnPosParser()) + .handler(ctx -> { + final ServerPlayer player; + try { + player = ctx.sender().getPlayerOrException(); + } catch (final CommandSyntaxException e) { + ctx.sender().sendSuccess(() -> ComponentUtils.fromMessage(e.getRawMessage()), false); + return; + } + final Vec3 vec = ctx.get("chunk_position").position(); + final ChunkPos pos = new ChunkPos((int) vec.x(), (int) vec.z()); + player.teleportToWithTicket(pos.getMinBlockX(), 128, pos.getMinBlockZ()); + })); } } diff --git a/cloud-minecraft-modded-common/src/main/java/cloud/commandframework/minecraft/modded/parser/ResourceLocationArgument.java b/cloud-minecraft-modded-common/src/main/java/cloud/commandframework/minecraft/modded/parser/ResourceLocationParser.java similarity index 91% rename from cloud-minecraft-modded-common/src/main/java/cloud/commandframework/minecraft/modded/parser/ResourceLocationArgument.java rename to cloud-minecraft-modded-common/src/main/java/cloud/commandframework/minecraft/modded/parser/ResourceLocationParser.java index 377f9e45..2ac3e3c4 100644 --- a/cloud-minecraft-modded-common/src/main/java/cloud/commandframework/minecraft/modded/parser/ResourceLocationArgument.java +++ b/cloud-minecraft-modded-common/src/main/java/cloud/commandframework/minecraft/modded/parser/ResourceLocationParser.java @@ -34,7 +34,7 @@ * * @param the sender type */ -public final class ResourceLocationArgument extends WrappedBrigadierParser { +public final class ResourceLocationParser extends WrappedBrigadierParser { /** * Creates a new resource location parser. @@ -43,7 +43,7 @@ public final class ResourceLocationArgument extends WrappedBrigadierParser @NonNull ParserDescriptor resourceLocationParser() { - return ParserDescriptor.of(new ResourceLocationArgument<>(), ResourceLocation.class); + return ParserDescriptor.of(new ResourceLocationParser<>(), ResourceLocation.class); } /** @@ -56,7 +56,7 @@ public final class ResourceLocationArgument extends WrappedBrigadierParserbuilder().parser(resourceLocationParser()); } - ResourceLocationArgument() { + ResourceLocationParser() { super(net.minecraft.commands.arguments.ResourceLocationArgument.id()); } diff --git a/cloud-minecraft-modded-common/src/main/java/cloud/commandframework/minecraft/modded/parser/VanillaArgumentParsers.java b/cloud-minecraft-modded-common/src/main/java/cloud/commandframework/minecraft/modded/parser/VanillaArgumentParsers.java index f0898f08..07aeffbc 100644 --- a/cloud-minecraft-modded-common/src/main/java/cloud/commandframework/minecraft/modded/parser/VanillaArgumentParsers.java +++ b/cloud-minecraft-modded-common/src/main/java/cloud/commandframework/minecraft/modded/parser/VanillaArgumentParsers.java @@ -57,6 +57,8 @@ import net.minecraft.commands.arguments.coordinates.ColumnPosArgument; import net.minecraft.commands.arguments.coordinates.Vec2Argument; import net.minecraft.commands.arguments.coordinates.Vec3Argument; +import net.minecraft.commands.arguments.item.ItemArgument; +import net.minecraft.commands.arguments.item.ItemInput; import net.minecraft.commands.arguments.selector.EntitySelector; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; @@ -90,6 +92,16 @@ private VanillaArgumentParsers() { return ParserDescriptor.of(new WrappedBrigadierParser<>(new ContextualArgumentTypeProvider<>(factory)), valueType); } + /** + * A parser for {@link ItemInput}. + * + * @param command sender type + * @return the parser + */ + public static @NonNull ParserDescriptor itemInput() { + return contextualParser(ItemArgument::item, ItemInput.class); + } + /** * A parser for in-game time, in ticks. *