From 6e464ea251cab63c776ece0b2a356f1498ffa294 Mon Sep 17 00:00:00 2001 From: Thog Date: Wed, 8 Mar 2017 08:17:04 +0100 Subject: Follow Fabric guidelines --- src/main/java/cuchaz/enigma/mapping/Mappings.java | 453 +++++++++++----------- 1 file changed, 222 insertions(+), 231 deletions(-) (limited to 'src/main/java/cuchaz/enigma/mapping/Mappings.java') diff --git a/src/main/java/cuchaz/enigma/mapping/Mappings.java b/src/main/java/cuchaz/enigma/mapping/Mappings.java index d493dcf..33dd3c5 100644 --- a/src/main/java/cuchaz/enigma/mapping/Mappings.java +++ b/src/main/java/cuchaz/enigma/mapping/Mappings.java @@ -8,246 +8,237 @@ * Contributors: * Jeff Martin - initial API and implementation ******************************************************************************/ + package cuchaz.enigma.mapping; import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import cuchaz.enigma.analysis.TranslationIndex; +import cuchaz.enigma.throwables.MappingConflict; import java.io.File; import java.io.IOException; import java.util.*; -import com.google.common.collect.Sets; -import cuchaz.enigma.analysis.TranslationIndex; -import cuchaz.enigma.throwables.MappingConflict; - public class Mappings { - protected Map classesByObf; - protected Map classesByDeobf; - private final FormatType originMapping; - private Mappings previousState; - - public Mappings() - { - this(FormatType.ENIGMA_DIRECTORY); - } - - public Mappings(FormatType originMapping) { - this.originMapping = originMapping; - this.classesByObf = Maps.newHashMap(); - this.classesByDeobf = Maps.newHashMap(); - this.previousState = null; - } - - public Collection classes() { - assert (this.classesByObf.size() >= this.classesByDeobf.size()); - return this.classesByObf.values(); - } - - public void addClassMapping(ClassMapping classMapping) throws MappingConflict { - if (this.classesByObf.containsKey(classMapping.getObfFullName())) { - throw new MappingConflict("class", classMapping.getObfFullName(), this.classesByObf.get(classMapping.getObfFullName()).getObfFullName()); - } - this.classesByObf.put(classMapping.getObfFullName(), classMapping); - - if (classMapping.getDeobfName() != null) { - if (this.classesByDeobf.containsKey(classMapping.getDeobfName())) { - throw new MappingConflict("class", classMapping.getDeobfName(), this.classesByDeobf.get(classMapping.getDeobfName()).getDeobfName()); - } - this.classesByDeobf.put(classMapping.getDeobfName(), classMapping); - } - } - - public void removeClassMapping(ClassMapping classMapping) { - boolean obfWasRemoved = this.classesByObf.remove(classMapping.getObfFullName()) != null; - assert (obfWasRemoved); - if (classMapping.getDeobfName() != null) { - boolean deobfWasRemoved = this.classesByDeobf.remove(classMapping.getDeobfName()) != null; - assert (deobfWasRemoved); - } - } - - - public ClassMapping getClassByObf(ClassEntry entry) { - return getClassByObf(entry.getName()); - } - - public ClassMapping getClassByObf(String obfName) { - return this.classesByObf.get(obfName); - } - - public ClassMapping getClassByDeobf(ClassEntry entry) { - return getClassByDeobf(entry.getName()); - } - - public ClassMapping getClassByDeobf(String deobfName) { - return this.classesByDeobf.get(deobfName); - } - - public void setClassDeobfName(ClassMapping classMapping, String deobfName) { - if (classMapping.getDeobfName() != null) { - boolean wasRemoved = this.classesByDeobf.remove(classMapping.getDeobfName()) != null; - assert (wasRemoved); - } - classMapping.setDeobfName(deobfName); - if (deobfName != null) { - boolean wasAdded = this.classesByDeobf.put(deobfName, classMapping) == null; - assert (wasAdded); - } - } - - public Translator getTranslator(TranslationDirection direction, TranslationIndex index) { - switch (direction) { - case Deobfuscating: - - return new Translator(direction, this.classesByObf, index); - - case Obfuscating: - - // fill in the missing deobf class entries with obf entries - Map classes = Maps.newHashMap(); - for (ClassMapping classMapping : classes()) { - if (classMapping.getDeobfName() != null) { - classes.put(classMapping.getDeobfName(), classMapping); - } else { - classes.put(classMapping.getObfFullName(), classMapping); - } - } - - // translate the translation index - // NOTE: this isn't actually recursive - TranslationIndex deobfIndex = new TranslationIndex(index, getTranslator(TranslationDirection.Deobfuscating, index)); - - return new Translator(direction, classes, deobfIndex); - - default: - throw new Error("Invalid translation direction!"); - } - } - - @Override - public String toString() { - StringBuilder buf = new StringBuilder(); - for (ClassMapping classMapping : this.classesByObf.values()) { - buf.append(classMapping.toString()); - buf.append("\n"); - } - return buf.toString(); - } - - public void renameObfClass(String oldObfName, String newObfName) { - new ArrayList<>(classes()).stream().filter(classMapping -> classMapping.renameObfClass(oldObfName, newObfName)).forEach(classMapping -> { - boolean wasRemoved = this.classesByObf.remove(oldObfName) != null; - assert (wasRemoved); - boolean wasAdded = this.classesByObf.put(newObfName, classMapping) == null; - assert (wasAdded); - }); - } - - public Set getAllObfClassNames() { - final Set classNames = Sets.newHashSet(); - for (ClassMapping classMapping : classes()) { - - // add the class name - classNames.add(classMapping.getObfFullName()); - - // add classes from method signatures - for (MethodMapping methodMapping : classMapping.methods()) { - for (Type type : methodMapping.getObfSignature().types()) { - if (type.hasClass()) { - classNames.add(type.getClassEntry().getClassName()); - } - } - } - } - return classNames; - } - - public boolean containsDeobfClass(String deobfName) { - return this.classesByDeobf.containsKey(deobfName); - } - - public boolean containsDeobfField(ClassEntry obfClassEntry, String deobfName, Type obfType) { - ClassMapping classMapping = this.classesByObf.get(obfClassEntry.getName()); - return classMapping != null && classMapping.containsDeobfField(deobfName, obfType); - } - - public boolean containsDeobfField(ClassEntry obfClassEntry, String deobfName) { - ClassMapping classMapping = this.classesByObf.get(obfClassEntry.getName()); - if (classMapping != null) - for (FieldMapping fieldMapping : classMapping.fields()) - if (deobfName.equals(fieldMapping.getDeobfName()) || deobfName.equals(fieldMapping.getObfName())) - return true; - - return false; - } - - public boolean containsDeobfMethod(ClassEntry obfClassEntry, String deobfName, Signature obfSignature) { - ClassMapping classMapping = this.classesByObf.get(obfClassEntry.getName()); - return classMapping != null && classMapping.containsDeobfMethod(deobfName, obfSignature); - } - - public boolean containsArgument(BehaviorEntry obfBehaviorEntry, String name) { - ClassMapping classMapping = this.classesByObf.get(obfBehaviorEntry.getClassName()); - return classMapping != null && classMapping.containsArgument(obfBehaviorEntry, name); - } - - public List getClassMappingChain(ClassEntry obfClass) { - List mappingChain = Lists.newArrayList(); - ClassMapping classMapping = null; - for (ClassEntry obfClassEntry : obfClass.getClassChain()) { - if (mappingChain.isEmpty()) { - classMapping = this.classesByObf.get(obfClassEntry.getName()); - } else if (classMapping != null) { - classMapping = classMapping.getInnerClassByObfSimple(obfClassEntry.getInnermostClassName()); - } - mappingChain.add(classMapping); - } - return mappingChain; - } - - public FormatType getOriginMappingFormat() - { - return originMapping; - } - - public void savePreviousState() - { - this.previousState = new Mappings(this.originMapping); - this.previousState.classesByDeobf = Maps.newHashMap(this.classesByDeobf); - this.previousState.classesByObf = Maps.newHashMap(this.classesByObf); - classesByDeobf.values().forEach(ClassMapping::resetDirty); - classesByObf.values().forEach(ClassMapping::resetDirty); - } - - public void saveEnigmaMappings(File file, boolean isDirectoryFormat) throws IOException - { - new MappingsEnigmaWriter().write(file, this, isDirectoryFormat); - this.savePreviousState(); - } - - public void saveSRGMappings(File file) throws IOException - { - new MappingsSRGWriter().write(file, this); - } - - public Mappings getPreviousState() { - return previousState; - } - - public enum FormatType - { - ENIGMA_FILE, ENIGMA_DIRECTORY, SRG_FILE - } - - public enum EntryModifier - { - UNCHANGED, PUBLIC, PROTECTED, PRIVATE; - - public String getFormattedName() - { - return " ACC:" + super.toString(); - } - } + private final FormatType originMapping; + protected Map classesByObf; + protected Map classesByDeobf; + private Mappings previousState; + + public Mappings() { + this(FormatType.ENIGMA_DIRECTORY); + } + + public Mappings(FormatType originMapping) { + this.originMapping = originMapping; + this.classesByObf = Maps.newHashMap(); + this.classesByDeobf = Maps.newHashMap(); + this.previousState = null; + } + + public Collection classes() { + assert (this.classesByObf.size() >= this.classesByDeobf.size()); + return this.classesByObf.values(); + } + + public void addClassMapping(ClassMapping classMapping) throws MappingConflict { + if (this.classesByObf.containsKey(classMapping.getObfFullName())) { + throw new MappingConflict("class", classMapping.getObfFullName(), this.classesByObf.get(classMapping.getObfFullName()).getObfFullName()); + } + this.classesByObf.put(classMapping.getObfFullName(), classMapping); + + if (classMapping.getDeobfName() != null) { + if (this.classesByDeobf.containsKey(classMapping.getDeobfName())) { + throw new MappingConflict("class", classMapping.getDeobfName(), this.classesByDeobf.get(classMapping.getDeobfName()).getDeobfName()); + } + this.classesByDeobf.put(classMapping.getDeobfName(), classMapping); + } + } + + public void removeClassMapping(ClassMapping classMapping) { + boolean obfWasRemoved = this.classesByObf.remove(classMapping.getObfFullName()) != null; + assert (obfWasRemoved); + if (classMapping.getDeobfName() != null) { + boolean deobfWasRemoved = this.classesByDeobf.remove(classMapping.getDeobfName()) != null; + assert (deobfWasRemoved); + } + } + + public ClassMapping getClassByObf(ClassEntry entry) { + return getClassByObf(entry.getName()); + } + + public ClassMapping getClassByObf(String obfName) { + return this.classesByObf.get(obfName); + } + + public ClassMapping getClassByDeobf(ClassEntry entry) { + return getClassByDeobf(entry.getName()); + } + + public ClassMapping getClassByDeobf(String deobfName) { + return this.classesByDeobf.get(deobfName); + } + + public void setClassDeobfName(ClassMapping classMapping, String deobfName) { + if (classMapping.getDeobfName() != null) { + boolean wasRemoved = this.classesByDeobf.remove(classMapping.getDeobfName()) != null; + assert (wasRemoved); + } + classMapping.setDeobfName(deobfName); + if (deobfName != null) { + boolean wasAdded = this.classesByDeobf.put(deobfName, classMapping) == null; + assert (wasAdded); + } + } + + public Translator getTranslator(TranslationDirection direction, TranslationIndex index) { + switch (direction) { + case Deobfuscating: + + return new Translator(direction, this.classesByObf, index); + + case Obfuscating: + + // fill in the missing deobf class entries with obf entries + Map classes = Maps.newHashMap(); + for (ClassMapping classMapping : classes()) { + if (classMapping.getDeobfName() != null) { + classes.put(classMapping.getDeobfName(), classMapping); + } else { + classes.put(classMapping.getObfFullName(), classMapping); + } + } + + // translate the translation index + // NOTE: this isn't actually recursive + TranslationIndex deobfIndex = new TranslationIndex(index, getTranslator(TranslationDirection.Deobfuscating, index)); + + return new Translator(direction, classes, deobfIndex); + + default: + throw new Error("Invalid translation direction!"); + } + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder(); + for (ClassMapping classMapping : this.classesByObf.values()) { + buf.append(classMapping); + buf.append("\n"); + } + return buf.toString(); + } + + public void renameObfClass(String oldObfName, String newObfName) { + new ArrayList<>(classes()).stream().filter(classMapping -> classMapping.renameObfClass(oldObfName, newObfName)).forEach(classMapping -> { + boolean wasRemoved = this.classesByObf.remove(oldObfName) != null; + assert (wasRemoved); + boolean wasAdded = this.classesByObf.put(newObfName, classMapping) == null; + assert (wasAdded); + }); + } + + public Set getAllObfClassNames() { + final Set classNames = Sets.newHashSet(); + for (ClassMapping classMapping : classes()) { + + // add the class name + classNames.add(classMapping.getObfFullName()); + + // add classes from method signatures + for (MethodMapping methodMapping : classMapping.methods()) { + for (Type type : methodMapping.getObfSignature().types()) { + if (type.hasClass()) { + classNames.add(type.getClassEntry().getClassName()); + } + } + } + } + return classNames; + } + + public boolean containsDeobfClass(String deobfName) { + return this.classesByDeobf.containsKey(deobfName); + } + + public boolean containsDeobfField(ClassEntry obfClassEntry, String deobfName, Type obfType) { + ClassMapping classMapping = this.classesByObf.get(obfClassEntry.getName()); + return classMapping != null && classMapping.containsDeobfField(deobfName, obfType); + } + + public boolean containsDeobfField(ClassEntry obfClassEntry, String deobfName) { + ClassMapping classMapping = this.classesByObf.get(obfClassEntry.getName()); + if (classMapping != null) + for (FieldMapping fieldMapping : classMapping.fields()) + if (deobfName.equals(fieldMapping.getDeobfName()) || deobfName.equals(fieldMapping.getObfName())) + return true; + + return false; + } + + public boolean containsDeobfMethod(ClassEntry obfClassEntry, String deobfName, Signature obfSignature) { + ClassMapping classMapping = this.classesByObf.get(obfClassEntry.getName()); + return classMapping != null && classMapping.containsDeobfMethod(deobfName, obfSignature); + } + + public boolean containsArgument(BehaviorEntry obfBehaviorEntry, String name) { + ClassMapping classMapping = this.classesByObf.get(obfBehaviorEntry.getClassName()); + return classMapping != null && classMapping.containsArgument(obfBehaviorEntry, name); + } + + public List getClassMappingChain(ClassEntry obfClass) { + List mappingChain = Lists.newArrayList(); + ClassMapping classMapping = null; + for (ClassEntry obfClassEntry : obfClass.getClassChain()) { + if (mappingChain.isEmpty()) { + classMapping = this.classesByObf.get(obfClassEntry.getName()); + } else if (classMapping != null) { + classMapping = classMapping.getInnerClassByObfSimple(obfClassEntry.getInnermostClassName()); + } + mappingChain.add(classMapping); + } + return mappingChain; + } + + public FormatType getOriginMappingFormat() { + return originMapping; + } + + public void savePreviousState() { + this.previousState = new Mappings(this.originMapping); + this.previousState.classesByDeobf = Maps.newHashMap(this.classesByDeobf); + this.previousState.classesByObf = Maps.newHashMap(this.classesByObf); + classesByDeobf.values().forEach(ClassMapping::resetDirty); + classesByObf.values().forEach(ClassMapping::resetDirty); + } + + public void saveEnigmaMappings(File file, boolean isDirectoryFormat) throws IOException { + new MappingsEnigmaWriter().write(file, this, isDirectoryFormat); + this.savePreviousState(); + } + + public void saveSRGMappings(File file) throws IOException { + new MappingsSRGWriter().write(file, this); + } + + public Mappings getPreviousState() { + return previousState; + } + + public enum FormatType { + ENIGMA_FILE, ENIGMA_DIRECTORY, SRG_FILE + } + + public enum EntryModifier { + UNCHANGED, PUBLIC, PROTECTED, PRIVATE; + + public String getFormattedName() { + return " ACC:" + super.toString(); + } + } } -- cgit v1.2.3