From 927542ff2eff9dd1675cd8465f1fe310dcc764c6 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Sat, 11 Apr 2020 00:20:34 +0100 Subject: [PATCH 1/8] Added base command completion --- .../JavaServerDeclareCommandsTranslator.java | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java new file mode 100644 index 000000000..d921bd79c --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.connector.network.translators.java; + +import com.github.steveice10.mc.protocol.data.game.command.CommandNode; +import com.github.steveice10.mc.protocol.data.game.command.CommandType; +import com.github.steveice10.mc.protocol.packet.ingame.server.ServerDeclareCommandsPacket; +import com.nukkitx.protocol.bedrock.data.CommandData; +import com.nukkitx.protocol.bedrock.data.CommandEnumData; +import com.nukkitx.protocol.bedrock.data.CommandParamData; +import com.nukkitx.protocol.bedrock.packet.AvailableCommandsPacket; +import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.PacketTranslator; +import org.geysermc.connector.network.translators.Translator; + +import java.util.*; + +@Translator(packet = ServerDeclareCommandsPacket.class) +public class JavaServerDeclareCommandsTranslator extends PacketTranslator { + @Override + public void translate(ServerDeclareCommandsPacket packet, GeyserSession session) { + GeyserConnector.getInstance().getLogger().info("ServerDeclareCommandsPacket"); + + List rootNodes = new ArrayList<>(); + List commandData = new ArrayList<>(); + Map commands = new HashMap<>(); + + for (CommandNode node : packet.getNodes()) { + if (node.getType() == CommandType.ROOT) { + rootNodes.add(node); + } + } + + for (CommandNode rootNode : rootNodes) { + for (int nodeIndex : rootNode.getChildIndices()) { + CommandNode node = packet.getNodes()[nodeIndex]; + + commands.put(nodeIndex, node.getName()); + } + } + + List flags = new ArrayList<>(); + for (int commandID : commands.keySet()) { + String commandName = commands.get(commandID); + + CommandEnumData aliases = new CommandEnumData( commandName + "Aliases", new String[]{commandName.toLowerCase()}, false); + + CommandData data = new CommandData(commandName, "A Java server command", flags, (byte) 0, aliases, new CommandParamData[0][0]); + commandData.add(data); + } + + + AvailableCommandsPacket availableCommandsPacket = new AvailableCommandsPacket(); + for (CommandData data : commandData) { + availableCommandsPacket.getCommands().add(data); + } + + session.getUpstream().sendPacket(availableCommandsPacket); + } +} From c0500862211c24912b0e710daf5f6ec4ec7f6986 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Sat, 11 Apr 2020 01:24:22 +0100 Subject: [PATCH 2/8] Basic param parsing --- .../JavaServerDeclareCommandsTranslator.java | 38 +++++++++++++++++-- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java index d921bd79c..9ae5bb48f 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java @@ -25,6 +25,8 @@ package org.geysermc.connector.network.translators.java; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import com.github.steveice10.mc.protocol.data.game.command.CommandNode; import com.github.steveice10.mc.protocol.data.game.command.CommandType; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerDeclareCommandsPacket; @@ -36,7 +38,9 @@ import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; +import org.geysermc.connector.utils.FileUtils; +import java.io.IOException; import java.util.*; @Translator(packet = ServerDeclareCommandsPacket.class) @@ -48,6 +52,8 @@ public class JavaServerDeclareCommandsTranslator extends PacketTranslator rootNodes = new ArrayList<>(); List commandData = new ArrayList<>(); Map commands = new HashMap<>(); + Map> commandArgs = new HashMap<>(); + ObjectMapper mapper = new ObjectMapper(); for (CommandNode node : packet.getNodes()) { if (node.getType() == CommandType.ROOT) { @@ -59,21 +65,47 @@ public class JavaServerDeclareCommandsTranslator extends PacketTranslator= 1) { + for (int childIndex : node.getChildIndices()) { + commandArgs.putIfAbsent(nodeIndex, new ArrayList<>()); + commandArgs.get(nodeIndex).add(packet.getNodes()[childIndex]); + } + } + commands.put(nodeIndex, node.getName()); } } + + + /* try { + GeyserConnector.getInstance().getLogger().debug(mapper.writeValueAsString(params)); + } catch (JsonProcessingException e) { } */ + List flags = new ArrayList<>(); for (int commandID : commands.keySet()) { String commandName = commands.get(commandID); - CommandEnumData aliases = new CommandEnumData( commandName + "Aliases", new String[]{commandName.toLowerCase()}, false); + CommandEnumData aliases = new CommandEnumData( commandName + "Aliases", new String[] { commandName.toLowerCase() }, false); + CommandParamData[][] params = new CommandParamData[0][0]; - CommandData data = new CommandData(commandName, "A Java server command", flags, (byte) 0, aliases, new CommandParamData[0][0]); + if (commandArgs.containsKey(commandID)) { + params = new CommandParamData[1][]; + CommandParamData[] param1 = new CommandParamData[commandArgs.get(commandID).size()]; + + int i = 0; + for (CommandNode paramNode : commandArgs.get(commandID)) { + param1[i] = new CommandParamData(paramNode.getName(), false, null, CommandParamData.Type.MESSAGE, null, Collections.emptyList()); + i++; + } + + params[0] = param1; + } + + CommandData data = new CommandData(commandName, "A Java server command", flags, (byte) 0, aliases, params); commandData.add(data); } - AvailableCommandsPacket availableCommandsPacket = new AvailableCommandsPacket(); for (CommandData data : commandData) { availableCommandsPacket.getCommands().add(data); From 010840bebe4125632e053211d0c7450c5a14a30f Mon Sep 17 00:00:00 2001 From: rtm516 Date: Sat, 11 Apr 2020 02:25:58 +0100 Subject: [PATCH 3/8] Better parameter handling --- .../JavaServerDeclareCommandsTranslator.java | 116 +++++++++++++++--- 1 file changed, 96 insertions(+), 20 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java index 9ae5bb48f..7ada88cb8 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java @@ -28,6 +28,7 @@ package org.geysermc.connector.network.translators.java; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.steveice10.mc.protocol.data.game.command.CommandNode; +import com.github.steveice10.mc.protocol.data.game.command.CommandParser; import com.github.steveice10.mc.protocol.data.game.command.CommandType; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerDeclareCommandsPacket; import com.nukkitx.protocol.bedrock.data.CommandData; @@ -65,6 +66,8 @@ public class JavaServerDeclareCommandsTranslator extends PacketTranslator= 1) { for (int childIndex : node.getChildIndices()) { commandArgs.putIfAbsent(nodeIndex, new ArrayList<>()); @@ -76,31 +79,12 @@ public class JavaServerDeclareCommandsTranslator extends PacketTranslator flags = new ArrayList<>(); for (int commandID : commands.keySet()) { String commandName = commands.get(commandID); CommandEnumData aliases = new CommandEnumData( commandName + "Aliases", new String[] { commandName.toLowerCase() }, false); - CommandParamData[][] params = new CommandParamData[0][0]; - - if (commandArgs.containsKey(commandID)) { - params = new CommandParamData[1][]; - CommandParamData[] param1 = new CommandParamData[commandArgs.get(commandID).size()]; - - int i = 0; - for (CommandNode paramNode : commandArgs.get(commandID)) { - param1[i] = new CommandParamData(paramNode.getName(), false, null, CommandParamData.Type.MESSAGE, null, Collections.emptyList()); - i++; - } - - params[0] = param1; - } + CommandParamData[][] params = getParams(commandID, packet.getNodes()[commandID], commandArgs); CommandData data = new CommandData(commandName, "A Java server command", flags, (byte) 0, aliases, params); commandData.add(data); @@ -113,4 +97,96 @@ public class JavaServerDeclareCommandsTranslator extends PacketTranslator> commandArgs) { + if (commandArgs.containsKey(commandID)) { + CommandParamData[][] params = new CommandParamData[commandArgs.get(commandID).size()][]; + + if (commandNode.getName().equals("ban")) { + GeyserConnector.getInstance().getLogger().debug("ban : " + commandArgs.get(commandID)); + } + + int i = 0; + for (CommandNode paramNode : commandArgs.get(commandID)) { + CommandParamData[] param1 = new CommandParamData[1]; + param1[0] = new CommandParamData(paramNode.getName(), false, null, mapCommandType(paramNode.getParser()), null, Collections.emptyList()); + params[i] = param1; + i++; + } + + return params; + } + + return new CommandParamData[0][0]; + } + + private CommandParamData.Type mapCommandType(CommandParser parser) { + if (parser == null) { return CommandParamData.Type.STRING; } + + switch (parser) { + case FLOAT: + return CommandParamData.Type.FLOAT; + + case INTEGER: + return CommandParamData.Type.INT; + + case ENTITY: + case GAME_PROFILE: + return CommandParamData.Type.TARGET; + + case BLOCK_POS: + return CommandParamData.Type.BLOCK_POSITION; + + case COLUMN_POS: + case VEC3: + return CommandParamData.Type.POSITION; + + case MESSAGE: + return CommandParamData.Type.MESSAGE; + + case NBT: + case NBT_COMPOUND_TAG: + case NBT_TAG: + case NBT_PATH: + return CommandParamData.Type.JSON; + + case RESOURCE_LOCATION: + return CommandParamData.Type.FILE_PATH; + + case INT_RANGE: + return CommandParamData.Type.INT_RANGE; + + case BOOL: + case DOUBLE: + case STRING: + case VEC2: + case BLOCK_STATE: + case BLOCK_PREDICATE: + case ITEM_STACK: + case ITEM_PREDICATE: + case COLOR: + case COMPONENT: + case OBJECTIVE: + case OBJECTIVE_CRITERIA: + case OPERATION: // Possibly OPERATOR + case PARTICLE: + case ROTATION: + case SCOREBOARD_SLOT: + case SCORE_HOLDER: + case SWIZZLE: + case TEAM: + case ITEM_SLOT: + case MOB_EFFECT: + case FUNCTION: + case ENTITY_ANCHOR: + case RANGE: + case FLOAT_RANGE: + case ITEM_ENCHANTMENT: + case ENTITY_SUMMON: + case DIMENSION: + case TIME: + default: + return CommandParamData.Type.STRING; + } + } } From 74d3254bf074ee79ead6eaeddc2eee6645978f73 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Sat, 11 Apr 2020 02:58:07 +0100 Subject: [PATCH 4/8] Automatic enum creation and comments --- .../JavaServerDeclareCommandsTranslator.java | 58 ++++++++++++++----- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java index 7ada88cb8..bd164a347 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java @@ -25,8 +25,6 @@ package org.geysermc.connector.network.translators.java; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import com.github.steveice10.mc.protocol.data.game.command.CommandNode; import com.github.steveice10.mc.protocol.data.game.command.CommandParser; import com.github.steveice10.mc.protocol.data.game.command.CommandType; @@ -35,39 +33,37 @@ import com.nukkitx.protocol.bedrock.data.CommandData; import com.nukkitx.protocol.bedrock.data.CommandEnumData; import com.nukkitx.protocol.bedrock.data.CommandParamData; import com.nukkitx.protocol.bedrock.packet.AvailableCommandsPacket; -import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; -import org.geysermc.connector.utils.FileUtils; -import java.io.IOException; import java.util.*; @Translator(packet = ServerDeclareCommandsPacket.class) public class JavaServerDeclareCommandsTranslator extends PacketTranslator { @Override public void translate(ServerDeclareCommandsPacket packet, GeyserSession session) { - GeyserConnector.getInstance().getLogger().info("ServerDeclareCommandsPacket"); - List rootNodes = new ArrayList<>(); List commandData = new ArrayList<>(); Map commands = new HashMap<>(); Map> commandArgs = new HashMap<>(); - ObjectMapper mapper = new ObjectMapper(); + // Find the root nodes for (CommandNode node : packet.getNodes()) { if (node.getType() == CommandType.ROOT) { rootNodes.add(node); } } + // Loop through the root nodes to get all commands for (CommandNode rootNode : rootNodes) { for (int nodeIndex : rootNode.getChildIndices()) { CommandNode node = packet.getNodes()[nodeIndex]; + // Make sure we dont have duplicated commands (happens if there is more than 1 root node) if (commands.containsKey(nodeIndex)) { continue; } + // Get and update the commandArgs list with the found arguments if (node.getChildIndices().length >= 1) { for (int childIndex : node.getChildIndices()) { commandArgs.putIfAbsent(nodeIndex, new ArrayList<>()); @@ -75,41 +71,77 @@ public class JavaServerDeclareCommandsTranslator extends PacketTranslator flags = new ArrayList<>(); + + // Loop through all the found commands for (int commandID : commands.keySet()) { String commandName = commands.get(commandID); + // Create a basic alias CommandEnumData aliases = new CommandEnumData( commandName + "Aliases", new String[] { commandName.toLowerCase() }, false); + + // Get and parse all params CommandParamData[][] params = getParams(commandID, packet.getNodes()[commandID], commandArgs); + // Build the completed command and add it to the final list CommandData data = new CommandData(commandName, "A Java server command", flags, (byte) 0, aliases, params); commandData.add(data); } + // Add our commands to the AvailableCommandsPacket for the bedrock client AvailableCommandsPacket availableCommandsPacket = new AvailableCommandsPacket(); for (CommandData data : commandData) { availableCommandsPacket.getCommands().add(data); } + // Finally, send the commands to the client session.getUpstream().sendPacket(availableCommandsPacket); } private CommandParamData[][] getParams(int commandID, CommandNode commandNode, Map> commandArgs) { if (commandArgs.containsKey(commandID)) { - CommandParamData[][] params = new CommandParamData[commandArgs.get(commandID).size()][]; + List parsedParams = new ArrayList<>(); + int enumIndex = -1; - if (commandNode.getName().equals("ban")) { - GeyserConnector.getInstance().getLogger().debug("ban : " + commandArgs.get(commandID)); + for (CommandNode paramNode : commandArgs.get(commandID)) { + if (paramNode.getParser() == null) { + if (enumIndex == -1) { + enumIndex = parsedParams.size(); + + // Create the new enum command + CommandEnumData enumData = new CommandEnumData(paramNode.getName(), new String[] { paramNode.getName() }, false); + parsedParams.add(new CommandParamData(paramNode.getName(), false, enumData, mapCommandType(paramNode.getParser()), null, Collections.emptyList())); + }else { + // Get the existing enum + CommandParamData enumParam = parsedParams.get(enumIndex); + + // Extend the current list of enum values + String[] enumOptions = Arrays.copyOf(enumParam.getEnumData().getValues(), enumParam.getEnumData().getValues().length + 1); + enumOptions[enumOptions.length - 1] = paramNode.getName(); + + // Re-create the command using the updated values + CommandEnumData enumData = new CommandEnumData(enumParam.getEnumData().getName(), enumOptions, false); + parsedParams.set(enumIndex, new CommandParamData(enumParam.getName(), false, enumData, enumParam.getType(), null, Collections.emptyList())); + } + }else{ + // Put the non-enum param into the list + parsedParams.add(new CommandParamData(paramNode.getName(), false, null, mapCommandType(paramNode.getParser()), null, Collections.emptyList())); + } } + CommandParamData[][] params = new CommandParamData[parsedParams.size()][]; + + // Fill the nested params array int i = 0; - for (CommandNode paramNode : commandArgs.get(commandID)) { + for (CommandParamData parsedParam : parsedParams) { CommandParamData[] param1 = new CommandParamData[1]; - param1[0] = new CommandParamData(paramNode.getName(), false, null, mapCommandType(paramNode.getParser()), null, Collections.emptyList()); + param1[0] = parsedParam; params[i] = param1; i++; } From c95d2d2f477079d6160360acf2b26989eb6e96fc Mon Sep 17 00:00:00 2001 From: rtm516 Date: Sat, 11 Apr 2020 14:57:29 +0100 Subject: [PATCH 5/8] New parameter parsing ready for multiple params --- .../JavaServerDeclareCommandsTranslator.java | 102 ++++++++++++------ 1 file changed, 68 insertions(+), 34 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java index bd164a347..22d6e7a64 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java @@ -25,6 +25,8 @@ package org.geysermc.connector.network.translators.java; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import com.github.steveice10.mc.protocol.data.game.command.CommandNode; import com.github.steveice10.mc.protocol.data.game.command.CommandParser; import com.github.steveice10.mc.protocol.data.game.command.CommandType; @@ -33,6 +35,8 @@ import com.nukkitx.protocol.bedrock.data.CommandData; import com.nukkitx.protocol.bedrock.data.CommandEnumData; import com.nukkitx.protocol.bedrock.data.CommandParamData; import com.nukkitx.protocol.bedrock.packet.AvailableCommandsPacket; +import lombok.Getter; +import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; @@ -87,7 +91,7 @@ public class JavaServerDeclareCommandsTranslator extends PacketTranslator> commandArgs) { - if (commandArgs.containsKey(commandID)) { - List parsedParams = new ArrayList<>(); - int enumIndex = -1; + private CommandParamData[][] getParams(int commandID, CommandNode commandNode, CommandNode[] allNodes) { + // Check if the command is an alias and redirect it + if (commandNode.getRedirectIndex() != -1) { + GeyserConnector.getInstance().getLogger().debug("Redirecting command " + commandNode.getName() + " to " + allNodes[commandNode.getRedirectIndex()].getName()); + commandNode = allNodes[commandNode.getRedirectIndex()]; + } - for (CommandNode paramNode : commandArgs.get(commandID)) { - if (paramNode.getParser() == null) { - if (enumIndex == -1) { - enumIndex = parsedParams.size(); + if (commandNode.getChildIndices().length >= 1) { + // Create the root param node and build all the children + ParamInfo rootParam = new ParamInfo(commandNode, null); + rootParam.buildChildren(allNodes); - // Create the new enum command - CommandEnumData enumData = new CommandEnumData(paramNode.getName(), new String[] { paramNode.getName() }, false); - parsedParams.add(new CommandParamData(paramNode.getName(), false, enumData, mapCommandType(paramNode.getParser()), null, Collections.emptyList())); - }else { - // Get the existing enum - CommandParamData enumParam = parsedParams.get(enumIndex); + try { + new ObjectMapper().writeValueAsString(rootParam.getChildren()); + } catch (JsonProcessingException e) { } - // Extend the current list of enum values - String[] enumOptions = Arrays.copyOf(enumParam.getEnumData().getValues(), enumParam.getEnumData().getValues().length + 1); - enumOptions[enumOptions.length - 1] = paramNode.getName(); - - // Re-create the command using the updated values - CommandEnumData enumData = new CommandEnumData(enumParam.getEnumData().getName(), enumOptions, false); - parsedParams.set(enumIndex, new CommandParamData(enumParam.getName(), false, enumData, enumParam.getType(), null, Collections.emptyList())); - } - }else{ - // Put the non-enum param into the list - parsedParams.add(new CommandParamData(paramNode.getName(), false, null, mapCommandType(paramNode.getParser()), null, Collections.emptyList())); - } - } - - CommandParamData[][] params = new CommandParamData[parsedParams.size()][]; + CommandParamData[][] params = new CommandParamData[rootParam.getChildren().size()][]; // Fill the nested params array int i = 0; - for (CommandParamData parsedParam : parsedParams) { - CommandParamData[] param1 = new CommandParamData[1]; - param1[0] = parsedParam; - params[i] = param1; + for (ParamInfo parmInfo : rootParam.getChildren()) { + CommandParamData[] paramParts = new CommandParamData[1]; + paramParts[0] = parmInfo.getParamData(); + params[i] = paramParts; i++; } @@ -221,4 +210,49 @@ public class JavaServerDeclareCommandsTranslator extends PacketTranslator children; + + public ParamInfo(CommandNode paramNode, CommandParamData paramData) { + this.paramNode = paramNode; + this.paramData = paramData; + this.children = new ArrayList<>(); + } + + public void buildChildren(CommandNode[] allNodes) { + int enumIndex = -1; + + for (int paramID : paramNode.getChildIndices()) { + CommandNode paramNode = allNodes[paramID]; + + if (paramNode.getParser() == null) { + if (enumIndex == -1) { + enumIndex = children.size(); + + // Create the new enum command + CommandEnumData enumData = new CommandEnumData(paramNode.getName(), new String[] { paramNode.getName() }, false); + children.add(new ParamInfo(paramNode, new CommandParamData(paramNode.getName(), false, enumData, mapCommandType(paramNode.getParser()), null, Collections.emptyList()))); + } else { + // Get the existing enum + ParamInfo enumParamInfo = children.get(enumIndex); + + // Extend the current list of enum values + String[] enumOptions = Arrays.copyOf(enumParamInfo.getParamData().getEnumData().getValues(), enumParamInfo.getParamData().getEnumData().getValues().length + 1); + enumOptions[enumOptions.length - 1] = paramNode.getName(); + + // Re-create the command using the updated values + CommandEnumData enumData = new CommandEnumData(enumParamInfo.getParamData().getEnumData().getName(), enumOptions, false); + children.set(enumIndex, new ParamInfo(enumParamInfo.getParamNode(), new CommandParamData(enumParamInfo.getParamData().getName(), false, enumData, enumParamInfo.getParamData().getType(), null, Collections.emptyList()))); + } + }else{ + // Put the non-enum param into the list + children.add(new ParamInfo(paramNode, new CommandParamData(paramNode.getName(), false, null, mapCommandType(paramNode.getParser()), null, Collections.emptyList()))); + } + } + } + } } From 00099b53323ad7dfbcaacd1ffb91610a3d9fdb1c Mon Sep 17 00:00:00 2001 From: rtm516 Date: Sat, 11 Apr 2020 15:53:53 +0100 Subject: [PATCH 6/8] Multi arguments handling --- .../JavaServerDeclareCommandsTranslator.java | 44 +++++++++++++++---- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java index 22d6e7a64..f8d31be9b 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java @@ -120,18 +120,17 @@ public class JavaServerDeclareCommandsTranslator extends PacketTranslator treeData = rootParam.getTree(); + CommandParamData[][] params = new CommandParamData[treeData.size()][]; // Fill the nested params array int i = 0; - for (ParamInfo parmInfo : rootParam.getChildren()) { - CommandParamData[] paramParts = new CommandParamData[1]; - paramParts[0] = parmInfo.getParamData(); - params[i] = paramParts; + for (CommandParamData[] tree : treeData) { + params[i] = tree; i++; } @@ -253,6 +252,35 @@ public class JavaServerDeclareCommandsTranslator extends PacketTranslator getTree() { + List treeParamData = new ArrayList<>(); + + for (ParamInfo child : children) { + List childTree = child.getTree(); + for (CommandParamData[] subchild : childTree) { + CommandParamData[] tmpTree = new ArrayList() { + { + add(child.getParamData()); + addAll(Arrays.asList(subchild)); + } + }.toArray(new CommandParamData[0]); + + treeParamData.add(tmpTree); + } + + if (childTree.size() == 0) { + treeParamData.add(new CommandParamData[] { child.getParamData() }); + } + } + + return treeParamData; } } } From b0d39c587f51b8bd218d9ab19b5dde14883f63c1 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Sat, 11 Apr 2020 19:31:06 +0100 Subject: [PATCH 7/8] Removed debugging code --- .../java/JavaServerDeclareCommandsTranslator.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java index f8d31be9b..614966a54 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java @@ -120,10 +120,6 @@ public class JavaServerDeclareCommandsTranslator extends PacketTranslator treeData = rootParam.getTree(); CommandParamData[][] params = new CommandParamData[treeData.size()][]; @@ -263,7 +259,10 @@ public class JavaServerDeclareCommandsTranslator extends PacketTranslator treeParamData = new ArrayList<>(); for (ParamInfo child : children) { + // Get the tree from the child List childTree = child.getTree(); + + // Un-pack the tree append the child node to it and push into the list for (CommandParamData[] subchild : childTree) { CommandParamData[] tmpTree = new ArrayList() { { @@ -275,6 +274,7 @@ public class JavaServerDeclareCommandsTranslator extends PacketTranslator Date: Mon, 13 Apr 2020 17:27:30 +0100 Subject: [PATCH 8/8] Fixed crashing bug when using more than 1 root node --- .../JavaServerDeclareCommandsTranslator.java | 40 ++++++++----------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java index 614966a54..391f0a610 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java @@ -25,11 +25,8 @@ package org.geysermc.connector.network.translators.java; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import com.github.steveice10.mc.protocol.data.game.command.CommandNode; import com.github.steveice10.mc.protocol.data.game.command.CommandParser; -import com.github.steveice10.mc.protocol.data.game.command.CommandType; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerDeclareCommandsPacket; import com.nukkitx.protocol.bedrock.data.CommandData; import com.nukkitx.protocol.bedrock.data.CommandEnumData; @@ -47,37 +44,30 @@ import java.util.*; public class JavaServerDeclareCommandsTranslator extends PacketTranslator { @Override public void translate(ServerDeclareCommandsPacket packet, GeyserSession session) { - List rootNodes = new ArrayList<>(); List commandData = new ArrayList<>(); Map commands = new HashMap<>(); Map> commandArgs = new HashMap<>(); - // Find the root nodes - for (CommandNode node : packet.getNodes()) { - if (node.getType() == CommandType.ROOT) { - rootNodes.add(node); - } - } + // Get the first node, it should be a root node + CommandNode rootNode = packet.getNodes()[packet.getFirstNodeIndex()]; // Loop through the root nodes to get all commands - for (CommandNode rootNode : rootNodes) { - for (int nodeIndex : rootNode.getChildIndices()) { - CommandNode node = packet.getNodes()[nodeIndex]; + for (int nodeIndex : rootNode.getChildIndices()) { + CommandNode node = packet.getNodes()[nodeIndex]; - // Make sure we dont have duplicated commands (happens if there is more than 1 root node) - if (commands.containsKey(nodeIndex)) { continue; } + // Make sure we dont have duplicated commands (happens if there is more than 1 root node) + if (commands.containsKey(nodeIndex)) { continue; } - // Get and update the commandArgs list with the found arguments - if (node.getChildIndices().length >= 1) { - for (int childIndex : node.getChildIndices()) { - commandArgs.putIfAbsent(nodeIndex, new ArrayList<>()); - commandArgs.get(nodeIndex).add(packet.getNodes()[childIndex]); - } + // Get and update the commandArgs list with the found arguments + if (node.getChildIndices().length >= 1) { + for (int childIndex : node.getChildIndices()) { + commandArgs.putIfAbsent(nodeIndex, new ArrayList<>()); + commandArgs.get(nodeIndex).add(packet.getNodes()[childIndex]); } - - // Insert the command name into the list - commands.put(nodeIndex, node.getName()); } + + // Insert the command name into the list + commands.put(nodeIndex, node.getName()); } // The command flags, not sure what these do apart from break things @@ -104,6 +94,8 @@ public class JavaServerDeclareCommandsTranslator extends PacketTranslator