diff options
Diffstat (limited to 'src/main/java/cuchaz/enigma/gui/ClassMatchingGui.java')
| -rw-r--r-- | src/main/java/cuchaz/enigma/gui/ClassMatchingGui.java | 290 |
1 files changed, 141 insertions, 149 deletions
diff --git a/src/main/java/cuchaz/enigma/gui/ClassMatchingGui.java b/src/main/java/cuchaz/enigma/gui/ClassMatchingGui.java index edf1e30..dcbe1c5 100644 --- a/src/main/java/cuchaz/enigma/gui/ClassMatchingGui.java +++ b/src/main/java/cuchaz/enigma/gui/ClassMatchingGui.java | |||
| @@ -13,19 +13,6 @@ package cuchaz.enigma.gui; | |||
| 13 | import com.google.common.collect.BiMap; | 13 | import com.google.common.collect.BiMap; |
| 14 | import com.google.common.collect.Lists; | 14 | import com.google.common.collect.Lists; |
| 15 | import com.google.common.collect.Maps; | 15 | import com.google.common.collect.Maps; |
| 16 | |||
| 17 | import java.awt.BorderLayout; | ||
| 18 | import java.awt.Container; | ||
| 19 | import java.awt.Dimension; | ||
| 20 | import java.awt.FlowLayout; | ||
| 21 | import java.awt.event.ActionListener; | ||
| 22 | import java.util.Collection; | ||
| 23 | import java.util.Collections; | ||
| 24 | import java.util.List; | ||
| 25 | import java.util.Map; | ||
| 26 | |||
| 27 | import javax.swing.*; | ||
| 28 | |||
| 29 | import cuchaz.enigma.Constants; | 16 | import cuchaz.enigma.Constants; |
| 30 | import cuchaz.enigma.Deobfuscator; | 17 | import cuchaz.enigma.Deobfuscator; |
| 31 | import cuchaz.enigma.convert.*; | 18 | import cuchaz.enigma.convert.*; |
| @@ -37,6 +24,13 @@ import cuchaz.enigma.mapping.MappingsChecker; | |||
| 37 | import cuchaz.enigma.throwables.MappingConflict; | 24 | import cuchaz.enigma.throwables.MappingConflict; |
| 38 | import de.sciss.syntaxpane.DefaultSyntaxKit; | 25 | import de.sciss.syntaxpane.DefaultSyntaxKit; |
| 39 | 26 | ||
| 27 | import javax.swing.*; | ||
| 28 | import java.awt.*; | ||
| 29 | import java.awt.event.ActionListener; | ||
| 30 | import java.util.Collection; | ||
| 31 | import java.util.List; | ||
| 32 | import java.util.Map; | ||
| 33 | |||
| 40 | 34 | ||
| 41 | public class ClassMatchingGui { | 35 | public class ClassMatchingGui { |
| 42 | 36 | ||
| @@ -80,35 +74,35 @@ public class ClassMatchingGui { | |||
| 80 | } | 74 | } |
| 81 | 75 | ||
| 82 | // controls | 76 | // controls |
| 83 | private JFrame m_frame; | 77 | private JFrame frame; |
| 84 | private ClassSelector m_sourceClasses; | 78 | private ClassSelector sourceClasses; |
| 85 | private ClassSelector m_destClasses; | 79 | private ClassSelector destClasses; |
| 86 | private CodeReader m_sourceReader; | 80 | private CodeReader sourceReader; |
| 87 | private CodeReader m_destReader; | 81 | private CodeReader destReader; |
| 88 | private JLabel m_sourceClassLabel; | 82 | private JLabel sourceClassLabel; |
| 89 | private JLabel m_destClassLabel; | 83 | private JLabel destClassLabel; |
| 90 | private JButton m_matchButton; | 84 | private JButton matchButton; |
| 91 | private Map<SourceType, JRadioButton> m_sourceTypeButtons; | 85 | private Map<SourceType, JRadioButton> sourceTypeButtons; |
| 92 | private JCheckBox m_advanceCheck; | 86 | private JCheckBox advanceCheck; |
| 93 | private JCheckBox m_top10Matches; | 87 | private JCheckBox top10Matches; |
| 94 | 88 | ||
| 95 | private ClassMatches m_classMatches; | 89 | private ClassMatches classMatches; |
| 96 | private Deobfuscator m_sourceDeobfuscator; | 90 | private Deobfuscator sourceDeobfuscator; |
| 97 | private Deobfuscator m_destDeobfuscator; | 91 | private Deobfuscator destDeobfuscator; |
| 98 | private ClassEntry m_sourceClass; | 92 | private ClassEntry sourceClass; |
| 99 | private ClassEntry m_destClass; | 93 | private ClassEntry destClass; |
| 100 | private SourceType m_sourceType; | 94 | private SourceType sourceType; |
| 101 | private SaveListener m_saveListener; | 95 | private SaveListener saveListener; |
| 102 | 96 | ||
| 103 | public ClassMatchingGui(ClassMatches matches, Deobfuscator sourceDeobfuscator, Deobfuscator destDeobfuscator) { | 97 | public ClassMatchingGui(ClassMatches matches, Deobfuscator sourceDeobfuscator, Deobfuscator destDeobfuscator) { |
| 104 | 98 | ||
| 105 | m_classMatches = matches; | 99 | classMatches = matches; |
| 106 | m_sourceDeobfuscator = sourceDeobfuscator; | 100 | this.sourceDeobfuscator = sourceDeobfuscator; |
| 107 | m_destDeobfuscator = destDeobfuscator; | 101 | this.destDeobfuscator = destDeobfuscator; |
| 108 | 102 | ||
| 109 | // init frame | 103 | // init frame |
| 110 | m_frame = new JFrame(Constants.NAME + " - Class Matcher"); | 104 | frame = new JFrame(Constants.NAME + " - Class Matcher"); |
| 111 | final Container pane = m_frame.getContentPane(); | 105 | final Container pane = frame.getContentPane(); |
| 112 | pane.setLayout(new BorderLayout()); | 106 | pane.setLayout(new BorderLayout()); |
| 113 | 107 | ||
| 114 | // init source side | 108 | // init source side |
| @@ -124,16 +118,16 @@ public class ClassMatchingGui { | |||
| 124 | sourceTypePanel.setLayout(new BoxLayout(sourceTypePanel, BoxLayout.PAGE_AXIS)); | 118 | sourceTypePanel.setLayout(new BoxLayout(sourceTypePanel, BoxLayout.PAGE_AXIS)); |
| 125 | ActionListener sourceTypeListener = event -> setSourceType(SourceType.valueOf(event.getActionCommand())); | 119 | ActionListener sourceTypeListener = event -> setSourceType(SourceType.valueOf(event.getActionCommand())); |
| 126 | ButtonGroup sourceTypeButtons = new ButtonGroup(); | 120 | ButtonGroup sourceTypeButtons = new ButtonGroup(); |
| 127 | m_sourceTypeButtons = Maps.newHashMap(); | 121 | this.sourceTypeButtons = Maps.newHashMap(); |
| 128 | for (SourceType sourceType : SourceType.values()) { | 122 | for (SourceType sourceType : SourceType.values()) { |
| 129 | JRadioButton button = sourceType.newRadio(sourceTypeListener, sourceTypeButtons); | 123 | JRadioButton button = sourceType.newRadio(sourceTypeListener, sourceTypeButtons); |
| 130 | m_sourceTypeButtons.put(sourceType, button); | 124 | this.sourceTypeButtons.put(sourceType, button); |
| 131 | sourceTypePanel.add(button); | 125 | sourceTypePanel.add(button); |
| 132 | } | 126 | } |
| 133 | 127 | ||
| 134 | m_sourceClasses = new ClassSelector(null, ClassSelector.DEOBF_CLASS_COMPARATOR, false); | 128 | sourceClasses = new ClassSelector(null, ClassSelector.DEOBF_CLASS_COMPARATOR, false); |
| 135 | m_sourceClasses.setSelectionListener(this::setSourceClass); | 129 | sourceClasses.setSelectionListener(this::setSourceClass); |
| 136 | JScrollPane sourceScroller = new JScrollPane(m_sourceClasses); | 130 | JScrollPane sourceScroller = new JScrollPane(sourceClasses); |
| 137 | sourcePanel.add(sourceScroller); | 131 | sourcePanel.add(sourceScroller); |
| 138 | 132 | ||
| 139 | // init dest side | 133 | // init dest side |
| @@ -143,13 +137,13 @@ public class ClassMatchingGui { | |||
| 143 | pane.add(destPanel, BorderLayout.WEST); | 137 | pane.add(destPanel, BorderLayout.WEST); |
| 144 | destPanel.add(new JLabel("Destination Classes")); | 138 | destPanel.add(new JLabel("Destination Classes")); |
| 145 | 139 | ||
| 146 | m_top10Matches = new JCheckBox("Show only top 10 matches"); | 140 | top10Matches = new JCheckBox("Show only top 10 matches"); |
| 147 | destPanel.add(m_top10Matches); | 141 | destPanel.add(top10Matches); |
| 148 | m_top10Matches.addActionListener(event -> toggleTop10Matches()); | 142 | top10Matches.addActionListener(event -> toggleTop10Matches()); |
| 149 | 143 | ||
| 150 | m_destClasses = new ClassSelector(null, ClassSelector.DEOBF_CLASS_COMPARATOR, false); | 144 | destClasses = new ClassSelector(null, ClassSelector.DEOBF_CLASS_COMPARATOR, false); |
| 151 | m_destClasses.setSelectionListener(this::setDestClass); | 145 | destClasses.setSelectionListener(this::setDestClass); |
| 152 | JScrollPane destScroller = new JScrollPane(m_destClasses); | 146 | JScrollPane destScroller = new JScrollPane(destClasses); |
| 153 | destPanel.add(destScroller); | 147 | destPanel.add(destScroller); |
| 154 | 148 | ||
| 155 | JButton autoMatchButton = new JButton("AutoMatch"); | 149 | JButton autoMatchButton = new JButton("AutoMatch"); |
| @@ -158,13 +152,14 @@ public class ClassMatchingGui { | |||
| 158 | 152 | ||
| 159 | // init source panels | 153 | // init source panels |
| 160 | DefaultSyntaxKit.initKit(); | 154 | DefaultSyntaxKit.initKit(); |
| 161 | m_sourceReader = new CodeReader(); | 155 | sourceReader = new CodeReader(); |
| 162 | m_destReader = new CodeReader(); | 156 | destReader = new CodeReader(); |
| 163 | 157 | ||
| 164 | // init all the splits | 158 | // init all the splits |
| 165 | JSplitPane splitLeft = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, sourcePanel, new JScrollPane(m_sourceReader)); | 159 | JSplitPane splitLeft = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, sourcePanel, new JScrollPane( |
| 160 | sourceReader)); | ||
| 166 | splitLeft.setResizeWeight(0); // let the right side take all the slack | 161 | splitLeft.setResizeWeight(0); // let the right side take all the slack |
| 167 | JSplitPane splitRight = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, new JScrollPane(m_destReader), destPanel); | 162 | JSplitPane splitRight = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, new JScrollPane(destReader), destPanel); |
| 168 | splitRight.setResizeWeight(1); // let the left side take all the slack | 163 | splitRight.setResizeWeight(1); // let the left side take all the slack |
| 169 | JSplitPane splitCenter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, splitLeft, splitRight); | 164 | JSplitPane splitCenter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, splitLeft, splitRight); |
| 170 | splitCenter.setResizeWeight(0.5); // resize 50:50 | 165 | splitCenter.setResizeWeight(0.5); // resize 50:50 |
| @@ -175,55 +170,52 @@ public class ClassMatchingGui { | |||
| 175 | JPanel bottomPanel = new JPanel(); | 170 | JPanel bottomPanel = new JPanel(); |
| 176 | bottomPanel.setLayout(new FlowLayout()); | 171 | bottomPanel.setLayout(new FlowLayout()); |
| 177 | 172 | ||
| 178 | m_sourceClassLabel = new JLabel(); | 173 | sourceClassLabel = new JLabel(); |
| 179 | m_sourceClassLabel.setHorizontalAlignment(SwingConstants.RIGHT); | 174 | sourceClassLabel.setHorizontalAlignment(SwingConstants.RIGHT); |
| 180 | m_destClassLabel = new JLabel(); | 175 | destClassLabel = new JLabel(); |
| 181 | m_destClassLabel.setHorizontalAlignment(SwingConstants.LEFT); | 176 | destClassLabel.setHorizontalAlignment(SwingConstants.LEFT); |
| 182 | 177 | ||
| 183 | m_matchButton = new JButton(); | 178 | matchButton = new JButton(); |
| 184 | 179 | ||
| 185 | m_advanceCheck = new JCheckBox("Advance to next likely match"); | 180 | advanceCheck = new JCheckBox("Advance to next likely match"); |
| 186 | m_advanceCheck.addActionListener(event -> { | 181 | advanceCheck.addActionListener(event -> { |
| 187 | if (m_advanceCheck.isSelected()) { | 182 | if (advanceCheck.isSelected()) { |
| 188 | advance(); | 183 | advance(); |
| 189 | } | 184 | } |
| 190 | }); | 185 | }); |
| 191 | 186 | ||
| 192 | bottomPanel.add(m_sourceClassLabel); | 187 | bottomPanel.add(sourceClassLabel); |
| 193 | bottomPanel.add(m_matchButton); | 188 | bottomPanel.add(matchButton); |
| 194 | bottomPanel.add(m_destClassLabel); | 189 | bottomPanel.add(destClassLabel); |
| 195 | bottomPanel.add(m_advanceCheck); | 190 | bottomPanel.add(advanceCheck); |
| 196 | pane.add(bottomPanel, BorderLayout.SOUTH); | 191 | pane.add(bottomPanel, BorderLayout.SOUTH); |
| 197 | 192 | ||
| 198 | // show the frame | 193 | // show the frame |
| 199 | pane.doLayout(); | 194 | pane.doLayout(); |
| 200 | m_frame.setSize(1024, 576); | 195 | frame.setSize(1024, 576); |
| 201 | m_frame.setMinimumSize(new Dimension(640, 480)); | 196 | frame.setMinimumSize(new Dimension(640, 480)); |
| 202 | m_frame.setVisible(true); | 197 | frame.setVisible(true); |
| 203 | m_frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); | 198 | frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); |
| 204 | 199 | ||
| 205 | // init state | 200 | // init state |
| 206 | updateDestMappings(); | 201 | updateDestMappings(); |
| 207 | setSourceType(SourceType.getDefault()); | 202 | setSourceType(SourceType.getDefault()); |
| 208 | updateMatchButton(); | 203 | updateMatchButton(); |
| 209 | m_saveListener = null; | 204 | saveListener = null; |
| 210 | } | 205 | } |
| 211 | 206 | ||
| 212 | public void setSaveListener(SaveListener val) { | 207 | public void setSaveListener(SaveListener val) { |
| 213 | m_saveListener = val; | 208 | saveListener = val; |
| 214 | } | 209 | } |
| 215 | 210 | ||
| 216 | private void updateDestMappings() { | 211 | private void updateDestMappings() { |
| 217 | try { | 212 | try { |
| 218 | Mappings newMappings = MappingsConverter.newMappings( | 213 | Mappings newMappings = MappingsConverter.newMappings(classMatches, |
| 219 | m_classMatches, | 214 | sourceDeobfuscator.getMappings(), sourceDeobfuscator, destDeobfuscator |
| 220 | m_sourceDeobfuscator.getMappings(), | ||
| 221 | m_sourceDeobfuscator, | ||
| 222 | m_destDeobfuscator | ||
| 223 | ); | 215 | ); |
| 224 | 216 | ||
| 225 | // look for dropped mappings | 217 | // look for dropped mappings |
| 226 | MappingsChecker checker = new MappingsChecker(m_destDeobfuscator.getJarIndex()); | 218 | MappingsChecker checker = new MappingsChecker(destDeobfuscator.getJarIndex()); |
| 227 | checker.dropBrokenMappings(newMappings); | 219 | checker.dropBrokenMappings(newMappings); |
| 228 | 220 | ||
| 229 | // count them | 221 | // count them |
| @@ -236,7 +228,7 @@ public class ClassMatchingGui { | |||
| 236 | numDroppedMethods | 228 | numDroppedMethods |
| 237 | )); | 229 | )); |
| 238 | 230 | ||
| 239 | m_destDeobfuscator.setMappings(newMappings); | 231 | destDeobfuscator.setMappings(newMappings); |
| 240 | } catch (MappingConflict ex) { | 232 | } catch (MappingConflict ex) { |
| 241 | System.out.println(ex.getMessage()); | 233 | System.out.println(ex.getMessage()); |
| 242 | ex.printStackTrace(); | 234 | ex.printStackTrace(); |
| @@ -247,14 +239,14 @@ public class ClassMatchingGui { | |||
| 247 | protected void setSourceType(SourceType val) { | 239 | protected void setSourceType(SourceType val) { |
| 248 | 240 | ||
| 249 | // show the source classes | 241 | // show the source classes |
| 250 | m_sourceType = val; | 242 | sourceType = val; |
| 251 | m_sourceClasses.setClasses(deobfuscateClasses(m_sourceType.getSourceClasses(m_classMatches), m_sourceDeobfuscator)); | 243 | sourceClasses.setClasses(deobfuscateClasses(sourceType.getSourceClasses(classMatches), sourceDeobfuscator)); |
| 252 | 244 | ||
| 253 | // update counts | 245 | // update counts |
| 254 | for (SourceType sourceType : SourceType.values()) { | 246 | for (SourceType sourceType : SourceType.values()) { |
| 255 | m_sourceTypeButtons.get(sourceType).setText(String.format("%s (%d)", | 247 | sourceTypeButtons.get(sourceType).setText(String.format("%s (%d)", |
| 256 | sourceType.name(), | 248 | sourceType.name(), |
| 257 | sourceType.getSourceClasses(m_classMatches).size() | 249 | sourceType.getSourceClasses(classMatches).size() |
| 258 | )); | 250 | )); |
| 259 | } | 251 | } |
| 260 | } | 252 | } |
| @@ -278,7 +270,7 @@ public class ClassMatchingGui { | |||
| 278 | protected void setSourceClass(ClassEntry classEntry) { | 270 | protected void setSourceClass(ClassEntry classEntry) { |
| 279 | 271 | ||
| 280 | Runnable onGetDestClasses = null; | 272 | Runnable onGetDestClasses = null; |
| 281 | if (m_advanceCheck.isSelected()) { | 273 | if (advanceCheck.isSelected()) { |
| 282 | onGetDestClasses = this::pickBestDestClass; | 274 | onGetDestClasses = this::pickBestDestClass; |
| 283 | } | 275 | } |
| 284 | 276 | ||
| @@ -288,35 +280,33 @@ public class ClassMatchingGui { | |||
| 288 | protected void setSourceClass(ClassEntry classEntry, final Runnable onGetDestClasses) { | 280 | protected void setSourceClass(ClassEntry classEntry, final Runnable onGetDestClasses) { |
| 289 | 281 | ||
| 290 | // update the current source class | 282 | // update the current source class |
| 291 | m_sourceClass = classEntry; | 283 | sourceClass = classEntry; |
| 292 | m_sourceClassLabel.setText(m_sourceClass != null ? m_sourceClass.getName() : ""); | 284 | sourceClassLabel.setText(sourceClass != null ? sourceClass.getName() : ""); |
| 293 | 285 | ||
| 294 | if (m_sourceClass != null) { | 286 | if (sourceClass != null) { |
| 295 | 287 | ||
| 296 | // show the dest class(es) | 288 | // show the dest class(es) |
| 297 | ClassMatch match = m_classMatches.getMatchBySource(m_sourceDeobfuscator.obfuscateEntry(m_sourceClass)); | 289 | ClassMatch match = classMatches.getMatchBySource(sourceDeobfuscator.obfuscateEntry(sourceClass)); |
| 298 | assert (match != null); | 290 | assert (match != null); |
| 299 | if (match.destClasses.isEmpty()) { | 291 | if (match.destClasses.isEmpty()) { |
| 300 | 292 | ||
| 301 | m_destClasses.setClasses(null); | 293 | destClasses.setClasses(null); |
| 302 | 294 | ||
| 303 | // run in a separate thread to keep ui responsive | 295 | // run in a separate thread to keep ui responsive |
| 304 | new Thread() { | 296 | new Thread(() -> |
| 305 | @Override | 297 | { |
| 306 | public void run() { | 298 | destClasses.setClasses(deobfuscateClasses(getLikelyMatches(sourceClass), destDeobfuscator)); |
| 307 | m_destClasses.setClasses(deobfuscateClasses(getLikelyMatches(m_sourceClass), m_destDeobfuscator)); | 299 | destClasses.expandAll(); |
| 308 | m_destClasses.expandAll(); | 300 | |
| 309 | 301 | if (onGetDestClasses != null) { | |
| 310 | if (onGetDestClasses != null) { | 302 | onGetDestClasses.run(); |
| 311 | onGetDestClasses.run(); | ||
| 312 | } | ||
| 313 | } | 303 | } |
| 314 | }.start(); | 304 | }).start(); |
| 315 | 305 | ||
| 316 | } else { | 306 | } else { |
| 317 | 307 | ||
| 318 | m_destClasses.setClasses(deobfuscateClasses(match.destClasses, m_destDeobfuscator)); | 308 | destClasses.setClasses(deobfuscateClasses(match.destClasses, destDeobfuscator)); |
| 319 | m_destClasses.expandAll(); | 309 | destClasses.expandAll(); |
| 320 | 310 | ||
| 321 | if (onGetDestClasses != null) { | 311 | if (onGetDestClasses != null) { |
| 322 | onGetDestClasses.run(); | 312 | onGetDestClasses.run(); |
| @@ -325,23 +315,24 @@ public class ClassMatchingGui { | |||
| 325 | } | 315 | } |
| 326 | 316 | ||
| 327 | setDestClass(null); | 317 | setDestClass(null); |
| 328 | m_sourceReader.decompileClass(m_sourceClass, m_sourceDeobfuscator, () -> m_sourceReader.navigateToClassDeclaration(m_sourceClass)); | 318 | sourceReader.decompileClass( |
| 319 | sourceClass, sourceDeobfuscator, () -> sourceReader.navigateToClassDeclaration(sourceClass)); | ||
| 329 | 320 | ||
| 330 | updateMatchButton(); | 321 | updateMatchButton(); |
| 331 | } | 322 | } |
| 332 | 323 | ||
| 333 | private Collection<ClassEntry> getLikelyMatches(ClassEntry sourceClass) { | 324 | private Collection<ClassEntry> getLikelyMatches(ClassEntry sourceClass) { |
| 334 | 325 | ||
| 335 | ClassEntry obfSourceClass = m_sourceDeobfuscator.obfuscateEntry(sourceClass); | 326 | ClassEntry obfSourceClass = sourceDeobfuscator.obfuscateEntry(sourceClass); |
| 336 | 327 | ||
| 337 | // set up identifiers | 328 | // set up identifiers |
| 338 | ClassNamer namer = new ClassNamer(m_classMatches.getUniqueMatches()); | 329 | ClassNamer namer = new ClassNamer(classMatches.getUniqueMatches()); |
| 339 | ClassIdentifier sourceIdentifier = new ClassIdentifier( | 330 | ClassIdentifier sourceIdentifier = new ClassIdentifier( |
| 340 | m_sourceDeobfuscator.getJar(), m_sourceDeobfuscator.getJarIndex(), | 331 | sourceDeobfuscator.getJar(), sourceDeobfuscator.getJarIndex(), |
| 341 | namer.getSourceNamer(), true | 332 | namer.getSourceNamer(), true |
| 342 | ); | 333 | ); |
| 343 | ClassIdentifier destIdentifier = new ClassIdentifier( | 334 | ClassIdentifier destIdentifier = new ClassIdentifier( |
| 344 | m_destDeobfuscator.getJar(), m_destDeobfuscator.getJarIndex(), | 335 | destDeobfuscator.getJar(), destDeobfuscator.getJarIndex(), |
| 345 | namer.getDestNamer(), true | 336 | namer.getDestNamer(), true |
| 346 | ); | 337 | ); |
| 347 | 338 | ||
| @@ -350,15 +341,16 @@ public class ClassMatchingGui { | |||
| 350 | // rank all the unmatched dest classes against the source class | 341 | // rank all the unmatched dest classes against the source class |
| 351 | ClassIdentity sourceIdentity = sourceIdentifier.identify(obfSourceClass); | 342 | ClassIdentity sourceIdentity = sourceIdentifier.identify(obfSourceClass); |
| 352 | List<ClassEntry> scoredDestClasses = Lists.newArrayList(); | 343 | List<ClassEntry> scoredDestClasses = Lists.newArrayList(); |
| 353 | for (ClassEntry unmatchedDestClass : m_classMatches.getUnmatchedDestClasses()) { | 344 | for (ClassEntry unmatchedDestClass : classMatches.getUnmatchedDestClasses()) { |
| 354 | ClassIdentity destIdentity = destIdentifier.identify(unmatchedDestClass); | 345 | ClassIdentity destIdentity = destIdentifier.identify(unmatchedDestClass); |
| 355 | float score = 100.0f * (sourceIdentity.getMatchScore(destIdentity) + destIdentity.getMatchScore(sourceIdentity)) | 346 | float score = 100.0f * (sourceIdentity.getMatchScore(destIdentity) + destIdentity.getMatchScore(sourceIdentity)) |
| 356 | / (sourceIdentity.getMaxMatchScore() + destIdentity.getMaxMatchScore()); | 347 | / (sourceIdentity.getMaxMatchScore() + destIdentity.getMaxMatchScore()); |
| 357 | scoredDestClasses.add(new ScoredClassEntry(unmatchedDestClass, score)); | 348 | scoredDestClasses.add(new ScoredClassEntry(unmatchedDestClass, score)); |
| 358 | } | 349 | } |
| 359 | 350 | ||
| 360 | if (m_top10Matches.isSelected() && scoredDestClasses.size() > 10) { | 351 | if (top10Matches.isSelected() && scoredDestClasses.size() > 10) { |
| 361 | Collections.sort(scoredDestClasses, (a, b) -> { | 352 | scoredDestClasses.sort((a, b) -> |
| 353 | { | ||
| 362 | ScoredClassEntry sa = (ScoredClassEntry) a; | 354 | ScoredClassEntry sa = (ScoredClassEntry) a; |
| 363 | ScoredClassEntry sb = (ScoredClassEntry) b; | 355 | ScoredClassEntry sb = (ScoredClassEntry) b; |
| 364 | return -Float.compare(sa.getScore(), sb.getScore()); | 356 | return -Float.compare(sa.getScore(), sb.getScore()); |
| @@ -376,30 +368,30 @@ public class ClassMatchingGui { | |||
| 376 | protected void setDestClass(ClassEntry classEntry) { | 368 | protected void setDestClass(ClassEntry classEntry) { |
| 377 | 369 | ||
| 378 | // update the current source class | 370 | // update the current source class |
| 379 | m_destClass = classEntry; | 371 | destClass = classEntry; |
| 380 | m_destClassLabel.setText(m_destClass != null ? m_destClass.getName() : ""); | 372 | destClassLabel.setText(destClass != null ? destClass.getName() : ""); |
| 381 | 373 | ||
| 382 | m_destReader.decompileClass(m_destClass, m_destDeobfuscator, () -> m_destReader.navigateToClassDeclaration(m_destClass)); | 374 | destReader.decompileClass(destClass, destDeobfuscator, () -> destReader.navigateToClassDeclaration(destClass)); |
| 383 | 375 | ||
| 384 | updateMatchButton(); | 376 | updateMatchButton(); |
| 385 | } | 377 | } |
| 386 | 378 | ||
| 387 | private void updateMatchButton() { | 379 | private void updateMatchButton() { |
| 388 | 380 | ||
| 389 | ClassEntry obfSource = m_sourceDeobfuscator.obfuscateEntry(m_sourceClass); | 381 | ClassEntry obfSource = sourceDeobfuscator.obfuscateEntry(sourceClass); |
| 390 | ClassEntry obfDest = m_destDeobfuscator.obfuscateEntry(m_destClass); | 382 | ClassEntry obfDest = destDeobfuscator.obfuscateEntry(destClass); |
| 391 | 383 | ||
| 392 | BiMap<ClassEntry, ClassEntry> uniqueMatches = m_classMatches.getUniqueMatches(); | 384 | BiMap<ClassEntry, ClassEntry> uniqueMatches = classMatches.getUniqueMatches(); |
| 393 | boolean twoSelected = m_sourceClass != null && m_destClass != null; | 385 | boolean twoSelected = sourceClass != null && destClass != null; |
| 394 | boolean isMatched = uniqueMatches.containsKey(obfSource) && uniqueMatches.containsValue(obfDest); | 386 | boolean isMatched = uniqueMatches.containsKey(obfSource) && uniqueMatches.containsValue(obfDest); |
| 395 | boolean canMatch = !uniqueMatches.containsKey(obfSource) && !uniqueMatches.containsValue(obfDest); | 387 | boolean canMatch = !uniqueMatches.containsKey(obfSource) && !uniqueMatches.containsValue(obfDest); |
| 396 | 388 | ||
| 397 | GuiTricks.deactivateButton(m_matchButton); | 389 | GuiTricks.deactivateButton(matchButton); |
| 398 | if (twoSelected) { | 390 | if (twoSelected) { |
| 399 | if (isMatched) { | 391 | if (isMatched) { |
| 400 | GuiTricks.activateButton(m_matchButton, "Unmatch", event -> onUnmatchClick()); | 392 | GuiTricks.activateButton(matchButton, "Unmatch", event -> onUnmatchClick()); |
| 401 | } else if (canMatch) { | 393 | } else if (canMatch) { |
| 402 | GuiTricks.activateButton(m_matchButton, "Match", event -> onMatchClick()); | 394 | GuiTricks.activateButton(matchButton, "Match", event -> onMatchClick()); |
| 403 | } | 395 | } |
| 404 | } | 396 | } |
| 405 | } | 397 | } |
| @@ -407,19 +399,19 @@ public class ClassMatchingGui { | |||
| 407 | private void onMatchClick() { | 399 | private void onMatchClick() { |
| 408 | // precondition: source and dest classes are set correctly | 400 | // precondition: source and dest classes are set correctly |
| 409 | 401 | ||
| 410 | ClassEntry obfSource = m_sourceDeobfuscator.obfuscateEntry(m_sourceClass); | 402 | ClassEntry obfSource = sourceDeobfuscator.obfuscateEntry(sourceClass); |
| 411 | ClassEntry obfDest = m_destDeobfuscator.obfuscateEntry(m_destClass); | 403 | ClassEntry obfDest = destDeobfuscator.obfuscateEntry(destClass); |
| 412 | 404 | ||
| 413 | // remove the classes from their match | 405 | // remove the classes from their match |
| 414 | m_classMatches.removeSource(obfSource); | 406 | classMatches.removeSource(obfSource); |
| 415 | m_classMatches.removeDest(obfDest); | 407 | classMatches.removeDest(obfDest); |
| 416 | 408 | ||
| 417 | // add them as matched classes | 409 | // add them as matched classes |
| 418 | m_classMatches.add(new ClassMatch(obfSource, obfDest)); | 410 | classMatches.add(new ClassMatch(obfSource, obfDest)); |
| 419 | 411 | ||
| 420 | ClassEntry nextClass = null; | 412 | ClassEntry nextClass = null; |
| 421 | if (m_advanceCheck.isSelected()) { | 413 | if (advanceCheck.isSelected()) { |
| 422 | nextClass = m_sourceClasses.getNextClass(m_sourceClass); | 414 | nextClass = sourceClasses.getNextClass(sourceClass); |
| 423 | } | 415 | } |
| 424 | 416 | ||
| 425 | save(); | 417 | save(); |
| @@ -433,11 +425,11 @@ public class ClassMatchingGui { | |||
| 433 | private void onUnmatchClick() { | 425 | private void onUnmatchClick() { |
| 434 | // precondition: source and dest classes are set to a unique match | 426 | // precondition: source and dest classes are set to a unique match |
| 435 | 427 | ||
| 436 | ClassEntry obfSource = m_sourceDeobfuscator.obfuscateEntry(m_sourceClass); | 428 | ClassEntry obfSource = sourceDeobfuscator.obfuscateEntry(sourceClass); |
| 437 | 429 | ||
| 438 | // remove the source to break the match, then add the source back as unmatched | 430 | // remove the source to break the match, then add the source back as unmatched |
| 439 | m_classMatches.removeSource(obfSource); | 431 | classMatches.removeSource(obfSource); |
| 440 | m_classMatches.add(new ClassMatch(obfSource, null)); | 432 | classMatches.add(new ClassMatch(obfSource, null)); |
| 441 | 433 | ||
| 442 | save(); | 434 | save(); |
| 443 | updateMatches(); | 435 | updateMatches(); |
| @@ -446,20 +438,20 @@ public class ClassMatchingGui { | |||
| 446 | private void updateMatches() { | 438 | private void updateMatches() { |
| 447 | updateDestMappings(); | 439 | updateDestMappings(); |
| 448 | setDestClass(null); | 440 | setDestClass(null); |
| 449 | m_destClasses.setClasses(null); | 441 | destClasses.setClasses(null); |
| 450 | updateMatchButton(); | 442 | updateMatchButton(); |
| 451 | 443 | ||
| 452 | // remember where we were in the source tree | 444 | // remember where we were in the source tree |
| 453 | String packageName = m_sourceClasses.getSelectedPackage(); | 445 | String packageName = sourceClasses.getSelectedPackage(); |
| 454 | 446 | ||
| 455 | setSourceType(m_sourceType); | 447 | setSourceType(sourceType); |
| 456 | 448 | ||
| 457 | m_sourceClasses.expandPackage(packageName); | 449 | sourceClasses.expandPackage(packageName); |
| 458 | } | 450 | } |
| 459 | 451 | ||
| 460 | private void save() { | 452 | private void save() { |
| 461 | if (m_saveListener != null) { | 453 | if (saveListener != null) { |
| 462 | m_saveListener.save(m_classMatches); | 454 | saveListener.save(classMatches); |
| 463 | } | 455 | } |
| 464 | } | 456 | } |
| 465 | 457 | ||
| @@ -469,17 +461,17 @@ public class ClassMatchingGui { | |||
| 469 | 461 | ||
| 470 | // compute a new matching | 462 | // compute a new matching |
| 471 | ClassMatching matching = MappingsConverter.computeMatching( | 463 | ClassMatching matching = MappingsConverter.computeMatching( |
| 472 | m_sourceDeobfuscator.getJar(), m_sourceDeobfuscator.getJarIndex(), | 464 | sourceDeobfuscator.getJar(), sourceDeobfuscator.getJarIndex(), |
| 473 | m_destDeobfuscator.getJar(), m_destDeobfuscator.getJarIndex(), | 465 | destDeobfuscator.getJar(), destDeobfuscator.getJarIndex(), |
| 474 | m_classMatches.getUniqueMatches() | 466 | classMatches.getUniqueMatches() |
| 475 | ); | 467 | ); |
| 476 | ClassMatches newMatches = new ClassMatches(matching.matches()); | 468 | ClassMatches newMatches = new ClassMatches(matching.matches()); |
| 477 | System.out.println(String.format("Automatch found %d new matches", | 469 | System.out.println(String.format("Automatch found %d new matches", |
| 478 | newMatches.getUniqueMatches().size() - m_classMatches.getUniqueMatches().size() | 470 | newMatches.getUniqueMatches().size() - classMatches.getUniqueMatches().size() |
| 479 | )); | 471 | )); |
| 480 | 472 | ||
| 481 | // update the current matches | 473 | // update the current matches |
| 482 | m_classMatches = newMatches; | 474 | classMatches = newMatches; |
| 483 | save(); | 475 | save(); |
| 484 | updateMatches(); | 476 | updateMatches(); |
| 485 | } | 477 | } |
| @@ -492,17 +484,17 @@ public class ClassMatchingGui { | |||
| 492 | 484 | ||
| 493 | // make sure we have a source class | 485 | // make sure we have a source class |
| 494 | if (sourceClass == null) { | 486 | if (sourceClass == null) { |
| 495 | sourceClass = m_sourceClasses.getSelectedClass(); | 487 | sourceClass = sourceClasses.getSelectedClass(); |
| 496 | if (sourceClass != null) { | 488 | if (sourceClass != null) { |
| 497 | sourceClass = m_sourceClasses.getNextClass(sourceClass); | 489 | sourceClass = sourceClasses.getNextClass(sourceClass); |
| 498 | } else { | 490 | } else { |
| 499 | sourceClass = m_sourceClasses.getFirstClass(); | 491 | sourceClass = sourceClasses.getFirstClass(); |
| 500 | } | 492 | } |
| 501 | } | 493 | } |
| 502 | 494 | ||
| 503 | // set the source class | 495 | // set the source class |
| 504 | setSourceClass(sourceClass, this::pickBestDestClass); | 496 | setSourceClass(sourceClass, this::pickBestDestClass); |
| 505 | m_sourceClasses.setSelectionClass(sourceClass); | 497 | sourceClasses.setSelectionClass(sourceClass); |
| 506 | } | 498 | } |
| 507 | 499 | ||
| 508 | private void pickBestDestClass() { | 500 | private void pickBestDestClass() { |
| @@ -510,8 +502,8 @@ public class ClassMatchingGui { | |||
| 510 | // then, pick the best dest class | 502 | // then, pick the best dest class |
| 511 | ClassEntry firstClass = null; | 503 | ClassEntry firstClass = null; |
| 512 | ScoredClassEntry bestDestClass = null; | 504 | ScoredClassEntry bestDestClass = null; |
| 513 | for (ClassSelectorPackageNode packageNode : m_destClasses.packageNodes()) { | 505 | for (ClassSelectorPackageNode packageNode : destClasses.packageNodes()) { |
| 514 | for (ClassSelectorClassNode classNode : m_destClasses.classNodes(packageNode)) { | 506 | for (ClassSelectorClassNode classNode : destClasses.classNodes(packageNode)) { |
| 515 | if (firstClass == null) { | 507 | if (firstClass == null) { |
| 516 | firstClass = classNode.getClassEntry(); | 508 | firstClass = classNode.getClassEntry(); |
| 517 | } | 509 | } |
| @@ -533,14 +525,14 @@ public class ClassMatchingGui { | |||
| 533 | } | 525 | } |
| 534 | 526 | ||
| 535 | setDestClass(destClass); | 527 | setDestClass(destClass); |
| 536 | m_destClasses.setSelectionClass(destClass); | 528 | destClasses.setSelectionClass(destClass); |
| 537 | } | 529 | } |
| 538 | 530 | ||
| 539 | private void toggleTop10Matches() { | 531 | private void toggleTop10Matches() { |
| 540 | if (m_sourceClass != null) { | 532 | if (sourceClass != null) { |
| 541 | m_destClasses.clearSelection(); | 533 | destClasses.clearSelection(); |
| 542 | m_destClasses.setClasses(deobfuscateClasses(getLikelyMatches(m_sourceClass), m_destDeobfuscator)); | 534 | destClasses.setClasses(deobfuscateClasses(getLikelyMatches(sourceClass), destDeobfuscator)); |
| 543 | m_destClasses.expandAll(); | 535 | destClasses.expandAll(); |
| 544 | } | 536 | } |
| 545 | } | 537 | } |
| 546 | } | 538 | } |