feat: remove spring support & optimize require

This commit is contained in:
MiaoWoo 2023-07-30 17:28:33 +08:00
parent 14cc05e923
commit 074e6e8a10
18 changed files with 225 additions and 322 deletions

3
.gitignore vendored
View File

@ -53,3 +53,6 @@ vendor/
# Minecraft Data # Minecraft Data
/world /world
**/node_modules/ **/node_modules/
# Gradle
.gradle

0
CHANGELOG.md Normal file
View File

60
pom.xml
View File

@ -2,13 +2,13 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>pw.yumc</groupId> <groupId>pw.yumc</groupId>
<artifactId>MiaoScript</artifactId> <artifactId>MiaoScript</artifactId>
<version>0.23.1</version> <version>0.28.0</version>
<developers> <developers>
<developer> <developer>
<id>502647092</id> <id>502647092</id>
<name>MiaoWoo</name> <name>MiaoWoo</name>
<email>admin@yumc.pw</email> <email>admin@yumc.pw</email>
<url>http://www.yumc.pw</url> <url>https://www.yumc.pw</url>
</developer> </developer>
</developers> </developers>
<build> <build>
@ -19,29 +19,6 @@
<filtering>true</filtering> <filtering>true</filtering>
</resource> </resource>
</resources> </resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<artifactSet>
<includes>
<include>org.kamranzafar:jtar</include>
</includes>
</artifactSet>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build> </build>
<ciManagement> <ciManagement>
<system>Jenkins</system> <system>Jenkins</system>
@ -50,6 +27,16 @@
<properties> <properties>
<env.GIT_COMMIT>DEV</env.GIT_COMMIT> <env.GIT_COMMIT>DEV</env.GIT_COMMIT>
<update.changes> <update.changes>
§623-07-30 §afeat: 优化 require 性能;
      §cfix: 修复 require 加载特殊文件异常;
§623-07-22 §afeat: 网络加载 jtar 优化包大小;
      §afeat: 移除 Spring 相关支持;
      §aremove: 移除 Spring 相关支持;
      §adeps: 更新 Nashorn 和 GraalvmJS 引擎版本
</update.changes>
<update.changelog>
§622-11-22 §afeat: 兼容 1.7.10-1.19.2 版本;
      §afeat: 新增 MiaoScriptAPI 相关方法;
§622-06-21 §afeat: 兼容 1.7.10-1.19 版本; §622-06-21 §afeat: 兼容 1.7.10-1.19 版本;
      §afeat: 兼容 JDK17 BungeeCord;       §afeat: 兼容 JDK17 BungeeCord;
§622-05-25 §afeat: 兼容 1.7.10-1.18.2 版本; §622-05-25 §afeat: 兼容 1.7.10-1.18.2 版本;
@ -61,7 +48,7 @@
      §afeat: 新增 自定义类型加载逻辑;       §afeat: 新增 自定义类型加载逻辑;
§622-02-16 §afeat: 新增 MiaoScriptAPI; §622-02-16 §afeat: 新增 MiaoScriptAPI;
      §afeat: 新增 ScriptEvent;       §afeat: 新增 ScriptEvent;
      §afeat: 新增 .mjs.json 类型加载;       §afeat: 新增 .mjs .json 类型加载;
§622-02-16 §afeat: 优化 初始化逻辑 加快引擎加载速度; §622-02-16 §afeat: 优化 初始化逻辑 加快引擎加载速度;
      §afeat: 新增 root 目录变更检测 变更后重新生成缓存;       §afeat: 新增 root 目录变更检测 变更后重新生成缓存;
      §afeat: 添加常用库的软依赖;       §afeat: 添加常用库的软依赖;
@ -71,9 +58,7 @@
§621-06-25 §afeat: 调整启动逻辑 兼容 Arclight; §621-06-25 §afeat: 调整启动逻辑 兼容 Arclight;
§621-06-22 §afeat: 新增本地版本锁定功能; §621-06-22 §afeat: 新增本地版本锁定功能;
§621-06-19 §afeat: 兼容JDK16 反射异常; §621-06-19 §afeat: 兼容JDK16 反射异常;
§621-05-15 §afeat: 兼容JDK15+ 自动下载Nashorn类库 §621-05-15 §afeat: 兼容JDK15+ 自动下载Nashorn类库;
</update.changes>
<update.changelog>
§621-03-25 §afeat: 异步加载 polyfill 并且同步加载 @ccms/core; §621-03-25 §afeat: 异步加载 polyfill 并且同步加载 @ccms/core;
§621-03-25 §cfix: 修改 ployfill 为 polyfill; §621-03-25 §cfix: 修改 ployfill 为 polyfill;
§620-12-22 §cfix: 增加 require 效验; §620-12-22 §cfix: 增加 require 效验;
@ -202,11 +187,6 @@
<version>1.18.24</version> <version>1.18.24</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency>
<groupId>org.kamranzafar</groupId>
<artifactId>jtar</artifactId>
<version>2.3</version>
</dependency>
<dependency> <dependency>
<groupId>org.spigotmc</groupId> <groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId> <artifactId>spigot-api</artifactId>
@ -231,17 +211,5 @@
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>5.3.19</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-websocket</artifactId>
<version>9.0.35</version>
<scope>compile</scope>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -21,7 +21,7 @@ import java.io.File;
* @author * @author
* Created on 2017/10/25 20:35. * Created on 2017/10/25 20:35.
*/ */
@Plugin(id = "miaoscript", name = "MiaoScript", version = MiaoScriptAPI.VERSION, authors = "MiaoWoo") @Plugin(id = "miaoscript", name = "MiaoScript", description = "MiaoScript runtime in Sponge", version = MiaoScriptAPI.VERSION, authors = "MiaoWoo")
public class MiaoScriptSponge { public class MiaoScriptSponge {
private ScriptEngine engine; private ScriptEngine engine;
@Inject @Inject

View File

@ -1,27 +0,0 @@
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 pw.yumc.MiaoScript.api.MiaoScriptAPI;
import pw.yumc.MiaoScript.api.ScriptEngine;
import java.io.File;
@Slf4j
@Component
public class MiaoScriptSpring {
@Bean
@SneakyThrows
public ScriptEngine buildScriptEngine(ApplicationContext applicationContext) {
return MiaoScriptAPI.createEngine(new File("MiaoScript").getCanonicalPath(), log, applicationContext);
}
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}

View File

@ -1,5 +1,7 @@
package pw.yumc.MiaoScript.api; package pw.yumc.MiaoScript.api;
import lombok.Getter;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@ -13,6 +15,7 @@ import java.nio.file.Paths;
* @author * @author
* Created on 2017/10/9 12:40. * Created on 2017/10/9 12:40.
*/ */
@Getter
public class Base { public class Base {
private final Object instance; private final Object instance;
@ -36,10 +39,6 @@ public class Base {
} }
} }
public Object getInstance() {
return this.instance;
}
public Class<?> getProxyClass() { public Class<?> getProxyClass() {
return ProxyClass.class; return ProxyClass.class;
} }

View File

@ -1,8 +1,11 @@
package pw.yumc.MiaoScript.api; package pw.yumc.MiaoScript.api;
import lombok.Getter;
import java.util.concurrent.Delayed; import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@Getter
public class JavaScriptTask implements Delayed { public class JavaScriptTask implements Delayed {
private final long id; private final long id;
private final Object task; private final Object task;
@ -35,20 +38,4 @@ public class JavaScriptTask implements Delayed {
return (int) (this.id - task.getId()); return (int) (this.id - task.getId());
} }
} }
public long getId() {
return this.id;
}
public Object getTask() {
return this.task;
}
public long getStartTime() {
return this.startTime;
}
public long getExecuteTime() {
return this.executeTime;
}
} }

View File

@ -1,5 +1,6 @@
package pw.yumc.MiaoScript.api; package pw.yumc.MiaoScript.api;
import lombok.Getter;
import pw.yumc.MiaoScript.api.loader.MavenDependLoader; import pw.yumc.MiaoScript.api.loader.MavenDependLoader;
import pw.yumc.MiaoScript.api.plugin.PluginManager; import pw.yumc.MiaoScript.api.plugin.PluginManager;
import pw.yumc.MiaoScript.engine.MiaoScriptEngine; import pw.yumc.MiaoScript.engine.MiaoScriptEngine;
@ -8,10 +9,12 @@ import java.io.File;
import java.nio.file.Paths; import java.nio.file.Paths;
public class MiaoScriptAPI { public class MiaoScriptAPI {
public static final String VERSION = "0.23.1"; public static final String VERSION = "0.28.0";
@Getter
private static String root; private static String root;
private static String libPath; private static String libPath;
private static ScriptEngine scriptEngine; private static ScriptEngine scriptEngine;
@Getter
private static PluginManager pluginManager; private static PluginManager pluginManager;
public static ScriptEngine createEngine(String root, Object logger, Object instance) { public static ScriptEngine createEngine(String root, Object logger, Object instance) {
@ -19,11 +22,7 @@ public class MiaoScriptAPI {
return MiaoScriptAPI.scriptEngine; return MiaoScriptAPI.scriptEngine;
} }
public static String getRoot() { static void setRoot(String root) {
return root;
}
public static void setRoot(String root) {
MiaoScriptAPI.root = root; MiaoScriptAPI.root = root;
MiaoScriptAPI.libPath = Paths.get(root, "libs").toString(); MiaoScriptAPI.libPath = Paths.get(root, "libs").toString();
} }
@ -32,14 +31,10 @@ public class MiaoScriptAPI {
return MiaoScriptAPI.scriptEngine.getEngine(); return MiaoScriptAPI.scriptEngine.getEngine();
} }
public static void setEngine(ScriptEngine scriptEngine) { static void setEngine(ScriptEngine scriptEngine) {
MiaoScriptAPI.scriptEngine = scriptEngine; MiaoScriptAPI.scriptEngine = scriptEngine;
} }
public static PluginManager getPluginManager() {
return pluginManager;
}
public static void setPluginManager(Object pluginManager) { public static void setPluginManager(Object pluginManager) {
MiaoScriptAPI.pluginManager = getEngine().getInterface(pluginManager, PluginManager.class); MiaoScriptAPI.pluginManager = getEngine().getInterface(pluginManager, PluginManager.class);
} }

View File

@ -0,0 +1,39 @@
package pw.yumc.MiaoScript.api.bukkit;
import lombok.Getter;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import javax.script.Bindings;
@Getter
public class EngineEvent extends Event implements Cancellable {
private final String event;
private final Bindings data;
private boolean cancelled = false;
public EngineEvent(String event, Bindings data) {
this.event = event;
this.data = data;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(boolean b) {
this.cancelled = b;
}
@Getter
private static final HandlerList handlerList = new HandlerList();
@Override
public HandlerList getHandlers() {
return handlerList;
}
}

View File

@ -1,15 +1,18 @@
package pw.yumc.MiaoScript.api.bukkit; package pw.yumc.MiaoScript.api.bukkit;
import lombok.Getter;
import org.bukkit.event.Cancellable; import org.bukkit.event.Cancellable;
import org.bukkit.event.Event; import org.bukkit.event.Event;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
import javax.script.Bindings; import javax.script.Bindings;
@Getter
public class ScriptEvent extends Event implements Cancellable { public class ScriptEvent extends Event implements Cancellable {
private final Bindings plugin; private final Bindings plugin;
private final String event; private final String event;
private final Bindings data; private final Bindings data;
private boolean cancelled = false; private boolean cancelled = false;
public ScriptEvent(Bindings plugin, String event, Bindings data) { public ScriptEvent(Bindings plugin, String event, Bindings data) {
@ -18,33 +21,6 @@ public class ScriptEvent extends Event implements Cancellable {
this.data = data; this.data = data;
} }
/**
* Which Plugin Call Event
*
* @return PluginName
*/
public Bindings getPlugin() {
return plugin;
}
/**
* Plugin Event Name
*
* @return EventName
*/
public String getEvent() {
return event;
}
/**
* Plugin Event Data
*
* @return EventData
*/
public Bindings getData() {
return data;
}
@Override @Override
public boolean isCancelled() { public boolean isCancelled() {
return this.cancelled; return this.cancelled;
@ -55,12 +31,9 @@ public class ScriptEvent extends Event implements Cancellable {
this.cancelled = b; this.cancelled = b;
} }
@Getter
private static final HandlerList handlerList = new HandlerList(); private static final HandlerList handlerList = new HandlerList();
public static HandlerList getHandlerList() {
return handlerList;
}
@Override @Override
public HandlerList getHandlers() { public HandlerList getHandlers() {
return handlerList; return handlerList;

View File

@ -4,6 +4,7 @@ import lombok.SneakyThrows;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
import java.nio.MappedByteBuffer; import java.nio.MappedByteBuffer;
@ -12,6 +13,8 @@ import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.nio.file.StandardCopyOption; import java.nio.file.StandardCopyOption;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class MavenDependLoader { public class MavenDependLoader {
public static final String MavenRepo = "https://maven.aliyun.com/repository/public"; public static final String MavenRepo = "https://maven.aliyun.com/repository/public";
@ -48,6 +51,7 @@ public class MavenDependLoader {
downloadFile(file, groupId, artifactId, version, ext); downloadFile(file, groupId, artifactId, version, ext);
} }
if (!new String(Files.readAllBytes(sha1.toPath())).equals(getSha1(file))) { if (!new String(Files.readAllBytes(sha1.toPath())).equals(getSha1(file))) {
sha1.delete();
file.delete(); file.delete();
throw new IllegalStateException("file " + file.getName() + " sha1 not match."); throw new IllegalStateException("file " + file.getName() + " sha1 not match.");
} }
@ -71,17 +75,19 @@ public class MavenDependLoader {
connection.setConnectTimeout(5000); connection.setConnectTimeout(5000);
connection.setReadTimeout(120000); connection.setReadTimeout(120000);
connection.setUseCaches(true); connection.setUseCaches(true);
Files.copy(connection.getInputStream(), target.toPath(), StandardCopyOption.REPLACE_EXISTING); try (InputStream inputStream = connection.getInputStream()) {
Files.copy(inputStream, target.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
} }
@SneakyThrows @SneakyThrows
private static String getSha1(File file) { private static String getSha1(File file) {
MessageDigest digest = MessageDigest.getInstance("SHA-1"); MessageDigest digest = MessageDigest.getInstance("SHA-1");
FileInputStream in = new FileInputStream(file); try (FileInputStream in = new FileInputStream(file)) {
FileChannel ch = in.getChannel(); MappedByteBuffer byteBuffer = in.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, file.length());
MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, 0, file.length()); digest.update(byteBuffer);
digest.update(byteBuffer); return getHash(digest.digest());
return getHash(digest.digest()); }
} }
private static String getHash(byte[] bytes) { private static String getHash(byte[] bytes) {

View File

@ -7,4 +7,16 @@ public interface PluginManager {
Map<String, Bindings> getPlugins(); Map<String, Bindings> getPlugins();
Bindings getPlugin(String name); Bindings getPlugin(String name);
boolean has(String name);
Bindings get(String name);
boolean enable(String name);
boolean disable(String name);
boolean install(String name);
boolean uninstall(String name);
} }

View File

@ -1,5 +1,6 @@
package pw.yumc.MiaoScript.engine; package pw.yumc.MiaoScript.engine;
import lombok.Getter;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import lombok.val; import lombok.val;
import pw.yumc.MiaoScript.api.loader.JarLoader; import pw.yumc.MiaoScript.api.loader.JarLoader;
@ -19,33 +20,41 @@ import java.util.List;
* @since 2016年8月29日 上午7:51:43 * @since 2016年8月29日 上午7:51:43
*/ */
public class MiaoScriptEngine implements ScriptEngine, Invocable { public class MiaoScriptEngine implements ScriptEngine, Invocable {
private final String libsRoot;
@Getter
private ScriptEngine engine; private ScriptEngine engine;
@SneakyThrows
public MiaoScriptEngine(String engineRoot) { public MiaoScriptEngine(String engineRoot) {
File libRootFile = new File(engineRoot, "libs");
libRootFile.mkdirs();
this.libsRoot = libRootFile.getCanonicalPath();
if (new File(engineRoot, "debug").exists()) { if (new File(engineRoot, "debug").exists()) {
System.setProperty("nashorn.debug", "true"); System.setProperty("nashorn.debug", "true");
} }
MavenDependLoader.load(this.libsRoot, "org.kamranzafar", "jtar", "2.3");
if (getJavaVersion() > 15) { if (getJavaVersion() > 15) {
this.loadGraalJS(engineRoot); this.loadGraalJS();
} else { } else {
this.loadNashorn(engineRoot); this.loadNashorn();
} }
if (engine == null) if (engine == null)
throw new UnsupportedOperationException("当前环境不支持 Nashorn 或 GraalJS 脚本引擎."); throw new UnsupportedOperationException("当前环境不支持 Nashorn 或 GraalJS 脚本引擎.");
} }
private void loadGraalJS(String engineRoot) { private void loadGraalJS() {
try { try {
this.engine = this.parentLoadNetworkNashorn(engineRoot); this.engine = this.parentLoadNetworkNashorn();
} catch (Throwable ex) { } catch (Throwable ex) {
this.engine = this.loadNetworkNashorn(engineRoot); this.engine = this.loadNetworkNashorn();
} }
if (this.engine == null) { if (this.engine == null) {
this.engine = this.loadNetworkGraalJS(engineRoot); this.engine = this.loadNetworkGraalJS();
} }
} }
private void loadNashorn(String engineRoot) { private void loadNashorn() {
try { try {
this.createEngineByName(); this.createEngineByName();
} catch (final Throwable ex) { } catch (final Throwable ex) {
@ -61,7 +70,7 @@ public class MiaoScriptEngine implements ScriptEngine, Invocable {
} }
try { try {
if (this.engine == null) { if (this.engine == null) {
this.engine = this.loadNetworkNashorn(engineRoot); this.engine = this.loadNetworkNashorn();
} }
} catch (final Throwable ex) { } catch (final Throwable ex) {
ex.printStackTrace(); ex.printStackTrace();
@ -95,43 +104,52 @@ public class MiaoScriptEngine implements ScriptEngine, Invocable {
return null; return null;
} }
@SneakyThrows private ScriptEngine loadNetworkNashorn() {
private ScriptEngine loadNetworkNashorn(String engineRoot) { MavenDependLoader.load(this.libsRoot, "org.openjdk.nashorn", "nashorn-core", "15.4");
File libRootFile = new File(engineRoot, "libs"); MavenDependLoader.load(this.libsRoot, "org.ow2.asm", "asm", "9.5");
libRootFile.mkdirs(); MavenDependLoader.load(this.libsRoot, "org.ow2.asm", "asm-commons", "9.5");
String libRoot = libRootFile.getCanonicalPath(); MavenDependLoader.load(this.libsRoot, "org.ow2.asm", "asm-tree", "9.5");
MavenDependLoader.load(libRoot, "org.openjdk.nashorn", "nashorn-core", "15.4"); MavenDependLoader.load(this.libsRoot, "org.ow2.asm", "asm-util", "9.5");
MavenDependLoader.load(libRoot, "org.ow2.asm", "asm", "9.3"); return createEngineByFactoryClassName("org.openjdk.nashorn.api.scripting.NashornScriptEngineFactory", false);
MavenDependLoader.load(libRoot, "org.ow2.asm", "asm-commons", "9.3"); }
MavenDependLoader.load(libRoot, "org.ow2.asm", "asm-tree", "9.3");
MavenDependLoader.load(libRoot, "org.ow2.asm", "asm-util", "9.3"); private ScriptEngine parentLoadNetworkNashorn() {
MavenDependLoader.parentLoad(this.libsRoot, "org.openjdk.nashorn", "nashorn-core", "15.4");
MavenDependLoader.parentLoad(this.libsRoot, "org.ow2.asm", "asm", "9.5");
MavenDependLoader.parentLoad(this.libsRoot, "org.ow2.asm", "asm-commons", "9.5");
MavenDependLoader.parentLoad(this.libsRoot, "org.ow2.asm", "asm-tree", "9.5");
MavenDependLoader.parentLoad(this.libsRoot, "org.ow2.asm", "asm-util", "9.5");
return createEngineByFactoryClassName("org.openjdk.nashorn.api.scripting.NashornScriptEngineFactory", false); return createEngineByFactoryClassName("org.openjdk.nashorn.api.scripting.NashornScriptEngineFactory", false);
} }
@SneakyThrows @SneakyThrows
private ScriptEngine parentLoadNetworkNashorn(String engineRoot) { private ScriptEngine loadNetworkGraalJS() {
File libRootFile = new File(engineRoot, "libs"); MavenDependLoader.load(this.libsRoot, "org.graalvm.js", "js", "23.0.1");
libRootFile.mkdirs(); MavenDependLoader.load(this.libsRoot, "org.graalvm.js", "js-scriptengine", "23.0.1");
String libRoot = libRootFile.getCanonicalPath(); MavenDependLoader.load(this.libsRoot, "org.graalvm.regex", "regex", "23.0.1");
MavenDependLoader.parentLoad(libRoot, "org.openjdk.nashorn", "nashorn-core", "15.4"); MavenDependLoader.load(this.libsRoot, "org.graalvm.sdk", "graal-sdk", "23.0.1");
MavenDependLoader.parentLoad(libRoot, "org.ow2.asm", "asm", "9.3"); MavenDependLoader.load(this.libsRoot, "org.graalvm.truffle", "truffle-api", "23.0.1");
MavenDependLoader.parentLoad(libRoot, "org.ow2.asm", "asm-commons", "9.3"); System.setProperty("polyglot.js.nashorn-compat", "true");
MavenDependLoader.parentLoad(libRoot, "org.ow2.asm", "asm-tree", "9.3"); System.setProperty("polyglot.js.scripting", "true");
MavenDependLoader.parentLoad(libRoot, "org.ow2.asm", "asm-util", "9.3"); System.setProperty("polyglot.js.ecmascript-version", "5");
return createEngineByFactoryClassName("org.openjdk.nashorn.api.scripting.NashornScriptEngineFactory", false); System.setProperty("polyglot.js.allowAllAccess", "true");
} Class<?> NashornScriptEngineFactory = Class.forName("com.oracle.truffle.js.scriptengine.GraalJSEngineFactory");
Method getScriptEngine = NashornScriptEngineFactory.getMethod("getScriptEngine");
@SneakyThrows Object factory = NashornScriptEngineFactory.newInstance();
private ScriptEngine loadNetworkGraalJS(String engineRoot) { return (ScriptEngine) getScriptEngine.invoke(factory);
File libRootFile = new File(engineRoot, "libs"); // Class<?> GraalJSScriptEngine = Class.forName("com.oracle.truffle.js.scriptengine.GraalJSScriptEngine");
libRootFile.mkdirs(); // Method createScriptEngine = GraalJSScriptEngine.getMethod("create", Class.forName("org.graalvm.polyglot.Engine"), Class.forName("org.graalvm.polyglot.Context"));
String libRoot = libRootFile.getCanonicalPath(); // Class<?> Context = Class.forName("org.graalvm.polyglot.Context");
MavenDependLoader.load(libRoot, "org.graalvm.js", "js", "22.1.0.1"); // Method newBuilder = Context.getMethod("newBuilder", String[].class);
MavenDependLoader.load(libRoot, "org.graalvm.js", "js-scriptengine", "22.1.0.1"); // Class<?> Builder = Class.forName("org.graalvm.polyglot.Context.Builder");
MavenDependLoader.load(libRoot, "org.graalvm.regex", "regex", "22.1.0.1"); // Method allowExperimentalOptions = Builder.getMethod("allowExperimentalOptions", boolean.class);
MavenDependLoader.load(libRoot, "org.graalvm.sdk", "graal-sdk", "22.1.0.1"); // Method allowAllAccess = Builder.getMethod("allowAllAccess", boolean.class);
MavenDependLoader.load(libRoot, "org.graalvm.truffle", "truffle-api", "22.1.0.1"); // Method option = Builder.getMethod("option", String.class, String.class);
return createEngineByFactoryClassName("org.openjdk.nashorn.api.scripting.NashornScriptEngineFactory", false); // Object context = newBuilder.invoke(null, (Object) new String[]{"js"});
// allowExperimentalOptions.invoke(context, true);
// allowAllAccess.invoke(context, true);
// option.invoke(context, "js.nashorn-compat", "true");
// return (ScriptEngine) createScriptEngine.invoke(null, null, context);
} }
@SneakyThrows @SneakyThrows
@ -153,10 +171,6 @@ public class MiaoScriptEngine implements ScriptEngine, Invocable {
return (ScriptEngine) getScriptEngine.invoke(factory, (Object) engineArgs.toArray(new String[]{})); return (ScriptEngine) getScriptEngine.invoke(factory, (Object) engineArgs.toArray(new String[]{}));
} }
public ScriptEngine getEngine() {
return this.engine;
}
@Override @Override
public Bindings createBindings() { public Bindings createBindings() {
return engine.createBindings(); return engine.createBindings();

View File

@ -1,6 +0,0 @@
package pw.yumc.MiaoScript.web;
import javax.servlet.Filter;
public interface WebFilterProxy extends Filter {
}

View File

@ -1,8 +0,0 @@
package pw.yumc.MiaoScript.web;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface WebServerProxy {
Object process(HttpServletRequest req, HttpServletResponse resp);
}

View File

@ -1,15 +0,0 @@
package pw.yumc.MiaoScript.websocket;
import javax.websocket.CloseReason;
import javax.websocket.EndpointConfig;
import javax.websocket.Session;
public interface WebSocketProxy {
void onOpen(Session session, EndpointConfig config);
void onMessage(Session session, String message);
void onClose(Session session, CloseReason reason);
void onError(Session session, Throwable error);
}

View File

@ -1,70 +0,0 @@
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 WebSocketProxy proxy;
private boolean checkProxy(Session session) {
try {
if (this.proxy == null) {
this.proxy = context.getBean(WebSocketProxy.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;
}
}

View File

@ -55,6 +55,7 @@
var MS_NODE_PATH = System.getenv("MS_NODE_PATH") || root + separatorChar + 'node_modules' var MS_NODE_PATH = System.getenv("MS_NODE_PATH") || root + separatorChar + 'node_modules'
var MS_NODE_REGISTRY = System.getenv("MS_NODE_REGISTRY") || 'https://registry.npmmirror.com' var MS_NODE_REGISTRY = System.getenv("MS_NODE_REGISTRY") || 'https://registry.npmmirror.com'
var MS_FALLBACK_NODE_REGISTRY = System.getenv("MS_FALLBACK_NODE_REGISTRY") || 'https://repo.yumc.pw/repository/npm' var MS_FALLBACK_NODE_REGISTRY = System.getenv("MS_FALLBACK_NODE_REGISTRY") || 'https://repo.yumc.pw/repository/npm'
var MS_SCRIPT_PACKAGE_CENTER = System.getenv("MS_SCRIPT_PACKAGE_CENTER") || 'https://mscript.yumc.pw/api/plugin/download'
var MS_NETWORK_CONNECT_TIMEOUT = System.getenv("MS_NETWORK_CONNECT_TIMEOUT") || 5000 var MS_NETWORK_CONNECT_TIMEOUT = System.getenv("MS_NETWORK_CONNECT_TIMEOUT") || 5000
var MS_NETWORK_READ_TIMEOUT = System.getenv("MS_NETWORK_TIMEOUT") || 45000 var MS_NETWORK_READ_TIMEOUT = System.getenv("MS_NETWORK_TIMEOUT") || 45000
var MS_NETWORK_DOWNLOAD_TIMEOUT = System.getenv("MS_NETWORK_DOWNLOAD_TIMEOUT") || 60000 var MS_NETWORK_DOWNLOAD_TIMEOUT = System.getenv("MS_NETWORK_DOWNLOAD_TIMEOUT") || 60000
@ -114,9 +115,11 @@
return file.absolutePath return file.absolutePath
} }
function __error(message) { function __error(message, name) {
var error = new Error(message)
if (name) { error.name = name }
console.error(message) console.error(message)
return new Error(message) return error
} }
/** /**
@ -153,7 +156,8 @@
function resolveAsFile(file, dir) { function resolveAsFile(file, dir) {
file = dir !== undefined ? new File(dir, file) : new File(file) file = dir !== undefined ? new File(dir, file) : new File(file)
// 直接文件 // 直接文件
if (file.isFile()) { // 只解析带后缀的文件 其他文件视为非法文件
if (file.isFile() && file.name.lastIndexOf('.') != -1) {
return file return file
} }
// JS文件 // JS文件
@ -364,6 +368,8 @@
/** /**
* 尝试从网络下载依赖包 * 尝试从网络下载依赖包
* @param {string} name 包名称 * @param {string} name 包名称
* @param {string} optional 附加选项
* @param {number} retry 重试次数
*/ */
function download(name, optional, retry) { function download(name, optional, retry) {
var name_arr = splitVersionFromName(name) var name_arr = splitVersionFromName(name)
@ -376,15 +382,19 @@
var info = fetchPackageInfo(module_name) var info = fetchPackageInfo(module_name)
if (!module_version) { if (!module_version) {
// if not special version get from lock or tag // if not special version get from lock or tag
module_version = ModulesVersionLock[module_name] || info['dist-tags']['latest'] module_version = ModulesVersionLock[module_name]
} else if (!/\d+\.\d+\.\w+/.test(module_version)) { } else if (!/\d+\.\d+\.\w+/.test(module_version)) {
// maybe module_version = latest // maybe module_version = latest if special version not exist then fallback latest
console.log('try get node_module ' + module_name + ' version from ' + module_version + ' tag waiting...')
module_version = info['dist-tags'][module_version] module_version = info['dist-tags'][module_version]
} }
var _version = info.versions[module_version] if (!module_version) {
if (!_version) { console.log('try get node_module ' + module_name + ' version from latest tag waiting...')
throw __error('fetch node_module ' + module_name + ' version ' + module_version + ' failed. can\t found tarball from versions.') module_version = info['dist-tags']['latest']
} }
if (!module_version) { throw __error('fetch node_module ' + module_name + " failed. can't found version from " + name + ".", 'ModuleNotFoundError') }
var _version = info.versions[module_version]
if (!_version) { throw __error('fetch node_module ' + module_name + ' version ' + module_version + " failed. can't found tarball from versions.", 'ModuleNotFoundError') }
var url = _version.dist.tarball var url = _version.dist.tarball
console.log('fetch node_module ' + module_name + ' version ' + module_version + ' waiting...') console.log('fetch node_module ' + module_name + ' version ' + module_version + ' waiting...')
return executor.submit(new Callable(function () { return executor.submit(new Callable(function () {
@ -400,18 +410,17 @@
Files.copy(tis, targetPath, StandardCopyOption.REPLACE_EXISTING) Files.copy(tis, targetPath, StandardCopyOption.REPLACE_EXISTING)
} }
return name return name
})).get(MS_NETWORK_DOWNLOAD_TIMEOUT, TimeUnit.SECONDS) })).get(MS_NETWORK_DOWNLOAD_TIMEOUT, TimeUnit.MILLISECONDS)
} catch (error) { } catch (error) {
retry = retry || 1 if (error.name == 'ModuleNotFoundError') { throw error }
if (retry > 3) { if (retry > 3) { throw __error('fetch node_module ' + module_name + ' version ' + module_version + ' failed. greater than 3 times stop retry.') }
throw __error('fetch node_module ' + module_name + ' version ' + module_version + ' failed. greater than 3 times stop retry.')
}
console.log('fetch node_module ' + module_name + ' version ' + module_version + ' failed retrying...') console.log('fetch node_module ' + module_name + ' version ' + module_version + ' failed retrying...')
return download(name, optional, ++retry) return download(name, optional, ++retry)
} }
} }
/** /**
* 获取包信息
* @param {string} module_name * @param {string} module_name
*/ */
function fetchPackageInfo(module_name) { function fetchPackageInfo(module_name) {
@ -419,7 +428,7 @@
try { try {
content = fetchContent(MS_NODE_REGISTRY + '/' + module_name) content = fetchContent(MS_NODE_REGISTRY + '/' + module_name)
} catch (ex) { } catch (ex) {
console.warn('can\'t fetch package ' + module_name + ' from ' + MS_NODE_REGISTRY + ' registry. try fetch from ' + MS_FALLBACK_NODE_REGISTRY + ' registry...') console.warn("can't fetch package " + module_name + ' from ' + MS_NODE_REGISTRY + ' registry. try fetch from ' + MS_FALLBACK_NODE_REGISTRY + ' registry...')
content = fetchContent(MS_FALLBACK_NODE_REGISTRY + '/' + module_name) content = fetchContent(MS_FALLBACK_NODE_REGISTRY + '/' + module_name)
} }
return JSON.parse(content) return JSON.parse(content)
@ -428,6 +437,7 @@
/** /**
* 获取网络内容 * 获取网络内容
* @param {string} url 网址 * @param {string} url 网址
* @param {number} [timeout] 超时时间
*/ */
function fetchContent(url, timeout) { function fetchContent(url, timeout) {
return executor.submit(new Callable(function fetchContent() { return executor.submit(new Callable(function fetchContent() {
@ -444,7 +454,7 @@
input.close() input.close()
output.close() output.close()
} }
})).get(timeout || MS_NETWORK_READ_TIMEOUT, TimeUnit.SECONDS) })).get(timeout || MS_NETWORK_READ_TIMEOUT, TimeUnit.MILLISECONDS)
} }
var lastModule = '' var lastModule = ''
@ -466,7 +476,7 @@
if (resolve(newName, path, optional) !== undefined) { if (resolve(newName, path, optional) !== undefined) {
return newName return newName
} }
throw __error("Can't load nodejs core module " + name + " . maybe later will auto replace to " + global.scope + "/nodejs/" + name + ' to compatible...') throw __error("can't load nodejs core module " + name + " . maybe later will auto replace to " + global.scope + "/nodejs/" + name + ' to compatible...')
} }
return name return name
} }
@ -488,7 +498,7 @@
function _require(name, path, optional) { function _require(name, path, optional) {
// require direct file // require direct file
var file = _isFile(name) ? name : new File(name) var file = _isFile(name) ? name : new File(name)
if (_isFile(file)) { if (_isFile(file) && file.name.lastIndexOf('.') != -1) {
return _requireFile(file, optional) return _requireFile(file, optional)
} }
// require cache module // require cache module
@ -499,14 +509,16 @@
} }
// check core module // check core module
name = checkCoreModule(name, path, optional) name = checkCoreModule(name, path, optional)
var file = resolve(name, path, optional)
// search module // search module
if ((file = resolve(name, path, optional)) === undefined) { if (file === undefined) {
// excloud local dir, prevent too many recursive call and cache not found module // excloud local dir, prevent too many recursive call and cache not found module
if (optional.local || optional.recursive || notFoundModules[name]) { if (optional.local || optional.recursive || notFoundModules[name]) {
throw __error("Can't found module " + name + '(' + JSON.stringify(optional) + ') at local ' + path + ' or network!') delete optional.parent
throw __error("can't found module " + name + '(' + JSON.stringify(optional) + ') at local ' + path + ' or network!')
} }
optional.recursive = true optional.recursive = true
return _require(download(name, optional), path, optional) return _require(download(name, optional, 1), path, optional)
} }
setCacheModule(file, optional) setCacheModule(file, optional)
return _requireFile(file, optional) return _requireFile(file, optional)
@ -545,7 +557,7 @@
*/ */
return function __DynamicRequire__(path, optional) { return function __DynamicRequire__(path, optional) {
if (!path) { if (!path) {
throw __error('require path can\'t be undefined or empty!') throw __error("require path can't be undefined or empty!")
} }
var optional = __assign({ var optional = __assign({
cache: true, cache: true,
@ -574,7 +586,7 @@
function __DynamicClear__(name) { function __DynamicClear__(name) {
for (var cacheModule in cacheModules) { for (var cacheModule in cacheModules) {
if (cacheModule.indexOf(name) !== -1) { if (cacheModule.indexOf(name) !== -1) {
console.trace('Clear module ' + cacheModule + ' ...') console.trace('clear module ' + cacheModule + ' ...')
delete cacheModules[cacheModule] delete cacheModules[cacheModule]
} }
} }
@ -585,12 +597,12 @@
for (var cacheModule in cacheModules) { for (var cacheModule in cacheModules) {
delete cacheModules[cacheModule] delete cacheModules[cacheModule]
} }
cacheModules = undefined cacheModules = {}
for (var cacheModuleId in cacheModuleIds) { for (var cacheModuleId in cacheModuleIds) {
delete cacheModuleIds[cacheModuleId] delete cacheModuleIds[cacheModuleId]
} }
cacheModuleIds = undefined cacheModuleIds = {}
notFoundModules = undefined notFoundModules = {}
} }
function __setUpgradeMode__(status) { function __setUpgradeMode__(status) {
@ -605,6 +617,7 @@
* @type {any} require * @type {any} require
*/ */
var require = exports(parent) var require = exports(parent)
require.cache = cacheModules
require.resolve = __DynamicResolve__ require.resolve = __DynamicResolve__
require.clear = __DynamicClear__ require.clear = __DynamicClear__
require.disable = __DynamicDisable__ require.disable = __DynamicDisable__
@ -621,6 +634,7 @@
notFoundModules: notFoundModules, notFoundModules: notFoundModules,
requireLoaders: requireLoaders requireLoaders: requireLoaders
} }
require.loadCoreScript = loadCoreScript
return require return require
} }
@ -629,8 +643,12 @@
* @param {any} loader * @param {any} loader
*/ */
function registerLoader(ext, loader) { function registerLoader(ext, loader) {
if (requireLoaders[ext]) {
return console.error('require loader ' + ext + ' already register ignore. if you want override loader please unregister before register.')
}
requireExts.push(ext)
requireLoaders[ext] = loader requireLoaders[ext] = loader
console.info('Register Require Loader ' + ext + ' => ' + (loader.name || '<anonymous>') + '.') console.info('register require loader ' + ext + ' => ' + (loader.name || '<anonymous>') + '.')
} }
/** /**
* @param {*} ext * @param {*} ext
@ -642,15 +660,17 @@
* @param {*} ext * @param {*} ext
*/ */
function unregisterLoader(ext) { function unregisterLoader(ext) {
requireExts.splice(requireExts.indexOf(ext), 1);
delete requireLoaders[ext] delete requireLoaders[ext]
console.info('unregister Require Loader ' + ext + '.') console.info('unregister require loader ' + ext + '.')
} }
function printRequireInfo() { function printRequireInfo() {
console.info('Initialization require module.') console.info('Initialization require module.')
console.info('ParentDir:', root) console.info('ParentDir:', root)
console.info('Require module env list:') console.info('Require module env list:')
console.info('- JAVA_VERSION: ', System.getProperty("java.version")) console.info('- JAVA_VERSION:', System.getProperty("java.version"))
console.info('- PLUGIN_VERSION:', base.version)
console.info('- MS_NODE_PATH:', MS_NODE_PATH.startsWith(root) ? MS_NODE_PATH.split(root)[1] : MS_NODE_PATH) console.info('- MS_NODE_PATH:', MS_NODE_PATH.startsWith(root) ? MS_NODE_PATH.split(root)[1] : MS_NODE_PATH)
console.info('- MS_NODE_REGISTRY:', MS_NODE_REGISTRY) console.info('- MS_NODE_REGISTRY:', MS_NODE_REGISTRY)
console.info('- MS_FALLBACK_NODE_REGISTRY:', MS_FALLBACK_NODE_REGISTRY) console.info('- MS_FALLBACK_NODE_REGISTRY:', MS_FALLBACK_NODE_REGISTRY)
@ -672,7 +692,7 @@
function initVersionLock() { function initVersionLock() {
try { try {
var version_lock_url = 'https://ms.yumc.pw/api/plugin/download/name/version_lock' + (global.debug ? '-debug' : '') var version_lock_url = MS_SCRIPT_PACKAGE_CENTER + '?name=version_lock' + (global.debug ? '-debug' : '')
ModulesVersionLock = JSON.parse(fetchContent(version_lock_url, 5000)) ModulesVersionLock = JSON.parse(fetchContent(version_lock_url, 5000))
try { try {
ModulesVersionLock = __assign(ModulesVersionLock, JSON.parse(base.read(localVersionLockFile))) ModulesVersionLock = __assign(ModulesVersionLock, JSON.parse(base.read(localVersionLockFile)))
@ -698,10 +718,7 @@
registerLoader('js', compileJsFile) registerLoader('js', compileJsFile)
registerLoader('json', compileJson) registerLoader('json', compileJson)
try { try {
engineLoad({ loadCoreScript('require_loader')(require)
script: fetchContent('https://ms.yumc.pw/api/plugin/download/name/require_loader', 5000),
name: 'core/require_loader.js'
})(require)
} catch (error) { } catch (error) {
console.warn("无法获取到最新的加载器信息 使用默认配置.") console.warn("无法获取到最新的加载器信息 使用默认配置.")
console.warn("InitRequireLoader Error:", error) console.warn("InitRequireLoader Error:", error)
@ -711,25 +728,41 @@
return require return require
} }
function loadCoreScript(name) {
return engineLoad({
script: fetchContent(MS_SCRIPT_PACKAGE_CENTER + '?name=' + name, 5000),
name: 'core/' + name + '.js'
})
}
if (typeof parent === 'string') { if (typeof parent === 'string') {
parent = new File(parent) parent = new File(parent)
} }
/** /**
* require 支持的后缀
* @type {string[]} requireExts
*/
var requireExts = []
/**
* require加载器
* @type {{[key:string]:(module:any, file:string, optional?:any)=>any}} requireLoader * @type {{[key:string]:(module:any, file:string, optional?:any)=>any}} requireLoader
*/ */
var requireLoaders = {} var requireLoaders = {}
/** /**
* @type {{[key:string]:any}} cacheModules * 已缓存的模块
* @type {{[key:string]:any}} [cacheModules]
*/ */
var cacheModules = {} var cacheModules = {}
var cacheModuleIdsFile = _canonical(new File(MS_NODE_PATH, 'cacheModuleIds.json')) var cacheModuleIdsFile = _canonical(new File(MS_NODE_PATH, 'cacheModuleIds.json'))
var localVersionLockFile = _canonical(new File(MS_NODE_PATH, 'moduleVersionLock.json')) var localVersionLockFile = _canonical(new File(MS_NODE_PATH, 'moduleVersionLock.json'))
/** /**
* @type {{[key:string]:{[key:string]:string}|string}} cacheModuleIds * 已缓存的模块ID
* @type {{[key:string]:{[key:string]:string}|string}} [cacheModuleIds]
*/ */
var cacheModuleIds = {} var cacheModuleIds = {}
/** /**
* @type {{[key:string]:boolean}} notFoundModules * 未找到的模块
* @type {{[key:string]:boolean}}
*/ */
var notFoundModules = {} var notFoundModules = {}
var upgradeMode = false var upgradeMode = false