Posted September 5, 20214 yr So I am building a rank system for forge servers. Very basic as of right now. When the player joins the server it automatically serializes the arguments required for /ranks so suggestions do work. However if and admin creates a new rank, the rank wont be suggested till the player disconnects and rejoins(retrieves new serialized arguments). Is there a way I can force the reserialization of ArgumentTypes to send to clients? Example: Look at the images attached! First two images are on the first connection. I had to leave and rejoin to get the suggestion to work for the third image. /ranks command: @Override protected void initCommand() { command = Commands.literal("ranks").requires( (commandContext) -> {return commandContext.hasPermission(3);} ).then(join()).then(create()).then(delete()).then(modify()); } private LiteralArgumentBuilder<CommandSourceStack> join(){ return Commands.literal("join").then(Commands.argument("player", EntityArgument.player()).then(Commands.argument("rank", IterableArgumentType.choices(ModStatics.rankManager.getAvaliableRanks())).executes( (commandContext) -> { return joinRank(commandContext);} ))); } private LiteralArgumentBuilder<CommandSourceStack> create(){ return Commands.literal("create").then(Commands.argument("name", MessageArgument.message()).executes( (commandContext) -> { return createRank(commandContext);} )); } private LiteralArgumentBuilder<CommandSourceStack> delete(){ return Commands.literal("delete").then(Commands.argument("rank", IterableArgumentType.choices(ModStatics.rankManager.getAvaliableRanks())).executes( (commandContext) -> { return deleteRank(commandContext);} )); } private LiteralArgumentBuilder<CommandSourceStack> modify(){ return Commands.literal("modify").then(Commands.argument("rank", IterableArgumentType.choices(ModStatics.rankManager.getAvaliableRanks())) .then(modifySetColor()) .then(modifySetColoredChat()) .then(modifyAddCommand()) .then(modifyRemoveCommand())); } private LiteralArgumentBuilder<CommandSourceStack> modifySetColor(){ return Commands.literal("setColor").then(Commands.argument("color", ColorArgument.color()).executes( (commandContext) -> {return setColor(commandContext);} )); } private LiteralArgumentBuilder<CommandSourceStack> modifySetColoredChat(){ return Commands.literal("setColoredChat") .then(Commands.literal("true").executes( (commandContext) -> {return setColoredChat(commandContext,true);} )) .then(Commands.literal("false").executes( (commandContext) -> {return setColoredChat(commandContext, false);} )); } private LiteralArgumentBuilder<CommandSourceStack> modifyAddCommand(){ return Commands.literal("addCommand").then(Commands.argument("command", IterableArgumentType.choices(ModStatics.modCommandList.getAvaliable())).executes( (commandContext) -> {return addCommand(commandContext);} )); } private LiteralArgumentBuilder<CommandSourceStack> modifyRemoveCommand(){ return Commands.literal("removeCommand").then(Commands.argument("command", IterableArgumentType.choices(ModStatics.modCommandList.getAvaliable())).executes( (commandContext) -> {return removeCommand(commandContext);} )); } private int joinRank(CommandContext<CommandSourceStack> commandContext) throws CommandSyntaxException { String name = IterableArgumentType.getChoice(commandContext, "rank"); Player player = EntityArgument.getPlayer(commandContext, "player"); System.out.println(player.getUUID().toString() + " : " + name); if(ModStatics.rankManager.joinRank(player.getUUID(), name)) { commandContext.getSource().sendSuccess(new TextComponent("Joined rank ["+name+"] !"),true); }else { commandContext.getSource().sendFailure(new TextComponent("Failed to join rank ["+name+"] !")); } return 1; } private static int createRank(CommandContext<CommandSourceStack> commandContext) throws CommandSyntaxException { Component message = MessageArgument.getMessage(commandContext, "name"); String name = message.getContents(); if(ModStatics.rankManager.createRank(name)) { commandContext.getSource().sendSuccess(new TextComponent("Created rank ["+name+"] !"),true); }else { commandContext.getSource().sendFailure(new TextComponent("Failed to create rank ["+name+"] !")); } return 1; } private static int deleteRank(CommandContext<CommandSourceStack> commandContext) { String name = IterableArgumentType.getChoice(commandContext, "rank"); if(ModStatics.rankManager.deleteRank(name)) { commandContext.getSource().sendSuccess(new TextComponent("Deleted rank ["+name+"] !"),true); }else { commandContext.getSource().sendFailure(new TextComponent("Failed to delete rank ["+name+"] !")); } return 1; } private static int addCommand(CommandContext<CommandSourceStack> commandContext) { String name = IterableArgumentType.getChoice(commandContext, "rank"); String literal = IterableArgumentType.getChoice(commandContext, "command"); if(ModStatics.rankManager.addCommandToRank(name, literal)) { commandContext.getSource().sendSuccess(new TextComponent("Added command /"+literal+" to rank ["+name+"] !"),true); }else { commandContext.getSource().sendFailure(new TextComponent("Failed to add command /"+literal+" to rank ["+name+"] !")); } return 1; } private static int removeCommand(CommandContext<CommandSourceStack> commandContext) { String name = IterableArgumentType.getChoice(commandContext, "rank"); String literal = IterableArgumentType.getChoice(commandContext, "command"); if(ModStatics.rankManager.removeCommandFromRank(name, literal)) { commandContext.getSource().sendSuccess(new TextComponent("Removed command "+literal+" to rank ["+name+"] !"),true); }else { commandContext.getSource().sendFailure(new TextComponent("Failed to removed command "+literal+" from rank ["+name+"] !")); } return 1; } private static int setColor(CommandContext<CommandSourceStack> commandContext) { String name = IterableArgumentType.getChoice(commandContext, "rank"); ChatFormatting formatting = ColorArgument.getColor(commandContext, "color"); if(ModStatics.rankManager.getRank(name).setColor(formatting)) { commandContext.getSource().sendSuccess(new TextComponent("Updated rank color!"),true); }else { commandContext.getSource().sendFailure(new TextComponent("Failed to update rank color!")); } return 1; } private static int setColoredChat(CommandContext<CommandSourceStack> commandContext, boolean b) { String name = IterableArgumentType.getChoice(commandContext, "rank"); if(ModStatics.rankManager.setRankColoredChat(name, b)) { commandContext.getSource().sendSuccess(new TextComponent("Updated rank canColoredChat!"),true); }else { commandContext.getSource().sendFailure(new TextComponent("Failed to update rank canColoredChat!")); } return 1; } IterableArgumentType: private Iterable<String> choices; private IterableArgumentType(Iterable<String> choices) { this.choices = choices; } public static IterableArgumentType choices(Iterable<String> choices) { return new IterableArgumentType(choices); } public static String getChoice(CommandContext<CommandSourceStack> commandContext, String name) { return commandContext.getArgument(name, String.class); } @Override public String parse(StringReader reader) throws CommandSyntaxException { String string = reader.readString(); return string; } public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> commandContext, SuggestionsBuilder suggestionBuilder) { return SharedSuggestionProvider.suggest(choices, suggestionBuilder); } public Iterable<String> getChoices(){ return choices; } public static class Serializer implements ArgumentSerializer<IterableArgumentType>{ private String delimiter = "-"; public String convertToString(Iterable<String> choices) { StringBuilder builder = new StringBuilder(); ArrayList<String> array_choices = new ArrayList<String>(); for(String choice : choices) { array_choices.add(choice); } for(int i = 0; i < array_choices.size(); i++) { builder.append(array_choices.get(i)); if(i != array_choices.size()-1) { builder.append(delimiter); } } return builder.toString(); } public Iterable<String> convertToIterable(String choices){ String[] array_choices = choices.split(delimiter); Hashtable<String, Byte> hashtable_choices = new Hashtable<String, Byte>(); for(String choice : array_choices) { hashtable_choices.put(choice, (byte) 0); } return hashtable_choices.keySet(); } @Override public void serializeToNetwork(IterableArgumentType argument, FriendlyByteBuf buffer) { buffer.writeUtf(convertToString(argument.getChoices())); } @Override public IterableArgumentType deserializeFromNetwork(FriendlyByteBuf buffer) { String utf = buffer.readUtf(); return new IterableArgumentType(convertToIterable(utf)); } @Override public void serializeToJson(IterableArgumentType argument, JsonObject json) { json.addProperty("iterableargumenttype", convertToString(argument.getChoices())); } }
September 5, 20214 yr Author 58 minutes ago, diesieben07 said: I would store the ranks separately and sync them in a separate packet. Then you can just reference that separately stored "thing" from your argument type. Otherwise you'd have to resend the entire command tree. I found a solution! I modified the /ranks command to use a custom StringArgument. StringArgument is empty and wont have any suggestions. Then I follow up this Commands.argument with a .suggest() that calls a function to return uptodate suggestions. Did not have to mess with packets at all! This is new code incase anyone in the future needs this! Command /ranks: public class RankCommands extends ModCommand{ @Override protected void initCommand() { command = Commands.literal("ranks").requires( (commandContext) -> {return commandContext.hasPermission(3);} ).then(join()).then(create()).then(delete()).then(modify()); } private LiteralArgumentBuilder<CommandSourceStack> join(){ return Commands.literal("join").then(Commands.argument("player", EntityArgument.player()).then(Commands.argument("rank", StringArgument.string()).suggests(CustomSuggestionProvider::getRankSuggestions).executes( (commandContext) -> { return joinRank(commandContext);} ))); } private LiteralArgumentBuilder<CommandSourceStack> create(){ return Commands.literal("create").then(Commands.argument("name", StringArgument.string()).executes( (commandContext) -> { return createRank(commandContext);} )); } private LiteralArgumentBuilder<CommandSourceStack> delete(){ return Commands.literal("delete").then(Commands.argument("rank", StringArgument.string()).suggests(CustomSuggestionProvider::getRankSuggestions).executes( (commandContext) -> { return deleteRank(commandContext);} )); } private LiteralArgumentBuilder<CommandSourceStack> modify(){ return Commands.literal("modify").then(Commands.argument("rank", StringArgument.string()).suggests(CustomSuggestionProvider::getRankSuggestions) .then(modifySetColor()) .then(modifySetColoredChat()) .then(modifyAddCommand()) .then(modifyRemoveCommand())); } private LiteralArgumentBuilder<CommandSourceStack> modifySetColor(){ return Commands.literal("setColor").then(Commands.argument("color", ColorArgument.color()).executes( (commandContext) -> {return setColor(commandContext);} )); } private LiteralArgumentBuilder<CommandSourceStack> modifySetColoredChat(){ return Commands.literal("setColoredChat") .then(Commands.literal("true").executes( (commandContext) -> {return setColoredChat(commandContext,true);} )) .then(Commands.literal("false").executes( (commandContext) -> {return setColoredChat(commandContext, false);} )); } private LiteralArgumentBuilder<CommandSourceStack> modifyAddCommand(){ return Commands.literal("addCommand").then(Commands.argument("command", StringArgument.string()).suggests(CustomSuggestionProvider::getCommandSuggestions).executes( (commandContext) -> {return addCommand(commandContext);} )); } private LiteralArgumentBuilder<CommandSourceStack> modifyRemoveCommand(){ return Commands.literal("removeCommand").then(Commands.argument("command", StringArgument.string()).suggests(CustomSuggestionProvider::getCommandSuggestions).executes( (commandContext) -> {return removeCommand(commandContext);} )); } private int joinRank(CommandContext<CommandSourceStack> commandContext) throws CommandSyntaxException { String name = StringArgument.getString(commandContext, "rank"); Player player = EntityArgument.getPlayer(commandContext, "player"); if(ModStatics.rankManager.joinRank(player.getUUID(), name)) { commandContext.getSource().sendSuccess(new TextComponent("Joined rank ["+name+"] !"),true); }else { commandContext.getSource().sendFailure(new TextComponent("Failed to join rank ["+name+"] !")); } return 1; } private static int createRank(CommandContext<CommandSourceStack> commandContext) throws CommandSyntaxException { String name = StringArgument.getString(commandContext, "name"); if(ModStatics.rankManager.createRank(name)) { commandContext.getSource().sendSuccess(new TextComponent("Created rank ["+name+"] !"),true); }else { commandContext.getSource().sendFailure(new TextComponent("Failed to create rank ["+name+"] !")); } return 1; } private static int deleteRank(CommandContext<CommandSourceStack> commandContext) { String name = StringArgument.getString(commandContext, "rank"); if(ModStatics.rankManager.deleteRank(name)) { commandContext.getSource().sendSuccess(new TextComponent("Deleted rank ["+name+"] !"),true); }else { commandContext.getSource().sendFailure(new TextComponent("Failed to delete rank ["+name+"] !")); } return 1; } private static int addCommand(CommandContext<CommandSourceStack> commandContext) { String name = StringArgument.getString(commandContext, "rank"); String literal = StringArgument.getString(commandContext, "command"); if(ModStatics.rankManager.addCommandToRank(name, literal)) { commandContext.getSource().sendSuccess(new TextComponent("Added command /"+literal+" to rank ["+name+"] !"),true); }else { commandContext.getSource().sendFailure(new TextComponent("Failed to add command /"+literal+" to rank ["+name+"] !")); } return 1; } private static int removeCommand(CommandContext<CommandSourceStack> commandContext) { String name = StringArgument.getString(commandContext, "rank"); String literal = StringArgument.getString(commandContext, "command"); if(ModStatics.rankManager.removeCommandFromRank(name, literal)) { commandContext.getSource().sendSuccess(new TextComponent("Removed command "+literal+" to rank ["+name+"] !"),true); }else { commandContext.getSource().sendFailure(new TextComponent("Failed to removed command "+literal+" from rank ["+name+"] !")); } return 1; } private static int setColor(CommandContext<CommandSourceStack> commandContext) { String name = StringArgument.getString(commandContext, "rank"); ChatFormatting formatting = ColorArgument.getColor(commandContext, "color"); if(ModStatics.rankManager.getRank(name).setColor(formatting)) { commandContext.getSource().sendSuccess(new TextComponent("Updated rank color!"),true); }else { commandContext.getSource().sendFailure(new TextComponent("Failed to update rank color!")); } return 1; } private static int setColoredChat(CommandContext<CommandSourceStack> commandContext, boolean b) { String name = StringArgument.getString(commandContext, "rank"); if(ModStatics.rankManager.setRankColoredChat(name, b)) { commandContext.getSource().sendSuccess(new TextComponent("Updated rank canColoredChat!"),true); }else { commandContext.getSource().sendFailure(new TextComponent("Failed to update rank canColoredChat!")); } return 1; } } StringArgument: public class StringArgument implements ArgumentType<String>{ private StringArgument() { } public static StringArgument string() { return new StringArgument(); } public static String getString(CommandContext<CommandSourceStack> commandContext, String name) { return commandContext.getArgument(name, String.class); } @Override public String parse(StringReader reader) throws CommandSyntaxException { String string = reader.readString(); return string; } public static class Serializer implements ArgumentSerializer<StringArgument>{ @Override public StringArgument deserializeFromNetwork(FriendlyByteBuf buffer) { return new StringArgument(); } @Override public void serializeToNetwork(StringArgument p_121579_, FriendlyByteBuf p_121580_) { } @Override public void serializeToJson(StringArgument p_121577_, JsonObject p_121578_) { } } } CustomSuggestionProvider: public class CustomSuggestionProvider{ public static CompletableFuture getRankSuggestions(CommandContext context, SuggestionsBuilder builder)throws CommandSyntaxException { Iterable<String> choices = ModStatics.rankManager.getAvaliableRanks(); for(String choice : choices) { builder.suggest(choice); } return builder.buildFuture(); } public static CompletableFuture getCommandSuggestions(CommandContext context, SuggestionsBuilder builder)throws CommandSyntaxException { Iterable<String> choices = ModStatics.modCommandList.getAvaliable(); for(String choice : choices) { builder.suggest(choice); } return builder.buildFuture(); } } Also don't forget to registry the custom argument type: ArgumentTypes.register("se:stringargument", StringArgument.class, new StringArgument.Serializer());
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.