diff --git a/pom.xml b/pom.xml
index e9a0931..dbaf405 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2,7 +2,7 @@
4.0.0
pw.yumc
MiaoScript
- 0.6.6
+ 0.7.0
502647092
@@ -53,6 +53,7 @@
DEV
+ §620-05-28 §afeat: 新增 Spring 的支持;
§620-05-02 §afeat: 调整 scope 为 @ccms;
§620-04-10 §afeat: 默认从 classpath 加载内建的js模块;
§620-04-07 §afeat: 默认初始化 内建 nodejs 模块;
@@ -180,11 +181,13 @@
org.spigotmc
spigot-api
1.15.2-R0.1-SNAPSHOT
+ compile
org.spongepowered
spongeapi
7.1.0
+ compile
net.md-5
@@ -195,6 +198,19 @@
cn.nukkit
nukkit
1.0-SNAPSHOT
+ compile
+
+
+ org.springframework
+ spring-websocket
+ 5.2.6.RELEASE
+ compile
+
+
+ org.apache.tomcat
+ tomcat-websocket
+ 9.0.35
+ compile
-
\ No newline at end of file
+
diff --git a/src/main/java/pw/yumc/MiaoScript/Base.java b/src/main/java/pw/yumc/MiaoScript/Base.java
index 6315b31..7568d80 100644
--- a/src/main/java/pw/yumc/MiaoScript/Base.java
+++ b/src/main/java/pw/yumc/MiaoScript/Base.java
@@ -21,7 +21,7 @@ public class Base {
this.instance = instance;
}
- public Class getClass(String name) throws ClassNotFoundException {
+ public Class> getClass(String name) throws ClassNotFoundException {
return Class.forName(name);
}
@@ -29,7 +29,7 @@ public class Base {
return this.instance;
}
- public Class getProxyClass() {
+ public Class> getProxyClass() {
return ProxyClass.class;
}
diff --git a/src/main/java/pw/yumc/MiaoScript/MiaoScriptSpring.java b/src/main/java/pw/yumc/MiaoScript/MiaoScriptSpring.java
new file mode 100644
index 0000000..1e1eb8e
--- /dev/null
+++ b/src/main/java/pw/yumc/MiaoScript/MiaoScriptSpring.java
@@ -0,0 +1,34 @@
+package pw.yumc.MiaoScript;
+
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.stereotype.Component;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+
+import java.io.File;
+import javax.annotation.PreDestroy;
+
+@Slf4j
+@Component
+public class MiaoScriptSpring {
+ private ScriptEngine engine;
+
+ @Bean
+ @SneakyThrows
+ public ScriptEngine buildScriptEngine(ApplicationContext applicationContext) {
+ return new ScriptEngine(new File("MiaoScript").getCanonicalPath(), log, applicationContext);
+ }
+
+ @Bean
+ public ServerEndpointExporter serverEndpointExporter() {
+ return new ServerEndpointExporter();
+ }
+
+ @PreDestroy
+ public void disableEngine() {
+ engine.disableEngine();
+ engine = null;
+ }
+}
diff --git a/src/main/java/pw/yumc/MiaoScript/ScriptEngine.java b/src/main/java/pw/yumc/MiaoScript/ScriptEngine.java
index d846c5e..3f856dc 100644
--- a/src/main/java/pw/yumc/MiaoScript/ScriptEngine.java
+++ b/src/main/java/pw/yumc/MiaoScript/ScriptEngine.java
@@ -1,6 +1,5 @@
package pw.yumc.MiaoScript;
-import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -12,8 +11,7 @@ import lombok.SneakyThrows;
/**
* Created with IntelliJ IDEA
*
- * @author 喵♂呜
- * Created on 2017/10/25 21:01.
+ * @author 喵♂呜 Created on 2017/10/25 21:01.
*/
public class ScriptEngine {
private String root;
@@ -30,24 +28,28 @@ public class ScriptEngine {
}
@SneakyThrows
- public void enableEngine() {
- this.engine = new MiaoScriptEngine(manager, "nashorn");
- this.engine.put("base", this.base);
- this.engine.put("ScriptEngineContextHolder", this);
- Path bios = Paths.get(root, "bios.js");
- // 如果存在自定义bios就加载自定义的
- if (Files.exists(bios)) {
- this.engine.eval("load('" + bios.toFile().getCanonicalPath() + "')");
- } else {
- this.engine.eval("load('classpath:bios.js')");
+ public synchronized void enableEngine() {
+ if (this.engine == null) {
+ this.engine = new MiaoScriptEngine(manager, "nashorn");
+ this.engine.put("base", this.base);
+ this.engine.put("ScriptEngineContextHolder", this);
+ Path bios = Paths.get(root, "bios.js");
+ // 如果存在自定义bios就加载自定义的
+ if (Files.exists(bios)) {
+ this.engine.eval("load('" + bios.toFile().getCanonicalPath() + "')");
+ } else {
+ this.engine.eval("load('classpath:bios.js')");
+ }
+ engine.invokeFunction("boot", root, logger);
}
- engine.invokeFunction("boot", root, logger);
}
@SneakyThrows
- public void disableEngine() {
- this.engine.invokeFunction("engineDisable");
- this.engine = null;
+ public synchronized void disableEngine() {
+ if (this.engine != null) {
+ this.engine.invokeFunction("engineDisable");
+ this.engine = null;
+ }
}
public MiaoScriptEngine getEngine() {
diff --git a/src/main/java/pw/yumc/MiaoScript/websocket/WebSocketServer.java b/src/main/java/pw/yumc/MiaoScript/websocket/WebSocketServer.java
new file mode 100644
index 0000000..12bb3df
--- /dev/null
+++ b/src/main/java/pw/yumc/MiaoScript/websocket/WebSocketServer.java
@@ -0,0 +1,70 @@
+package pw.yumc.MiaoScript.websocket;
+
+import lombok.SneakyThrows;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+import javax.websocket.*;
+import javax.websocket.server.ServerEndpoint;
+
+@Component
+@ServerEndpoint("/ws/")
+public class WebSocketServer implements ApplicationContextAware {
+ private static ApplicationContext context;
+ private WebSocketServerProxy proxy;
+
+ private boolean checkProxy(Session session) {
+ try {
+ if (this.proxy == null) {
+ this.proxy = context.getBean(WebSocketServerProxy.class);
+ }
+ return true;
+ } catch (Exception ex) {
+ try {
+ session.close();
+ } catch (Exception ignore) {
+ }
+ return false;
+ }
+ }
+
+ @OnOpen
+ @SneakyThrows
+ public void onOpen(Session session, EndpointConfig config) {
+ if (this.checkProxy(session)) {
+ this.proxy.onOpen(session, config);
+ }
+ }
+
+ @OnMessage
+ @SneakyThrows
+ public void onMessage(Session session, String message) {
+ if (this.checkProxy(session)) {
+ this.proxy.onMessage(session, message);
+ }
+ }
+
+ @OnClose
+ @SneakyThrows
+ public void onClose(Session session, CloseReason reason) {
+ if (this.checkProxy(session)) {
+ this.proxy.onClose(session, reason);
+ }
+ }
+
+ @OnError
+ @SneakyThrows
+ public void onError(Session session, Throwable error) {
+ if (this.checkProxy(session)) {
+ this.proxy.onError(session, error);
+ }
+ }
+
+ @Override
+ public void setApplicationContext(ApplicationContext ctx) throws BeansException {
+ context = ctx;
+ }
+}
diff --git a/src/main/java/pw/yumc/MiaoScript/websocket/WebSocketServerProxy.java b/src/main/java/pw/yumc/MiaoScript/websocket/WebSocketServerProxy.java
new file mode 100644
index 0000000..65c73a6
--- /dev/null
+++ b/src/main/java/pw/yumc/MiaoScript/websocket/WebSocketServerProxy.java
@@ -0,0 +1,15 @@
+package pw.yumc.MiaoScript.websocket;
+
+import javax.websocket.CloseReason;
+import javax.websocket.EndpointConfig;
+import javax.websocket.Session;
+
+public interface WebSocketServerProxy {
+ void onOpen(Session session, EndpointConfig config);
+
+ void onMessage(Session session, String message);
+
+ void onClose(Session session, CloseReason reason);
+
+ void onError(Session session, Throwable error);
+}
diff --git a/src/main/resources/bios.js b/src/main/resources/bios.js
index 1c6e42b..2ea2e2b 100644
--- a/src/main/resources/bios.js
+++ b/src/main/resources/bios.js
@@ -32,11 +32,9 @@ var global = this;
}, "MiaoScript thread").start()
};
- var pluginYml;
function checkClassLoader() {
var classLoader = java.lang.Thread.currentThread().contextClassLoader;
- pluginYml = classLoader.getResource("plugin.yml");
- if (pluginYml === null) {
+ if (classLoader.getResource("bios.js") === null) {
throw Error("Error class loader: " + classLoader.class.name + " Please contact the author MiaoWoo!");
} else {
log.info("Class loader compatible: " + classLoader.class.name);