mirror of
https://github.com/zaaarf/lillero-mapper.git
synced 2024-11-25 22:04:48 +01:00
feat: implemented multimapper
This commit is contained in:
parent
f03bb3c932
commit
4f5394ce5a
3 changed files with 141 additions and 15 deletions
123
src/main/java/ftbsc/lll/mapper/impl/MultiMapper.java
Normal file
123
src/main/java/ftbsc/lll/mapper/impl/MultiMapper.java
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue