Skip to content

Commit d2bdec3

Browse files
(WIP) #77
1 parent ec2c7dc commit d2bdec3

File tree

5 files changed

+113
-25
lines changed

5 files changed

+113
-25
lines changed

src/main/java/cn/maxpixel/mcdecompiler/Properties.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,6 @@ public class Properties {
2727
public static Path TEMP_DIR = Path.of("temp");
2828
public static Path DOWNLOAD_DIR = Path.of("downloads");
2929

30-
public static Path getDownloadedProguardMappingPath(String version, Info.SideType type) {
31-
return DOWNLOAD_DIR.resolve(version).resolve(type + "_mappings.txt");
32-
}
33-
3430
public static Path getDownloadedDecompilerPath(@NotNull Info.DecompilerType type) {
3531
if(type == Info.DecompilerType.USER_DEFINED) throw new UnsupportedOperationException();
3632
return DOWNLOAD_DIR.resolve("decompiler").resolve(Objects.requireNonNull(type) + ".jar");

src/main/java/cn/maxpixel/mcdecompiler/asm/ClassProcessor.java

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -59,37 +59,37 @@ private ClassProcessor() {
5959

6060
public static void registerCommandLineOptions(OptionParser parser) {
6161
CoreProcess.INSTANCE.registerCommandLineOptions(parser::accepts, parser::accepts);
62-
for(Process process : LOADER) {
62+
for (Process process : LOADER) {
6363
process.registerCommandLineOptions((option) -> parser.accepts(process.getName() + '.' + option),
6464
(option, description) -> parser.accepts(process.getName() + '.' + option, description));
6565
}
6666
}
6767

6868
public static void acceptCommandLineValues(OptionSet options) {
6969
CoreProcess.INSTANCE.acceptCommandLineValues(options::has, options::hasArgument, options::valueOf, options::valuesOf);
70-
for(Process process : LOADER) {
70+
for (Process process : LOADER) {
7171
process.acceptCommandLineValues(options::has, options::hasArgument, options::valueOf, options::valuesOf);
7272
}
7373
}
7474

7575
public static void fetchOptions() {
76-
for(Process process : LOADER) {
76+
for (Process process : LOADER) {
7777
process.fetchOptions();
7878
}
7979
}
8080

8181
public static void beforeRunning(ClassifiedDeobfuscator.DeobfuscateOptions options, @Nullable String targetNamespace,
8282
ClassifiedMappingRemapper mappingRemapper) throws IOException {
8383
CoreProcess.INSTANCE.beforeRunning(options, targetNamespace, mappingRemapper);
84-
for(Process process : LOADER) {
84+
for (Process process : LOADER) {
8585
process.beforeRunning(options, targetNamespace, mappingRemapper);
8686
}
8787
}
8888

8989
public static void afterRunning(ClassifiedDeobfuscator.DeobfuscateOptions options, @Nullable String targetNamespace,
9090
ClassifiedMappingRemapper mappingRemapper) throws IOException {
9191
CoreProcess.INSTANCE.afterRunning(options, targetNamespace, mappingRemapper);
92-
for(Process process : LOADER) {
92+
for (Process process : LOADER) {
9393
process.afterRunning(options, targetNamespace, mappingRemapper);
9494
}
9595
}
@@ -98,11 +98,11 @@ public static ClassVisitor getVisitor(ClassWriter writer, ClassifiedDeobfuscator
9898
@Nullable ClassMapping<? extends Mapping> mapping, String targetNamespace,
9999
ClassifiedMappingRemapper mappingRemapper) {
100100
ClassVisitor cv = writer;
101-
for(Process process : AFTER) {
101+
for (Process process : AFTER) {
102102
cv = process.getVisitor(options, reader, mapping, targetNamespace, mappingRemapper).apply(cv);
103103
}
104104
cv = CoreProcess.INSTANCE.getVisitor(options, reader, mapping, targetNamespace, mappingRemapper).apply(cv);
105-
for(Process process : BEFORE) {
105+
for (Process process : BEFORE) {
106106
cv = process.getVisitor(options, reader, mapping, targetNamespace, mappingRemapper).apply(cv);
107107
}
108108
return cv;
@@ -173,13 +173,13 @@ public State getState() {
173173
@Override
174174
public void beforeRunning(ClassifiedDeobfuscator.DeobfuscateOptions options, String targetNamespace,
175175
ClassifiedMappingRemapper mappingRemapper) {
176-
if(options.rvn()) VariableNameGenerator.startRecord();
176+
if (options.rvn()) VariableNameGenerator.startRecord();
177177
}
178178

179179
@Override
180180
public void afterRunning(ClassifiedDeobfuscator.DeobfuscateOptions options, String targetNamespace,
181181
ClassifiedMappingRemapper mappingRemapper) throws IOException {
182-
if(options.rvn()) VariableNameGenerator.endRecord(Properties.TEMP_DIR.resolve(FERNFLOWER_ABSTRACT_PARAMETER_NAMES));
182+
if (options.rvn()) VariableNameGenerator.endRecord(Properties.TEMP_DIR.resolve(FERNFLOWER_ABSTRACT_PARAMETER_NAMES));
183183
}
184184

185185
@Override
@@ -188,13 +188,15 @@ public Function<ClassVisitor, ClassVisitor> getVisitor(ClassifiedDeobfuscator.De
188188
ClassifiedMappingRemapper mappingRemapper) {
189189
return parent -> {
190190
ClassVisitor cv = parent;
191-
if(options.rvn()) cv = new VariableNameGenerator(cv);
192-
if((reader.getAccess() & Opcodes.ACC_RECORD) != 0) cv = new RecordNameRemapper(cv);
193-
if(mapping != null && mapping.mapping instanceof NameGetter.Namespaced ngn) {
191+
if (options.rvn()) cv = new VariableNameGenerator(cv);
192+
if ((reader.getAccess() & Opcodes.ACC_RECORD) != 0) cv = new RecordNameRemapper(cv);
193+
if (mapping != null && mapping.mapping instanceof NameGetter.Namespaced ngn) {
194194
ngn.setMappedNamespace(targetNamespace);
195195
cv = new LVTRemapper(cv, (ClassMapping<NamespacedMapping>) mapping, mappingRemapper);
196196
}
197-
return new RuntimeParameterAnnotationFixer(new ClassRemapper(cv, mappingRemapper));
197+
return new RuntimeParameterAnnotationFixer(
198+
new MixinClassRemapper(
199+
new ClassRemapper(cv, mappingRemapper), mappingRemapper));
198200
};
199201
}
200202
}

src/main/java/cn/maxpixel/mcdecompiler/asm/ClassifiedMappingRemapper.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.objectweb.asm.Type;
3737
import org.objectweb.asm.commons.Remapper;
3838

39+
import java.lang.reflect.Modifier;
3940
import java.util.Objects;
4041
import java.util.Optional;
4142
import java.util.logging.Logger;
@@ -176,21 +177,20 @@ private Optional<PairedMapping> processSuperMethod(String owner, String name, St
176177
private PairedMapping reduceMethod(@NotNull PairedMapping left, @NotNull PairedMapping right) {
177178
if(left == right || nameAndDescEquals(left, right)) return left;
178179
int leftAcc = extraClassesInformation.getAccessFlags(left.getOwned().getOwner().mapping.unmappedName,
179-
left.unmappedName.concat(getUnmappedDesc(left))) & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED | Opcodes.ACC_PRIVATE);
180+
left.unmappedName.concat(getUnmappedDesc(left)));
180181
int rightAcc = extraClassesInformation.getAccessFlags(right.getOwned().getOwner().mapping.unmappedName,
181-
right.unmappedName.concat(getUnmappedDesc(right))) & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED | Opcodes.ACC_PRIVATE);
182+
right.unmappedName.concat(getUnmappedDesc(right)));
182183
if((leftAcc & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED)) != 0) {
183184
if((rightAcc & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED)) != 0) throw new IllegalArgumentException("This can't happen!");
184185
return left;
185186
} else if((rightAcc & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED)) != 0) return right;
186-
else if(leftAcc == Opcodes.ACC_PRIVATE || rightAcc == Opcodes.ACC_PRIVATE)
187-
throw new IllegalArgumentException("This can't happen!");
187+
else if(Modifier.isPrivate(leftAcc) || Modifier.isPrivate(rightAcc)) throw new IllegalArgumentException("This can't happen!");
188188
else throw new IllegalArgumentException("Method duplicated... This should not happen!");
189189
}
190190

191191
private static boolean nameAndDescEquals(@NotNull PairedMapping left, @NotNull PairedMapping right) {
192192
if(left.unmappedName.equals(right.unmappedName) && left.mappedName.equals(right.mappedName)) {
193-
// Will return false if they either have no descriptor components
193+
// Will return false if they have no descriptor components
194194
boolean leftD = left.hasComponent(Descriptor.class), leftDM = left.hasComponent(Descriptor.Mapped.class),
195195
rightD = right.hasComponent(Descriptor.class), rightDM = right.hasComponent(Descriptor.Mapped.class);
196196
if(leftD && rightD) {
@@ -248,7 +248,7 @@ private PairedMapping reduceField(PairedMapping left, PairedMapping right) {
248248
if((rightAcc & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED)) != 0) throw new IllegalArgumentException("This can't happen!");
249249
return left;
250250
} else if((rightAcc & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED)) != 0) return right;
251-
else if(leftAcc == Opcodes.ACC_PRIVATE || rightAcc == Opcodes.ACC_PRIVATE)
251+
else if(Modifier.isPrivate(leftAcc) || Modifier.isPrivate(rightAcc))
252252
throw new IllegalArgumentException("This can't happen!");
253253
throw new IllegalArgumentException("Field duplicated... This should not happen!");
254254
}

src/main/java/cn/maxpixel/mcdecompiler/asm/ExtraClassesInformation.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,9 @@ public ObjectList<String> getSuperNames(String name) {
112112
return superClassMap.get(name);
113113
}
114114

115-
public int getAccessFlags(String className, String composedMemberName) {
115+
public int getAccessFlags(String className, String combinedMemberName) {
116116
Object2IntMap<String> map = accessMap.get(className);
117117
if(map == null) return Opcodes.ACC_PUBLIC;
118-
return map.getInt(composedMemberName);
118+
return map.getInt(combinedMemberName);
119119
}
120120
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* MinecraftDecompiler. A tool/library to deobfuscate and decompile Minecraft.
3+
* Copyright (C) 2019-2022 MaxPixelStudios
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
*/
18+
19+
package cn.maxpixel.mcdecompiler.asm;
20+
21+
import cn.maxpixel.mcdecompiler.Info;
22+
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
23+
import it.unimi.dsi.fastutil.objects.ObjectList;
24+
import it.unimi.dsi.fastutil.objects.ObjectLists;
25+
import org.objectweb.asm.*;
26+
27+
public class MixinClassRemapper extends ClassVisitor {
28+
private final ClassifiedMappingRemapper mappingRemapper;
29+
private boolean isMixin;
30+
private ObjectList<String> targetClasses = ObjectLists.emptyList();
31+
32+
public MixinClassRemapper(ClassVisitor classVisitor, ClassifiedMappingRemapper mappingRemapper) {
33+
super(Info.ASM_VERSION, classVisitor);
34+
this.mappingRemapper = mappingRemapper;
35+
}
36+
37+
@Override
38+
public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
39+
AnnotationVisitor av = super.visitAnnotation(descriptor, visible);
40+
if ("Lorg/spongepowered/asm/mixin/Mixin;".equals(descriptor)) {
41+
this.isMixin = true;
42+
this.targetClasses = new ObjectArrayList<>();
43+
return new AnnotationVisitor(api, av) {
44+
@Override
45+
public AnnotationVisitor visitArray(String name) {
46+
AnnotationVisitor v = super.visitArray(name);
47+
if (name.equals("value")) {
48+
return new AnnotationVisitor(api, v) {
49+
@Override
50+
public void visit(String name, Object value) {
51+
if (value instanceof Type t && t.getSort() == Type.OBJECT) {
52+
targetClasses.add(t.getInternalName());
53+
}
54+
super.visit(name, value);
55+
}
56+
};
57+
}
58+
return v;
59+
}
60+
};
61+
}
62+
return av;
63+
}
64+
65+
@Override
66+
public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) {
67+
if (isMixin) {// FIXME: Cannot determine whether this is a shadow field or not
68+
for (String targetClass : targetClasses) {
69+
String result = mappingRemapper.mapFieldName(targetClass, name, descriptor);
70+
if (result != name) {// Use != because name will be returned if mapped name is not found
71+
return super.visitField(access, result, descriptor, signature, value);
72+
}
73+
}
74+
}
75+
return super.visitField(access, name, descriptor, signature, value);
76+
}
77+
78+
@Override
79+
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
80+
if (isMixin) {
81+
for (String targetClass : targetClasses) {
82+
String result = mappingRemapper.mapMethodName(targetClass, name, descriptor);
83+
if (result != name) {
84+
return super.visitMethod(access, result, descriptor, signature, exceptions);
85+
}
86+
}
87+
}
88+
return super.visitMethod(access, name, descriptor, signature, exceptions);
89+
}
90+
}

0 commit comments

Comments
 (0)