diff options
author | zaaarf <zaaarf@proton.me> | 2023-08-26 18:09:36 +0200 |
---|---|---|
committer | zaaarf <zaaarf@proton.me> | 2023-08-26 18:09:52 +0200 |
commit | 7898882bc5811e5f06e70bc2bb6925e114869a56 (patch) | |
tree | ee2f2a4f75c72f4beaead402d7cbf2ad8d71bfe0 /src/main/java/ftbsc/lll/mapper/AbstractMapper.java | |
parent | c3cc90d7743b18aaef0d22adb7292c63ef48603f (diff) |
feat: implemented abstraction logic
Diffstat (limited to 'src/main/java/ftbsc/lll/mapper/AbstractMapper.java')
-rw-r--r-- | src/main/java/ftbsc/lll/mapper/AbstractMapper.java | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/src/main/java/ftbsc/lll/mapper/AbstractMapper.java b/src/main/java/ftbsc/lll/mapper/AbstractMapper.java new file mode 100644 index 0000000..037e7c9 --- /dev/null +++ b/src/main/java/ftbsc/lll/mapper/AbstractMapper.java @@ -0,0 +1,142 @@ +package ftbsc.lll.mapper; + +import ftbsc.lll.exceptions.MalformedMappingsException; +import ftbsc.lll.exceptions.MappingNotFoundException; +import ftbsc.lll.mapper.tools.data.ClassData; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * A default implementation of {@link IMapper} meant to + * recycle as much code as possible. + */ +public abstract class AbstractMapper implements IMapper { + + /** + * A {@link Map} tying each plain class name to its class data. + */ + protected final Map<String, ClassData> mappings = new HashMap<>(); + + /** + * A {@link Map} tying each obfuscated name to its class data. + */ + protected final Map<String, ClassData> mappingsInverted = new HashMap<>(); + + /** + * 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 { + this.processLines(lines, ignoreErrors); + this.mappings.forEach((name, data) -> { + ClassData reverse = data.generateReverseMappings(this); + this.mappingsInverted.put(data.nameMapped, reverse); + }); + } + + /** + * Reads the given lines of text and attempts to interpret them as + * mappings of the given type. + * @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 + */ + protected abstract void processLines(List<String> lines, boolean ignoreErrors) throws MalformedMappingsException; + + /** + * Completely resets the mapper, clearing it of all existing mappings. + */ + @Override + public void reset() { + this.mappings.clear(); + this.mappingsInverted.clear(); + } + + /** + * Gets a name of a class from the given {@link Map}. + * @param name the name + * @param mappings the {@link Map} to pull data from + * @return the mapped name + * @throws MappingNotFoundException if no mapping is found + */ + private static String mapClass(String name, Map<String, ClassData> mappings) { + ClassData data = mappings.get(name.replace('.', '/')); + if(data == null) + throw new MappingNotFoundException("class", name); + else return data.nameMapped; + } + + /** + * 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) { + return mapClass(name, this.mappings); + } + + /** + * 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 { + return mapClass(nameObf, this.mappingsInverted); + } + + /** + * Gets the name of a member from the given {@link Map}. + * @param parentName the parent class + * @param mappings the {@link Map} to pull data from + * @param memberName the field or method name + * @param methodDescriptor the method descriptor, may be null or partial + * @return the mapped member name + * @throws MappingNotFoundException if no mapping is found + */ + private static String mapMember(String parentName, Map<String, ClassData> mappings, + String memberName, String methodDescriptor) { + ClassData data = mappings.get(parentName.replace('.', '/')); + if(data == null) + throw new MappingNotFoundException("class", parentName); + + if(methodDescriptor == null) + return data.mapField(memberName).name; + else return data.mapMethod(memberName, methodDescriptor).signature.name; + } + + /** + * Gets the obfuscated name of a class member (field or method). + * @param parentName the unobfuscated internal name of the parent class + * @param memberName the field or method name + * @param methodDescriptor the optional descriptor of the member, may be null or partial + * @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) { + return mapMember(parentName, this.mappings, memberName, methodDescriptor); + } + + /** + * 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 { + return mapMember(parentName, this.mappingsInverted, memberName, methodDescriptor); + } +} |