diff options
| author | 2020-03-17 23:28:47 +0000 | |
|---|---|---|
| committer | 2020-03-17 23:28:47 +0000 | |
| commit | bfd7bfd739968af5b7bad17134783deedd424f1f (patch) | |
| tree | a9dc7906c88c1c8c40c98f0f97632cd7dd269e25 /src | |
| parent | Fix documenting constructors (#201) (diff) | |
| download | enigma-bfd7bfd739968af5b7bad17134783deedd424f1f.tar.gz enigma-bfd7bfd739968af5b7bad17134783deedd424f1f.tar.xz enigma-bfd7bfd739968af5b7bad17134783deedd424f1f.zip | |
Add support for reading/writing zipped mappings (#199)
* Add support to read/write Enigma mappings from ZIP
Takes any path which points to a ZIP as wanting to be read/written as a ZIP
Paths from an existing ZIP file system will be correctly handled as directories
* Fix deleting a path needing to be from the default file system
* Allow calling MapSpecializedMethodsCommand directly
* Fix indentation
* Missing static
Diffstat (limited to 'src')
9 files changed, 46 insertions, 6 deletions
diff --git a/src/main/java/cuchaz/enigma/Main.java b/src/main/java/cuchaz/enigma/Main.java index ceb5554b..1d63ec1c 100644 --- a/src/main/java/cuchaz/enigma/Main.java +++ b/src/main/java/cuchaz/enigma/Main.java | |||
| @@ -25,6 +25,8 @@ import java.nio.file.Files; | |||
| 25 | import java.nio.file.Path; | 25 | import java.nio.file.Path; |
| 26 | import java.nio.file.Paths; | 26 | import java.nio.file.Paths; |
| 27 | 27 | ||
| 28 | import com.google.common.io.MoreFiles; | ||
| 29 | |||
| 28 | public class Main { | 30 | public class Main { |
| 29 | 31 | ||
| 30 | public static void main(String[] args) throws IOException { | 32 | public static void main(String[] args) throws IOException { |
| @@ -78,6 +80,8 @@ public class Main { | |||
| 78 | Path mappingsPath = options.valueOf(mappings); | 80 | Path mappingsPath = options.valueOf(mappings); |
| 79 | if (Files.isDirectory(mappingsPath)) { | 81 | if (Files.isDirectory(mappingsPath)) { |
| 80 | controller.openMappings(MappingFormat.ENIGMA_DIRECTORY, mappingsPath); | 82 | controller.openMappings(MappingFormat.ENIGMA_DIRECTORY, mappingsPath); |
| 83 | } else if ("zip".equalsIgnoreCase(MoreFiles.getFileExtension(mappingsPath))) { | ||
| 84 | controller.openMappings(MappingFormat.ENIGMA_ZIP, mappingsPath); | ||
| 81 | } else { | 85 | } else { |
| 82 | controller.openMappings(MappingFormat.ENIGMA_FILE, mappingsPath); | 86 | controller.openMappings(MappingFormat.ENIGMA_FILE, mappingsPath); |
| 83 | } | 87 | } |
diff --git a/src/main/java/cuchaz/enigma/command/Command.java b/src/main/java/cuchaz/enigma/command/Command.java index d53ed6ef..09dd3216 100644 --- a/src/main/java/cuchaz/enigma/command/Command.java +++ b/src/main/java/cuchaz/enigma/command/Command.java | |||
| @@ -13,6 +13,8 @@ import java.nio.file.Files; | |||
| 13 | import java.nio.file.Path; | 13 | import java.nio.file.Path; |
| 14 | import java.nio.file.Paths; | 14 | import java.nio.file.Paths; |
| 15 | 15 | ||
| 16 | import com.google.common.io.MoreFiles; | ||
| 17 | |||
| 16 | public abstract class Command { | 18 | public abstract class Command { |
| 17 | public final String name; | 19 | public final String name; |
| 18 | 20 | ||
| @@ -49,6 +51,8 @@ public abstract class Command { | |||
| 49 | protected static MappingFormat chooseEnigmaFormat(Path path) { | 51 | protected static MappingFormat chooseEnigmaFormat(Path path) { |
| 50 | if (Files.isDirectory(path)) { | 52 | if (Files.isDirectory(path)) { |
| 51 | return MappingFormat.ENIGMA_DIRECTORY; | 53 | return MappingFormat.ENIGMA_DIRECTORY; |
| 54 | } else if ("zip".equalsIgnoreCase(MoreFiles.getFileExtension(path))) { | ||
| 55 | return MappingFormat.ENIGMA_ZIP; | ||
| 52 | } else { | 56 | } else { |
| 53 | return MappingFormat.ENIGMA_FILE; | 57 | return MappingFormat.ENIGMA_FILE; |
| 54 | } | 58 | } |
diff --git a/src/main/java/cuchaz/enigma/command/MapSpecializedMethodsCommand.java b/src/main/java/cuchaz/enigma/command/MapSpecializedMethodsCommand.java index 7696f0f1..eb8d5dcc 100644 --- a/src/main/java/cuchaz/enigma/command/MapSpecializedMethodsCommand.java +++ b/src/main/java/cuchaz/enigma/command/MapSpecializedMethodsCommand.java | |||
| @@ -36,10 +36,13 @@ public class MapSpecializedMethodsCommand extends Command { | |||
| 36 | 36 | ||
| 37 | @Override | 37 | @Override |
| 38 | public void run(String... args) throws IOException, MappingParseException { | 38 | public void run(String... args) throws IOException, MappingParseException { |
| 39 | run(Paths.get(args[0]), args[1], Paths.get(args[2]), args[3], Paths.get(args[4])); | ||
| 40 | } | ||
| 41 | |||
| 42 | public static void run(Path jar, String sourceFormat, Path sourcePath, String resultFormat, Path output) throws IOException, MappingParseException { | ||
| 39 | MappingSaveParameters saveParameters = new MappingSaveParameters(MappingFileNameFormat.BY_DEOBF); | 43 | MappingSaveParameters saveParameters = new MappingSaveParameters(MappingFileNameFormat.BY_DEOBF); |
| 40 | EntryTree<EntryMapping> source = MappingCommandsUtil.read(args[1], Paths.get(args[2]), saveParameters); | 44 | EntryTree<EntryMapping> source = MappingCommandsUtil.read(sourceFormat, sourcePath, saveParameters); |
| 41 | EntryTree<EntryMapping> result = new HashEntryTree<>(); | 45 | EntryTree<EntryMapping> result = new HashEntryTree<>(); |
| 42 | Path jar = Paths.get(args[0]); | ||
| 43 | ClassCache classCache = ClassCache.of(jar); | 46 | ClassCache classCache = ClassCache.of(jar); |
| 44 | JarIndex jarIndex = classCache.index(ProgressListener.none()); | 47 | JarIndex jarIndex = classCache.index(ProgressListener.none()); |
| 45 | BridgeMethodIndex bridgeMethodIndex = jarIndex.getBridgeMethodIndex(); | 48 | BridgeMethodIndex bridgeMethodIndex = jarIndex.getBridgeMethodIndex(); |
| @@ -60,8 +63,7 @@ public class MapSpecializedMethodsCommand extends Command { | |||
| 60 | result.insert(specialized, new EntryMapping(name)); | 63 | result.insert(specialized, new EntryMapping(name)); |
| 61 | } | 64 | } |
| 62 | 65 | ||
| 63 | Path output = Paths.get(args[4]); | ||
| 64 | Utils.delete(output); | 66 | Utils.delete(output); |
| 65 | MappingCommandsUtil.write(result, args[3], output, saveParameters); | 67 | MappingCommandsUtil.write(result, resultFormat, output, saveParameters); |
| 66 | } | 68 | } |
| 67 | } | 69 | } |
diff --git a/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java b/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java index fc68edf0..fc7afbc0 100644 --- a/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java +++ b/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java | |||
| @@ -17,6 +17,7 @@ import cuchaz.enigma.translation.representation.entry.FieldEntry; | |||
| 17 | import cuchaz.enigma.translation.representation.entry.MethodEntry; | 17 | import cuchaz.enigma.translation.representation.entry.MethodEntry; |
| 18 | 18 | ||
| 19 | import java.io.IOException; | 19 | import java.io.IOException; |
| 20 | import java.nio.file.Files; | ||
| 20 | import java.nio.file.Path; | 21 | import java.nio.file.Path; |
| 21 | import java.util.HashSet; | 22 | import java.util.HashSet; |
| 22 | import java.util.Set; | 23 | import java.util.Set; |
| @@ -81,7 +82,7 @@ public final class MappingCommandsUtil { | |||
| 81 | 82 | ||
| 82 | public static EntryTree<EntryMapping> read(String type, Path path, MappingSaveParameters saveParameters) throws MappingParseException, IOException { | 83 | public static EntryTree<EntryMapping> read(String type, Path path, MappingSaveParameters saveParameters) throws MappingParseException, IOException { |
| 83 | if (type.equals("enigma")) { | 84 | if (type.equals("enigma")) { |
| 84 | return EnigmaMappingsReader.DIRECTORY.read(path, ProgressListener.none(), saveParameters); | 85 | return (Files.isDirectory(path) ? EnigmaMappingsReader.DIRECTORY : EnigmaMappingsReader.ZIP).read(path, ProgressListener.none(), saveParameters); |
| 85 | } | 86 | } |
| 86 | 87 | ||
| 87 | if (type.equals("tiny")) { | 88 | if (type.equals("tiny")) { |
diff --git a/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsReader.java b/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsReader.java index 60ce587d..a1d5e01d 100644 --- a/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsReader.java +++ b/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsReader.java | |||
| @@ -16,6 +16,8 @@ import cuchaz.enigma.utils.I18n; | |||
| 16 | 16 | ||
| 17 | import javax.annotation.Nullable; | 17 | import javax.annotation.Nullable; |
| 18 | import java.io.IOException; | 18 | import java.io.IOException; |
| 19 | import java.nio.file.FileSystem; | ||
| 20 | import java.nio.file.FileSystems; | ||
| 19 | import java.nio.file.Files; | 21 | import java.nio.file.Files; |
| 20 | import java.nio.file.Path; | 22 | import java.nio.file.Path; |
| 21 | import java.util.ArrayDeque; | 23 | import java.util.ArrayDeque; |
| @@ -62,6 +64,14 @@ public enum EnigmaMappingsReader implements MappingsReader { | |||
| 62 | 64 | ||
| 63 | return mappings; | 65 | return mappings; |
| 64 | } | 66 | } |
| 67 | }, | ||
| 68 | ZIP { | ||
| 69 | @Override | ||
| 70 | public EntryTree<EntryMapping> read(Path zip, ProgressListener progress, MappingSaveParameters saveParameters) throws MappingParseException, IOException { | ||
| 71 | try (FileSystem fs = FileSystems.newFileSystem(zip, (ClassLoader) null)) { | ||
| 72 | return DIRECTORY.read(fs.getPath("/"), progress, saveParameters); | ||
| 73 | } | ||
| 74 | } | ||
| 65 | }; | 75 | }; |
| 66 | 76 | ||
| 67 | protected void readFile(Path path, EntryTree<EntryMapping> mappings) throws IOException, MappingParseException { | 77 | protected void readFile(Path path, EntryTree<EntryMapping> mappings) throws IOException, MappingParseException { |
diff --git a/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsWriter.java b/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsWriter.java index 2ce1234a..2f6c7bc4 100644 --- a/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsWriter.java +++ b/src/main/java/cuchaz/enigma/translation/mapping/serde/EnigmaMappingsWriter.java | |||
| @@ -13,12 +13,17 @@ package cuchaz.enigma.translation.mapping.serde; | |||
| 13 | 13 | ||
| 14 | import java.io.IOException; | 14 | import java.io.IOException; |
| 15 | import java.io.PrintWriter; | 15 | import java.io.PrintWriter; |
| 16 | import java.net.URI; | ||
| 17 | import java.net.URISyntaxException; | ||
| 16 | import java.nio.file.DirectoryStream; | 18 | import java.nio.file.DirectoryStream; |
| 19 | import java.nio.file.FileSystem; | ||
| 20 | import java.nio.file.FileSystems; | ||
| 17 | import java.nio.file.Files; | 21 | import java.nio.file.Files; |
| 18 | import java.nio.file.Path; | 22 | import java.nio.file.Path; |
| 19 | import java.nio.file.Paths; | 23 | import java.nio.file.Paths; |
| 20 | import java.util.ArrayList; | 24 | import java.util.ArrayList; |
| 21 | import java.util.Collection; | 25 | import java.util.Collection; |
| 26 | import java.util.Collections; | ||
| 22 | import java.util.Objects; | 27 | import java.util.Objects; |
| 23 | import java.util.concurrent.atomic.AtomicInteger; | 28 | import java.util.concurrent.atomic.AtomicInteger; |
| 24 | import java.util.stream.Collectors; | 29 | import java.util.stream.Collectors; |
| @@ -159,6 +164,18 @@ public enum EnigmaMappingsWriter implements MappingsWriter { | |||
| 159 | private Path resolve(Path root, ClassEntry classEntry) { | 164 | private Path resolve(Path root, ClassEntry classEntry) { |
| 160 | return root.resolve(classEntry.getFullName() + ".mapping"); | 165 | return root.resolve(classEntry.getFullName() + ".mapping"); |
| 161 | } | 166 | } |
| 167 | }, | ||
| 168 | ZIP { | ||
| 169 | @Override | ||
| 170 | public void write(EntryTree<EntryMapping> mappings, MappingDelta<EntryMapping> delta, Path zip, ProgressListener progress, MappingSaveParameters saveParameters) { | ||
| 171 | try (FileSystem fs = FileSystems.newFileSystem(new URI("jar:file", null, zip.toUri().getPath(), ""), Collections.singletonMap("create", "true"))) { | ||
| 172 | DIRECTORY.write(mappings, delta, fs.getPath("/"), progress, saveParameters); | ||
| 173 | } catch (IOException e) { | ||
| 174 | e.printStackTrace(); | ||
| 175 | } catch (URISyntaxException e) { | ||
| 176 | throw new RuntimeException("Unexpected error creating URI for " + zip, e); | ||
| 177 | } | ||
| 178 | } | ||
| 162 | }; | 179 | }; |
| 163 | 180 | ||
| 164 | protected void writeRoot(PrintWriter writer, EntryTree<EntryMapping> mappings, ClassEntry classEntry) { | 181 | protected void writeRoot(PrintWriter writer, EntryTree<EntryMapping> mappings, ClassEntry classEntry) { |
diff --git a/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java b/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java index c04eec5e..6c8c3430 100644 --- a/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java +++ b/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java | |||
| @@ -14,6 +14,7 @@ import java.nio.file.Path; | |||
| 14 | public enum MappingFormat { | 14 | public enum MappingFormat { |
| 15 | ENIGMA_FILE(EnigmaMappingsWriter.FILE, EnigmaMappingsReader.FILE), | 15 | ENIGMA_FILE(EnigmaMappingsWriter.FILE, EnigmaMappingsReader.FILE), |
| 16 | ENIGMA_DIRECTORY(EnigmaMappingsWriter.DIRECTORY, EnigmaMappingsReader.DIRECTORY), | 16 | ENIGMA_DIRECTORY(EnigmaMappingsWriter.DIRECTORY, EnigmaMappingsReader.DIRECTORY), |
| 17 | ENIGMA_ZIP(EnigmaMappingsWriter.ZIP, EnigmaMappingsReader.ZIP), | ||
| 17 | TINY_V2(new TinyV2Writer("intermediary", "named"), new TinyV2Reader()), | 18 | TINY_V2(new TinyV2Writer("intermediary", "named"), new TinyV2Reader()), |
| 18 | TINY_FILE(TinyMappingsWriter.INSTANCE, TinyMappingsReader.INSTANCE), | 19 | TINY_FILE(TinyMappingsWriter.INSTANCE, TinyMappingsReader.INSTANCE), |
| 19 | SRG_FILE(SrgMappingsWriter.INSTANCE, null), | 20 | SRG_FILE(SrgMappingsWriter.INSTANCE, null), |
diff --git a/src/main/java/cuchaz/enigma/utils/Utils.java b/src/main/java/cuchaz/enigma/utils/Utils.java index 3c3e68ae..17f6fb8f 100644 --- a/src/main/java/cuchaz/enigma/utils/Utils.java +++ b/src/main/java/cuchaz/enigma/utils/Utils.java | |||
| @@ -101,7 +101,7 @@ public class Utils { | |||
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | public static void delete(Path path) throws IOException { | 103 | public static void delete(Path path) throws IOException { |
| 104 | if (path.toFile().exists()) { | 104 | if (Files.exists(path)) { |
| 105 | for (Path p : Files.walk(path).sorted(Comparator.reverseOrder()).collect(Collectors.toList())) { | 105 | for (Path p : Files.walk(path).sorted(Comparator.reverseOrder()).collect(Collectors.toList())) { |
| 106 | Files.delete(p); | 106 | Files.delete(p); |
| 107 | } | 107 | } |
diff --git a/src/main/resources/lang/en_us.json b/src/main/resources/lang/en_us.json index 8cd5823f..dbba1983 100644 --- a/src/main/resources/lang/en_us.json +++ b/src/main/resources/lang/en_us.json | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | "mapping_format.enigma_file": "Enigma File", | 4 | "mapping_format.enigma_file": "Enigma File", |
| 5 | "mapping_format.enigma_directory": "Enigma Directory", | 5 | "mapping_format.enigma_directory": "Enigma Directory", |
| 6 | "mapping_format.enigma_zip": "Enigma ZIP", | ||
| 6 | "mapping_format.tiny_v2": "Tiny v2", | 7 | "mapping_format.tiny_v2": "Tiny v2", |
| 7 | "mapping_format.tiny_file": "Tiny File", | 8 | "mapping_format.tiny_file": "Tiny File", |
| 8 | "mapping_format.srg_file": "SRG File", | 9 | "mapping_format.srg_file": "SRG File", |