diff options
| author | 2015-02-28 18:00:25 -0500 | |
|---|---|---|
| committer | 2015-02-28 18:00:25 -0500 | |
| commit | 741e3472f76d959645ee0e025547d69a03e5b6f2 (patch) | |
| tree | da17641de8b891721e435636edbf7a5077d9e6ec /src/cuchaz/enigma/convert/ClassMatching.java | |
| parent | ignore more harmless exceptions from the buggy highlight painter system (diff) | |
| download | enigma-fork-741e3472f76d959645ee0e025547d69a03e5b6f2.tar.gz enigma-fork-741e3472f76d959645ee0e025547d69a03e5b6f2.tar.xz enigma-fork-741e3472f76d959645ee0e025547d69a03e5b6f2.zip | |
fix up conversion tool to handle Minecraft 1.8.3
Diffstat (limited to 'src/cuchaz/enigma/convert/ClassMatching.java')
| -rw-r--r-- | src/cuchaz/enigma/convert/ClassMatching.java | 200 |
1 files changed, 91 insertions, 109 deletions
diff --git a/src/cuchaz/enigma/convert/ClassMatching.java b/src/cuchaz/enigma/convert/ClassMatching.java index 53b6f7f..b94fd8b 100644 --- a/src/cuchaz/enigma/convert/ClassMatching.java +++ b/src/cuchaz/enigma/convert/ClassMatching.java | |||
| @@ -10,164 +10,146 @@ | |||
| 10 | ******************************************************************************/ | 10 | ******************************************************************************/ |
| 11 | package cuchaz.enigma.convert; | 11 | package cuchaz.enigma.convert; |
| 12 | 12 | ||
| 13 | import java.util.AbstractMap; | ||
| 14 | import java.util.ArrayList; | 13 | import java.util.ArrayList; |
| 15 | import java.util.Arrays; | ||
| 16 | import java.util.Collection; | 14 | import java.util.Collection; |
| 17 | import java.util.List; | 15 | import java.util.List; |
| 18 | import java.util.Map; | 16 | import java.util.Map.Entry; |
| 17 | import java.util.Set; | ||
| 19 | 18 | ||
| 20 | import com.google.common.collect.ArrayListMultimap; | ||
| 21 | import com.google.common.collect.BiMap; | 19 | import com.google.common.collect.BiMap; |
| 22 | import com.google.common.collect.HashBiMap; | 20 | import com.google.common.collect.HashBiMap; |
| 23 | import com.google.common.collect.Lists; | 21 | import com.google.common.collect.Lists; |
| 24 | import com.google.common.collect.Maps; | 22 | import com.google.common.collect.Sets; |
| 25 | import com.google.common.collect.Multimap; | 23 | |
| 24 | import cuchaz.enigma.mapping.ClassEntry; | ||
| 26 | 25 | ||
| 27 | public class ClassMatching { | 26 | public class ClassMatching { |
| 28 | 27 | ||
| 29 | private Multimap<ClassIdentity,ClassIdentity> m_sourceClasses; | 28 | private ClassForest m_sourceClasses; |
| 30 | private Multimap<ClassIdentity,ClassIdentity> m_matchedDestClasses; | 29 | private ClassForest m_destClasses; |
| 31 | private List<ClassIdentity> m_unmatchedDestClasses; | 30 | private BiMap<ClassEntry,ClassEntry> m_knownMatches; |
| 32 | |||
| 33 | public ClassMatching() { | ||
| 34 | m_sourceClasses = ArrayListMultimap.create(); | ||
| 35 | m_matchedDestClasses = ArrayListMultimap.create(); | ||
| 36 | m_unmatchedDestClasses = Lists.newArrayList(); | ||
| 37 | } | ||
| 38 | 31 | ||
| 39 | public void addSource(ClassIdentity c) { | 32 | public ClassMatching(ClassIdentifier sourceIdentifier, ClassIdentifier destIdentifier) { |
| 40 | m_sourceClasses.put(c, c); | 33 | m_sourceClasses = new ClassForest(sourceIdentifier); |
| 34 | m_destClasses = new ClassForest(destIdentifier); | ||
| 35 | m_knownMatches = HashBiMap.create(); | ||
| 41 | } | 36 | } |
| 42 | 37 | ||
| 43 | public void matchDestClass(ClassIdentity destClass) { | 38 | public void addKnownMatches(BiMap<ClassEntry,ClassEntry> knownMatches) { |
| 44 | Collection<ClassIdentity> matchedSourceClasses = m_sourceClasses.get(destClass); | 39 | m_knownMatches.putAll(knownMatches); |
| 45 | if (matchedSourceClasses.isEmpty()) { | ||
| 46 | // no match | ||
| 47 | m_unmatchedDestClasses.add(destClass); | ||
| 48 | } else { | ||
| 49 | // found a match | ||
| 50 | m_matchedDestClasses.put(destClass, destClass); | ||
| 51 | |||
| 52 | // DEBUG | ||
| 53 | ClassIdentity sourceClass = matchedSourceClasses.iterator().next(); | ||
| 54 | assert (sourceClass.hashCode() == destClass.hashCode()); | ||
| 55 | assert (sourceClass.equals(destClass)); | ||
| 56 | } | ||
| 57 | } | 40 | } |
| 58 | 41 | ||
| 59 | public void removeSource(ClassIdentity sourceClass) { | 42 | public void match(Iterable<ClassEntry> sourceClasses, Iterable<ClassEntry> destClasses) { |
| 60 | m_sourceClasses.remove(sourceClass, sourceClass); | 43 | m_sourceClasses.addAll(sourceClasses); |
| 44 | m_destClasses.addAll(destClasses); | ||
| 61 | } | 45 | } |
| 62 | 46 | ||
| 63 | public void removeDest(ClassIdentity destClass) { | 47 | public Collection<ClassMatch> matches() { |
| 64 | m_matchedDestClasses.remove(destClass, destClass); | 48 | List<ClassMatch> matches = Lists.newArrayList(); |
| 65 | m_unmatchedDestClasses.remove(destClass); | 49 | for (Entry<ClassEntry,ClassEntry> entry : m_knownMatches.entrySet()) { |
| 50 | matches.add(new ClassMatch( | ||
| 51 | entry.getKey(), | ||
| 52 | entry.getValue() | ||
| 53 | )); | ||
| 54 | } | ||
| 55 | for (ClassIdentity identity : m_sourceClasses.identities()) { | ||
| 56 | matches.add(new ClassMatch( | ||
| 57 | m_sourceClasses.getClasses(identity), | ||
| 58 | m_destClasses.getClasses(identity) | ||
| 59 | )); | ||
| 60 | } | ||
| 61 | for (ClassIdentity identity : m_destClasses.identities()) { | ||
| 62 | if (!m_sourceClasses.containsIdentity(identity)) { | ||
| 63 | matches.add(new ClassMatch( | ||
| 64 | new ArrayList<ClassEntry>(), | ||
| 65 | m_destClasses.getClasses(identity) | ||
| 66 | )); | ||
| 67 | } | ||
| 68 | } | ||
| 69 | return matches; | ||
| 66 | } | 70 | } |
| 67 | 71 | ||
| 68 | public List<ClassIdentity> getSourceClasses() { | 72 | public Collection<ClassEntry> sourceClasses() { |
| 69 | return new ArrayList<ClassIdentity>(m_sourceClasses.values()); | 73 | Set<ClassEntry> classes = Sets.newHashSet(); |
| 74 | for (ClassMatch match : matches()) { | ||
| 75 | classes.addAll(match.sourceClasses); | ||
| 76 | } | ||
| 77 | return classes; | ||
| 70 | } | 78 | } |
| 71 | 79 | ||
| 72 | public List<ClassIdentity> getDestClasses() { | 80 | public Collection<ClassEntry> destClasses() { |
| 73 | List<ClassIdentity> classes = Lists.newArrayList(); | 81 | Set<ClassEntry> classes = Sets.newHashSet(); |
| 74 | classes.addAll(m_matchedDestClasses.values()); | 82 | for (ClassMatch match : matches()) { |
| 75 | classes.addAll(m_unmatchedDestClasses); | 83 | classes.addAll(match.destClasses); |
| 84 | } | ||
| 76 | return classes; | 85 | return classes; |
| 77 | } | 86 | } |
| 78 | 87 | ||
| 79 | public BiMap<ClassIdentity,ClassIdentity> getUniqueMatches() { | 88 | public BiMap<ClassEntry,ClassEntry> uniqueMatches() { |
| 80 | BiMap<ClassIdentity,ClassIdentity> uniqueMatches = HashBiMap.create(); | 89 | BiMap<ClassEntry,ClassEntry> uniqueMatches = HashBiMap.create(); |
| 81 | for (ClassIdentity sourceClass : m_sourceClasses.keySet()) { | 90 | for (ClassMatch match : matches()) { |
| 82 | Collection<ClassIdentity> matchedSourceClasses = m_sourceClasses.get(sourceClass); | 91 | if (match.isMatched() && !match.isAmbiguous()) { |
| 83 | Collection<ClassIdentity> matchedDestClasses = m_matchedDestClasses.get(sourceClass); | 92 | uniqueMatches.put(match.getUniqueSource(), match.getUniqueDest()); |
| 84 | if (matchedSourceClasses.size() == 1 && matchedDestClasses.size() == 1) { | ||
| 85 | ClassIdentity matchedSourceClass = matchedSourceClasses.iterator().next(); | ||
| 86 | ClassIdentity matchedDestClass = matchedDestClasses.iterator().next(); | ||
| 87 | uniqueMatches.put(matchedSourceClass, matchedDestClass); | ||
| 88 | } | 93 | } |
| 89 | } | 94 | } |
| 90 | return uniqueMatches; | 95 | return uniqueMatches; |
| 91 | } | 96 | } |
| 92 | 97 | ||
| 93 | public BiMap<List<ClassIdentity>,List<ClassIdentity>> getAmbiguousMatches() { | 98 | public Collection<ClassMatch> ambiguousMatches() { |
| 94 | BiMap<List<ClassIdentity>,List<ClassIdentity>> ambiguousMatches = HashBiMap.create(); | 99 | List<ClassMatch> ambiguousMatches = Lists.newArrayList(); |
| 95 | for (ClassIdentity sourceClass : m_sourceClasses.keySet()) { | 100 | for (ClassMatch match : matches()) { |
| 96 | Collection<ClassIdentity> matchedSourceClasses = m_sourceClasses.get(sourceClass); | 101 | if (match.isMatched() && match.isAmbiguous()) { |
| 97 | Collection<ClassIdentity> matchedDestClasses = m_matchedDestClasses.get(sourceClass); | 102 | ambiguousMatches.add(match); |
| 98 | if (matchedSourceClasses.size() > 1 && matchedDestClasses.size() > 1) { | ||
| 99 | ambiguousMatches.put( | ||
| 100 | new ArrayList<ClassIdentity>(matchedSourceClasses), | ||
| 101 | new ArrayList<ClassIdentity>(matchedDestClasses) | ||
| 102 | ); | ||
| 103 | } | 103 | } |
| 104 | } | 104 | } |
| 105 | return ambiguousMatches; | 105 | return ambiguousMatches; |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | public int getNumAmbiguousSourceMatches() { | 108 | public Collection<ClassEntry> unmatchedSourceClasses() { |
| 109 | int num = 0; | 109 | List<ClassEntry> classes = Lists.newArrayList(); |
| 110 | for (Map.Entry<List<ClassIdentity>,List<ClassIdentity>> entry : getAmbiguousMatches().entrySet()) { | 110 | for (ClassMatch match : matches()) { |
| 111 | num += entry.getKey().size(); | 111 | if (!match.isMatched() && !match.sourceClasses.isEmpty()) { |
| 112 | } | 112 | classes.addAll(match.sourceClasses); |
| 113 | return num; | 113 | } |
| 114 | } | ||
| 115 | |||
| 116 | public int getNumAmbiguousDestMatches() { | ||
| 117 | int num = 0; | ||
| 118 | for (Map.Entry<List<ClassIdentity>,List<ClassIdentity>> entry : getAmbiguousMatches().entrySet()) { | ||
| 119 | num += entry.getValue().size(); | ||
| 120 | } | 114 | } |
| 121 | return num; | 115 | return classes; |
| 122 | } | 116 | } |
| 123 | 117 | ||
| 124 | public List<ClassIdentity> getUnmatchedSourceClasses() { | 118 | public Collection<ClassEntry> unmatchedDestClasses() { |
| 125 | List<ClassIdentity> classes = Lists.newArrayList(); | 119 | List<ClassEntry> classes = Lists.newArrayList(); |
| 126 | for (ClassIdentity sourceClass : getSourceClasses()) { | 120 | for (ClassMatch match : matches()) { |
| 127 | if (m_matchedDestClasses.get(sourceClass).isEmpty()) { | 121 | if (!match.isMatched() && !match.destClasses.isEmpty()) { |
| 128 | classes.add(sourceClass); | 122 | classes.addAll(match.destClasses); |
| 129 | } | 123 | } |
| 130 | } | 124 | } |
| 131 | return classes; | 125 | return classes; |
| 132 | } | 126 | } |
| 133 | 127 | ||
| 134 | public List<ClassIdentity> getUnmatchedDestClasses() { | 128 | public ClassIdentifier getSourceIdentifier() { |
| 135 | return new ArrayList<ClassIdentity>(m_unmatchedDestClasses); | 129 | return m_sourceClasses.getIdentifier(); |
| 136 | } | 130 | } |
| 137 | 131 | ||
| 138 | public Map<String,Map.Entry<ClassIdentity,List<ClassIdentity>>> getIndex() { | 132 | public ClassIdentifier getDestIdentifier() { |
| 139 | Map<String,Map.Entry<ClassIdentity,List<ClassIdentity>>> conversion = Maps.newHashMap(); | 133 | return m_destClasses.getIdentifier(); |
| 140 | for (Map.Entry<ClassIdentity,ClassIdentity> entry : getUniqueMatches().entrySet()) { | ||
| 141 | conversion.put( | ||
| 142 | entry.getKey().getClassEntry().getName(), | ||
| 143 | new AbstractMap.SimpleEntry<ClassIdentity,List<ClassIdentity>>(entry.getKey(), Arrays.asList(entry.getValue())) | ||
| 144 | ); | ||
| 145 | } | ||
| 146 | for (Map.Entry<List<ClassIdentity>,List<ClassIdentity>> entry : getAmbiguousMatches().entrySet()) { | ||
| 147 | for (ClassIdentity sourceClass : entry.getKey()) { | ||
| 148 | conversion.put( | ||
| 149 | sourceClass.getClassEntry().getName(), | ||
| 150 | new AbstractMap.SimpleEntry<ClassIdentity,List<ClassIdentity>>(sourceClass, entry.getValue()) | ||
| 151 | ); | ||
| 152 | } | ||
| 153 | } | ||
| 154 | for (ClassIdentity sourceClass : getUnmatchedSourceClasses()) { | ||
| 155 | conversion.put( | ||
| 156 | sourceClass.getClassEntry().getName(), | ||
| 157 | new AbstractMap.SimpleEntry<ClassIdentity,List<ClassIdentity>>(sourceClass, getUnmatchedDestClasses()) | ||
| 158 | ); | ||
| 159 | } | ||
| 160 | return conversion; | ||
| 161 | } | 134 | } |
| 162 | 135 | ||
| 163 | @Override | 136 | @Override |
| 164 | public String toString() { | 137 | public String toString() { |
| 138 | |||
| 139 | // count the ambiguous classes | ||
| 140 | int numAmbiguousSource = 0; | ||
| 141 | int numAmbiguousDest = 0; | ||
| 142 | for (ClassMatch match : ambiguousMatches()) { | ||
| 143 | numAmbiguousSource += match.sourceClasses.size(); | ||
| 144 | numAmbiguousDest += match.destClasses.size(); | ||
| 145 | } | ||
| 146 | |||
| 165 | StringBuilder buf = new StringBuilder(); | 147 | StringBuilder buf = new StringBuilder(); |
| 166 | buf.append(String.format("%12s%8s%8s\n", "", "Source", "Dest")); | 148 | buf.append(String.format("%20s%8s%8s\n", "", "Source", "Dest")); |
| 167 | buf.append(String.format("%12s%8d%8d\n", "Classes", getSourceClasses().size(), getDestClasses().size())); | 149 | buf.append(String.format("%20s%8d%8d\n", "Classes", sourceClasses().size(), destClasses().size())); |
| 168 | buf.append(String.format("%12s%8d%8d\n", "Unique", getUniqueMatches().size(), getUniqueMatches().size())); | 150 | buf.append(String.format("%20s%8d%8d\n", "Uniquely matched", uniqueMatches().size(), uniqueMatches().size())); |
| 169 | buf.append(String.format("%12s%8d%8d\n", "Ambiguous", getNumAmbiguousSourceMatches(), getNumAmbiguousDestMatches())); | 151 | buf.append(String.format("%20s%8d%8d\n", "Ambiguously matched", numAmbiguousSource, numAmbiguousDest)); |
| 170 | buf.append(String.format("%12s%8d%8d\n", "Unmatched", getUnmatchedSourceClasses().size(), getUnmatchedDestClasses().size())); | 152 | buf.append(String.format("%20s%8d%8d\n", "Unmatched", unmatchedSourceClasses().size(), unmatchedDestClasses().size())); |
| 171 | return buf.toString(); | 153 | return buf.toString(); |
| 172 | } | 154 | } |
| 173 | } | 155 | } |