summaryrefslogtreecommitdiff
path: root/src/cuchaz/enigma/gui/MatchingGui.java
blob: 53c767ac2b6705e6c1cfd78c1620018e3e3e186d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package cuchaz.enigma.gui;

import cuchaz.enigma.Deobfuscator;
import cuchaz.enigma.convert.Matches;


public class MatchingGui {

	public MatchingGui(Matches matches, Deobfuscator sourceDeobfuscator, Deobfuscator destDeobfuscator) {
		// TODO Auto-generated constructor stub
	}
	

	/* TODO: see if we can use any of this here
	public static doTheThings() {
		
		// get all the obf class names used in the mappings
		Set<ClassEntry> usedClasses = Sets.newHashSet();
		for (String className : mappings.getAllObfClassNames()) {
			usedClasses.add(new ClassEntry(className));
		}
		System.out.println(String.format("Mappings reference %d/%d classes",
			usedClasses.size(), sourceIndex.getObfClassEntries().size()
		));
		
		// get the used matches
		Collection<ClassMatch> matches = matching.matches();
		Matches usedMatches = new Matches();
		for (ClassMatch match : matching.matches()) {
			if (!match.intersectSourceClasses(usedClasses).isEmpty()) {
				usedMatches.add(match);
			}
		}
		System.out.println(String.format("Mappings reference %d/%d match groups",
			usedMatches.size(), matches.size()
		));
		
		// see what the used classes map to
		BiMap<ClassEntry,ClassEntry> uniqueUsedMatches = HashBiMap.create();
		Map<ClassEntry,ClassMatch> ambiguousUsedMatches = Maps.newHashMap();
		Set<ClassEntry> unmatchedUsedClasses = Sets.newHashSet();
		for (ClassMatch match : matching.matches()) {
			Set<ClassEntry> matchUsedClasses = match.intersectSourceClasses(usedClasses);
			if (matchUsedClasses.isEmpty()) {
				continue;
			}
			
			usedMatches.add(match);

			// classify the match
			if (!match.isMatched()) {
				// unmatched
				unmatchedUsedClasses.addAll(matchUsedClasses);
			} else {
				if (match.isAmbiguous()) {
					// ambiguously matched
					for (ClassEntry matchUsedClass : matchUsedClasses) {
						ambiguousUsedMatches.put(matchUsedClass, match);
					}
				} else {
					// uniquely matched
					uniqueUsedMatches.put(match.getUniqueSource(), match.getUniqueDest());
				}
			}
		}
		
		// get unmatched dest classes
		Set<ClassEntry> unmatchedDestClasses = Sets.newHashSet();
		for (ClassMatch match : matching.matches()) {
			if (!match.isMatched()) {
				unmatchedDestClasses.addAll(match.destClasses);
			}
		}
		
		// warn about the ambiguous used matches
		if (ambiguousUsedMatches.size() > 0) {
			System.out.println(String.format("%d source classes have ambiguous mappings", ambiguousUsedMatches.size()));
			List<ClassMatch> ambiguousMatchesList = Lists.newArrayList(Sets.newHashSet(ambiguousUsedMatches.values()));
			Collections.sort(ambiguousMatchesList, new Comparator<ClassMatch>() {
				@Override
				public int compare(ClassMatch a, ClassMatch b) {
					String aName = a.sourceClasses.iterator().next().getName();
					String bName = b.sourceClasses.iterator().next().getName();
					return aName.compareTo(bName);
				}
			});
			for (ClassMatch match : ambiguousMatchesList) {
				System.out.println("Ambiguous matching:");
				System.out.println("\tSource: " + getClassNames(match.sourceClasses));
				System.out.println("\tDest:   " + getClassNames(match.destClasses));
			}
		}
		
		// warn about unmatched used classes
		for (ClassEntry unmatchedUsedClass : unmatchedUsedClasses) {
			System.out.println("No exact match for source class " + unmatchedUsedClass.getClassEntry());
			
			// rank all the unmatched dest classes against the used class
			ClassIdentity sourceIdentity = matching.getSourceIdentifier().identify(unmatchedUsedClass);
			Multimap<Integer,ClassEntry> scoredDestClasses = ArrayListMultimap.create();
			for (ClassEntry unmatchedDestClass : unmatchedDestClasses) {
				ClassIdentity destIdentity = matching.getDestIdentifier().identify(unmatchedDestClass);	
				scoredDestClasses.put(sourceIdentity.getMatchScore(destIdentity), unmatchedDestClass);
			}
			
			List<Integer> scores = new ArrayList<Integer>(scoredDestClasses.keySet());
			Collections.sort(scores, Collections.reverseOrder());
			printScoredMatches(sourceIdentity.getMaxMatchScore(), scores, scoredDestClasses);
		}
		
		// bail if there were unmatched classes
		if (!unmatchedUsedClasses.isEmpty()) {
			throw new Error("There were " + unmatchedUsedClasses.size() + " unmatched classes!");
		}
	}
	
	private static void printScoredMatches(int maxScore, List<Integer> scores, Multimap<Integer,ClassEntry> scoredMatches) {
		int numScoredMatchesShown = 0;
		for (int score : scores) {
			for (ClassEntry classEntry : scoredMatches.get(score)) {
				System.out.println(String.format("\tScore: %3d %3.0f%%   %s",
					score, 100.0 * score / maxScore, classEntry.getName()
				));
				if (numScoredMatchesShown++ > 10) {
					return;
				}
			}
		}
	}
	
	private static List<String> getClassNames(Collection<ClassEntry> classes) {
		List<String> out = Lists.newArrayList();
		for (ClassEntry c : classes) {
			out.add(c.getName());
		}
		Collections.sort(out);
		return out;
	}
	*/
}