summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Toshimichi09152022-06-12 21:24:41 +0900
committerGravatar GitHub2022-06-12 14:24:41 +0200
commit72176117bf75866fc702bbb094e7adc6661f2b01 (patch)
treedf721ed738be8dbf184bb167a8712e8d6088d530
parentUpdate ja_jp.json (#450) (diff)
downloadenigma-fork-72176117bf75866fc702bbb094e7adc6661f2b01.tar.gz
enigma-fork-72176117bf75866fc702bbb094e7adc6661f2b01.tar.xz
enigma-fork-72176117bf75866fc702bbb094e7adc6661f2b01.zip
Add Recaf format support (#451)
* Add Recaf format support * Update language files Co-authored-by: 2xsaiko <me@dblsaiko.net>
-rw-r--r--enigma/build.gradle2
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java4
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/recaf/RecafMappingsReader.java61
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/recaf/RecafMappingsWriter.java85
-rw-r--r--enigma/src/main/resources/lang/en_us.json1
-rw-r--r--enigma/src/main/resources/lang/fr_fr.json1
-rw-r--r--enigma/src/main/resources/lang/ja_jp.json1
-rw-r--r--enigma/src/main/resources/lang/zh_cn.json1
-rw-r--r--enigma/src/test/java/cuchaz/enigma/translation/mapping/serde/recaf/TestRecaf.java46
-rw-r--r--enigma/src/test/resources/recaf.mappings10
10 files changed, 211 insertions, 1 deletions
diff --git a/enigma/build.gradle b/enigma/build.gradle
index 8de7615..b4a4062 100644
--- a/enigma/build.gradle
+++ b/enigma/build.gradle
@@ -12,6 +12,8 @@ dependencies {
12 implementation 'net.fabricmc:cfr:0.1.0' 12 implementation 'net.fabricmc:cfr:0.1.0'
13 13
14 proGuard 'com.guardsquare:proguard-base:7.2.0-beta2' 14 proGuard 'com.guardsquare:proguard-base:7.2.0-beta2'
15
16 testImplementation 'com.google.jimfs:jimfs:1.2'
15} 17}
16 18
17// Generate "version.txt" file 19// Generate "version.txt" file
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java
index ca275eb..062c877 100644
--- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java
+++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java
@@ -6,6 +6,7 @@ import cuchaz.enigma.translation.mapping.MappingDelta;
6import cuchaz.enigma.translation.mapping.serde.enigma.EnigmaMappingsReader; 6import cuchaz.enigma.translation.mapping.serde.enigma.EnigmaMappingsReader;
7import cuchaz.enigma.translation.mapping.serde.enigma.EnigmaMappingsWriter; 7import cuchaz.enigma.translation.mapping.serde.enigma.EnigmaMappingsWriter;
8import cuchaz.enigma.translation.mapping.serde.proguard.ProguardMappingsReader; 8import cuchaz.enigma.translation.mapping.serde.proguard.ProguardMappingsReader;
9import cuchaz.enigma.translation.mapping.serde.recaf.RecafMappingsReader;
9import cuchaz.enigma.translation.mapping.serde.srg.SrgMappingsWriter; 10import cuchaz.enigma.translation.mapping.serde.srg.SrgMappingsWriter;
10import cuchaz.enigma.translation.mapping.serde.tiny.TinyMappingsReader; 11import cuchaz.enigma.translation.mapping.serde.tiny.TinyMappingsReader;
11import cuchaz.enigma.translation.mapping.serde.tiny.TinyMappingsWriter; 12import cuchaz.enigma.translation.mapping.serde.tiny.TinyMappingsWriter;
@@ -24,7 +25,8 @@ public enum MappingFormat {
24 TINY_V2(new TinyV2Writer("intermediary", "named"), new TinyV2Reader()), 25 TINY_V2(new TinyV2Writer("intermediary", "named"), new TinyV2Reader()),
25 TINY_FILE(TinyMappingsWriter.INSTANCE, TinyMappingsReader.INSTANCE), 26 TINY_FILE(TinyMappingsWriter.INSTANCE, TinyMappingsReader.INSTANCE),
26 SRG_FILE(SrgMappingsWriter.INSTANCE, null), 27 SRG_FILE(SrgMappingsWriter.INSTANCE, null),
27 PROGUARD(null, ProguardMappingsReader.INSTANCE); 28 PROGUARD(null, ProguardMappingsReader.INSTANCE),
29 RECAF(null, RecafMappingsReader.INSTANCE);
28 30
29 31
30 private final MappingsWriter writer; 32 private final MappingsWriter writer;
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/recaf/RecafMappingsReader.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/recaf/RecafMappingsReader.java
new file mode 100644
index 0000000..483e4e4
--- /dev/null
+++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/recaf/RecafMappingsReader.java
@@ -0,0 +1,61 @@
1package cuchaz.enigma.translation.mapping.serde.recaf;
2
3import cuchaz.enigma.ProgressListener;
4import cuchaz.enigma.translation.mapping.EntryMapping;
5import cuchaz.enigma.translation.mapping.serde.MappingParseException;
6import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters;
7import cuchaz.enigma.translation.mapping.serde.MappingsReader;
8import cuchaz.enigma.translation.mapping.tree.EntryTree;
9import cuchaz.enigma.translation.mapping.tree.HashEntryTree;
10import cuchaz.enigma.translation.representation.MethodDescriptor;
11import cuchaz.enigma.translation.representation.TypeDescriptor;
12import cuchaz.enigma.translation.representation.entry.ClassEntry;
13import cuchaz.enigma.translation.representation.entry.FieldEntry;
14import cuchaz.enigma.translation.representation.entry.MethodEntry;
15
16import java.io.IOException;
17import java.nio.file.Files;
18import java.nio.file.Path;
19import java.util.List;
20import java.util.regex.Matcher;
21import java.util.regex.Pattern;
22
23public class RecafMappingsReader implements MappingsReader {
24
25 public static final RecafMappingsReader INSTANCE = new RecafMappingsReader();
26 private static final Pattern METHOD_PATTERN = Pattern.compile("(.*?)\\.(.*?)(\\(.*?) (.*)");
27 private static final Pattern FIELD_PATTERN = Pattern.compile("(.*?)\\.(.*?) (.*?) (.*)");
28 private static final Pattern CLASS_PATTERN = Pattern.compile("(.*?) (.*)");
29
30 @Override
31 public EntryTree<EntryMapping> read(Path path, ProgressListener progress, MappingSaveParameters saveParameters) throws MappingParseException, IOException {
32 EntryTree<EntryMapping> mappings = new HashEntryTree<>();
33 List<String> lines = Files.readAllLines(path);
34
35 for (String line : lines) {
36 Matcher methodMatcher = METHOD_PATTERN.matcher(line);
37 if (methodMatcher.find()) {
38 ClassEntry owner = new ClassEntry(methodMatcher.group(1));
39 String name = methodMatcher.group(2);
40 MethodDescriptor desc = new MethodDescriptor(methodMatcher.group(3));
41 mappings.insert(new MethodEntry(owner, name, desc), new EntryMapping(methodMatcher.group(4)));
42 continue;
43 }
44
45 Matcher fieldMatcher = FIELD_PATTERN.matcher(line);
46 if (fieldMatcher.find()) {
47 ClassEntry owner = new ClassEntry(fieldMatcher.group(1));
48 String name = fieldMatcher.group(2);
49 TypeDescriptor desc = new TypeDescriptor(fieldMatcher.group(3));
50 mappings.insert(new FieldEntry(owner, name, desc), new EntryMapping(fieldMatcher.group(4)));
51 continue;
52 }
53
54 Matcher classMatcher = CLASS_PATTERN.matcher(line);
55 if (classMatcher.find()) {
56 mappings.insert(new ClassEntry(classMatcher.group(1)), new EntryMapping(classMatcher.group(2)));
57 }
58 }
59 return mappings;
60 }
61}
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/recaf/RecafMappingsWriter.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/recaf/RecafMappingsWriter.java
new file mode 100644
index 0000000..aa29ff6
--- /dev/null
+++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/recaf/RecafMappingsWriter.java
@@ -0,0 +1,85 @@
1package cuchaz.enigma.translation.mapping.serde.recaf;
2
3import com.google.common.collect.Lists;
4import cuchaz.enigma.ProgressListener;
5import cuchaz.enigma.translation.mapping.EntryMapping;
6import cuchaz.enigma.translation.mapping.MappingDelta;
7import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters;
8import cuchaz.enigma.translation.mapping.serde.MappingsWriter;
9import cuchaz.enigma.translation.mapping.tree.EntryTree;
10import cuchaz.enigma.translation.mapping.tree.EntryTreeNode;
11import cuchaz.enigma.translation.representation.entry.ClassEntry;
12import cuchaz.enigma.translation.representation.entry.Entry;
13import cuchaz.enigma.translation.representation.entry.FieldEntry;
14import cuchaz.enigma.translation.representation.entry.MethodEntry;
15
16import java.io.BufferedWriter;
17import java.io.IOException;
18import java.io.Writer;
19import java.nio.file.Files;
20import java.nio.file.Path;
21
22public class RecafMappingsWriter implements MappingsWriter {
23
24 public static final RecafMappingsWriter INSTANCE = new RecafMappingsWriter();
25
26 @Override
27 public void write(EntryTree<EntryMapping> mappings, MappingDelta<EntryMapping> delta, Path path, ProgressListener progress, MappingSaveParameters saveParameters) {
28 try {
29 Files.deleteIfExists(path);
30 Files.createFile(path);
31 } catch (IOException e) {
32 e.printStackTrace();
33 }
34
35 try (BufferedWriter writer = Files.newBufferedWriter(path)) {
36 Lists.newArrayList(mappings)
37 .stream()
38 .map(EntryTreeNode::getEntry)
39 .forEach(entry -> writeEntry(writer, mappings, entry));
40 } catch (IOException e) {
41 e.printStackTrace();
42 }
43 }
44
45 private void writeEntry(Writer writer, EntryTree<EntryMapping> mappings, Entry<?> entry) {
46 EntryTreeNode<EntryMapping> node = mappings.findNode(entry);
47 if (node == null) {
48 return;
49 }
50
51 EntryMapping mapping = mappings.get(entry);
52
53 try {
54 if (mapping != null && mapping.targetName() != null) {
55 if (entry instanceof ClassEntry classEntry) {
56
57 writer.write(classEntry.getFullName());
58 writer.write(" ");
59 writer.write(mapping.targetName());
60
61 } else if (entry instanceof FieldEntry fieldEntry) {
62
63 writer.write(fieldEntry.getFullName());
64 writer.write(" ");
65 writer.write(fieldEntry.getDesc().toString());
66 writer.write(" ");
67 writer.write(mapping.targetName());
68
69 } else if (entry instanceof MethodEntry methodEntry) {
70
71 writer.write(methodEntry.getFullName());
72 writer.write(methodEntry.getDesc().toString());
73 writer.write(" ");
74 writer.write(mapping.targetName());
75
76 }
77 writer.write("\n");
78 }
79 } catch (IOException e) {
80 e.printStackTrace();
81 }
82
83 node.getChildren().forEach(child -> writeEntry(writer, mappings, child));
84 }
85}
diff --git a/enigma/src/main/resources/lang/en_us.json b/enigma/src/main/resources/lang/en_us.json
index 4488bb2..4ec2f08 100644
--- a/enigma/src/main/resources/lang/en_us.json
+++ b/enigma/src/main/resources/lang/en_us.json
@@ -8,6 +8,7 @@
8 "mapping_format.tiny_file": "Tiny File", 8 "mapping_format.tiny_file": "Tiny File",
9 "mapping_format.srg_file": "SRG File", 9 "mapping_format.srg_file": "SRG File",
10 "mapping_format.proguard": "Proguard", 10 "mapping_format.proguard": "Proguard",
11 "mapping_format.recaf": "Recaf",
11 "type.methods": "Methods", 12 "type.methods": "Methods",
12 "type.fields": "Fields", 13 "type.fields": "Fields",
13 "type.parameters": "Parameters", 14 "type.parameters": "Parameters",
diff --git a/enigma/src/main/resources/lang/fr_fr.json b/enigma/src/main/resources/lang/fr_fr.json
index 2c9ec2c..d3d0c29 100644
--- a/enigma/src/main/resources/lang/fr_fr.json
+++ b/enigma/src/main/resources/lang/fr_fr.json
@@ -8,6 +8,7 @@
8 "mapping_format.tiny_file": "Fichier Tiny", 8 "mapping_format.tiny_file": "Fichier Tiny",
9 "mapping_format.srg_file": "Fichier SRG", 9 "mapping_format.srg_file": "Fichier SRG",
10 "mapping_format.proguard": "Proguard", 10 "mapping_format.proguard": "Proguard",
11 "mapping_format.recaf": "Recaf",
11 "type.methods": "Méthodes", 12 "type.methods": "Méthodes",
12 "type.fields": "Champs", 13 "type.fields": "Champs",
13 "type.parameters": "Paramètres", 14 "type.parameters": "Paramètres",
diff --git a/enigma/src/main/resources/lang/ja_jp.json b/enigma/src/main/resources/lang/ja_jp.json
index 50449b6..09e7ee0 100644
--- a/enigma/src/main/resources/lang/ja_jp.json
+++ b/enigma/src/main/resources/lang/ja_jp.json
@@ -8,6 +8,7 @@
8 "mapping_format.tiny_file": "Tiny ファイル", 8 "mapping_format.tiny_file": "Tiny ファイル",
9 "mapping_format.srg_file": "SRG ファイル", 9 "mapping_format.srg_file": "SRG ファイル",
10 "mapping_format.proguard": "Proguard", 10 "mapping_format.proguard": "Proguard",
11 "mapping_format.recaf": "Recaf",
11 "type.methods": "メソッド", 12 "type.methods": "メソッド",
12 "type.fields": "フィールド", 13 "type.fields": "フィールド",
13 "type.parameters": "パラメータ", 14 "type.parameters": "パラメータ",
diff --git a/enigma/src/main/resources/lang/zh_cn.json b/enigma/src/main/resources/lang/zh_cn.json
index fc36cb8..fe806fb 100644
--- a/enigma/src/main/resources/lang/zh_cn.json
+++ b/enigma/src/main/resources/lang/zh_cn.json
@@ -8,6 +8,7 @@
8 "mapping_format.tiny_file": "Tiny 文件", 8 "mapping_format.tiny_file": "Tiny 文件",
9 "mapping_format.srg_file": "SRG 文件", 9 "mapping_format.srg_file": "SRG 文件",
10 "mapping_format.proguard": "Proguard 文件", 10 "mapping_format.proguard": "Proguard 文件",
11 "mapping_format.recaf": "Recaf 文件",
11 "type.methods": "方法", 12 "type.methods": "方法",
12 "type.fields": "字段", 13 "type.fields": "字段",
13 "type.parameters": "参数", 14 "type.parameters": "参数",
diff --git a/enigma/src/test/java/cuchaz/enigma/translation/mapping/serde/recaf/TestRecaf.java b/enigma/src/test/java/cuchaz/enigma/translation/mapping/serde/recaf/TestRecaf.java
new file mode 100644
index 0000000..1026f57
--- /dev/null
+++ b/enigma/src/test/java/cuchaz/enigma/translation/mapping/serde/recaf/TestRecaf.java
@@ -0,0 +1,46 @@
1package cuchaz.enigma.translation.mapping.serde.recaf;
2
3import com.google.common.collect.Sets;
4import com.google.common.jimfs.Jimfs;
5import cuchaz.enigma.ProgressListener;
6import cuchaz.enigma.translation.mapping.EntryMapping;
7import cuchaz.enigma.translation.mapping.tree.EntryTree;
8import org.junit.Test;
9
10import java.io.InputStream;
11import java.nio.charset.StandardCharsets;
12import java.nio.file.FileSystem;
13import java.nio.file.Files;
14import java.nio.file.Path;
15import java.util.HashSet;
16import java.util.Set;
17
18import static org.junit.Assert.assertEquals;
19
20public class TestRecaf {
21
22 @Test
23 public void testIntegrity() throws Exception {
24 Set<String> contents;
25 try (InputStream in = getClass().getResourceAsStream("/recaf.mappings")) {
26 contents = Sets.newHashSet(new String(in.readAllBytes(), StandardCharsets.UTF_8).split("\\R"));
27 }
28
29 try (FileSystem fs = Jimfs.newFileSystem()) {
30
31 Path path = fs.getPath("recaf.mappings");
32 Files.writeString(path, String.join("\n", contents));
33
34 RecafMappingsWriter writer = RecafMappingsWriter.INSTANCE;
35 RecafMappingsReader reader = RecafMappingsReader.INSTANCE;
36
37 EntryTree<EntryMapping> mappings = reader.read(path, ProgressListener.none(), null);
38 writer.write(mappings, path, ProgressListener.none(), null);
39
40 reader.read(path, ProgressListener.none(), null);
41 Set<String> newContents = new HashSet<>(Files.readAllLines(path));
42
43 assertEquals(contents, newContents);
44 }
45 }
46}
diff --git a/enigma/src/test/resources/recaf.mappings b/enigma/src/test/resources/recaf.mappings
new file mode 100644
index 0000000..479099e
--- /dev/null
+++ b/enigma/src/test/resources/recaf.mappings
@@ -0,0 +1,10 @@
1a testClass
2a.a Z testField
3a.a()V testMethod0
4a.a(Z)V testMethod1
5a.b()V testMethod2
6a/a testInnerClass
7a/a.a Z testInnerField
8a/a.a()V testInnerMethod0
9a/a.a(Z)V testInnerMethod1
10a/a.b()V testInnerMethod2