diff options
| author | 2018-10-26 19:42:24 +0200 | |
|---|---|---|
| committer | 2018-10-26 19:42:42 +0200 | |
| commit | 97056986946cafdf79005721161edea2087c3b67 (patch) | |
| tree | 020fede2de6dcb120ebc74569b856bb9f7e2e59d /src/main/java/cuchaz | |
| parent | make rebuild method names discard child-only names. imperfect, but eh (diff) | |
| parent | "make sure this is actually a field" properly (diff) | |
| download | enigma-97056986946cafdf79005721161edea2087c3b67.tar.gz enigma-97056986946cafdf79005721161edea2087c3b67.tar.xz enigma-97056986946cafdf79005721161edea2087c3b67.zip | |
update ASM/Guava, merge ASM port fixes
Diffstat (limited to 'src/main/java/cuchaz')
8 files changed, 112 insertions, 19 deletions
diff --git a/src/main/java/cuchaz/enigma/CachingClasspathTypeLoader.java b/src/main/java/cuchaz/enigma/CachingClasspathTypeLoader.java index 58682e23..fe13321c 100644 --- a/src/main/java/cuchaz/enigma/CachingClasspathTypeLoader.java +++ b/src/main/java/cuchaz/enigma/CachingClasspathTypeLoader.java | |||
| @@ -8,6 +8,12 @@ import com.strobel.assembler.metadata.ITypeLoader; | |||
| 8 | * Caching version of {@link ClasspathTypeLoader} | 8 | * Caching version of {@link ClasspathTypeLoader} |
| 9 | */ | 9 | */ |
| 10 | public class CachingClasspathTypeLoader extends CachingTypeLoader { | 10 | public class CachingClasspathTypeLoader extends CachingTypeLoader { |
| 11 | private static ITypeLoader extraClassPathLoader = null; | ||
| 12 | |||
| 13 | public static void setExtraClassPathLoader(ITypeLoader loader){ | ||
| 14 | extraClassPathLoader = loader; | ||
| 15 | } | ||
| 16 | |||
| 11 | private final ITypeLoader classpathLoader = new ClasspathTypeLoader(); | 17 | private final ITypeLoader classpathLoader = new ClasspathTypeLoader(); |
| 12 | 18 | ||
| 13 | protected byte[] doLoad(String className) { | 19 | protected byte[] doLoad(String className) { |
| @@ -15,6 +21,12 @@ public class CachingClasspathTypeLoader extends CachingTypeLoader { | |||
| 15 | if (classpathLoader.tryLoadType(className, parentBuf)) { | 21 | if (classpathLoader.tryLoadType(className, parentBuf)) { |
| 16 | return parentBuf.array(); | 22 | return parentBuf.array(); |
| 17 | } | 23 | } |
| 24 | if (extraClassPathLoader != null){ | ||
| 25 | parentBuf.reset(); | ||
| 26 | if (extraClassPathLoader.tryLoadType(className, parentBuf)){ | ||
| 27 | return parentBuf.array(); | ||
| 28 | } | ||
| 29 | } | ||
| 18 | return EMPTY_ARRAY;//need to return *something* as null means no store | 30 | return EMPTY_ARRAY;//need to return *something* as null means no store |
| 19 | } | 31 | } |
| 20 | } | 32 | } |
diff --git a/src/main/java/cuchaz/enigma/Deobfuscator.java b/src/main/java/cuchaz/enigma/Deobfuscator.java index 5980f1fc..0c671589 100644 --- a/src/main/java/cuchaz/enigma/Deobfuscator.java +++ b/src/main/java/cuchaz/enigma/Deobfuscator.java | |||
| @@ -15,6 +15,7 @@ import com.google.common.base.Stopwatch; | |||
| 15 | import com.google.common.collect.Lists; | 15 | import com.google.common.collect.Lists; |
| 16 | import com.google.common.collect.Maps; | 16 | import com.google.common.collect.Maps; |
| 17 | import com.google.common.collect.Sets; | 17 | import com.google.common.collect.Sets; |
| 18 | import com.strobel.assembler.metadata.ITypeLoader; | ||
| 18 | import com.strobel.assembler.metadata.MetadataSystem; | 19 | import com.strobel.assembler.metadata.MetadataSystem; |
| 19 | import com.strobel.assembler.metadata.TypeDefinition; | 20 | import com.strobel.assembler.metadata.TypeDefinition; |
| 20 | import com.strobel.assembler.metadata.TypeReference; | 21 | import com.strobel.assembler.metadata.TypeReference; |
| @@ -33,14 +34,18 @@ import cuchaz.enigma.mapping.*; | |||
| 33 | import cuchaz.enigma.mapping.entry.*; | 34 | import cuchaz.enigma.mapping.entry.*; |
| 34 | import cuchaz.enigma.throwables.IllegalNameException; | 35 | import cuchaz.enigma.throwables.IllegalNameException; |
| 35 | import cuchaz.enigma.utils.Utils; | 36 | import cuchaz.enigma.utils.Utils; |
| 37 | import oml.ast.transformers.InvalidIdentifierFix; | ||
| 38 | import oml.ast.transformers.Java8Generics; | ||
| 36 | import oml.ast.transformers.ObfuscatedEnumSwitchRewriterTransform; | 39 | import oml.ast.transformers.ObfuscatedEnumSwitchRewriterTransform; |
| 37 | import oml.ast.transformers.RemoveObjectCasts; | 40 | import oml.ast.transformers.RemoveObjectCasts; |
| 41 | import oml.ast.transformers.VarargsFixer; | ||
| 38 | import org.objectweb.asm.ClassWriter; | 42 | import org.objectweb.asm.ClassWriter; |
| 39 | import org.objectweb.asm.Opcodes; | 43 | import org.objectweb.asm.Opcodes; |
| 40 | import org.objectweb.asm.tree.ClassNode; | 44 | import org.objectweb.asm.tree.ClassNode; |
| 41 | 45 | ||
| 42 | import java.io.*; | 46 | import java.io.*; |
| 43 | import java.util.*; | 47 | import java.util.*; |
| 48 | import java.util.concurrent.ConcurrentHashMap; | ||
| 44 | import java.util.concurrent.atomic.AtomicInteger; | 49 | import java.util.concurrent.atomic.AtomicInteger; |
| 45 | import java.util.jar.JarEntry; | 50 | import java.util.jar.JarEntry; |
| 46 | import java.util.jar.JarFile; | 51 | import java.util.jar.JarFile; |
| @@ -170,6 +175,10 @@ public class Deobfuscator { | |||
| 170 | } | 175 | } |
| 171 | 176 | ||
| 172 | public CompilationUnit getSourceTree(String className, ITranslatingTypeLoader loader) { | 177 | public CompilationUnit getSourceTree(String className, ITranslatingTypeLoader loader) { |
| 178 | return getSourceTree(className, loader, new NoRetryMetadataSystem(loader)); | ||
| 179 | } | ||
| 180 | |||
| 181 | public CompilationUnit getSourceTree(String className, ITranslatingTypeLoader loader, MetadataSystem metadataSystem) { | ||
| 173 | 182 | ||
| 174 | // we don't know if this class name is obfuscated or deobfuscated | 183 | // we don't know if this class name is obfuscated or deobfuscated |
| 175 | // we need to tell the decompiler the deobfuscated name so it doesn't get freaked out | 184 | // we need to tell the decompiler the deobfuscated name so it doesn't get freaked out |
| @@ -188,7 +197,7 @@ public class Deobfuscator { | |||
| 188 | this.settings.setTypeLoader(loader); | 197 | this.settings.setTypeLoader(loader); |
| 189 | 198 | ||
| 190 | // see if procyon can find the desc | 199 | // see if procyon can find the desc |
| 191 | TypeReference type = new MetadataSystem(loader).lookupType(deobfClassName); | 200 | TypeReference type = metadataSystem.lookupType(deobfClassName); |
| 192 | if (type == null) { | 201 | if (type == null) { |
| 193 | throw new Error(String.format("Unable to find desc: %s (deobf: %s)\nTried class names: %s", | 202 | throw new Error(String.format("Unable to find desc: %s (deobf: %s)\nTried class names: %s", |
| 194 | className, deobfClassName, loader.getClassNamesToTry(deobfClassName) | 203 | className, deobfClassName, loader.getClassNamesToTry(deobfClassName) |
| @@ -278,6 +287,9 @@ public class Deobfuscator { | |||
| 278 | //synchronized to make sure the parallelStream doesn't CME with the cache | 287 | //synchronized to make sure the parallelStream doesn't CME with the cache |
| 279 | ITranslatingTypeLoader typeLoader = new SynchronizedTypeLoader(createTypeLoader()); | 288 | ITranslatingTypeLoader typeLoader = new SynchronizedTypeLoader(createTypeLoader()); |
| 280 | 289 | ||
| 290 | MetadataSystem metadataSystem = new NoRetryMetadataSystem(typeLoader); | ||
| 291 | metadataSystem.setEagerMethodLoadingEnabled(true);//ensures methods are loaded on classload and prevents race conditions | ||
| 292 | |||
| 281 | // DEOBFUSCATE ALL THE THINGS!! @_@ | 293 | // DEOBFUSCATE ALL THE THINGS!! @_@ |
| 282 | Stopwatch stopwatch = Stopwatch.createStarted(); | 294 | Stopwatch stopwatch = Stopwatch.createStarted(); |
| 283 | AtomicInteger count = new AtomicInteger(); | 295 | AtomicInteger count = new AtomicInteger(); |
| @@ -289,7 +301,7 @@ public class Deobfuscator { | |||
| 289 | 301 | ||
| 290 | try { | 302 | try { |
| 291 | // get the source | 303 | // get the source |
| 292 | CompilationUnit sourceTree = getSourceTree(obfClassEntry.getName(), typeLoader); | 304 | CompilationUnit sourceTree = getSourceTree(obfClassEntry.getName(), typeLoader, metadataSystem); |
| 293 | 305 | ||
| 294 | // write the file | 306 | // write the file |
| 295 | File file = new File(dirOut, deobfClassEntry.getName().replace('.', '/') + ".java"); | 307 | File file = new File(dirOut, deobfClassEntry.getName().replace('.', '/') + ".java"); |
| @@ -355,28 +367,28 @@ public class Deobfuscator { | |||
| 355 | } | 367 | } |
| 356 | 368 | ||
| 357 | public void rebuildMethodNames(ProgressListener progress) { | 369 | public void rebuildMethodNames(ProgressListener progress) { |
| 358 | int i = 0; | 370 | final AtomicInteger i = new AtomicInteger(); |
| 359 | Map<ClassMapping, Map<Entry, String>> renameClassMap = new HashMap<>(); | 371 | Map<ClassMapping, Map<Entry, String>> renameClassMap = new HashMap<>(); |
| 360 | 372 | ||
| 361 | progress.init(getMappings().classes().size() * 3, "Rebuilding method names"); | 373 | progress.init(getMappings().classes().size() * 3, "Rebuilding method names"); |
| 362 | 374 | ||
| 363 | for (ClassMapping classMapping : Lists.newArrayList(getMappings().classes())) { | 375 | Lists.newArrayList(getMappings().classes()).parallelStream().forEach(classMapping -> { |
| 364 | progress.onProgress(i++, classMapping.getDeobfName()); | 376 | progress.onProgress(i.getAndIncrement(), classMapping.getDeobfName()); |
| 365 | rebuildMethodNames(classMapping, renameClassMap); | 377 | rebuildMethodNames(classMapping, renameClassMap); |
| 366 | } | 378 | }); |
| 367 | 379 | ||
| 368 | for (Map.Entry<ClassMapping, Map<Entry, String>> renameClassMapEntry : renameClassMap.entrySet()) { | ||
| 369 | progress.onProgress(i++, renameClassMapEntry.getKey().getDeobfName()); | ||
| 370 | 380 | ||
| 381 | renameClassMap.entrySet().parallelStream().forEach(renameClassMapEntry -> { | ||
| 382 | progress.onProgress(i.getAndIncrement(), renameClassMapEntry.getKey().getDeobfName()); | ||
| 371 | for (Map.Entry<Entry, String> entry : renameClassMapEntry.getValue().entrySet()) { | 383 | for (Map.Entry<Entry, String> entry : renameClassMapEntry.getValue().entrySet()) { |
| 372 | Entry obfEntry = entry.getKey(); | 384 | Entry obfEntry = entry.getKey(); |
| 373 | 385 | ||
| 374 | removeMapping(obfEntry); | 386 | removeMapping(obfEntry); |
| 375 | } | 387 | } |
| 376 | } | 388 | }); |
| 377 | 389 | ||
| 378 | for (Map.Entry<ClassMapping, Map<Entry, String>> renameClassMapEntry : renameClassMap.entrySet()) { | 390 | renameClassMap.entrySet().parallelStream().forEach(renameClassMapEntry -> { |
| 379 | progress.onProgress(i++, renameClassMapEntry.getKey().getDeobfName()); | 391 | progress.onProgress(i.getAndIncrement(), renameClassMapEntry.getKey().getDeobfName()); |
| 380 | 392 | ||
| 381 | for (Map.Entry<Entry, String> entry : renameClassMapEntry.getValue().entrySet()) { | 393 | for (Map.Entry<Entry, String> entry : renameClassMapEntry.getValue().entrySet()) { |
| 382 | Entry obfEntry = entry.getKey(); | 394 | Entry obfEntry = entry.getKey(); |
| @@ -390,7 +402,7 @@ public class Deobfuscator { | |||
| 390 | } | 402 | } |
| 391 | } | 403 | } |
| 392 | } | 404 | } |
| 393 | } | 405 | }); |
| 394 | } | 406 | } |
| 395 | 407 | ||
| 396 | private void rebuildMethodNames(ClassMapping classMapping, Map<ClassMapping, Map<Entry, String>> renameClassMap) { | 408 | private void rebuildMethodNames(ClassMapping classMapping, Map<ClassMapping, Map<Entry, String>> renameClassMap) { |
| @@ -680,9 +692,12 @@ public class Deobfuscator { | |||
| 680 | public static void runCustomTransforms(AstBuilder builder, DecompilerContext context){ | 692 | public static void runCustomTransforms(AstBuilder builder, DecompilerContext context){ |
| 681 | List<IAstTransform> transformers = Arrays.asList( | 693 | List<IAstTransform> transformers = Arrays.asList( |
| 682 | new ObfuscatedEnumSwitchRewriterTransform(context), | 694 | new ObfuscatedEnumSwitchRewriterTransform(context), |
| 683 | new RemoveObjectCasts(context) | 695 | new VarargsFixer(context), |
| 696 | new RemoveObjectCasts(context), | ||
| 697 | new Java8Generics(), | ||
| 698 | new InvalidIdentifierFix() | ||
| 684 | ); | 699 | ); |
| 685 | for (IAstTransform transform : transformers){ | 700 | for (IAstTransform transform : transformers) { |
| 686 | transform.run(builder.getCompilationUnit()); | 701 | transform.run(builder.getCompilationUnit()); |
| 687 | } | 702 | } |
| 688 | } | 703 | } |
| @@ -697,4 +712,30 @@ public class Deobfuscator { | |||
| 697 | String transform(ClassNode node, ClassWriter writer); | 712 | String transform(ClassNode node, ClassWriter writer); |
| 698 | } | 713 | } |
| 699 | 714 | ||
| 715 | public static class NoRetryMetadataSystem extends MetadataSystem { | ||
| 716 | private final Set<String> _failedTypes = Collections.newSetFromMap(new ConcurrentHashMap<>()); | ||
| 717 | |||
| 718 | public NoRetryMetadataSystem(final ITypeLoader typeLoader) { | ||
| 719 | super(typeLoader); | ||
| 720 | } | ||
| 721 | |||
| 722 | @Override | ||
| 723 | protected synchronized TypeDefinition resolveType(final String descriptor, final boolean mightBePrimitive) { | ||
| 724 | if (_failedTypes.contains(descriptor)) { | ||
| 725 | return null; | ||
| 726 | } | ||
| 727 | |||
| 728 | final TypeDefinition result = super.resolveType(descriptor, mightBePrimitive); | ||
| 729 | |||
| 730 | if (result == null) { | ||
| 731 | _failedTypes.add(descriptor); | ||
| 732 | } | ||
| 733 | |||
| 734 | return result; | ||
| 735 | } | ||
| 736 | |||
| 737 | public synchronized TypeDefinition resolve(final TypeReference type) { | ||
| 738 | return super.resolve(type); | ||
| 739 | } | ||
| 740 | } | ||
| 700 | } | 741 | } |
diff --git a/src/main/java/cuchaz/enigma/TranslatingTypeLoader.java b/src/main/java/cuchaz/enigma/TranslatingTypeLoader.java index eb780ee9..42ceec4d 100644 --- a/src/main/java/cuchaz/enigma/TranslatingTypeLoader.java +++ b/src/main/java/cuchaz/enigma/TranslatingTypeLoader.java | |||
| @@ -22,7 +22,10 @@ import cuchaz.enigma.mapping.entry.ReferencedEntryPool; | |||
| 22 | import cuchaz.enigma.mapping.Translator; | 22 | import cuchaz.enigma.mapping.Translator; |
| 23 | import org.objectweb.asm.ClassWriter; | 23 | import org.objectweb.asm.ClassWriter; |
| 24 | import org.objectweb.asm.Opcodes; | 24 | import org.objectweb.asm.Opcodes; |
| 25 | import org.objectweb.asm.tree.AbstractInsnNode; | ||
| 25 | import org.objectweb.asm.tree.ClassNode; | 26 | import org.objectweb.asm.tree.ClassNode; |
| 27 | import org.objectweb.asm.tree.MethodInsnNode; | ||
| 28 | import org.objectweb.asm.tree.MethodNode; | ||
| 26 | 29 | ||
| 27 | import java.util.List; | 30 | import java.util.List; |
| 28 | 31 | ||
| @@ -89,6 +92,31 @@ public class TranslatingTypeLoader extends CachingTypeLoader implements ITransla | |||
| 89 | return null; | 92 | return null; |
| 90 | } | 93 | } |
| 91 | 94 | ||
| 95 | |||
| 96 | // remove <obj>.getClass() calls that are seemingly injected | ||
| 97 | // DUP | ||
| 98 | // INVOKEVIRTUAL java/lang/Object.getClass ()Ljava/lang/Class; | ||
| 99 | // POP | ||
| 100 | for (MethodNode methodNode : node.methods){ | ||
| 101 | AbstractInsnNode insnNode = methodNode.instructions.getFirst(); | ||
| 102 | while (insnNode != null){ | ||
| 103 | if (insnNode instanceof MethodInsnNode && insnNode.getOpcode() == Opcodes.INVOKEVIRTUAL){ | ||
| 104 | MethodInsnNode methodInsnNode = (MethodInsnNode)insnNode; | ||
| 105 | if (methodInsnNode.name.equals("getClass") && methodInsnNode.owner.equals("java/lang/Object") && methodInsnNode.desc.equals("()Ljava/lang/Class;")){ | ||
| 106 | AbstractInsnNode previous = methodInsnNode.getPrevious(); | ||
| 107 | AbstractInsnNode next = methodInsnNode.getNext(); | ||
| 108 | if (previous.getOpcode() == Opcodes.DUP && next.getOpcode() == Opcodes.POP){ | ||
| 109 | insnNode = previous.getPrevious();//reset the iterator so it gets the new next instruction | ||
| 110 | methodNode.instructions.remove(previous); | ||
| 111 | methodNode.instructions.remove(methodInsnNode); | ||
| 112 | methodNode.instructions.remove(next); | ||
| 113 | } | ||
| 114 | } | ||
| 115 | } | ||
| 116 | insnNode = insnNode.getNext(); | ||
| 117 | } | ||
| 118 | } | ||
| 119 | |||
| 92 | ClassWriter writer = new ClassWriter(0); | 120 | ClassWriter writer = new ClassWriter(0); |
| 93 | transformInto(node, writer); | 121 | transformInto(node, writer); |
| 94 | 122 | ||
diff --git a/src/main/java/cuchaz/enigma/analysis/SourceIndex.java b/src/main/java/cuchaz/enigma/analysis/SourceIndex.java index 14b2e768..78195cb7 100644 --- a/src/main/java/cuchaz/enigma/analysis/SourceIndex.java +++ b/src/main/java/cuchaz/enigma/analysis/SourceIndex.java | |||
| @@ -17,15 +17,19 @@ import com.google.common.collect.Maps; | |||
| 17 | import com.google.common.collect.Multimap; | 17 | import com.google.common.collect.Multimap; |
| 18 | import com.strobel.decompiler.languages.Region; | 18 | import com.strobel.decompiler.languages.Region; |
| 19 | import com.strobel.decompiler.languages.java.ast.AstNode; | 19 | import com.strobel.decompiler.languages.java.ast.AstNode; |
| 20 | import com.strobel.decompiler.languages.java.ast.ConstructorDeclaration; | ||
| 20 | import com.strobel.decompiler.languages.java.ast.Identifier; | 21 | import com.strobel.decompiler.languages.java.ast.Identifier; |
| 22 | import com.strobel.decompiler.languages.java.ast.TypeDeclaration; | ||
| 21 | import cuchaz.enigma.mapping.entry.Entry; | 23 | import cuchaz.enigma.mapping.entry.Entry; |
| 22 | 24 | ||
| 23 | import java.util.Collection; | 25 | import java.util.Collection; |
| 24 | import java.util.List; | 26 | import java.util.List; |
| 25 | import java.util.Map; | 27 | import java.util.Map; |
| 26 | import java.util.TreeMap; | 28 | import java.util.TreeMap; |
| 29 | import java.util.regex.Pattern; | ||
| 27 | 30 | ||
| 28 | public class SourceIndex { | 31 | public class SourceIndex { |
| 32 | private static Pattern ANONYMOUS_INNER = Pattern.compile("\\$\\d+$"); | ||
| 29 | 33 | ||
| 30 | private String source; | 34 | private String source; |
| 31 | private TreeMap<Token, EntryReference<Entry, Entry>> tokenToReference; | 35 | private TreeMap<Token, EntryReference<Entry, Entry>> tokenToReference; |
| @@ -81,6 +85,14 @@ public class SourceIndex { | |||
| 81 | return null; | 85 | return null; |
| 82 | } | 86 | } |
| 83 | 87 | ||
| 88 | if (node instanceof Identifier && name.indexOf('$') >=0 && node.getParent() instanceof ConstructorDeclaration && name.lastIndexOf('$') >= 0 && !ANONYMOUS_INNER.matcher(name).matches()){ | ||
| 89 | TypeDeclaration type = node.getParent().getParent() instanceof TypeDeclaration ? (TypeDeclaration) node.getParent().getParent() : null; | ||
| 90 | if (type != null){ | ||
| 91 | name = type.getName(); | ||
| 92 | token.end = token.start + name.length(); | ||
| 93 | } | ||
| 94 | } | ||
| 95 | |||
| 84 | // DEBUG | 96 | // DEBUG |
| 85 | // System.out.println( String.format( "%s \"%s\" region: %s", node.getNodeType(), name, region ) ); | 97 | // System.out.println( String.format( "%s \"%s\" region: %s", node.getNodeType(), name, region ) ); |
| 86 | 98 | ||
diff --git a/src/main/java/cuchaz/enigma/analysis/SourceIndexMethodVisitor.java b/src/main/java/cuchaz/enigma/analysis/SourceIndexMethodVisitor.java index 83fe296c..83e5e04f 100644 --- a/src/main/java/cuchaz/enigma/analysis/SourceIndexMethodVisitor.java +++ b/src/main/java/cuchaz/enigma/analysis/SourceIndexMethodVisitor.java | |||
| @@ -76,7 +76,7 @@ public class SourceIndexMethodVisitor extends SourceIndexVisitor { | |||
| 76 | @Override | 76 | @Override |
| 77 | public Void visitMemberReferenceExpression(MemberReferenceExpression node, SourceIndex index) { | 77 | public Void visitMemberReferenceExpression(MemberReferenceExpression node, SourceIndex index) { |
| 78 | MemberReference ref = node.getUserData(Keys.MEMBER_REFERENCE); | 78 | MemberReference ref = node.getUserData(Keys.MEMBER_REFERENCE); |
| 79 | if (ref != null) { | 79 | if (ref instanceof FieldReference) { |
| 80 | // make sure this is actually a field | 80 | // make sure this is actually a field |
| 81 | String erasedSignature = ref.getErasedSignature(); | 81 | String erasedSignature = ref.getErasedSignature(); |
| 82 | if (erasedSignature.indexOf('(') >= 0) { | 82 | if (erasedSignature.indexOf('(') >= 0) { |
diff --git a/src/main/java/cuchaz/enigma/bytecode/AccessFlags.java b/src/main/java/cuchaz/enigma/bytecode/AccessFlags.java index 21b24897..0bfc59bd 100644 --- a/src/main/java/cuchaz/enigma/bytecode/AccessFlags.java +++ b/src/main/java/cuchaz/enigma/bytecode/AccessFlags.java | |||
| @@ -51,7 +51,7 @@ public class AccessFlags { | |||
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | public AccessFlags setBridged() { | 53 | public AccessFlags setBridged() { |
| 54 | this.setVisibility(Opcodes.ACC_BRIDGE); | 54 | flags |= Opcodes.ACC_BRIDGE; |
| 55 | return this; | 55 | return this; |
| 56 | } | 56 | } |
| 57 | 57 | ||
diff --git a/src/main/java/cuchaz/enigma/config/Config.java b/src/main/java/cuchaz/enigma/config/Config.java index 87ef3531..75ced70c 100644 --- a/src/main/java/cuchaz/enigma/config/Config.java +++ b/src/main/java/cuchaz/enigma/config/Config.java | |||
| @@ -62,7 +62,7 @@ public class Config { | |||
| 62 | public void loadConfig() throws IOException { | 62 | public void loadConfig() throws IOException { |
| 63 | if (!ENIGMA_DIR.exists()) ENIGMA_DIR.mkdirs(); | 63 | if (!ENIGMA_DIR.exists()) ENIGMA_DIR.mkdirs(); |
| 64 | File configFile = new File(ENIGMA_DIR, "config.json"); | 64 | File configFile = new File(ENIGMA_DIR, "config.json"); |
| 65 | if (configFile.exists()) gson.fromJson(Files.toString(configFile, Charset.defaultCharset()), Config.class); | 65 | if (configFile.exists()) gson.fromJson(Files.asCharSource(configFile, Charset.defaultCharset()).read(), Config.class); |
| 66 | else { | 66 | else { |
| 67 | this.reset(); | 67 | this.reset(); |
| 68 | Files.touch(configFile); | 68 | Files.touch(configFile); |
| @@ -71,7 +71,7 @@ public class Config { | |||
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | public void saveConfig() throws IOException { | 73 | public void saveConfig() throws IOException { |
| 74 | Files.write(gson.toJson(this), CONFIG_FILE, Charset.defaultCharset()); | 74 | Files.asCharSink(CONFIG_FILE, Charset.defaultCharset()).write(gson.toJson(this)); |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | public void reset() throws IOException { | 77 | public void reset() throws IOException { |
diff --git a/src/main/java/cuchaz/enigma/gui/panels/PanelEditor.java b/src/main/java/cuchaz/enigma/gui/panels/PanelEditor.java index fd30e389..ffceae12 100644 --- a/src/main/java/cuchaz/enigma/gui/panels/PanelEditor.java +++ b/src/main/java/cuchaz/enigma/gui/panels/PanelEditor.java | |||
| @@ -56,7 +56,7 @@ public class PanelEditor extends JEditorPane { | |||
| 56 | gui.popupMenu.showCallsMenu.doClick(); | 56 | gui.popupMenu.showCallsMenu.doClick(); |
| 57 | break; | 57 | break; |
| 58 | 58 | ||
| 59 | case KeyEvent.VK_T: | 59 | case KeyEvent.VK_O: |
| 60 | gui.popupMenu.toggleMappingMenu.doClick(); | 60 | gui.popupMenu.toggleMappingMenu.doClick(); |
| 61 | break; | 61 | break; |
| 62 | case KeyEvent.VK_F5: | 62 | case KeyEvent.VK_F5: |