Skip to content

Commit 14d89de

Browse files
committed
Upgrade plugin loader
1 parent df67d51 commit 14d89de

File tree

2 files changed

+64
-10
lines changed

2 files changed

+64
-10
lines changed

src/main/java/the/bytecode/club/jda/JDA.java

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616
import java.io.FileInputStream;
1717
import java.io.IOException;
1818
import java.net.MalformedURLException;
19-
import java.net.URL;
20-
import java.net.URLClassLoader;
2119
import java.nio.file.Files;
2220
import java.nio.file.Paths;
2321
import java.util.ArrayList;
@@ -90,14 +88,7 @@ else if (!pluginsDir.isDirectory())
9088
System.out.println("Skipping non-jar " + pluginFile.getName());
9189
continue;
9290
}
93-
94-
try {
95-
ClassLoader loader = URLClassLoader.newInstance(new URL[] {pluginFile.toURL()}, JDA.class.getClassLoader());
96-
Class.forName("Plugin", true, loader).getConstructor().newInstance();
97-
} catch (ReflectiveOperationException e) {
98-
System.err.println("Failed to load plugin " + pluginFile.getName());
99-
e.printStackTrace();
100-
}
91+
PluginLoader.tryLoadPlugin(pluginFile);
10192
}
10293
}
10394

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package the.bytecode.club.jda;
2+
3+
import java.io.*;
4+
import java.lang.reflect.Method;
5+
import java.net.MalformedURLException;
6+
import java.net.URL;
7+
import java.net.URLClassLoader;
8+
9+
public class PluginLoader {
10+
public static void tryLoadPlugin(File pluginFile) throws MalformedURLException {
11+
String pluginFileName = pluginFile.getName();
12+
try {
13+
ClassLoader loader = new URLClassLoader(new URL[] { pluginFile.toURI().toURL() }) {
14+
public URL getResource(String name) {
15+
if (name.startsWith("\0JDA-hack:"))
16+
return findResource(name.substring(name.indexOf(':') + 1));
17+
else
18+
return super.getResource(name);
19+
}
20+
};
21+
22+
InputStream metaInfStream = loader.getResourceAsStream("\0JDA-hack:META-INF/MANIFEST.MF");
23+
if (metaInfStream == null) {
24+
System.out.println("Invalid plugin " + pluginFileName + ": no manifest");
25+
return;
26+
}
27+
28+
String mainClass = parseManifest(metaInfStream);
29+
if (mainClass == null) {
30+
System.out.println("Invalid plugin " + pluginFileName + ": unable to parse manifest");
31+
return;
32+
}
33+
34+
Class<?> clazz = Class.forName(mainClass, true, loader);
35+
Method mainMethod = clazz.getMethod("main", String[].class);
36+
mainMethod.invoke(null, (Object) new String[0]);
37+
} catch (ReflectiveOperationException e) {
38+
System.err.println("Failed to load plugin " + pluginFileName);
39+
e.printStackTrace();
40+
}
41+
}
42+
43+
// Read Main-Class attribute from manifest. Return null if invalid
44+
public static String parseManifest(InputStream manifestStream) {
45+
BufferedReader reader = new BufferedReader(new InputStreamReader(manifestStream));
46+
String line;
47+
try {
48+
while ((line = reader.readLine()) != null) {
49+
String[] parts = line.split(":");
50+
if (parts.length < 2)
51+
return null;
52+
53+
String header = parts[0];
54+
if (header.equals("Main-Class")) {
55+
return parts[1].trim();
56+
}
57+
}
58+
return null;
59+
} catch (IOException e) {
60+
return null;
61+
}
62+
}
63+
}

0 commit comments

Comments
 (0)