diff --git a/.factorypath b/.factorypath new file mode 100644 index 00000000..7c91a24b --- /dev/null +++ b/.factorypath @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/tools/redstone/redstonetools/RedstoneToolsClient.java b/src/main/java/tools/redstone/redstonetools/RedstoneToolsClient.java index 551ad222..66467350 100644 --- a/src/main/java/tools/redstone/redstonetools/RedstoneToolsClient.java +++ b/src/main/java/tools/redstone/redstonetools/RedstoneToolsClient.java @@ -1,7 +1,10 @@ package tools.redstone.redstonetools; import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.command.v2.ArgumentTypeRegistry; import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.command.argument.serialize.ArgumentSerializer; +import net.minecraft.util.Identifier; import org.reflections.Reflections; import org.slf4j.Logger; @@ -9,9 +12,11 @@ import rip.hippo.inject.Doctor; import rip.hippo.inject.Injector; +import tools.redstone.redstonetools.features.arguments.serializers.GenericArgumentType; import tools.redstone.redstonetools.utils.DependencyLookup; import tools.redstone.redstonetools.utils.ReflectionUtils; +import java.lang.reflect.InvocationTargetException; import java.nio.file.Path; public class RedstoneToolsClient implements ClientModInitializer { @@ -31,6 +36,32 @@ public void onInitializeClient() { // Register game rules RedstoneToolsGameRules.register(); + // Register arguments + ReflectionUtils.getAllArguments().forEach(argument -> { + var nestedClasses = (Class[]) argument + .getDeclaredClasses(); + + if (nestedClasses.length == 0) { + LOGGER.error("Failed to register {} because no serializer nested class was found", + argument.getSimpleName()); + return; + } + + Identifier id = new Identifier(MOD_ID, argument.getSimpleName().toLowerCase()); + + try { + var serializer = nestedClasses[0].getDeclaredConstructor().newInstance(); + + ArgumentTypeRegistry.registerArgumentType( + id, + argument, serializer); + } catch (InstantiationException | IllegalAccessException | IllegalArgumentException + | InvocationTargetException | NoSuchMethodException | SecurityException e) { + LOGGER.error("Failed to register argument type {}. Skipping registration.", + argument.getName()); + } + }); + // Register features ReflectionUtils.getFeatures().forEach(feature -> diff --git a/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/BlockColorSerializer.java b/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/BlockColorSerializer.java index a90c2a85..b79060f0 100644 --- a/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/BlockColorSerializer.java +++ b/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/BlockColorSerializer.java @@ -1,5 +1,7 @@ package tools.redstone.redstonetools.features.arguments.serializers; +import net.minecraft.command.CommandRegistryAccess; +import net.minecraft.command.argument.serialize.ArgumentSerializer; import tools.redstone.redstonetools.utils.BlockColor; public class BlockColorSerializer extends EnumSerializer { @@ -12,4 +14,27 @@ private BlockColorSerializer() { public static BlockColorSerializer blockColor() { return INSTANCE; } + + public static class Serializer + extends GenericArgumentType.Serializer { + + public final class Properties + implements ArgumentSerializer.ArgumentTypeProperties { + + @Override + public BlockColorSerializer createType(CommandRegistryAccess var1) { + return blockColor(); + } + + @Override + public ArgumentSerializer getSerializer() { + return new Serializer(); + } + } + + @Override + public Properties getArgumentTypeProperties(BlockColorSerializer var1) { + return new Properties(); + } + } } diff --git a/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/BoolSerializer.java b/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/BoolSerializer.java index 02fb39e5..81c400e1 100644 --- a/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/BoolSerializer.java +++ b/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/BoolSerializer.java @@ -3,6 +3,9 @@ import com.mojang.brigadier.arguments.ArgumentType; import com.mojang.brigadier.arguments.BoolArgumentType; +import net.minecraft.command.CommandRegistryAccess; +import net.minecraft.command.argument.serialize.ArgumentSerializer; + public class BoolSerializer extends StringBrigadierSerializer { private static final BoolSerializer INSTANCE = new BoolSerializer(BoolArgumentType.bool()); @@ -20,4 +23,27 @@ public String serialize(Boolean value) { return String.valueOf(value); } + public static class Serializer + extends GenericArgumentType.Serializer { + + public final class Properties + implements ArgumentSerializer.ArgumentTypeProperties { + + @Override + public BoolSerializer createType(CommandRegistryAccess var1) { + return bool(); + } + + @Override + public ArgumentSerializer getSerializer() { + return new Serializer(); + } + } + + @Override + public Properties getArgumentTypeProperties(BoolSerializer serializer) { + return new Properties(); + } + } + } diff --git a/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/CollectionSerializer.java b/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/CollectionSerializer.java index 16bb16b7..c01c7ef6 100644 --- a/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/CollectionSerializer.java +++ b/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/CollectionSerializer.java @@ -6,6 +6,9 @@ import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import net.minecraft.command.CommandRegistryAccess; +import net.minecraft.command.argument.serialize.ArgumentSerializer; + import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.function.Function; @@ -18,8 +21,7 @@ * @param The collection type. */ public class CollectionSerializer> - extends GenericArgumentType> -{ + extends GenericArgumentType> { public static CollectionSerializer> listOf(GenericArgumentType element) { return new CollectionSerializer<>(List.class, element, ArrayList::new); @@ -39,8 +41,8 @@ public static CollectionSerializer> setOf(GenericArgumentType clazz, - GenericArgumentType elementType, - Function, C> collectionFactory) { + GenericArgumentType elementType, + Function, C> collectionFactory) { super((Class) clazz); this.elementType = (GenericArgumentType) elementType; this.collectionFactory = collectionFactory; @@ -116,7 +118,8 @@ public CompletableFuture listSuggestions(CommandContext cont int oldCursor = inputParser.getCursor(); try { elementType.deserialize(inputParser); - } catch (CommandSyntaxException ignored) { } + } catch (CommandSyntaxException ignored) { + } if (oldCursor == inputParser.getCursor()) break; inputParser.skipWhitespace(); @@ -173,4 +176,28 @@ public List serialize(C value) { .toList(); } + public static class Serializer + extends GenericArgumentType.Serializer, Serializer.Properties> { + + public final class Properties + implements ArgumentSerializer.ArgumentTypeProperties> { + + @Override + public CollectionSerializer createType(CommandRegistryAccess var1) { + // TODO: Actually make this work, this is currently a work around to get it to + // compile + return listOf(IntegerSerializer.integer()); + } + + @Override + public ArgumentSerializer, ?> getSerializer() { + return new Serializer(); + } + } + + @Override + public Properties getArgumentTypeProperties(CollectionSerializer serializer) { + return new Properties(); + } + } } diff --git a/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/ColoredBlockTypeSerializer.java b/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/ColoredBlockTypeSerializer.java index 3b7b6e99..b19a3ee1 100644 --- a/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/ColoredBlockTypeSerializer.java +++ b/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/ColoredBlockTypeSerializer.java @@ -1,5 +1,7 @@ package tools.redstone.redstonetools.features.arguments.serializers; +import net.minecraft.command.CommandRegistryAccess; +import net.minecraft.command.argument.serialize.ArgumentSerializer; import tools.redstone.redstonetools.utils.ColoredBlockType; public class ColoredBlockTypeSerializer extends EnumSerializer { @@ -12,4 +14,27 @@ private ColoredBlockTypeSerializer() { public static ColoredBlockTypeSerializer coloredBlockType() { return INSTANCE; } + + public static class Serializer + extends GenericArgumentType.Serializer { + + public final class Properties + implements ArgumentSerializer.ArgumentTypeProperties { + + @Override + public ColoredBlockTypeSerializer createType(CommandRegistryAccess var1) { + return coloredBlockType(); + } + + @Override + public ArgumentSerializer getSerializer() { + return new Serializer(); + } + } + + @Override + public Properties getArgumentTypeProperties(ColoredBlockTypeSerializer serializer) { + return new Properties(); + } + } } diff --git a/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/DirectionSerializer.java b/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/DirectionSerializer.java index 9a2f3b36..daddaeea 100644 --- a/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/DirectionSerializer.java +++ b/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/DirectionSerializer.java @@ -1,5 +1,7 @@ package tools.redstone.redstonetools.features.arguments.serializers; +import net.minecraft.command.CommandRegistryAccess; +import net.minecraft.command.argument.serialize.ArgumentSerializer; import tools.redstone.redstonetools.utils.DirectionArgument; public class DirectionSerializer extends EnumSerializer { @@ -12,4 +14,27 @@ private DirectionSerializer() { public static DirectionSerializer direction() { return INSTANCE; } + + public static class Serializer + extends GenericArgumentType.Serializer { + + public final class Properties + implements ArgumentSerializer.ArgumentTypeProperties { + + @Override + public DirectionSerializer createType(CommandRegistryAccess var1) { + return direction(); + } + + @Override + public ArgumentSerializer getSerializer() { + return new Serializer(); + } + } + + @Override + public Properties getArgumentTypeProperties(DirectionSerializer serializer) { + return new Properties(); + } + } } diff --git a/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/DoubleSerializer.java b/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/DoubleSerializer.java index 86daafa0..f1c2b394 100644 --- a/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/DoubleSerializer.java +++ b/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/DoubleSerializer.java @@ -3,6 +3,9 @@ import com.mojang.brigadier.arguments.ArgumentType; import com.mojang.brigadier.arguments.DoubleArgumentType; +import net.minecraft.command.CommandRegistryAccess; +import net.minecraft.command.argument.serialize.ArgumentSerializer; + public class DoubleSerializer extends StringBrigadierSerializer { private static final DoubleSerializer INSTANCE = new DoubleSerializer(DoubleArgumentType.doubleArg()); @@ -28,4 +31,26 @@ public String serialize(Double value) { return String.valueOf(value); } + public static class Serializer + extends GenericArgumentType.Serializer { + + public final class Properties + implements ArgumentSerializer.ArgumentTypeProperties { + + @Override + public DoubleSerializer createType(CommandRegistryAccess var1) { + return doubleArg(); + } + + @Override + public ArgumentSerializer getSerializer() { + return new Serializer(); + } + } + + @Override + public Properties getArgumentTypeProperties(DoubleSerializer serializer) { + return new Properties(); + } + } } diff --git a/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/FloatSerializer.java b/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/FloatSerializer.java index 3511e418..fd9ae6bb 100644 --- a/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/FloatSerializer.java +++ b/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/FloatSerializer.java @@ -3,6 +3,9 @@ import com.mojang.brigadier.arguments.ArgumentType; import com.mojang.brigadier.arguments.FloatArgumentType; +import net.minecraft.command.CommandRegistryAccess; +import net.minecraft.command.argument.serialize.ArgumentSerializer; + public class FloatSerializer extends StringBrigadierSerializer { private static final FloatSerializer INSTANCE = new FloatSerializer(FloatArgumentType.floatArg()); @@ -28,4 +31,26 @@ public String serialize(Float value) { return String.valueOf(value); } + public static class Serializer + extends GenericArgumentType.Serializer { + + public final class Properties + implements ArgumentSerializer.ArgumentTypeProperties { + + @Override + public FloatSerializer createType(CommandRegistryAccess var1) { + return floatArg(); + } + + @Override + public ArgumentSerializer getSerializer() { + return new Serializer(); + } + } + + @Override + public Properties getArgumentTypeProperties(FloatSerializer serializer) { + return new Properties(); + } + } } diff --git a/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/IntegerSerializer.java b/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/IntegerSerializer.java index 22f53850..bc8bfb4f 100644 --- a/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/IntegerSerializer.java +++ b/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/IntegerSerializer.java @@ -2,6 +2,9 @@ import java.util.Optional; +import net.minecraft.command.CommandRegistryAccess; +import net.minecraft.command.argument.serialize.ArgumentSerializer; + public class IntegerSerializer extends IntLikeArgumentType { private static final IntegerSerializer INSTANCE = new IntegerSerializer(Integer.MIN_VALUE, Integer.MAX_VALUE); @@ -29,4 +32,27 @@ protected Optional tryParseOptional(String string, int radix) { return Optional.empty(); } } + + public static class Serializer + extends GenericArgumentType.Serializer { + + public final class Properties + implements ArgumentSerializer.ArgumentTypeProperties { + + @Override + public IntegerSerializer createType(CommandRegistryAccess var1) { + return integer(); + } + + @Override + public ArgumentSerializer getSerializer() { + return new Serializer(); + } + } + + @Override + public Properties getArgumentTypeProperties(IntegerSerializer var1) { + return new Properties(); + } + } } diff --git a/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/LongSerializer.java b/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/LongSerializer.java index 3038e6a0..8c2577e3 100644 --- a/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/LongSerializer.java +++ b/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/LongSerializer.java @@ -2,6 +2,9 @@ import java.util.Optional; +import net.minecraft.command.CommandRegistryAccess; +import net.minecraft.command.argument.serialize.ArgumentSerializer; + public class LongSerializer extends IntLikeArgumentType { private static final LongSerializer INSTANCE = new LongSerializer(Long.MIN_VALUE, Long.MAX_VALUE); @@ -29,4 +32,27 @@ protected Optional tryParseOptional(String string, int radix) { return Optional.empty(); } } + + public static class Serializer + extends GenericArgumentType.Serializer { + + public final class Properties + implements ArgumentSerializer.ArgumentTypeProperties { + + @Override + public LongSerializer createType(CommandRegistryAccess var1) { + return longArg(); + } + + @Override + public ArgumentSerializer getSerializer() { + return new Serializer(); + } + } + + @Override + public Properties getArgumentTypeProperties(LongSerializer serializer) { + return new Properties(); + } + } } diff --git a/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/MacroNameSerializer.java b/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/MacroNameSerializer.java index 8f9ce185..72ab8516 100644 --- a/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/MacroNameSerializer.java +++ b/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/MacroNameSerializer.java @@ -5,11 +5,14 @@ import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; + +import net.minecraft.command.CommandRegistryAccess; +import net.minecraft.command.argument.serialize.ArgumentSerializer; + import java.util.concurrent.CompletableFuture; import static tools.redstone.redstonetools.RedstoneToolsClient.INJECTOR; - public class MacroNameSerializer extends StringSerializer { private static final MacroNameSerializer INSTANCE = new MacroNameSerializer(); @@ -33,4 +36,27 @@ public CompletableFuture listSuggestions(CommandContext cont return builder.buildFuture(); } + + public static class Serializer + extends GenericArgumentType.Serializer { + + public final class Properties + implements ArgumentSerializer.ArgumentTypeProperties { + + @Override + public MacroNameSerializer createType(CommandRegistryAccess var1) { + return macroName(); + } + + @Override + public ArgumentSerializer getSerializer() { + return new Serializer(); + } + } + + @Override + public Properties getArgumentTypeProperties(MacroNameSerializer serializer) { + return new Properties(); + } + } } diff --git a/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/NumberSerializer.java b/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/NumberSerializer.java index a12d9744..7c8426f0 100644 --- a/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/NumberSerializer.java +++ b/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/NumberSerializer.java @@ -4,10 +4,13 @@ import java.util.Optional; +import net.minecraft.command.CommandRegistryAccess; +import net.minecraft.command.argument.serialize.ArgumentSerializer; + public class NumberSerializer extends IntLikeArgumentType { - private static final NumberSerializer INSTANCE = new NumberSerializer(null,null); + private static final NumberSerializer INSTANCE = new NumberSerializer(null, null); - public static NumberSerializer numberArg(){ + public static NumberSerializer numberArg() { return INSTANCE; } @@ -19,8 +22,8 @@ public static NumberSerializer numberArg(NumberArg min, NumberArg max) { return new NumberSerializer(min, max); } - private NumberSerializer(NumberArg min, NumberArg max){ - super(NumberArg.class,min, max); + private NumberSerializer(NumberArg min, NumberArg max) { + super(NumberArg.class, min, max); } @Override @@ -31,4 +34,27 @@ protected Optional tryParseOptional(String string, int radix) { return Optional.empty(); } } + + public static class Serializer + extends GenericArgumentType.Serializer { + + public final class Properties + implements ArgumentSerializer.ArgumentTypeProperties { + + @Override + public NumberSerializer createType(CommandRegistryAccess var1) { + return numberArg(); + } + + @Override + public ArgumentSerializer getSerializer() { + return new Serializer(); + } + } + + @Override + public Properties getArgumentTypeProperties(NumberSerializer serializer) { + return new Properties(); + } + } } diff --git a/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/SignalBlockSerializer.java b/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/SignalBlockSerializer.java index 14c12ad3..8c76b91d 100644 --- a/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/SignalBlockSerializer.java +++ b/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/SignalBlockSerializer.java @@ -1,5 +1,7 @@ package tools.redstone.redstonetools.features.arguments.serializers; +import net.minecraft.command.CommandRegistryAccess; +import net.minecraft.command.argument.serialize.ArgumentSerializer; import tools.redstone.redstonetools.utils.SignalBlock; public class SignalBlockSerializer extends EnumSerializer { @@ -12,4 +14,27 @@ private SignalBlockSerializer() { public static SignalBlockSerializer signalBlock() { return INSTANCE; } + + public static class Serializer + extends GenericArgumentType.Serializer { + + public final class Properties + implements ArgumentSerializer.ArgumentTypeProperties { + + @Override + public SignalBlockSerializer createType(CommandRegistryAccess var1) { + return signalBlock(); + } + + @Override + public ArgumentSerializer getSerializer() { + return new Serializer(); + } + } + + @Override + public Properties getArgumentTypeProperties(SignalBlockSerializer serializer) { + return new Properties(); + } + } } diff --git a/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/StringSerializer.java b/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/StringSerializer.java index a7ddbf29..db8f7b66 100644 --- a/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/StringSerializer.java +++ b/src/main/java/tools/redstone/redstonetools/features/arguments/serializers/StringSerializer.java @@ -3,11 +3,15 @@ import com.mojang.brigadier.arguments.ArgumentType; import com.mojang.brigadier.arguments.StringArgumentType; +import net.minecraft.command.CommandRegistryAccess; +import net.minecraft.command.argument.serialize.ArgumentSerializer; + public class StringSerializer extends StringBrigadierSerializer { private static final StringSerializer INSTANCE_WORD = new StringSerializer(StringArgumentType.word()); private static final StringSerializer INSTANCE_STRING = new StringSerializer(StringArgumentType.string()); - private static final StringSerializer INSTANCE_GREEDY_STRING = new StringSerializer(StringArgumentType.greedyString()); + private static final StringSerializer INSTANCE_GREEDY_STRING = new StringSerializer( + StringArgumentType.greedyString()); public static StringSerializer string() { return INSTANCE_STRING; @@ -27,8 +31,32 @@ protected StringSerializer(ArgumentType argumentType) { @Override public String serialize(String value) { - // TODO: Check if this is correct, doesn't StringArgumentType.string() require quotes which this doesn't add? + // TODO: Check if this is correct, doesn't StringArgumentType.string() require + // quotes which this doesn't add? return value; } + public static class Serializer + extends GenericArgumentType.Serializer { + + public final class Properties + implements ArgumentSerializer.ArgumentTypeProperties { + + @Override + public StringSerializer createType(CommandRegistryAccess var1) { + return string(); + } + + @Override + public ArgumentSerializer getSerializer() { + return new Serializer(); + } + } + + @Override + public Properties getArgumentTypeProperties(StringSerializer serializer) { + return new Properties(); + } + } + } diff --git a/src/main/java/tools/redstone/redstonetools/utils/ReflectionUtils.java b/src/main/java/tools/redstone/redstonetools/utils/ReflectionUtils.java index 076916c7..d1f54a95 100644 --- a/src/main/java/tools/redstone/redstonetools/utils/ReflectionUtils.java +++ b/src/main/java/tools/redstone/redstonetools/utils/ReflectionUtils.java @@ -31,6 +31,7 @@ public class ReflectionUtils { private static final Logger LOGGER = LogManager.getLogger(); private static DoctorModule[] modules; private static Set features; + private static Set> arguments; private ReflectionUtils() { throw new IllegalStateException("Utility class"); @@ -79,7 +80,12 @@ public static DoctorModule[] getModules() { } public static Set> getAllArguments() { - return REFLECTIONS.getSubTypesOf(GenericArgumentType.class); + if (arguments == null) { + arguments = REFLECTIONS.getSubTypesOf(GenericArgumentType.class).stream() + .filter(argument -> !Modifier.isAbstract(argument.getModifiers())).collect(Collectors.toSet()); + } + + return arguments; } public static Set getFeatures() {