From 0724b8639bf1a87a2120655f0296c7d116e91771 Mon Sep 17 00:00:00 2001 From: MrGazdag <44264503+MrGazdag@users.noreply.github.com> Date: Sat, 17 Jul 2021 21:20:10 +0200 Subject: [PATCH 1/5] Fix ArrayUtils#sameStart Fixes #370, which was a weird occurrence of this bug lmao --- src/main/java/net/minestom/server/utils/ArrayUtils.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/minestom/server/utils/ArrayUtils.java b/src/main/java/net/minestom/server/utils/ArrayUtils.java index 4a1e077cd..b25332366 100644 --- a/src/main/java/net/minestom/server/utils/ArrayUtils.java +++ b/src/main/java/net/minestom/server/utils/ArrayUtils.java @@ -94,11 +94,9 @@ public final class ArrayUtils { for (int i = 0; i < length; i++) { final T value1 = array1[i]; - for (int j = 0; j < length; j++) { - final T value2 = array2[j]; - if (!value1.equals(value2)) { - return false; - } + final T value2 = array2[i]; + if (!value1.equals(value2)) { + return false; } } return true; From 2ee14704709ad409c7fb2bd373cf770d604cc395 Mon Sep 17 00:00:00 2001 From: TheMode Date: Sat, 17 Jul 2021 21:38:32 +0200 Subject: [PATCH 2/5] Cleanup ArrayUtils --- .../net/minestom/server/utils/ArrayUtils.java | 52 +++++-------------- 1 file changed, 12 insertions(+), 40 deletions(-) diff --git a/src/main/java/net/minestom/server/utils/ArrayUtils.java b/src/main/java/net/minestom/server/utils/ArrayUtils.java index b25332366..356bd377c 100644 --- a/src/main/java/net/minestom/server/utils/ArrayUtils.java +++ b/src/main/java/net/minestom/server/utils/ArrayUtils.java @@ -1,30 +1,28 @@ package net.minestom.server.utils; import it.unimi.dsi.fastutil.ints.IntList; -import net.minestom.server.utils.validate.Check; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; -import java.util.function.Supplier; +import java.util.Objects; +@ApiStatus.Internal public final class ArrayUtils { private ArrayUtils() { - } - public static int[] concatenateIntArrays(@NotNull int[]... arrays) { + public static int[] concatenateIntArrays(int @NotNull []... arrays) { int totalLength = 0; for (int[] array : arrays) { totalLength += array.length; } int[] result = new int[totalLength]; - int startingPos = 0; for (int[] array : arrays) { System.arraycopy(array, 0, result, startingPos, array.length); startingPos += array.length; } - return result; } @@ -32,11 +30,6 @@ public final class ArrayUtils { System.arraycopy(arr, index + 1, arr, index, arr.length - 1 - index); } - public static void copyToDestination(short[] src, short[] dest) { - Check.argCondition(src.length != dest.length, "The two arrays need to have the same length."); - System.arraycopy(src, 0, dest, 0, src.length); - } - /** * Gets the differences between 2 arrays. * @@ -44,8 +37,7 @@ public final class ArrayUtils { * @param b the second array * @return an array containing a's indexes that aren't in b array */ - @NotNull - public static int[] getDifferencesBetweenArray(@NotNull long[] a, @NotNull long[] b) { + public static int @NotNull [] getDifferencesBetweenArray(long @NotNull [] a, long @NotNull [] b) { int counter = 0; int[] indexes = new int[Math.max(a.length, b.length)]; @@ -69,50 +61,30 @@ public final class ArrayUtils { return result; } - @NotNull - public static int[] toArray(@NotNull IntList list) { + public static int @NotNull [] toArray(@NotNull IntList list) { int[] array = new int[list.size()]; - for (int i = 0; i < array.length; i++) { - array[i] = list.getInt(i); - } + list.getElements(0, array, 0, array.length); return array; } /** * Gets if two arrays share the same start until {@code length}. * - * @param array1 the first array - * @param array2 the second array + * @param first the first array + * @param second the second array * @param length the length to check (0-length) * @param the type of the arrays * @return true if both arrays share the same start */ - public static boolean sameStart(T[] array1, T[] array2, int length) { - if (length > array1.length || length > array2.length) { + public static boolean sameStart(@NotNull T[] first, @NotNull T[] second, int length) { + if (Math.min(first.length, second.length) < length) { return false; } - for (int i = 0; i < length; i++) { - final T value1 = array1[i]; - final T value2 = array2[i]; - if (!value1.equals(value2)) { + if (!Objects.equals(first[i], second[i])) { return false; } } return true; } - - /** - * Fills an array using a supplier. - * - * @param array the array to fill - * @param supplier the supplier to fill the array - * @param the array type - */ - public static void fill(@NotNull T[] array, @NotNull Supplier supplier) { - for (int i = 0; i < array.length; i++) { - array[i] = supplier.get(); - } - } - } From 93fa65f90b200d6caf4310fb080c103bc160f021 Mon Sep 17 00:00:00 2001 From: TheMode Date: Sat, 17 Jul 2021 23:21:31 +0200 Subject: [PATCH 3/5] Temporary command node fix --- src/main/java/net/minestom/server/command/CommandManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/minestom/server/command/CommandManager.java b/src/main/java/net/minestom/server/command/CommandManager.java index ad9b5e5df..12587a92b 100644 --- a/src/main/java/net/minestom/server/command/CommandManager.java +++ b/src/main/java/net/minestom/server/command/CommandManager.java @@ -354,7 +354,7 @@ public final class CommandManager { final List storedNodes = storedArgumentsNodes.get(sharedArgument); argChildren = new IntArrayList(); - lastNodes = storedNodes.get(index); + lastNodes = storedNodes.get(storedNodes.size() > index ? index : i); foundSharedPart = true; } } From 97104df793d2137f81c3210a30af0c4c1458f1d5 Mon Sep 17 00:00:00 2001 From: TheMode Date: Sun, 18 Jul 2021 01:09:59 +0200 Subject: [PATCH 4/5] Potentially fix command node creation --- .../server/command/CommandManager.java | 55 ++++++++++++++++--- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/src/main/java/net/minestom/server/command/CommandManager.java b/src/main/java/net/minestom/server/command/CommandManager.java index 12587a92b..d07cd8d45 100644 --- a/src/main/java/net/minestom/server/command/CommandManager.java +++ b/src/main/java/net/minestom/server/command/CommandManager.java @@ -316,9 +316,9 @@ public final class CommandManager { final int literalNodeId = addCommandNameNode(literalNode, rootChildren, nodes); // Contains the arguments of the already-parsed syntaxes - List[]> syntaxesArguments = new ArrayList<>(); + Map[]> syntaxesArguments = new HashMap<>(); // Contains the nodes of an argument - Map, List> storedArgumentsNodes = new HashMap<>(); + Map> storedArgumentsNodes = new HashMap<>(); // Sort syntaxes by argument count. Brigadier requires it. syntaxes = syntaxes.stream().sorted(Comparator.comparingInt(o -> -o.getArguments().length)).collect(Collectors.toList()); @@ -347,14 +347,16 @@ public final class CommandManager { { // Find shared part boolean foundSharedPart = false; - for (Argument[] parsedArguments : syntaxesArguments) { + for (var entry : syntaxesArguments.entrySet()) { + final var parsedArguments = entry.getValue(); final int index = i + 1; if (ArrayUtils.sameStart(arguments, parsedArguments, index)) { final Argument sharedArgument = parsedArguments[i]; - final List storedNodes = storedArgumentsNodes.get(sharedArgument); + final var indexed = new IndexedArgument(entry.getKey(), sharedArgument, i); + final List storedNodes = storedArgumentsNodes.get(indexed); argChildren = new IntArrayList(); - lastNodes = storedNodes.get(storedNodes.size() > index ? index : i); + lastNodes = storedNodes.get(index); foundSharedPart = true; } } @@ -369,7 +371,7 @@ public final class CommandManager { // Each node array represent a layer final List nodesLayer = nodeMaker.getNodes(); - storedArgumentsNodes.put(argument, new ArrayList<>(nodesLayer)); + storedArgumentsNodes.put(new IndexedArgument(syntax, argument, i), new ArrayList<>(nodesLayer)); for (int nodeIndex = lastArgumentNodeIndex; nodeIndex < nodesLayer.size(); nodeIndex++) { final NodeMaker.ConfiguredNodes configuredNodes = nodeMaker.getConfiguredNodes().get(nodeIndex); final NodeMaker.Options options = configuredNodes.getOptions(); @@ -417,17 +419,18 @@ public final class CommandManager { nodeRequests.addAll(nodeMaker.getNodeRequests()); - syntaxesArguments.add(arguments); + syntaxesArguments.put(syntax, arguments); } - storedArgumentsNodes.forEach((argument, argNodes) -> { + storedArgumentsNodes.forEach((indexedArgument, argNodes) -> { int value = 0; for (DeclareCommandsPacket.Node[] n1 : argNodes) { for (DeclareCommandsPacket.Node n2 : n1) { value = nodes.indexOf(n2); } } - argumentIdentityMap.put(argument, value); + // FIXME: add syntax for indexing + argumentIdentityMap.put(indexedArgument.argument, value); }); literalNode.children = ArrayUtils.toArray(cmdChildren); @@ -451,4 +454,38 @@ public final class CommandManager { nodes.add(commandNode); return node; } + + private static class IndexedArgument { + private final CommandSyntax syntax; + private final Argument argument; + private final int index; + + public IndexedArgument(CommandSyntax syntax, Argument argument, int index) { + this.syntax = syntax; + this.argument = argument; + this.index = index; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + IndexedArgument that = (IndexedArgument) o; + return index == that.index && Objects.equals(syntax, that.syntax) && Objects.equals(argument, that.argument); + } + + @Override + public int hashCode() { + return Objects.hash(syntax, argument, index); + } + + @Override + public String toString() { + return "IndexedArgument{" + + "syntax=" + syntax + + ", argument=" + argument + + ", index=" + index + + '}'; + } + } } From a07177fbf0f96d9a2affc31bddf5322bbbe01752 Mon Sep 17 00:00:00 2001 From: TheMode Date: Sun, 18 Jul 2021 02:13:20 +0200 Subject: [PATCH 5/5] Prevent IOB --- src/main/java/net/minestom/server/command/CommandManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/minestom/server/command/CommandManager.java b/src/main/java/net/minestom/server/command/CommandManager.java index d07cd8d45..b908bd6c3 100644 --- a/src/main/java/net/minestom/server/command/CommandManager.java +++ b/src/main/java/net/minestom/server/command/CommandManager.java @@ -356,7 +356,7 @@ public final class CommandManager { final List storedNodes = storedArgumentsNodes.get(indexed); argChildren = new IntArrayList(); - lastNodes = storedNodes.get(index); + lastNodes = storedNodes.get(storedNodes.size() >= index ? index : 1); foundSharedPart = true; } }