fix: allow webinterface schematic format to be detected (#2901)

* fix: allow webinterface schematic format to be detected

* chore: address review
This commit is contained in:
Pierre Maurice Schwang 2024-09-11 22:27:21 +02:00 committed by GitHub
parent f771b0cf90
commit a1bea11c80
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 43 additions and 23 deletions

View File

@ -701,7 +701,7 @@ public class MainUtil {
public static File resolve(File dir, String filename, @Nullable ClipboardFormat format, boolean allowDir) { public static File resolve(File dir, String filename, @Nullable ClipboardFormat format, boolean allowDir) {
if (format != null) { if (format != null) {
if (!filename.matches(".*\\.[\\w].*")) { if (!filename.matches(".*\\.\\w.*")) {
filename = filename + "." + format.getPrimaryFileExtension(); filename = filename + "." + format.getPrimaryFileExtension();
} }
return MainUtil.resolveRelative(new File(dir, filename)); return MainUtil.resolveRelative(new File(dir, filename));
@ -712,7 +712,7 @@ public class MainUtil {
return file; return file;
} }
} }
if (filename.matches(".*\\.[\\w].*")) { if (filename.matches(".*\\.\\w.*")) {
File file = MainUtil.resolveRelative(new File(dir, filename)); File file = MainUtil.resolveRelative(new File(dir, filename));
if (file.exists()) { if (file.exists()) {
return file; return file;

View File

@ -69,18 +69,18 @@ import org.enginehub.piston.exception.StopExecutionException;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.BufferedOutputStream; import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.EOFException;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.URI;
import java.net.URL;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -91,8 +91,8 @@ import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.function.Consumer;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -326,13 +326,13 @@ public class SchematicCommands {
//FAWE start //FAWE start
ClipboardFormat format; ClipboardFormat format;
InputStream in = null; InputStream in;
// if format is set explicitly, do not look up by extension! // if format is set explicitly, do not look up by extension!
boolean noExplicitFormat = formatName == null; boolean noExplicitFormat = formatName == null;
if (noExplicitFormat) { if (noExplicitFormat) {
formatName = "fast"; formatName = "fast";
} }
try { try(final Closer closer = Closer.create()) {
URI uri; URI uri;
if (formatName.startsWith("url:")) { if (formatName.startsWith("url:")) {
String t = filename; String t = filename;
@ -346,11 +346,31 @@ public class SchematicCommands {
} }
UUID uuid = UUID.fromString(filename.substring(4)); UUID uuid = UUID.fromString(filename.substring(4));
URL webUrl = new URL(Settings.settings().WEB.URL); URL webUrl = new URL(Settings.settings().WEB.URL);
format = ClipboardFormats.findByAlias(formatName); if ((format = ClipboardFormats.findByAlias(formatName)) == null) {
actor.print(Caption.of("worldedit.schematic.unknown-format", TextComponent.of(formatName)));
return;
}
// The interface requires the correct schematic extension - otherwise it can't be downloaded
// So it basically only supports .schem files (sponge v2 + v3) - or the correct extensions is specified manually
// Sadly it's not really an API endpoint but spits out the HTML source of the uploader - so no real handling
// can happen
URL url = new URL(webUrl, "uploads/" + uuid + "." + format.getPrimaryFileExtension()); URL url = new URL(webUrl, "uploads/" + uuid + "." + format.getPrimaryFileExtension());
ReadableByteChannel byteChannel = Channels.newChannel(url.openStream()); final Path temp = Files.createTempFile("faweremoteschem", null);
in = Channels.newInputStream(byteChannel); final File tempFile = temp.toFile();
uri = url.toURI(); // delete temporary file when we're done
closer.register((Closeable) () -> Files.deleteIfExists(temp));
// write schematic into temporary file
try (final InputStream urlIn = new BufferedInputStream(url.openStream());
final OutputStream tempOut = new BufferedOutputStream(new FileOutputStream(tempFile))) {
urlIn.transferTo(tempOut);
}
// No format is specified -> try or fail
if (noExplicitFormat && (format = ClipboardFormats.findByFile(tempFile)) == null) {
actor.print(Caption.of("fawe.worldedit.schematic.schematic.load-failure", TextComponent.of(filename)));
return;
}
in = new FileInputStream(tempFile);
uri = temp.toUri();
} else { } else {
File saveDir = worldEdit.getWorkingDirectoryPath(config.saveDir).toFile(); File saveDir = worldEdit.getWorkingDirectoryPath(config.saveDir).toFile();
File dir = Settings.settings().PATHS.PER_PLAYER_SCHEMATICS ? new File(saveDir, actor.getUniqueId().toString()) : saveDir; File dir = Settings.settings().PATHS.PER_PLAYER_SCHEMATICS ? new File(saveDir, actor.getUniqueId().toString()) : saveDir;
@ -378,7 +398,7 @@ public class SchematicCommands {
} }
if (!noExplicitFormat) { if (!noExplicitFormat) {
format = ClipboardFormats.findByAlias(formatName); format = ClipboardFormats.findByAlias(formatName);
} else if (filename.matches(".*\\.[\\w].*")) { } else if (filename.matches(".*\\.\\w.*")) {
format = ClipboardFormats format = ClipboardFormats
.findByExplicitExtension(filename.substring(filename.lastIndexOf('.') + 1)); .findByExplicitExtension(filename.substring(filename.lastIndexOf('.') + 1));
} else { } else {
@ -412,6 +432,7 @@ public class SchematicCommands {
in = new FileInputStream(file); in = new FileInputStream(file);
uri = file.toURI(); uri = file.toURI();
} }
closer.register(in);
format.hold(actor, uri, in); format.hold(actor, uri, in);
if (randomRotate) { if (randomRotate) {
AffineTransform transform = new AffineTransform(); AffineTransform transform = new AffineTransform();
@ -422,19 +443,18 @@ public class SchematicCommands {
actor.print(Caption.of("fawe.worldedit.schematic.schematic.loaded", filename)); actor.print(Caption.of("fawe.worldedit.schematic.schematic.loaded", filename));
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
actor.print(Caption.of("worldedit.schematic.unknown-filename", TextComponent.of(filename))); actor.print(Caption.of("worldedit.schematic.unknown-filename", TextComponent.of(filename)));
} catch (URISyntaxException | IOException e) { } catch (EOFException e) {
// EOFException is extending IOException - but the IOException error is too generic.
// EOF mostly occurs when there was unexpected content in the schematic - due to the wrong reader (= version)
actor.print(Caption.of("fawe.worldedit.schematic.schematic.load-failure",
TextComponent.of(e.getMessage() != null ? e.getMessage() : "EOFException"))); // often null...
LOGGER.error("Error loading a schematic", e);
} catch (IOException e) {
actor.print(Caption.of("worldedit.schematic.file-not-exist", TextComponent.of(Objects.toString(e.getMessage())))); actor.print(Caption.of("worldedit.schematic.file-not-exist", TextComponent.of(Objects.toString(e.getMessage()))));
LOGGER.warn("Failed to load a saved clipboard", e); LOGGER.warn("Failed to load a saved clipboard", e);
} catch (Exception e) { } catch (Exception e) {
actor.print(Caption.of("fawe.worldedit.schematic.schematic.load-failure", TextComponent.of(e.getMessage()))); actor.print(Caption.of("fawe.worldedit.schematic.schematic.load-failure", TextComponent.of(e.getMessage())));
LOGGER.error("Error loading a schematic", e); LOGGER.error("Error loading a schematic", e);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ignored) {
}
}
} }
//FAWE end //FAWE end
} }