diff --git a/Common/src/main/java/dev/upcraft/sparkweave/api/command/CommandHelper.java b/Common/src/main/java/dev/upcraft/sparkweave/api/command/CommandHelper.java new file mode 100644 index 0000000..b74e6c8 --- /dev/null +++ b/Common/src/main/java/dev/upcraft/sparkweave/api/command/CommandHelper.java @@ -0,0 +1,19 @@ +package dev.upcraft.sparkweave.api.command; + +import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; +import dev.upcraft.sparkweave.api.platform.Services; +import dev.upcraft.sparkweave.api.platform.services.SparkweaveHelperService; +import net.minecraft.commands.synchronization.ArgumentTypeInfo; +import net.minecraft.network.chat.Component; + +public class CommandHelper { + + private static final SparkweaveHelperService HELPER = Services.getService(SparkweaveHelperService.class); + + public static final DynamicCommandExceptionType IO_EXCEPTION = new DynamicCommandExceptionType(ex -> Component.translatable("commands.sparkweave.error.io_exception", ex instanceof Throwable t ? t.getMessage() : ex)); + + public static , T extends ArgumentTypeInfo.Template> ArgumentTypeInfo createArgumentInfo(Class clazz, ArgumentTypeInfo info) { + return HELPER.create(clazz, info); + } +} diff --git a/Common/src/main/java/dev/upcraft/sparkweave/api/command/argument/RegistryArgumentHelper.java b/Common/src/main/java/dev/upcraft/sparkweave/api/command/argument/RegistryArgumentType.java similarity index 51% rename from Common/src/main/java/dev/upcraft/sparkweave/api/command/argument/RegistryArgumentHelper.java rename to Common/src/main/java/dev/upcraft/sparkweave/api/command/argument/RegistryArgumentType.java index 860a763..724f5e5 100644 --- a/Common/src/main/java/dev/upcraft/sparkweave/api/command/argument/RegistryArgumentHelper.java +++ b/Common/src/main/java/dev/upcraft/sparkweave/api/command/argument/RegistryArgumentType.java @@ -1,5 +1,6 @@ package dev.upcraft.sparkweave.api.command.argument; +import com.mojang.brigadier.StringReader; import com.mojang.brigadier.arguments.ArgumentType; import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; @@ -8,25 +9,25 @@ import com.mojang.brigadier.suggestion.SuggestionsBuilder; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.SharedSuggestionProvider; -import net.minecraft.commands.arguments.ResourceLocationArgument; import net.minecraft.core.Registry; +import net.minecraft.core.registries.Registries; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; +import java.util.Collection; +import java.util.List; import java.util.Optional; import java.util.concurrent.CompletableFuture; +import java.util.stream.Stream; -public class RegistryArgumentHelper { +public class RegistryArgumentType implements ArgumentType { - private static final DynamicCommandExceptionType REGISTRY_NOT_FOUND = new DynamicCommandExceptionType(x -> Component.translatable("argument.sparkweave.registries.not_found", x)); + private static final DynamicCommandExceptionType REGISTRY_NOT_FOUND = new DynamicCommandExceptionType(x -> Component.translatable("argument.sparkweave.registry.not_found", x)); + private static final List EXAMPLES = Stream.of(Registries.ITEM, Registries.BLOCK, Registries.BIOME, Registries.BANNER_PATTERN, Registries.CONFIGURED_FEATURE).map(ResourceKey::location).map(ResourceLocation::toString).toList(); - public static CompletableFuture suggestRegistries(CommandContext ctx, SuggestionsBuilder builder) { - return SharedSuggestionProvider.suggestResource(ctx.getSource().registryAccess().listRegistries().map(ResourceKey::location), builder); - } - - public static ArgumentType registryArgument() { - return ResourceLocationArgument.id(); + public static RegistryArgumentType registry() { + return new RegistryArgumentType(); } public static Registry getRegistry(CommandContext ctx, String name) throws CommandSyntaxException { @@ -35,4 +36,22 @@ public static Registry getRegistry(CommandContext ctx return optional.orElseThrow(() -> REGISTRY_NOT_FOUND.create(location)); } + @Override + public ResourceLocation parse(StringReader reader) throws CommandSyntaxException { + return ResourceLocation.read(reader); + } + + @Override + public CompletableFuture listSuggestions(CommandContext context, SuggestionsBuilder builder) { + if (context.getSource() instanceof SharedSuggestionProvider provider) { + return SharedSuggestionProvider.suggestResource(provider.registryAccess().listRegistries().map(ResourceKey::location), builder); + } + + return builder.buildFuture(); + } + + @Override + public Collection getExamples() { + return EXAMPLES; + } } diff --git a/Common/src/main/java/dev/upcraft/sparkweave/api/platform/services/SparkweaveHelperService.java b/Common/src/main/java/dev/upcraft/sparkweave/api/platform/services/SparkweaveHelperService.java index 7a80f43..bd4fac4 100644 --- a/Common/src/main/java/dev/upcraft/sparkweave/api/platform/services/SparkweaveHelperService.java +++ b/Common/src/main/java/dev/upcraft/sparkweave/api/platform/services/SparkweaveHelperService.java @@ -1,5 +1,7 @@ package dev.upcraft.sparkweave.api.platform.services; +import com.mojang.brigadier.arguments.ArgumentType; +import net.minecraft.commands.synchronization.ArgumentTypeInfo; import net.minecraft.world.item.CreativeModeTab; public interface SparkweaveHelperService { @@ -8,4 +10,9 @@ public interface SparkweaveHelperService { * @see dev.upcraft.sparkweave.api.item.CreativeTabHelper */ CreativeModeTab.Builder newCreativeTabBuilder(); + + /** + * @see dev.upcraft.sparkweave.api.command.CommandHelper#createArgumentInfo(Class, ArgumentTypeInfo) + */ + , T extends ArgumentTypeInfo.Template> ArgumentTypeInfo create(Class clazz, ArgumentTypeInfo info); } diff --git a/Common/src/main/java/dev/upcraft/sparkweave/command/DumpRegistryCommand.java b/Common/src/main/java/dev/upcraft/sparkweave/command/DumpRegistryCommand.java index a3469a4..b4baf30 100644 --- a/Common/src/main/java/dev/upcraft/sparkweave/command/DumpRegistryCommand.java +++ b/Common/src/main/java/dev/upcraft/sparkweave/command/DumpRegistryCommand.java @@ -3,13 +3,13 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; -import dev.upcraft.sparkweave.api.command.argument.RegistryArgumentHelper; +import dev.upcraft.sparkweave.SparkweaveMod; +import dev.upcraft.sparkweave.api.command.CommandHelper; +import dev.upcraft.sparkweave.api.command.argument.RegistryArgumentType; import dev.upcraft.sparkweave.api.platform.Services; import dev.upcraft.sparkweave.api.serialization.CSVWriter; import dev.upcraft.sparkweave.logging.SparkweaveLogging; import net.minecraft.ChatFormatting; -import net.minecraft.commands.CommandBuildContext; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; import net.minecraft.core.Registry; @@ -24,17 +24,16 @@ public class DumpRegistryCommand { - private static final DynamicCommandExceptionType IO_EXCEPTION = new DynamicCommandExceptionType(ex -> Component.translatable("commands.sparkweave.debug.dump_registries.io_exception", ex)); - - public static void register(LiteralArgumentBuilder $, CommandBuildContext buildContext) { + public static void register(LiteralArgumentBuilder $) { $.then(Commands.literal("dump_registries") + .requires(src -> src.hasPermission(Commands.LEVEL_OWNERS)) .executes(DumpRegistryCommand::dumpAllRegistries) - .then(Commands.argument("registry", RegistryArgumentHelper.registryArgument()) - .suggests(RegistryArgumentHelper::suggestRegistries) - .executes(ctx -> dumpRegistry(ctx, RegistryArgumentHelper.getRegistry(ctx, "registry"))) + .then(Commands.argument("registry", RegistryArgumentType.registry()) + .executes(ctx -> dumpRegistry(ctx, RegistryArgumentType.getRegistry(ctx, "registry"))) ) .then(Commands.literal("all") - .executes(DumpRegistryCommand::dumpAllRegistries)) + .executes(DumpRegistryCommand::dumpAllRegistries) + ) ); } @@ -42,7 +41,7 @@ private static int dumpAllRegistries(CommandContext ctx) thr var player = ctx.getSource().getPlayerOrException(); var registryAccess = ctx.getSource().getServer().registries().compositeAccess(); var registries = registryAccess.listRegistries().toList(); - var dir = Services.PLATFORM.getGameDir().resolve("sparkweave").resolve("registry_export"); + var dir = Services.PLATFORM.getGameDir().resolve(SparkweaveMod.MODID).resolve("registry_export"); for (ResourceKey> registryKey : registries) { var registry = registryAccess.registry(registryKey).orElseThrow(); @@ -76,7 +75,7 @@ private static void saveRegistryToFile(Registry registry, Path outputDir) thr } } catch (IOException e) { SparkweaveLogging.getLogger().error("Failed to write registry dump for {}", registry.key().location(), e); - throw IO_EXCEPTION.create(e.getMessage()); + throw CommandHelper.IO_EXCEPTION.create(e.getMessage()); } } diff --git a/Common/src/main/java/dev/upcraft/sparkweave/command/DumpTagsCommand.java b/Common/src/main/java/dev/upcraft/sparkweave/command/DumpTagsCommand.java new file mode 100644 index 0000000..573c92e --- /dev/null +++ b/Common/src/main/java/dev/upcraft/sparkweave/command/DumpTagsCommand.java @@ -0,0 +1,118 @@ +package dev.upcraft.sparkweave.command; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import dev.upcraft.sparkweave.SparkweaveMod; +import dev.upcraft.sparkweave.api.command.CommandHelper; +import dev.upcraft.sparkweave.api.command.argument.RegistryArgumentType; +import dev.upcraft.sparkweave.api.platform.Services; +import net.minecraft.ChatFormatting; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; +import net.minecraft.core.Registry; +import net.minecraft.network.chat.ClickEvent; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.HoverEvent; +import net.minecraft.resources.ResourceKey; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +public class DumpTagsCommand { + + private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); + + public static void register(LiteralArgumentBuilder $) { + $.then(Commands.literal("dump_tags") + .requires(src -> src.hasPermission(Commands.LEVEL_OWNERS)) + .executes(DumpTagsCommand::dumpAllTags) + .then(Commands.argument("type", RegistryArgumentType.registry()) + .executes(ctx -> dumpTags(ctx, RegistryArgumentType.getRegistry(ctx, "type"))) + ) + .then(Commands.literal("all") + .executes(DumpTagsCommand::dumpAllTags) + ) + ); + } + + private static int dumpAllTags(CommandContext ctx) throws CommandSyntaxException { + var player = ctx.getSource().getPlayerOrException(); + var registryAccess = ctx.getSource().getServer().registries().compositeAccess(); + var registries = registryAccess.listRegistries().toList(); + var dir = Services.PLATFORM.getGameDir().resolve(SparkweaveMod.MODID).resolve("tag_export"); + + for (ResourceKey> registryKey : registries) { + var registry = registryAccess.registry(registryKey).orElseThrow(); + saveTags(registry, dir); + } + + if (ctx.getSource().getServer().isSingleplayerOwner(player.getGameProfile())) { + var path = Component.literal(dir.toString()).withStyle(style -> style + .applyFormats(ChatFormatting.BLUE, ChatFormatting.UNDERLINE) + .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Component.translatable("chat.sparkweave.open_folder"))) + .withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_FILE, dir.toString())) + ); + + //TODO directly send to client to bypass message click event filtering + ctx.getSource().sendSuccess(() -> Component.translatable("commands.sparkweave.debug.dump_tags.multi_success_path", registries.size(), path), true); + } else { + ctx.getSource().sendSuccess(() -> Component.translatable("commands.sparkweave.debug.dump_tags.multi_success", registries.size()), true); + } + + return registries.size(); + } + + private static void saveTags(Registry registry, Path dir) throws CommandSyntaxException { + Path rootDir = dir.resolve(registry.key().location().getNamespace()).resolve(registry.key().location().getPath()); + + var tags = registry.getTags().toList(); + for (var tagPair : tags) { + var name = tagPair.getFirst().location(); + var outputFile = rootDir.resolve(name.getNamespace()).resolve(name.getPath() + ".json"); + + var json = new JsonObject(); + var array = new JsonArray(); + tagPair.getSecond().stream() + .map(holder -> holder.unwrap().map(k -> k.location().toString(), Object::toString)) + .forEach(array::add); + json.add("values", array); + + try { + Files.createDirectories(outputFile.getParent()); + try (var writer = Files.newBufferedWriter(outputFile)) { + GSON.toJson(json, writer); + } + } catch (IOException e) { + throw CommandHelper.IO_EXCEPTION.create(e); + } + } + } + + private static int dumpTags(CommandContext ctx, Registry registry) throws CommandSyntaxException { + var player = ctx.getSource().getPlayerOrException(); + + var dir = Services.PLATFORM.getGameDir().resolve("sparkweave").resolve("tag_export"); + saveTags(registry, dir); + + if (ctx.getSource().getServer().isSingleplayerOwner(player.getGameProfile())) { + var resolvedDir = dir.resolve(registry.key().location().getNamespace()).resolve(registry.key().location().getPath()).toString(); + var path = Component.literal(resolvedDir).withStyle(style -> style + .applyFormats(ChatFormatting.BLUE, ChatFormatting.UNDERLINE) + .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Component.translatable("chat.sparkweave.open_folder"))) + .withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_FILE, resolvedDir)) + ); + + //TODO directly send to client to bypass message click event filtering + ctx.getSource().sendSuccess(() -> Component.translatable("commands.sparkweave.debug.dump_tags.success_path", registry.key().location(), path), true); + } else { + ctx.getSource().sendSuccess(() -> Component.translatable("commands.sparkweave.debug.dump_tags.success", registry.key().location()), true); + } + return 0; + } +} diff --git a/Common/src/main/java/dev/upcraft/sparkweave/command/SparkweaveCommandRoot.java b/Common/src/main/java/dev/upcraft/sparkweave/command/SparkweaveCommandRoot.java index 123cfb8..96da51e 100644 --- a/Common/src/main/java/dev/upcraft/sparkweave/command/SparkweaveCommandRoot.java +++ b/Common/src/main/java/dev/upcraft/sparkweave/command/SparkweaveCommandRoot.java @@ -10,9 +10,10 @@ public class SparkweaveCommandRoot { public static void register(CommandDispatcher dispatcher, CommandBuildContext buildContext, Commands.CommandSelection environment) { var root = Commands.literal(SparkweaveMod.MODID); - var debug = Commands.literal("debug"); + var debug = Commands.literal("debug").requires(src -> src.hasPermission(Commands.LEVEL_ADMINS)); - DumpRegistryCommand.register(debug, buildContext); + DumpRegistryCommand.register(debug); + DumpTagsCommand.register(debug); root.then(debug); dispatcher.register(root); diff --git a/Common/src/main/java/dev/upcraft/sparkweave/registry/SparkweaveCommandArgumentTypes.java b/Common/src/main/java/dev/upcraft/sparkweave/registry/SparkweaveCommandArgumentTypes.java new file mode 100644 index 0000000..b03f025 --- /dev/null +++ b/Common/src/main/java/dev/upcraft/sparkweave/registry/SparkweaveCommandArgumentTypes.java @@ -0,0 +1,17 @@ +package dev.upcraft.sparkweave.registry; + +import dev.upcraft.sparkweave.SparkweaveMod; +import dev.upcraft.sparkweave.api.command.CommandHelper; +import dev.upcraft.sparkweave.api.command.argument.RegistryArgumentType; +import dev.upcraft.sparkweave.api.registry.RegistryHandler; +import dev.upcraft.sparkweave.api.registry.RegistrySupplier; +import net.minecraft.commands.synchronization.ArgumentTypeInfo; +import net.minecraft.commands.synchronization.SingletonArgumentInfo; +import net.minecraft.core.registries.Registries; + +public class SparkweaveCommandArgumentTypes { + + public static final RegistryHandler> ARGUMENT_TYPES = RegistryHandler.create(Registries.COMMAND_ARGUMENT_TYPE, SparkweaveMod.MODID); + + public static final RegistrySupplier> REGISTRY = ARGUMENT_TYPES.register("registry", () -> CommandHelper.createArgumentInfo(RegistryArgumentType.class, SingletonArgumentInfo.contextFree(RegistryArgumentType::registry))); +} diff --git a/Common/src/main/resources/assets/sparkweave/lang/en_us.json b/Common/src/main/resources/assets/sparkweave/lang/en_us.json index 96bd799..2058947 100644 --- a/Common/src/main/resources/assets/sparkweave/lang/en_us.json +++ b/Common/src/main/resources/assets/sparkweave/lang/en_us.json @@ -1,7 +1,11 @@ { - "argument.sparkweave.registries.not_found": "Registry not found: %s", + "argument.sparkweave.registry.not_found": "Registry not found: %s", "chat.sparkweave.open_folder": "Click to view in File Explorer", - "commands.sparkweave.debug.dump_registries.io_exception": "An IO error occurred while dumping registries: %s", + "commands.sparkweave.error.io_exception": "An IO error occurred while performing the command: %s", + "commands.sparkweave.debug.dump_tags.success": "Successfully exported tags for registry %s", + "commands.sparkweave.debug.dump_tags.success_path": "Successfully exported tags for registry %s to %s", + "commands.sparkweave.debug.dump_tags.multi_success": "Successfully exported tags for %s registries", + "commands.sparkweave.debug.dump_tags.multi_success_path": "Successfully exported tags for %s registries to %s", "commands.sparkweave.debug.dump_registries.success": "Successfully exported registry %s", "commands.sparkweave.debug.dump_registries.success_path": "Successfully exported registry %s to %s", "commands.sparkweave.debug.dump_registries.multi_success": "Successfully exported %s registries", diff --git a/NeoForge/src/main/java/dev/upcraft/sparkweave/neoforge/entrypoint/Main.java b/NeoForge/src/main/java/dev/upcraft/sparkweave/neoforge/entrypoint/Main.java index 76cc596..63ffdf1 100644 --- a/NeoForge/src/main/java/dev/upcraft/sparkweave/neoforge/entrypoint/Main.java +++ b/NeoForge/src/main/java/dev/upcraft/sparkweave/neoforge/entrypoint/Main.java @@ -5,9 +5,11 @@ import dev.upcraft.sparkweave.api.entrypoint.ClientEntryPoint; import dev.upcraft.sparkweave.api.entrypoint.DedicatedServerEntryPoint; import dev.upcraft.sparkweave.api.entrypoint.MainEntryPoint; +import dev.upcraft.sparkweave.api.platform.services.RegistryService; import dev.upcraft.sparkweave.api.registry.block.BlockItemProvider; import dev.upcraft.sparkweave.entrypoint.EntrypointHelper; import dev.upcraft.sparkweave.logging.SparkweaveLogging; +import dev.upcraft.sparkweave.registry.SparkweaveCommandArgumentTypes; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; import net.neoforged.bus.api.IEventBus; @@ -23,11 +25,16 @@ public class Main { public Main(IEventBus bus) { bus.register(this); + var helper = RegistryService.get(); + SparkweaveCommandArgumentTypes.ARGUMENT_TYPES.accept(helper); + EntrypointHelper.fireEntrypoints(MainEntryPoint.class, MainEntryPoint::onInitialize); switch (FMLEnvironment.dist) { - case CLIENT -> EntrypointHelper.fireEntrypoints(ClientEntryPoint.class, ClientEntryPoint::onInitializeClient); - case DEDICATED_SERVER -> EntrypointHelper.fireEntrypoints(DedicatedServerEntryPoint.class, DedicatedServerEntryPoint::onInitializeServer); + case CLIENT -> + EntrypointHelper.fireEntrypoints(ClientEntryPoint.class, ClientEntryPoint::onInitializeClient); + case DEDICATED_SERVER -> + EntrypointHelper.fireEntrypoints(DedicatedServerEntryPoint.class, DedicatedServerEntryPoint::onInitializeServer); } SparkweaveLogging.getLogger().debug("System initialized!"); @@ -35,9 +42,9 @@ public Main(IEventBus bus) { @SubscribeEvent public void processBlockItems(RegisterEvent event) { - if(event.getRegistryKey() == Registries.ITEM) { + if (event.getRegistryKey() == Registries.ITEM) { BuiltInRegistries.BLOCK.entrySet().forEach(entry -> { - if(entry.getValue() instanceof BlockItemProvider provider) { + if (entry.getValue() instanceof BlockItemProvider provider) { event.register(Registries.ITEM, entry.getKey().location(), provider::createItem); } }); diff --git a/NeoForge/src/main/java/dev/upcraft/sparkweave/neoforge/service/NeoHelperService.java b/NeoForge/src/main/java/dev/upcraft/sparkweave/neoforge/service/NeoHelperService.java index 35faab4..671503f 100644 --- a/NeoForge/src/main/java/dev/upcraft/sparkweave/neoforge/service/NeoHelperService.java +++ b/NeoForge/src/main/java/dev/upcraft/sparkweave/neoforge/service/NeoHelperService.java @@ -1,7 +1,10 @@ package dev.upcraft.sparkweave.neoforge.service; +import com.mojang.brigadier.arguments.ArgumentType; import dev.upcraft.sparkweave.api.annotation.CalledByReflection; import dev.upcraft.sparkweave.api.platform.services.SparkweaveHelperService; +import net.minecraft.commands.synchronization.ArgumentTypeInfo; +import net.minecraft.commands.synchronization.ArgumentTypeInfos; import net.minecraft.world.item.CreativeModeTab; public class NeoHelperService implements SparkweaveHelperService { @@ -15,4 +18,9 @@ public NeoHelperService() { public CreativeModeTab.Builder newCreativeTabBuilder() { return CreativeModeTab.builder(); } + + @Override + public , T extends ArgumentTypeInfo.Template> ArgumentTypeInfo create(Class clazz, ArgumentTypeInfo info) { + return ArgumentTypeInfos.registerByClass(clazz, info); + } } diff --git a/Quilt/src/main/java/dev/upcraft/sparkweave/quilt/entrypoint/Main.java b/Quilt/src/main/java/dev/upcraft/sparkweave/quilt/entrypoint/Main.java index 7f0840e..091af25 100644 --- a/Quilt/src/main/java/dev/upcraft/sparkweave/quilt/entrypoint/Main.java +++ b/Quilt/src/main/java/dev/upcraft/sparkweave/quilt/entrypoint/Main.java @@ -7,6 +7,7 @@ import dev.upcraft.sparkweave.api.registry.block.BlockItemProvider; import dev.upcraft.sparkweave.entrypoint.EntrypointHelper; import dev.upcraft.sparkweave.logging.SparkweaveLogging; +import dev.upcraft.sparkweave.registry.SparkweaveCommandArgumentTypes; import dev.upcraft.sparkweave.scheduler.ScheduledTaskQueue; import net.minecraft.core.Registry; import net.minecraft.core.registries.BuiltInRegistries; @@ -32,6 +33,9 @@ public void onInitialize(ModContainer mod) { ServerTickEvents.START.register(server -> ScheduledTaskQueue.onServerTick()); CommandRegistrationCallback.EVENT.register((dispatcher, buildContext, environment) -> CommandEvents.REGISTER.invoker().registerCommands(dispatcher, buildContext, environment)); + var service = RegistryService.get(); + SparkweaveCommandArgumentTypes.ARGUMENT_TYPES.accept(service); + EntrypointHelper.fireEntrypoints(MainEntryPoint.class, MainEntryPoint::onInitialize); SparkweaveLogging.getLogger().debug("System initialized!"); diff --git a/Quilt/src/main/java/dev/upcraft/sparkweave/quilt/mixin/impl/ArgumentTypeInfosAccessor.java b/Quilt/src/main/java/dev/upcraft/sparkweave/quilt/mixin/impl/ArgumentTypeInfosAccessor.java new file mode 100644 index 0000000..47060ae --- /dev/null +++ b/Quilt/src/main/java/dev/upcraft/sparkweave/quilt/mixin/impl/ArgumentTypeInfosAccessor.java @@ -0,0 +1,17 @@ +package dev.upcraft.sparkweave.quilt.mixin.impl; + +import net.minecraft.commands.synchronization.ArgumentTypeInfo; +import net.minecraft.commands.synchronization.ArgumentTypeInfos; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.Map; + +@Mixin(ArgumentTypeInfos.class) +public interface ArgumentTypeInfosAccessor { + + @Accessor("BY_CLASS") + static Map, ArgumentTypeInfo> sparkweave$getByClass() { + throw new UnsupportedOperationException("Mixin not transformed"); + } +} diff --git a/Quilt/src/main/java/dev/upcraft/sparkweave/quilt/service/QuiltHelperService.java b/Quilt/src/main/java/dev/upcraft/sparkweave/quilt/service/QuiltHelperService.java index 5930de3..6c97208 100644 --- a/Quilt/src/main/java/dev/upcraft/sparkweave/quilt/service/QuiltHelperService.java +++ b/Quilt/src/main/java/dev/upcraft/sparkweave/quilt/service/QuiltHelperService.java @@ -1,8 +1,11 @@ package dev.upcraft.sparkweave.quilt.service; +import com.mojang.brigadier.arguments.ArgumentType; import dev.upcraft.sparkweave.api.annotation.CalledByReflection; import dev.upcraft.sparkweave.api.platform.services.SparkweaveHelperService; +import dev.upcraft.sparkweave.quilt.mixin.impl.ArgumentTypeInfosAccessor; import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup; +import net.minecraft.commands.synchronization.ArgumentTypeInfo; import net.minecraft.world.item.CreativeModeTab; public class QuiltHelperService implements SparkweaveHelperService { @@ -16,4 +19,10 @@ public QuiltHelperService() { public CreativeModeTab.Builder newCreativeTabBuilder() { return FabricItemGroup.builder(); } + + @Override + public synchronized , T extends ArgumentTypeInfo.Template> ArgumentTypeInfo create(Class clazz, ArgumentTypeInfo info) { + ArgumentTypeInfosAccessor.sparkweave$getByClass().put(clazz, info); + return info; + } } diff --git a/Quilt/src/main/resources/sparkweave.quilt.mixins.json b/Quilt/src/main/resources/sparkweave.quilt.mixins.json index 51d6a26..c9b6926 100644 --- a/Quilt/src/main/resources/sparkweave.quilt.mixins.json +++ b/Quilt/src/main/resources/sparkweave.quilt.mixins.json @@ -6,6 +6,7 @@ "refmap": "${mod_id}.refmap.json", "compatibilityLevel": "JAVA_17", "mixins": [ + "impl.ArgumentTypeInfosAccessor" ], "client": [ ],