mirror of
https://github.com/boy0001/FastAsyncWorldedit.git
synced 2024-11-24 19:46:34 +01:00
Clipboard upload/download
This commit is contained in:
parent
50e4231125
commit
7bc7f5841f
@ -4,11 +4,12 @@ import com.boydti.fawe.config.BBC;
|
|||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.FaweLocation;
|
import com.boydti.fawe.object.FaweLocation;
|
||||||
import com.boydti.fawe.object.FawePlayer;
|
import com.boydti.fawe.object.FawePlayer;
|
||||||
|
import com.boydti.fawe.object.FaweQueue;
|
||||||
import com.boydti.fawe.object.PseudoRandom;
|
import com.boydti.fawe.object.PseudoRandom;
|
||||||
import com.boydti.fawe.object.RegionWrapper;
|
import com.boydti.fawe.object.RegionWrapper;
|
||||||
|
import com.boydti.fawe.object.RunnableVal;
|
||||||
import com.boydti.fawe.object.changeset.DiskStorageHistory;
|
import com.boydti.fawe.object.changeset.DiskStorageHistory;
|
||||||
import com.boydti.fawe.regions.FaweMaskManager;
|
import com.boydti.fawe.regions.FaweMaskManager;
|
||||||
import com.boydti.fawe.object.FaweQueue;
|
|
||||||
import com.boydti.fawe.util.MainUtil;
|
import com.boydti.fawe.util.MainUtil;
|
||||||
import com.boydti.fawe.util.MemUtil;
|
import com.boydti.fawe.util.MemUtil;
|
||||||
import com.boydti.fawe.util.SetQueue;
|
import com.boydti.fawe.util.SetQueue;
|
||||||
@ -23,11 +24,15 @@ import com.sk89q.worldedit.EditSession;
|
|||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.channels.Channels;
|
import java.nio.channels.Channels;
|
||||||
import java.nio.channels.ReadableByteChannel;
|
import java.nio.channels.ReadableByteChannel;
|
||||||
@ -41,6 +46,7 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
import java.util.zip.GZIPOutputStream;
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@ -124,6 +130,28 @@ public class FaweAPI {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upload the clipboard to the configured web interface
|
||||||
|
* @param clipboard The clipboard (may not be null)
|
||||||
|
* @param format The format to use (some formats may not be supported)
|
||||||
|
* @return The download URL or null
|
||||||
|
*/
|
||||||
|
public static URL upload(final Clipboard clipboard, final ClipboardFormat format) {
|
||||||
|
return MainUtil.upload(null, "clipboard", format.getExtension(), new RunnableVal<OutputStream>() {
|
||||||
|
@Override
|
||||||
|
public void run(OutputStream value) {
|
||||||
|
try {
|
||||||
|
GZIPOutputStream gzip = new GZIPOutputStream(value, true);
|
||||||
|
ClipboardWriter writer = format.getWriter(gzip);
|
||||||
|
writer.write(clipboard, null);
|
||||||
|
gzip.flush();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of supported protection plugin masks.
|
* Get a list of supported protection plugin masks.
|
||||||
* @return Set of FaweMaskManager
|
* @return Set of FaweMaskManager
|
||||||
|
@ -39,6 +39,10 @@ public enum BBC {
|
|||||||
WORLDEDIT_OOM_ADMIN("&cPossible options:\n&8 - &7//fast\n&8 - &7Do smaller edits\n&8 - &7Allocate more memory\n&8 - &7Disable this safeguard", "Info"),
|
WORLDEDIT_OOM_ADMIN("&cPossible options:\n&8 - &7//fast\n&8 - &7Do smaller edits\n&8 - &7Allocate more memory\n&8 - &7Disable this safeguard", "Info"),
|
||||||
COMPRESSED("History compressed. Saved ~ %s0b (%s1x smaller)", "Info"),
|
COMPRESSED("History compressed. Saved ~ %s0b (%s1x smaller)", "Info"),
|
||||||
ACTION_COMPLETE("Action completed in %s0 seconds", "Info"),
|
ACTION_COMPLETE("Action completed in %s0 seconds", "Info"),
|
||||||
|
GENERATING_LINK("Uploading %s, please wait...", "Web"),
|
||||||
|
GENERATING_LINK_FAILED("&cFailed to generate download link!", "Web"),
|
||||||
|
DOWNLOAD_LINK("%s", "Web"),
|
||||||
|
|
||||||
|
|
||||||
COMMAND_COPY("%s0 blocks were copied", "WorldEdit.Copy"),
|
COMMAND_COPY("%s0 blocks were copied", "WorldEdit.Copy"),
|
||||||
COMMAND_CUT("%s0 blocks were cut", "WorldEdit.Cut"),
|
COMMAND_CUT("%s0 blocks were cut", "WorldEdit.Cut"),
|
||||||
|
@ -37,6 +37,7 @@ public class Settings {
|
|||||||
public static boolean ASYNC_LIGHTING = true;
|
public static boolean ASYNC_LIGHTING = true;
|
||||||
public static int PHYSICS_PER_TICK = 500000;
|
public static int PHYSICS_PER_TICK = 500000;
|
||||||
public static int ITEMS_PER_TICK = 50000;
|
public static int ITEMS_PER_TICK = 50000;
|
||||||
|
public static String WEB_URL = "http://empcraft.com/fawe/";
|
||||||
|
|
||||||
// Maybe confusing?
|
// Maybe confusing?
|
||||||
// - `compression: false` just uses cheaper compression, but still compresses
|
// - `compression: false` just uses cheaper compression, but still compresses
|
||||||
@ -108,6 +109,7 @@ public class Settings {
|
|||||||
options.put("queue.max-wait-ms", QUEUE_MAX_WAIT);
|
options.put("queue.max-wait-ms", QUEUE_MAX_WAIT);
|
||||||
options.put("extent.allowed-plugins", new ArrayList<String>());
|
options.put("extent.allowed-plugins", new ArrayList<String>());
|
||||||
options.put("extent.debug", EXTENT_DEBUG);
|
options.put("extent.debug", EXTENT_DEBUG);
|
||||||
|
options.put("web.url", WEB_URL);
|
||||||
options.put("metrics", METRICS);
|
options.put("metrics", METRICS);
|
||||||
|
|
||||||
// Possibly confusing? - leave configurable since not entirely stable yet
|
// Possibly confusing? - leave configurable since not entirely stable yet
|
||||||
@ -165,6 +167,8 @@ public class Settings {
|
|||||||
QUEUE_DISCARD_AFTER = config.getInt("queue.discard-after-ms", QUEUE_DISCARD_AFTER);
|
QUEUE_DISCARD_AFTER = config.getInt("queue.discard-after-ms", QUEUE_DISCARD_AFTER);
|
||||||
COMBINE_HISTORY_STAGE = config.getBoolean("history.combine-stages", COMBINE_HISTORY_STAGE);
|
COMBINE_HISTORY_STAGE = config.getBoolean("history.combine-stages", COMBINE_HISTORY_STAGE);
|
||||||
|
|
||||||
|
WEB_URL = config.getString("web.url");
|
||||||
|
|
||||||
if (STORE_HISTORY_ON_DISK = config.getBoolean("history.use-disk")) {
|
if (STORE_HISTORY_ON_DISK = config.getBoolean("history.use-disk")) {
|
||||||
LocalSession.MAX_HISTORY_SIZE = Integer.MAX_VALUE;
|
LocalSession.MAX_HISTORY_SIZE = Integer.MAX_VALUE;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package com.boydti.fawe.util;
|
|||||||
|
|
||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.config.BBC;
|
import com.boydti.fawe.config.BBC;
|
||||||
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.FawePlayer;
|
import com.boydti.fawe.object.FawePlayer;
|
||||||
import com.boydti.fawe.object.RegionWrapper;
|
import com.boydti.fawe.object.RegionWrapper;
|
||||||
import com.boydti.fawe.object.RunnableVal;
|
import com.boydti.fawe.object.RunnableVal;
|
||||||
@ -21,14 +22,22 @@ 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.io.OutputStream;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.io.PrintWriter;
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Paths;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipInputStream;
|
import java.util.zip.ZipInputStream;
|
||||||
|
|
||||||
@ -55,6 +64,69 @@ public class MainUtil {
|
|||||||
Fawe.debug(s);
|
Fawe.debug(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static File getFile(File base, String path) {
|
||||||
|
if (Paths.get(path).isAbsolute()) {
|
||||||
|
return new File(path);
|
||||||
|
}
|
||||||
|
return new File(base, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static File getFile(File base, String path, String extension) {
|
||||||
|
return getFile(base, path.endsWith("." + extension) ? path : path + "." + extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static URL upload(UUID uuid, String file, String extension, final RunnableVal<OutputStream> writeTask) {
|
||||||
|
if (writeTask == null) {
|
||||||
|
Fawe.debug("&cWrite task cannot be null");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final String filename;
|
||||||
|
final String website;
|
||||||
|
if (uuid == null) {
|
||||||
|
uuid = UUID.randomUUID();
|
||||||
|
website = Settings.WEB_URL + "upload.php?" + uuid;
|
||||||
|
filename = "plot." + extension;
|
||||||
|
} else {
|
||||||
|
website = Settings.WEB_URL + "save.php?" + uuid;
|
||||||
|
filename = file + '.' + extension;
|
||||||
|
}
|
||||||
|
final URL url;
|
||||||
|
try {
|
||||||
|
url = new URL(Settings.WEB_URL + "?key=" + uuid + "&type=" + extension);
|
||||||
|
String boundary = Long.toHexString(System.currentTimeMillis());
|
||||||
|
URLConnection con = new URL(website).openConnection();
|
||||||
|
con.setDoOutput(true);
|
||||||
|
con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
|
||||||
|
try (OutputStream output = con.getOutputStream();
|
||||||
|
PrintWriter writer = new PrintWriter(new OutputStreamWriter(output, StandardCharsets.UTF_8), true)) {
|
||||||
|
String CRLF = "\r\n";
|
||||||
|
writer.append("--" + boundary).append(CRLF);
|
||||||
|
writer.append("Content-Disposition: form-data; name=\"param\"").append(CRLF);
|
||||||
|
writer.append("Content-Type: text/plain; charset=" + StandardCharsets.UTF_8.displayName()).append(CRLF);
|
||||||
|
String param = "value";
|
||||||
|
writer.append(CRLF).append(param).append(CRLF).flush();
|
||||||
|
writer.append("--" + boundary).append(CRLF);
|
||||||
|
writer.append("Content-Disposition: form-data; name=\"schematicFile\"; filename=\"" + filename + '"').append(CRLF);
|
||||||
|
writer.append("Content-Type: " + URLConnection.guessContentTypeFromName(filename)).append(CRLF);
|
||||||
|
writer.append("Content-Transfer-Encoding: binary").append(CRLF);
|
||||||
|
writer.append(CRLF).flush();
|
||||||
|
writeTask.value = output;
|
||||||
|
writeTask.run();
|
||||||
|
output.flush();
|
||||||
|
writer.append(CRLF).flush();
|
||||||
|
writer.append("--" + boundary + "--").append(CRLF).flush();
|
||||||
|
}
|
||||||
|
int responseCode = ((HttpURLConnection) con).getResponseCode();
|
||||||
|
if (responseCode == 200) {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void setPosition(CompoundTag tag, int x, int y, int z) {
|
public static void setPosition(CompoundTag tag, int x, int y, int z) {
|
||||||
Map<String, Tag> value = ReflectionUtils.getMap(tag.getValue());
|
Map<String, Tag> value = ReflectionUtils.getMap(tag.getValue());
|
||||||
value.put("x", new IntTag(x));
|
value.put("x", new IntTag(x));
|
||||||
|
@ -19,10 +19,12 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.command;
|
package com.sk89q.worldedit.command;
|
||||||
|
|
||||||
|
import com.boydti.fawe.FaweAPI;
|
||||||
import com.boydti.fawe.config.BBC;
|
import com.boydti.fawe.config.BBC;
|
||||||
import com.boydti.fawe.object.RunnableVal2;
|
import com.boydti.fawe.object.RunnableVal2;
|
||||||
import com.boydti.fawe.object.clipboard.LazyClipboard;
|
import com.boydti.fawe.object.clipboard.LazyClipboard;
|
||||||
import com.sk89q.minecraft.util.commands.Command;
|
import com.sk89q.minecraft.util.commands.Command;
|
||||||
|
import com.sk89q.minecraft.util.commands.CommandException;
|
||||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||||
import com.sk89q.minecraft.util.commands.Logging;
|
import com.sk89q.minecraft.util.commands.Logging;
|
||||||
import com.sk89q.worldedit.BlockVector;
|
import com.sk89q.worldedit.BlockVector;
|
||||||
@ -38,6 +40,7 @@ import com.sk89q.worldedit.entity.Player;
|
|||||||
import com.sk89q.worldedit.extension.platform.Actor;
|
import com.sk89q.worldedit.extension.platform.Actor;
|
||||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||||
import com.sk89q.worldedit.function.block.BlockReplace;
|
import com.sk89q.worldedit.function.block.BlockReplace;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
||||||
@ -55,6 +58,7 @@ import com.sk89q.worldedit.session.ClipboardHolder;
|
|||||||
import com.sk89q.worldedit.util.Location;
|
import com.sk89q.worldedit.util.Location;
|
||||||
import com.sk89q.worldedit.util.command.binding.Switch;
|
import com.sk89q.worldedit.util.command.binding.Switch;
|
||||||
import com.sk89q.worldedit.util.command.parametric.Optional;
|
import com.sk89q.worldedit.util.command.parametric.Optional;
|
||||||
|
import java.net.URL;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -204,6 +208,26 @@ public class ClipboardCommands {
|
|||||||
BBC.COMMAND_CUT.send(player, region.getArea());
|
BBC.COMMAND_CUT.send(player, region.getArea());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Command(aliases = { "download" }, desc = "Download your clipboard")
|
||||||
|
@Deprecated
|
||||||
|
@CommandPermissions({ "worldedit.clipboard.download"})
|
||||||
|
public void download(final Player player, final LocalSession session, @Optional("schematic") final String formatName) throws CommandException, WorldEditException {
|
||||||
|
final ClipboardFormat format = ClipboardFormat.findByAlias(formatName);
|
||||||
|
if (format == null) {
|
||||||
|
player.printError("Unknown schematic format: " + formatName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ClipboardHolder holder = session.getClipboard();
|
||||||
|
Clipboard clipboard = holder.getClipboard();
|
||||||
|
BBC.GENERATING_LINK.send(player, formatName);
|
||||||
|
URL url = FaweAPI.upload(clipboard, format);
|
||||||
|
if (url == null) {
|
||||||
|
BBC.GENERATING_LINK_FAILED.send(player);
|
||||||
|
} else {
|
||||||
|
BBC.DOWNLOAD_LINK.send(player, url.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
aliases = { "/paste" },
|
aliases = { "/paste" },
|
||||||
usage = "",
|
usage = "",
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
package com.sk89q.worldedit.command;
|
package com.sk89q.worldedit.command;
|
||||||
|
|
||||||
import com.boydti.fawe.config.BBC;
|
import com.boydti.fawe.config.BBC;
|
||||||
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.schematic.StructureFormat;
|
import com.boydti.fawe.object.schematic.StructureFormat;
|
||||||
import com.sk89q.minecraft.util.commands.Command;
|
import com.sk89q.minecraft.util.commands.Command;
|
||||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||||
@ -42,7 +43,6 @@ import com.sk89q.worldedit.function.operation.Operations;
|
|||||||
import com.sk89q.worldedit.math.transform.Transform;
|
import com.sk89q.worldedit.math.transform.Transform;
|
||||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||||
import com.sk89q.worldedit.util.command.parametric.Optional;
|
import com.sk89q.worldedit.util.command.parametric.Optional;
|
||||||
import com.sk89q.worldedit.util.io.Closer;
|
|
||||||
import com.sk89q.worldedit.util.io.file.FilenameException;
|
import com.sk89q.worldedit.util.io.file.FilenameException;
|
||||||
import com.sk89q.worldedit.util.io.file.FilenameResolutionException;
|
import com.sk89q.worldedit.util.io.file.FilenameResolutionException;
|
||||||
import com.sk89q.worldedit.world.registry.WorldData;
|
import com.sk89q.worldedit.world.registry.WorldData;
|
||||||
@ -53,8 +53,13 @@ import java.io.FileFilter;
|
|||||||
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.net.URL;
|
||||||
|
import java.nio.channels.Channels;
|
||||||
|
import java.nio.channels.ReadableByteChannel;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@ -84,31 +89,36 @@ public class SchematicCommands {
|
|||||||
@CommandPermissions({ "worldedit.clipboard.load", "worldedit.schematic.load" })
|
@CommandPermissions({ "worldedit.clipboard.load", "worldedit.schematic.load" })
|
||||||
public void load(final Player player, final LocalSession session, @Optional("schematic") final String formatName, final String filename) throws FilenameException {
|
public void load(final Player player, final LocalSession session, @Optional("schematic") final String formatName, final String filename) throws FilenameException {
|
||||||
final LocalConfiguration config = this.worldEdit.getConfiguration();
|
final LocalConfiguration config = this.worldEdit.getConfiguration();
|
||||||
|
|
||||||
final File dir = this.worldEdit.getWorkingDirectoryFile(config.saveDir);
|
|
||||||
final File f = this.worldEdit.getSafeOpenFile(player, dir, filename, "schematic", "schematic");
|
|
||||||
|
|
||||||
if (!f.exists()) {
|
|
||||||
player.printError("Schematic " + filename + " does not exist!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final ClipboardFormat format = ClipboardFormat.findByAlias(formatName);
|
final ClipboardFormat format = ClipboardFormat.findByAlias(formatName);
|
||||||
if (format == null) {
|
if (format == null) {
|
||||||
player.printError("Unknown schematic format: " + formatName);
|
player.printError("Unknown schematic format: " + formatName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final Closer closer = Closer.create();
|
InputStream in = null;
|
||||||
try {
|
try {
|
||||||
|
if (filename.startsWith("url:")) {
|
||||||
|
UUID uuid = UUID.fromString(filename.substring(4));
|
||||||
|
URL base = new URL(Settings.WEB_URL);
|
||||||
|
URL url = new URL(base, "uploads/" + uuid + ".schematic");
|
||||||
|
ReadableByteChannel rbc = Channels.newChannel(url.openStream());
|
||||||
|
in = Channels.newInputStream(rbc);
|
||||||
|
} else {
|
||||||
|
final File dir = this.worldEdit.getWorkingDirectoryFile(config.saveDir);
|
||||||
|
final File f = this.worldEdit.getSafeOpenFile(player, dir, filename, format.getExtension(), format.getExtension());
|
||||||
|
if (!f.exists()) {
|
||||||
|
player.printError("Schematic " + filename + " does not exist!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
final String filePath = f.getCanonicalPath();
|
final String filePath = f.getCanonicalPath();
|
||||||
final String dirPath = dir.getCanonicalPath();
|
final String dirPath = dir.getCanonicalPath();
|
||||||
|
|
||||||
if (!filePath.substring(0, dirPath.length()).equals(dirPath)) {
|
if (!filePath.substring(0, dirPath.length()).equals(dirPath)) {
|
||||||
player.printError("Clipboard file could not read or it does not exist.");
|
player.printError("Clipboard file could not read or it does not exist.");
|
||||||
} else {
|
}
|
||||||
final FileInputStream fis = closer.register(new FileInputStream(f));
|
in = new FileInputStream(f);
|
||||||
final BufferedInputStream bis = closer.register(new BufferedInputStream(fis));
|
}
|
||||||
final ClipboardReader reader = format.getReader(bis);
|
in = new BufferedInputStream(in);
|
||||||
|
|
||||||
|
final ClipboardReader reader = format.getReader(in);
|
||||||
|
|
||||||
final WorldData worldData = player.getWorld().getWorldData();
|
final WorldData worldData = player.getWorld().getWorldData();
|
||||||
final Clipboard clipboard;
|
final Clipboard clipboard;
|
||||||
@ -120,16 +130,18 @@ public class SchematicCommands {
|
|||||||
clipboard = reader.read(player.getWorld().getWorldData());
|
clipboard = reader.read(player.getWorld().getWorldData());
|
||||||
}
|
}
|
||||||
session.setClipboard(new ClipboardHolder(clipboard, worldData));
|
session.setClipboard(new ClipboardHolder(clipboard, worldData));
|
||||||
log.info(player.getName() + " loaded " + filePath);
|
|
||||||
BBC.SCHEMATIC_LOADED.send(player, filename);
|
BBC.SCHEMATIC_LOADED.send(player, filename);
|
||||||
}
|
} catch (IllegalArgumentException e) {
|
||||||
} catch (final IOException e) {
|
player.printError("Unknown filename: " + filename);
|
||||||
player.printError("Schematic could not read or it does not exist: " + e.getMessage());
|
} catch (IOException e) {
|
||||||
|
player.printError("File could not be read or it does not exist: " + e.getMessage());
|
||||||
log.log(Level.WARNING, "Failed to load a saved clipboard", e);
|
log.log(Level.WARNING, "Failed to load a saved clipboard", e);
|
||||||
} finally {
|
} finally {
|
||||||
|
if (in != null) {
|
||||||
try {
|
try {
|
||||||
closer.close();
|
in.close();
|
||||||
} catch (final IOException ignored) {}
|
} catch (IOException ignored) {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,17 +150,26 @@ public class SchematicCommands {
|
|||||||
@CommandPermissions({ "worldedit.clipboard.save", "worldedit.schematic.save" })
|
@CommandPermissions({ "worldedit.clipboard.save", "worldedit.schematic.save" })
|
||||||
public void save(final Player player, final LocalSession session, @Optional("schematic") final String formatName, final String filename) throws CommandException, WorldEditException {
|
public void save(final Player player, final LocalSession session, @Optional("schematic") final String formatName, final String filename) throws CommandException, WorldEditException {
|
||||||
final LocalConfiguration config = this.worldEdit.getConfiguration();
|
final LocalConfiguration config = this.worldEdit.getConfiguration();
|
||||||
|
|
||||||
final File dir = this.worldEdit.getWorkingDirectoryFile(config.saveDir);
|
|
||||||
|
|
||||||
final ClipboardFormat format = ClipboardFormat.findByAlias(formatName);
|
final ClipboardFormat format = ClipboardFormat.findByAlias(formatName);
|
||||||
if (format == null) {
|
if (format == null) {
|
||||||
player.printError("Unknown schematic format: " + formatName);
|
player.printError("Unknown schematic format: " + formatName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final File f = this.worldEdit.getSafeSaveFile(player, dir, filename, "schematic", "schematic");
|
final File dir = this.worldEdit.getWorkingDirectoryFile(config.saveDir);
|
||||||
|
final File f = this.worldEdit.getSafeSaveFile(player, dir, filename, format.getExtension(), format.getExtension());
|
||||||
|
final File parent = f.getParentFile();
|
||||||
|
if ((parent != null) && !parent.exists()) {
|
||||||
|
if (!parent.mkdirs()) {
|
||||||
|
log.info("Could not create folder for schematics!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (!f.exists()) {
|
||||||
|
f.createNewFile();
|
||||||
|
}
|
||||||
|
try (FileOutputStream fos = new FileOutputStream(f)) {
|
||||||
final ClipboardHolder holder = session.getClipboard();
|
final ClipboardHolder holder = session.getClipboard();
|
||||||
final Clipboard clipboard = holder.getClipboard();
|
final Clipboard clipboard = holder.getClipboard();
|
||||||
final Transform transform = holder.getTransform();
|
final Transform transform = holder.getTransform();
|
||||||
@ -164,20 +185,8 @@ public class SchematicCommands {
|
|||||||
target = clipboard;
|
target = clipboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Closer closer = Closer.create();
|
try (BufferedOutputStream bos = new BufferedOutputStream(fos)) {
|
||||||
try {
|
try (ClipboardWriter writer = format.getWriter(bos)) {
|
||||||
// Create parent directories
|
|
||||||
final File parent = f.getParentFile();
|
|
||||||
if ((parent != null) && !parent.exists()) {
|
|
||||||
if (!parent.mkdirs()) {
|
|
||||||
log.info("Could not create folder for schematics!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final FileOutputStream fos = closer.register(new FileOutputStream(f));
|
|
||||||
final BufferedOutputStream bos = closer.register(new BufferedOutputStream(fos));
|
|
||||||
final ClipboardWriter writer = closer.register(format.getWriter(bos));
|
|
||||||
if (writer instanceof StructureFormat) {
|
if (writer instanceof StructureFormat) {
|
||||||
((StructureFormat) writer).write(target, holder.getWorldData(), player.getName());
|
((StructureFormat) writer).write(target, holder.getWorldData(), player.getName());
|
||||||
} else {
|
} else {
|
||||||
@ -185,13 +194,14 @@ public class SchematicCommands {
|
|||||||
}
|
}
|
||||||
log.info(player.getName() + " saved " + f.getCanonicalPath());
|
log.info(player.getName() + " saved " + f.getCanonicalPath());
|
||||||
BBC.SCHEMATIC_SAVED.send(player, filename);
|
BBC.SCHEMATIC_SAVED.send(player, filename);
|
||||||
} catch (final IOException e) {
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
player.printError("Unknown filename: " + filename);
|
||||||
|
} catch (IOException e) {
|
||||||
player.printError("Schematic could not written: " + e.getMessage());
|
player.printError("Schematic could not written: " + e.getMessage());
|
||||||
log.log(Level.WARNING, "Failed to write a saved clipboard", e);
|
log.log(Level.WARNING, "Failed to write a saved clipboard", e);
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
closer.close();
|
|
||||||
} catch (final IOException ignored) {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,13 @@ public enum ClipboardFormat {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
|
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
|
||||||
NBTOutputStream nbtStream = new NBTOutputStream(new GZIPOutputStream(outputStream));
|
GZIPOutputStream gzip;
|
||||||
|
if (outputStream instanceof GZIPOutputStream) {
|
||||||
|
gzip = (GZIPOutputStream) outputStream;
|
||||||
|
} else {
|
||||||
|
gzip = new GZIPOutputStream(outputStream, true);
|
||||||
|
}
|
||||||
|
NBTOutputStream nbtStream = new NBTOutputStream(gzip);
|
||||||
return new SchematicWriter(nbtStream);
|
return new SchematicWriter(nbtStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +109,13 @@ public enum ClipboardFormat {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
|
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
|
||||||
NBTOutputStream nbtStream = new NBTOutputStream(new GZIPOutputStream(outputStream));
|
GZIPOutputStream gzip;
|
||||||
|
if (outputStream instanceof GZIPOutputStream) {
|
||||||
|
gzip = (GZIPOutputStream) outputStream;
|
||||||
|
} else {
|
||||||
|
gzip = new GZIPOutputStream(outputStream, true);
|
||||||
|
}
|
||||||
|
NBTOutputStream nbtStream = new NBTOutputStream(gzip);
|
||||||
return new StructureFormat(nbtStream);
|
return new StructureFormat(nbtStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user