From d65e9d0965b93f6d4c1f4c8de206c3c34ec5ee6c Mon Sep 17 00:00:00 2001 From: Runemoro Date: Fri, 21 Dec 2018 07:42:20 -0500 Subject: [PATCH] Nested class and mapping saving bug fixes - Fixed bugs related to nested classes - Fixed issue with moving classes twice --- build.gradle | 2 +- .../java/org/dimdev/knit/MappingsService.java | 6 +- .../java/org/dimdev/knit/RenameHandler.java | 156 +++++++++++------- src/main/resources/META-INF/plugin.xml | 5 + 4 files changed, 104 insertions(+), 65 deletions(-) diff --git a/build.gradle b/build.gradle index 774f0f6..57873cb 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { } group 'org.dimdev' -version '1.0.2' +version '1.0.3' sourceCompatibility = 1.8 diff --git a/src/main/java/org/dimdev/knit/MappingsService.java b/src/main/java/org/dimdev/knit/MappingsService.java index 139ad63..142af37 100644 --- a/src/main/java/org/dimdev/knit/MappingsService.java +++ b/src/main/java/org/dimdev/knit/MappingsService.java @@ -3,7 +3,6 @@ import com.intellij.openapi.ui.Messages; import cuchaz.enigma.mapping.Mappings; import cuchaz.enigma.mapping.MappingsEnigmaReader; -import cuchaz.enigma.mapping.MappingsEnigmaWriter; import cuchaz.enigma.throwables.MappingParseException; import java.io.File; @@ -11,7 +10,6 @@ public class MappingsService { private final MappingsEnigmaReader mappingsReader = new MappingsEnigmaReader(); - private final MappingsEnigmaWriter mappingsWriter = new MappingsEnigmaWriter(); private File mappingDirectory = null; private Mappings mappings = null; @@ -24,7 +22,7 @@ public void loadMappings(File mappingDirectory) { mappings = new Mappings(); try { - mappingsReader.readDirectory(mappings, mappingDirectory); + mappings = mappingsReader.read(mappingDirectory); } catch (MappingParseException e) { Messages.showErrorDialog("Exception occured while parsing mappings: " + e, "Mapping Parse Error"); } catch (IOException e) { @@ -38,7 +36,7 @@ public void saveMappings() { } try { - mappingsWriter.writeAsDirectory(mappingDirectory, mappings); + mappings.saveEnigmaMappings(mappingDirectory, true); } catch (IOException e) { throw new RuntimeException(e); } diff --git a/src/main/java/org/dimdev/knit/RenameHandler.java b/src/main/java/org/dimdev/knit/RenameHandler.java index 0ad63d7..2dfbe08 100644 --- a/src/main/java/org/dimdev/knit/RenameHandler.java +++ b/src/main/java/org/dimdev/knit/RenameHandler.java @@ -7,9 +7,10 @@ import cuchaz.enigma.mapping.*; import cuchaz.enigma.throwables.MappingConflict; +import java.util.function.Supplier; + public class RenameHandler { public static final String NO_PACKAGE_PREFIX = "nopackage/"; - public static final int MAX_OBFUSCATED_NAME_LENGTH = 3; private final MappingsService mappingsService = ServiceManager.getService(MappingsService.class); public void handleRename(String oldName, PsiElement element) { @@ -22,7 +23,13 @@ public void handleRename(String oldName, PsiElement element) { ClassMapping mapping = getOrCreateClassMapping(oldName); if (mapping != null) { - mappingsService.getMappings().setClassDeobfName(mapping, getClassName(clazz)); + int dollarSignIndex = oldName.indexOf('$'); + if (dollarSignIndex == -1) { + mappingsService.getMappings().setClassDeobfName(mapping, getClassName(clazz)); + } else { + ClassMapping parent = getOrCreateClassMapping(oldName.substring(0, dollarSignIndex)); + parent.setInnerClassName(mapping.getObfEntry(), clazz.getName()); + } } } @@ -73,23 +80,40 @@ public void handleRename(String oldName, PsiElement element) { } private ClassMapping getOrCreateClassMapping(String className) { - // Try getting deobfuscated class mapping - ClassMapping mapping = mappingsService.getMappings().getClassByDeobf(className); - - // If that doesn't work, try getting obfuscated class mapping - if (mapping == null) { - mapping = mappingsService.getMappings().getClassByObf(className); - } - - // If that doesn't work either, create a new class mapping - if (mapping == null && className.length() <= MAX_OBFUSCATED_NAME_LENGTH) { - try { - mapping = new ClassMapping(className); - mappingsService.getMappings().addClassMapping(mapping); - } catch (MappingConflict e) { - throw new IllegalStateException("Both getClassByDeobf and getClassByObf returned null yet addClassMapping " + - "threw a MappingConflict exception", e); - } + String[] parts = className.split("\\$"); + + // Get or create root mapping + ClassMapping mapping = coalesce( + () -> mappingsService.getMappings().getClassByDeobf(parts[0]), + () -> mappingsService.getMappings().getClassByObf(parts[0]), + () -> { + try { + ClassMapping newMapping = new ClassMapping(className); + mappingsService.getMappings().addClassMapping(newMapping); + return newMapping; + } catch (MappingConflict e) { + throw new IllegalStateException(e); + } + } + ); + + // Get or create subclass mappings + for (int i = 1; i < parts.length && mapping != null; i++) { + ClassMapping mapping_ = mapping; + int i_ = i; + mapping = coalesce( + () -> mapping_.getInnerClassByDeobf(parts[i_]), + () -> mapping_.getInnerClassByObfSimple(parts[i_]), + () -> { + try { + ClassMapping newMapping = new ClassMapping(className); + mapping_.addInnerClassMapping(newMapping); + return newMapping; + } catch (MappingConflict e) { + throw new IllegalStateException(e); + } + } + ); } return mapping; @@ -106,22 +130,16 @@ private MethodMapping getOrCreateMethodMapping(PsiMethod method, String actualNa return null; } - // Try getting deobfuscated method mapping - MethodDescriptor descriptor = obfuscateDescriptor(new MethodDescriptor(getDescriptor(method))); - MethodMapping mapping = classMapping.getMethodByDeobf(actualName, descriptor); - - // If that doesn't work, try getting obfuscated method mapping - if (mapping == null) { - mapping = classMapping.getMethodByObf(actualName, descriptor); - } - - // If that doesn't work either, create a new method mapping - if (mapping == null && actualName.length() <= MAX_OBFUSCATED_NAME_LENGTH) { - mapping = new MethodMapping(actualName, descriptor); - classMapping.addMethodMapping(mapping); - } - - return mapping; + MethodDescriptor descriptor = new MethodDescriptor(getDescriptor(method)).remap(this::obfuscateClassName); + String actualName_ = actualName; + return coalesce( + () -> classMapping.getMethodByDeobf(actualName_, descriptor), + () -> classMapping.getMethodByObf(actualName_, descriptor), + () -> { + MethodMapping newMapping = new MethodMapping(actualName_, descriptor); + classMapping.addMethodMapping(newMapping); + return newMapping; + }); } private FieldMapping getOrCreateFieldMapping(PsiField field, String actualName) { @@ -131,36 +149,43 @@ private FieldMapping getOrCreateFieldMapping(PsiField field, String actualName) return null; } - // Try getting deobfuscated method mapping - TypeDescriptor descriptor = obfuscateDescriptor(new TypeDescriptor(getDescriptor(field.getType()))); - FieldMapping mapping = classMapping.getFieldByDeobf(actualName, descriptor); + TypeDescriptor descriptor = new TypeDescriptor(getDescriptor(field.getType())).remap(this::obfuscateClassName); + return coalesce( + () -> classMapping.getFieldByDeobf(actualName, descriptor), + () -> classMapping.getFieldByObf(actualName, descriptor), + () -> { + FieldMapping newMapping = new FieldMapping(actualName, descriptor, actualName, Mappings.EntryModifier.UNCHANGED); + classMapping.addFieldMapping(newMapping); + return newMapping; + }); + } - // If that doesn't work, try getting obfuscated method mapping - if (mapping == null) { - mapping = classMapping.getFieldByObf(actualName, descriptor); - } + private String obfuscateClassName(String className) { + StringBuilder obfuscatedName = new StringBuilder(); - // If that doesn't work either, create a new field mapping - if (mapping == null && actualName.length() <= MAX_OBFUSCATED_NAME_LENGTH) { - mapping = new FieldMapping(actualName, descriptor, actualName, Mappings.EntryModifier.UNCHANGED); - classMapping.addFieldMapping(mapping); - } + String[] parts = className.split("\\$"); - return mapping; - } + // Append root class + ClassMapping mapping = coalesce( + () -> mappingsService.getMappings().getClassByDeobf(parts[0]), + () -> mappingsService.getMappings().getClassByObf(parts[0]) + ); + obfuscatedName.append(mapping != null ? mapping.getObfFullName() : parts[0]); - public MethodDescriptor obfuscateDescriptor(MethodDescriptor descriptor) { - return descriptor.remap(className -> { - ClassMapping mapping = mappingsService.getMappings().getClassByDeobf(className); - return mapping != null ? mapping.getObfFullName() : className; - }); - } + // Append inner classes + for (int i = 1; i < parts.length; i++) { + if (mapping != null) { + ClassMapping mapping_ = mapping; + int i_ = i; + mapping = coalesce( + () -> mapping_.getInnerClassByDeobf(parts[i_]), + () -> mapping_.getInnerClassByObfSimple(parts[i_]) + ); + } + obfuscatedName.append("$").append(mapping != null ? mapping.getObfSimpleName() : parts[i]); + } - public TypeDescriptor obfuscateDescriptor(TypeDescriptor descriptor) { - return descriptor.remap(clazzName -> { - ClassMapping mapping = mappingsService.getMappings().getClassByDeobf(clazzName); - return mapping != null ? mapping.getObfFullName() : clazzName; - }); + return obfuscatedName.toString(); } public static String getClassName(PsiClass element) { @@ -194,4 +219,15 @@ public static String getDescriptor(PsiType type) { public static String getDescriptor(PsiMethod method) { return JVMNameUtil.getJVMSignature(method).getDisplayName(null); } + + @SafeVarargs + private static T coalesce(Supplier... suppliers) { + for (Supplier supplier : suppliers) { + T item = supplier.get(); + if (item != null) { + return item; + } + } + return null; + } } diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 2170f27..f8ed409 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -41,6 +41,11 @@ 1.0.3 +
    +
  • Fixed bugs related to nested classes
  • +
  • Fixed issue with moving classes twice
  • +
1.0.2
  • Fixed class mappings not being created