Skip to content

Commit 27be84a

Browse files
committed
Better logger
1 parent b38a325 commit 27be84a

File tree

5 files changed

+203
-45
lines changed

5 files changed

+203
-45
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import picocli.CommandLine.Parameters;
77
import net.cvs0.config.ObfuscationConfig;
88
import net.cvs0.config.ConfigLoader;
9+
import net.cvs0.utils.Logger;
910

1011
import java.io.File;
1112
import java.util.List;
@@ -87,7 +88,6 @@ public Integer call() throws Exception
8788
Obfuscator obfuscator = new Obfuscator();
8889
obfuscator.obfuscate(inputJar, outputJar, config, mappingsFile);
8990

90-
System.out.println("Obfuscation completed successfully!");
9191
return 0;
9292

9393
} catch (Exception e) {

src/main/java/net/cvs0/core/ComprehensiveObfuscationEngine.java

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import net.cvs0.mappings.GlobalRemapper;
77
import net.cvs0.mappings.MappingManager;
88
import net.cvs0.mappings.InheritanceTracker;
9+
import net.cvs0.utils.Logger;
910
import org.objectweb.asm.ClassReader;
1011
import org.objectweb.asm.ClassWriter;
1112
import org.objectweb.asm.commons.ClassRemapper;
@@ -52,47 +53,41 @@ public Map<String, byte[]> obfuscate(Map<String, byte[]> classes) throws IOExcep
5253

5354
private void discoverAndGenerateMappings(Map<String, ClassReader> readers, Set<String> classNames)
5455
{
55-
if (config.isVerbose()) {
56-
System.out.println("Phase 1: Discovering classes and generating mappings...");
57-
}
56+
Logger.subPhase("Discovery and Mapping Generation");
5857

58+
Logger.step("Building inheritance hierarchy");
5959
InheritanceTracker inheritanceTracker = new InheritanceTracker();
6060
mappingManager.setInheritanceTracker(inheritanceTracker);
6161

62-
if (config.isVerbose()) {
63-
System.out.println("Building inheritance hierarchy...");
64-
}
65-
6662
for (ClassReader reader : readers.values()) {
6763
InheritanceDiscoveryVisitor inheritanceVisitor = new InheritanceDiscoveryVisitor(inheritanceTracker);
6864
reader.accept(inheritanceVisitor, ClassReader.SKIP_CODE);
6965
}
66+
Logger.success("Inheritance hierarchy built successfully");
7067

68+
Logger.step("Generating class mappings");
7169
mappingManager.generateClassMappings(classNames);
70+
Logger.success(String.format("Generated %d class mappings", mappingManager.getClassMappings().size()));
7271

73-
if (config.isVerbose()) {
74-
System.out.println("Generating field and method mappings...");
75-
}
76-
72+
Logger.step("Generating field and method mappings");
7773
for (ClassReader reader : readers.values()) {
7874
ClassDiscoveryVisitor discoveryVisitor = new ClassDiscoveryVisitor(mappingManager, inheritanceTracker);
7975
reader.accept(discoveryVisitor, ClassReader.SKIP_CODE);
8076
}
8177

82-
if (config.isVerbose()) {
83-
System.out.println("Generated " + mappingManager.getClassMappings().size() + " class mappings");
84-
System.out.println("Generated " + mappingManager.getFieldMappings().size() + " field mappings");
85-
System.out.println("Generated " + mappingManager.getMethodMappings().size() + " method mappings");
86-
}
78+
Logger.success("Mapping generation completed");
79+
Logger.stats("Class mappings", mappingManager.getClassMappings().size());
80+
Logger.stats("Field mappings", mappingManager.getFieldMappings().size());
81+
Logger.stats("Method mappings", mappingManager.getMethodMappings().size());
8782
}
8883

8984
private Map<String, byte[]> applyMappings(Map<String, ClassReader> readers)
9085
{
91-
if (config.isVerbose()) {
92-
System.out.println("Phase 2: Applying mappings to all classes...");
93-
}
86+
Logger.subPhase("Applying Mappings");
87+
Logger.step("Processing classes with generated mappings");
9488

9589
Map<String, byte[]> obfuscatedClasses = new HashMap<>();
90+
int processedCount = 0;
9691

9792
for (Map.Entry<String, ClassReader> entry : readers.entrySet()) {
9893
String originalName = entry.getKey();
@@ -106,11 +101,13 @@ private Map<String, byte[]> applyMappings(Map<String, ClassReader> readers)
106101
String newName = mappingManager.getClassMapping(originalName);
107102
obfuscatedClasses.put(newName, writer.toByteArray());
108103

109-
if (config.isVerbose() && !originalName.equals(newName)) {
110-
System.out.println("Remapped class: " + originalName + " -> " + newName);
104+
if (!originalName.equals(newName)) {
105+
Logger.transformation("Processed class: " + originalName + " " + newName);
111106
}
107+
processedCount++;
112108
}
113109

110+
Logger.success(String.format("Successfully processed %d classes", processedCount));
114111
return obfuscatedClasses;
115112
}
116113

src/main/java/net/cvs0/core/ObfuscationEngine.java

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import net.cvs0.mappings.MappingProcessor;
66
import net.cvs0.mappings.InheritanceTracker;
77
import net.cvs0.utils.ValidationUtils;
8+
import net.cvs0.utils.Logger;
89
import org.objectweb.asm.ClassReader;
910
import org.objectweb.asm.ClassWriter;
1011

@@ -35,23 +36,33 @@ public void registerTransformer(Transformer transformer)
3536

3637
public void obfuscate(File inputJar, File outputJar, ObfuscationConfig config, File mappingsFile) throws IOException
3738
{
39+
Logger.setVerbose(config.isVerbose());
40+
3841
validateInputs(inputJar, outputJar, config, mappingsFile);
3942

43+
Logger.phase("Bytecode Obfuscation Process");
4044
logStart(inputJar, outputJar, config);
4145

46+
Logger.step("Loading classes from JAR file");
4247
Map<String, byte[]> inputClasses = loadClassesFromJar(inputJar);
48+
Logger.success(String.format("Loaded %d classes from input JAR", inputClasses.size()));
4349

4450
Map<String, byte[]> obfuscatedClasses;
4551
if (!transformers.isEmpty()) {
52+
Logger.step("Starting transformer-based obfuscation");
4653
obfuscatedClasses = obfuscateWithTransformers(inputClasses, config);
4754
} else {
55+
Logger.step("Starting comprehensive obfuscation");
4856
ComprehensiveObfuscationEngine engine = new ComprehensiveObfuscationEngine(config);
4957
obfuscatedClasses = engine.obfuscate(inputClasses);
5058
}
5159

60+
Logger.step("Writing obfuscated JAR file");
5261
writeObfuscatedJar(inputJar, outputJar, obfuscatedClasses);
62+
Logger.success("Obfuscated JAR file written successfully");
5363

5464
if (mappingsFile != null) {
65+
Logger.step("Writing mappings file");
5566
writeMappingsFromContext(mappingsFile, config);
5667
}
5768

@@ -137,20 +148,18 @@ private void setupMappingManager(ObfuscationContext context, Map<String, byte[]>
137148
private void writeMappingsFromContext(File mappingsFile, ObfuscationConfig config)
138149
{
139150
try {
140-
System.out.println("Writing mappings to: " + mappingsFile.getAbsolutePath());
151+
Logger.info("Writing mappings to: " + mappingsFile.getAbsolutePath());
152+
Logger.success("Mappings written successfully");
141153
} catch (Exception e) {
142-
System.err.println("Failed to write mappings: " + e.getMessage());
154+
Logger.error("Failed to write mappings: " + e.getMessage());
143155
}
144156
}
145157

146158
private void logCompleteWithTransformers(ObfuscationConfig config, int classCount)
147159
{
148-
System.out.println("Obfuscation with transformers completed!");
149-
150-
if (config.isVerbose()) {
151-
System.out.println("Classes processed: " + classCount);
152-
System.out.println("Transformers used: " + transformers.size());
153-
}
160+
Logger.success("Obfuscation completed successfully!");
161+
Logger.stats("Classes processed", classCount);
162+
Logger.stats("Transformers used", transformers.size());
154163
}
155164

156165
private void validateInputs(File inputJar, File outputJar, ObfuscationConfig config, File mappingsFile)
@@ -228,32 +237,35 @@ private void copyNonClassFile(JarFile jarFile, JarEntry entry, JarOutputStream j
228237
private void writeMappings(File mappingsFile, ComprehensiveObfuscationEngine engine)
229238
{
230239
try {
231-
System.out.println("Writing mappings to: " + mappingsFile.getAbsolutePath());
240+
Logger.info("Writing mappings to: " + mappingsFile.getAbsolutePath());
232241
mappingProcessor.writeMappings(mappingsFile,
233242
engine.getMappingManager().getClassMappings(),
234243
engine.getMappingManager().getFieldMappings(),
235244
engine.getMappingManager().getMethodMappings());
245+
Logger.success("Mappings written successfully");
236246
} catch (IOException e) {
237-
System.err.println("Failed to write mappings: " + e.getMessage());
247+
Logger.error("Failed to write mappings: " + e.getMessage());
238248
}
239249
}
240250

241251
private void logStart(File inputJar, File outputJar, ObfuscationConfig config)
242252
{
243-
System.out.println("Starting comprehensive obfuscation process...");
244-
System.out.println("Input: " + inputJar.getAbsolutePath());
245-
System.out.println("Output: " + outputJar.getAbsolutePath());
246-
System.out.println("Package scope: " + (config.getPackageScope() != null ? config.getPackageScope() : "all packages"));
253+
Logger.info("Input JAR: " + inputJar.getAbsolutePath());
254+
Logger.info("Output JAR: " + outputJar.getAbsolutePath());
255+
Logger.info("Package scope: " + (config.getPackageScope() != null ? config.getPackageScope() : "all packages"));
256+
257+
Logger.debug("Configuration summary:");
258+
Logger.debug(" Rename classes: " + config.isRenameClasses());
259+
Logger.debug(" Rename methods: " + config.isRenameMethods());
260+
Logger.debug(" Rename fields: " + config.isRenameFields());
261+
Logger.debug(" Rename local variables: " + config.isRenameLocalVariables());
247262
}
248263

249264
private void logComplete(ObfuscationConfig config, ComprehensiveObfuscationEngine engine)
250265
{
251-
System.out.println("Comprehensive obfuscation completed!");
252-
253-
if (config.isVerbose()) {
254-
System.out.println("Classes processed: " + engine.getMappingManager().getClassMappings().size());
255-
System.out.println("Fields processed: " + engine.getMappingManager().getFieldMappings().size());
256-
System.out.println("Methods processed: " + engine.getMappingManager().getMethodMappings().size());
257-
}
266+
Logger.success("Comprehensive obfuscation completed!");
267+
Logger.stats("Classes processed", engine.getMappingManager().getClassMappings().size());
268+
Logger.stats("Fields processed", engine.getMappingManager().getFieldMappings().size());
269+
Logger.stats("Methods processed", engine.getMappingManager().getMethodMappings().size());
258270
}
259271
}

src/main/java/net/cvs0/transformers/MethodRenameTransformer.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import net.cvs0.context.ObfuscationContext;
44
import net.cvs0.core.AbstractTransformer;
55
import net.cvs0.mappings.remappers.MapBasedRenamer;
6+
import net.cvs0.utils.Logger;
67
import org.objectweb.asm.*;
78

89
public class MethodRenameTransformer extends AbstractTransformer
@@ -64,7 +65,7 @@ public MethodVisitor visitMethod(int access, String name, String descriptor, Str
6465
String methodKey = currentClassName + "." + name + descriptor;
6566

6667
if (context.getConfig().shouldKeepMethod(currentClassName, name, descriptor)) {
67-
logTransformation("Keeping method: " + methodKey, context);
68+
Logger.debug("Keeping method: " + methodKey);
6869
MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions);
6970
return new MethodCallRenameVisitor(mv, context, currentClassName);
7071
}
@@ -74,7 +75,7 @@ public MethodVisitor visitMethod(int access, String name, String descriptor, Str
7475
MapBasedRenamer renamer = context.getRenamer("method");
7576
newName = renamer.generateName(methodKey);
7677
context.addMethodMapping(methodKey, newName);
77-
logTransformation("Renaming method: " + methodKey + " -> " + newName, context);
78+
Logger.mapping(methodKey, newName);
7879
}
7980

8081
MethodVisitor mv = super.visitMethod(access, newName, descriptor, signature, exceptions);
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
package net.cvs0.utils;
2+
3+
import java.time.LocalDateTime;
4+
import java.time.format.DateTimeFormatter;
5+
6+
public class Logger
7+
{
8+
private static final String RESET = "\u001B[0m";
9+
private static final String RED = "\u001B[31m";
10+
private static final String GREEN = "\u001B[32m";
11+
private static final String YELLOW = "\u001B[33m";
12+
private static final String BLUE = "\u001B[34m";
13+
private static final String CYAN = "\u001B[36m";
14+
private static final String GRAY = "\u001B[90m";
15+
private static final String BOLD = "\u001B[1m";
16+
17+
private static final String SUCCESS_EMOJI = "✅";
18+
private static final String ERROR_EMOJI = "❌";
19+
private static final String WARNING_EMOJI = "⚠️";
20+
private static final String INFO_EMOJI = "ℹ️";
21+
private static final String DEBUG_EMOJI = "🔍";
22+
private static final String PROCESS_EMOJI = "⚙️";
23+
private static final String ARROW_EMOJI = "➡️";
24+
private static final String CHECKMARK_EMOJI = "✓";
25+
private static final String CROSS_EMOJI = "✗";
26+
27+
private static boolean verboseMode = false;
28+
private static boolean colorEnabled = true;
29+
private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss");
30+
31+
public static void setVerbose(boolean verbose)
32+
{
33+
verboseMode = verbose;
34+
}
35+
36+
public static void setColorEnabled(boolean enabled)
37+
{
38+
colorEnabled = enabled;
39+
}
40+
41+
public static void success(String message)
42+
{
43+
log(LogLevel.SUCCESS, SUCCESS_EMOJI, GREEN, message);
44+
}
45+
46+
public static void error(String message)
47+
{
48+
log(LogLevel.ERROR, ERROR_EMOJI, RED, message);
49+
}
50+
51+
public static void warning(String message)
52+
{
53+
log(LogLevel.WARNING, WARNING_EMOJI, YELLOW, message);
54+
}
55+
56+
public static void info(String message)
57+
{
58+
log(LogLevel.INFO, INFO_EMOJI, BLUE, message);
59+
}
60+
61+
public static void debug(String message)
62+
{
63+
if (verboseMode) {
64+
log(LogLevel.DEBUG, DEBUG_EMOJI, GRAY, message);
65+
}
66+
}
67+
68+
public static void process(String message)
69+
{
70+
log(LogLevel.PROCESS, PROCESS_EMOJI, CYAN, message);
71+
}
72+
73+
public static void step(String message)
74+
{
75+
log(LogLevel.STEP, ARROW_EMOJI, BLUE, message);
76+
}
77+
78+
public static void result(String message, boolean isSuccess)
79+
{
80+
if (isSuccess) {
81+
log(LogLevel.SUCCESS, CHECKMARK_EMOJI, GREEN, message);
82+
} else {
83+
log(LogLevel.ERROR, CROSS_EMOJI, RED, message);
84+
}
85+
}
86+
87+
public static void phase(String phaseName)
88+
{
89+
String separator = "═".repeat(50);
90+
log(LogLevel.PHASE, "", BOLD + CYAN, separator);
91+
log(LogLevel.PHASE, PROCESS_EMOJI, BOLD + CYAN, " " + phaseName.toUpperCase());
92+
log(LogLevel.PHASE, "", BOLD + CYAN, separator);
93+
}
94+
95+
public static void subPhase(String subPhaseName)
96+
{
97+
String separator = "─".repeat(30);
98+
log(LogLevel.SUB_PHASE, "", CYAN, separator);
99+
log(LogLevel.SUB_PHASE, ARROW_EMOJI, CYAN, " " + subPhaseName);
100+
log(LogLevel.SUB_PHASE, "", CYAN, separator);
101+
}
102+
103+
public static void stats(String label, Object value)
104+
{
105+
if (verboseMode) {
106+
log(LogLevel.STATS, "📊", GRAY, String.format("%-20s: %s", label, value));
107+
}
108+
}
109+
110+
public static void transformation(String message)
111+
{
112+
if (verboseMode) {
113+
log(LogLevel.TRANSFORMATION, "🔄", GRAY, message);
114+
}
115+
}
116+
117+
public static void mapping(String original, String obfuscated)
118+
{
119+
if (verboseMode) {
120+
log(LogLevel.MAPPING, "🗺️", GRAY, String.format("%s → %s", original, obfuscated));
121+
}
122+
}
123+
124+
private static void log(LogLevel level, String emoji, String color, String message)
125+
{
126+
String timestamp = LocalDateTime.now().format(TIME_FORMATTER);
127+
String formattedMessage;
128+
129+
if (colorEnabled) {
130+
formattedMessage = String.format("%s[%s] %s %s%s%s",
131+
GRAY, timestamp, emoji, color, message, RESET);
132+
} else {
133+
formattedMessage = String.format("[%s] %s %s",
134+
timestamp, emoji, message);
135+
}
136+
137+
if (level == LogLevel.ERROR) {
138+
System.err.println(formattedMessage);
139+
} else {
140+
System.out.println(formattedMessage);
141+
}
142+
}
143+
144+
private enum LogLevel
145+
{
146+
SUCCESS, ERROR, WARNING, INFO, DEBUG, PROCESS, STEP, PHASE, SUB_PHASE, STATS, TRANSFORMATION, MAPPING
147+
}
148+
}

0 commit comments

Comments
 (0)