Skip to content

Commit e6f18e6

Browse files
author
magiclu550
committed
add the simple plugin class loader
1 parent 406bb1e commit e6f18e6

File tree

6 files changed

+192
-6
lines changed

6 files changed

+192
-6
lines changed

src/main/java/cn/nukkit/plugin/JavaPluginLoader.java

Lines changed: 81 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
import cn.nukkit.Server;
44
import cn.nukkit.event.plugin.PluginDisableEvent;
55
import cn.nukkit.event.plugin.PluginEnableEvent;
6+
import cn.nukkit.plugin.simple.Command;
7+
import cn.nukkit.plugin.simple.Main;
68
import cn.nukkit.utils.PluginException;
79
import cn.nukkit.utils.Utils;
810

911
import java.io.File;
1012
import java.io.IOException;
1113
import java.io.InputStream;
12-
import java.util.HashMap;
13-
import java.util.Map;
14+
import java.util.*;
1415
import java.util.jar.JarEntry;
1516
import java.util.jar.JarFile;
1617
import java.util.regex.Pattern;
@@ -46,9 +47,7 @@ public Plugin loadPlugin(File file) throws Exception {
4647
try {
4748
Class javaClass = classLoader.loadClass(className);
4849

49-
if (!PluginBase.class.isAssignableFrom(javaClass)) {
50-
throw new PluginException("Main class `" + description.getMain() + "' does not extend PluginBase");
51-
}
50+
PluginAssert.isPluginBaseChild(javaClass,description.getMain());
5251

5352
try {
5453
Class<PluginBase> pluginClass = (Class<PluginBase>) javaClass.asSubclass(PluginBase.class);
@@ -64,13 +63,89 @@ public Plugin loadPlugin(File file) throws Exception {
6463
}
6564

6665
} catch (ClassNotFoundException e) {
67-
throw new PluginException("Couldn't load plugin " + description.getName() + ": main class not found");
66+
PluginAssert.findMainClass(description.getName());
6867
}
6968
}
7069

7170
return null;
7271
}
7372

73+
//TODO
74+
@Override
75+
public Plugin simpleLoadPlugin(File file) {
76+
try {
77+
Class<?> pluginClass = getSimplePlugin(file);
78+
PluginDescription pluginDescription = getSimpleDescription(pluginClass);
79+
this.server.getLogger().info(this.server.getLanguage().translateString("nukkit.plugin.load", pluginDescription.getFullName()));
80+
File dataFolder = new File(file.getParentFile(), pluginDescription.getName());
81+
PluginBase plugin = (PluginBase) pluginClass.newInstance();
82+
this.initPlugin(plugin,pluginDescription,dataFolder,file);
83+
return plugin;
84+
}catch (InstantiationException | IllegalAccessException e){
85+
throw new PluginException(e.getMessage());
86+
}
87+
//do it
88+
}
89+
90+
private Class getSimplePlugin(File file){
91+
try(JarFile jarFile = new JarFile(file)){
92+
PluginClassLoader classLoader = new PluginClassLoader(this, this.getClass().getClassLoader(),file);
93+
Enumeration<JarEntry> entries = jarFile.entries();
94+
while (entries.hasMoreElements()){
95+
String name = entries.nextElement().getName();
96+
if(name.endsWith(".class")) {
97+
String mainName = name.substring(0, name.lastIndexOf(".")).replace("/", ".");
98+
Class<?> clz = classLoader.loadClass(mainName);
99+
Main main = clz.getAnnotation(Main.class);
100+
if(main != null){
101+
PluginAssert.isPluginBaseChild(clz,mainName);
102+
return clz;
103+
}
104+
}
105+
}
106+
PluginAssert.findMainClass("");
107+
}catch (IOException|ClassNotFoundException e){
108+
throw new PluginException(e.getMessage());
109+
}
110+
return null;
111+
}
112+
113+
private PluginDescription getSimpleDescription(Class<?> plugin){
114+
Main main = plugin.getAnnotation(Main.class);
115+
if(main == null){
116+
throw new PluginException("this is not a main class");
117+
}
118+
String name = main.name();
119+
String version = main.version();
120+
String author = main.author();
121+
String description = main.description();
122+
String pluginLoadOrder = main.load();
123+
String website = main.website();
124+
String prefix = main.prefix();
125+
List<String> api = Arrays.asList(main.api());
126+
List<String> depend = Arrays.asList(main.depend());
127+
List<String> loadBefore = Arrays.asList(main.loadBefore());
128+
List<String> softDepend = Arrays.asList(main.softDepend());
129+
Map<String,Object> hashMap = new HashMap<>();
130+
hashMap.put("name",name);
131+
hashMap.put("version",version);
132+
hashMap.put("author",author);
133+
hashMap.put("api",api);
134+
hashMap.put("depend",depend);
135+
hashMap.put("loadBefore",loadBefore);
136+
hashMap.put("softDepend",softDepend);
137+
hashMap.put("description",description);
138+
hashMap.put("load",pluginLoadOrder);
139+
hashMap.put("website",website);
140+
hashMap.put("prefix",prefix);
141+
PluginDescription descript = new PluginDescription(hashMap);
142+
Command[] commands = main.commands();
143+
for(Command command:commands){
144+
descript.getCommands().put(command.name(),command);
145+
}
146+
return descript;
147+
}
148+
74149
@Override
75150
public Plugin loadPlugin(String filename) throws Exception {
76151
return this.loadPlugin(new File(filename));
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package cn.nukkit.plugin;
2+
3+
import cn.nukkit.utils.PluginException;
4+
5+
public class PluginAssert {
6+
7+
static void isPluginBaseChild(Class<?> javaClass,String main){
8+
if (!PluginBase.class.isAssignableFrom(javaClass)) {
9+
throw new PluginException("Main class `" + main + "' does not extend PluginBase");
10+
}
11+
}
12+
13+
static void findMainClass(String name) throws PluginException{
14+
throw new PluginException("Couldn't load plugin "+name+": main class not found");
15+
}
16+
}

src/main/java/cn/nukkit/plugin/PluginLoader.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,16 @@ public interface PluginLoader {
5858
*/
5959
Plugin loadPlugin(File file) throws Exception;
6060

61+
/**
62+
* 一个简便开发的插件加载系统,基于原来的插件系统<br>
63+
* A simple plugin loading system based on the original plugin system
64+
* @param file 这个插件的文件的 {@code File}对象。<br>A {@code File} object for this plugin.
65+
* @return 加载完毕的插件的 {@code Plugin}对象。<br>The loaded plugin as a {@code Plugin} object.
66+
* @see #loadPlugin(File)
67+
* @since Nukkit 1.0 | Nukkit API 1.0.9
68+
*/
69+
Plugin simpleLoadPlugin(File file);
70+
6171
/**
6272
* 通过插件文件名的字符串,来获得描述这个插件的 {@code PluginDescription}对象。<br>
6373
* Gets a {@code PluginDescription} object describes the plugin by its file name.
@@ -135,4 +145,5 @@ public interface PluginLoader {
135145
*/
136146
void disablePlugin(Plugin plugin);
137147

148+
138149
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package cn.nukkit.plugin.simple;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
8+
@Retention(RetentionPolicy.RUNTIME)
9+
@Target(ElementType.TYPE)
10+
public @interface Command {
11+
12+
String name();
13+
14+
String usage() default "";
15+
16+
String description() default "";
17+
18+
Permission permission();
19+
20+
String[] aliases() default {};
21+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package cn.nukkit.plugin.simple;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
8+
/**
9+
@ Main(name="11",api = "1.0.9",commands ={
10+
@ Command(name="fp",
11+
permission = @ Permission(
12+
theDefault = "op"
13+
)
14+
)
15+
})
16+
*/
17+
@Retention(RetentionPolicy.RUNTIME)
18+
@Target(ElementType.TYPE)
19+
public @interface Main {
20+
21+
22+
String name();
23+
24+
String version() default "0.0.1";
25+
26+
String author() default "";
27+
28+
String[] api();
29+
30+
String[] depend() default {};
31+
32+
String[] loadBefore() default {};
33+
34+
String [] softDepend() default {};
35+
36+
String description() default "";
37+
38+
String load() default "POSTWORLD";
39+
40+
String website() default "";
41+
42+
String prefix() default "";
43+
44+
Command[] commands() default {};
45+
46+
47+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package cn.nukkit.plugin.simple;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
8+
@Retention(RetentionPolicy.RUNTIME)
9+
@Target(ElementType.TYPE)
10+
public @interface Permission {
11+
12+
String description() default "";
13+
14+
String theDefault();
15+
16+
}

0 commit comments

Comments
 (0)