diff --git a/src/api/java/baritone/api/schematic/ISchematicSystem.java b/src/api/java/baritone/api/schematic/ISchematicSystem.java index c8f039070..385cc0514 100644 --- a/src/api/java/baritone/api/schematic/ISchematicSystem.java +++ b/src/api/java/baritone/api/schematic/ISchematicSystem.java @@ -21,6 +21,7 @@ import baritone.api.command.registry.Registry; import baritone.api.schematic.format.ISchematicFormat; import java.io.File; +import java.util.List; import java.util.Optional; /** @@ -41,4 +42,9 @@ public interface ISchematicSystem { * @return The corresponding format for the file, {@link Optional#empty()} if no candidates were found. */ Optional getByFile(File file); + + /** + * @return A list of file extensions used by supported formats + */ + List getFileExtensions(); } diff --git a/src/api/java/baritone/api/schematic/format/ISchematicFormat.java b/src/api/java/baritone/api/schematic/format/ISchematicFormat.java index 3fe045bcf..0ccf059b0 100644 --- a/src/api/java/baritone/api/schematic/format/ISchematicFormat.java +++ b/src/api/java/baritone/api/schematic/format/ISchematicFormat.java @@ -23,6 +23,7 @@ import baritone.api.schematic.IStaticSchematic; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.util.List; /** * The base of a {@link ISchematic} file format @@ -42,4 +43,9 @@ public interface ISchematicFormat { * @return Whether or not the specified file matches this schematic format */ boolean isFileType(File file); + + /** + * @return A list of file extensions used by this format + */ + List getFileExtensions(); } diff --git a/src/main/java/baritone/command/defaults/BuildCommand.java b/src/main/java/baritone/command/defaults/BuildCommand.java index bb34254ae..f9ddd33ef 100644 --- a/src/main/java/baritone/command/defaults/BuildCommand.java +++ b/src/main/java/baritone/command/defaults/BuildCommand.java @@ -26,11 +26,13 @@ import baritone.api.command.datatypes.RelativeFile; import baritone.api.command.exception.CommandException; import baritone.api.command.exception.CommandInvalidStateException; import baritone.api.utils.BetterBlockPos; +import baritone.utils.schematic.SchematicSystem; import org.apache.commons.io.FilenameUtils; import java.io.File; import java.util.Arrays; import java.util.List; +import java.util.StringJoiner; import java.util.stream.Stream; public class BuildCommand extends Command { @@ -44,10 +46,29 @@ public class BuildCommand extends Command { @Override public void execute(String label, IArgConsumer args) throws CommandException { - File file = args.getDatatypePost(RelativeFile.INSTANCE, schematicsDir).getAbsoluteFile(); + final File file0 = args.getDatatypePost(RelativeFile.INSTANCE, schematicsDir).getAbsoluteFile(); + File file = file0; if (FilenameUtils.getExtension(file.getAbsolutePath()).isEmpty()) { file = new File(file.getAbsolutePath() + "." + Baritone.settings().schematicFallbackExtension.value); } + if (!file.exists()) { + if (file0.exists()) { + throw new CommandInvalidStateException(String.format( + "Cannot load %s because I do not know which schematic format" + + " that is. Please rename the file to include the correct" + + " file extension.", + file)); + } + throw new CommandInvalidStateException("Cannot find " + file); + } + if (!SchematicSystem.INSTANCE.getByFile(file).isPresent()) { + StringJoiner formats = new StringJoiner(", "); + SchematicSystem.INSTANCE.getFileExtensions().forEach(formats::add); + throw new CommandInvalidStateException(String.format( + "Unsupported schematic format. Reckognized file extensions are: %s", + formats + )); + } BetterBlockPos origin = ctx.playerFeet(); BetterBlockPos buildOrigin; if (args.hasAny()) { @@ -59,7 +80,7 @@ public class BuildCommand extends Command { } boolean success = baritone.getBuilderProcess().build(file.getName(), file, buildOrigin); if (!success) { - throw new CommandInvalidStateException("Couldn't load the schematic. Make sure to use the FULL file name, including the extension (e.g. blah.schematic)."); + throw new CommandInvalidStateException("Couldn't load the schematic. Either your schematic is corrupt or this is a bug."); } logDirect(String.format("Successfully loaded schematic for building\nOrigin: %s", buildOrigin)); } diff --git a/src/main/java/baritone/utils/schematic/SchematicSystem.java b/src/main/java/baritone/utils/schematic/SchematicSystem.java index 8afafa8c3..ec6e7f626 100644 --- a/src/main/java/baritone/utils/schematic/SchematicSystem.java +++ b/src/main/java/baritone/utils/schematic/SchematicSystem.java @@ -24,6 +24,7 @@ import baritone.utils.schematic.format.DefaultSchematicFormats; import java.io.File; import java.util.Arrays; +import java.util.List; import java.util.Optional; /** @@ -48,4 +49,9 @@ public enum SchematicSystem implements ISchematicSystem { public Optional getByFile(File file) { return this.registry.stream().filter(format -> format.isFileType(file)).findFirst(); } + + @Override + public List getFileExtensions() { + return this.registry.stream().map(ISchematicFormat::getFileExtensions).flatMap(List::stream).toList(); + } } diff --git a/src/main/java/baritone/utils/schematic/format/DefaultSchematicFormats.java b/src/main/java/baritone/utils/schematic/format/DefaultSchematicFormats.java index 40a95b50c..25ef7b0d9 100644 --- a/src/main/java/baritone/utils/schematic/format/DefaultSchematicFormats.java +++ b/src/main/java/baritone/utils/schematic/format/DefaultSchematicFormats.java @@ -22,13 +22,15 @@ import baritone.api.schematic.format.ISchematicFormat; import baritone.utils.schematic.format.defaults.LitematicaSchematic; import baritone.utils.schematic.format.defaults.MCEditSchematic; import baritone.utils.schematic.format.defaults.SpongeSchematic; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtIo; import org.apache.commons.io.FilenameUtils; import java.io.File; import java.io.IOException; import java.io.InputStream; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.NbtIo; +import java.util.Collections; +import java.util.List; /** * Default implementations of {@link ISchematicFormat} @@ -98,4 +100,9 @@ public enum DefaultSchematicFormats implements ISchematicFormat { public boolean isFileType(File file) { return this.extension.equalsIgnoreCase(FilenameUtils.getExtension(file.getAbsolutePath())); } + + @Override + public List getFileExtensions() { + return Collections.singletonList(this.extension); + } }