From 4cf84311619dbbf57dfbffae8c9099f33f143238 Mon Sep 17 00:00:00 2001 From: TimMayr Date: Sun, 9 Feb 2025 20:54:25 +0100 Subject: [PATCH] fix(commands): update command registration and improve error handling Signed-off-by: TimMayr --- .../lunatrius/schematica/Schematica.java | 15 ++-- .../command/CommandSchematicaBase.java | 20 +++--- .../command/CommandSchematicaDownload.java | 64 ++++++++--------- .../command/CommandSchematicaList.java | 22 +++--- .../command/CommandSchematicaSave.java | 35 +++++----- .../client/CommandSchematicaReplace.java | 70 ++++++++++--------- .../schematica/handler/DownloadHandler.java | 3 - .../network/message/MessageCapabilities.java | 3 +- .../network/message/MessageDownloadBegin.java | 5 +- .../network/message/MessageDownloadChunk.java | 47 ++++--------- .../network/transfer/SchematicTransfer.java | 48 ++++++++++++- .../lunatrius/schematica/reference/Names.java | 3 + .../lunatrius/schematica/world/FakeLevel.java | 52 ++++++-------- gradle.properties | 8 +-- .../neoforge/SchematicaNeoForge.java | 3 +- 15 files changed, 211 insertions(+), 187 deletions(-) diff --git a/common/src/main/java/com/github/lunatrius/schematica/Schematica.java b/common/src/main/java/com/github/lunatrius/schematica/Schematica.java index 67857987..b773c044 100644 --- a/common/src/main/java/com/github/lunatrius/schematica/Schematica.java +++ b/common/src/main/java/com/github/lunatrius/schematica/Schematica.java @@ -26,16 +26,13 @@ public class Schematica { public static void init() { if (Platform.getEnv() == EnvType.CLIENT) { Schematica.clientInit(); + } else { + Schematica.serverInit(); } CommandRegistrationEvent.EVENT.register( (dispatcher, context, selection) -> CommandSchematicaBase.register(dispatcher)); - if (Platform.getEnv() == EnvType.SERVER) { - LifecycleEvent.SERVER_STARTING.register( - (server) -> ServerProxy.serverWeakReference = new WeakReference<>(server)); - } - Reference.proxy = EnvExecutor.getEnvSpecific(() -> ClientProxy::new, () -> ServerProxy::new); Reference.proxy.init(); PacketHandler.init(); @@ -48,7 +45,11 @@ public static void init() { } private static void clientInit() { - ClientCommandRegistrationEvent.EVENT.register( - ((dispatcher, context) -> CommandSchematicaBase.registerClient(context))); + ClientCommandRegistrationEvent.EVENT.register(CommandSchematicaBase::registerClient); + } + + private static void serverInit() { + LifecycleEvent.SERVER_STARTING.register( + (server) -> ServerProxy.serverWeakReference = new WeakReference<>(server)); } } \ No newline at end of file diff --git a/common/src/main/java/com/github/lunatrius/schematica/command/CommandSchematicaBase.java b/common/src/main/java/com/github/lunatrius/schematica/command/CommandSchematicaBase.java index d51bbd8a..8ffcbe73 100644 --- a/common/src/main/java/com/github/lunatrius/schematica/command/CommandSchematicaBase.java +++ b/common/src/main/java/com/github/lunatrius/schematica/command/CommandSchematicaBase.java @@ -1,6 +1,7 @@ package com.github.lunatrius.schematica.command; import com.github.lunatrius.schematica.command.client.CommandSchematicaReplace; +import com.github.lunatrius.schematica.reference.Names; import com.github.lunatrius.schematica.reference.Reference; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.arguments.StringArgumentType; @@ -8,7 +9,8 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; -import com.mojang.brigadier.tree.LiteralCommandNode; +import com.mojang.brigadier.tree.CommandNode; +import dev.architectury.event.events.client.ClientCommandRegistrationEvent; import net.minecraft.ChatFormatting; import net.minecraft.commands.CommandBuildContext; import net.minecraft.commands.CommandSourceStack; @@ -27,7 +29,7 @@ import java.util.concurrent.CompletableFuture; public abstract class CommandSchematicaBase { - private static LiteralCommandNode mainNode; + private static CommandNode rootNode; protected static @NotNull MutableComponent withStyle(MutableComponent component, ChatFormatting formatting, @Nullable String command) { @@ -41,15 +43,15 @@ public abstract class CommandSchematicaBase { } public static void register(@NotNull CommandDispatcher dispatcher) { - mainNode = dispatcher.register(Commands.literal("schematica") - .then(CommandSchematicaDownload.register()) - .then(CommandSchematicaList.register()) - .then(CommandSchematicaSave.register()) - .then(CommandSchematicaRemove.register())); + rootNode = dispatcher.register(Commands.literal(Names.Command.BASE) + .then(CommandSchematicaDownload.register()) + .then(CommandSchematicaList.register()) + .then(CommandSchematicaSave.register()) + .then(CommandSchematicaRemove.register())); } - public static void registerClient(CommandBuildContext context) { - mainNode.addChild(CommandSchematicaReplace.register(context).build()); + public static void registerClient(@NotNull CommandDispatcher dispatcher, CommandBuildContext context) { + dispatcher.register(CommandSchematicaReplace.register(context)); } public static CompletableFuture getSchematicNamesSuggestions( diff --git a/common/src/main/java/com/github/lunatrius/schematica/command/CommandSchematicaDownload.java b/common/src/main/java/com/github/lunatrius/schematica/command/CommandSchematicaDownload.java index 86fea2c0..7cc85021 100644 --- a/common/src/main/java/com/github/lunatrius/schematica/command/CommandSchematicaDownload.java +++ b/common/src/main/java/com/github/lunatrius/schematica/command/CommandSchematicaDownload.java @@ -23,43 +23,43 @@ public class CommandSchematicaDownload extends CommandSchematicaBase { public static ArgumentBuilder register() { return Commands.literal(Names.Command.Download.NAME) - .then(Commands.argument("filename", StringArgumentType.string()) - .suggests( - ((context, builder) -> CommandSchematicaBase.getSchematicNamesSuggestions( - context, builder, FILE_FILTER_SCHEMATIC))) - .executes((commandContext) -> { - CommandSourceStack source = commandContext.getSource(); - ServerPlayer player = source.getPlayerOrException(); + .then(Commands.argument("filename", StringArgumentType.string()) + .suggests( + ((context, builder) -> CommandSchematicaBase.getSchematicNamesSuggestions( + context, builder, FILE_FILTER_SCHEMATIC))) + .executes((commandContext) -> { + CommandSourceStack source = commandContext.getSource(); + ServerPlayer player = source.getPlayerOrException(); - String filename = StringArgumentType.getString(commandContext, "filename"); - File directory = Reference.proxy.getPlayerSchematicDirectory(player, true); + String filename = StringArgumentType.getString(commandContext, "filename"); + File directory = Reference.proxy.getPlayerSchematicDirectory(player, true); - if (!FileUtils.contains(directory, filename)) { - Reference.logger.error("{} has tried to download" + " the file " + "{}", - player.getName(), filename); + if (!FileUtils.contains(directory, filename)) { + Reference.logger.error("{} has tried to download" + " the file " + "{}", + player.getName(), filename); - source.sendFailure(Component.translatable( - Names.Command.Download.Message.DOWNLOAD_FAILED)); - return -1; - } + source.sendFailure(Component.translatable( + Names.Command.Download.Message.DOWNLOAD_FAILED)); + return -1; + } - ISchematic schematic = SchematicFormat.readFromFile(directory, filename, - Reference.proxy.getLevel( - player)); + ISchematic schematic = SchematicFormat.readFromFile(directory, filename, + Reference.proxy.getLevel( + player)); - if (schematic != null) { - DownloadHandler.INSTANCE.transferMap.put(player.getScoreboardName(), - new SchematicTransfer(schematic, - filename)); - source.sendSuccess(() -> Component.translatable( - Names.Command.Download.Message.DOWNLOAD_STARTED, filename), true); - } else { - source.sendFailure(Component.translatable( - Names.Command.Download.Message.DOWNLOAD_FAILED)); - return -1; - } + if (schematic != null) { + DownloadHandler.INSTANCE.transferMap.put(player.getScoreboardName(), + new SchematicTransfer(schematic, + filename)); + source.sendSuccess(() -> Component.translatable( + Names.Command.Download.Message.DOWNLOAD_STARTED, filename), true); + } else { + source.sendFailure(Component.translatable( + Names.Command.Download.Message.DOWNLOAD_FAILED)); + return -1; + } - return 0; - })); + return 0; + })); } } \ No newline at end of file diff --git a/common/src/main/java/com/github/lunatrius/schematica/command/CommandSchematicaList.java b/common/src/main/java/com/github/lunatrius/schematica/command/CommandSchematicaList.java index 5effa93e..fdae43c6 100644 --- a/common/src/main/java/com/github/lunatrius/schematica/command/CommandSchematicaList.java +++ b/common/src/main/java/com/github/lunatrius/schematica/command/CommandSchematicaList.java @@ -25,9 +25,9 @@ public class CommandSchematicaList extends CommandSchematicaBase { public static ArgumentBuilder register() { return Commands.literal(Names.Command.List.NAME) - .executes(CommandSchematicaList::printList) - .then(Commands.argument("page", IntegerArgumentType.integer(1)) - .executes(CommandSchematicaList::printList)); + .executes(CommandSchematicaList::printList) + .then(Commands.argument("page", IntegerArgumentType.integer(1)) + .executes(CommandSchematicaList::printList)); } private static int printList(@NotNull CommandContext commandContext) @@ -60,7 +60,7 @@ private static int printList(@NotNull CommandContext command if (!schematicDirectory.exists()) { if (!schematicDirectory.mkdirs()) { Reference.logger.warn("Could not create player schematic directory {}", - schematicDirectory.getAbsolutePath()); + schematicDirectory.getAbsolutePath()); source.sendFailure(Component.translatable(Names.Command.Save.Message.PLAYER_SCHEMATIC_DIR_UNAVAILABLE)); return -1; @@ -74,23 +74,23 @@ private static int printList(@NotNull CommandContext command String fileName = path.getName(); Component chatComponent = Component.literal(String.format("%2d (%s): %s [", currentFile + 1, - FileUtils.humanReadableByteCount( - path.length()), - FilenameUtils.removeExtension(fileName))); + FileUtils.humanReadableByteCount( + path.length()), + FilenameUtils.removeExtension(fileName))); String removeCommand = String.format("/%s %s", Reference.MOD_ID + " " + Names.Command.Remove.NAME, fileName); Component removeLink = withStyle(Component.translatable(Names.Command.List.Message.REMOVE), ChatFormatting.RED, - removeCommand); + removeCommand); chatComponent = chatComponent.copy().append(removeLink).append("]["); String downloadCommand = String.format("/%s %s", Reference.MOD_ID + " " + Names.Command.Download.NAME, fileName); Component downloadLink = withStyle(Component.translatable(Names.Command.List.Message.DOWNLOAD), - ChatFormatting.GREEN, - downloadCommand); + ChatFormatting.GREEN, + downloadCommand); chatComponent = chatComponent.copy().append(downloadLink).append("]"); componentsToSend.add(chatComponent); @@ -112,7 +112,7 @@ private static int printList(@NotNull CommandContext command source.sendSystemMessage( withStyle(Component.translatable(Names.Command.List.Message.PAGE_HEADER, page + 1, totalPages + 1), - ChatFormatting.DARK_GREEN, null)); + ChatFormatting.DARK_GREEN, null)); for (Component chatComponent : componentsToSend) { source.sendSystemMessage(chatComponent); } diff --git a/common/src/main/java/com/github/lunatrius/schematica/command/CommandSchematicaSave.java b/common/src/main/java/com/github/lunatrius/schematica/command/CommandSchematicaSave.java index af4bf1e0..d3f9ddcf 100644 --- a/common/src/main/java/com/github/lunatrius/schematica/command/CommandSchematicaSave.java +++ b/common/src/main/java/com/github/lunatrius/schematica/command/CommandSchematicaSave.java @@ -21,21 +21,20 @@ public class CommandSchematicaSave extends CommandSchematicaBase { public static ArgumentBuilder register() { return Commands.literal(Names.Command.Save.NAME) - .then(Commands.argument("from", BlockPosArgument.blockPos()) - .then(Commands.argument("to", BlockPosArgument.blockPos()) - .then(Commands.argument("name", StringArgumentType.string()) - .executes(CommandSchematicaSave::execute) - .then(Commands.argument("format", - StringArgumentType.string()) - .suggests(((context, builder) -> { - for (String s : - SchematicFormat.FORMATS.keySet()) { - builder.suggest(s); - } - return builder.buildFuture(); - })) - .executes( - CommandSchematicaSave::execute))))); + .then(Commands.argument("from", BlockPosArgument.blockPos()) + .then(Commands.argument("to", BlockPosArgument.blockPos()) + .then(Commands.argument("name", StringArgumentType.string()) + .executes(CommandSchematicaSave::execute) + .then(Commands.argument("format", + StringArgumentType.string()) + .suggests(((context, builder) -> { + for (String s : + SchematicFormat.FORMATS.keySet()) { + builder.suggest(s); + } + return builder.buildFuture(); + })) + .executes(CommandSchematicaSave::execute))))); } private static int execute(@NotNull CommandContext commandContext) @@ -67,7 +66,7 @@ private static int execute(@NotNull CommandContext commandCo String filename = name + SchematicFormat.getExtension(format); - Reference.logger.debug("Saving " + "schematic from {} to {} to {}", from, to, filename); + Reference.logger.debug("Saving schematic from {} to {} to {}", from, to, filename); File schematicDirectory = Reference.proxy.getPlayerSchematicDirectory(player, true); if (schematicDirectory == null) { //Chances are that if this is null, we could not retrieve their UUID. @@ -79,7 +78,7 @@ private static int execute(@NotNull CommandContext commandCo if (!schematicDirectory.exists()) { if (!schematicDirectory.mkdirs()) { Reference.logger.warn("Could not create " + "player " + "schematic " + "directory " + "{}", - schematicDirectory.getAbsolutePath()); + schematicDirectory.getAbsolutePath()); source.sendFailure(Component.translatable(Names.Command.Save.Message.PLAYER_SCHEMATIC_DIR_UNAVAILABLE)); return -1; } @@ -87,7 +86,7 @@ private static int execute(@NotNull CommandContext commandCo try { Reference.proxy.saveSchematic(player, schematicDirectory, filename, player.getCommandSenderWorld(), format, - from, to); + from, to); } catch (Exception e) { source.sendFailure(Component.translatable(Names.Command.Save.Message.SAVE_FAILED)); return -1; diff --git a/common/src/main/java/com/github/lunatrius/schematica/command/client/CommandSchematicaReplace.java b/common/src/main/java/com/github/lunatrius/schematica/command/client/CommandSchematicaReplace.java index ee6d7858..4caeb27a 100644 --- a/common/src/main/java/com/github/lunatrius/schematica/command/client/CommandSchematicaReplace.java +++ b/common/src/main/java/com/github/lunatrius/schematica/command/client/CommandSchematicaReplace.java @@ -6,49 +6,53 @@ import com.github.lunatrius.schematica.reference.Names; import com.github.lunatrius.schematica.reference.Reference; import com.github.lunatrius.schematica.world.FakeLevel; -import com.mojang.brigadier.builder.ArgumentBuilder; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import dev.architectury.event.events.client.ClientCommandRegistrationEvent; import net.minecraft.commands.CommandBuildContext; -import net.minecraft.commands.CommandSourceStack; -import net.minecraft.commands.Commands; +import net.minecraft.commands.arguments.blocks.BlockInput; import net.minecraft.commands.arguments.blocks.BlockStateArgument; import net.minecraft.network.chat.Component; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.levelgen.structure.templatesystem.BlockStateMatchTest; public class CommandSchematicaReplace extends CommandSchematicaBase { - public static ArgumentBuilder register(CommandBuildContext context) { - return Commands.literal(Names.Command.Replace.NAME) - .then(Commands.argument("toReplace", BlockStateArgument.block(context)) - .then(Commands.argument("with", BlockStateArgument.block(context))) - .executes((commandContext) -> { - CommandSourceStack source = commandContext.getSource(); - BlockState toReplace = - BlockStateArgument.getBlock(commandContext, "toReplace").getState(); - BlockState with = - BlockStateArgument.getBlock(commandContext, "with").getState(); + public static LiteralArgumentBuilder register(CommandBuildContext context) { + return ClientCommandRegistrationEvent.literal(Names.Command.BASE).then( + ClientCommandRegistrationEvent.literal(Names.Command.Replace.NAME) + .then(ClientCommandRegistrationEvent.argument("toReplace", BlockStateArgument.block(context)) + .then(ClientCommandRegistrationEvent.argument("with", + BlockStateArgument.block(context)) + .executes((commandContext) -> { + ClientCommandRegistrationEvent.ClientCommandSourceStack source = + commandContext.getSource(); - FakeLevel schematic = ClientProxy.schematic; + BlockState toReplace = commandContext.getArgument("toReplace", + BlockInput.class).getState(); + BlockState with = + commandContext.getArgument("with", BlockInput.class).getState(); - if (schematic == null) { - source.sendFailure(Component.translatable( - Names.Command.Replace.Message.NO_SCHEMATIC)); - return -1; - } + FakeLevel schematic = ClientProxy.schematic; - try { - BlockStateMatchTest matcher = new BlockStateMatchTest(toReplace); - BlockStateReplacer replacer = BlockStateReplacer.forBlockState(with); - int count = schematic.replaceBlock(matcher, replacer); + if (schematic == null) { + source.arch$sendFailure(Component.translatable( + Names.Command.Replace.Message.NO_SCHEMATIC)); + return -1; + } - source.sendSuccess( - () -> Component.translatable(Names.Command.Replace.Message.SUCCESS, - count), true); - } catch (Exception e) { - Reference.logger.error("Something went wrong!", e); - source.sendFailure(Component.literal(e.getMessage())); - return -1; - } - return 0; - })); + try { + BlockStateMatchTest matcher = new BlockStateMatchTest(toReplace); + BlockStateReplacer replacer = BlockStateReplacer.forBlockState(with); + int count = schematic.replaceBlock(matcher, replacer); + + source.arch$sendSuccess( + () -> Component.translatable(Names.Command.Replace.Message.SUCCESS, + count), true); + } catch (Exception e) { + Reference.logger.error("Something went wrong!", e); + source.arch$sendFailure(Component.literal(e.getMessage())); + return -1; + } + return 0; + })))); } } \ No newline at end of file diff --git a/common/src/main/java/com/github/lunatrius/schematica/handler/DownloadHandler.java b/common/src/main/java/com/github/lunatrius/schematica/handler/DownloadHandler.java index 27542846..edcc8f99 100644 --- a/common/src/main/java/com/github/lunatrius/schematica/handler/DownloadHandler.java +++ b/common/src/main/java/com/github/lunatrius/schematica/handler/DownloadHandler.java @@ -9,15 +9,12 @@ import com.github.lunatrius.schematica.reference.Reference; import commonnetwork.api.Dispatcher; import dev.architectury.event.events.common.TickEvent; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import java.util.LinkedHashMap; import java.util.Map; -@Environment(EnvType.SERVER) public class DownloadHandler { public static final DownloadHandler INSTANCE = new DownloadHandler(); public final Map transferMap = new LinkedHashMap<>(); diff --git a/common/src/main/java/com/github/lunatrius/schematica/network/message/MessageCapabilities.java b/common/src/main/java/com/github/lunatrius/schematica/network/message/MessageCapabilities.java index 35556c05..a59f84ad 100644 --- a/common/src/main/java/com/github/lunatrius/schematica/network/message/MessageCapabilities.java +++ b/common/src/main/java/com/github/lunatrius/schematica/network/message/MessageCapabilities.java @@ -11,6 +11,7 @@ import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.NotNull; @MethodsReturnNonnullByDefault public record MessageCapabilities(boolean isPrinterEnabled, boolean isSaveEnabled, boolean isLoadEnabled) @@ -23,7 +24,7 @@ public record MessageCapabilities(boolean isPrinterEnabled, boolean isSaveEnable MessageCapabilities::isSaveEnabled, ByteBufCodecs.BOOL, MessageCapabilities::isLoadEnabled, MessageCapabilities::new); - public static void handle(PacketContext ctx) { + public static void handle(@NotNull PacketContext ctx) { if (ctx.side() == Side.CLIENT) { SchematicPrinter.INSTANCE.setEnabled(ctx.message().isPrinterEnabled()); Reference.proxy.isSaveEnabled = ctx.message().isSaveEnabled(); diff --git a/common/src/main/java/com/github/lunatrius/schematica/network/message/MessageDownloadBegin.java b/common/src/main/java/com/github/lunatrius/schematica/network/message/MessageDownloadBegin.java index 27807a31..d38721e5 100644 --- a/common/src/main/java/com/github/lunatrius/schematica/network/message/MessageDownloadBegin.java +++ b/common/src/main/java/com/github/lunatrius/schematica/network/message/MessageDownloadBegin.java @@ -15,6 +15,7 @@ import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.ItemStack; +import org.jetbrains.annotations.NotNull; @MethodsReturnNonnullByDefault public record MessageDownloadBegin(ItemStack icon, int width, int height, int length) @@ -28,11 +29,11 @@ public record MessageDownloadBegin(ItemStack icon, int width, int height, int le MessageDownloadBegin::width, ByteBufCodecs.INT, MessageDownloadBegin::height, ByteBufCodecs.INT, MessageDownloadBegin::length, MessageDownloadBegin::new); - public MessageDownloadBegin(ISchematic schematic) { + public MessageDownloadBegin(@NotNull ISchematic schematic) { this(schematic.getIcon(), schematic.getSizeX(), schematic.getHeight(), schematic.getSizeZ()); } - public static void handle(PacketContext ctx) { + public static void handle(@NotNull PacketContext ctx) { if (ctx.side() == Side.CLIENT) { DownloadHandler.INSTANCE.schematic = new Schematic(ctx.message().icon, ctx.message().width, ctx.message().height, ctx.message().length); diff --git a/common/src/main/java/com/github/lunatrius/schematica/network/message/MessageDownloadChunk.java b/common/src/main/java/com/github/lunatrius/schematica/network/message/MessageDownloadChunk.java index d505645b..41596a4c 100644 --- a/common/src/main/java/com/github/lunatrius/schematica/network/message/MessageDownloadChunk.java +++ b/common/src/main/java/com/github/lunatrius/schematica/network/message/MessageDownloadChunk.java @@ -4,14 +4,16 @@ import com.github.lunatrius.schematica.api.ISchematic; import com.github.lunatrius.schematica.handler.DownloadHandler; import com.github.lunatrius.schematica.nbt.NBTHelper; +import com.github.lunatrius.schematica.network.transfer.SchematicTransfer; import com.github.lunatrius.schematica.reference.Constants; import com.github.lunatrius.schematica.reference.Names; import com.github.lunatrius.schematica.reference.Reference; import commonnetwork.api.Dispatcher; import commonnetwork.networking.data.PacketContext; import commonnetwork.networking.data.Side; +import dev.architectury.platform.Platform; +import net.fabricmc.api.EnvType; import net.minecraft.MethodsReturnNonnullByDefault; -import net.minecraft.client.Minecraft; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.StreamCodec; @@ -21,6 +23,7 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -32,38 +35,16 @@ public class MessageDownloadChunk implements CustomPacketPayload { ResourceLocation.fromNamespaceAndPath(Reference.MOD_ID, Names.Network.DOWNLOAD_CHUNK_LOCATION)); public static final StreamCodec STREAM_CODEC = new StreamCodec<>() { - public @NotNull MessageDownloadChunk decode(RegistryFriendlyByteBuf buf) { - int msgBaseX = buf.readInt(); - int msgBaseY = buf.readInt(); - int msgBaseZ = buf.readInt(); - - BlockState[][][] msgBlocks = - new BlockState[Constants.SchematicChunk.WIDTH][Constants.SchematicChunk.HEIGHT][Constants.SchematicChunk.LENGTH]; - List msgBlockEntities = new ArrayList<>(); - List msgEntities = new ArrayList<>(); - - for (int x = 0; x < Constants.SchematicChunk.WIDTH; x++) { - for (int y = 0; y < Constants.SchematicChunk.HEIGHT; y++) { - for (int z = 0; z < Constants.SchematicChunk.LENGTH; z++) { - msgBlocks[x][y][z] = Block.stateById(buf.readVarInt()); - } - } - } - - CompoundTag blockEntitiesTag = buf.readNbt(); - if (blockEntitiesTag != null) { - NBTHelper.readBlockEntitiesFromCompound(blockEntitiesTag, Minecraft.getInstance().level, - msgBlockEntities); + @Contract("_ -> new") + public @NotNull MessageDownloadChunk decode(@NotNull RegistryFriendlyByteBuf buf) { + if (Platform.getEnv() == EnvType.CLIENT) { + return SchematicTransfer.readFromBuff(buf); } - CompoundTag entitiesTag = buf.readNbt(); - NBTHelper.readEntitiesFromCompound(entitiesTag, msgEntities, Minecraft.getInstance().level); - - return new MessageDownloadChunk(msgBaseX, msgBaseY, msgBaseZ, msgBlocks, msgBlockEntities, msgEntities); - + throw new IllegalStateException("Can't be run on server"); } - public void encode(RegistryFriendlyByteBuf buf, MessageDownloadChunk msg) { + public void encode(@NotNull RegistryFriendlyByteBuf buf, @NotNull MessageDownloadChunk msg) { buf.writeInt(msg.getBaseX()); buf.writeInt(msg.getBaseY()); buf.writeInt(msg.getBaseZ()); @@ -116,8 +97,8 @@ public MessageDownloadChunk(ISchematic schematic, int baseX, int baseY, int base } } - private MessageDownloadChunk(int baseX, int baseY, int baseZ, BlockState[][][] blocks, - List blockEntities, List entities) { + public MessageDownloadChunk(int baseX, int baseY, int baseZ, BlockState[][][] blocks, + List blockEntities, List entities) { this.baseX = baseX; this.baseY = baseY; this.baseZ = baseZ; @@ -126,12 +107,12 @@ private MessageDownloadChunk(int baseX, int baseY, int baseZ, BlockState[][][] b this.entities = entities; } - public static void handle(PacketContext ctx) { + public static void handle(@NotNull PacketContext ctx) { if (ctx.side() == Side.CLIENT) { ctx.message().copyToSchematic(DownloadHandler.INSTANCE.schematic); Dispatcher.sendToServer( new MessageDownloadChunkAck(true, ctx.message().getBaseX(), ctx.message().getBaseY(), - ctx.message().getBaseZ())); + ctx.message().getBaseZ())); } } diff --git a/common/src/main/java/com/github/lunatrius/schematica/network/transfer/SchematicTransfer.java b/common/src/main/java/com/github/lunatrius/schematica/network/transfer/SchematicTransfer.java index 582dc90b..29c6c063 100644 --- a/common/src/main/java/com/github/lunatrius/schematica/network/transfer/SchematicTransfer.java +++ b/common/src/main/java/com/github/lunatrius/schematica/network/transfer/SchematicTransfer.java @@ -1,7 +1,21 @@ package com.github.lunatrius.schematica.network.transfer; import com.github.lunatrius.schematica.api.ISchematic; +import com.github.lunatrius.schematica.nbt.NBTHelper; +import com.github.lunatrius.schematica.network.message.MessageDownloadChunk; import com.github.lunatrius.schematica.reference.Constants; +import net.minecraft.client.Minecraft; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; public class SchematicTransfer { public final ISchematic schematic; @@ -16,7 +30,7 @@ public class SchematicTransfer { public int baseY = 0; public int baseZ = 0; - public SchematicTransfer(ISchematic schematic, String name) { + public SchematicTransfer(@NotNull ISchematic schematic, String name) { this.schematic = schematic; this.name = name; @@ -71,4 +85,36 @@ public boolean isWaiting() { return this.waiting; } } + + @Contract("_ -> new") + public static @NotNull MessageDownloadChunk readFromBuff(@NotNull RegistryFriendlyByteBuf buf) { + int msgBaseX = buf.readInt(); + int msgBaseY = buf.readInt(); + int msgBaseZ = buf.readInt(); + + BlockState[][][] msgBlocks = + new BlockState[Constants.SchematicChunk.WIDTH][Constants.SchematicChunk.HEIGHT][Constants.SchematicChunk.LENGTH]; + List msgBlockEntities = new ArrayList<>(); + List msgEntities = new ArrayList<>(); + + for (int x = 0; x < Constants.SchematicChunk.WIDTH; x++) { + for (int y = 0; y < Constants.SchematicChunk.HEIGHT; y++) { + for (int z = 0; z < Constants.SchematicChunk.LENGTH; z++) { + msgBlocks[x][y][z] = Block.stateById(buf.readVarInt()); + } + } + } + + CompoundTag blockEntitiesTag = buf.readNbt(); + if (blockEntitiesTag != null) { + NBTHelper.readBlockEntitiesFromCompound(blockEntitiesTag, Minecraft.getInstance().level, + msgBlockEntities); + } + + CompoundTag entitiesTag = buf.readNbt(); + NBTHelper.readEntitiesFromCompound(entitiesTag, msgEntities, Minecraft.getInstance().level); + + return new MessageDownloadChunk(msgBaseX, msgBaseY, msgBaseZ, msgBlocks, msgBlockEntities, + msgEntities); + } } \ No newline at end of file diff --git a/common/src/main/java/com/github/lunatrius/schematica/reference/Names.java b/common/src/main/java/com/github/lunatrius/schematica/reference/Names.java index b864644d..aeb64c46 100644 --- a/common/src/main/java/com/github/lunatrius/schematica/reference/Names.java +++ b/common/src/main/java/com/github/lunatrius/schematica/reference/Names.java @@ -66,6 +66,9 @@ public static class Category { } public static class Command { + public static final String BASE = "schematica"; + public static final String CLIENT_BASE = "schematicaClient"; + public static class Save { public static final String NAME = "save"; diff --git a/common/src/main/java/com/github/lunatrius/schematica/world/FakeLevel.java b/common/src/main/java/com/github/lunatrius/schematica/world/FakeLevel.java index 6458af35..b00f9d5b 100644 --- a/common/src/main/java/com/github/lunatrius/schematica/world/FakeLevel.java +++ b/common/src/main/java/com/github/lunatrius/schematica/world/FakeLevel.java @@ -108,15 +108,10 @@ public class FakeLevel extends Level { private boolean isRendering; /** - * @param levelSource - * data source, also try to set block entities/entities collections - * @param lightProvider - * light source - * @param scoreboard - * if null client level is used instead - * @param overrideBeLevel - * if true all block entities will have set level to this instance - * + * @param levelSource data source, also try to set block entities/entities collections + * @param lightProvider light source + * @param scoreboard if null client level is used instead + * @param overrideBeLevel if true all block entities will have set level to this instance * @see #setBlockEntities(Map) for better block entity handling, if set then levelSource BE getter is not used * @see #setEntities(Collection) only way to add entities into fake level * @see #setRealLevel(Level) if you want to reuse this instance @@ -124,8 +119,9 @@ public class FakeLevel extends Level { public FakeLevel(final ISchematic levelSource, final IFakeLevelLightProvider lightProvider, @Nullable final Scoreboard scoreboard, final boolean overrideBeLevel) { super(new FakeLevelData(clientLevel()::getLevelData, lightProvider), clientLevel().dimension(), - clientLevel().registryAccess(), clientLevel().dimensionTypeRegistration(), clientLevel().isClientSide(), - clientLevel().isDebug(), 0, 0); + clientLevel().registryAccess(), clientLevel().dimensionTypeRegistration(), + clientLevel().isClientSide(), + clientLevel().isDebug(), 0, 0); this.setLevelSource(levelSource); this.lightProvider = lightProvider; this.realLevel = clientLevel(); @@ -194,8 +190,7 @@ public MBlockPos getWorldPos() { } /** - * @param worldPos - * where is fake level anchor when querying current client level data + * @param worldPos where is fake level anchor when querying current client level data */ public void setWorldPos(MBlockPos worldPos) { this.worldPos = worldPos; @@ -206,8 +201,7 @@ public void setWorldPos(MBlockPos worldPos) { * {@link ISchematic#getBlockEntity(BlockPos) * levelSource.getBlockEntity(BlockPos)} is not used. Reset with empty collection * - * @param blockEntities - * all block entities, should be data equivalent to levelSource + * @param blockEntities all block entities, should be data equivalent to levelSource */ public void setBlockEntities(Map blockEntities) { this.blockEntities = blockEntities; @@ -245,10 +239,9 @@ public ChunkAccess getChunk(int x, int z, @NotNull ChunkStatus requiredStatus, b } @Override - public boolean setBlock(@Nullable BlockPos ignored_1, @Nullable BlockState ignored_2, int ignored_3, - int ignored_4) { - // Noop - return false; + public boolean setBlock(@Nullable BlockPos pos, @Nullable BlockState block, int ignored_1, + int ignored_2) { + return levelSource.setBlockState(pos, block); } @Override @@ -309,7 +302,7 @@ public LevelLightEngine getLightEngine() { @Override public BlockState getBlockState(@NotNull BlockPos pos) { return getLevelSource().isPosInside(pos) ? getLevelSource().getBlockState(pos) : - Blocks.AIR.defaultBlockState(); + Blocks.AIR.defaultBlockState(); } @Override @@ -584,13 +577,12 @@ protected LevelEntityGetter getEntities() { } /** - * @param entities - * all entities, their level should be this fake level instance. Reset with empty collection + * @param entities all entities, their level should be this fake level instance. Reset with empty collection */ public void setEntities(@NotNull Collection entities) { levelEntityGetter = entities.isEmpty() - ? FakeLevelEntityGetterAdapter.EMPTY - : FakeLevelEntityGetterAdapter.ofEntities(entities); + ? FakeLevelEntityGetterAdapter.EMPTY + : FakeLevelEntityGetterAdapter.ofEntities(entities); } @Override @@ -674,8 +666,8 @@ public float getShade(@NotNull Direction direction, boolean shade) { public int getBrightness(@NotNull LightLayer lightType, @NotNull BlockPos pos) { try (Level realLevel = realLevel()) { return lightProvider.forceOwnLightLevel() - ? lightProvider.getBrightness(lightType, pos) - : realLevel.getBrightness(lightType, worldPos.offset(pos)); + ? lightProvider.getBrightness(lightType, pos) + : realLevel.getBrightness(lightType, worldPos.offset(pos)); } catch (IOException e) { throw new RuntimeException(e); } @@ -685,8 +677,8 @@ public int getBrightness(@NotNull LightLayer lightType, @NotNull BlockPos pos) { public int getRawBrightness(@NotNull BlockPos pos, int amount) { try (Level realLevel = realLevel()) { return lightProvider.forceOwnLightLevel() - ? lightProvider.getRawBrightness(pos, amount) - : realLevel.getRawBrightness(worldPos.offset(pos), amount); + ? lightProvider.getRawBrightness(pos, amount) + : realLevel.getRawBrightness(worldPos.offset(pos), amount); } catch (IOException e) { throw new RuntimeException(e); } @@ -778,10 +770,9 @@ public int replaceBlock(BlockStateMatchTest matcher, BlockStateReplacer replacer int count = 0; for (MBlockPos pos : BlockPosHelper.getAllInBox(0, 0, 0, getLevelSource().getMaxX(), getHeight(), - getLevelSource().getMaxZ())) { + getLevelSource().getMaxZ())) { BlockState blockState = this.getBlockState(pos); - // TODO: add support for tile entities? if (blockState.hasBlockEntity()) { continue; } @@ -790,7 +781,6 @@ public int replaceBlock(BlockStateMatchTest matcher, BlockStateReplacer replacer Map properties = BlockStateHelper.getProperties(blockState); BlockState replacement = replacer.getReplacement(properties); - // TODO: add support for tile entities? if (replacement.hasBlockEntity()) { continue; } diff --git a/gradle.properties b/gradle.properties index f2fdb1e0..62c91a2b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,11 +12,9 @@ minecraft_version=1.21.4 # Dependencies architectury_api_version=15.0.1 fabric_loader_version=0.16.10 -fabric_api_version=0.115.1+1.21.4 -neoforge_version=21.4.82-beta +fabric_api_version=0.116.0+1.21.4 +neoforge_version=21.4.88-beta mapping_version=2025.01.19 lunatriuscore_version=2.1.0 forge_config_api_port_version=21.4.1 -common_networking_version=1.0.18-1.21.1 -owo_version=0.12.20+1.21.4 -owo_version_neo=0.12.19-beta.1+1.21.4 \ No newline at end of file +common_networking_version=1.0.18-1.21.1 \ No newline at end of file diff --git a/neoforge/src/main/java/com/github/lunatrius/schematica/neoforge/SchematicaNeoForge.java b/neoforge/src/main/java/com/github/lunatrius/schematica/neoforge/SchematicaNeoForge.java index 5852f7b4..29ca530f 100644 --- a/neoforge/src/main/java/com/github/lunatrius/schematica/neoforge/SchematicaNeoForge.java +++ b/neoforge/src/main/java/com/github/lunatrius/schematica/neoforge/SchematicaNeoForge.java @@ -6,10 +6,11 @@ import net.neoforged.fml.ModContainer; import net.neoforged.fml.common.Mod; import net.neoforged.fml.config.ModConfig; +import org.jetbrains.annotations.NotNull; @Mod(Reference.MOD_ID) public final class SchematicaNeoForge { - public SchematicaNeoForge(ModContainer modContainer) { + public SchematicaNeoForge(@NotNull ModContainer modContainer) { // Run our common setup. Schematica.init();