aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/ftbsc/lll/mapper/impl/MultiMapper.java123
-rw-r--r--src/main/java/ftbsc/lll/mapper/tools/MappingUtils.java31
-rw-r--r--src/main/java/ftbsc/lll/mapper/tools/data/ClassData.java2
3 files changed, 141 insertions, 15 deletions
diff --git a/src/main/java/ftbsc/lll/mapper/impl/MultiMapper.java b/src/main/java/ftbsc/lll/mapper/impl/MultiMapper.java
new file mode 100644
index 0000000..20cb2a5
--- /dev/null
+++ b/src/main/java/ftbsc/lll/mapper/impl/MultiMapper.java
@@ -0,0 +1,123 @@
+package ftbsc.lll.mapper.impl;
+
+import com.google.auto.service.AutoService;
+import ftbsc.lll.exceptions.MalformedMappingsException;
+import ftbsc.lll.exceptions.MappingNotFoundException;
+import ftbsc.lll.mapper.IMapper;
+import ftbsc.lll.mapper.MapperProvider;
+import ftbsc.lll.mapper.tools.MappingUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Special mapper type that actually resolves to an ordered
+ * sequence of mappers applied one after the other.
+ */
+@AutoService(IMapper.class)
+public class MultiMapper implements IMapper {
+
+ /**
+ * The list of mappers.
+ */
+ private final List<IMapper> mapperList = new ArrayList<>();
+
+ /**
+ * Checks whether this mapper can process the given lines.
+ * @param lines the lines to read
+ * @return whether this type of mapper can process these lines
+ */
+ @Override
+ public boolean claim(List<String> lines) {
+ return lines.get(0).equals("lll multimapper");
+ }
+
+ /**
+ * Populates the {@link IMapper} given the lines, ignoring errors depending on the
+ * given ignoreErrors flag.
+ * @param lines the lines to read
+ * @param ignoreErrors try to ignore errors and keep going
+ * @throws MalformedMappingsException if an error is encountered and ignoreErrors is false
+ */
+ @Override
+ public void populate(List<String> lines, boolean ignoreErrors) throws MalformedMappingsException {
+ for(int i = 1; i < lines.size(); i++) {
+ List<String> data = MapperProvider.fetchFromLocalOrRemote(lines.get(i));
+ IMapper mapper = MapperProvider.getMapper(data);
+ mapper.populate(data, ignoreErrors);
+ this.mapperList.add(mapper);
+ }
+ }
+
+ /**
+ * Completely resets the mapper, clearing it of all existing mappings.
+ */
+ @Override
+ public void reset() {
+ this.mapperList.forEach(IMapper::reset);
+ this.mapperList.clear();
+ }
+
+ /**
+ * Gets the obfuscated name of the class.
+ * @param name the plain internal name of the desired class
+ * @return the obfuscated name of the class
+ * @throws MappingNotFoundException if no mapping is found
+ */
+ @Override
+ public String obfuscateClass(String name) throws MappingNotFoundException {
+ for(IMapper mapper : this.mapperList)
+ name = mapper.obfuscateClass(name);
+ return name;
+ }
+
+ /**
+ * Gets the plain name of the class.
+ * @param nameObf the obfuscated internal name of the desired class
+ * @return the plain name of the class
+ * @throws MappingNotFoundException if no mapping is found
+ */
+ @Override
+ public String deobfuscateClass(String nameObf) throws MappingNotFoundException {
+ for(int i = this.mapperList.size() - 1; i >= 0; i--)
+ nameObf = this.mapperList.get(i).deobfuscateClass(nameObf);
+ return nameObf;
+ }
+
+ /**
+ * Gets the obfuscated name of a class member (field or method).
+ * @param parentName the plain internal name of the parent class
+ * @param memberName the field name or method signature
+ * @param methodDescriptor the descriptor of the member (only for methods)
+ * @return the obfuscated name of the given member
+ * @throws MappingNotFoundException if no mapping is found
+ */
+ @Override
+ public String obfuscateMember(String parentName, String memberName, String methodDescriptor) throws MappingNotFoundException {
+ for(IMapper mapper : this.mapperList) {
+ memberName = mapper.obfuscateMember(parentName, memberName, methodDescriptor);
+ methodDescriptor = MappingUtils.mapMethodDescriptor(methodDescriptor, mapper, false);
+ parentName = mapper.obfuscateClass(parentName);
+ }
+ return memberName;
+ }
+
+ /**
+ * Gets the plain name of a class member (field or method).
+ * @param parentName the obfuscated internal name of the parent class
+ * @param memberName the obfuscated field name or method signature
+ * @param methodDescriptor the obfuscated descriptor of the member (only for methods)
+ * @return the plain name of the given member
+ * @throws MappingNotFoundException if no mapping is found
+ */
+ @Override
+ public String deobfuscateMember(String parentName, String memberName, String methodDescriptor) throws MappingNotFoundException {
+ for(int i = this.mapperList.size() - 1; i >= 0; i--) {
+ IMapper mapper = this.mapperList.get(i);
+ memberName = mapper.deobfuscateMember(parentName, memberName, methodDescriptor);
+ methodDescriptor = MappingUtils.mapMethodDescriptor(methodDescriptor, mapper, true);
+ parentName = mapper.deobfuscateClass(parentName);
+ }
+ return memberName;
+ }
+}
diff --git a/src/main/java/ftbsc/lll/mapper/tools/MappingUtils.java b/src/main/java/ftbsc/lll/mapper/tools/MappingUtils.java
index df0b79d..c8d76af 100644
--- a/src/main/java/ftbsc/lll/mapper/tools/MappingUtils.java
+++ b/src/main/java/ftbsc/lll/mapper/tools/MappingUtils.java
@@ -10,33 +10,34 @@ import org.objectweb.asm.Type;
* mappers.
*/
public class MappingUtils {
+
/**
- * Obfuscates a method descriptor, replacing its class references
- * with their obfuscated counterparts.
+ * Maps a method descriptor, replacing its class references with their mapped counterparts.
* @param descriptor a {@link String} containing the descriptor
* @param mapper the {@link IMapper} to use for the process
- * @return the obfuscated descriptor
+ * @param reverse whether it should deobfuscate rather than obfuscate
+ * @return the mapped descriptor
*/
- public static String obfuscateMethodDescriptor(String descriptor, IMapper mapper) {
+ public static String mapMethodDescriptor(String descriptor, IMapper mapper, boolean reverse) {
Type method = Type.getMethodType(descriptor);
Type[] arguments = method.getArgumentTypes();
Type returnType = method.getReturnType();
- Type[] obfArguments = new Type[arguments.length];
- for(int i = 0; i < obfArguments.length; i++)
- obfArguments[i] = obfuscateType(arguments[i], mapper);
+ Type[] mappedArguents = new Type[arguments.length];
+ for(int i = 0; i < mappedArguents.length; i++)
+ mappedArguents[i] = mapType(arguments[i], mapper, reverse);
- return Type.getMethodDescriptor(obfuscateType(returnType, mapper), obfArguments);
+ return Type.getMethodDescriptor(mapType(returnType, mapper, reverse), mappedArguents);
}
/**
- * Given a {@link Type} and a valid {@link IMapper} it returns its obfuscated
- * counterpart.
+ * Given a {@link Type} and a valid {@link IMapper} it returns its mapped counterpart.
* @param type the type in question
* @param mapper the {@link IMapper} to use for the process
+ * @param reverse whether it should deobfuscate rather than obfuscate
* @return the obfuscated type
*/
- public static Type obfuscateType(Type type, IMapper mapper) {
+ public static Type mapType(Type type, IMapper mapper, boolean reverse) {
//unwrap arrays
Type unwrapped = type;
int arrayLevel = 0;
@@ -51,10 +52,12 @@ public class MappingUtils {
String internalName = type.getInternalName();
- String internalNameObf;
+ String internalNameMapped;
try {
- internalNameObf = mapper.obfuscateClass(internalName);
- return Type.getType(DescriptorBuilder.nameToDescriptor(internalNameObf, arrayLevel));
+ internalNameMapped = reverse
+ ? mapper.deobfuscateClass(internalName)
+ : mapper.obfuscateClass(internalName);
+ return Type.getType(DescriptorBuilder.nameToDescriptor(internalNameMapped, arrayLevel));
} catch(MappingNotFoundException e) {
return type;
}
diff --git a/src/main/java/ftbsc/lll/mapper/tools/data/ClassData.java b/src/main/java/ftbsc/lll/mapper/tools/data/ClassData.java
index 5ae4124..3b53055 100644
--- a/src/main/java/ftbsc/lll/mapper/tools/data/ClassData.java
+++ b/src/main/java/ftbsc/lll/mapper/tools/data/ClassData.java
@@ -77,7 +77,7 @@ public class ClassData {
public ClassData generateReverseMappings(IMapper mapper) {
ClassData reverse = new ClassData(this.nameMapped, this.name);
this.methods.forEach((signature, data) -> reverse.addMethod(nameMapped, signature.name,
- MappingUtils.obfuscateMethodDescriptor(signature.descriptor, mapper)));
+ MappingUtils.mapMethodDescriptor(signature.descriptor, mapper, false)));
this.fields.forEach((name, data) -> reverse.addField(data.nameMapped, name));
return reverse;
}