Pull boy0001/WorldEdit#9
This commit is contained in:
parent
ac3005be36
commit
3c9b0fa3ea
@ -11,6 +11,7 @@ import com.github.luben.zstd.ZstdInputStream;
|
|||||||
import com.github.luben.zstd.ZstdOutputStream;
|
import com.github.luben.zstd.ZstdOutputStream;
|
||||||
import com.sk89q.jnbt.*;
|
import com.sk89q.jnbt.*;
|
||||||
import com.sk89q.worldedit.entity.Entity;
|
import com.sk89q.worldedit.entity.Entity;
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||||
import com.sk89q.worldedit.history.changeset.ChangeSet;
|
import com.sk89q.worldedit.history.changeset.ChangeSet;
|
||||||
import com.sk89q.worldedit.util.Location;
|
import com.sk89q.worldedit.util.Location;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
@ -34,6 +35,7 @@ import java.util.concurrent.atomic.AtomicLong;
|
|||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.zip.*;
|
import java.util.zip.*;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import net.jpountz.lz4.*;
|
import net.jpountz.lz4.*;
|
||||||
|
|
||||||
@ -880,9 +882,29 @@ public class MainUtil {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isInSubDirectory(File dir, File file) {
|
public static File resolve(File dir, String filename, @Nullable ClipboardFormat format, boolean allowDir) {
|
||||||
|
if (format != null) {
|
||||||
|
if (!filename.matches(".*\\.[\\w].*")) {
|
||||||
|
filename = filename + "." + format.getExtension();
|
||||||
|
}
|
||||||
|
return MainUtil.resolveRelative(new File(dir, filename));
|
||||||
|
}
|
||||||
|
if (allowDir) {
|
||||||
|
File file = MainUtil.resolveRelative(new File(dir, filename));
|
||||||
|
if (file.exists() && file.isDirectory()) return file;
|
||||||
|
}
|
||||||
|
for (ClipboardFormat f : ClipboardFormat.values()) {
|
||||||
|
File file = MainUtil.resolveRelative(new File(dir, filename + "." + f.getExtension()));
|
||||||
|
if (file.exists()) return file;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isInSubDirectory(File dir, File file) throws IOException {
|
||||||
if (file == null) return false;
|
if (file == null) return false;
|
||||||
if (file.equals(dir)) return true;
|
if (file.equals(dir)) return true;
|
||||||
|
file = file.getCanonicalFile();
|
||||||
|
dir = dir.getCanonicalFile();
|
||||||
return isInSubDirectory(dir, file.getParentFile());
|
return isInSubDirectory(dir, file.getParentFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,20 +191,6 @@ public class SchematicCommands extends MethodCommands {
|
|||||||
player.print(BBC.getPrefix() + "Remapped schematic");
|
player.print(BBC.getPrefix() + "Remapped schematic");
|
||||||
}
|
}
|
||||||
|
|
||||||
private File resolve(File dir, String filename, @Nullable ClipboardFormat format) {
|
|
||||||
if (format != null) {
|
|
||||||
if (!filename.matches(".*\\.[\\w].*")) {
|
|
||||||
filename = filename + "." + format.getExtension();
|
|
||||||
}
|
|
||||||
return MainUtil.resolveRelative(new File(dir, filename));
|
|
||||||
}
|
|
||||||
for (ClipboardFormat f : ClipboardFormat.values()) {
|
|
||||||
File file = MainUtil.resolveRelative(new File(dir, filename + "." + f.getExtension()));
|
|
||||||
if (file.exists()) return file;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Command(aliases = {"load"}, usage = "[<format>] <filename>", desc = "Load a schematic into your clipboard")
|
@Command(aliases = {"load"}, usage = "[<format>] <filename>", desc = "Load a schematic into your clipboard")
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@CommandPermissions({"worldedit.clipboard.load", "worldedit.schematic.load", "worldedit.schematic.upload", "worldedit.schematic.load.other"})
|
@CommandPermissions({"worldedit.clipboard.load", "worldedit.schematic.load", "worldedit.schematic.upload", "worldedit.schematic.load.other"})
|
||||||
@ -255,12 +241,12 @@ public class SchematicCommands extends MethodCommands {
|
|||||||
String extension = filename.substring(filename.lastIndexOf('.') + 1, filename.length());
|
String extension = filename.substring(filename.lastIndexOf('.') + 1, filename.length());
|
||||||
format = ClipboardFormat.findByExtension(extension);
|
format = ClipboardFormat.findByExtension(extension);
|
||||||
}
|
}
|
||||||
f = resolve(dir, filename, format);
|
f = MainUtil.resolve(dir, filename, format, false);
|
||||||
}
|
}
|
||||||
if (f == null || !f.exists()) {
|
if (f == null || !f.exists()) {
|
||||||
if (!filename.contains("../")) {
|
if (!filename.contains("../")) {
|
||||||
dir = this.worldEdit.getWorkingDirectoryFile(config.saveDir);
|
dir = this.worldEdit.getWorkingDirectoryFile(config.saveDir);
|
||||||
f = resolve(dir, filename, format);
|
f = MainUtil.resolve(dir, filename, format, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (f == null || !f.exists() || !MainUtil.isInSubDirectory(working, f)) {
|
if (f == null || !f.exists() || !MainUtil.isInSubDirectory(working, f)) {
|
||||||
@ -385,7 +371,7 @@ public class SchematicCommands extends MethodCommands {
|
|||||||
|
|
||||||
@Command(aliases = {"move", "m"}, usage = "<directory>", desc = "Move your loaded schematic", help = "Move your currently loaded schematics", min = 1, max = 1)
|
@Command(aliases = {"move", "m"}, usage = "<directory>", desc = "Move your loaded schematic", help = "Move your currently loaded schematics", min = 1, max = 1)
|
||||||
@CommandPermissions({"worldedit.schematic.move", "worldedit.schematic.move.other"})
|
@CommandPermissions({"worldedit.schematic.move", "worldedit.schematic.move.other"})
|
||||||
public void move(final Player player, final LocalSession session, final CommandContext args) throws WorldEditException {
|
public void move(final Player player, final LocalSession session, final CommandContext args) throws WorldEditException, IOException {
|
||||||
final LocalConfiguration config = this.worldEdit.getConfiguration();
|
final LocalConfiguration config = this.worldEdit.getConfiguration();
|
||||||
final File working = this.worldEdit.getWorkingDirectoryFile(config.saveDir);
|
final File working = this.worldEdit.getWorkingDirectoryFile(config.saveDir);
|
||||||
final File dir = Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS ? new File(working, player.getUniqueId().toString()) : working;
|
final File dir = Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS ? new File(working, player.getUniqueId().toString()) : working;
|
||||||
@ -431,7 +417,7 @@ public class SchematicCommands extends MethodCommands {
|
|||||||
|
|
||||||
@Command(aliases = {"delete", "d"}, usage = "<filename|*>", desc = "Delete a saved schematic", help = "Delete a schematic from the schematic list", min = 1, max = 1)
|
@Command(aliases = {"delete", "d"}, usage = "<filename|*>", desc = "Delete a saved schematic", help = "Delete a schematic from the schematic list", min = 1, max = 1)
|
||||||
@CommandPermissions({"worldedit.schematic.delete", "worldedit.schematic.delete.other"})
|
@CommandPermissions({"worldedit.schematic.delete", "worldedit.schematic.delete.other"})
|
||||||
public void delete(final Player player, final LocalSession session, final CommandContext args) throws WorldEditException {
|
public void delete(final Player player, final LocalSession session, final CommandContext args) throws WorldEditException, IOException {
|
||||||
final LocalConfiguration config = this.worldEdit.getConfiguration();
|
final LocalConfiguration config = this.worldEdit.getConfiguration();
|
||||||
final File working = this.worldEdit.getWorkingDirectoryFile(config.saveDir);
|
final File working = this.worldEdit.getWorkingDirectoryFile(config.saveDir);
|
||||||
final File dir = Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS ? new File(working, player.getUniqueId().toString()) : working;
|
final File dir = Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS ? new File(working, player.getUniqueId().toString()) : working;
|
||||||
|
@ -49,6 +49,7 @@ import com.sk89q.worldedit.event.extent.PlayerSaveClipboardEvent;
|
|||||||
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.ClipboardFormats;
|
||||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||||
import com.sk89q.worldedit.world.registry.WorldData;
|
import com.sk89q.worldedit.world.registry.WorldData;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
@ -59,6 +60,7 @@ import java.nio.channels.Channels;
|
|||||||
import java.nio.channels.ReadableByteChannel;
|
import java.nio.channels.ReadableByteChannel;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
import java.util.zip.GZIPOutputStream;
|
import java.util.zip.GZIPOutputStream;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
@ -303,16 +305,25 @@ public enum ClipboardFormat {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public MultiClipboardHolder loadAllFromInput(Actor player, WorldData worldData, String input, boolean message) throws IOException {
|
public static MultiClipboardHolder loadAllFromInput(Actor player, WorldData worldData, String input, boolean message) throws IOException {
|
||||||
checkNotNull(player);
|
checkNotNull(player);
|
||||||
checkNotNull(input);
|
checkNotNull(input);
|
||||||
|
ClipboardFormat format = null;
|
||||||
WorldEdit worldEdit = WorldEdit.getInstance();
|
WorldEdit worldEdit = WorldEdit.getInstance();
|
||||||
LocalConfiguration config = worldEdit.getConfiguration();
|
LocalConfiguration config = worldEdit.getConfiguration();
|
||||||
if (input.startsWith("url:")) {
|
if (input.startsWith("url:")) {
|
||||||
|
if (!player.hasPermission("worldedit.schematic.load.web")) {
|
||||||
|
if (message) BBC.NO_PERM.send(player, "worldedit.schematic.load.web");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
URL base = new URL(Settings.IMP.WEB.URL);
|
URL base = new URL(Settings.IMP.WEB.URL);
|
||||||
input = new URL(base, "uploads/" + input.substring(4) + ".schematic").toString();
|
input = new URL(base, "uploads/" + input.substring(4) + ".schematic").toString();
|
||||||
}
|
}
|
||||||
if (input.startsWith("http")) {
|
if (input.startsWith("http")) {
|
||||||
|
if (!player.hasPermission("worldedit.schematic.load.asset")) {
|
||||||
|
if (message) BBC.NO_PERM.send(player, "worldedit.schematic.load.asset");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
URL url = new URL(input);
|
URL url = new URL(input);
|
||||||
URL webInterface = new URL(Settings.IMP.WEB.ASSETS);
|
URL webInterface = new URL(Settings.IMP.WEB.ASSETS);
|
||||||
if (!url.getHost().equalsIgnoreCase(webInterface.getHost())) {
|
if (!url.getHost().equalsIgnoreCase(webInterface.getHost())) {
|
||||||
@ -322,64 +333,89 @@ public enum ClipboardFormat {
|
|||||||
MultiClipboardHolder clipboards = loadAllFromUrl(url, worldData);
|
MultiClipboardHolder clipboards = loadAllFromUrl(url, worldData);
|
||||||
return clipboards;
|
return clipboards;
|
||||||
} else {
|
} else {
|
||||||
if (input.contains("../") && !player.hasPermission("worldedit.schematic.load.other")) {
|
if (Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS && Pattern.compile("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}").matcher(input).find() && !player.hasPermission("worldedit.schematic.load.other")) {
|
||||||
if (message) BBC.NO_PERM.send(player, "worldedit.schematic.load.other");
|
BBC.NO_PERM.send(player, "worldedit.schematic.load.other");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
File working = worldEdit.getWorkingDirectoryFile(config.saveDir);
|
File working = worldEdit.getWorkingDirectoryFile(config.saveDir);
|
||||||
File dir = new File(working, (Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS ? (player.getUniqueId().toString() + File.separator) : "") + input);
|
File dir = Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS ? new File(working, player.getUniqueId().toString()) : working;
|
||||||
if (!dir.exists()) {
|
File f;
|
||||||
dir = new File(dir + "." + getExtension());
|
if (input.startsWith("#")) {
|
||||||
}
|
String[] extensions;
|
||||||
if (!dir.exists()) {
|
if (format != null) {
|
||||||
if ((!input.contains("/") && !input.contains("\\")) || player.hasPermission("worldedit.schematic.load.other")) {
|
extensions = new String[] { format.getExtension() };
|
||||||
dir = new File(worldEdit.getWorkingDirectoryFile(config.saveDir), input);
|
} else {
|
||||||
|
extensions = ClipboardFormats.getFileExtensionArray();
|
||||||
}
|
}
|
||||||
if (!dir.exists()) {
|
f = player.openFileOpenDialog(extensions);
|
||||||
dir = new File(dir + "." + getExtension());
|
if (f == null || !f.exists()) {
|
||||||
|
if (message) player.printError("Schematic " + input + " does not exist! (" + f + ")");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS && Pattern.compile("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}").matcher(input).find() && !player.hasPermission("worldedit.schematic.load.other")) {
|
||||||
|
if (message) BBC.NO_PERM.send(player, "worldedit.schematic.load.other");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (format == null && input.matches(".*\\.[\\w].*")) {
|
||||||
|
String extension = input.substring(input.lastIndexOf('.') + 1, input.length());
|
||||||
|
format = ClipboardFormat.findByExtension(extension);
|
||||||
|
}
|
||||||
|
f = MainUtil.resolve(dir, input, format, true);
|
||||||
|
}
|
||||||
|
if (f == null || !f.exists()) {
|
||||||
|
if (!input.contains("../")) {
|
||||||
|
dir = worldEdit.getWorkingDirectoryFile(config.saveDir);
|
||||||
|
f = MainUtil.resolve(dir, input, format, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!dir.exists()) {
|
if (f == null || !f.exists() || !MainUtil.isInSubDirectory(working, f)) {
|
||||||
|
if (message) player.printError("Schematic " + input + " does not exist! (" + ((f == null) ? false : f.exists()) + "|" + f + "|" + (f == null ? false : !MainUtil.isInSubDirectory(working, f)) + ")");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (format == null && f.isFile()) {
|
||||||
|
format = ClipboardFormat.findByFile(f);
|
||||||
|
if (format == null) {
|
||||||
|
BBC.CLIPBOARD_INVALID_FORMAT.send(player, f.getName());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!f.exists()) {
|
||||||
if (message) BBC.SCHEMATIC_NOT_FOUND.send(player, input);
|
if (message) BBC.SCHEMATIC_NOT_FOUND.send(player, input);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (!dir.isDirectory()) {
|
if (!f.isDirectory()) {
|
||||||
ByteSource source = Files.asByteSource(dir);
|
ByteSource source = Files.asByteSource(f);
|
||||||
URI uri = dir.toURI();
|
URI uri = f.toURI();
|
||||||
return new MultiClipboardHolder(uri, worldData, new LazyClipboardHolder(dir.toURI(), source, this, worldData, null));
|
return new MultiClipboardHolder(uri, worldData, new LazyClipboardHolder(f.toURI(), source, format, worldData, null));
|
||||||
}
|
}
|
||||||
URIClipboardHolder[] clipboards = loadAllFromDirectory(dir, worldData);
|
URIClipboardHolder[] clipboards = loadAllFromDirectory(f, worldData);
|
||||||
if (clipboards.length < 1) {
|
if (clipboards.length < 1) {
|
||||||
if (message) BBC.SCHEMATIC_NOT_FOUND.send(player, input);
|
if (message) BBC.SCHEMATIC_NOT_FOUND.send(player, input);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new MultiClipboardHolder(dir.toURI(), worldData, clipboards);
|
return new MultiClipboardHolder(f.toURI(), worldData, clipboards);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public URIClipboardHolder[] loadAllFromDirectory(File dir, WorldData worldData) {
|
public static URIClipboardHolder[] loadAllFromDirectory(File dir, WorldData worldData) {
|
||||||
if (worldData == null) {
|
HashSet<String> extensions = new HashSet<>(Arrays.asList(ClipboardFormats.getFileExtensionArray()));
|
||||||
try {
|
File[] files = dir.listFiles(pathname -> {
|
||||||
worldData = WorldEdit.getInstance().getServer().getWorlds().get(0).getWorldData();
|
String input = pathname.getName();
|
||||||
} catch (Throwable ignore) {
|
String extension = input.substring(input.lastIndexOf('.') + 1, input.length());
|
||||||
}
|
return (extensions.contains(extension.toLowerCase()));
|
||||||
}
|
|
||||||
File[] files = dir.listFiles(new FileFilter() {
|
|
||||||
@Override
|
|
||||||
public boolean accept(File pathname) {
|
|
||||||
return pathname.getName().endsWith(".schematic");
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
LazyClipboardHolder[] clipboards = new LazyClipboardHolder[files.length];
|
LazyClipboardHolder[] clipboards = new LazyClipboardHolder[files.length];
|
||||||
for (int i = 0; i < files.length; i++) {
|
for (int i = 0; i < files.length; i++) {
|
||||||
File file = files[i];
|
File file = files[i];
|
||||||
ByteSource source = Files.asByteSource(file);
|
ByteSource source = Files.asByteSource(file);
|
||||||
clipboards[i] = new LazyClipboardHolder(file.toURI(), source, this, worldData, null);
|
ClipboardFormat format = ClipboardFormat.findByFile(file);
|
||||||
|
clipboards[i] = new LazyClipboardHolder(file.toURI(), source, format, worldData, null);
|
||||||
}
|
}
|
||||||
return clipboards;
|
return clipboards;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MultiClipboardHolder loadAllFromUrl(URL url, WorldData worldData) throws IOException {
|
public static MultiClipboardHolder loadAllFromUrl(URL url, WorldData worldData) throws IOException {
|
||||||
List<LazyClipboardHolder> clipboards = new ArrayList<>();
|
List<LazyClipboardHolder> clipboards = new ArrayList<>();
|
||||||
try (ReadableByteChannel rbc = Channels.newChannel(url.openStream())) {
|
try (ReadableByteChannel rbc = Channels.newChannel(url.openStream())) {
|
||||||
try (InputStream in = Channels.newInputStream(rbc)) {
|
try (InputStream in = Channels.newInputStream(rbc)) {
|
||||||
@ -387,7 +423,10 @@ public enum ClipboardFormat {
|
|||||||
ZipEntry entry;
|
ZipEntry entry;
|
||||||
byte[] buffer = new byte[8192];
|
byte[] buffer = new byte[8192];
|
||||||
while ((entry = zip.getNextEntry()) != null) {
|
while ((entry = zip.getNextEntry()) != null) {
|
||||||
if (entry.getName().endsWith(".schematic")) {
|
String filename = entry.getName();
|
||||||
|
String extension = filename.substring(filename.lastIndexOf('.') + 1, filename.length());
|
||||||
|
ClipboardFormat format = findByExtension(filename);
|
||||||
|
if (format != null) {
|
||||||
FastByteArrayOutputStream out = new FastByteArrayOutputStream();
|
FastByteArrayOutputStream out = new FastByteArrayOutputStream();
|
||||||
int len = 0;
|
int len = 0;
|
||||||
while ((len = zip.read(buffer)) > 0) {
|
while ((len = zip.read(buffer)) > 0) {
|
||||||
@ -395,7 +434,7 @@ public enum ClipboardFormat {
|
|||||||
}
|
}
|
||||||
byte[] array = out.toByteArray();
|
byte[] array = out.toByteArray();
|
||||||
ByteSource source = ByteSource.wrap(array);
|
ByteSource source = ByteSource.wrap(array);
|
||||||
LazyClipboardHolder clipboard = new LazyClipboardHolder(url.toURI(), source, this, worldData, null);
|
LazyClipboardHolder clipboard = new LazyClipboardHolder(url.toURI(), source, format, worldData, null);
|
||||||
clipboards.add(clipboard);
|
clipboards.add(clipboard);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user