Skip to content

Commit 263ef5b

Browse files
committed
Package scope fixes + mapping exporting
1 parent ebf72f5 commit 263ef5b

13 files changed

+1244
-67
lines changed

.idea/misc.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build.gradle

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ plugins {
66
group = 'cc.squidhackdevelopment'
77
version = '1.0-SNAPSHOT'
88

9+
java {
10+
sourceCompatibility = JavaVersion.VERSION_21
11+
targetCompatibility = JavaVersion.VERSION_21
12+
}
13+
914
repositories {
1015
mavenCentral()
1116
}

src/main/java/net/cvs0/Main.java

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import net.cvs0.config.ObfuscationConfig;
88
import net.cvs0.config.ConfigLoader;
99
import net.cvs0.config.NamingMode;
10+
import net.cvs0.mappings.export.MappingExporter;
1011
import net.cvs0.utils.Logger;
1112

1213
import java.io.File;
@@ -47,6 +48,18 @@ public class Main implements Callable<Integer>
4748
@Option(names = {"--mappings", "--output-mappings"}, description = "Output mappings file")
4849
private File mappingsFile;
4950

51+
@Option(names = {"--mapping-format"},
52+
description = "Mapping output format (default: auto-detect from file extension):%n" +
53+
" PROGUARD - ProGuard mapping format%n" +
54+
" SRG - SRG (Mod Coder Pack) format%n" +
55+
" TINY - Tiny mapping format%n" +
56+
" JSON - JSON format%n" +
57+
" CSV - CSV format%n" +
58+
" HUMAN_READABLE - Human readable format%n" +
59+
" RETRACE - Retrace format%n" +
60+
" ALL - Export all formats")
61+
private String mappingFormat;
62+
5063
@Option(names = {"-v", "--verbose"}, description = "Enable verbose output")
5164
private boolean verbose;
5265

@@ -99,8 +112,10 @@ public Integer call() throws Exception
99112
System.out.println();
100113
}
101114

115+
MappingExporter.MappingFormat format = parseMappingFormat();
116+
102117
Obfuscator obfuscator = new Obfuscator();
103-
obfuscator.obfuscate(inputJar, outputJar, config, mappingsFile);
118+
obfuscator.obfuscate(inputJar, outputJar, config, mappingsFile, format);
104119

105120
return 0;
106121

@@ -200,4 +215,18 @@ private ObfuscationConfig buildConfiguration() throws Exception
200215

201216
return builder.build();
202217
}
218+
219+
private MappingExporter.MappingFormat parseMappingFormat()
220+
{
221+
if (mappingFormat == null || mappingFormat.equalsIgnoreCase("AUTO")) {
222+
return null;
223+
}
224+
225+
try {
226+
return MappingExporter.MappingFormat.valueOf(mappingFormat.toUpperCase());
227+
} catch (IllegalArgumentException e) {
228+
System.err.println("Warning: Unknown mapping format '" + mappingFormat + "', using auto-detection");
229+
return null;
230+
}
231+
}
203232
}

src/main/java/net/cvs0/Obfuscator.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
import java.io.File;
1212
import java.io.IOException;
13+
import net.cvs0.mappings.export.MappingExporter;
1314

1415
public class Obfuscator
1516
{
@@ -35,6 +36,11 @@ public void obfuscate(File inputJar, File outputJar, ObfuscationConfig config, F
3536
engine.obfuscate(inputJar, outputJar, config, mappingsFile);
3637
}
3738

39+
public void obfuscate(File inputJar, File outputJar, ObfuscationConfig config, File mappingsFile, MappingExporter.MappingFormat format) throws IOException
40+
{
41+
engine.obfuscate(inputJar, outputJar, config, mappingsFile, format);
42+
}
43+
3844
public ObfuscationEngine getEngine()
3945
{
4046
return engine;

src/main/java/net/cvs0/config/ObfuscationConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public boolean shouldKeepField(String className, String fieldName)
108108
public boolean isInPackageScope(String className)
109109
{
110110
if (packageScope == null || packageScope.isEmpty()) {
111-
return true;
111+
return false;
112112
}
113113
if (className == null) {
114114
return false;
Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
package net.cvs0.context;
2+
3+
import java.util.HashMap;
4+
import java.util.HashSet;
5+
import java.util.Map;
6+
import java.util.Set;
7+
8+
public class ClassContext
9+
{
10+
private final String className;
11+
private final TransformationContext globalContext;
12+
private final Map<String, Object> classProperties;
13+
private final Set<String> processedMethods;
14+
private final Set<String> processedFields;
15+
16+
private String superClass;
17+
private String[] interfaces;
18+
private int access;
19+
private boolean isInterface;
20+
private boolean isAbstract;
21+
private boolean isEnum;
22+
private boolean isAnnotation;
23+
24+
private long methodCount;
25+
private long fieldCount;
26+
private long transformationsApplied;
27+
28+
public ClassContext(String className, TransformationContext globalContext)
29+
{
30+
this.className = className;
31+
this.globalContext = globalContext;
32+
this.classProperties = new HashMap<>();
33+
this.processedMethods = new HashSet<>();
34+
this.processedFields = new HashSet<>();
35+
36+
initializeClassInfo();
37+
}
38+
39+
private void initializeClassInfo()
40+
{
41+
setProperty("className", className);
42+
setProperty("startTime", System.currentTimeMillis());
43+
setProperty("thread", Thread.currentThread().getName());
44+
}
45+
46+
public void setClassInfo(int access, String superName, String[] interfaces)
47+
{
48+
this.access = access;
49+
this.superClass = superName;
50+
this.interfaces = interfaces != null ? interfaces.clone() : new String[0];
51+
52+
this.isInterface = (access & 0x0200) != 0;
53+
this.isAbstract = (access & 0x0400) != 0;
54+
this.isEnum = (access & 0x4000) != 0;
55+
this.isAnnotation = (access & 0x2000) != 0;
56+
57+
setProperty("access", access);
58+
setProperty("superClass", superName);
59+
setProperty("interfaces", interfaces);
60+
setProperty("isInterface", isInterface);
61+
setProperty("isAbstract", isAbstract);
62+
setProperty("isEnum", isEnum);
63+
setProperty("isAnnotation", isAnnotation);
64+
}
65+
66+
public String getClassName()
67+
{
68+
return className;
69+
}
70+
71+
public TransformationContext getGlobalContext()
72+
{
73+
return globalContext;
74+
}
75+
76+
public void setProperty(String key, Object value)
77+
{
78+
classProperties.put(key, value);
79+
}
80+
81+
public <T> T getProperty(String key, Class<T> type)
82+
{
83+
Object value = classProperties.get(key);
84+
return type.isInstance(value) ? type.cast(value) : null;
85+
}
86+
87+
public <T> T getProperty(String key, T defaultValue, Class<T> type)
88+
{
89+
T value = getProperty(key, type);
90+
return value != null ? value : defaultValue;
91+
}
92+
93+
public void recordMethodProcessed(String methodName, String descriptor)
94+
{
95+
String methodKey = methodName + descriptor;
96+
processedMethods.add(methodKey);
97+
methodCount++;
98+
setProperty("methodCount", methodCount);
99+
}
100+
101+
public void recordFieldProcessed(String fieldName)
102+
{
103+
processedFields.add(fieldName);
104+
fieldCount++;
105+
setProperty("fieldCount", fieldCount);
106+
}
107+
108+
public void recordTransformation(String transformationType)
109+
{
110+
transformationsApplied++;
111+
globalContext.recordTransformation();
112+
setProperty("transformationsApplied", transformationsApplied);
113+
114+
String counterKey = "transformation." + transformationType;
115+
Long currentCount = getProperty(counterKey, Long.class);
116+
setProperty(counterKey, currentCount != null ? currentCount + 1 : 1L);
117+
}
118+
119+
public boolean isMethodProcessed(String methodName, String descriptor)
120+
{
121+
return processedMethods.contains(methodName + descriptor);
122+
}
123+
124+
public boolean isFieldProcessed(String fieldName)
125+
{
126+
return processedFields.contains(fieldName);
127+
}
128+
129+
public boolean shouldProcess()
130+
{
131+
return globalContext.getConfig().isInPackageScope(className) &&
132+
!globalContext.getConfig().shouldKeepClass(className) &&
133+
!globalContext.isAborted();
134+
}
135+
136+
public boolean shouldProcessMethod(String methodName, String descriptor)
137+
{
138+
return shouldProcess() &&
139+
!globalContext.getConfig().shouldKeepMethod(className, methodName, descriptor);
140+
}
141+
142+
public boolean shouldProcessField(String fieldName)
143+
{
144+
return shouldProcess() &&
145+
!globalContext.getConfig().shouldKeepField(className, fieldName);
146+
}
147+
148+
public void logTransformation(String transformationType, String message)
149+
{
150+
if (globalContext.getConfig().isVerbose()) {
151+
System.out.println(String.format("[%s] %s in %s: %s",
152+
transformationType, globalContext.getCurrentPhase(), className, message));
153+
}
154+
}
155+
156+
public String getSuperClass()
157+
{
158+
return superClass;
159+
}
160+
161+
public String[] getInterfaces()
162+
{
163+
return interfaces != null ? interfaces.clone() : new String[0];
164+
}
165+
166+
public int getAccess()
167+
{
168+
return access;
169+
}
170+
171+
public boolean isInterface()
172+
{
173+
return isInterface;
174+
}
175+
176+
public boolean isAbstract()
177+
{
178+
return isAbstract;
179+
}
180+
181+
public boolean isEnum()
182+
{
183+
return isEnum;
184+
}
185+
186+
public boolean isAnnotation()
187+
{
188+
return isAnnotation;
189+
}
190+
191+
public long getMethodCount()
192+
{
193+
return methodCount;
194+
}
195+
196+
public long getFieldCount()
197+
{
198+
return fieldCount;
199+
}
200+
201+
public long getTransformationsApplied()
202+
{
203+
return transformationsApplied;
204+
}
205+
206+
public Set<String> getProcessedMethods()
207+
{
208+
return new HashSet<>(processedMethods);
209+
}
210+
211+
public Set<String> getProcessedFields()
212+
{
213+
return new HashSet<>(processedFields);
214+
}
215+
216+
public void complete()
217+
{
218+
setProperty("endTime", System.currentTimeMillis());
219+
Long startTime = getProperty("startTime", Long.class);
220+
if (startTime != null) {
221+
setProperty("processingDuration", System.currentTimeMillis() - startTime);
222+
}
223+
setProperty("completed", true);
224+
}
225+
226+
@Override
227+
public String toString()
228+
{
229+
return "ClassContext{" +
230+
"className='" + className + '\'' +
231+
", methods=" + methodCount +
232+
", fields=" + fieldCount +
233+
", transformations=" + transformationsApplied +
234+
", processed=" + (processedMethods.size() + processedFields.size()) +
235+
'}';
236+
}
237+
}

0 commit comments

Comments
 (0)