diff options
| author | 2016-10-30 23:37:29 +0100 | |
|---|---|---|
| committer | 2016-10-30 23:37:29 +0100 | |
| commit | 6235bfc5ab85cdd471e315c52c413991fb9dbddf (patch) | |
| tree | f8d726850a60786176f999952c2e9f7c83e5ccbd | |
| parent | Fix order of packages, hanging of Enigma and classes nodes not renamed when p... (diff) | |
| download | enigma-6235bfc5ab85cdd471e315c52c413991fb9dbddf.tar.gz enigma-6235bfc5ab85cdd471e315c52c413991fb9dbddf.tar.xz enigma-6235bfc5ab85cdd471e315c52c413991fb9dbddf.zip | |
BREAKING CHANGE: Implement modifier transformer
Known Bugs:
- Inner class modifier isn't saved to mapping
- Inner class modifier isn't applied to bytecode
15 files changed, 339 insertions, 45 deletions
diff --git a/src/main/java/cuchaz/enigma/Deobfuscator.java b/src/main/java/cuchaz/enigma/Deobfuscator.java index ca387541..fe0e31dc 100644 --- a/src/main/java/cuchaz/enigma/Deobfuscator.java +++ b/src/main/java/cuchaz/enigma/Deobfuscator.java | |||
| @@ -607,4 +607,25 @@ public class Deobfuscator { | |||
| 607 | // clear caches | 607 | // clear caches |
| 608 | this.translatorCache.clear(); | 608 | this.translatorCache.clear(); |
| 609 | } | 609 | } |
| 610 | |||
| 611 | public void changeModifier(Entry entry, Mappings.EntryModifier modifierEntry) | ||
| 612 | { | ||
| 613 | Entry obfEntry = obfuscateEntry(entry); | ||
| 614 | if (obfEntry instanceof ClassEntry) | ||
| 615 | this.renamer.setClassModifier((ClassEntry) obfEntry, modifierEntry); | ||
| 616 | else if (obfEntry instanceof FieldEntry) | ||
| 617 | this.renamer.setFieldModifier((FieldEntry) obfEntry, modifierEntry); | ||
| 618 | else if (obfEntry instanceof BehaviorEntry) | ||
| 619 | this.renamer.setMethodModifier((BehaviorEntry) obfEntry, modifierEntry); | ||
| 620 | else | ||
| 621 | throw new Error("Unknown entry type: " + obfEntry); | ||
| 622 | } | ||
| 623 | |||
| 624 | public Mappings.EntryModifier getModifier(Entry obEntry) | ||
| 625 | { | ||
| 626 | Entry entry = obfuscateEntry(obEntry); | ||
| 627 | if (entry != null) | ||
| 628 | obEntry = entry; | ||
| 629 | return getTranslator(TranslationDirection.Deobfuscating).getModifier(obEntry); | ||
| 630 | } | ||
| 610 | } | 631 | } |
diff --git a/src/main/java/cuchaz/enigma/TranslatingTypeLoader.java b/src/main/java/cuchaz/enigma/TranslatingTypeLoader.java index e4c162da..73405662 100644 --- a/src/main/java/cuchaz/enigma/TranslatingTypeLoader.java +++ b/src/main/java/cuchaz/enigma/TranslatingTypeLoader.java | |||
| @@ -198,7 +198,7 @@ public class TranslatingTypeLoader implements ITypeLoader { | |||
| 198 | throws IOException, NotFoundException, CannotCompileException { | 198 | throws IOException, NotFoundException, CannotCompileException { |
| 199 | 199 | ||
| 200 | // reconstruct inner classes | 200 | // reconstruct inner classes |
| 201 | new InnerClassWriter(this.jarIndex).write(c); | 201 | new InnerClassWriter(this.jarIndex, this.deobfuscatingTranslator).write(c); |
| 202 | 202 | ||
| 203 | // re-get the javassist handle since we changed class names | 203 | // re-get the javassist handle since we changed class names |
| 204 | ClassEntry obfClassEntry = new ClassEntry(Descriptor.toJvmName(c.getName())); | 204 | ClassEntry obfClassEntry = new ClassEntry(Descriptor.toJvmName(c.getName())); |
diff --git a/src/main/java/cuchaz/enigma/bytecode/ClassRenamer.java b/src/main/java/cuchaz/enigma/bytecode/ClassRenamer.java index eb7e9a17..d49f13ab 100644 --- a/src/main/java/cuchaz/enigma/bytecode/ClassRenamer.java +++ b/src/main/java/cuchaz/enigma/bytecode/ClassRenamer.java | |||
| @@ -19,8 +19,9 @@ import java.util.Map; | |||
| 19 | 19 | ||
| 20 | import cuchaz.enigma.mapping.ClassEntry; | 20 | import cuchaz.enigma.mapping.ClassEntry; |
| 21 | import cuchaz.enigma.mapping.ClassNameReplacer; | 21 | import cuchaz.enigma.mapping.ClassNameReplacer; |
| 22 | import cuchaz.enigma.mapping.Mappings; | ||
| 22 | import cuchaz.enigma.mapping.Translator; | 23 | import cuchaz.enigma.mapping.Translator; |
| 23 | import javassist.CtClass; | 24 | import javassist.*; |
| 24 | import javassist.bytecode.*; | 25 | import javassist.bytecode.*; |
| 25 | import javassist.bytecode.SignatureAttribute.*; | 26 | import javassist.bytecode.SignatureAttribute.*; |
| 26 | 27 | ||
| @@ -70,6 +71,41 @@ public class ClassRenamer { | |||
| 70 | } | 71 | } |
| 71 | } | 72 | } |
| 72 | 73 | ||
| 74 | public static void applyModifier(Object obj, Mappings.EntryModifier modifier) | ||
| 75 | { | ||
| 76 | int mod = -1; | ||
| 77 | if (obj instanceof CtField) | ||
| 78 | mod = ((CtField) obj).getModifiers(); | ||
| 79 | else if (obj instanceof CtBehavior) | ||
| 80 | mod = ((CtBehavior) obj).getModifiers(); | ||
| 81 | else if (obj instanceof CtClass) | ||
| 82 | mod = ((CtClass) obj).getModifiers(); | ||
| 83 | |||
| 84 | if (mod != -1) | ||
| 85 | { | ||
| 86 | switch (modifier) | ||
| 87 | { | ||
| 88 | case PRIVATE: | ||
| 89 | mod = Modifier.setPrivate(mod); | ||
| 90 | break; | ||
| 91 | case PROTECTED: | ||
| 92 | mod = Modifier.setProtected(mod); | ||
| 93 | break; | ||
| 94 | case PUBLIC: | ||
| 95 | mod = Modifier.setPublic(mod); | ||
| 96 | break; | ||
| 97 | default: | ||
| 98 | break; | ||
| 99 | } | ||
| 100 | if (obj instanceof CtField) | ||
| 101 | ((CtField) obj).setModifiers(mod); | ||
| 102 | else if (obj instanceof CtBehavior) | ||
| 103 | ((CtBehavior) obj).setModifiers(mod); | ||
| 104 | else | ||
| 105 | ((CtClass) obj).setModifiers(mod); | ||
| 106 | } | ||
| 107 | } | ||
| 108 | |||
| 73 | public static void renameClasses(CtClass c, final Translator translator) { | 109 | public static void renameClasses(CtClass c, final Translator translator) { |
| 74 | renameClasses(c, className -> { | 110 | renameClasses(c, className -> { |
| 75 | ClassEntry entry = translator.translateEntry(new ClassEntry(className)); | 111 | ClassEntry entry = translator.translateEntry(new ClassEntry(className)); |
| @@ -110,6 +146,7 @@ public class ClassRenamer { | |||
| 110 | 146 | ||
| 111 | // rename the constant pool (covers ClassInfo, MethodTypeInfo, and NameAndTypeInfo) | 147 | // rename the constant pool (covers ClassInfo, MethodTypeInfo, and NameAndTypeInfo) |
| 112 | ConstPool constPool = c.getClassFile().getConstPool(); | 148 | ConstPool constPool = c.getClassFile().getConstPool(); |
| 149 | String className = constPool.getClassName(); | ||
| 113 | constPool.renameClass(map); | 150 | constPool.renameClass(map); |
| 114 | 151 | ||
| 115 | // rename class attributes | 152 | // rename class attributes |
| @@ -140,8 +177,9 @@ public class ClassRenamer { | |||
| 140 | if (attr != null) { | 177 | if (attr != null) { |
| 141 | for (int i = 0; i < attr.tableLength(); i++) { | 178 | for (int i = 0; i < attr.tableLength(); i++) { |
| 142 | 179 | ||
| 180 | String innerName = attr.innerClass(i); | ||
| 143 | // get the inner class full name (which has already been translated) | 181 | // get the inner class full name (which has already been translated) |
| 144 | ClassEntry classEntry = new ClassEntry(Descriptor.toJvmName(attr.innerClass(i))); | 182 | ClassEntry classEntry = new ClassEntry(Descriptor.toJvmName(innerName)); |
| 145 | 183 | ||
| 146 | if (attr.innerNameIndex(i) != 0) { | 184 | if (attr.innerNameIndex(i) != 0) { |
| 147 | // update the inner name | 185 | // update the inner name |
diff --git a/src/main/java/cuchaz/enigma/bytecode/ClassTranslator.java b/src/main/java/cuchaz/enigma/bytecode/ClassTranslator.java index 6c05b838..62ebfafb 100644 --- a/src/main/java/cuchaz/enigma/bytecode/ClassTranslator.java +++ b/src/main/java/cuchaz/enigma/bytecode/ClassTranslator.java | |||
| @@ -11,14 +11,9 @@ | |||
| 11 | package cuchaz.enigma.bytecode; | 11 | package cuchaz.enigma.bytecode; |
| 12 | 12 | ||
| 13 | import cuchaz.enigma.mapping.*; | 13 | import cuchaz.enigma.mapping.*; |
| 14 | import javassist.CtBehavior; | 14 | import cuchaz.enigma.mapping.Translator; |
| 15 | import javassist.CtClass; | 15 | import javassist.*; |
| 16 | import javassist.CtField; | 16 | import javassist.bytecode.*; |
| 17 | import javassist.CtMethod; | ||
| 18 | import javassist.bytecode.ConstPool; | ||
| 19 | import javassist.bytecode.Descriptor; | ||
| 20 | import javassist.bytecode.EnclosingMethodAttribute; | ||
| 21 | import javassist.bytecode.SourceFileAttribute; | ||
| 22 | 17 | ||
| 23 | public class ClassTranslator { | 18 | public class ClassTranslator { |
| 24 | 19 | ||
| @@ -74,6 +69,9 @@ public class ClassTranslator { | |||
| 74 | } | 69 | } |
| 75 | 70 | ||
| 76 | ClassEntry classEntry = new ClassEntry(Descriptor.toJvmName(c.getName())); | 71 | ClassEntry classEntry = new ClassEntry(Descriptor.toJvmName(c.getName())); |
| 72 | Mappings.EntryModifier modifier = this.translator.getModifier(classEntry); | ||
| 73 | if (modifier != null && modifier != Mappings.EntryModifier.UNCHANGED) | ||
| 74 | ClassRenamer.applyModifier(c, modifier); | ||
| 77 | 75 | ||
| 78 | // translate all the fields | 76 | // translate all the fields |
| 79 | for (CtField field : c.getDeclaredFields()) { | 77 | for (CtField field : c.getDeclaredFields()) { |
| @@ -81,6 +79,10 @@ public class ClassTranslator { | |||
| 81 | // translate the name | 79 | // translate the name |
| 82 | FieldEntry entry = EntryFactory.getFieldEntry(field); | 80 | FieldEntry entry = EntryFactory.getFieldEntry(field); |
| 83 | String translatedName = this.translator.translate(entry); | 81 | String translatedName = this.translator.translate(entry); |
| 82 | modifier = this.translator.getModifier(entry); | ||
| 83 | if (modifier != null && modifier != Mappings.EntryModifier.UNCHANGED) | ||
| 84 | ClassRenamer.applyModifier(field, modifier); | ||
| 85 | |||
| 84 | if (translatedName != null) { | 86 | if (translatedName != null) { |
| 85 | field.setName(translatedName); | 87 | field.setName(translatedName); |
| 86 | } | 88 | } |
| @@ -95,6 +97,10 @@ public class ClassTranslator { | |||
| 95 | 97 | ||
| 96 | BehaviorEntry entry = EntryFactory.getBehaviorEntry(behavior); | 98 | BehaviorEntry entry = EntryFactory.getBehaviorEntry(behavior); |
| 97 | 99 | ||
| 100 | modifier = this.translator.getModifier(entry); | ||
| 101 | if (modifier != null && modifier != Mappings.EntryModifier.UNCHANGED) | ||
| 102 | ClassRenamer.applyModifier(behavior, modifier); | ||
| 103 | |||
| 98 | if (behavior instanceof CtMethod) { | 104 | if (behavior instanceof CtMethod) { |
| 99 | CtMethod method = (CtMethod) behavior; | 105 | CtMethod method = (CtMethod) behavior; |
| 100 | 106 | ||
| @@ -149,5 +155,8 @@ public class ClassTranslator { | |||
| 149 | String sourceFile = Descriptor.toJvmName(deobfClassEntry.getOutermostClassEntry().getSimpleName()) + ".java"; | 155 | String sourceFile = Descriptor.toJvmName(deobfClassEntry.getOutermostClassEntry().getSimpleName()) + ".java"; |
| 150 | c.getClassFile().addAttribute(new SourceFileAttribute(constants, sourceFile)); | 156 | c.getClassFile().addAttribute(new SourceFileAttribute(constants, sourceFile)); |
| 151 | } | 157 | } |
| 158 | InnerClassesAttribute attr = (InnerClassesAttribute) c.getClassFile().getAttribute(InnerClassesAttribute.tag); | ||
| 159 | if (attr != null) | ||
| 160 | InnerClassWriter.changeModifier(c, attr, translator); | ||
| 152 | } | 161 | } |
| 153 | } | 162 | } |
diff --git a/src/main/java/cuchaz/enigma/bytecode/InnerClassWriter.java b/src/main/java/cuchaz/enigma/bytecode/InnerClassWriter.java index 6d926106..6e2a29d5 100644 --- a/src/main/java/cuchaz/enigma/bytecode/InnerClassWriter.java +++ b/src/main/java/cuchaz/enigma/bytecode/InnerClassWriter.java | |||
| @@ -15,22 +15,22 @@ import com.google.common.collect.Lists; | |||
| 15 | import java.util.Collection; | 15 | import java.util.Collection; |
| 16 | import java.util.List; | 16 | import java.util.List; |
| 17 | 17 | ||
| 18 | import cuchaz.enigma.Deobfuscator; | ||
| 18 | import cuchaz.enigma.analysis.JarIndex; | 19 | import cuchaz.enigma.analysis.JarIndex; |
| 19 | import cuchaz.enigma.mapping.BehaviorEntry; | 20 | import cuchaz.enigma.mapping.*; |
| 20 | import cuchaz.enigma.mapping.ClassEntry; | 21 | import javassist.ClassPool; |
| 21 | import cuchaz.enigma.mapping.EntryFactory; | ||
| 22 | import javassist.CtClass; | 22 | import javassist.CtClass; |
| 23 | import javassist.bytecode.AccessFlag; | 23 | import javassist.NotFoundException; |
| 24 | import javassist.bytecode.ConstPool; | 24 | import javassist.bytecode.*; |
| 25 | import javassist.bytecode.EnclosingMethodAttribute; | ||
| 26 | import javassist.bytecode.InnerClassesAttribute; | ||
| 27 | 25 | ||
| 28 | public class InnerClassWriter { | 26 | public class InnerClassWriter { |
| 29 | 27 | ||
| 30 | private JarIndex index; | 28 | private JarIndex index; |
| 29 | private Translator deobfuscatorTranslator; | ||
| 31 | 30 | ||
| 32 | public InnerClassWriter(JarIndex index) { | 31 | public InnerClassWriter(JarIndex index, Translator deobfuscatorTranslator) { |
| 33 | this.index = index; | 32 | this.index = index; |
| 33 | this.deobfuscatorTranslator = deobfuscatorTranslator; | ||
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | public void write(CtClass c) { | 36 | public void write(CtClass c) { |
| @@ -96,6 +96,29 @@ public class InnerClassWriter { | |||
| 96 | } | 96 | } |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | // FIXME: modiffier is not applied to inner class | ||
| 100 | public static void changeModifier(CtClass c, InnerClassesAttribute attr, Translator translator) | ||
| 101 | { | ||
| 102 | ClassPool pool = c.getClassPool(); | ||
| 103 | for (int i = 0; i < attr.tableLength(); i++) { | ||
| 104 | |||
| 105 | String innerName = attr.innerClass(i); | ||
| 106 | // get the inner class full name (which has already been translated) | ||
| 107 | ClassEntry classEntry = new ClassEntry(Descriptor.toJvmName(innerName)); | ||
| 108 | try | ||
| 109 | { | ||
| 110 | CtClass innerClass = pool.get(innerName); | ||
| 111 | Mappings.EntryModifier modifier = translator.getModifier(classEntry); | ||
| 112 | if (modifier != null && modifier != Mappings.EntryModifier.UNCHANGED) | ||
| 113 | ClassRenamer.applyModifier(innerClass, modifier); | ||
| 114 | } catch (NotFoundException e) | ||
| 115 | { | ||
| 116 | // This shouldn't be possible in theory | ||
| 117 | //e.printStackTrace(); | ||
| 118 | } | ||
| 119 | } | ||
| 120 | } | ||
| 121 | |||
| 99 | private void writeInnerClass(InnerClassesAttribute attr, List<ClassEntry> obfClassChain, ClassEntry obfClassEntry) { | 122 | private void writeInnerClass(InnerClassesAttribute attr, List<ClassEntry> obfClassChain, ClassEntry obfClassEntry) { |
| 100 | 123 | ||
| 101 | // get the new inner class name | 124 | // get the new inner class name |
diff --git a/src/main/java/cuchaz/enigma/gui/Gui.java b/src/main/java/cuchaz/enigma/gui/Gui.java index 6d9ea1df..ed18777a 100644 --- a/src/main/java/cuchaz/enigma/gui/Gui.java +++ b/src/main/java/cuchaz/enigma/gui/Gui.java | |||
| @@ -461,24 +461,29 @@ public class Gui { | |||
| 461 | 461 | ||
| 462 | private void showClassEntry(ClassEntry entry) { | 462 | private void showClassEntry(ClassEntry entry) { |
| 463 | addNameValue(m_infoPanel, "Class", entry.getName()); | 463 | addNameValue(m_infoPanel, "Class", entry.getName()); |
| 464 | addModifierComboBox(m_infoPanel, "Modifier", entry); | ||
| 464 | } | 465 | } |
| 465 | 466 | ||
| 466 | private void showFieldEntry(FieldEntry entry) { | 467 | private void showFieldEntry(FieldEntry entry) { |
| 467 | addNameValue(m_infoPanel, "Field", entry.getName()); | 468 | addNameValue(m_infoPanel, "Field", entry.getName()); |
| 468 | addNameValue(m_infoPanel, "Class", entry.getClassEntry().getName()); | 469 | addNameValue(m_infoPanel, "Class", entry.getClassEntry().getName()); |
| 469 | addNameValue(m_infoPanel, "Type", entry.getType().toString()); | 470 | addNameValue(m_infoPanel, "Type", entry.getType().toString()); |
| 471 | addModifierComboBox(m_infoPanel, "Modifier", entry); | ||
| 470 | } | 472 | } |
| 471 | 473 | ||
| 472 | private void showMethodEntry(MethodEntry entry) { | 474 | private void showMethodEntry(MethodEntry entry) { |
| 473 | addNameValue(m_infoPanel, "Method", entry.getName()); | 475 | addNameValue(m_infoPanel, "Method", entry.getName()); |
| 474 | addNameValue(m_infoPanel, "Class", entry.getClassEntry().getName()); | 476 | addNameValue(m_infoPanel, "Class", entry.getClassEntry().getName()); |
| 475 | addNameValue(m_infoPanel, "Signature", entry.getSignature().toString()); | 477 | addNameValue(m_infoPanel, "Signature", entry.getSignature().toString()); |
| 478 | addModifierComboBox(m_infoPanel, "Modifier", entry); | ||
| 479 | |||
| 476 | } | 480 | } |
| 477 | 481 | ||
| 478 | private void showConstructorEntry(ConstructorEntry entry) { | 482 | private void showConstructorEntry(ConstructorEntry entry) { |
| 479 | addNameValue(m_infoPanel, "Constructor", entry.getClassEntry().getName()); | 483 | addNameValue(m_infoPanel, "Constructor", entry.getClassEntry().getName()); |
| 480 | if (!entry.isStatic()) { | 484 | if (!entry.isStatic()) { |
| 481 | addNameValue(m_infoPanel, "Signature", entry.getSignature().toString()); | 485 | addNameValue(m_infoPanel, "Signature", entry.getSignature().toString()); |
| 486 | addModifierComboBox(m_infoPanel, "Modifier", entry); | ||
| 482 | } | 487 | } |
| 483 | } | 488 | } |
| 484 | 489 | ||
| @@ -501,6 +506,25 @@ public class Gui { | |||
| 501 | panel.add(Utils.unboldLabel(new JLabel(value, JLabel.LEFT))); | 506 | panel.add(Utils.unboldLabel(new JLabel(value, JLabel.LEFT))); |
| 502 | } | 507 | } |
| 503 | 508 | ||
| 509 | private JComboBox<Mappings.EntryModifier> addModifierComboBox(JPanel container, String name, Entry entry) | ||
| 510 | { | ||
| 511 | if (!getController().entryIsInJar(entry)) | ||
| 512 | return null; | ||
| 513 | JPanel panel = new JPanel(); | ||
| 514 | panel.setLayout(new FlowLayout(FlowLayout.LEFT, 6, 0)); | ||
| 515 | container.add(panel); | ||
| 516 | JLabel label = new JLabel(name + ":", JLabel.RIGHT); | ||
| 517 | label.setPreferredSize(new Dimension(100, label.getPreferredSize().height)); | ||
| 518 | panel.add(label); | ||
| 519 | JComboBox<Mappings.EntryModifier> combo = new JComboBox<>(Mappings.EntryModifier.values()); | ||
| 520 | ((JLabel)combo.getRenderer()).setHorizontalAlignment(JLabel.LEFT); | ||
| 521 | combo.setPreferredSize(new Dimension(100, label.getPreferredSize().height)); | ||
| 522 | combo.setSelectedIndex(getController().getDeobfuscator().getModifier(entry).ordinal()); | ||
| 523 | combo.addItemListener(getController()::modifierChange); | ||
| 524 | panel.add(combo); | ||
| 525 | return combo; | ||
| 526 | } | ||
| 527 | |||
| 504 | public void onCaretMove(int pos) { | 528 | public void onCaretMove(int pos) { |
| 505 | 529 | ||
| 506 | Token token = this.controller.getToken(pos); | 530 | Token token = this.controller.getToken(pos); |
diff --git a/src/main/java/cuchaz/enigma/gui/GuiController.java b/src/main/java/cuchaz/enigma/gui/GuiController.java index 70fb4cf2..c2e202e2 100644 --- a/src/main/java/cuchaz/enigma/gui/GuiController.java +++ b/src/main/java/cuchaz/enigma/gui/GuiController.java | |||
| @@ -20,6 +20,7 @@ import cuchaz.enigma.mapping.*; | |||
| 20 | import cuchaz.enigma.throwables.MappingParseException; | 20 | import cuchaz.enigma.throwables.MappingParseException; |
| 21 | import cuchaz.enigma.utils.ReadableToken; | 21 | import cuchaz.enigma.utils.ReadableToken; |
| 22 | 22 | ||
| 23 | import java.awt.event.ItemEvent; | ||
| 23 | import java.io.File; | 24 | import java.io.File; |
| 24 | import java.io.IOException; | 25 | import java.io.IOException; |
| 25 | import java.util.Collection; | 26 | import java.util.Collection; |
| @@ -338,4 +339,19 @@ public class GuiController { | |||
| 338 | } | 339 | } |
| 339 | }.start(); | 340 | }.start(); |
| 340 | } | 341 | } |
| 342 | |||
| 343 | public Deobfuscator getDeobfuscator() | ||
| 344 | { | ||
| 345 | return deobfuscator; | ||
| 346 | } | ||
| 347 | |||
| 348 | public void modifierChange(ItemEvent event) | ||
| 349 | { | ||
| 350 | if (event.getStateChange() == ItemEvent.SELECTED) | ||
| 351 | { | ||
| 352 | deobfuscator.changeModifier(gui.m_reference.entry, (Mappings.EntryModifier) event.getItem()); | ||
| 353 | this.isDirty = true; | ||
| 354 | refreshCurrentClass(); | ||
| 355 | } | ||
| 356 | } | ||
| 341 | } | 357 | } |
diff --git a/src/main/java/cuchaz/enigma/mapping/ClassMapping.java b/src/main/java/cuchaz/enigma/mapping/ClassMapping.java index 923c8ece..017a5b9f 100644 --- a/src/main/java/cuchaz/enigma/mapping/ClassMapping.java +++ b/src/main/java/cuchaz/enigma/mapping/ClassMapping.java | |||
| @@ -30,12 +30,20 @@ public class ClassMapping implements Comparable<ClassMapping> { | |||
| 30 | private Map<String, MethodMapping> m_methodsByObf; | 30 | private Map<String, MethodMapping> m_methodsByObf; |
| 31 | private Map<String, MethodMapping> m_methodsByDeobf; | 31 | private Map<String, MethodMapping> m_methodsByDeobf; |
| 32 | private boolean isDirty; | 32 | private boolean isDirty; |
| 33 | private Mappings.EntryModifier modifier; | ||
| 33 | 34 | ||
| 34 | public ClassMapping(String obfFullName) { | 35 | public ClassMapping(String obfFullName) |
| 35 | this(obfFullName, null); | 36 | { |
| 37 | this(obfFullName, null, Mappings.EntryModifier.UNCHANGED); | ||
| 36 | } | 38 | } |
| 37 | 39 | ||
| 38 | public ClassMapping(String obfFullName, String deobfName) { | 40 | public ClassMapping(String obfFullName, String deobfName) |
| 41 | { | ||
| 42 | this(obfFullName, deobfName, Mappings.EntryModifier.UNCHANGED); | ||
| 43 | } | ||
| 44 | |||
| 45 | public ClassMapping(String obfFullName, String deobfName, Mappings.EntryModifier modifier) | ||
| 46 | { | ||
| 39 | m_obfFullName = obfFullName; | 47 | m_obfFullName = obfFullName; |
| 40 | ClassEntry classEntry = new ClassEntry(obfFullName); | 48 | ClassEntry classEntry = new ClassEntry(obfFullName); |
| 41 | m_obfSimpleName = classEntry.isInnerClass() ? classEntry.getInnermostClassName() : classEntry.getSimpleName(); | 49 | m_obfSimpleName = classEntry.isInnerClass() ? classEntry.getInnermostClassName() : classEntry.getSimpleName(); |
| @@ -48,6 +56,7 @@ public class ClassMapping implements Comparable<ClassMapping> { | |||
| 48 | m_methodsByObf = Maps.newHashMap(); | 56 | m_methodsByObf = Maps.newHashMap(); |
| 49 | m_methodsByDeobf = Maps.newHashMap(); | 57 | m_methodsByDeobf = Maps.newHashMap(); |
| 50 | isDirty = true; | 58 | isDirty = true; |
| 59 | this.modifier = modifier; | ||
| 51 | } | 60 | } |
| 52 | 61 | ||
| 53 | public String getObfFullName() { | 62 | public String getObfFullName() { |
| @@ -186,15 +195,16 @@ public class ClassMapping implements Comparable<ClassMapping> { | |||
| 186 | if (m_fieldsByObf.containsKey(obfKey)) { | 195 | if (m_fieldsByObf.containsKey(obfKey)) { |
| 187 | throw new Error("Already have mapping for " + m_obfFullName + "." + obfKey); | 196 | throw new Error("Already have mapping for " + m_obfFullName + "." + obfKey); |
| 188 | } | 197 | } |
| 189 | String deobfKey = getFieldKey(fieldMapping.getDeobfName(), fieldMapping.getObfType()); | 198 | if (fieldMapping.getDeobfName() != null) { |
| 190 | if (m_fieldsByDeobf.containsKey(deobfKey)) { | 199 | String deobfKey = getFieldKey(fieldMapping.getDeobfName(), fieldMapping.getObfType()); |
| 191 | throw new Error("Already have mapping for " + m_deobfName + "." + deobfKey); | 200 | if (m_fieldsByDeobf.containsKey(deobfKey)) { |
| 201 | throw new Error("Already have mapping for " + m_deobfName + "." + deobfKey); | ||
| 202 | } | ||
| 203 | boolean deobfWasAdded = m_fieldsByDeobf.put(deobfKey, fieldMapping) == null; | ||
| 204 | assert (deobfWasAdded); | ||
| 192 | } | 205 | } |
| 193 | boolean obfWasAdded = m_fieldsByObf.put(obfKey, fieldMapping) == null; | 206 | boolean obfWasAdded = m_fieldsByObf.put(obfKey, fieldMapping) == null; |
| 194 | assert (obfWasAdded); | 207 | assert (obfWasAdded); |
| 195 | boolean deobfWasAdded = m_fieldsByDeobf.put(deobfKey, fieldMapping) == null; | ||
| 196 | assert (deobfWasAdded); | ||
| 197 | assert (m_fieldsByObf.size() == m_fieldsByDeobf.size()); | ||
| 198 | this.isDirty = true; | 208 | this.isDirty = true; |
| 199 | } | 209 | } |
| 200 | 210 | ||
| @@ -242,12 +252,11 @@ public class ClassMapping implements Comparable<ClassMapping> { | |||
| 242 | return name + ":" + type; | 252 | return name + ":" + type; |
| 243 | } | 253 | } |
| 244 | 254 | ||
| 245 | |||
| 246 | public void setFieldName(String obfName, Type obfType, String deobfName) { | 255 | public void setFieldName(String obfName, Type obfType, String deobfName) { |
| 247 | assert (deobfName != null); | 256 | assert (deobfName != null); |
| 248 | FieldMapping fieldMapping = m_fieldsByObf.get(getFieldKey(obfName, obfType)); | 257 | FieldMapping fieldMapping = m_fieldsByObf.get(getFieldKey(obfName, obfType)); |
| 249 | if (fieldMapping == null) { | 258 | if (fieldMapping == null) { |
| 250 | fieldMapping = new FieldMapping(obfName, obfType, deobfName); | 259 | fieldMapping = new FieldMapping(obfName, obfType, deobfName, Mappings.EntryModifier.UNCHANGED); |
| 251 | boolean obfWasAdded = m_fieldsByObf.put(getFieldKey(obfName, obfType), fieldMapping) == null; | 260 | boolean obfWasAdded = m_fieldsByObf.put(getFieldKey(obfName, obfType), fieldMapping) == null; |
| 252 | assert (obfWasAdded); | 261 | assert (obfWasAdded); |
| 253 | } else { | 262 | } else { |
| @@ -492,4 +501,44 @@ public class ClassMapping implements Comparable<ClassMapping> { | |||
| 492 | { | 501 | { |
| 493 | this.isDirty = false; | 502 | this.isDirty = false; |
| 494 | } | 503 | } |
| 504 | |||
| 505 | public void setModifier(Mappings.EntryModifier modifier) | ||
| 506 | { | ||
| 507 | if (this.modifier != modifier) | ||
| 508 | this.isDirty = true; | ||
| 509 | this.modifier = modifier; | ||
| 510 | } | ||
| 511 | |||
| 512 | public Mappings.EntryModifier getModifier() | ||
| 513 | { | ||
| 514 | return modifier; | ||
| 515 | } | ||
| 516 | |||
| 517 | public void setFieldModifier(String obfName, Type obfType, Mappings.EntryModifier modifier) { | ||
| 518 | FieldMapping fieldMapping = m_fieldsByObf.get(getFieldKey(obfName, obfType)); | ||
| 519 | if (fieldMapping == null) { | ||
| 520 | fieldMapping = new FieldMapping(obfName, obfType, null, Mappings.EntryModifier.UNCHANGED); | ||
| 521 | m_fieldsByObf.put(getFieldKey(obfName, obfType), fieldMapping); | ||
| 522 | } | ||
| 523 | |||
| 524 | if (fieldMapping.getModifier() != modifier) | ||
| 525 | { | ||
| 526 | fieldMapping.setModifier(modifier); | ||
| 527 | this.isDirty = true; | ||
| 528 | } | ||
| 529 | } | ||
| 530 | |||
| 531 | public void setMethodModifier(String obfName, Signature sig, Mappings.EntryModifier modifier) { | ||
| 532 | MethodMapping methodMapping = m_methodsByObf.get(getMethodKey(obfName, sig)); | ||
| 533 | if (methodMapping == null) { | ||
| 534 | methodMapping = new MethodMapping(obfName, sig, null, Mappings.EntryModifier.UNCHANGED); | ||
| 535 | m_methodsByObf.put(getMethodKey(obfName, sig), methodMapping); | ||
| 536 | } | ||
| 537 | |||
| 538 | if (methodMapping.getModifier() != modifier) | ||
| 539 | { | ||
| 540 | methodMapping.setModifier(modifier); | ||
| 541 | this.isDirty = true; | ||
| 542 | } | ||
| 543 | } | ||
| 495 | } | 544 | } |
diff --git a/src/main/java/cuchaz/enigma/mapping/FieldMapping.java b/src/main/java/cuchaz/enigma/mapping/FieldMapping.java index 1b596606..e75485cd 100644 --- a/src/main/java/cuchaz/enigma/mapping/FieldMapping.java +++ b/src/main/java/cuchaz/enigma/mapping/FieldMapping.java | |||
| @@ -15,16 +15,19 @@ public class FieldMapping implements Comparable<FieldMapping>, MemberMapping<Fie | |||
| 15 | private String obfName; | 15 | private String obfName; |
| 16 | private String deobfName; | 16 | private String deobfName; |
| 17 | private Type obfType; | 17 | private Type obfType; |
| 18 | private Mappings.EntryModifier modifier; | ||
| 18 | 19 | ||
| 19 | public FieldMapping(String obfName, Type obfType, String deobfName) { | 20 | public FieldMapping(String obfName, Type obfType, String deobfName, Mappings.EntryModifier modifier) { |
| 20 | this.obfName = obfName; | 21 | this.obfName = obfName; |
| 21 | this.deobfName = NameValidator.validateFieldName(deobfName); | 22 | this.deobfName = NameValidator.validateFieldName(deobfName); |
| 22 | this.obfType = obfType; | 23 | this.obfType = obfType; |
| 24 | this.modifier = modifier; | ||
| 23 | } | 25 | } |
| 24 | 26 | ||
| 25 | public FieldMapping(FieldMapping other, ClassNameReplacer obfClassNameReplacer) { | 27 | public FieldMapping(FieldMapping other, ClassNameReplacer obfClassNameReplacer) { |
| 26 | this.obfName = other.obfName; | 28 | this.obfName = other.obfName; |
| 27 | this.deobfName = other.deobfName; | 29 | this.deobfName = other.deobfName; |
| 30 | this.modifier = other.modifier; | ||
| 28 | this.obfType = new Type(other.obfType, obfClassNameReplacer); | 31 | this.obfType = new Type(other.obfType, obfClassNameReplacer); |
| 29 | } | 32 | } |
| 30 | 33 | ||
| @@ -58,6 +61,16 @@ public class FieldMapping implements Comparable<FieldMapping>, MemberMapping<Fie | |||
| 58 | this.obfType = val; | 61 | this.obfType = val; |
| 59 | } | 62 | } |
| 60 | 63 | ||
| 64 | public void setModifier(Mappings.EntryModifier modifier) | ||
| 65 | { | ||
| 66 | this.modifier = modifier; | ||
| 67 | } | ||
| 68 | |||
| 69 | public Mappings.EntryModifier getModifier() | ||
| 70 | { | ||
| 71 | return modifier; | ||
| 72 | } | ||
| 73 | |||
| 61 | @Override | 74 | @Override |
| 62 | public int compareTo(FieldMapping other) { | 75 | public int compareTo(FieldMapping other) { |
| 63 | return (this.obfName + this.obfType).compareTo(other.obfName + other.obfType); | 76 | return (this.obfName + this.obfType).compareTo(other.obfName + other.obfType); |
diff --git a/src/main/java/cuchaz/enigma/mapping/Mappings.java b/src/main/java/cuchaz/enigma/mapping/Mappings.java index 2166bb9f..d493dcfa 100644 --- a/src/main/java/cuchaz/enigma/mapping/Mappings.java +++ b/src/main/java/cuchaz/enigma/mapping/Mappings.java | |||
| @@ -240,4 +240,14 @@ public class Mappings { | |||
| 240 | { | 240 | { |
| 241 | ENIGMA_FILE, ENIGMA_DIRECTORY, SRG_FILE | 241 | ENIGMA_FILE, ENIGMA_DIRECTORY, SRG_FILE |
| 242 | } | 242 | } |
| 243 | |||
| 244 | public enum EntryModifier | ||
| 245 | { | ||
| 246 | UNCHANGED, PUBLIC, PROTECTED, PRIVATE; | ||
| 247 | |||
| 248 | public String getFormattedName() | ||
| 249 | { | ||
| 250 | return " ACC:" + super.toString(); | ||
| 251 | } | ||
| 252 | } | ||
| 243 | } | 253 | } |
diff --git a/src/main/java/cuchaz/enigma/mapping/MappingsEnigmaReader.java b/src/main/java/cuchaz/enigma/mapping/MappingsEnigmaReader.java index 93276a63..cdfed726 100644 --- a/src/main/java/cuchaz/enigma/mapping/MappingsEnigmaReader.java +++ b/src/main/java/cuchaz/enigma/mapping/MappingsEnigmaReader.java | |||
| @@ -135,21 +135,51 @@ public class MappingsEnigmaReader | |||
| 135 | private ClassMapping readClass(String[] parts, boolean makeSimple) { | 135 | private ClassMapping readClass(String[] parts, boolean makeSimple) { |
| 136 | if (parts.length == 2) { | 136 | if (parts.length == 2) { |
| 137 | return new ClassMapping(parts[1]); | 137 | return new ClassMapping(parts[1]); |
| 138 | } else { | 138 | } else if (parts.length == 3) { |
| 139 | return new ClassMapping(parts[1], parts[2]); | 139 | boolean access = parts[2].startsWith("ACC:"); |
| 140 | } | 140 | ClassMapping mapping; |
| 141 | if (access) | ||
| 142 | mapping = new ClassMapping(parts[1], null, Mappings.EntryModifier.valueOf(parts[2].substring(4))); | ||
| 143 | else | ||
| 144 | mapping = new ClassMapping(parts[1], parts[2]); | ||
| 145 | |||
| 146 | return mapping; | ||
| 147 | } else if (parts.length == 4) | ||
| 148 | return new ClassMapping(parts[1], parts[2], Mappings.EntryModifier.valueOf(parts[3].substring(4))); | ||
| 149 | return null; | ||
| 141 | } | 150 | } |
| 142 | 151 | ||
| 143 | /* TEMP */ | 152 | /* TEMP */ |
| 144 | protected FieldMapping readField(String[] parts) { | 153 | protected FieldMapping readField(String[] parts) { |
| 145 | return new FieldMapping(parts[1], new Type(parts[3]), parts[2]); | 154 | FieldMapping mapping = null; |
| 155 | if (parts.length == 4) | ||
| 156 | { | ||
| 157 | boolean access = parts[3].startsWith("ACC:"); | ||
| 158 | if (access) | ||
| 159 | mapping = new FieldMapping(parts[1], new Type(parts[2]), null, | ||
| 160 | Mappings.EntryModifier.valueOf(parts[3].substring(4))); | ||
| 161 | else | ||
| 162 | mapping = new FieldMapping(parts[1], new Type(parts[3]), parts[2], Mappings.EntryModifier.UNCHANGED); | ||
| 163 | } | ||
| 164 | else if (parts.length == 5) | ||
| 165 | mapping = new FieldMapping(parts[1], new Type(parts[3]), parts[2], Mappings.EntryModifier.valueOf(parts[4].substring(4))); | ||
| 166 | return mapping; | ||
| 146 | } | 167 | } |
| 147 | 168 | ||
| 148 | private MethodMapping readMethod(String[] parts) { | 169 | private MethodMapping readMethod(String[] parts) { |
| 149 | if (parts.length == 3) { | 170 | MethodMapping mapping = null; |
| 150 | return new MethodMapping(parts[1], new Signature(parts[2])); | 171 | if (parts.length == 3) |
| 151 | } else { | 172 | mapping = new MethodMapping(parts[1], new Signature(parts[2])); |
| 152 | return new MethodMapping(parts[1], new Signature(parts[3]), parts[2]); | 173 | else if (parts.length == 4){ |
| 174 | boolean access = parts[3].startsWith("ACC:"); | ||
| 175 | if (access) | ||
| 176 | mapping = new MethodMapping(parts[1], new Signature(parts[2]), null, Mappings.EntryModifier.valueOf(parts[3].substring(4))); | ||
| 177 | else | ||
| 178 | mapping = new MethodMapping(parts[1], new Signature(parts[3]), parts[2]); | ||
| 153 | } | 179 | } |
| 180 | else if (parts.length == 5) | ||
| 181 | mapping = new MethodMapping(parts[1], new Signature(parts[3]), parts[2], | ||
| 182 | Mappings.EntryModifier.valueOf(parts[4].substring(4))); | ||
| 183 | return mapping; | ||
| 154 | } | 184 | } |
| 155 | } | 185 | } |
diff --git a/src/main/java/cuchaz/enigma/mapping/MappingsEnigmaWriter.java b/src/main/java/cuchaz/enigma/mapping/MappingsEnigmaWriter.java index e1763d0a..95896898 100644 --- a/src/main/java/cuchaz/enigma/mapping/MappingsEnigmaWriter.java +++ b/src/main/java/cuchaz/enigma/mapping/MappingsEnigmaWriter.java | |||
| @@ -110,9 +110,9 @@ public class MappingsEnigmaWriter { | |||
| 110 | 110 | ||
| 111 | private void write(PrintWriter out, ClassMapping classMapping, int depth) throws IOException { | 111 | private void write(PrintWriter out, ClassMapping classMapping, int depth) throws IOException { |
| 112 | if (classMapping.getDeobfName() == null) { | 112 | if (classMapping.getDeobfName() == null) { |
| 113 | out.format("%sCLASS %s\n", getIndent(depth), classMapping.getObfFullName()); | 113 | out.format("%sCLASS %s%s\n", getIndent(depth), classMapping.getObfFullName(), classMapping.getModifier() == Mappings.EntryModifier.UNCHANGED ? "" : classMapping.getModifier().getFormattedName()); |
| 114 | } else { | 114 | } else { |
| 115 | out.format("%sCLASS %s %s\n", getIndent(depth), classMapping.getObfFullName(), classMapping.getDeobfName()); | 115 | out.format("%sCLASS %s %s%s\n", getIndent(depth), classMapping.getObfFullName(), classMapping.getDeobfName(), classMapping.getModifier() == Mappings.EntryModifier.UNCHANGED ? "" : classMapping.getModifier().getFormattedName()); |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | for (ClassMapping innerClassMapping : sorted(classMapping.innerClasses())) { | 118 | for (ClassMapping innerClassMapping : sorted(classMapping.innerClasses())) { |
| @@ -129,14 +129,17 @@ public class MappingsEnigmaWriter { | |||
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | private void write(PrintWriter out, FieldMapping fieldMapping, int depth) throws IOException { | 131 | private void write(PrintWriter out, FieldMapping fieldMapping, int depth) throws IOException { |
| 132 | out.format("%sFIELD %s %s %s\n", getIndent(depth), fieldMapping.getObfName(), fieldMapping.getDeobfName(), fieldMapping.getObfType().toString()); | 132 | if (fieldMapping.getDeobfName() == null) |
| 133 | out.format("%sFIELD %s %s%s\n", getIndent(depth), fieldMapping.getObfName(), fieldMapping.getObfType().toString(), fieldMapping.getModifier() == Mappings.EntryModifier.UNCHANGED ? "" : fieldMapping.getModifier().getFormattedName()); | ||
| 134 | else | ||
| 135 | out.format("%sFIELD %s %s %s%s\n", getIndent(depth), fieldMapping.getObfName(), fieldMapping.getDeobfName(), fieldMapping.getObfType().toString(), fieldMapping.getModifier() == Mappings.EntryModifier.UNCHANGED ? "" : fieldMapping.getModifier().getFormattedName()); | ||
| 133 | } | 136 | } |
| 134 | 137 | ||
| 135 | private void write(PrintWriter out, MethodMapping methodMapping, int depth) throws IOException { | 138 | private void write(PrintWriter out, MethodMapping methodMapping, int depth) throws IOException { |
| 136 | if (methodMapping.getDeobfName() == null) { | 139 | if (methodMapping.getDeobfName() == null) { |
| 137 | out.format("%sMETHOD %s %s\n", getIndent(depth), methodMapping.getObfName(), methodMapping.getObfSignature()); | 140 | out.format("%sMETHOD %s %s%s\n", getIndent(depth), methodMapping.getObfName(), methodMapping.getObfSignature(), methodMapping.getModifier() == Mappings.EntryModifier.UNCHANGED ? "" :methodMapping.getModifier().getFormattedName()); |
| 138 | } else { | 141 | } else { |
| 139 | out.format("%sMETHOD %s %s %s\n", getIndent(depth), methodMapping.getObfName(), methodMapping.getDeobfName(), methodMapping.getObfSignature()); | 142 | out.format("%sMETHOD %s %s %s%s\n", getIndent(depth), methodMapping.getObfName(), methodMapping.getDeobfName(), methodMapping.getObfSignature(), methodMapping.getModifier() == Mappings.EntryModifier.UNCHANGED ? "" : methodMapping.getModifier().getFormattedName()); |
| 140 | } | 143 | } |
| 141 | 144 | ||
| 142 | for (ArgumentMapping argumentMapping : sorted(methodMapping.arguments())) { | 145 | for (ArgumentMapping argumentMapping : sorted(methodMapping.arguments())) { |
diff --git a/src/main/java/cuchaz/enigma/mapping/MappingsRenamer.java b/src/main/java/cuchaz/enigma/mapping/MappingsRenamer.java index 4e812b10..bac62503 100644 --- a/src/main/java/cuchaz/enigma/mapping/MappingsRenamer.java +++ b/src/main/java/cuchaz/enigma/mapping/MappingsRenamer.java | |||
| @@ -321,4 +321,22 @@ public class MappingsRenamer { | |||
| 321 | } | 321 | } |
| 322 | return mappingChain; | 322 | return mappingChain; |
| 323 | } | 323 | } |
| 324 | |||
| 325 | public void setClassModifier(ClassEntry obEntry, Mappings.EntryModifier modifier) | ||
| 326 | { | ||
| 327 | ClassMapping classMapping = getOrCreateClassMapping(obEntry); | ||
| 328 | classMapping.setModifier(modifier); | ||
| 329 | } | ||
| 330 | |||
| 331 | public void setFieldModifier(FieldEntry obEntry, Mappings.EntryModifier modifier) | ||
| 332 | { | ||
| 333 | ClassMapping classMapping = getOrCreateClassMapping(obEntry.getClassEntry()); | ||
| 334 | classMapping.setFieldModifier(obEntry.getName(), obEntry.getType(), modifier); | ||
| 335 | } | ||
| 336 | |||
| 337 | public void setMethodModifier(BehaviorEntry obEntry, Mappings.EntryModifier modifier) | ||
| 338 | { | ||
| 339 | ClassMapping classMapping = getOrCreateClassMapping(obEntry.getClassEntry()); | ||
| 340 | classMapping.setMethodModifier(obEntry.getName(), obEntry.getSignature(), modifier); | ||
| 341 | } | ||
| 324 | } | 342 | } |
diff --git a/src/main/java/cuchaz/enigma/mapping/MethodMapping.java b/src/main/java/cuchaz/enigma/mapping/MethodMapping.java index 99b9c887..455ff6b7 100644 --- a/src/main/java/cuchaz/enigma/mapping/MethodMapping.java +++ b/src/main/java/cuchaz/enigma/mapping/MethodMapping.java | |||
| @@ -22,12 +22,17 @@ public class MethodMapping implements Comparable<MethodMapping>, MemberMapping<B | |||
| 22 | private String deobfName; | 22 | private String deobfName; |
| 23 | private Signature obfSignature; | 23 | private Signature obfSignature; |
| 24 | private Map<Integer, ArgumentMapping> arguments; | 24 | private Map<Integer, ArgumentMapping> arguments; |
| 25 | private Mappings.EntryModifier modifier; | ||
| 25 | 26 | ||
| 26 | public MethodMapping(String obfName, Signature obfSignature) { | 27 | public MethodMapping(String obfName, Signature obfSignature) { |
| 27 | this(obfName, obfSignature, null); | 28 | this(obfName, obfSignature, null,Mappings.EntryModifier.UNCHANGED); |
| 28 | } | 29 | } |
| 29 | 30 | ||
| 30 | public MethodMapping(String obfName, Signature obfSignature, String deobfName) { | 31 | public MethodMapping(String obfName, Signature obfSignature, String deobfName) { |
| 32 | this(obfName, obfSignature, deobfName, Mappings.EntryModifier.UNCHANGED); | ||
| 33 | } | ||
| 34 | |||
| 35 | public MethodMapping(String obfName, Signature obfSignature, String deobfName, Mappings.EntryModifier modifier) { | ||
| 31 | if (obfName == null) { | 36 | if (obfName == null) { |
| 32 | throw new IllegalArgumentException("obf name cannot be null!"); | 37 | throw new IllegalArgumentException("obf name cannot be null!"); |
| 33 | } | 38 | } |
| @@ -38,11 +43,13 @@ public class MethodMapping implements Comparable<MethodMapping>, MemberMapping<B | |||
| 38 | this.deobfName = NameValidator.validateMethodName(deobfName); | 43 | this.deobfName = NameValidator.validateMethodName(deobfName); |
| 39 | this.obfSignature = obfSignature; | 44 | this.obfSignature = obfSignature; |
| 40 | this.arguments = Maps.newTreeMap(); | 45 | this.arguments = Maps.newTreeMap(); |
| 46 | this.modifier = modifier; | ||
| 41 | } | 47 | } |
| 42 | 48 | ||
| 43 | public MethodMapping(MethodMapping other, ClassNameReplacer obfClassNameReplacer) { | 49 | public MethodMapping(MethodMapping other, ClassNameReplacer obfClassNameReplacer) { |
| 44 | this.obfName = other.obfName; | 50 | this.obfName = other.obfName; |
| 45 | this.deobfName = other.deobfName; | 51 | this.deobfName = other.deobfName; |
| 52 | this.modifier = other.modifier; | ||
| 46 | this.obfSignature = new Signature(other.obfSignature, obfClassNameReplacer); | 53 | this.obfSignature = new Signature(other.obfSignature, obfClassNameReplacer); |
| 47 | this.arguments = Maps.newTreeMap(); | 54 | this.arguments = Maps.newTreeMap(); |
| 48 | for (Map.Entry<Integer,ArgumentMapping> entry : other.arguments.entrySet()) { | 55 | for (Map.Entry<Integer,ArgumentMapping> entry : other.arguments.entrySet()) { |
| @@ -187,4 +194,14 @@ public class MethodMapping implements Comparable<MethodMapping>, MemberMapping<B | |||
| 187 | return new MethodEntry(classEntry, this.obfName, this.obfSignature); | 194 | return new MethodEntry(classEntry, this.obfName, this.obfSignature); |
| 188 | } | 195 | } |
| 189 | } | 196 | } |
| 197 | |||
| 198 | public Mappings.EntryModifier getModifier() | ||
| 199 | { | ||
| 200 | return modifier; | ||
| 201 | } | ||
| 202 | |||
| 203 | public void setModifier(Mappings.EntryModifier modifier) | ||
| 204 | { | ||
| 205 | this.modifier = modifier; | ||
| 206 | } | ||
| 190 | } | 207 | } |
diff --git a/src/main/java/cuchaz/enigma/mapping/Translator.java b/src/main/java/cuchaz/enigma/mapping/Translator.java index 6b636f2f..e94009ee 100644 --- a/src/main/java/cuchaz/enigma/mapping/Translator.java +++ b/src/main/java/cuchaz/enigma/mapping/Translator.java | |||
| @@ -329,4 +329,27 @@ public class Translator { | |||
| 329 | assert (mappingsChain.size() == parts.length); | 329 | assert (mappingsChain.size() == parts.length); |
| 330 | return mappingsChain; | 330 | return mappingsChain; |
| 331 | } | 331 | } |
| 332 | |||
| 333 | public Mappings.EntryModifier getModifier(Entry entry) | ||
| 334 | { | ||
| 335 | ClassMapping classMapping = findClassMapping(entry.getClassEntry()); | ||
| 336 | if (classMapping != null && !entry.getName().equals("<clinit>")) | ||
| 337 | { | ||
| 338 | if (entry instanceof ClassEntry) | ||
| 339 | return classMapping.getModifier(); | ||
| 340 | else if (entry instanceof FieldEntry) | ||
| 341 | { | ||
| 342 | FieldMapping fieldMapping = classMapping.getFieldByObf(entry.getName(), ((FieldEntry) entry).getType()); | ||
| 343 | return fieldMapping != null ? fieldMapping.getModifier() : Mappings.EntryModifier.UNCHANGED; | ||
| 344 | } | ||
| 345 | else if (entry instanceof BehaviorEntry) | ||
| 346 | { | ||
| 347 | MethodMapping methodMapping = classMapping.getMethodByObf(entry.getName(), ((BehaviorEntry) entry).getSignature()); | ||
| 348 | return methodMapping != null ? methodMapping.getModifier() : Mappings.EntryModifier.UNCHANGED; | ||
| 349 | } | ||
| 350 | else | ||
| 351 | throw new Error("Unknown entry type: " + entry.getClass().getName()); | ||
| 352 | } | ||
| 353 | return Mappings.EntryModifier.UNCHANGED; | ||
| 354 | } | ||
| 332 | } | 355 | } |