diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt
index 3963b978..ecc19b27 100644
--- a/buildSrc/src/main/kotlin/Versions.kt
+++ b/buildSrc/src/main/kotlin/Versions.kt
@@ -26,7 +26,7 @@ object Versions {
const val fabricLoader = "0.11.1"
const val fabricMc = "1.16.5"
const val fabricYarn = "1"
- const val fabricApi = "0.29.3+1.16"
+ const val fabricApi = "0.31.0+1.16"
// IRC DEPENDENCIES
const val pircbotx = "83a4c22e80"
diff --git a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/FabricClientCommandManager.java b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/FabricClientCommandManager.java
new file mode 100644
index 00000000..31594c1b
--- /dev/null
+++ b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/FabricClientCommandManager.java
@@ -0,0 +1,114 @@
+//
+// MIT License
+//
+// Copyright (c) 2021 Alexander Söderberg & Contributors
+//
+// 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.
+//
+
+package cloud.commandframework.fabric;
+
+import cloud.commandframework.CommandTree;
+import cloud.commandframework.execution.AsynchronousCommandExecutionCoordinator;
+import cloud.commandframework.execution.CommandExecutionCoordinator;
+import net.fabricmc.fabric.api.client.command.v1.FabricClientCommandSource;
+import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.network.ClientCommandSource;
+import org.checkerframework.checker.nullness.qual.NonNull;
+
+import java.util.function.Function;
+
+/**
+ * A command manager for registering client-side commands.
+ *
+ *
All commands should be registered within mod initializers. Any registrations occurring after the first call to
+ * {@link CommandRegistrationCallback} will be considered unsafe, and will only be permitted when the unsafe
+ * registration manager option is enabled.
+ *
+ * @param the command sender type
+ * @since 1.5.0
+ */
+public final class FabricClientCommandManager extends FabricCommandManager {
+
+ /**
+ * Create a command manager using native source types.
+ *
+ * @param execCoordinator Execution coordinator instance.
+ * @return a new command manager
+ * @see #FabricClientCommandManager(Function, Function, Function) for a more thorough explanation
+ */
+ public static FabricClientCommandManager createNative(
+ final Function, CommandExecutionCoordinator> execCoordinator
+ ) {
+ return new FabricClientCommandManager<>(execCoordinator, Function.identity(), Function.identity());
+ }
+
+ /**
+ * Create a new command manager instance.
+ *
+ * @param commandExecutionCoordinator Execution coordinator instance. The coordinator is in charge of executing incoming
+ * commands. Some considerations must be made when picking a suitable execution coordinator
+ * for your platform. For example, an entirely asynchronous coordinator is not suitable
+ * when the parsers used in that particular platform are not thread safe. If you have
+ * commands that perform blocking operations, however, it might not be a good idea to
+ * use a synchronous execution coordinator. In most cases you will want to pick between
+ * {@link CommandExecutionCoordinator#simpleCoordinator()} and
+ * {@link AsynchronousCommandExecutionCoordinator}
+ * @param commandSourceMapper Function that maps {@link FabricClientCommandSource} to the command sender type
+ * @param backwardsCommandSourceMapper Function that maps the command sender type to {@link FabricClientCommandSource}
+ */
+ @SuppressWarnings("unchecked")
+ public FabricClientCommandManager(
+ final @NonNull Function<@NonNull CommandTree, @NonNull CommandExecutionCoordinator> commandExecutionCoordinator,
+ final Function commandSourceMapper,
+ final Function backwardsCommandSourceMapper
+ ) {
+ super(
+ commandExecutionCoordinator,
+ commandSourceMapper,
+ backwardsCommandSourceMapper,
+ new FabricCommandRegistrationHandler.Client<>(),
+ () -> (FabricClientCommandSource) new ClientCommandSource(
+ MinecraftClient.getInstance().getNetworkHandler(),
+ MinecraftClient.getInstance()
+ )
+ );
+
+ this.registerParsers();
+ }
+
+ private void registerParsers() {
+ }
+
+ /**
+ * Check if a sender has a certain permission.
+ *
+ * The implementation for client commands always returns true.
+ *
+ * @param sender Command sender
+ * @param permission Permission node
+ * @return whether the sender has the specified permission
+ */
+ @Override
+ public boolean hasPermission(@NonNull final C sender, @NonNull final String permission) {
+ return true;
+ }
+
+}
diff --git a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/FabricCommandManager.java b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/FabricCommandManager.java
index 2fd5591b..916920dc 100644
--- a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/FabricCommandManager.java
+++ b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/FabricCommandManager.java
@@ -74,7 +74,6 @@ import net.minecraft.particle.ParticleEffect;
import net.minecraft.predicate.NumberRange;
import net.minecraft.scoreboard.ScoreboardCriterion;
import net.minecraft.scoreboard.Team;
-import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.Direction;
@@ -107,7 +106,7 @@ import java.util.function.Supplier;
* @param the manager's sender type
* @param the platform sender type
* @see FabricServerCommandManager for server commands
- * @since 1.4.0
+ * @since 1.5.0
*/
public abstract class FabricCommandManager extends CommandManager implements BrigadierManagerHolder {
private static final Logger LOGGER = LogManager.getLogger();
@@ -129,8 +128,8 @@ public abstract class FabricCommandManager extends C
* use a synchronous execution coordinator. In most cases you will want to pick between
* {@link CommandExecutionCoordinator#simpleCoordinator()} and
* {@link AsynchronousCommandExecutionCoordinator}
- * @param commandSourceMapper Function that maps {@link ServerCommandSource} to the command sender type
- * @param backwardsCommandSourceMapper Function that maps the command sender type to {@link ServerCommandSource}
+ * @param commandSourceMapper Function that maps {@link CommandSource} to the command sender type
+ * @param backwardsCommandSourceMapper Function that maps the command sender type to {@link CommandSource}
* @param registrationHandler the handler accepting command registrations
* @param dummyCommandSourceProvider a provider of a dummy command source, for use with brigadier registration
*/
@@ -323,7 +322,7 @@ public abstract class FabricCommandManager extends C
}
/**
- * Gets the mapper from a game {@link ServerCommandSource} to the manager's {@code C} type.
+ * Gets the mapper from a game {@link CommandSource} to the manager's {@code C} type.
*
* @return Command source mapper
*/
@@ -332,7 +331,7 @@ public abstract class FabricCommandManager extends C
}
/**
- * Gets the mapper from the manager's {@code C} type to a game {@link ServerCommandSource}.
+ * Gets the mapper from the manager's {@code C} type to a game {@link CommandSource}.
*
* @return Command source mapper
*/
diff --git a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/FabricCommandRegistrationHandler.java b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/FabricCommandRegistrationHandler.java
index 91ae71d9..b981092a 100644
--- a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/FabricCommandRegistrationHandler.java
+++ b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/FabricCommandRegistrationHandler.java
@@ -32,6 +32,8 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.CommandNode;
import com.mojang.brigadier.tree.LiteralCommandNode;
import com.mojang.brigadier.tree.RootCommandNode;
+import net.fabricmc.fabric.api.client.command.v1.ClientCommandManager;
+import net.fabricmc.fabric.api.client.command.v1.FabricClientCommandSource;
import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback;
import net.minecraft.command.CommandSource;
import net.minecraft.server.command.CommandManager.RegistrationEnvironment;
@@ -61,6 +63,80 @@ abstract class FabricCommandRegistrationHandler impl
return this.commandManager;
}
+ /**
+ * Returns a literal node that redirects its execution to
+ * the given destination node.
+ *
+ * This method is taken from MIT licensed code in the Velocity project, see
+ *
+ * Velocity's BrigadierUtils class
+ *
+ * @param alias the command alias
+ * @param destination the destination node
+ * @param brig sender type
+ * @return the built node
+ */
+ private static LiteralCommandNode buildRedirect(
+ final @NonNull String alias,
+ final @NonNull CommandNode destination
+ ) {
+ // Redirects only work for nodes with children, but break the top argument-less command.
+ // Manually adding the root command after setting the redirect doesn't fix it.
+ // (See https://github.com/Mojang/brigadier/issues/46) Manually clone the node instead.
+ LiteralArgumentBuilder builder = LiteralArgumentBuilder
+ .literal(alias)
+ .requires(destination.getRequirement())
+ .forward(
+ destination.getRedirect(),
+ destination.getRedirectModifier(),
+ destination.isFork()
+ )
+ .executes(destination.getCommand());
+ for (final CommandNode child : destination.getChildren()) {
+ builder.then(child);
+ }
+ return builder.build();
+ }
+
+ static class Client extends FabricCommandRegistrationHandler {
+ @Override
+ void initialize(final FabricCommandManager manager) {
+ super.initialize(manager);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public boolean registerCommand(final @NonNull Command> cmd) {
+ final Command command = (Command) cmd;
+ final RootCommandNode rootNode = ClientCommandManager.DISPATCHER.getRoot();
+ final StaticArgument first = ((StaticArgument) command.getArguments().get(0));
+ final CommandNode baseNode = this
+ .getCommandManager()
+ .brigadierManager()
+ .createLiteralCommandNode(
+ first.getName(),
+ command,
+ (src, perm) -> this.getCommandManager().hasPermission(
+ this.getCommandManager().getCommandSourceMapper().apply(src),
+ perm
+ ),
+ true,
+ new FabricExecutor<>(
+ this.getCommandManager(),
+ source -> source.getPlayer().getName().asString(),
+ FabricClientCommandSource::sendError
+ )
+ );
+
+ rootNode.addChild(baseNode);
+
+ for (final String alias : first.getAlternativeAliases()) {
+ rootNode.addChild(buildRedirect(alias, baseNode));
+ }
+ return true;
+ }
+ }
+
static class Server extends FabricCommandRegistrationHandler {
private final Set> registeredCommands = ConcurrentHashMap.newKeySet();
@@ -112,40 +188,5 @@ abstract class FabricCommandRegistrationHandler impl
dispatcher.addChild(buildRedirect(alias, baseNode));
}
}
-
- /**
- * Returns a literal node that redirects its execution to
- * the given destination node.
- *
- * This method is taken from MIT licensed code in the Velocity project, see
- *
- * Velocity's BrigadierUtils class
- *
- * @param alias the command alias
- * @param destination the destination node
- * @return the built node
- */
- private static LiteralCommandNode buildRedirect(
- final @NonNull String alias,
- final @NonNull CommandNode destination
- ) {
- // Redirects only work for nodes with children, but break the top argument-less command.
- // Manually adding the root command after setting the redirect doesn't fix it.
- // (See https://github.com/Mojang/brigadier/issues/46) Manually clone the node instead.
- LiteralArgumentBuilder builder = LiteralArgumentBuilder
- .literal(alias)
- .requires(destination.getRequirement())
- .forward(
- destination.getRedirect(),
- destination.getRedirectModifier(),
- destination.isFork()
- )
- .executes(destination.getCommand());
- for (final CommandNode child : destination.getChildren()) {
- builder.then(child);
- }
- return builder.build();
- }
-
}
}
diff --git a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/FabricExecutor.java b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/FabricExecutor.java
index d54f6842..7517ba16 100644
--- a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/FabricExecutor.java
+++ b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/FabricExecutor.java
@@ -104,7 +104,7 @@ final class FabricExecutor implements Command {
this.sendError.accept(
source,
new LiteralText("Invalid Command Syntax. Correct command syntax is: ")
- .append(new LiteralText(e.getCorrectSyntax())
+ .append(new LiteralText(String.format("/%s", e.getCorrectSyntax()))
.styled(style -> style.withColor(Formatting.GRAY))))
);
} else if (throwable instanceof InvalidCommandSenderException) {
diff --git a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/FabricServerCommandManager.java b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/FabricServerCommandManager.java
index 75c25a2a..d7283d87 100644
--- a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/FabricServerCommandManager.java
+++ b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/FabricServerCommandManager.java
@@ -52,7 +52,7 @@ import java.util.function.Function;
* registration manager option is enabled.
*
* @param the command sender type
- * @since 1.4.0
+ * @since 1.5.0
*/
public final class FabricServerCommandManager extends FabricCommandManager {
diff --git a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/AngleArgument.java b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/AngleArgument.java
index 18d33628..a8f01df9 100644
--- a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/AngleArgument.java
+++ b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/AngleArgument.java
@@ -38,7 +38,7 @@ import java.util.function.BiFunction;
* An argument for an angle, specified in degrees.
*
* @param the sender type
- * @since 1.4.0
+ * @since 1.5.0
*/
public final class AngleArgument extends CommandArgument {
diff --git a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/AxisArgument.java b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/AxisArgument.java
index e5511dbe..42c1c6e1 100644
--- a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/AxisArgument.java
+++ b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/AxisArgument.java
@@ -42,7 +42,7 @@ import java.util.function.BiFunction;
* An argument for a set of axes, described in Vanilla as a "swizzle".
*
* @param the sender type
- * @since 1.4.0
+ * @since 1.5.0
*/
public final class AxisArgument extends CommandArgument> {
private static final TypeToken> TYPE = new TypeToken>() {};
diff --git a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/ColorArgument.java b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/ColorArgument.java
index 86598f17..39824434 100644
--- a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/ColorArgument.java
+++ b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/ColorArgument.java
@@ -39,7 +39,7 @@ import java.util.function.BiFunction;
* An argument for named colors in the {@link Formatting} enum.
*
* @param the sender type
- * @since 1.4.0
+ * @since 1.5.0
*/
public final class ColorArgument extends CommandArgument {
diff --git a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/CompoundTagArgument.java b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/CompoundTagArgument.java
index b50fd876..8412cb8d 100644
--- a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/CompoundTagArgument.java
+++ b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/CompoundTagArgument.java
@@ -39,7 +39,7 @@ import java.util.function.BiFunction;
* An argument for the string representation of an NBT {@link CompoundTag}.
*
* @param the sender type
- * @since 1.4.0
+ * @since 1.5.0
*/
public final class CompoundTagArgument extends CommandArgument {
diff --git a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/EntityAnchorArgument.java b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/EntityAnchorArgument.java
index ecb68080..1df70859 100644
--- a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/EntityAnchorArgument.java
+++ b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/EntityAnchorArgument.java
@@ -38,7 +38,7 @@ import java.util.function.BiFunction;
* An argument parsing an entity anchor.
*
* @param the sender type
- * @since 1.4.0
+ * @since 1.5.0
*/
public final class EntityAnchorArgument extends CommandArgument {
diff --git a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/FabricArgumentParsers.java b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/FabricArgumentParsers.java
index 6e81a546..6981fbba 100644
--- a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/FabricArgumentParsers.java
+++ b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/FabricArgumentParsers.java
@@ -50,7 +50,7 @@ import java.util.HashSet;
/**
* Parsers for Vanilla command argument types.
*
- * @since 1.4.0
+ * @since 1.5.0
*/
public final class FabricArgumentParsers {
@@ -68,6 +68,7 @@ public final class FabricArgumentParsers {
.map((ctx, val) -> ArgumentParseResult.success(MinecraftTime.of(val)));
}
+ /*
public static ArgumentParser commandFunction() {
// TODO: Should probably write our own parser for this, it's either Identifier or tag.
// Server parsers
@@ -76,6 +77,7 @@ public final class FabricArgumentParsers {
source.getCompletions()
})
}
+ */
public static ArgumentParser message() {
return new WrappedBrigadierParser(MessageArgumentType.message())
diff --git a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/FloatRangeArgument.java b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/FloatRangeArgument.java
index e7ade188..7bcc32f6 100644
--- a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/FloatRangeArgument.java
+++ b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/FloatRangeArgument.java
@@ -40,7 +40,7 @@ import java.util.function.BiFunction;
* optional.
*
* @param the sender type
- * @since 1.4.0
+ * @since 1.5.0
*/
public final class FloatRangeArgument extends CommandArgument {
diff --git a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/IdentifierArgument.java b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/IdentifierArgument.java
index 4fbf2a51..2c442691 100644
--- a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/IdentifierArgument.java
+++ b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/IdentifierArgument.java
@@ -39,7 +39,7 @@ import java.util.function.BiFunction;
* An argument parsing an identifier, or "resource location".
*
* @param the sender type
- * @since 1.4.0
+ * @since 1.5.0
*/
public final class IdentifierArgument extends CommandArgument {
diff --git a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/IntRangeArgument.java b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/IntRangeArgument.java
index 1484e681..8a4675f3 100644
--- a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/IntRangeArgument.java
+++ b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/IntRangeArgument.java
@@ -40,7 +40,7 @@ import java.util.function.BiFunction;
* optional.
*
* @param the sender type
- * @since 1.4.0
+ * @since 1.5.0
*/
public final class IntRangeArgument extends CommandArgument {
diff --git a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/ItemDataArgument.java b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/ItemDataArgument.java
index 7fc34c74..07ccd735 100644
--- a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/ItemDataArgument.java
+++ b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/ItemDataArgument.java
@@ -41,7 +41,7 @@ import java.util.function.BiFunction;
* An argument parsing an item identifier and optional NBT data
*
* @param the sender type
- * @since 1.4.0
+ * @since 1.5.0
*/
public final class ItemDataArgument extends CommandArgument {
diff --git a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/NbtPathArgument.java b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/NbtPathArgument.java
index 076d8837..f0170be0 100644
--- a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/NbtPathArgument.java
+++ b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/NbtPathArgument.java
@@ -38,7 +38,7 @@ import java.util.function.BiFunction;
* An argument for NBT paths to locations within {@link net.minecraft.nbt.Tag Tags}.
*
* @param the sender type
- * @since 1.4.0
+ * @since 1.5.0
*/
public final class NbtPathArgument extends CommandArgument {
diff --git a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/NbtTagArgument.java b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/NbtTagArgument.java
index 8fc5669e..aea75351 100644
--- a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/NbtTagArgument.java
+++ b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/NbtTagArgument.java
@@ -39,7 +39,7 @@ import java.util.function.BiFunction;
* An argument for the string representation of an NBT {@link Tag}.
*
* @param the sender type
- * @since 1.4.0
+ * @since 1.5.0
*/
public final class NbtTagArgument extends CommandArgument {
diff --git a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/ParticleEffectArgument.java b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/ParticleEffectArgument.java
index 14e6cbd8..04b02199 100644
--- a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/ParticleEffectArgument.java
+++ b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/ParticleEffectArgument.java
@@ -41,7 +41,7 @@ import java.util.function.BiFunction;
* These operations can be used to compare scores on a {@link net.minecraft.scoreboard.Scoreboard}.
*
* @param the sender type
- * @since 1.4.0
+ * @since 1.5.0
*/
public final class ParticleEffectArgument extends CommandArgument {
diff --git a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/RegistryEntryArgument.java b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/RegistryEntryArgument.java
index 5b5b96cc..35be539e 100644
--- a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/RegistryEntryArgument.java
+++ b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/RegistryEntryArgument.java
@@ -58,7 +58,7 @@ import static java.util.Objects.requireNonNull;
*
* @param the command sender type
* @param the registry entry type
- * @since 1.4.0
+ * @since 1.5.0
*/
public class RegistryEntryArgument extends CommandArgument {
private static final String NAMESPACE_MINECRAFT = "minecraft";
diff --git a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/ScoreboardCriterionArgument.java b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/ScoreboardCriterionArgument.java
index bf72f926..96465dcd 100644
--- a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/ScoreboardCriterionArgument.java
+++ b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/ScoreboardCriterionArgument.java
@@ -39,7 +39,7 @@ import java.util.function.BiFunction;
* An argument for a {@linkplain ScoreboardCriterion criterion} in a scoreboard.
*
* @param the sender type
- * @since 1.4.0
+ * @since 1.5.0
*/
public final class ScoreboardCriterionArgument extends CommandArgument {
diff --git a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/ScoreboardOperationArgument.java b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/ScoreboardOperationArgument.java
index b61288b2..6414f978 100644
--- a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/ScoreboardOperationArgument.java
+++ b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/ScoreboardOperationArgument.java
@@ -41,7 +41,7 @@ import java.util.function.BiFunction;
* These operations can be used to compare scores on a {@link net.minecraft.scoreboard.Scoreboard}.
*
* @param the sender type
- * @since 1.4.0
+ * @since 1.5.0
*/
public final class ScoreboardOperationArgument extends CommandArgument {
diff --git a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/StatusEffectArgument.java b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/StatusEffectArgument.java
index 32c88c3c..608b8629 100644
--- a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/StatusEffectArgument.java
+++ b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/StatusEffectArgument.java
@@ -40,7 +40,7 @@ import java.util.function.BiFunction;
* An argument parsing a status effect from the {@link net.minecraft.util.registry.Registry#STATUS_EFFECT status effect registry}
*
* @param the sender type
- * @since 1.4.0
+ * @since 1.5.0
*/
public final class StatusEffectArgument extends CommandArgument {
diff --git a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/TeamArgument.java b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/TeamArgument.java
index 71bfc21a..1057b805 100644
--- a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/TeamArgument.java
+++ b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/TeamArgument.java
@@ -49,7 +49,7 @@ import java.util.function.BiFunction;
* An argument parsing an entity anchor.
*
* @param the sender type
- * @since 1.4.0
+ * @since 1.5.0
*/
public final class TeamArgument extends CommandArgument {
@@ -182,6 +182,7 @@ public final class TeamArgument extends CommandArgument {
}
public static final class UnknownTeamException extends ParserException {
+ private static final long serialVersionUID = 4249139487412603424L;
UnknownTeamException(
final @NonNull CommandContext> context,
diff --git a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/TimeArgument.java b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/TimeArgument.java
index 40d52e3e..73fbb7e4 100644
--- a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/TimeArgument.java
+++ b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/TimeArgument.java
@@ -40,7 +40,7 @@ import java.util.function.BiFunction;
* An argument for in-game time
*
* @param the sender type
- * @since 1.4.0
+ * @since 1.5.0
*/
public final class TimeArgument extends CommandArgument {
diff --git a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/server/MessageArgument.java b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/server/MessageArgument.java
index 5f2ee9f5..07c62cf2 100644
--- a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/server/MessageArgument.java
+++ b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/server/MessageArgument.java
@@ -52,7 +52,7 @@ import java.util.function.BiFunction;
* An argument similar to a greedy string, but one that resolves selectors.
*
* @param the sender type
- * @since 1.4.0
+ * @since 1.5.0
*/
public final class MessageArgument extends CommandArgument {
diff --git a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/server/package-info.java b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/server/package-info.java
index d9d6e251..28fb5ab6 100644
--- a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/server/package-info.java
+++ b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/argument/server/package-info.java
@@ -25,6 +25,6 @@
/**
* Command arguments that can only be used on the logical server.
*
- * @since 1.4.0
+ * @since 1.5.0
*/
package cloud.commandframework.fabric.argument.server;
diff --git a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/data/MinecraftTime.java b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/data/MinecraftTime.java
index caf3aa60..348c2fa9 100644
--- a/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/data/MinecraftTime.java
+++ b/cloud-minecraft/cloud-fabric/src/main/java/cloud/commandframework/fabric/data/MinecraftTime.java
@@ -35,7 +35,7 @@ import static java.util.Objects.requireNonNull;
*
* The basic unit is 1 tick, which aims to be {@code 50ms}
*
- * @since 1.4.0
+ * @since 1.5.0
*/
public final class MinecraftTime {
private static final MinecraftTime ZERO = new MinecraftTime(0);
diff --git a/cloud-minecraft/cloud-fabric/src/testmod/java/cloud/commandframework/fabric/testmod/FabricClientExample.java b/cloud-minecraft/cloud-fabric/src/testmod/java/cloud/commandframework/fabric/testmod/FabricClientExample.java
new file mode 100644
index 00000000..8c01e3a4
--- /dev/null
+++ b/cloud-minecraft/cloud-fabric/src/testmod/java/cloud/commandframework/fabric/testmod/FabricClientExample.java
@@ -0,0 +1,48 @@
+//
+// MIT License
+//
+// Copyright (c) 2021 Alexander Söderberg & Contributors
+//
+// 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.
+//
+package cloud.commandframework.fabric.testmod;
+
+import cloud.commandframework.arguments.standard.StringArgument;
+import cloud.commandframework.execution.CommandExecutionCoordinator;
+import cloud.commandframework.fabric.FabricClientCommandManager;
+import net.fabricmc.api.ClientModInitializer;
+import net.fabricmc.fabric.api.client.command.v1.FabricClientCommandSource;
+import net.minecraft.text.Text;
+
+public class FabricClientExample implements ClientModInitializer {
+ @Override
+ public void onInitializeClient() {
+ final FabricClientCommandManager commandManager =
+ FabricClientCommandManager.createNative(CommandExecutionCoordinator.simpleCoordinator());
+
+ commandManager.command(
+ commandManager.commandBuilder("cloud_client")
+ .literal("say")
+ .argument(StringArgument.greedy("message"))
+ .handler(ctx -> ctx.getSender().sendFeedback(
+ Text.of("Cloud client commands says: " + ctx.get("message"))
+ ))
+ );
+ }
+}
diff --git a/cloud-minecraft/cloud-fabric/src/testmod/resources/fabric.mod.json b/cloud-minecraft/cloud-fabric/src/testmod/resources/fabric.mod.json
index 7144a098..bb29107c 100644
--- a/cloud-minecraft/cloud-fabric/src/testmod/resources/fabric.mod.json
+++ b/cloud-minecraft/cloud-fabric/src/testmod/resources/fabric.mod.json
@@ -16,6 +16,9 @@
"entrypoints": {
"main": [
"cloud.commandframework.fabric.testmod.FabricExample"
+ ],
+ "client": [
+ "cloud.commandframework.fabric.testmod.FabricClientExample"
]
},
diff --git a/cloud-minecraft/cloud-minecraft-extras/src/main/java/cloud/commandframework/minecraft/extras/MinecraftExceptionHandler.java b/cloud-minecraft/cloud-minecraft-extras/src/main/java/cloud/commandframework/minecraft/extras/MinecraftExceptionHandler.java
index 815629c5..0985c30f 100644
--- a/cloud-minecraft/cloud-minecraft-extras/src/main/java/cloud/commandframework/minecraft/extras/MinecraftExceptionHandler.java
+++ b/cloud-minecraft/cloud-minecraft-extras/src/main/java/cloud/commandframework/minecraft/extras/MinecraftExceptionHandler.java
@@ -108,6 +108,7 @@ public final class MinecraftExceptionHandler {
final HoverEvent hover = HoverEvent.showText(
Component.text()
.append(getMessage(cause))
+ .append(Component.newline())
.append(Component.text(stackTrace))
.append(Component.newline())
.append(Component.text(