fix: improve schematic format selection (#2838)

- no longer allow selecting a format specifically because of the generic extension `.schem`
This commit is contained in:
Jordan 2024-07-25 21:05:16 +02:00 committed by GitHub
parent ddacb976e4
commit 8c3df59413
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 101 additions and 7 deletions

View File

@ -376,11 +376,13 @@ public class SchematicCommands {
actor.print(Caption.of("fawe.error.no-perm", "worldedit.schematic.load.other")); actor.print(Caption.of("fawe.error.no-perm", "worldedit.schematic.load.other"));
return; return;
} }
if (noExplicitFormat && filename.matches(".*\\.[\\w].*")) { if (!noExplicitFormat) {
format = ClipboardFormats
.findByExtension(filename.substring(filename.lastIndexOf('.') + 1));
} else {
format = ClipboardFormats.findByAlias(formatName); format = ClipboardFormats.findByAlias(formatName);
} else if (filename.matches(".*\\.[\\w].*")) {
format = ClipboardFormats
.findByExplicitExtension(filename.substring(filename.lastIndexOf('.') + 1));
} else {
format = null;
} }
file = MainUtil.resolve(dir, filename, format, false); file = MainUtil.resolve(dir, filename, format, false);
} }
@ -396,7 +398,7 @@ public class SchematicCommands {
.isInSubDirectory(saveDir, file)) + ")")); .isInSubDirectory(saveDir, file)) + ")"));
return; return;
} }
if (format == null || noExplicitFormat) { if (format == null) {
format = ClipboardFormats.findByFile(file); format = ClipboardFormats.findByFile(file);
if (format == null) { if (format == null) {
actor.print(Caption.of("worldedit.schematic.unknown-format", TextComponent.of(formatName))); actor.print(Caption.of("worldedit.schematic.unknown-format", TextComponent.of(formatName)));

View File

@ -50,6 +50,7 @@ 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.io.OutputStream;
import java.util.Collections;
import java.util.Locale; import java.util.Locale;
import java.util.Set; import java.util.Set;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
@ -125,6 +126,11 @@ public enum BuiltInClipboardFormat implements ClipboardFormat {
public String getPrimaryFileExtension() { public String getPrimaryFileExtension() {
return "schem"; return "schem";
} }
@Override
public Set<String> getExplicitFileExtensions() {
return Set.of("schem3", "sponge3", "fast3");
}
}, },
FAST_V2("fast.2", "fawe.2", "schem.2") { FAST_V2("fast.2", "fawe.2", "schem.2") {
@Override @Override
@ -168,6 +174,11 @@ public enum BuiltInClipboardFormat implements ClipboardFormat {
} }
return super.isFormat(file); return super.isFormat(file);
} }
@Override
public Set<String> getExplicitFileExtensions() {
return Set.of("schem2", "sponge2", "fast2");
}
}, },
//FAWE end //FAWE end
@ -217,6 +228,11 @@ public enum BuiltInClipboardFormat implements ClipboardFormat {
} }
return rootEntry.value().value().containsKey("Materials"); return rootEntry.value().value().containsKey("Materials");
} }
@Override
public Set<String> getExplicitFileExtensions() {
return Set.of("mcedit", "schem1", "sponge1", "fast1");
}
}, },
SPONGE_V1_SCHEMATIC("sponge.1") { SPONGE_V1_SCHEMATIC("sponge.1") {
@Override @Override
@ -243,6 +259,11 @@ public enum BuiltInClipboardFormat implements ClipboardFormat {
public boolean isFormat(File file) { public boolean isFormat(File file) {
return MCEDIT_SCHEMATIC.isFormat(file); return MCEDIT_SCHEMATIC.isFormat(file);
} }
@Override
public Set<String> getExplicitFileExtensions() {
return Collections.emptySet();
}
}, },
/** /**
@ -277,6 +298,11 @@ public enum BuiltInClipboardFormat implements ClipboardFormat {
public boolean isFormat(File file) { public boolean isFormat(File file) {
return FAST_V2.isFormat(file); return FAST_V2.isFormat(file);
} }
@Override
public Set<String> getExplicitFileExtensions() {
return Collections.emptySet();
}
}, },
SPONGE_V3_SCHEMATIC("sponge.3", "slow", "safe") { // FAWE - edit aliases for fast SPONGE_V3_SCHEMATIC("sponge.3", "slow", "safe") { // FAWE - edit aliases for fast
@ -301,6 +327,11 @@ public enum BuiltInClipboardFormat implements ClipboardFormat {
return FAST_V3.isFormat(file); return FAST_V3.isFormat(file);
//FAWE end //FAWE end
} }
@Override
public Set<String> getExplicitFileExtensions() {
return Collections.emptySet();
}
}, },
//FAWE start - recover schematics with bad entity data & register other clipboard formats //FAWE start - recover schematics with bad entity data & register other clipboard formats
BROKENENTITY("brokenentity", "legacyentity", "le", "be", "brokenentities", "legacyentities") { BROKENENTITY("brokenentity", "legacyentity", "le", "be", "brokenentities", "legacyentities") {
@ -341,6 +372,10 @@ public enum BuiltInClipboardFormat implements ClipboardFormat {
return false; return false;
} }
@Override
public Set<String> getExplicitFileExtensions() {
return Collections.emptySet();
}
}, },
/** /**
@ -401,6 +436,11 @@ public enum BuiltInClipboardFormat implements ClipboardFormat {
public boolean isFormat(final File file) { public boolean isFormat(final File file) {
return file.getName().toLowerCase(Locale.ROOT).endsWith(".nbt") && super.isFormat(file); return file.getName().toLowerCase(Locale.ROOT).endsWith(".nbt") && super.isFormat(file);
} }
@Override
public Set<String> getExplicitFileExtensions() {
return Set.of("nbt");
}
}, },
/** /**
@ -427,6 +467,11 @@ public enum BuiltInClipboardFormat implements ClipboardFormat {
public String getPrimaryFileExtension() { public String getPrimaryFileExtension() {
return "png"; return "png";
} }
@Override
public Set<String> getExplicitFileExtensions() {
return Set.of("png");
}
}; };
//FAWE end //FAWE end

View File

@ -124,6 +124,13 @@ public interface ClipboardFormat {
//FAWE start //FAWE start
/**
* Get the explicit file extensions (e.g. .schem2) this format is commonly known to use.
*
* @return The explicit file extensions this format might be known by
*/
Set<String> getExplicitFileExtensions();
/** /**
* Sets the actor's clipboard. * Sets the actor's clipboard.
* *

View File

@ -66,6 +66,7 @@ public class ClipboardFormats {
private static final Map<String, ClipboardFormat> aliasMap = new HashMap<>(); private static final Map<String, ClipboardFormat> aliasMap = new HashMap<>();
// FAWE start - keep order of ClipboardFormat entries -> prefer FAST over SPONGE_SCHEMATIC // FAWE start - keep order of ClipboardFormat entries -> prefer FAST over SPONGE_SCHEMATIC
private static final Multimap<String, ClipboardFormat> fileExtensionMap = Multimaps.newMultimap(new HashMap<>(), LinkedHashSet::new); private static final Multimap<String, ClipboardFormat> fileExtensionMap = Multimaps.newMultimap(new HashMap<>(), LinkedHashSet::new);
private static final Multimap<String, ClipboardFormat> explicitFileExtensionMap = Multimaps.newMultimap(new HashMap<>(), LinkedHashSet::new);
// FAWE end // FAWE end
private static final List<ClipboardFormat> registeredFormats = new ArrayList<>(); private static final List<ClipboardFormat> registeredFormats = new ArrayList<>();
@ -86,6 +87,10 @@ public class ClipboardFormats {
String lowExt = ext.toLowerCase(Locale.ROOT); String lowExt = ext.toLowerCase(Locale.ROOT);
fileExtensionMap.put(lowExt, format); fileExtensionMap.put(lowExt, format);
} }
for (String ext : format.getExplicitFileExtensions()) {
String lowExt = ext.toLowerCase(Locale.ROOT);
explicitFileExtensionMap.put(lowExt, format);
}
registeredFormats.add(format); registeredFormats.add(format);
} }
@ -147,6 +152,18 @@ public class ClipboardFormats {
return fileExtensionMap.keySet().toArray(new String[fileExtensionMap.keySet().size()]); return fileExtensionMap.keySet().toArray(new String[fileExtensionMap.keySet().size()]);
} }
//FAWE start
/**
* A mapping from explicit extensions (e.g. .schem2) to formats.
*
* @return a multimap from a file extension to the potential matching formats.
*/
public static Multimap<String, ClipboardFormat> getExplicitFileExtensionMap() {
return Multimaps.unmodifiableMultimap(explicitFileExtensionMap);
}
//FAWE end
private ClipboardFormats() { private ClipboardFormats() {
} }
@ -157,8 +174,10 @@ public class ClipboardFormats {
* *
* @param extension the extension * @param extension the extension
* @return the format, otherwise null if one cannot be detected * @return the format, otherwise null if one cannot be detected
* @deprecated DO NOT USE. Sponge formats 2 and 3 both use .schem by default.
*/ */
@Nullable @Nullable
@Deprecated(forRemoval = true, since = "TODO")
public static ClipboardFormat findByExtension(String extension) { public static ClipboardFormat findByExtension(String extension) {
checkNotNull(extension); checkNotNull(extension);
@ -172,6 +191,26 @@ public class ClipboardFormats {
} }
/**
* Detect the format given an explicit extension, e.g. ".schem2"
*
* @param extension the extension
* @return the format, otherwise null if one cannot be detected
*/
@Nullable
public static ClipboardFormat findByExplicitExtension(String extension) {
checkNotNull(extension);
Collection<Entry<String, ClipboardFormat>> entries = getExplicitFileExtensionMap().entries();
for (Map.Entry<String, ClipboardFormat> entry : entries) {
if (entry.getKey().equalsIgnoreCase(extension)) {
return entry.getValue();
}
}
return null;
}
public static MultiClipboardHolder loadAllFromInput( public static MultiClipboardHolder loadAllFromInput(
Actor player, Actor player,
String input, String input,
@ -231,7 +270,7 @@ public class ClipboardFormats {
} }
if (format == null && input.matches(".*\\.[\\w].*")) { if (format == null && input.matches(".*\\.[\\w].*")) {
String extension = input.substring(input.lastIndexOf('.') + 1); String extension = input.substring(input.lastIndexOf('.') + 1);
format = findByExtension(extension); format = findByExplicitExtension(extension);
} }
f = MainUtil.resolve(dir, input, format, true); f = MainUtil.resolve(dir, input, format, true);
} }
@ -302,7 +341,7 @@ public class ClipboardFormats {
byte[] buffer = new byte[8192]; byte[] buffer = new byte[8192];
while ((entry = zip.getNextEntry()) != null) { while ((entry = zip.getNextEntry()) != null) {
String filename = entry.getName(); String filename = entry.getName();
ClipboardFormat format = findByExtension(filename); ClipboardFormat format = findByExtension(filename); // FIXME
if (format != null) { if (format != null) {
FastByteArrayOutputStream out = new FastByteArrayOutputStream(); FastByteArrayOutputStream out = new FastByteArrayOutputStream();
int len; int len;

View File

@ -68,6 +68,7 @@
"fawe.worldedit.schematic.schematic.loaded": "{0} loaded. Paste it with //paste", "fawe.worldedit.schematic.schematic.loaded": "{0} loaded. Paste it with //paste",
"fawe.worldedit.schematic.schematic.saved": "{0} saved.", "fawe.worldedit.schematic.schematic.saved": "{0} saved.",
"fawe.worldedit.schematic.schematic.none": "No files found.", "fawe.worldedit.schematic.schematic.none": "No files found.",
"fawe.worldedit.schematic.schematic.load-failure": "File could not be read or it does not exist: {0}. If you are specifying a format, you may not be specifying the correct one. Sponge schematic v2 and v3 both use the .schem file extension. To allow FAWE to select the format, do not specify one.",
"fawe.worldedit.clipboard.clipboard.uri.not.found": "You do not have {0} loaded", "fawe.worldedit.clipboard.clipboard.uri.not.found": "You do not have {0} loaded",
"fawe.worldedit.clipboard.clipboard.cleared": "Clipboard cleared", "fawe.worldedit.clipboard.clipboard.cleared": "Clipboard cleared",
"fawe.worldedit.clipboard.clipboard.invalid.format": "Unknown clipboard format: {0}", "fawe.worldedit.clipboard.clipboard.invalid.format": "Unknown clipboard format: {0}",