Skip to content

Commit 498957e

Browse files
committed
feat: auto common dependency downloader
1 parent 648f125 commit 498957e

10 files changed

Lines changed: 357 additions & 82 deletions

File tree

.github/workflows/gradle.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,4 @@ jobs:
2828
uses: actions/upload-artifact@v3.1.0
2929
with:
3030
name: Skidfuscator.jar
31-
path: staging/client-2.0.0-SNAPSHOT.jar
31+
path: staging/client-standalone-all.jar

dev.skidfuscator.client.standalone/src/main/java/dev/skidfuscator/obfuscator/SkidfuscatorMain.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package dev.skidfuscator.obfuscator;
22

33
import dev.skidfuscator.obfuscator.command.HelpCommand;
4+
import dev.skidfuscator.obfuscator.command.MappingsCommand;
45
import dev.skidfuscator.obfuscator.command.ObfuscateCommand;
6+
import dev.skidfuscator.obfuscator.util.LogoUtil;
57
import lombok.SneakyThrows;
68
import org.jline.reader.EndOfFileException;
79
import org.jline.reader.LineReader;
@@ -70,8 +72,10 @@ public static void main(String[] args) {
7072
}
7173

7274
} else {
75+
LogoUtil.printLogo();
7376
new CommandLine(new HelpCommand())
7477
.addSubcommand("obfuscate", new ObfuscateCommand())
78+
.addSubcommand("mappings", new MappingsCommand())
7579
.execute(args);
7680
}
7781
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package dev.skidfuscator.obfuscator.command;
2+
3+
import dev.skidfuscator.jghost.GhostHelper;
4+
import dev.skidfuscator.jghost.tree.GhostLibrary;
5+
import dev.skidfuscator.obfuscator.Skidfuscator;
6+
import dev.skidfuscator.obfuscator.util.misc.SkidTimedLogger;
7+
import org.apache.log4j.LogManager;
8+
import org.apache.log4j.Logger;
9+
import picocli.CommandLine;
10+
11+
import java.io.File;
12+
import java.util.Arrays;
13+
import java.util.concurrent.Callable;
14+
import java.util.concurrent.atomic.AtomicReference;
15+
16+
@CommandLine.Command(
17+
aliases = "mappings",
18+
mixinStandardHelpOptions = true,
19+
version = "1.0.0",
20+
description = "Creates a collated mappings file given a specific directory"
21+
)
22+
public class MappingsCommand implements Callable<Integer> {
23+
24+
@CommandLine.Parameters(
25+
index = "0",
26+
description = "The directory which will be used to create the mappings file"
27+
)
28+
private File input;
29+
30+
@CommandLine.Option(
31+
names = {"-o", "--output"},
32+
description = "Path to the output mappings file location"
33+
)
34+
private File output = new File("compressed-mappings.json");
35+
36+
@Override
37+
public Integer call() throws Exception {
38+
if (input == null) {
39+
System.out.println("Invalid input file");
40+
return 1;
41+
}
42+
43+
if (!input.getPath().endsWith(".jar") && !input.isDirectory()) {
44+
System.err.println("Invalid input file. Must be a jar file or a directory");
45+
return 1;
46+
}
47+
48+
if (output == null) {
49+
System.err.println("Invalid output file");
50+
return 1;
51+
}
52+
53+
final Logger log = LogManager.getLogger(Skidfuscator.class);
54+
final SkidTimedLogger logger = new SkidTimedLogger(true, log);
55+
56+
AtomicReference<GhostLibrary> ghostLibrary = new AtomicReference<>(null);
57+
iterateFolder(input, logger, ghostLibrary);
58+
59+
GhostHelper.saveLibraryFile(logger, ghostLibrary.get(), output);
60+
logger.style("Successfully created mappings file");
61+
62+
return 0;
63+
}
64+
65+
private void iterateFolder(File file, SkidTimedLogger logger, AtomicReference<GhostLibrary> ghostLibrary) {
66+
if (file.isDirectory()) {
67+
for (File files : file.listFiles()) {
68+
iterateFolder(files, logger, ghostLibrary);
69+
}
70+
} else {
71+
if (file.getAbsolutePath().endsWith(".jar") || file.getAbsolutePath().endsWith(".jmod")) {
72+
final GhostLibrary ghost = GhostHelper.createFromLibraryFile(logger, file);
73+
logger.style("Creating mappings for " + file.getAbsolutePath() + "...\n");
74+
if (ghostLibrary.get() == null) {
75+
ghostLibrary.set(ghost);
76+
} else {
77+
ghostLibrary.get().merge(ghost);
78+
}
79+
}
80+
}
81+
}
82+
}

dev.skidfuscator.client.standalone/src/main/java/dev/skidfuscator/obfuscator/command/ObfuscateCommand.java

Lines changed: 1 addition & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import dev.skidfuscator.obfuscator.Skidfuscator;
55
import dev.skidfuscator.obfuscator.SkidfuscatorSession;
66
import dev.skidfuscator.obfuscator.util.ConsoleColors;
7+
import dev.skidfuscator.obfuscator.util.LogoUtil;
78
import dev.skidfuscator.obfuscator.util.MiscUtil;
89
import picocli.CommandLine;
910

@@ -89,66 +90,6 @@ public class ObfuscateCommand implements Callable<Integer> {
8990

9091
@Override
9192
public Integer call() {
92-
/* Total number of processors or cores available to the JVM */
93-
final String processors =
94-
String.format("%19.19s", "Processors:")
95-
+ " "
96-
+ String.format(
97-
"%-19.19s",
98-
Runtime.getRuntime().availableProcessors() + " cores"
99-
);
100-
101-
final long freeMemory = Math.round(Runtime.getRuntime().freeMemory() / 1E6);
102-
final String memory =
103-
String.format("%19.19s", "Current Memory:")
104-
+ " "
105-
+ String.format("%-19.19s", freeMemory + "mb");
106-
107-
final long maxMemory = Math.round(Runtime.getRuntime().maxMemory() / 1E6);
108-
final String memoryString = (maxMemory == Long.MAX_VALUE
109-
? ConsoleColors.GREEN + "no limit"
110-
: maxMemory + "mb"
111-
);
112-
String topMemory =
113-
String.format("%19.19s", "Max Memory:")
114-
+ " "
115-
+ String.format("%-19.19s",
116-
memoryString + (maxMemory > 1500 ? "" : " ⚠️")
117-
);
118-
119-
topMemory = MiscUtil.replaceColor(
120-
topMemory,
121-
memoryString,
122-
maxMemory > 1500 ? ConsoleColors.GREEN_BRIGHT : ConsoleColors.RED_BRIGHT
123-
);
124-
// slight fix for thing
125-
topMemory = topMemory.replace("⚠️", "⚠️ ");
126-
127-
final String[] logo = new String[] {
128-
"",
129-
" /$$$$$$ /$$ /$$ /$$ /$$$$$$ /$$",
130-
" /$$__ $$| $$ |__/ | $$ /$$__ $$ | $$",
131-
"| $$ \\__/| $$ /$$ /$$ /$$$$$$$| $$ \\__//$$ /$$ /$$$$$$$ /$$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$",
132-
"| $$$$$$ | $$ /$$/| $$ /$$__ $$| $$$$ | $$ | $$ /$$_____/ /$$_____/ |____ $$|_ $$_/ /$$__ $$ /$$__ $$",
133-
" \\____ $$| $$$$$$/ | $$| $$ | $$| $$_/ | $$ | $$| $$$$$$ | $$ /$$$$$$$ | $$ | $$ \\ $$| $$ \\__/",
134-
" /$$ \\ $$| $$_ $$ | $$| $$ | $$| $$ | $$ | $$ \\____ $$| $$ /$$__ $$ | $$ /$$| $$ | $$| $$",
135-
"| $$$$$$/| $$ \\ $$| $$| $$$$$$$| $$ | $$$$$$/ /$$$$$$$/| $$$$$$$| $$$$$$$ | $$$$/| $$$$$$/| $$",
136-
" \\______/ |__/ \\__/|__/ \\_______/|__/ \\______/ |_______/ \\_______/ \\_______/ \\___/ \\______/ |__/",
137-
"",
138-
" ┌───────────────────────────────────────────┐",
139-
" │ " + processors + " │",
140-
" │ " + memory + " │",
141-
" │ " + topMemory + " │",
142-
" └───────────────────────────────────────────┘",
143-
"",
144-
" Author: Ghast Version: 2.0.8 Today: "
145-
+ DateFormat.getDateTimeInstance().format(new Date(Instant.now().toEpochMilli())),
146-
""
147-
};
148-
149-
for (String s : logo) {
150-
System.out.println(s);
151-
}
15293

15394
if (input == null) {
15495
return -1;
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package dev.skidfuscator.obfuscator.util;
2+
3+
import lombok.experimental.UtilityClass;
4+
5+
import java.text.DateFormat;
6+
import java.time.Instant;
7+
import java.util.Date;
8+
9+
@UtilityClass
10+
public class LogoUtil {
11+
public static void printLogo() {
12+
/* Total number of processors or cores available to the JVM */
13+
final String processors =
14+
String.format("%19.19s", "Processors:")
15+
+ " "
16+
+ String.format(
17+
"%-19.19s",
18+
Runtime.getRuntime().availableProcessors() + " cores"
19+
);
20+
21+
final long freeMemory = Math.round(Runtime.getRuntime().freeMemory() / 1E6);
22+
final String memory =
23+
String.format("%19.19s", "Current Memory:")
24+
+ " "
25+
+ String.format("%-19.19s", freeMemory + "mb");
26+
27+
final long maxMemory = Math.round(Runtime.getRuntime().maxMemory() / 1E6);
28+
final String memoryString = (maxMemory == Long.MAX_VALUE
29+
? ConsoleColors.GREEN + "no limit"
30+
: maxMemory + "mb"
31+
);
32+
String topMemory =
33+
String.format("%19.19s", "Max Memory:")
34+
+ " "
35+
+ String.format("%-19.19s",
36+
memoryString + (maxMemory > 1500 ? "" : " ⚠️")
37+
);
38+
39+
topMemory = MiscUtil.replaceColor(
40+
topMemory,
41+
memoryString,
42+
maxMemory > 1500 ? ConsoleColors.GREEN_BRIGHT : ConsoleColors.RED_BRIGHT
43+
);
44+
// slight fix for thing
45+
topMemory = topMemory.replace("⚠️", "⚠️ ");
46+
47+
final String[] logo = new String[] {
48+
"",
49+
" /$$$$$$ /$$ /$$ /$$ /$$$$$$ /$$",
50+
" /$$__ $$| $$ |__/ | $$ /$$__ $$ | $$",
51+
"| $$ \\__/| $$ /$$ /$$ /$$$$$$$| $$ \\__//$$ /$$ /$$$$$$$ /$$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$",
52+
"| $$$$$$ | $$ /$$/| $$ /$$__ $$| $$$$ | $$ | $$ /$$_____/ /$$_____/ |____ $$|_ $$_/ /$$__ $$ /$$__ $$",
53+
" \\____ $$| $$$$$$/ | $$| $$ | $$| $$_/ | $$ | $$| $$$$$$ | $$ /$$$$$$$ | $$ | $$ \\ $$| $$ \\__/",
54+
" /$$ \\ $$| $$_ $$ | $$| $$ | $$| $$ | $$ | $$ \\____ $$| $$ /$$__ $$ | $$ /$$| $$ | $$| $$",
55+
"| $$$$$$/| $$ \\ $$| $$| $$$$$$$| $$ | $$$$$$/ /$$$$$$$/| $$$$$$$| $$$$$$$ | $$$$/| $$$$$$/| $$",
56+
" \\______/ |__/ \\__/|__/ \\_______/|__/ \\______/ |_______/ \\_______/ \\_______/ \\___/ \\______/ |__/",
57+
"",
58+
" ┌───────────────────────────────────────────┐",
59+
" │ " + processors + " │",
60+
" │ " + memory + " │",
61+
" │ " + topMemory + " │",
62+
" └───────────────────────────────────────────┘",
63+
"",
64+
" Author: Ghast Version: 2.0.8 Today: "
65+
+ DateFormat.getDateTimeInstance().format(new Date(Instant.now().toEpochMilli())),
66+
""
67+
};
68+
69+
for (String s : logo) {
70+
System.out.println(s);
71+
}
72+
}
73+
}

dev.skidfuscator.obfuscator/src/main/java/dev/skidfuscator/obfuscator/Skidfuscator.java

Lines changed: 71 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
import dev.skidfuscator.config.DefaultSkidConfig;
99
import dev.skidfuscator.obfuscator.creator.SkidApplicationClassSource;
1010
import dev.skidfuscator.obfuscator.creator.SkidCache;
11+
import dev.skidfuscator.obfuscator.dependency.CommonDependency;
12+
import dev.skidfuscator.obfuscator.dependency.DependencyDownloader;
13+
import dev.skidfuscator.obfuscator.dependency.matcher.DependencyMatcher;
1114
import dev.skidfuscator.obfuscator.directory.SkiddedDirectory;
1215
import dev.skidfuscator.obfuscator.event.EventBus;
1316
import dev.skidfuscator.obfuscator.event.impl.transform.ClassTransformEvent;
@@ -113,6 +116,7 @@ public class Skidfuscator {
113116
private PredicateAnalysis predicateAnalysis;
114117

115118
private final SkidRemapper classRemapper = new SkidRemapper(new HashMap<>());
119+
private final DependencyDownloader dependencyDownloader = new DependencyDownloader();
116120

117121
private final Counter counter = new Counter();
118122

@@ -685,28 +689,78 @@ private void _verify() {
685689
LOGGER.post("Starting verification");
686690
try {
687691
classSource.getClassTree().verify();
688-
} catch (Exception e) {
689-
LOGGER.error("\n" +
690-
"-----------------------------------------------------\n"
691-
+ "/!\\ Skidfuscator failed to compute some libraries!\n"
692-
+ "It it advised to read https://github.com/terminalsin/skidfuscator-java-obfuscator/wiki/Libraries\n"
693-
+ "\n"
694-
+ "The following class was NOT found. This can be a dependency of a dependency."
695-
+ "Error: " + e.getMessage() + "\n" +
696-
(e.getCause() == null
697-
? "\n"
698-
: " " + e.getCause().getMessage() + "\n"
699-
)
700-
+ "-----------------------------------------------------\n"
701-
, e);
702-
703-
if (!CLOUD)
704-
System.exit(1);
692+
} catch (Exception ex) {
693+
final List<String> missingClasses = classSource.getClassTree().getMissingClasses();
694+
695+
LOGGER.warn("Attempting to auto-resolve missing classes...");
696+
final Set<CommonDependency> commonDependencies = Arrays.stream(CommonDependency.values()).filter(f -> f.getMatcher().test(missingClasses)).collect(Collectors.toSet());
697+
698+
if (commonDependencies.isEmpty()) {
699+
LOGGER.warn("\n" +
700+
"-----------------------------------------------------\n"
701+
+ "/!\\ Skidfuscator failed to compute some libraries!\n"
702+
+ "PLEASE READ THE FOLLOWING WITH MUCH ATTENTION\n"
703+
+ "-----------------------------------------------------\n"
704+
+ "It it advised to read https://skidfuscator.dev/docs/libraries.html\n"
705+
+ "\n"
706+
+ "The following classes were NOT found. This means they are \n"
707+
+ "either not present in the libraries or the libraries are \n"
708+
+ "corrupted. Libraries themselves can have dependencies\n"
709+
+ "\n"
710+
+ "List of missing classes:\n"
711+
+ missingClasses.stream().map(f -> " --> " + f + "\n").collect(Collectors.joining())
712+
+ "-----------------------------------------------------\n"
713+
);
714+
715+
if (!CLOUD)
716+
System.exit(1);
717+
return;
718+
}
719+
commonDependencies.forEach(e -> {
720+
LOGGER.warn("Found common dependency: " + e.name() + "...\n");
721+
dependencyDownloader.download(e);
722+
LOGGER.warn("Downloaded " + e.name() + "...\n");
723+
});
724+
725+
726+
final Path mappingsDir = Paths.get("mappings");
727+
this.importMappingFolder(mappingsDir.toFile());
728+
729+
LOGGER.warn(String.format(
730+
"Resolved %d common dependencies... retrying verification...\n",
731+
commonDependencies.size()
732+
));
733+
_verify();
705734
return;
706735
}
707736
LOGGER.log("Finished verification!");
708737
}
709738

739+
private void importMappingFolder(final File folder) {
740+
for (File lib : folder.listFiles()) {
741+
if (lib.isDirectory()) {
742+
importMappingFolder(lib);
743+
continue;
744+
}
745+
746+
final String absolute = lib.getAbsolutePath();
747+
if (!absolute.endsWith(".json")) {
748+
LOGGER.debug(String.format("Skipping over %s since not end in json", absolute));
749+
continue;
750+
}
751+
752+
final GhostLibrary library = GhostHelper.readFromLibraryFile(LOGGER, lib);
753+
final ApplicationClassSource libraryClassSource = GhostHelper.importFile(LOGGER, session.isFuckIt(), library);
754+
/* Add library source to class source */
755+
classSource.addLibraries(new LibraryClassSource(
756+
libraryClassSource,
757+
5
758+
));
759+
760+
LOGGER.style(String.format("Importing %s... please wait...\n", absolute));
761+
}
762+
}
763+
710764
protected void _cleanup() {
711765
this.hierarchy = null;
712766
this.irFactory.clear();

0 commit comments

Comments
 (0)