summaryrefslogtreecommitdiff
path: root/src/cuchaz/enigma/mapping/Mappings.java
diff options
context:
space:
mode:
authorGravatar Michael Smith2015-05-21 23:30:00 +0100
committerGravatar Michael Smith2015-05-21 23:30:00 +0100
commite3f452250e51b7271f3989c7dfd12e4422934942 (patch)
tree5aa482f9a6e21eb318a3e23e7d8274d77c73faf6 /src/cuchaz/enigma/mapping/Mappings.java
downloadenigma-fork-e3f452250e51b7271f3989c7dfd12e4422934942.tar.gz
enigma-fork-e3f452250e51b7271f3989c7dfd12e4422934942.tar.xz
enigma-fork-e3f452250e51b7271f3989c7dfd12e4422934942.zip
Support Gradle alongside SSJB
This makes builds faster, simpler and better automated but still keeps Cuchaz happy. :)
Diffstat (limited to 'src/cuchaz/enigma/mapping/Mappings.java')
-rw-r--r--src/cuchaz/enigma/mapping/Mappings.java216
1 files changed, 216 insertions, 0 deletions
diff --git a/src/cuchaz/enigma/mapping/Mappings.java b/src/cuchaz/enigma/mapping/Mappings.java
new file mode 100644
index 0000000..11ed5d0
--- /dev/null
+++ b/src/cuchaz/enigma/mapping/Mappings.java
@@ -0,0 +1,216 @@
1/*******************************************************************************
2 * Copyright (c) 2015 Jeff Martin.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the GNU Lesser General Public
5 * License v3.0 which accompanies this distribution, and is available at
6 * http://www.gnu.org/licenses/lgpl.html
7 *
8 * Contributors:
9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/
11package cuchaz.enigma.mapping;
12
13import java.io.Serializable;
14import java.util.ArrayList;
15import java.util.Collection;
16import java.util.List;
17import java.util.Map;
18import java.util.Set;
19
20import com.google.common.collect.Lists;
21import com.google.common.collect.Maps;
22import com.google.common.collect.Sets;
23
24import cuchaz.enigma.analysis.TranslationIndex;
25
26public class Mappings implements Serializable {
27
28 private static final long serialVersionUID = 4649790259460259026L;
29
30 protected Map<String,ClassMapping> m_classesByObf;
31 protected Map<String,ClassMapping> m_classesByDeobf;
32
33 public Mappings() {
34 m_classesByObf = Maps.newHashMap();
35 m_classesByDeobf = Maps.newHashMap();
36 }
37
38 public Mappings(Iterable<ClassMapping> classes) {
39 this();
40
41 for (ClassMapping classMapping : classes) {
42 m_classesByObf.put(classMapping.getObfFullName(), classMapping);
43 if (classMapping.getDeobfName() != null) {
44 m_classesByDeobf.put(classMapping.getDeobfName(), classMapping);
45 }
46 }
47 }
48
49 public Collection<ClassMapping> classes() {
50 assert (m_classesByObf.size() >= m_classesByDeobf.size());
51 return m_classesByObf.values();
52 }
53
54 public void addClassMapping(ClassMapping classMapping) {
55 if (m_classesByObf.containsKey(classMapping.getObfFullName())) {
56 throw new Error("Already have mapping for " + classMapping.getObfFullName());
57 }
58 boolean obfWasAdded = m_classesByObf.put(classMapping.getObfFullName(), classMapping) == null;
59 assert (obfWasAdded);
60 if (classMapping.getDeobfName() != null) {
61 if (m_classesByDeobf.containsKey(classMapping.getDeobfName())) {
62 throw new Error("Already have mapping for " + classMapping.getDeobfName());
63 }
64 boolean deobfWasAdded = m_classesByDeobf.put(classMapping.getDeobfName(), classMapping) == null;
65 assert (deobfWasAdded);
66 }
67 }
68
69 public void removeClassMapping(ClassMapping classMapping) {
70 boolean obfWasRemoved = m_classesByObf.remove(classMapping.getObfFullName()) != null;
71 assert (obfWasRemoved);
72 if (classMapping.getDeobfName() != null) {
73 boolean deobfWasRemoved = m_classesByDeobf.remove(classMapping.getDeobfName()) != null;
74 assert (deobfWasRemoved);
75 }
76 }
77
78 public ClassMapping getClassByObf(ClassEntry entry) {
79 return getClassByObf(entry.getName());
80 }
81
82 public ClassMapping getClassByObf(String obfName) {
83 return m_classesByObf.get(obfName);
84 }
85
86 public ClassMapping getClassByDeobf(ClassEntry entry) {
87 return getClassByDeobf(entry.getName());
88 }
89
90 public ClassMapping getClassByDeobf(String deobfName) {
91 return m_classesByDeobf.get(deobfName);
92 }
93
94 public void setClassDeobfName(ClassMapping classMapping, String deobfName) {
95 if (classMapping.getDeobfName() != null) {
96 boolean wasRemoved = m_classesByDeobf.remove(classMapping.getDeobfName()) != null;
97 assert (wasRemoved);
98 }
99 classMapping.setDeobfName(deobfName);
100 if (deobfName != null) {
101 boolean wasAdded = m_classesByDeobf.put(deobfName, classMapping) == null;
102 assert (wasAdded);
103 }
104 }
105
106 public Translator getTranslator(TranslationDirection direction, TranslationIndex index) {
107 switch (direction) {
108 case Deobfuscating:
109
110 return new Translator(direction, m_classesByObf, index);
111
112 case Obfuscating:
113
114 // fill in the missing deobf class entries with obf entries
115 Map<String,ClassMapping> classes = Maps.newHashMap();
116 for (ClassMapping classMapping : classes()) {
117 if (classMapping.getDeobfName() != null) {
118 classes.put(classMapping.getDeobfName(), classMapping);
119 } else {
120 classes.put(classMapping.getObfFullName(), classMapping);
121 }
122 }
123
124 // translate the translation index
125 // NOTE: this isn't actually recursive
126 TranslationIndex deobfIndex = new TranslationIndex(index, getTranslator(TranslationDirection.Deobfuscating, index));
127
128 return new Translator(direction, classes, deobfIndex);
129
130 default:
131 throw new Error("Invalid translation direction!");
132 }
133 }
134
135 @Override
136 public String toString() {
137 StringBuilder buf = new StringBuilder();
138 for (ClassMapping classMapping : m_classesByObf.values()) {
139 buf.append(classMapping.toString());
140 buf.append("\n");
141 }
142 return buf.toString();
143 }
144
145 public void renameObfClass(String oldObfName, String newObfName) {
146 for (ClassMapping classMapping : new ArrayList<ClassMapping>(classes())) {
147 if (classMapping.renameObfClass(oldObfName, newObfName)) {
148 boolean wasRemoved = m_classesByObf.remove(oldObfName) != null;
149 assert (wasRemoved);
150 boolean wasAdded = m_classesByObf.put(newObfName, classMapping) == null;
151 assert (wasAdded);
152 }
153 }
154 }
155
156 public Set<String> getAllObfClassNames() {
157 final Set<String> classNames = Sets.newHashSet();
158 for (ClassMapping classMapping : classes()) {
159
160 // add the class name
161 classNames.add(classMapping.getObfFullName());
162
163 // add classes from method signatures
164 for (MethodMapping methodMapping : classMapping.methods()) {
165 for (Type type : methodMapping.getObfSignature().types()) {
166 if (type.hasClass()) {
167 classNames.add(type.getClassEntry().getClassName());
168 }
169 }
170 }
171 }
172 return classNames;
173 }
174
175 public boolean containsDeobfClass(String deobfName) {
176 return m_classesByDeobf.containsKey(deobfName);
177 }
178
179 public boolean containsDeobfField(ClassEntry obfClassEntry, String deobfName, Type obfType) {
180 ClassMapping classMapping = m_classesByObf.get(obfClassEntry.getName());
181 if (classMapping != null) {
182 return classMapping.containsDeobfField(deobfName, obfType);
183 }
184 return false;
185 }
186
187 public boolean containsDeobfMethod(ClassEntry obfClassEntry, String deobfName, Signature deobfSignature) {
188 ClassMapping classMapping = m_classesByObf.get(obfClassEntry.getName());
189 if (classMapping != null) {
190 return classMapping.containsDeobfMethod(deobfName, deobfSignature);
191 }
192 return false;
193 }
194
195 public boolean containsArgument(BehaviorEntry obfBehaviorEntry, String name) {
196 ClassMapping classMapping = m_classesByObf.get(obfBehaviorEntry.getClassName());
197 if (classMapping != null) {
198 return classMapping.containsArgument(obfBehaviorEntry, name);
199 }
200 return false;
201 }
202
203 public List<ClassMapping> getClassMappingChain(ClassEntry obfClass) {
204 List<ClassMapping> mappingChain = Lists.newArrayList();
205 ClassMapping classMapping = null;
206 for (ClassEntry obfClassEntry : obfClass.getClassChain()) {
207 if (mappingChain.isEmpty()) {
208 classMapping = m_classesByObf.get(obfClassEntry.getName());
209 } else if (classMapping != null) {
210 classMapping = classMapping.getInnerClassByObfSimple(obfClassEntry.getInnermostClassName());
211 }
212 mappingChain.add(classMapping);
213 }
214 return mappingChain;
215 }
216}