aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/com/replaymod/gradle/remap/legacy
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/replaymod/gradle/remap/legacy')
-rw-r--r--src/main/java/com/replaymod/gradle/remap/legacy/LegacyMapping.java118
-rw-r--r--src/main/java/com/replaymod/gradle/remap/legacy/LegacyMappingSetModelFactory.java36
-rw-r--r--src/main/java/com/replaymod/gradle/remap/legacy/LegacyMappingsReader.java44
3 files changed, 198 insertions, 0 deletions
diff --git a/src/main/java/com/replaymod/gradle/remap/legacy/LegacyMapping.java b/src/main/java/com/replaymod/gradle/remap/legacy/LegacyMapping.java
new file mode 100644
index 0000000..05a85d9
--- /dev/null
+++ b/src/main/java/com/replaymod/gradle/remap/legacy/LegacyMapping.java
@@ -0,0 +1,118 @@
+package com.replaymod.gradle.remap.legacy;
+
+import org.cadixdev.lorenz.MappingSet;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class LegacyMapping {
+ public static MappingSet readMappingSet(Path mappingFile, boolean invert) throws IOException {
+ return new LegacyMappingsReader(readMappings(mappingFile, invert)).read();
+ }
+
+ public static Map<String, LegacyMapping> readMappings(Path mappingFile, boolean invert) throws IOException {
+ Map<String, LegacyMapping> mappings = new HashMap<>();
+ Map<String, LegacyMapping> revMappings = new HashMap<>();
+ int lineNumber = 0;
+ for (String line : Files.readAllLines(mappingFile, StandardCharsets.UTF_8)) {
+ lineNumber++;
+ if (line.trim().startsWith("#") || line.trim().isEmpty()) continue;
+
+ String[] parts = line.split(" ");
+ if (parts.length < 2 || line.contains(";")) {
+ throw new IllegalArgumentException("Failed to parse line " + lineNumber + " in " + mappingFile + ".");
+ }
+
+ LegacyMapping mapping = mappings.get(parts[0]);
+ if (mapping == null) {
+ mapping = new LegacyMapping();
+ mapping.oldName = mapping.newName = parts[0];
+ mappings.put(mapping.oldName, mapping);
+ }
+
+ if (parts.length == 2) {
+ // Class mapping
+ mapping.newName = parts[1];
+ // Possibly merge with reverse mapping
+ LegacyMapping revMapping = revMappings.remove(mapping.newName);
+ if (revMapping != null) {
+ mapping.fields.putAll(revMapping.fields);
+ mapping.methods.putAll(revMapping.methods);
+ }
+ revMappings.put(mapping.newName, mapping);
+ } else if (parts.length == 3 || parts.length == 4) {
+ String fromName = parts[1];
+ String toName;
+ LegacyMapping revMapping;
+ if (parts.length == 4) {
+ toName = parts[3];
+ revMapping = revMappings.get(parts[2]);
+ if (revMapping == null) {
+ revMapping = new LegacyMapping();
+ revMapping.oldName = revMapping.newName = parts[2];
+ revMappings.put(revMapping.newName, revMapping);
+ }
+ } else {
+ toName = parts[2];
+ revMapping = mapping;
+ }
+ if (fromName.endsWith("()")) {
+ // Method mapping
+ fromName = fromName.substring(0, fromName.length() - 2);
+ toName = toName.substring(0, toName.length() - 2);
+ mapping.methods.put(fromName, toName);
+ revMapping.methods.put(fromName, toName);
+ } else {
+ // Field mapping
+ mapping.fields.put(fromName, toName);
+ revMapping.fields.put(fromName, toName);
+ }
+ } else {
+ throw new IllegalArgumentException("Failed to parse line " + lineNumber + " in " + mappingFile + ".");
+ }
+ }
+ if (invert) {
+ Stream.concat(
+ mappings.values().stream(),
+ revMappings.values().stream()
+ ).distinct().forEach(it -> {
+ String oldName = it.oldName;
+ it.oldName = it.newName;
+ it.newName = oldName;
+ it.fields = it.fields.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
+ it.methods = it.methods.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
+ });
+ }
+ return Stream.concat(
+ mappings.values().stream(),
+ revMappings.values().stream()
+ ).collect(Collectors.toMap(mapping -> mapping.oldName, Function.identity(), (mapping, other) -> {
+ if (!other.oldName.equals(other.newName)) {
+ if (!mapping.oldName.equals(mapping.newName)
+ && !other.oldName.equals(mapping.oldName)
+ && !other.newName.equals(mapping.newName)) {
+ throw new IllegalArgumentException("Conflicting mappings: "
+ + mapping.oldName + " -> " + mapping.newName
+ + " and " + other.oldName + " -> " + other.newName);
+ }
+ mapping.oldName = other.oldName;
+ mapping.newName = other.newName;
+ }
+ mapping.fields.putAll(other.fields);
+ mapping.methods.putAll(other.methods);
+ return mapping;
+ }));
+ }
+
+ public String oldName;
+ public String newName;
+ public Map<String, String> fields = new HashMap<>();
+ public Map<String, String> methods = new HashMap<>();
+}
diff --git a/src/main/java/com/replaymod/gradle/remap/legacy/LegacyMappingSetModelFactory.java b/src/main/java/com/replaymod/gradle/remap/legacy/LegacyMappingSetModelFactory.java
new file mode 100644
index 0000000..eb72788
--- /dev/null
+++ b/src/main/java/com/replaymod/gradle/remap/legacy/LegacyMappingSetModelFactory.java
@@ -0,0 +1,36 @@
+package com.replaymod.gradle.remap.legacy;
+
+import org.cadixdev.bombe.type.signature.MethodSignature;
+import org.cadixdev.lorenz.MappingSet;
+import org.cadixdev.lorenz.impl.MappingSetModelFactoryImpl;
+import org.cadixdev.lorenz.impl.model.TopLevelClassMappingImpl;
+import org.cadixdev.lorenz.model.MethodMapping;
+import org.cadixdev.lorenz.model.TopLevelClassMapping;
+
+import java.util.Optional;
+
+public class LegacyMappingSetModelFactory extends MappingSetModelFactoryImpl {
+ @Override
+ public TopLevelClassMapping createTopLevelClassMapping(MappingSet parent, String obfuscatedName, String deobfuscatedName) {
+ return new TopLevelClassMappingImpl(parent, obfuscatedName, deobfuscatedName) {
+ private MethodSignature stripDesc(MethodSignature signature) {
+ // actual descriptor isn't included in legacy format
+ return MethodSignature.of(signature.getName(), "()V");
+ }
+
+ @Override
+ public boolean hasMethodMapping(MethodSignature signature) {
+ return super.hasMethodMapping(signature) || super.hasMethodMapping(stripDesc(signature));
+ }
+
+ @Override
+ public Optional<MethodMapping> getMethodMapping(MethodSignature signature) {
+ Optional<MethodMapping> maybeMapping = super.getMethodMapping(signature);
+ if (!maybeMapping.isPresent() || !maybeMapping.get().hasMappings()) {
+ maybeMapping = super.getMethodMapping(stripDesc(signature));
+ }
+ return maybeMapping;
+ }
+ };
+ }
+}
diff --git a/src/main/java/com/replaymod/gradle/remap/legacy/LegacyMappingsReader.java b/src/main/java/com/replaymod/gradle/remap/legacy/LegacyMappingsReader.java
new file mode 100644
index 0000000..502f7ba
--- /dev/null
+++ b/src/main/java/com/replaymod/gradle/remap/legacy/LegacyMappingsReader.java
@@ -0,0 +1,44 @@
+package com.replaymod.gradle.remap.legacy;
+
+import org.cadixdev.lorenz.MappingSet;
+import org.cadixdev.lorenz.io.MappingsReader;
+import org.cadixdev.lorenz.model.ClassMapping;
+
+import java.util.Map;
+
+public class LegacyMappingsReader extends MappingsReader {
+ private final Map<String, LegacyMapping> map;
+
+ public LegacyMappingsReader(Map<String, LegacyMapping> map) {
+ this.map = map;
+ }
+
+ @Override
+ public MappingSet read() {
+ return read(MappingSet.create(new LegacyMappingSetModelFactory()));
+ }
+
+ @Override
+ public MappingSet read(MappingSet mappings) {
+ if (!(mappings.getModelFactory() instanceof LegacyMappingSetModelFactory)) {
+ throw new IllegalArgumentException("legacy mappings must use legacy model factory, use read() instead");
+ }
+ for (LegacyMapping legacyMapping : map.values()) {
+ ClassMapping classMapping = mappings.getOrCreateClassMapping(legacyMapping.oldName)
+ .setDeobfuscatedName(legacyMapping.newName);
+ for (Map.Entry<String, String> entry : legacyMapping.fields.entrySet()) {
+ classMapping.getOrCreateFieldMapping(entry.getKey())
+ .setDeobfuscatedName(entry.getValue());
+ }
+ for (Map.Entry<String, String> entry : legacyMapping.methods.entrySet()) {
+ classMapping.getOrCreateMethodMapping(entry.getKey(), "()V")
+ .setDeobfuscatedName(entry.getValue());
+ }
+ }
+ return mappings;
+ }
+
+ @Override
+ public void close() {
+ }
+}