diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/schematic/StructureFormat.java b/worldedit-core/src/main/java/com/boydti/fawe/object/schematic/StructureFormat.java index cf5707677..5720015f9 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/schematic/StructureFormat.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/schematic/StructureFormat.java @@ -91,17 +91,19 @@ public class StructureFormat implements ClipboardReader, ClipboardWriter { Map map = compound.getValue(); String name = ((StringTag) map.get("Name")).getValue(); BlockType type = BlockTypes.get(name); - BlockState state = BlockState.get(type.getInternalId()); + BlockState state = type.getDefaultState(); if (type == null) { Fawe.debug("Unknown block: " + name); continue; } CompoundTag properties = (CompoundTag) map.get("Properties"); - for (Map.Entry entry : properties.getValue().entrySet()) { - String key = entry.getKey(); - String value = ((StringTag) entry.getValue()).getValue(); - Property property = type.getProperty(key); - state = state.with(property, property.getValueFor(value)); + if (properties != null) { + for (Map.Entry entry : properties.getValue().entrySet()) { + String key = entry.getKey(); + String value = ((StringTag) entry.getValue()).getValue(); + Property property = type.getProperty(key); + state = state.with(property, property.getValueFor(value)); + } } combinedArray[i] = state; } @@ -140,7 +142,7 @@ public class StructureFormat implements ClipboardReader, ClipboardWriter { Map entityEntryMap = entityEntry.getValue(); ListTag posTag = (ListTag) entityEntryMap.get("pos"); CompoundTag nbtTag = (CompoundTag) entityEntryMap.get("nbt"); - String id = ((StringTag) entityEntryMap.get("Id")).getValue(); + String id = nbtTag.getString("Id"); Location location = NBTConversions.toLocation(clipboard, posTag, nbtTag.getListTag("Rotation")); if (!id.isEmpty()) { BaseEntity state = new BaseEntity(EntityTypes.get(id), nbtTag); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java index 6529b6363..796652140 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java @@ -46,6 +46,7 @@ import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat; +import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats; import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter; import com.sk89q.worldedit.function.operation.Operations; import com.sk89q.worldedit.math.transform.Transform; @@ -53,6 +54,8 @@ import com.sk89q.worldedit.session.ClipboardHolder; import com.sk89q.worldedit.util.command.binding.Switch; import com.sk89q.worldedit.util.command.parametric.Optional; import com.sk89q.worldedit.util.io.file.FilenameException; + +import javax.annotation.Nullable; import java.io.*; import java.net.URI; import java.net.URISyntaxException; @@ -184,16 +187,27 @@ public class SchematicCommands extends MethodCommands { 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 = "[] ", desc = "Load a schematic into your clipboard") @Deprecated @CommandPermissions({"worldedit.clipboard.load", "worldedit.schematic.load", "worldedit.schematic.upload", "worldedit.schematic.load.other"}) - public void load(final Player player, final LocalSession session, @Optional("schematic") final String formatName, String filename) throws FilenameException { + public void load(final Player player, final LocalSession session, @Optional() final String formatName, String filename) throws FilenameException { final LocalConfiguration config = this.worldEdit.getConfiguration(); - final ClipboardFormat format = ClipboardFormat.findByAlias(formatName); - if (format == null) { - BBC.CLIPBOARD_INVALID_FORMAT.send(player, formatName); - return; - } + ClipboardFormat format = formatName == null ? null : ClipboardFormat.findByAlias(formatName); InputStream in = null; try { URI uri; @@ -217,8 +231,14 @@ public class SchematicCommands extends MethodCommands { File dir = Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS ? new File(working, player.getUniqueId().toString()) : working; File f; if (filename.startsWith("#")) { - f = player.openFileOpenDialog(new String[] { format.getExtension() }); - if (!f.exists()) { + String[] extensions; + if (format != null) { + extensions = format.getFileExtensions().toArray(new String[0]); + } else { + extensions = ClipboardFormats.getFileExtensionArray(); + } + f = player.openFileOpenDialog(extensions); + if (f == null || !f.exists()) { player.printError("Schematic " + filename + " does not exist! (" + f + ")"); return; } @@ -227,32 +247,30 @@ public class SchematicCommands extends MethodCommands { BBC.NO_PERM.send(player, "worldedit.schematic.load.other"); return; } - if (!filename.matches(".*\\.[\\w].*")) { - filename += "." + format.getExtension(); + if (format == null && filename.matches(".*\\.[\\w].*")) { + String extension = filename.substring(filename.lastIndexOf('.') + 1, filename.length()); + format = ClipboardFormat.findByExtension(extension); } - f = MainUtil.resolveRelative(new File(dir, filename)); + f = resolve(dir, filename, format); } - if (f.getName().replaceAll("." + format.getExtension(), "").isEmpty()) { - File directory = f.getParentFile(); - if (directory.exists()) { - int max = MainUtil.getMaxFileId(directory) - 1; - f = new File(directory, max + "." + format.getExtension()); - } else { - f = new File(directory, "1." + format.getExtension()); - } - } - if (!f.exists()) { + if (f == null || !f.exists()) { if (!filename.contains("../")) { dir = this.worldEdit.getWorkingDirectoryFile(config.saveDir); - f = this.worldEdit.getSafeSaveFile(player, dir, filename, format.getExtension(), format.getExtension()); + f = resolve(dir, filename, format); } } - if (!f.exists() || !MainUtil.isInSubDirectory(working, f)) { - player.printError("Schematic " + filename + " does not exist! (" + f.exists() + "|" + f + "|" + (!MainUtil.isInSubDirectory(working, f)) + ")"); + if (f == null || !f.exists() || !MainUtil.isInSubDirectory(working, f)) { + player.printError("Schematic " + filename + " does not exist! (" + ((f == null) ? false : f.exists()) + "|" + f + "|" + (f == null ? false : !MainUtil.isInSubDirectory(working, f)) + ")"); return; } + if (format == null) { + format = ClipboardFormat.findByFile(f); + if (format == null) { + BBC.CLIPBOARD_INVALID_FORMAT.send(player, f.getName()); + return; + } + } in = new FileInputStream(f); - uri = f.toURI(); } format.hold(player, uri, in); @@ -473,7 +491,7 @@ public class SchematicCommands extends MethodCommands { Message m = new Message(BBC.SCHEMATIC_FORMAT).newline(); String baseCmd = Commands.getAlias(SchematicCommands.class, "schematic") + " " + Commands.getAlias(SchematicCommands.class, "save"); boolean first = true; - for (final ClipboardFormat format : ClipboardFormat.values()) { + for (final ClipboardFormat format : ClipboardFormat.values) { StringBuilder builder = new StringBuilder(); builder.append(format.name()).append(": "); for (final String lookupName : format.getAliases()) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java index e03160c84..24ceded83 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java @@ -31,7 +31,7 @@ public class BuiltInClipboardFormat { @Deprecated public static final ClipboardFormat[] values() { - return ClipboardFormat.values(); + return ClipboardFormat.values; } @Deprecated diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormat.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormat.java index 88dd09aa5..be356ddf2 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormat.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormat.java @@ -48,6 +48,7 @@ import com.sk89q.worldedit.session.ClipboardHolder; import com.sk89q.worldedit.world.block.BlockTypes; import java.io.*; +import java.lang.reflect.Array; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; @@ -243,6 +244,8 @@ public enum ClipboardFormat { ; + public static final ClipboardFormat[] values; + private static final Map aliasMap; static { @@ -252,6 +255,7 @@ public enum ClipboardFormat { aliasMap.put(alias, emum); } } + values = values(); } private IClipboardFormat format; @@ -560,6 +564,18 @@ public enum ClipboardFormat { return aliasMap.get(alias.toLowerCase(Locale.ENGLISH).trim()); } + @Nullable + public static ClipboardFormat findByExtension(String extension) { + checkNotNull(extension); + extension = extension.toLowerCase(); + for (ClipboardFormat format : values) { + if (format.getFileExtensions().contains(extension)) { + return format; + } + } + return null; + } + /** * Detect the format given a file. * @@ -584,6 +600,17 @@ public enum ClipboardFormat { for (String alias : newEnum.getAliases()) { aliasMap.put(alias, newEnum); } + + ArrayList newValues = new ArrayList<>(Arrays.asList(values)); + newValues.add(newEnum); + ClipboardFormat[] newValuesArray = newValues.toArray(new ClipboardFormat[newValues.size()]); + try { + ReflectionUtils.setFailsafeFieldValue(ClipboardFormat.class.getDeclaredField("values"), null, newValuesArray); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } return newEnum; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormats.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormats.java index 14e7c93f9..cdc0e0461 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormats.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormats.java @@ -53,7 +53,7 @@ public class ClipboardFormats { public static ClipboardFormat findByFile(File file) { checkNotNull(file); - for (ClipboardFormat format : ClipboardFormat.values()) { + for (ClipboardFormat format : ClipboardFormat.values) { if (format.isFormat(file)) { return format; } @@ -67,7 +67,7 @@ public class ClipboardFormats { */ public static Multimap getFileExtensionMap() { HashMultimap map = HashMultimap.create(); - for (ClipboardFormat format : ClipboardFormat.values()) { + for (ClipboardFormat format : ClipboardFormat.values) { for (String ext : format.getFileExtensions()) { map.put(ext, format); } @@ -76,7 +76,7 @@ public class ClipboardFormats { } public static Collection getAll() { - return Arrays.asList(ClipboardFormat.values()); + return Arrays.asList(ClipboardFormat.values); } /** @@ -86,7 +86,7 @@ public class ClipboardFormats { public static String[] getFileExtensionArray() { List exts = new ArrayList<>(); HashMultimap map = HashMultimap.create(); - for (ClipboardFormat format : ClipboardFormat.values()) { + for (ClipboardFormat format : ClipboardFormat.values) { exts.addAll(format.getFileExtensions()); } return exts.toArray(new String[exts.size()]);