aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/de/hysky/skyblocker/utils
diff options
context:
space:
mode:
authorKevin <92656833+kevinthegreat1@users.noreply.github.com>2024-07-14 21:37:45 +0800
committerGitHub <noreply@github.com>2024-07-14 21:37:45 +0800
commit1d1cfea67947dada26ac178d24c75beba677770f (patch)
tree48cc2a5ab9e2dbcd2060bb06c90e0d7615441a4e /src/main/java/de/hysky/skyblocker/utils
parent8fc27fc21c7ac1b72f8327da0855db9148c69895 (diff)
parent3a7dce4e3d60232805e6fb07ec5cbd5c26b7673e (diff)
downloadSkyblocker-1d1cfea67947dada26ac178d24c75beba677770f.tar.gz
Skyblocker-1d1cfea67947dada26ac178d24c75beba677770f.tar.bz2
Skyblocker-1d1cfea67947dada26ac178d24c75beba677770f.zip
Merge pull request #834 from Emirlol/command-changes
Add some custom command argument types
Diffstat (limited to 'src/main/java/de/hysky/skyblocker/utils')
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/EggTypeArgumentType.java40
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/blockpos/ClientBlockPosArgumentType.java72
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/blockpos/ClientPosArgument.java27
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/blockpos/DefaultClientPosArgument.java113
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/blockpos/LookingClientPosArgument.java106
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/color/ColorArgumentType.java28
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/color/HexColorArgumentType.java38
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/color/RgbColorArgumentType.java39
8 files changed, 463 insertions, 0 deletions
diff --git a/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/EggTypeArgumentType.java b/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/EggTypeArgumentType.java
new file mode 100644
index 00000000..a6532ff8
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/EggTypeArgumentType.java
@@ -0,0 +1,40 @@
+package de.hysky.skyblocker.utils.command.argumenttypes;
+
+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 de.hysky.skyblocker.skyblock.chocolatefactory.EggFinder;
+import net.minecraft.command.CommandSource;
+
+import java.util.Collection;
+import java.util.concurrent.CompletableFuture;
+
+public final class EggTypeArgumentType implements ArgumentType<EggFinder.EggType> {
+ @Override
+ public EggFinder.EggType parse(StringReader reader) throws CommandSyntaxException {
+ String name = reader.readUnquotedString();
+ for (EggFinder.EggType type : EggFinder.EggType.entries) {
+ if (type.name().equalsIgnoreCase(name)) return type;
+ }
+ throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownArgument().create();
+ }
+
+ @Override
+ public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
+ return context.getSource() instanceof CommandSource
+ ? CommandSource.suggestMatching(EggFinder.EggType.entries.stream().map(EggFinder.EggType::name).map(String::toLowerCase), builder)
+ : Suggestions.empty();
+ }
+
+ @Override
+ public Collection<String> getExamples() {
+ return EggFinder.EggType.entries.stream().map(EggFinder.EggType::name).map(String::toLowerCase).toList();
+ }
+
+ public static EggTypeArgumentType eggType() {
+ return new EggTypeArgumentType();
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/blockpos/ClientBlockPosArgumentType.java b/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/blockpos/ClientBlockPosArgumentType.java
new file mode 100644
index 00000000..3a226414
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/blockpos/ClientBlockPosArgumentType.java
@@ -0,0 +1,72 @@
+package de.hysky.skyblocker.utils.command.argumenttypes.blockpos;
+
+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 net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
+import net.minecraft.client.world.ClientWorld;
+import net.minecraft.command.CommandSource;
+import net.minecraft.command.argument.BlockPosArgumentType;
+import net.minecraft.server.command.CommandManager;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.World;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.concurrent.CompletableFuture;
+
+import static net.minecraft.command.argument.BlockPosArgumentType.*;
+
+// Uses the static fields of BlockPosArgumentType to not create the same field twice
+public class ClientBlockPosArgumentType implements ArgumentType<ClientPosArgument> {
+ public static ClientBlockPosArgumentType blockPos() {
+ return new ClientBlockPosArgumentType();
+ }
+
+ public static BlockPos getLoadedBlockPos(CommandContext<FabricClientCommandSource> context, String name) throws CommandSyntaxException {
+ return getLoadedBlockPos(context, context.getSource().getWorld(), name);
+ }
+
+ public static BlockPos getLoadedBlockPos(CommandContext<FabricClientCommandSource> context, ClientWorld world, String name) throws CommandSyntaxException {
+ BlockPos blockPos = getBlockPos(context, name);
+ if (!world.isChunkLoaded(blockPos)) throw UNLOADED_EXCEPTION.create();
+ if (!world.isInBuildLimit(blockPos)) throw OUT_OF_WORLD_EXCEPTION.create();
+
+ return blockPos;
+ }
+
+ public static BlockPos getBlockPos(CommandContext<FabricClientCommandSource> context, String name) {
+ return context.getArgument(name, ClientPosArgument.class).toAbsoluteBlockPos(context.getSource());
+ }
+
+ public static BlockPos getValidBlockPos(CommandContext<FabricClientCommandSource> context, String name) throws CommandSyntaxException {
+ BlockPos blockPos = getBlockPos(context, name);
+ if (!World.isValid(blockPos)) {
+ throw OUT_OF_BOUNDS_EXCEPTION.create();
+ } else {
+ return blockPos;
+ }
+ }
+
+ public ClientPosArgument parse(StringReader stringReader) throws CommandSyntaxException {
+ return stringReader.canRead() && stringReader.peek() == '^' ? LookingClientPosArgument.parse(stringReader) : DefaultClientPosArgument.parse(stringReader);
+ }
+
+ @Override
+ public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
+ if (!(context.getSource() instanceof CommandSource commandSource)) return Suggestions.empty();
+
+ String string = builder.getRemaining();
+ Collection<CommandSource.RelativePosition> collection = !string.isEmpty() && string.charAt(0) == '^' ? Collections.singleton(CommandSource.RelativePosition.ZERO_LOCAL) : commandSource.getBlockPositionSuggestions();
+
+ return CommandSource.suggestPositions(string, collection, builder, CommandManager.getCommandValidator(this::parse));
+ }
+
+ @Override
+ public Collection<String> getExamples() {
+ return BlockPosArgumentType.EXAMPLES;
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/blockpos/ClientPosArgument.java b/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/blockpos/ClientPosArgument.java
new file mode 100644
index 00000000..3dff86ab
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/blockpos/ClientPosArgument.java
@@ -0,0 +1,27 @@
+package de.hysky.skyblocker.utils.command.argumenttypes.blockpos;
+
+import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.Vec2f;
+import net.minecraft.util.math.Vec3d;
+
+/**
+ * This interface, its 2 implementations and ClientBlockPosArgumentType are all copied from minecraft
+ * and converted to use FabricClientCommandSource instead of ServerCommandSource.
+ * This removes the need for hacky workarounds such as creating new ServerCommandSources with null or 0 on every argument.
+ */
+public interface ClientPosArgument {
+ Vec3d toAbsolutePos(FabricClientCommandSource source);
+
+ Vec2f toAbsoluteRotation(FabricClientCommandSource source);
+
+ default BlockPos toAbsoluteBlockPos(FabricClientCommandSource source) {
+ return BlockPos.ofFloored(this.toAbsolutePos(source));
+ }
+
+ boolean isXRelative();
+
+ boolean isYRelative();
+
+ boolean isZRelative();
+}
diff --git a/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/blockpos/DefaultClientPosArgument.java b/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/blockpos/DefaultClientPosArgument.java
new file mode 100644
index 00000000..47258b9f
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/blockpos/DefaultClientPosArgument.java
@@ -0,0 +1,113 @@
+package de.hysky.skyblocker.utils.command.argumenttypes.blockpos;
+
+import com.mojang.brigadier.StringReader;
+import com.mojang.brigadier.exceptions.CommandSyntaxException;
+import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
+import net.minecraft.command.argument.CoordinateArgument;
+import net.minecraft.command.argument.Vec3ArgumentType;
+import net.minecraft.util.math.Vec2f;
+import net.minecraft.util.math.Vec3d;
+
+public class DefaultClientPosArgument implements ClientPosArgument {
+ private final CoordinateArgument x;
+ private final CoordinateArgument y;
+ private final CoordinateArgument z;
+
+ public DefaultClientPosArgument(CoordinateArgument x, CoordinateArgument y, CoordinateArgument z) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ @Override
+ public Vec3d toAbsolutePos(FabricClientCommandSource source) {
+ Vec3d vec3d = source.getPosition();
+ return new Vec3d(this.x.toAbsoluteCoordinate(vec3d.x), this.y.toAbsoluteCoordinate(vec3d.y), this.z.toAbsoluteCoordinate(vec3d.z));
+ }
+
+ @Override
+ public Vec2f toAbsoluteRotation(FabricClientCommandSource source) {
+ Vec2f vec2f = source.getRotation();
+ return new Vec2f((float)this.x.toAbsoluteCoordinate(vec2f.x), (float)this.y.toAbsoluteCoordinate(vec2f.y));
+ }
+
+ @Override
+ public boolean isXRelative() {
+ return this.x.isRelative();
+ }
+
+ @Override
+ public boolean isYRelative() {
+ return this.y.isRelative();
+ }
+
+ @Override
+ public boolean isZRelative() {
+ return this.z.isRelative();
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) return true;
+
+ return o instanceof DefaultClientPosArgument defaultPosArgument &&
+ this.x.equals(defaultPosArgument.x) && this.y.equals(defaultPosArgument.y) && this.z.equals(defaultPosArgument.z);
+ }
+
+ public static DefaultClientPosArgument parse(StringReader reader) throws CommandSyntaxException {
+ int i = reader.getCursor();
+ CoordinateArgument coordinateArgument = CoordinateArgument.parse(reader);
+ if (reader.canRead() && reader.peek() == ' ') {
+ reader.skip();
+ CoordinateArgument coordinateArgument2 = CoordinateArgument.parse(reader);
+ if (reader.canRead() && reader.peek() == ' ') {
+ reader.skip();
+ CoordinateArgument coordinateArgument3 = CoordinateArgument.parse(reader);
+ return new DefaultClientPosArgument(coordinateArgument, coordinateArgument2, coordinateArgument3);
+ } else {
+ reader.setCursor(i);
+ throw Vec3ArgumentType.INCOMPLETE_EXCEPTION.createWithContext(reader);
+ }
+ } else {
+ reader.setCursor(i);
+ throw Vec3ArgumentType.INCOMPLETE_EXCEPTION.createWithContext(reader);
+ }
+ }
+
+ public static DefaultClientPosArgument parse(StringReader reader, boolean centerIntegers) throws CommandSyntaxException {
+ int i = reader.getCursor();
+ CoordinateArgument coordinateArgument = CoordinateArgument.parse(reader, centerIntegers);
+ if (reader.canRead() && reader.peek() == ' ') {
+ reader.skip();
+ CoordinateArgument coordinateArgument2 = CoordinateArgument.parse(reader, false);
+ if (reader.canRead() && reader.peek() == ' ') {
+ reader.skip();
+ CoordinateArgument coordinateArgument3 = CoordinateArgument.parse(reader, centerIntegers);
+ return new DefaultClientPosArgument(coordinateArgument, coordinateArgument2, coordinateArgument3);
+ } else {
+ reader.setCursor(i);
+ throw Vec3ArgumentType.INCOMPLETE_EXCEPTION.createWithContext(reader);
+ }
+ } else {
+ reader.setCursor(i);
+ throw Vec3ArgumentType.INCOMPLETE_EXCEPTION.createWithContext(reader);
+ }
+ }
+
+ public static DefaultClientPosArgument absolute(double x, double y, double z) {
+ return new DefaultClientPosArgument(new CoordinateArgument(false, x), new CoordinateArgument(false, y), new CoordinateArgument(false, z));
+ }
+
+ public static DefaultClientPosArgument absolute(Vec2f vec) {
+ return new DefaultClientPosArgument(new CoordinateArgument(false, vec.x), new CoordinateArgument(false, vec.y), new CoordinateArgument(true, 0.0));
+ }
+
+ public static DefaultClientPosArgument zero() {
+ return new DefaultClientPosArgument(new CoordinateArgument(true, 0.0), new CoordinateArgument(true, 0.0), new CoordinateArgument(true, 0.0));
+ }
+
+ public int hashCode() {
+ int i = this.x.hashCode();
+ i = 31 * i + this.y.hashCode();
+ return 31 * i + this.z.hashCode();
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/blockpos/LookingClientPosArgument.java b/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/blockpos/LookingClientPosArgument.java
new file mode 100644
index 00000000..3f89f9c7
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/blockpos/LookingClientPosArgument.java
@@ -0,0 +1,106 @@
+package de.hysky.skyblocker.utils.command.argumenttypes.blockpos;
+
+import com.mojang.brigadier.StringReader;
+import com.mojang.brigadier.exceptions.CommandSyntaxException;
+import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
+import net.minecraft.command.argument.CoordinateArgument;
+import net.minecraft.command.argument.Vec3ArgumentType;
+import net.minecraft.util.math.MathHelper;
+import net.minecraft.util.math.Vec2f;
+import net.minecraft.util.math.Vec3d;
+
+import java.util.Objects;
+
+public class LookingClientPosArgument implements ClientPosArgument {
+ private final double x;
+ private final double y;
+ private final double z;
+
+ public LookingClientPosArgument(double x, double y, double z) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ @Override
+ public Vec3d toAbsolutePos(FabricClientCommandSource source) {
+ Vec2f vec2f = source.getRotation();
+ Vec3d vec3d = source.getPlayer().getPos();
+ float f = MathHelper.cos((vec2f.y + 90.0F) * (float) (Math.PI / 180.0));
+ float g = MathHelper.sin((vec2f.y + 90.0F) * (float) (Math.PI / 180.0));
+ float h = MathHelper.cos(-vec2f.x * (float) (Math.PI / 180.0));
+ float i = MathHelper.sin(-vec2f.x * (float) (Math.PI / 180.0));
+ float j = MathHelper.cos((-vec2f.x + 90.0F) * (float) (Math.PI / 180.0));
+ float k = MathHelper.sin((-vec2f.x + 90.0F) * (float) (Math.PI / 180.0));
+ Vec3d vec3d2 = new Vec3d(f * h, i, g * h);
+ Vec3d vec3d3 = new Vec3d(f * j, k, g * j);
+ Vec3d vec3d4 = vec3d2.crossProduct(vec3d3).multiply(-1.0);
+ double d = vec3d2.x * this.z + vec3d3.x * this.y + vec3d4.x * this.x;
+ double e = vec3d2.y * this.z + vec3d3.y * this.y + vec3d4.y * this.x;
+ double l = vec3d2.z * this.z + vec3d3.z * this.y + vec3d4.z * this.x;
+ return new Vec3d(vec3d.x + d, vec3d.y + e, vec3d.z + l);
+ }
+
+ @Override
+ public Vec2f toAbsoluteRotation(FabricClientCommandSource source) {
+ return Vec2f.ZERO;
+ }
+
+ @Override
+ public boolean isXRelative() {
+ return true;
+ }
+
+ @Override
+ public boolean isYRelative() {
+ return true;
+ }
+
+ @Override
+ public boolean isZRelative() {
+ return true;
+ }
+
+ public static LookingClientPosArgument parse(StringReader reader) throws CommandSyntaxException {
+ int i = reader.getCursor();
+ double d = readCoordinate(reader, i);
+ if (reader.canRead() && reader.peek() == ' ') {
+ reader.skip();
+ double e = readCoordinate(reader, i);
+ if (reader.canRead() && reader.peek() == ' ') {
+ reader.skip();
+ double f = readCoordinate(reader, i);
+ return new LookingClientPosArgument(d, e, f);
+ } else {
+ reader.setCursor(i);
+ throw Vec3ArgumentType.INCOMPLETE_EXCEPTION.createWithContext(reader);
+ }
+ } else {
+ reader.setCursor(i);
+ throw Vec3ArgumentType.INCOMPLETE_EXCEPTION.createWithContext(reader);
+ }
+ }
+
+ private static double readCoordinate(StringReader reader, int startingCursorPos) throws CommandSyntaxException {
+ if (!reader.canRead()) {
+ throw CoordinateArgument.MISSING_COORDINATE.createWithContext(reader);
+ } else if (reader.peek() != '^') {
+ reader.setCursor(startingCursorPos);
+ throw Vec3ArgumentType.MIXED_COORDINATE_EXCEPTION.createWithContext(reader);
+ } else {
+ reader.skip();
+ return reader.canRead() && reader.peek() != ' ' ? reader.readDouble() : 0.0;
+ }
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) return true;
+
+ return o instanceof LookingClientPosArgument lookingPosArgument
+ && this.x == lookingPosArgument.x && this.y == lookingPosArgument.y && this.z == lookingPosArgument.z;
+ }
+
+ public int hashCode() {
+ return Objects.hash(x, y, z);
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/color/ColorArgumentType.java b/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/color/ColorArgumentType.java
new file mode 100644
index 00000000..a6dc8510
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/color/ColorArgumentType.java
@@ -0,0 +1,28 @@
+package de.hysky.skyblocker.utils.command.argumenttypes.color;
+
+import com.mojang.brigadier.context.CommandContext;
+import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
+
+/**
+ * Utility class that provides static methods for abstracting away the actual argument type classes.
+ */
+public final class ColorArgumentType {
+ private ColorArgumentType() {} // Prevent instantiation
+
+ public static RgbColorArgumentType rgb() {
+ return new RgbColorArgumentType();
+ }
+
+ public static HexColorArgumentType hex() {
+ return new HexColorArgumentType();
+ }
+
+ public static int getIntFromHex(CommandContext<FabricClientCommandSource> context, String name) {
+ return HexColorArgumentType.getInt(context, name);
+ }
+
+ public static int getIntFromRgb(CommandContext<FabricClientCommandSource> context, String name) {
+ return RgbColorArgumentType.getInt(context, name);
+ }
+}
+
diff --git a/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/color/HexColorArgumentType.java b/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/color/HexColorArgumentType.java
new file mode 100644
index 00000000..516eb7b9
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/color/HexColorArgumentType.java
@@ -0,0 +1,38 @@
+package de.hysky.skyblocker.utils.command.argumenttypes.color;
+
+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.exceptions.DynamicCommandExceptionType;
+import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
+import net.minecraft.text.Text;
+import org.apache.commons.lang3.StringUtils;
+
+@SuppressWarnings("RedundantCast")
+public final class HexColorArgumentType implements ArgumentType<Integer> {
+ public static final DynamicCommandExceptionType WRONG_INPUT_WIDTH = new DynamicCommandExceptionType(found -> Text.translatable("argument.color.hex.invalidString", ((String) found).length()));
+ public static final DynamicCommandExceptionType INVALID_CHARACTER = new DynamicCommandExceptionType(character -> Text.translatable("argument.color.hex.invalidChar", (String) character));
+
+ @Override
+ public Integer parse(StringReader reader) throws CommandSyntaxException {
+ String input = reader.readString();
+ if (StringUtils.startsWithIgnoreCase(input, "0x")) input = input.substring(2);
+// else if (input.startsWith("#")) input = input.substring(1); // This doesn't work because minecraft has the # prefix reserved for tags, so inputs with that prefix never reach this reader
+
+ if (input.length() != 6) throw WRONG_INPUT_WIDTH.create(input);
+
+ for (int i = 0; i < input.length(); i++) {
+ char character = input.charAt(i);
+ if ((character < '0' || character > '9') && (character < 'a' || character > 'f') && (character < 'A' || character > 'F')) {
+ throw INVALID_CHARACTER.create(String.valueOf(character)); //Have to wrap character in a string, because mcdev doesn't appreciate chars and I cba to suppress the warnings
+ }
+ }
+
+ return Integer.decode("#" + input);
+ }
+
+ public static int getInt(CommandContext<FabricClientCommandSource> context, String name) {
+ return context.getArgument(name, Integer.class);
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/color/RgbColorArgumentType.java b/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/color/RgbColorArgumentType.java
new file mode 100644
index 00000000..d9a99fae
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/color/RgbColorArgumentType.java
@@ -0,0 +1,39 @@
+package de.hysky.skyblocker.utils.command.argumenttypes.color;
+
+import com.mojang.brigadier.StringReader;
+import com.mojang.brigadier.arguments.ArgumentType;
+import com.mojang.brigadier.arguments.IntegerArgumentType;
+import com.mojang.brigadier.context.CommandContext;
+import com.mojang.brigadier.exceptions.CommandSyntaxException;
+import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
+import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
+import net.minecraft.text.Text;
+
+public final class RgbColorArgumentType implements ArgumentType<Integer> {
+ public static final SimpleCommandExceptionType INCOMPLETE_EXCEPTION = new SimpleCommandExceptionType(Text.translatable("argument.color.rgb.incomplete"));
+
+ @Override
+ public Integer parse(StringReader reader) throws CommandSyntaxException {
+ int i = reader.getCursor();
+ int redArgument = IntegerArgumentType.integer(0x00, 0xFF).parse(reader);
+ if (reader.canRead() && reader.peek() == ' ') {
+ reader.skip();
+ int greenArgument = IntegerArgumentType.integer(0x00, 0xFF).parse(reader);
+ if (reader.canRead() && reader.peek() == ' ') {
+ reader.skip();
+ int blueArgument = IntegerArgumentType.integer(0x00, 0xFF).parse(reader);
+ return redArgument << 16 | greenArgument << 8 | blueArgument;
+ } else {
+ reader.setCursor(i);
+ throw INCOMPLETE_EXCEPTION.createWithContext(reader);
+ }
+ } else {
+ reader.setCursor(i);
+ throw INCOMPLETE_EXCEPTION.createWithContext(reader);
+ }
+ }
+
+ public static int getInt(CommandContext<FabricClientCommandSource> context, String name) {
+ return context.getArgument(name, Integer.class);
+ }
+}