From 07cae4554a3facaf31e57dd0e0ca94187c4c1bb4 Mon Sep 17 00:00:00 2001 From: Bdogs15 Date: Mon, 28 Oct 2019 16:25:51 -0500 Subject: [PATCH] Modified String Arg for commands commands never checked if the slot provided existed. even if the slot didnt exist the player would get a message that the slot has been modified(via set/remove/add cmds) --- .../java/top/theillusivec4/curios/Curios.java | 4 +- .../common/{ => command}/CommandCurios.java | 43 ++++---- .../common/command/CuriosStringArgType.java | 101 ++++++++++++++++++ .../resources/assets/curios/lang/en_us.json | 1 + 4 files changed, 126 insertions(+), 23 deletions(-) rename src/main/java/top/theillusivec4/curios/common/{ => command}/CommandCurios.java (85%) create mode 100644 src/main/java/top/theillusivec4/curios/common/command/CuriosStringArgType.java diff --git a/src/main/java/top/theillusivec4/curios/Curios.java b/src/main/java/top/theillusivec4/curios/Curios.java index 3cdfc78b..cab69da7 100644 --- a/src/main/java/top/theillusivec4/curios/Curios.java +++ b/src/main/java/top/theillusivec4/curios/Curios.java @@ -49,7 +49,7 @@ import top.theillusivec4.curios.client.gui.CuriosScreen; import top.theillusivec4.curios.client.gui.GuiEventHandler; import top.theillusivec4.curios.client.render.CuriosLayer; -import top.theillusivec4.curios.common.CommandCurios; +import top.theillusivec4.curios.common.command.CommandCurios; import top.theillusivec4.curios.common.CuriosConfig; import top.theillusivec4.curios.common.CuriosIMC; import top.theillusivec4.curios.common.CuriosRegistry; @@ -116,7 +116,7 @@ private void enqueue(InterModEnqueueEvent evt) { send(CuriosAPI.IMC.REGISTER_ICON, new Tuple<>(icon, new ResourceLocation(MODID, "textures/item/empty_" + icon + "_slot.png"))); } - } +} private void process(InterModProcessEvent evt) { diff --git a/src/main/java/top/theillusivec4/curios/common/CommandCurios.java b/src/main/java/top/theillusivec4/curios/common/command/CommandCurios.java similarity index 85% rename from src/main/java/top/theillusivec4/curios/common/CommandCurios.java rename to src/main/java/top/theillusivec4/curios/common/command/CommandCurios.java index a4fdd3fc..d34a6618 100644 --- a/src/main/java/top/theillusivec4/curios/common/CommandCurios.java +++ b/src/main/java/top/theillusivec4/curios/common/command/CommandCurios.java @@ -17,13 +17,12 @@ * License along with Curios. If not, see . */ -package top.theillusivec4.curios.common; +package top.theillusivec4.curios.common.command; import com.google.common.collect.Maps; import com.mojang.brigadier.Command; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.arguments.IntegerArgumentType; -import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import java.util.SortedMap; import net.minecraft.command.CommandSource; @@ -51,75 +50,75 @@ public static void register(CommandDispatcher dispatcher) { .requires(player -> player.hasPermissionLevel(opPermissionLevel)); curiosCommand.then(Commands.literal("set") - .then(Commands.argument("slot", StringArgumentType.string()) + .then(Commands.argument("slot", CuriosStringArgType.string()) .suggests((ctx, builder) -> ISuggestionProvider .suggest(CuriosAPI.getTypeIdentifiers(), builder)) .then(Commands.argument("player", EntityArgument.player()) .executes(context -> setSlotsOfPlayer(context.getSource(), EntityArgument.getPlayer(context, "player"), - StringArgumentType.getString(context, "slot"), 1)) + CuriosStringArgType.getString(context, "slot"), 1)) .then(Commands.argument("amount", IntegerArgumentType.integer()) .executes(context -> setSlotsOfPlayer(context.getSource(), EntityArgument.getPlayer(context, "player"), - StringArgumentType.getString(context, "slot"), + CuriosStringArgType.getString(context, "slot"), IntegerArgumentType.getInteger(context, "amount"))))))); curiosCommand.then(Commands.literal("add") - .then(Commands.argument("slot", StringArgumentType.string()) + .then(Commands.argument("slot", CuriosStringArgType.string()) .suggests((ctx, builder) -> ISuggestionProvider .suggest(CuriosAPI.getTypeIdentifiers(), builder)) .then(Commands.argument("player", EntityArgument.player()) .executes(context -> addSlotToPlayer(context.getSource(), EntityArgument.getPlayer(context, "player"), - StringArgumentType.getString(context, "slot"), 1)) + CuriosStringArgType.getString(context, "slot"), 1)) .then(Commands.argument("amount", IntegerArgumentType.integer()) .executes(context -> addSlotToPlayer(context.getSource(), EntityArgument.getPlayer(context, "player"), - StringArgumentType.getString(context, "slot"), + CuriosStringArgType.getString(context, "slot"), IntegerArgumentType.getInteger(context, "amount"))))))); curiosCommand.then(Commands.literal("remove") - .then(Commands.argument("slot", StringArgumentType.string()) + .then(Commands.argument("slot", CuriosStringArgType.string()) .suggests((ctx, builder) -> ISuggestionProvider .suggest(CuriosAPI.getTypeIdentifiers(), builder)) .then(Commands.argument("player", EntityArgument.player()) .executes(context -> removeSlotFromPlayer(context.getSource(), EntityArgument.getPlayer(context, "player"), - StringArgumentType.getString(context, "slot"), 1)) + CuriosStringArgType.getString(context, "slot"), 1)) .then(Commands.argument("amount", IntegerArgumentType.integer()) .executes(context -> removeSlotFromPlayer(context.getSource(), EntityArgument.getPlayer(context, "player"), - StringArgumentType.getString(context, "slot"), + CuriosStringArgType.getString(context, "slot"), IntegerArgumentType.getInteger(context, "amount"))))))); curiosCommand.then(Commands.literal("enable") - .then(Commands.argument("slot", StringArgumentType.string()) + .then(Commands.argument("slot", CuriosStringArgType.string()) .suggests((ctx, builder) -> ISuggestionProvider .suggest(CuriosAPI.getTypeIdentifiers(), builder)) .then(Commands.argument("player", EntityArgument.player()) .executes(context -> enableSlotForPlayer(context.getSource(), EntityArgument.getPlayer(context, "player"), - StringArgumentType.getString(context, "slot")))))); + CuriosStringArgType.getString(context, "slot")))))); curiosCommand.then(Commands.literal("disable") - .then(Commands.argument("slot", StringArgumentType.string()) + .then(Commands.argument("slot", CuriosStringArgType.string()) .suggests((ctx, builder) -> ISuggestionProvider .suggest(CuriosAPI.getTypeIdentifiers(), builder)) .then(Commands.argument("player", EntityArgument.player()) .executes(context -> disableSlotForPlayer(context.getSource(), EntityArgument.getPlayer(context, "player"), - StringArgumentType.getString(context, "slot")))))); + CuriosStringArgType.getString(context, "slot")))))); curiosCommand.then(Commands.literal("clear") .then(Commands.argument("player", EntityArgument.player()) .executes(context -> clearSlotsForPlayer(context.getSource(), EntityArgument.getPlayer(context, "player"), "")) - .then(Commands.argument("slot", StringArgumentType.string()) + .then(Commands.argument("slot", CuriosStringArgType.string()) .suggests((ctx, builder) -> ISuggestionProvider .suggest(CuriosAPI.getTypeIdentifiers(), builder)) .executes(context -> clearSlotsForPlayer(context.getSource(), EntityArgument.getPlayer(context, "player"), - StringArgumentType.getString(context, "slot")))))); + CuriosStringArgType.getString(context, "slot")))))); curiosCommand.then(Commands.literal("reset") .then(Commands.argument("player", EntityArgument.player()) @@ -131,10 +130,10 @@ public static void register(CommandDispatcher dispatcher) { private static int setSlotsOfPlayer(CommandSource source, ServerPlayerEntity playerMP, String slot, int amount) { - CuriosAPI.setSlotsForType(slot, playerMP, amount); - source.sendFeedback(new TranslationTextComponent("commands.curios.set.success", slot, CuriosAPI.getSlotsForType(playerMP, slot), - playerMP.getDisplayName()), true); - return Command.SINGLE_SUCCESS; + CuriosAPI.setSlotsForType(slot, playerMP, amount); + source.sendFeedback(new TranslationTextComponent("commands.curios.set.success", slot, CuriosAPI.getSlotsForType(playerMP, slot), + playerMP.getDisplayName()), true); + return Command.SINGLE_SUCCESS; } private static int addSlotToPlayer(CommandSource source, ServerPlayerEntity playerMP, String slot, @@ -218,6 +217,8 @@ private static int resetSlotsForPlayer(CommandSource source, ServerPlayerEntity return Command.SINGLE_SUCCESS; } + private static boolean doesSlotExist(String identifier) { return CuriosAPI.getTypeIdentifiers().contains(identifier); } + private static void clear(CurioStackHandler stacks) { for (int i = 0; i < stacks.getSlots(); i++) { diff --git a/src/main/java/top/theillusivec4/curios/common/command/CuriosStringArgType.java b/src/main/java/top/theillusivec4/curios/common/command/CuriosStringArgType.java new file mode 100644 index 00000000..84153fe0 --- /dev/null +++ b/src/main/java/top/theillusivec4/curios/common/command/CuriosStringArgType.java @@ -0,0 +1,101 @@ +package top.theillusivec4.curios.common.command; + +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; +import net.minecraft.util.text.TranslationTextComponent; +import top.theillusivec4.curios.api.CuriosAPI; + +import java.util.Arrays; +import java.util.Collection; + +public class CuriosStringArgType implements ArgumentType +{ + public static final SimpleCommandExceptionType SLOT_NOT_EXIST = new SimpleCommandExceptionType(new TranslationTextComponent("arguments.curios.slot_not_exist")); + private final StringType type; + + private CuriosStringArgType(final StringType type) { + this.type = type; + } + + public static CuriosStringArgType string() { + return new CuriosStringArgType(StringType.QUOTABLE_PHRASE); + } + + public static String getString(final CommandContext context, final String name) throws CommandSyntaxException + { + String val = context.getArgument(name, String.class); + if(!CuriosAPI.getTypeIdentifiers().contains(val)) + throw SLOT_NOT_EXIST.create(); + return val; + } + + public StringType getType() { + return type; + } + + @Override + public String parse(final StringReader reader) throws CommandSyntaxException { + if (type == StringType.GREEDY_PHRASE) { + final String text = reader.getRemaining(); + reader.setCursor(reader.getTotalLength()); + return text; + } else if (type == StringType.SINGLE_WORD) { + return reader.readUnquotedString(); + } else { + return reader.readString(); + } + } + + @Override + public String toString() { + return "string()"; + } + + @Override + public Collection getExamples() { + return type.getExamples(); + } + + public static String escapeIfRequired(final String input) { + for (final char c : input.toCharArray()) { + if (!StringReader.isAllowedInUnquotedString(c)) { + return escape(input); + } + } + return input; + } + + private static String escape(final String input) { + final StringBuilder result = new StringBuilder("\""); + + for (int i = 0; i < input.length(); i++) { + final char c = input.charAt(i); + if (c == '\\' || c == '"') { + result.append('\\'); + } + result.append(c); + } + + result.append("\""); + return result.toString(); + } + + public enum StringType { + SINGLE_WORD("word", "words_with_underscores"), + QUOTABLE_PHRASE("\"quoted phrase\"", "word", "\"\""), + GREEDY_PHRASE("word", "words with spaces", "\"and symbols\""),; + + private final Collection examples; + + StringType(final String... examples) { + this.examples = Arrays.asList(examples); + } + + public Collection getExamples() { + return examples; + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/curios/lang/en_us.json b/src/main/resources/assets/curios/lang/en_us.json index b2cbc6e8..f07fa533 100644 --- a/src/main/resources/assets/curios/lang/en_us.json +++ b/src/main/resources/assets/curios/lang/en_us.json @@ -9,6 +9,7 @@ "commands.curios.clear.success": "Slot %s has been cleared for %s", "commands.curios.clearAll.success": "All slots have been cleared for %s", "commands.curios.reset.success": "Reset slots for %s", + "arguments.curios.slot_not_exist": "Slot does not exist!", "item.curios.amulet": "Curious Amulet", "item.curios.ring": "Curious Ring", "item.curios.crown": "Curious Crown",