From 329524288df6b3853363687f819ebb960f90bdc3 Mon Sep 17 00:00:00 2001 From: Maddy Miller Date: Mon, 25 Dec 2023 13:52:22 +1000 Subject: [PATCH] Improve error handling for unsupported schematic files (#2453) * Improve error handling for unsupported schematic files * Fix review notes --- .../clipboard/io/SchematicLoadException.java | 43 +++++++++++++++++++ .../clipboard/io/SpongeSchematicReader.java | 11 ++++- .../WorldEditExceptionConverter.java | 6 +++ .../src/main/resources/lang/strings.json | 1 + 4 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SchematicLoadException.java diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SchematicLoadException.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SchematicLoadException.java new file mode 100644 index 000000000..f94216669 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SchematicLoadException.java @@ -0,0 +1,43 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.extent.clipboard.io; + +import com.sk89q.worldedit.util.formatting.text.Component; + +/** + * Raised when a known exception occurs during schematic load. + */ +public final class SchematicLoadException extends RuntimeException { + + private final Component message; + + public SchematicLoadException(Component message) { + this.message = message; + } + + /** + * Get the message of this exception as a rich text component. + * + * @return The rich message + */ + public Component getRichMessage() { + return this.message; + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java index 89c70db10..a18d1dbbf 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java @@ -45,6 +45,8 @@ import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.Location; +import com.sk89q.worldedit.util.formatting.text.TextComponent; +import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; import com.sk89q.worldedit.world.DataFixer; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeTypes; @@ -124,7 +126,7 @@ public class SpongeSchematicReader extends NBTSchematicReader { BlockArrayClipboard clip = readVersion1(schematicTag); return readVersion2(clip, schematicTag); } - throw new IOException("This schematic version is currently not supported"); + throw new SchematicLoadException(TranslatableComponent.of("worldedit.schematic.load.unsupported-version", TextComponent.of(schematicVersion))); } @Override @@ -154,6 +156,13 @@ public class SpongeSchematicReader extends NBTSchematicReader { // Check Map schematic = schematicTag.getValue(); + // Be lenient about the specific nesting level of the Schematic tag + // Also allows checking the version from newer versions of the specification + if (schematic.size() == 1 && schematic.containsKey("Schematic")) { + schematicTag = requireTag(schematic, "Schematic", CompoundTag.class); + schematic = schematicTag.getValue(); + } + schematicVersion = requireTag(schematic, "Version", IntTag.class).getValue(); return schematicTag; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/exception/WorldEditExceptionConverter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/exception/WorldEditExceptionConverter.java index 22cc824e0..8d2fd40a3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/exception/WorldEditExceptionConverter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/exception/WorldEditExceptionConverter.java @@ -34,6 +34,7 @@ import com.sk89q.worldedit.command.InsufficientArgumentsException; import com.sk89q.worldedit.command.tool.InvalidToolBindException; import com.sk89q.worldedit.extension.input.DisallowedUsageException; import com.sk89q.worldedit.extension.input.NoMatchException; +import com.sk89q.worldedit.extent.clipboard.io.SchematicLoadException; import com.sk89q.worldedit.internal.expression.ExpressionException; import com.sk89q.worldedit.regions.RegionOperationException; import com.sk89q.worldedit.util.formatting.text.Component; @@ -183,6 +184,11 @@ public class WorldEditExceptionConverter extends ExceptionConverterHelper { throw newCommandException(TranslatableComponent.of("worldedit.error.file-aborted"), e); } + @ExceptionMatch + public void convert(SchematicLoadException e) throws CommandException { + throw newCommandException(e.getRichMessage(), e); + } + @ExceptionMatch public void convert(WorldEditException e) throws CommandException { throw newCommandException(e.getRichMessage(), e); diff --git a/worldedit-core/src/main/resources/lang/strings.json b/worldedit-core/src/main/resources/lang/strings.json index e1f7e210e..63df5a3fb 100644 --- a/worldedit-core/src/main/resources/lang/strings.json +++ b/worldedit-core/src/main/resources/lang/strings.json @@ -106,6 +106,7 @@ "worldedit.schematic.load.does-not-exist": "Schematic {0} does not exist!", "worldedit.schematic.load.loading": "(Please wait... loading schematic.)", "worldedit.schematic.load.still-loading": "(Please wait... still loading schematic.)", + "worldedit.schematic.load.unsupported-version": "This schematic version is currently not supported. Version: {0}.", "worldedit.schematic.save.already-exists": "That schematic already exists. Use the -f flag to overwrite it.", "worldedit.schematic.save.failed-directory": "Could not create folder for schematics!", "worldedit.schematic.save.saving": "(Please wait... saving schematic.)",