Posted September 3, 20214 yr I am having problems with my custom ArgumentType(s) not serializing when running my mod on a server. It works fine on single player because there is not serialization required. Log: [00:00:24] [Server thread/INFO]: Made X_ZombieSlayer_X a server operator [00:00:24] [Netty Server IO #4/ERROR]: Could not serialize mod.ranks.commands.RankArgument@3f19c861 (class mod.ranks.commands.RankArgument) - will not be sent to client! [00:00:24] [Netty Server IO #4/ERROR]: Could not serialize mod.ranks.commands.RankArgument@72f73fc4 (class mod.ranks.commands.RankArgument) - will not be sent to client! [00:00:24] [Netty Server IO #4/ERROR]: Could not serialize mod.ranks.commands.RankArgument@78019307 (class mod.ranks.commands.RankArgument) - will not be sent to client! [00:00:24] [Netty Server IO #4/ERROR]: Could not serialize mod.commands.base.ModCommandArgument@5ff1379e (class mod.commands.base.ModCommandArgument) - will not be sent to client! [00:00:24] [Netty Server IO #4/ERROR]: Could not serialize mod.commands.base.ModCommandArgument@27d41c38 (class mod.commands.base.ModCommandArgument) - will not be sent to client! RankArgument: Spoiler import java.util.concurrent.CompletableFuture; 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.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; import mod.utils.ModStatics; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.SharedSuggestionProvider; public class RankArgument implements ArgumentType<String>{ public static RankArgument ranks() { return new RankArgument(); } public static String getRankName(CommandContext<CommandSourceStack> p_98430_, String p_98431_) { return p_98430_.getArgument(p_98431_, String.class); } @Override public String parse(StringReader reader) throws CommandSyntaxException { String name = reader.readString(); return name; } public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> p_98438_, SuggestionsBuilder p_98439_) { return SharedSuggestionProvider.suggest(ModStatics.rankManager.getAvaliableRanks(), p_98439_); } } ModCommandArgument: Spoiler import java.util.concurrent.CompletableFuture; 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.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; import mod.utils.ModStatics; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.SharedSuggestionProvider; public class ModCommandArgument implements ArgumentType<String>{ public static ModCommandArgument commands() { return new ModCommandArgument(); } public static String getCommandLiteral(CommandContext<CommandSourceStack> p_98430_, String p_98431_) { return p_98430_.getArgument(p_98431_, String.class); } @Override public String parse(StringReader reader) throws CommandSyntaxException { String name = reader.readString(); return name; } public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> p_98438_, SuggestionsBuilder p_98439_) { return SharedSuggestionProvider.suggest(ModStatics.modCommandList.getAvaliable(), p_98439_); } } Like I said before it works great on single player. I just need to get multiplayer working. Any help would be much appreciated. Seems like I need to call ArgumentTypes.register() but I am a bit confused on the arguments. Can someone please explain? Do I need a custom ArgumentSerializer? Edited September 3, 20214 yr by X_ZombieSlayer_X English and better info!
September 3, 20214 yr Author 6 hours ago, diesieben07 said: Actually I just noticed this is missing enqueueWork. I thought enqueueWork was for modifying existing attributes? I am just needing tab-complete suggestions to work on multiplayer. The commands run and operated as expected but they just appear red on multiplayer do to my lack of an ArgumentSerializer. If you could explain in further detail why it would be a good idea to include enqueuWork, that would be much appreciated! 7 hours ago, diesieben07 said: See how Forge does it: https://github.com/MinecraftForge/MinecraftForge/blob/a336e443f725eea7735633b9a7d2b932feed56fe/src/main/java/net/minecraftforge/common/ForgeMod.java#L185-L198 I will take a look and create my custom serializer ! Thanks.
September 3, 20214 yr Author 2 minutes ago, diesieben07 said: enqueueWork is when you need to interact with things that are not thread safe (such as registering argument types) from a parallel mod loading event (such as FMLCommonSetupEvent). It has nothing to do with attributes. What I meant is that the forge code I linked is missing enqueueWork. Ah, thank you for the enlightenment and help!
September 3, 20214 yr Author 15 hours ago, diesieben07 said: See how Forge does it: https://github.com/MinecraftForge/MinecraftForge/blob/a336e443f725eea7735633b9a7d2b932feed56fe/src/main/java/net/minecraftforge/common/ForgeMod.java#L185-L198 I made one that should replace both my ranks and modcommands argumenttype. It is no longer throwing errors/or red(invalid command), however, I can't see the suggestions. No suggestions are being listed(on multiplayer) and I am not sure why? Here is my new code: public class IterableArgumentType implements ArgumentType<String>{ 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())); } } } Any ideas as to why it is not suggesting anything? Edited September 3, 20214 yr by X_ZombieSlayer_X Fixing errors
September 4, 20214 yr Author 13 hours ago, diesieben07 said: I don't see anything wrong, no. So I did a bit of primitive debugging(printing out from serializer methods). The server is sending information but the client is not deserializing the data for whatever reason. Client Log: [16:47:49] [Netty Client IO #2/INFO]: Connected to a modded server. [04Sep2021 16:47:50.587] [Render thread/INFO] [com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService/]: Environment: authHost='https://authserver.mojang.com', accountsHost='https://api.mojang.com', sessionHost='https://sessionserver.mojang.com', servicesHost='https://api.minecraftservices.com', name='PROD' [16:47:51] [Render thread/INFO]: Loaded 0 advancements [16:48:08] [Render thread/INFO]: [CHAT] §8[default]§f<X_ZombieSlayer_X> test [16:48:14] [Render thread/INFO]: Stopping! Server Log: [16:47:49] [Server thread/INFO]: X_ZombieSlayer_X joined the game seserializeToNetwork:ench seserializeToNetwork:rename seserializeToNetwork:ench seserializeToNetwork:rename seserializeToNetwork:ench seserializeToNetwork:rename seserializeToNetwork:ench seserializeToNetwork:rename seserializeToNetwork:ench seserializeToNetwork:rename [16:48:08] [Server thread/INFO]: º8[default]ºf<X_ZombieSlayer_X> test [16:48:11] [Server thread/INFO]: X_ZombieSlayer_X lost connection: Disconnected [16:48:11] [Server thread/INFO]: X_ZombieSlayer_X left the game Serializer: 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); System.out.println("seserializeToNetwork:"+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) { System.out.println("deserializeFromNetwork:"+choice); 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())); } } I should be hitting the println("deserializeFromNetwork:"+choice) but the client is outputting nothing?
September 4, 20214 yr Author 13 hours ago, diesieben07 said: I don't see anything wrong, no. 24 minutes ago, X_ZombieSlayer_X said: So I did a bit of primitive debugging(printing out from serializer methods). The server is sending information but the client is not deserializing the data for whatever reason. Client Log: [16:47:49] [Netty Client IO #2/INFO]: Connected to a modded server. [04Sep2021 16:47:50.587] [Render thread/INFO] [com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService/]: Environment: authHost='https://authserver.mojang.com', accountsHost='https://api.mojang.com', sessionHost='https://sessionserver.mojang.com', servicesHost='https://api.minecraftservices.com', name='PROD' [16:47:51] [Render thread/INFO]: Loaded 0 advancements [16:48:08] [Render thread/INFO]: [CHAT] §8[default]§f<X_ZombieSlayer_X> test [16:48:14] [Render thread/INFO]: Stopping! Server Log: [16:47:49] [Server thread/INFO]: X_ZombieSlayer_X joined the game seserializeToNetwork:ench seserializeToNetwork:rename seserializeToNetwork:ench seserializeToNetwork:rename seserializeToNetwork:ench seserializeToNetwork:rename seserializeToNetwork:ench seserializeToNetwork:rename seserializeToNetwork:ench seserializeToNetwork:rename [16:48:08] [Server thread/INFO]: º8[default]ºf<X_ZombieSlayer_X> test [16:48:11] [Server thread/INFO]: X_ZombieSlayer_X lost connection: Disconnected [16:48:11] [Server thread/INFO]: X_ZombieSlayer_X left the game Serializer: 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); System.out.println("seserializeToNetwork:"+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) { System.out.println("deserializeFromNetwork:"+choice); 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())); } } I should be hitting the println("deserializeFromNetwork:"+choice) but the client is outputting nothing? Found solution! Don't use "." as a delimiter, now using "-" instead for better .split(delimiter)!
September 5, 20214 yr read the java doc of String#split, if you want to split a String at a dot you need to use "\\."
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.