Skip to content

Commit

Permalink
Merge pull request #189 from RedstoneTools/dev
Browse files Browse the repository at this point in the history
Merge dev
  • Loading branch information
Matthias1590 authored May 29, 2023
2 parents 918ff12 + 2c88054 commit 71d4b3a
Show file tree
Hide file tree
Showing 10 changed files with 298 additions and 47 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package tools.redstone.redstonetools.features.arguments.serializers;

import java.math.BigInteger;
import java.util.Optional;

public class BigIntegerSerializer extends IntLikeSerializer<BigInteger> {
private static final BigIntegerSerializer INSTANCE = new BigIntegerSerializer(null, null);

public static BigIntegerSerializer bigInteger() {
return INSTANCE;
}

public static BigIntegerSerializer bigInteger(BigInteger min) {
return new BigIntegerSerializer(min, null);
}

public static BigIntegerSerializer bigInteger(BigInteger min, BigInteger max) {
return new BigIntegerSerializer(min, max);
}

private BigIntegerSerializer(BigInteger min, BigInteger max) {
super(BigInteger.class, min, max);
}

@Override
protected Optional<BigInteger> tryParseOptional(String string, int radix) {
try {
return Optional.of(new BigInteger(string, radix));
} catch (NumberFormatException ignored) {
return Optional.empty();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package tools.redstone.redstonetools.features.arguments.serializers;

import com.mojang.brigadier.StringReader;
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.minecraft.text.Text;
import tools.redstone.redstonetools.utils.NumberBase;

import java.util.Collection;
import java.util.Collections;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;

public abstract class IntLikeSerializer<T extends Comparable<T>> extends TypeSerializer<T, String> {
private final T min;
private final boolean hasMin;
private final T max;
private final boolean hasMax;

protected IntLikeSerializer(Class<T> clazz, T min, T max) {
super(clazz);

this.min = min;
hasMin = min != null;
this.max = max;
hasMax = max != null;
}

@Override
public T deserialize(StringReader reader) throws CommandSyntaxException {
var input = reader.readUnquotedString();

try {
return deserialize(input);
} catch (IllegalArgumentException e) {
throw new CommandSyntaxException(null, Text.of(e.getMessage()));
}
}

@Override
public T deserialize(String serialized) {
var value = deserializeUnchecked(serialized);

if (hasMin && value.compareTo(min) < 0) {
throw new IllegalArgumentException(value + " is below the minimum of " + min + ".");
} else if (hasMax && value.compareTo(max) > 0) {
throw new IllegalArgumentException(value + " is above the maximum of " + max + ".");
}

return value;
}

private T deserializeUnchecked(String serialized) {
if (serialized.length() == 1) {
return tryParse(serialized);
}

if (serialized.charAt(0) == '0') {
var prefixedBase = serialized.substring(0, 2);
var number = serialized.substring(2);

// TODO(Refactor): Write a NumberBase.fromCharacter method instead of this that iterates of the NumberBases (add the char to the NumberBase constructor)
var numberBase = switch (prefixedBase.charAt(1)) {
case 'b' -> NumberBase.BINARY;
case 'o' -> NumberBase.OCTAL;
case 'd' -> NumberBase.DECIMAL;
case 'x' -> NumberBase.HEXADECIMAL;
default -> throw new IllegalArgumentException("Invalid base '" + prefixedBase.charAt(1) + "'.");
};

return tryParse(number, numberBase.toInt());
}

// TODO(Error handling): Add some checks here to make sure the specified base is valid
var parts = serialized.split("_", 2);
if (parts.length == 2) {
var number = parts[0];
var base = Integer.parseInt(parts[1]);

return tryParse(number, base);
}

return tryParse(serialized);
}

private T tryParse(String string) {
return tryParse(string, 10);
}

private T tryParse(String string, int radix) {
return tryParseOptional(string, radix)
.orElseThrow(() -> new IllegalArgumentException(radix == 10
? "Invalid number '" + string + "'."
: "Invalid base " + radix + " number '" + string + "'."));
}

protected abstract Optional<T> tryParseOptional(String string, int radix);

@Override
public String serialize(T value) {
return String.valueOf(value);
}

@Override
public Collection<String> getExamples() {
return Collections.emptyList();
}

@Override
public <R> CompletableFuture<Suggestions> listSuggestions(CommandContext<R> context, SuggestionsBuilder builder) {
return builder.buildFuture();
}
}
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
package tools.redstone.redstonetools.features.arguments.serializers;

import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import java.util.Optional;

public class IntegerSerializer extends StringBrigadierSerializer<Integer> {

private static final IntegerSerializer INSTANCE = new IntegerSerializer(IntegerArgumentType.integer());
public class IntegerSerializer extends IntLikeSerializer<Integer> {
private static final IntegerSerializer INSTANCE = new IntegerSerializer(Integer.MIN_VALUE, Integer.MAX_VALUE);

public static IntegerSerializer integer() {
return INSTANCE;
}

public static IntegerSerializer integer(int min) {
return new IntegerSerializer(IntegerArgumentType.integer(min));
return new IntegerSerializer(min, Integer.MAX_VALUE);
}

public static IntegerSerializer integer(int min, int max) {
return new IntegerSerializer(IntegerArgumentType.integer(min, max));
return new IntegerSerializer(min, max);
}

private IntegerSerializer(ArgumentType<Integer> argumentType) {
super(Integer.class, argumentType);
private IntegerSerializer(int min, int max) {
super(Integer.class, min, max);
}

@Override
public String serialize(Integer value) {
return String.valueOf(value);
protected Optional<Integer> tryParseOptional(String string, int radix) {
try {
return Optional.of(Integer.parseInt(string, radix));
} catch (NumberFormatException ignored) {
return Optional.empty();
}
}

}
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
package tools.redstone.redstonetools.features.arguments.serializers;

import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.arguments.LongArgumentType;
import java.util.Optional;

public class LongSerializer extends StringBrigadierSerializer<Long> {

private static final LongSerializer INSTANCE = new LongSerializer(LongArgumentType.longArg());
public class LongSerializer extends IntLikeSerializer<Long> {
private static final LongSerializer INSTANCE = new LongSerializer(Long.MIN_VALUE, Long.MAX_VALUE);

public static LongSerializer longArg() {
return INSTANCE;
}

public static LongSerializer longArg(long min) {
return new LongSerializer(LongArgumentType.longArg(min));
return new LongSerializer(min, Long.MAX_VALUE);
}

public static LongSerializer longArg(long min, long max) {
return new LongSerializer(LongArgumentType.longArg(min, max));
return new LongSerializer(min, max);
}

private LongSerializer(ArgumentType<Long> argumentType) {
super(Long.class, argumentType);
private LongSerializer(long min, long max) {
super(Long.class, min, max);
}

@Override
public String serialize(Long value) {
return String.valueOf(value);
protected Optional<Long> tryParseOptional(String string, int radix) {
try {
return Optional.of(Long.parseLong(string, radix));
} catch (NumberFormatException ignored) {
return Optional.empty();
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package tools.redstone.redstonetools.features.arguments.serializers;

import com.mojang.brigadier.StringReader;
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.minecraft.text.Text;
import tools.redstone.redstonetools.utils.NumberBase;

import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.CompletableFuture;

public class NumberBaseSerializer extends TypeSerializer<Integer, String> {
private static final IntegerSerializer INT_SERIALIZER = IntegerSerializer.integer(2, 36);
private static final NumberBaseSerializer INSTANCE = new NumberBaseSerializer();

public static NumberBaseSerializer numberBase() {
return INSTANCE;
}

protected NumberBaseSerializer() {
super(Integer.class);
}

@Override
public Integer deserialize(StringReader reader) throws CommandSyntaxException {
var input = reader.readUnquotedString();

try {
return deserialize(input);
} catch (IllegalArgumentException e) {
throw new CommandSyntaxException(null, Text.of(e.getMessage()));
}
}

@Override
public Integer deserialize(String serialized) {
try {
return NumberBase.fromString(serialized)
.map(NumberBase::toInt)
.orElseGet(() -> INT_SERIALIZER.deserialize(serialized));
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Invalid base '" + serialized + "'.", e);
}
}

@Override
public String serialize(Integer value) {
return NumberBase.fromInt(value)
.map(NumberBase::toString)
.orElseGet(() -> INT_SERIALIZER.serialize(value));
}

public String serialize(NumberBase value) {
return serialize(value.toInt());
}

@Override
public Collection<String> getExamples() {
return Arrays.stream(NumberBase.values())
.map(this::serialize)
.toList();
}

@Override
public <R> CompletableFuture<Suggestions> listSuggestions(CommandContext<R> context, SuggestionsBuilder builder) {
for (var value : NumberBase.values()) {
builder = builder.suggest(serialize(value));
}

return builder.buildFuture();
}
}
Original file line number Diff line number Diff line change
@@ -1,38 +1,28 @@
package tools.redstone.redstonetools.features.commands;

import net.minecraft.server.command.ServerCommandSource;
import tools.redstone.redstonetools.features.Feature;
import tools.redstone.redstonetools.features.arguments.Argument;
import tools.redstone.redstonetools.features.feedback.Feedback;
import net.minecraft.server.command.ServerCommandSource;

import static tools.redstone.redstonetools.features.arguments.serializers.IntegerSerializer.integer;
import static tools.redstone.redstonetools.features.arguments.serializers.StringSerializer.word;


import java.math.BigInteger;

import static tools.redstone.redstonetools.features.arguments.serializers.BigIntegerSerializer.bigInteger;
import static tools.redstone.redstonetools.features.arguments.serializers.NumberBaseSerializer.numberBase;

@Feature(name = "Base Convert", description = "Converts a number from one base to another.", command = "base")
public class BaseConvertFeature extends CommandFeature {

public static final Argument<String> number = Argument
.ofType(word());
public static final Argument<Integer> fromBase = Argument
.ofType(integer(2, 36));
public static final Argument<BigInteger> number = Argument
.ofType(bigInteger());
public static final Argument<Integer> toBase = Argument
.ofType(integer(2, 36));

.ofType(numberBase())
.withDefault(10);

@Override
protected Feedback execute(ServerCommandSource source) {
BigInteger input;
try {
input = new BigInteger(number.getValue(), fromBase.getValue());
} catch (NumberFormatException e) {
return Feedback.invalidUsage("Inputted number does not match the specified base");
}
var output = number.getValue().toString(toBase.getValue());

var output = input.toString(toBase.getValue());
return Feedback.success(output);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import static tools.redstone.redstonetools.features.arguments.serializers.BlockStateArgumentSerializer.blockState;
import static tools.redstone.redstonetools.features.arguments.serializers.BoolSerializer.bool;
import static tools.redstone.redstonetools.features.arguments.serializers.IntegerSerializer.integer;
import static tools.redstone.redstonetools.features.arguments.serializers.NumberBaseSerializer.numberBase;

@Feature(name = "Binary Block Read", description = "Interprets your WorldEdit selection as a binary number.", command = "/read")
public class BinaryBlockReadFeature extends CommandFeature {
Expand All @@ -28,7 +29,7 @@ public class BinaryBlockReadFeature extends CommandFeature {
.ofType(blockState())
.withDefault(LIT_LAMP_ARG);
public static final Argument<Integer> toBase = Argument
.ofType(integer(2, 36))
.ofType(numberBase())
.withDefault(10);
public static final Argument<Boolean> reverseBits = Argument
.ofType(bool())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
@Feature(name = "Color Code", description = "Color codes all color-able blocks in your WorldEdit selection.", command = "/colorcode")
public class ColorCodeFeature extends CommandFeature {
public static final Argument<BlockColor> color = Argument

.ofType(blockColor());
public static final Argument<BlockColor> onlyColor = Argument
.ofType(blockColor())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@

@Feature(name = "Quick TP", description = "Teleports you in the direction you are looking.", command = "quicktp")
public class QuickTpFeature extends CommandFeature {

public static final Argument<Float> distance = Argument

.ofType(floatArg(1.0f))
.withDefault(50.0f);
public static final Argument<Boolean> includeFluids = Argument
Expand Down
Loading

0 comments on commit 71d4b3a

Please sign in to comment.