From 56152657c8e5c8ed9c423515a694f552dfef3b9d Mon Sep 17 00:00:00 2001 From: MiaoWoo Date: Sat, 14 May 2022 18:44:24 +0800 Subject: [PATCH] feat: add MavenDependLoader Signed-off-by: MiaoWoo --- pom.xml | 12 +- .../pw/yumc/MiaoScript/MiaoScriptBukkit.java | 1 + .../pw/yumc/MiaoScript/MiaoScriptBungee.java | 1 + .../pw/yumc/MiaoScript/MiaoScriptNukkit.java | 1 + .../pw/yumc/MiaoScript/MiaoScriptSponge.java | 1 + .../pw/yumc/MiaoScript/MiaoScriptSpring.java | 1 + .../pw/yumc/MiaoScript/{ => api}/Base.java | 10 +- .../MiaoScript/{ => api}/JavaScriptTask.java | 2 +- .../pw/yumc/MiaoScript/api/MiaoScriptAPI.java | 41 ++- .../yumc/MiaoScript/{ => api}/ProxyClass.java | 2 +- .../MiaoScript/{ => api}/ScriptEngine.java | 5 +- .../MiaoScript/api/bukkit/ScriptEvent.java | 6 +- .../yumc/MiaoScript/api/loader/JarLoader.java | 48 ++++ .../api/loader/MavenDependLoader.java | 80 ++++++ .../MiaoScript/api/plugin/PluginManager.java | 10 + .../{ => engine}/MiaoScriptEngine.java | 76 +---- src/main/resources/bios.js | 12 +- src/main/resources/core/console.js | 34 ++- src/main/resources/core/require.js | 34 +-- src/main/resources/dev-plugins/HelloWorld.js | 69 ----- src/main/resources/dev-plugins/ItemTag.js | 88 ------ src/main/resources/dev-plugins/MiaoAuth.js | 70 ----- src/main/resources/dev-plugins/MiaoChat.js | 261 ------------------ .../resources/dev-plugins/bukkit/Lottery.js | 231 ---------------- .../resources/dev-plugins/bukkit/MiaoTag.js | 188 ------------- .../resources/dev-plugins/bukkit/WorldEdit.js | 48 ---- .../dev-plugins/markdown/MiaoChat.md | 32 --- .../resources/dev-plugins/sponge/MiaoBoard.js | 220 --------------- 28 files changed, 267 insertions(+), 1317 deletions(-) rename src/main/java/pw/yumc/MiaoScript/{ => api}/Base.java (91%) rename src/main/java/pw/yumc/MiaoScript/{ => api}/JavaScriptTask.java (97%) rename src/main/java/pw/yumc/MiaoScript/{ => api}/ProxyClass.java (97%) rename src/main/java/pw/yumc/MiaoScript/{ => api}/ScriptEngine.java (94%) create mode 100644 src/main/java/pw/yumc/MiaoScript/api/loader/JarLoader.java create mode 100644 src/main/java/pw/yumc/MiaoScript/api/loader/MavenDependLoader.java create mode 100644 src/main/java/pw/yumc/MiaoScript/api/plugin/PluginManager.java rename src/main/java/pw/yumc/MiaoScript/{ => engine}/MiaoScriptEngine.java (67%) delete mode 100644 src/main/resources/dev-plugins/HelloWorld.js delete mode 100644 src/main/resources/dev-plugins/ItemTag.js delete mode 100644 src/main/resources/dev-plugins/MiaoAuth.js delete mode 100644 src/main/resources/dev-plugins/MiaoChat.js delete mode 100644 src/main/resources/dev-plugins/bukkit/Lottery.js delete mode 100644 src/main/resources/dev-plugins/bukkit/MiaoTag.js delete mode 100644 src/main/resources/dev-plugins/bukkit/WorldEdit.js delete mode 100644 src/main/resources/dev-plugins/markdown/MiaoChat.md delete mode 100644 src/main/resources/dev-plugins/sponge/MiaoBoard.js diff --git a/pom.xml b/pom.xml index 664e414..b44e6ac 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 pw.yumc MiaoScript - 0.20.0 + 0.21.1 502647092 @@ -16,9 +16,6 @@ src/main/resources - - dev-plugins/** - true @@ -230,7 +227,7 @@ org.springframework spring-websocket - 5.3.13 + 5.3.18 compile @@ -239,5 +236,10 @@ 9.0.35 compile + + com.zaxxer + HikariCP + 4.0.3 + \ No newline at end of file diff --git a/src/main/java/pw/yumc/MiaoScript/MiaoScriptBukkit.java b/src/main/java/pw/yumc/MiaoScript/MiaoScriptBukkit.java index b43a70b..7138be8 100644 --- a/src/main/java/pw/yumc/MiaoScript/MiaoScriptBukkit.java +++ b/src/main/java/pw/yumc/MiaoScript/MiaoScriptBukkit.java @@ -2,6 +2,7 @@ package pw.yumc.MiaoScript; import lombok.SneakyThrows; import org.bukkit.plugin.java.JavaPlugin; +import pw.yumc.MiaoScript.api.ScriptEngine; /** * 喵式脚本 diff --git a/src/main/java/pw/yumc/MiaoScript/MiaoScriptBungee.java b/src/main/java/pw/yumc/MiaoScript/MiaoScriptBungee.java index ffa5620..84579c3 100644 --- a/src/main/java/pw/yumc/MiaoScript/MiaoScriptBungee.java +++ b/src/main/java/pw/yumc/MiaoScript/MiaoScriptBungee.java @@ -2,6 +2,7 @@ package pw.yumc.MiaoScript; import lombok.SneakyThrows; import net.md_5.bungee.api.plugin.Plugin; +import pw.yumc.MiaoScript.api.ScriptEngine; /** * Created with IntelliJ IDEA diff --git a/src/main/java/pw/yumc/MiaoScript/MiaoScriptNukkit.java b/src/main/java/pw/yumc/MiaoScript/MiaoScriptNukkit.java index 6aa1415..6aa658c 100644 --- a/src/main/java/pw/yumc/MiaoScript/MiaoScriptNukkit.java +++ b/src/main/java/pw/yumc/MiaoScript/MiaoScriptNukkit.java @@ -2,6 +2,7 @@ package pw.yumc.MiaoScript; import cn.nukkit.plugin.PluginBase; import lombok.SneakyThrows; +import pw.yumc.MiaoScript.api.ScriptEngine; /** * @author MiaoWoo diff --git a/src/main/java/pw/yumc/MiaoScript/MiaoScriptSponge.java b/src/main/java/pw/yumc/MiaoScript/MiaoScriptSponge.java index 372f1b5..1ba2ae4 100644 --- a/src/main/java/pw/yumc/MiaoScript/MiaoScriptSponge.java +++ b/src/main/java/pw/yumc/MiaoScript/MiaoScriptSponge.java @@ -11,6 +11,7 @@ import org.spongepowered.api.event.game.state.GameStartingServerEvent; import org.spongepowered.api.event.game.state.GameStoppingServerEvent; import org.spongepowered.api.plugin.Plugin; import pw.yumc.MiaoScript.api.MiaoScriptAPI; +import pw.yumc.MiaoScript.api.ScriptEngine; import java.io.File; diff --git a/src/main/java/pw/yumc/MiaoScript/MiaoScriptSpring.java b/src/main/java/pw/yumc/MiaoScript/MiaoScriptSpring.java index 7a9a019..4f9abf3 100644 --- a/src/main/java/pw/yumc/MiaoScript/MiaoScriptSpring.java +++ b/src/main/java/pw/yumc/MiaoScript/MiaoScriptSpring.java @@ -6,6 +6,7 @@ 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.ScriptEngine; import java.io.File; diff --git a/src/main/java/pw/yumc/MiaoScript/Base.java b/src/main/java/pw/yumc/MiaoScript/api/Base.java similarity index 91% rename from src/main/java/pw/yumc/MiaoScript/Base.java rename to src/main/java/pw/yumc/MiaoScript/api/Base.java index bd7d2e8..3e78676 100644 --- a/src/main/java/pw/yumc/MiaoScript/Base.java +++ b/src/main/java/pw/yumc/MiaoScript/api/Base.java @@ -1,6 +1,4 @@ -package pw.yumc.MiaoScript; - -import pw.yumc.MiaoScript.api.MiaoScriptAPI; +package pw.yumc.MiaoScript.api; import java.io.File; import java.io.IOException; @@ -16,7 +14,7 @@ import java.nio.file.Paths; * Created on 2017/10/9 12:40. */ public class Base { - private Object instance; + private final Object instance; Base(Object instance) { this.instance = instance; @@ -42,6 +40,10 @@ public class Base { return JavaScriptTask.class; } + public File[] loadMavenDepend(String groupId, String artifactId, String version) { + return MiaoScriptAPI.loadMavenDepend(groupId, artifactId, version); + } + public String read(String path) throws IOException { return read(Paths.get(path)); } diff --git a/src/main/java/pw/yumc/MiaoScript/JavaScriptTask.java b/src/main/java/pw/yumc/MiaoScript/api/JavaScriptTask.java similarity index 97% rename from src/main/java/pw/yumc/MiaoScript/JavaScriptTask.java rename to src/main/java/pw/yumc/MiaoScript/api/JavaScriptTask.java index 9a6fe8b..e128d7a 100644 --- a/src/main/java/pw/yumc/MiaoScript/JavaScriptTask.java +++ b/src/main/java/pw/yumc/MiaoScript/api/JavaScriptTask.java @@ -1,4 +1,4 @@ -package pw.yumc.MiaoScript; +package pw.yumc.MiaoScript.api; import java.util.concurrent.Delayed; import java.util.concurrent.TimeUnit; diff --git a/src/main/java/pw/yumc/MiaoScript/api/MiaoScriptAPI.java b/src/main/java/pw/yumc/MiaoScript/api/MiaoScriptAPI.java index ca20137..ed560b4 100644 --- a/src/main/java/pw/yumc/MiaoScript/api/MiaoScriptAPI.java +++ b/src/main/java/pw/yumc/MiaoScript/api/MiaoScriptAPI.java @@ -1,17 +1,48 @@ package pw.yumc.MiaoScript.api; -import pw.yumc.MiaoScript.MiaoScriptEngine; -import pw.yumc.MiaoScript.ScriptEngine; +import pw.yumc.MiaoScript.api.loader.MavenDependLoader; +import pw.yumc.MiaoScript.api.plugin.PluginManager; +import pw.yumc.MiaoScript.engine.MiaoScriptEngine; + +import java.io.File; +import java.nio.file.Paths; public class MiaoScriptAPI { - public static final String VERSION = "0.20.0"; + public static final String VERSION = "0.21.1"; + private static String root; + private static String libPath; private static ScriptEngine scriptEngine; + private static PluginManager pluginManager; - public static void setEngine(ScriptEngine scriptEngine) { - MiaoScriptAPI.scriptEngine = scriptEngine; + public static String getRoot() { + return root; + } + + public static void setRoot(String root) { + MiaoScriptAPI.root = root; + MiaoScriptAPI.libPath = Paths.get(root, "libs").toString(); } public static MiaoScriptEngine getEngine() { return MiaoScriptAPI.scriptEngine.getEngine(); } + + public static void setEngine(ScriptEngine scriptEngine) { + MiaoScriptAPI.scriptEngine = scriptEngine; + } + + public static PluginManager getPluginManager() { + return pluginManager; + } + + public static void setPluginManager(Object pluginManager) { + MiaoScriptAPI.pluginManager = getEngine().getInterface(pluginManager, PluginManager.class); + } + + public static File[] loadMavenDepend(String groupId, String artifactId, String version) { + if (root == null || scriptEngine == null) { + throw new IllegalStateException("root can't be null before loadMavenDepend."); + } + return MavenDependLoader.load(MiaoScriptAPI.libPath, groupId, artifactId, version); + } } diff --git a/src/main/java/pw/yumc/MiaoScript/ProxyClass.java b/src/main/java/pw/yumc/MiaoScript/api/ProxyClass.java similarity index 97% rename from src/main/java/pw/yumc/MiaoScript/ProxyClass.java rename to src/main/java/pw/yumc/MiaoScript/api/ProxyClass.java index 17369d0..2832269 100644 --- a/src/main/java/pw/yumc/MiaoScript/ProxyClass.java +++ b/src/main/java/pw/yumc/MiaoScript/api/ProxyClass.java @@ -1,4 +1,4 @@ -package pw.yumc.MiaoScript; +package pw.yumc.MiaoScript.api; import javax.script.Bindings; import javax.script.ScriptEngine; diff --git a/src/main/java/pw/yumc/MiaoScript/ScriptEngine.java b/src/main/java/pw/yumc/MiaoScript/api/ScriptEngine.java similarity index 94% rename from src/main/java/pw/yumc/MiaoScript/ScriptEngine.java rename to src/main/java/pw/yumc/MiaoScript/api/ScriptEngine.java index d6bf28e..f296156 100644 --- a/src/main/java/pw/yumc/MiaoScript/ScriptEngine.java +++ b/src/main/java/pw/yumc/MiaoScript/api/ScriptEngine.java @@ -1,7 +1,7 @@ -package pw.yumc.MiaoScript; +package pw.yumc.MiaoScript.api; import lombok.SneakyThrows; -import pw.yumc.MiaoScript.api.MiaoScriptAPI; +import pw.yumc.MiaoScript.engine.MiaoScriptEngine; import java.nio.file.Files; import java.nio.file.Path; @@ -25,6 +25,7 @@ public class ScriptEngine { this.root = root; this.logger = logger; this.base = new Base(instance); + MiaoScriptAPI.setRoot(root); MiaoScriptAPI.setEngine(this); } diff --git a/src/main/java/pw/yumc/MiaoScript/api/bukkit/ScriptEvent.java b/src/main/java/pw/yumc/MiaoScript/api/bukkit/ScriptEvent.java index 84ee323..3503da0 100644 --- a/src/main/java/pw/yumc/MiaoScript/api/bukkit/ScriptEvent.java +++ b/src/main/java/pw/yumc/MiaoScript/api/bukkit/ScriptEvent.java @@ -7,12 +7,12 @@ import org.bukkit.event.HandlerList; import javax.script.Bindings; public class ScriptEvent extends Event implements Cancellable { - private final String plugin; + private final Bindings plugin; private final String event; private final Bindings data; private boolean cancelled = false; - public ScriptEvent(String plugin, String event, Bindings data) { + public ScriptEvent(Bindings plugin, String event, Bindings data) { this.plugin = plugin; this.event = event; this.data = data; @@ -23,7 +23,7 @@ public class ScriptEvent extends Event implements Cancellable { * * @return PluginName */ - public String getPlugin() { + public Bindings getPlugin() { return plugin; } diff --git a/src/main/java/pw/yumc/MiaoScript/api/loader/JarLoader.java b/src/main/java/pw/yumc/MiaoScript/api/loader/JarLoader.java new file mode 100644 index 0000000..5905d24 --- /dev/null +++ b/src/main/java/pw/yumc/MiaoScript/api/loader/JarLoader.java @@ -0,0 +1,48 @@ +package pw.yumc.MiaoScript.api.loader; + +import lombok.SneakyThrows; + +import java.io.File; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.net.URL; + +public class JarLoader { + private static Object ucp; + private static MethodHandle addURLMethodHandle; + + static { + initReflect(); + } + + @SneakyThrows + public static File load(File file) { + addURLMethodHandle.invoke(ucp, file.toURI().toURL()); + return file; + } + + private static void initReflect() { + try { + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + Field theUnsafe = sun.misc.Unsafe.class.getDeclaredField("theUnsafe"); + theUnsafe.setAccessible(true); + sun.misc.Unsafe unsafe = (sun.misc.Unsafe) theUnsafe.get(null); + Field field = MethodHandles.Lookup.class.getDeclaredField("IMPL_LOOKUP"); + MethodHandles.Lookup lookup = (MethodHandles.Lookup) unsafe.getObject(unsafe.staticFieldBase(field), unsafe.staticFieldOffset(field)); + Field ucpField; + try { + ucpField = loader.getClass().getDeclaredField("ucp"); + } catch (NoSuchFieldException e) { + ucpField = loader.getClass().getSuperclass().getDeclaredField("ucp"); + } + long offset = unsafe.objectFieldOffset(ucpField); + ucp = unsafe.getObject(loader, offset); + Method method = ucp.getClass().getDeclaredMethod("addURL", URL.class); + addURLMethodHandle = lookup.unreflect(method); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/main/java/pw/yumc/MiaoScript/api/loader/MavenDependLoader.java b/src/main/java/pw/yumc/MiaoScript/api/loader/MavenDependLoader.java new file mode 100644 index 0000000..b5778b7 --- /dev/null +++ b/src/main/java/pw/yumc/MiaoScript/api/loader/MavenDependLoader.java @@ -0,0 +1,80 @@ +package pw.yumc.MiaoScript.api.loader; + +import lombok.SneakyThrows; + +import java.io.File; +import java.io.FileInputStream; +import java.net.URL; +import java.net.URLConnection; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.security.MessageDigest; + +public class MavenDependLoader { + private static final String MavenRepo = "https://maven.aliyun.com/repository/public"; + + public static File[] load(String libPath, String groupId, String artifactId, String version) { + return new File[]{ + downloadAndCheckSha1(libPath, groupId, artifactId, version, "pom"), + JarLoader.load(downloadAndCheckSha1(libPath, groupId, artifactId, version, "jar")) + }; + } + + @SneakyThrows + public static File downloadAndCheckSha1(String libPath, String groupId, String artifactId, String version, String ext) { + File sha1 = getMavenFile(libPath, groupId, artifactId, version, ext + ".sha1"); + if (!sha1.exists()) { + downloadFile(sha1, groupId, artifactId, version, ext + ".sha1"); + } + File file = getMavenFile(libPath, groupId, artifactId, version, ext); + if (!file.exists()) { + downloadFile(file, groupId, artifactId, version, ext); + } + if (!new String(Files.readAllBytes(sha1.toPath())).equals(getSha1(file))) { + file.delete(); + throw new IllegalStateException("file " + file.getName() + " sha1 not match."); + } + return file; + } + + public static File getMavenFile(String libPath, String groupId, String artifactId, String version, String ext) { + return Paths.get(libPath, groupId.replace(".", File.separator), artifactId, version, String.format("%s-%s.%s", artifactId, version, ext)).toFile(); + } + + @SneakyThrows + public static void downloadFile(File target, String groupId, String artifactId, String version, String ext) { + target.getParentFile().mkdirs(); + URLConnection connection = new URL(MavenRepo + + String.format("/%1$s/%2$s/%3$s/%2$s-%3$s.%4$s", + groupId.replace(".", "/"), + artifactId, + version, + ext) + ).openConnection(); + connection.setConnectTimeout(5000); + connection.setReadTimeout(30000); + connection.setUseCaches(true); + Files.copy(connection.getInputStream(), target.toPath(), StandardCopyOption.REPLACE_EXISTING); + } + + @SneakyThrows + private static String getSha1(File file) { + MessageDigest digest = MessageDigest.getInstance("SHA-1"); + FileInputStream in = new FileInputStream(file); + FileChannel ch = in.getChannel(); + MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, 0, file.length()); + digest.update(byteBuffer); + return getHash(digest.digest()); + } + + private static String getHash(byte[] bytes) { + StringBuilder result = new StringBuilder(); + for (byte b : bytes) { + result.append(String.format("%02x", b)); + } + return result.toString(); + } +} diff --git a/src/main/java/pw/yumc/MiaoScript/api/plugin/PluginManager.java b/src/main/java/pw/yumc/MiaoScript/api/plugin/PluginManager.java new file mode 100644 index 0000000..a51682a --- /dev/null +++ b/src/main/java/pw/yumc/MiaoScript/api/plugin/PluginManager.java @@ -0,0 +1,10 @@ +package pw.yumc.MiaoScript.api.plugin; + +import javax.script.Bindings; +import java.util.Map; + +public interface PluginManager { + Map getPlugins(); + + Bindings getPlugin(String name); +} diff --git a/src/main/java/pw/yumc/MiaoScript/MiaoScriptEngine.java b/src/main/java/pw/yumc/MiaoScript/engine/MiaoScriptEngine.java similarity index 67% rename from src/main/java/pw/yumc/MiaoScript/MiaoScriptEngine.java rename to src/main/java/pw/yumc/MiaoScript/engine/MiaoScriptEngine.java index ed2e61c..8193f7d 100644 --- a/src/main/java/pw/yumc/MiaoScript/MiaoScriptEngine.java +++ b/src/main/java/pw/yumc/MiaoScript/engine/MiaoScriptEngine.java @@ -1,19 +1,15 @@ -package pw.yumc.MiaoScript; +package pw.yumc.MiaoScript.engine; import lombok.SneakyThrows; import lombok.val; +import pw.yumc.MiaoScript.api.loader.JarLoader; +import pw.yumc.MiaoScript.api.loader.MavenDependLoader; import javax.script.ScriptEngine; import javax.script.*; import java.io.File; import java.io.Reader; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.StandardCopyOption; import java.util.HashMap; /** @@ -23,12 +19,9 @@ import java.util.HashMap; * @since 2016年8月29日 上午7:51:43 */ public class MiaoScriptEngine implements ScriptEngine, Invocable { - private static String MavenRepo = "https://maven.aliyun.com/repository/public"; private static MiaoScriptEngine DEFAULT; private static final ScriptEngineManager manager; - private Object ucp; - private MethodHandle addURLMethodHandle; private ScriptEngine engine; static { @@ -88,71 +81,26 @@ public class MiaoScriptEngine implements ScriptEngine, Invocable { for (String dir : dirs) { File nashorn = new File(dir, "nashorn.jar"); if (nashorn.exists()) { - this.loadJar(nashorn); + JarLoader.load(nashorn); this.createEngineByName(engineType); } } } - private void initReflect() { - try { - ClassLoader loader = Thread.currentThread().getContextClassLoader(); - Field theUnsafe = sun.misc.Unsafe.class.getDeclaredField("theUnsafe"); - theUnsafe.setAccessible(true); - sun.misc.Unsafe unsafe = (sun.misc.Unsafe) theUnsafe.get(null); - Field field = MethodHandles.Lookup.class.getDeclaredField("IMPL_LOOKUP"); - MethodHandles.Lookup lookup = (MethodHandles.Lookup) unsafe.getObject(unsafe.staticFieldBase(field), unsafe.staticFieldOffset(field)); - Field ucpField; - try { - ucpField = loader.getClass().getDeclaredField("ucp"); - } catch (NoSuchFieldException e) { - ucpField = loader.getClass().getSuperclass().getDeclaredField("ucp"); - } - long offset = unsafe.objectFieldOffset(ucpField); - ucp = unsafe.getObject(loader, offset); - Method method = ucp.getClass().getDeclaredMethod("addURL", URL.class); - addURLMethodHandle = lookup.unreflect(method); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - @SneakyThrows private void loadNetworkNashorn(String engineRoot) { - initReflect(); - File libRootFile = new File(engineRoot, "lib"); + File libRootFile = new File(engineRoot, "libs"); libRootFile.mkdirs(); String libRoot = libRootFile.getCanonicalPath(); - downloadJar(libRoot, "org.openjdk.nashorn", "nashorn-core", "15.3"); - downloadJar(libRoot, "org.ow2.asm", "asm", "9.2"); - downloadJar(libRoot, "org.ow2.asm", "asm-commons", "9.2"); - downloadJar(libRoot, "org.ow2.asm", "asm-tree", "9.2"); - downloadJar(libRoot, "org.ow2.asm", "asm-util", "9.2"); + MavenDependLoader.load(libRoot, "org.openjdk.nashorn", "nashorn-core", "15.3"); + MavenDependLoader.load(libRoot, "org.ow2.asm", "asm", "9.2"); + MavenDependLoader.load(libRoot, "org.ow2.asm", "asm-commons", "9.2"); + MavenDependLoader.load(libRoot, "org.ow2.asm", "asm-tree", "9.2"); + MavenDependLoader.load(libRoot, "org.ow2.asm", "asm-util", "9.2"); Class NashornScriptEngineFactory = Class.forName("org.openjdk.nashorn.api.scripting.NashornScriptEngineFactory"); - Method getScriptEngine = NashornScriptEngineFactory.getMethod("getScriptEngine", ClassLoader.class); + Method getScriptEngine = NashornScriptEngineFactory.getMethod("getScriptEngine"); Object factory = NashornScriptEngineFactory.newInstance(); - engine = (ScriptEngine) getScriptEngine.invoke(factory, ClassLoader.getSystemClassLoader()); - } - - @SneakyThrows - private void loadJar(File file) { - addURLMethodHandle.invoke(ucp, file.toURI().toURL()); - } - - @SneakyThrows - private void downloadJar(String engineRoot, String groupId, String artifactId, String version) { - File lib = new File(engineRoot, String.format("%s-%s.jar", artifactId, version)); - if (!lib.exists()) { - Files.copy(new URL(MavenRepo + - String.format("/%1$s/%2$s/%3$s/%2$s-%3$s.jar", - groupId.replace(".", "/"), - artifactId, - version) - ).openStream(), - lib.toPath(), - StandardCopyOption.REPLACE_EXISTING); - } - this.loadJar(lib); + engine = (ScriptEngine) getScriptEngine.invoke(factory); } private void createEngineByName(String engineType) { diff --git a/src/main/resources/bios.js b/src/main/resources/bios.js index f34d566..14b91cb 100644 --- a/src/main/resources/bios.js +++ b/src/main/resources/bios.js @@ -16,7 +16,7 @@ var global = this; global.logger = logger // Development Env Detect global.root = root || "src/main/resources" - checkDebug() + readEnvironment() if (!global.debug) { checkUpgrade() } @@ -50,24 +50,24 @@ var global = this; global.engineDisableImpl && global.engineDisableImpl() } - function checkDebug() { + function readEnvironment() { if (__FILE__.indexOf('!') === -1) { - logger.info('Loading custom BIOS file ' + __FILE__) + logger.info('loading custom BIOS file ' + __FILE__) global.debug = true } if (Files.exists(Paths.get(root, "debug"))) { - logger.info('Running in debug mode...') + logger.info('running in debug mode...') global.debug = true } if (Files.exists(Paths.get(root, "level"))) { global.level = base.read(Paths.get(root, "level")) - logger.info('Set system level to [' + global.level + ']...') + logger.info('set system level to [' + global.level + ']...') } } function checkUpgrade() { if (Files.exists(Paths.get(root, "upgrade"))) { - logger.info('Found upgrade file starting upgrade...') + logger.info('found upgrade file starting upgrade...') base.move(Paths.get(root, "node_modules"), Paths.get(root, "old_node_modules")) base.delete(Paths.get(root, "upgrade")) } diff --git a/src/main/resources/core/console.js b/src/main/resources/core/console.js index 17d2a21..af7f91a 100644 --- a/src/main/resources/core/console.js +++ b/src/main/resources/core/console.js @@ -2,12 +2,30 @@ // @ts-check ( /** - * @param {{ info: (arg0: string) => void; }} logger + * @param {{ + * info: (arg0: string) => void; + * warn: (arg0: string) => void; + * debug: (arg0: string) => void; + * error: (arg0: string) => void; + * warning: (arg0: string) => void; + * }} logger */ function (logger) { function log() { logger.info(Array.prototype.join.call(arguments, ' ')) } + function warn() { + logger.warn(Array.prototype.join.call(arguments, ' ')) + } + function debug() { + logger.debug(Array.prototype.join.call(arguments, ' ')) + } + function error() { + logger.error(Array.prototype.join.call(arguments, ' ')) + } + function warning() { + logger.warning(Array.prototype.join.call(arguments, ' ')) + } /** * @param {string} prefix */ @@ -16,13 +34,23 @@ log('[' + prefix + ']', Array.prototype.join.call(arguments, ' ')) } } - return { + var logProxy = { log: log, info: log, ex: log, trace: global.level === "trace" ? _proxy('TRACE') : global.noop, - debug: global.debug ? _proxy('DEBUG') : global.noop, + debug: global.debug ? logger.debug ? debug : _proxy('DEBUG') : global.noop, warn: _proxy('WARN'), error: _proxy('ERROR') } + if (logger.warn) { + logProxy.warn = warn + } + if (logger.warning) { + logProxy.warn = warning + } + if (logger.error) { + logProxy.error = error + } + return logProxy }) diff --git a/src/main/resources/core/require.js b/src/main/resources/core/require.js index 21e34ef..87e332d 100644 --- a/src/main/resources/core/require.js +++ b/src/main/resources/core/require.js @@ -217,7 +217,7 @@ var filename = file.name var lastDotIndexOf = filename.lastIndexOf('.') if (lastDotIndexOf == -1) { - throw Error('require module must include file ext.') + throw Error('require ' + file + ' error: module must include file ext.') } var name = filename.substring(0, lastDotIndexOf) var ext = filename.substring(lastDotIndexOf + 1) @@ -268,8 +268,9 @@ } // 2019-09-19 使用 扩展函数直接 load 无需保存/删除文件 // 2020-02-16 结尾新增换行 防止有注释导致加载失败 + var wrapperScript = '(function (module, exports, require, __dirname, __filename) {' + script + '\n});' var compiledWrapper = engineLoad({ - script: '(function (module, exports, require, __dirname, __filename) {' + script + '\n});', + script: wrapperScript, name: optional.id }) compiledWrapper.apply(module.exports, [ @@ -306,19 +307,24 @@ var module_name = name.startsWith('@') ? name_arr[0] + '/' + name_arr[1] : name_arr[0] var target = MS_NODE_PATH + separatorChar + module_name var _package = new File(target, 'package.json') - if (_package.exists()) { - return - } + if (_package.exists()) { return name } // at windows need replace file name java.lang.IllegalArgumentException: Invalid prefix or suffix var info = fetchPackageInfo(module_name) - var url = info.versions[ModulesVersionLock[module_name] || info['dist-tags']['latest']].dist.tarball - console.log('fetch node_module ' + module_name + ' from ' + url + ' waiting...') + var latest_version = info['dist-tags']['latest'] + var version = ModulesVersionLock[module_name] || latest_version + var _version = info.versions[version] || info.versions[latest_version] + var url = _version.dist.tarball + console.log('fetch node_module ' + module_name + ' version ' + version + ' waiting...') return executor.submit(new Callable(function () { var tis = new TarInputStream(new BufferedInputStream(new GZIPInputStream(new URL(url).openStream()))) var entry while ((entry = tis.getNextEntry()) != null) { var targetPath = Paths.get(target + separatorChar + entry.getName().substring(8)) - targetPath.toFile().getParentFile().mkdirs() + var parentFile = targetPath.toFile().getParentFile() + if (!parentFile.isDirectory()) { + parentFile.delete() + parentFile.mkdirs() + } Files.copy(tis, targetPath, StandardCopyOption.REPLACE_EXISTING) } return name @@ -418,13 +424,8 @@ if (optional.local || optional.recursive || notFoundModules[name]) { throw new Error("Can't found module " + name + '(' + JSON.stringify(optional) + ') at local ' + path + ' or network!') } - try { - optional.recursive = true - return _require(download(name), path, optional) - } catch (ex) { - notFoundModules[name] = true - throw new Error("Can't found module " + name + ' in directory ' + path + ' ERROR: ' + ex) - } + optional.recursive = true + return _require(download(name), path, optional) } setCacheModule(file, optional) return _requireFile(file, optional) @@ -592,7 +593,8 @@ function initVersionLock() { try { - ModulesVersionLock = JSON.parse(fetchContent('https://ms.yumc.pw/api/plugin/download/name/version_lock', 5)) + var version_lock_url = 'https://ms.yumc.pw/api/plugin/download/name/version_lock' + (global.debug ? '-debug' : '') + ModulesVersionLock = JSON.parse(fetchContent(version_lock_url, 5)) try { ModulesVersionLock = __assign(ModulesVersionLock, JSON.parse(base.read(localVersionLockFile))) } catch (e) { diff --git a/src/main/resources/dev-plugins/HelloWorld.js b/src/main/resources/dev-plugins/HelloWorld.js deleted file mode 100644 index 327fdfc..0000000 --- a/src/main/resources/dev-plugins/HelloWorld.js +++ /dev/null @@ -1,69 +0,0 @@ -'use strict'; -/** - * Hello Wrold 测试插件 - */ -/*global Java, base, module, exports, require*/ - -var event = require('api/event'); -var wrapper = require('api/wrapper'); -var command = require('api/command'); -var server = require('api/server'); -var fs = require('fs'); - -var description = { - name: 'HelloWorld', - version: '1.0', - author: 'MiaoWoo', - commands: { - 'hello': { - description: 'HelloWorld主命令' - } - } -}; - -function load() { - console.log('载入 Hello Wrold 测试插件!'); -} - -function enable() { - // noinspection JSUnusedLocalSymbols - command.on(this, 'hello', { - cmd: function(sender, command, args) { - engineLoad(fs.file(root, 'test.js')); - return true; - } - }); - console.log('启用 Hello World 测试插件!'); - switch (DetectServerType) { - case ServerType.Bukkit: - event.on(this, 'PlayerLoginEvent', function join(event) { - send(event, wrapper.player(event.player)); - }); - break; - case ServerType.Sponge: - event.on(this, 'ClientConnectionEvent.Join', function join(event) { - send(event, wrapper.player(event.targetEntity)); - }); - break; - } -} - -function send(event, player) { - // noinspection JSUnresolvedVariable - console.debug('玩家', player.getName(), "触发事件", event.class.simpleName); - setTimeout(function() { - // noinspection JSUnresolvedVariable - player.sendMessage("§a欢迎来到 §bMiaoScript §a的世界! 当前在线: " + server.players().length) - }, 10); -} - -function disable() { - console.log('卸载 Hello World 测试插件!'); -} - -module.exports = { - description: description, - load: load, - enable: enable, - disable: disable -}; diff --git a/src/main/resources/dev-plugins/ItemTag.js b/src/main/resources/dev-plugins/ItemTag.js deleted file mode 100644 index b90d88b..0000000 --- a/src/main/resources/dev-plugins/ItemTag.js +++ /dev/null @@ -1,88 +0,0 @@ -'use strict'; -/*global Java, base, module, exports, require*/ -var event = require('api/event'); -var task = require('api/task'); -var http = require('http'); -var fs = require('fs'); - -var Keys; - -var description = { - name: 'ItemTag', - version: '1.0', - author: 'MiaoWoo' -}; - -var itemConfig; - -function load() { - var itemFile = self.file('item.yml'); - task.async(function() { - if (!itemFile.exists()) { - fs.save(itemFile, http.get('https://data.yumc.pw/config/Item_zh_CN.yml')) - } - itemConfig = self.getConfig('item.yml') - }) -} - -function enable() { - switch (DetectServerType) { - case ServerType.Bukkit: - var i = require('api/item').create('STONE') - if (!i.setCustomName) { return } - event.on(self, 'ItemMergeEvent', function(event) { - bukkit(event.target, event.entity.itemStack.amount + event.target.itemStack.amount); - }); - event.on(self, 'ItemSpawnEvent', function(event) { - if (event.entity.itemStack) { - bukkit(event.entity, event.entity.itemStack.amount); - } - }); - break; - case ServerType.Sponge: - Keys = Java.type('org.spongepowered.api.data.key.Keys'); - event.on(self, 'ItemMergeItemEvent', function(event) { - // Sponge 暂未实现当前事件 - }); - event.on(self, 'SpawnEntityEvent', function(event) { - event.entities.forEach(function(entity) { - if (entity.type.name === "item") sponge(entity); - }) - }); - break; - } -} - -function bukkit(item, amount) { - item.setCustomName('§b' + getItemName(item.itemStack.type) + getItemCount(amount)); - item.setCustomNameVisible(true); -} - -function sponge(entity) { - var itemOptional = entity.get(Keys['REPRESENTED_ITEM']); - if (itemOptional.isPresent()) { - var item = itemOptional.get(); - var itemName = '§b' + getItemName(item.type.name.split(':')[1]) + getItemCount(item.count); - entity.offer(Keys['DISPLAY_NAME'], org.spongepowered.api.text.Text.of(itemName)); - entity.offer(Keys['CUSTOM_NAME_VISIBLE'], true); - } -} - -function getItemName(name) { - return itemConfig[(name + '').toUpperCase()] || name; -} - -function getItemCount(amount) { - return amount === 1 ? "" : "*" + amount; -} - -function disable() { - console.log('卸载', description.name, '插件!'); -} - -module.exports = { - description: description, - load: load, - enable: enable, - disable: disable -}; diff --git a/src/main/resources/dev-plugins/MiaoAuth.js b/src/main/resources/dev-plugins/MiaoAuth.js deleted file mode 100644 index 257ac55..0000000 --- a/src/main/resources/dev-plugins/MiaoAuth.js +++ /dev/null @@ -1,70 +0,0 @@ -'use strict'; -/** - * MiaoAuth简易登录系统 - */ -/*global Java, base, module, exports, require*/ - -var event = require('api/event'); -var wrapper = require('api/wrapper'); -var command = require('api/command'); - -var description = { - name: 'MiaoAuth', - version: '1.0', - author: 'MiaoWoo', - commands: { - 'l': { - description: 'MiaoAuth登录命令' - }, - 'r': { - description: 'MiaoAuth注册命令' - } - } -}; - -function load() { - console.log('载入 MiaoAuth 插件!'); -} - -function enable() { - command.on(this, 'l', { - cmd: function(sender, command, args) { - return true; - } - }); - command.on(this, 'r', { - cmd: function(sender, command, args) { - return true; - } - }); - console.log('启用 MiaoAuth 测试插件!'); - switch (DetectServerType) { - case ServerType.Bukkit: - event.on(this, 'playerloginevent', function join(event) { - send(wrapper.player(event.player)); - }); - break; - case ServerType.Sponge: - event.on(this, 'clientconnectionevent.join', function join(event) { - send(wrapper.player(event.targetEntity)); - }); - break; - } -} - -function send(player) { - setTimeout(function sendMessage() { - player.sendMessage('§a输入 /l <密码> 以登录!'); - }, 1000); -} - -function disable() { - console.log('卸载 MiaoAuth 测试插件!'); -} - -module.exports = { - description: description, - load: load, - enable: enable, - disable: disable -}; diff --git a/src/main/resources/dev-plugins/MiaoChat.js b/src/main/resources/dev-plugins/MiaoChat.js deleted file mode 100644 index 3048d87..0000000 --- a/src/main/resources/dev-plugins/MiaoChat.js +++ /dev/null @@ -1,261 +0,0 @@ -'use strict'; -/** - * MiaoChat 喵式聊天插件 - */ -/*global Java, base, module, exports, require*/ - -var event = require('api/event'); -var command = require('api/command'); - -var tellraw = require('tellraw'); -var papi = require('papi'); -var utils = require('utils'); - -var Player; - -var description = { - name: 'MiaoChat', - version: '1.0', - author: 'MiaoWoo', - commands: { - 'mchat': { - description: 'MiaoChat登录命令' - } - }, - permissions: { - 'MiaoChat.default': { - default: true, - description: '默认权限 赋予玩家' - }, - 'MiaoChat.admin': { - default: false, - description: '管理权限' - } - }, - config: { - Version: "1.8.5", - BungeeCord: true, - Server: "生存服", - ChatFormats: { - "default": { - "index": 50, - "permission": "MiaoChat.default", - "range": 0, - "format": "[world][player]&7: ", - "item": true, - "itemformat": "&6[&b%s&6]&r" - }, - "admin": { - "index": 49, - "permission": "MiaoChat.admin", - "format": "[admin][world][player][help]&7: ", - "range": 0, - "item": true, - "itemformat": "&6[&b%s&6]&r" - } - }, - StyleFormats: { - "world": { - "text": "&6[&a%player_world%&6]", - "hover": [ - "&6当前所在位置:", - "&6世界: &d%player_world%", - "&6坐标: &aX:%player_x% Y: %player_y% Z: %player_z%", - "", - "&c点击即可TP我!" - ], - "click": { - "type": "COMMAND", - "command": "/tpa %player_name%" - } - }, - "player": { - "text": "&b%player_name%", - "hover": [ - "&6玩家名称: &b%player_name%", - "&6玩家等级: &a%player_level%", - "&6玩家血量: &c%player_health%", - "&6玩家饥饿: &d%player_food_level%", - "&6游戏模式: &4%player_gamemode%", - "", - "&c点击与我聊天" - ], - "click": { - "type": "SUGGEST", - "command": "/tell %player_name%" - } - }, - "admin": { - "text": "&6[&c管理员&6]" - }, - "help": { - "text": "&4[求助]", - "hover": [ - "点击求助OP" - ], - "click": { - "type": "COMMAND", - "command": "管理员@%player_name% 我需要你的帮助!" - } - } - } - } -}; - -var chat_formats; -var style_formats; - -function load() { - chat_formats = Object.values(self.config.ChatFormats); - chat_formats.sort(utils.compare('index')); - initFormat(chat_formats); - style_formats = self.config.StyleFormats; -} - -// 用于匹配 '[xx]' 聊天格式 -var FORMAT_PATTERN = /[\[]([^\[\]]+)[\]]/ig; - -function initFormat(chat_formats) { - chat_formats.forEach(function(chat_format) { - var chat_format_str = chat_format.format; - var temp = []; - var r; - while (r = FORMAT_PATTERN.exec(chat_format_str)) { - temp.push(r[1]); - } - var format_list = []; - temp.forEach(function splitStyle(t) { - var arr = chat_format_str.split('[' + t + ']', 2); - if (arr[0]) { - format_list.push(arr[0]); - } - format_list.push(t); - chat_format_str = arr[1]; - }); - if (chat_format_str) { - format_list.push(chat_format_str); - } - chat_format.format_list = format_list; - }) -} - -function enable() { - registerCommand(); - registerEvent(); -} - -function registerCommand() { - command.on(self, 'mchat', { - cmd: mainCommand - }); -} - -// noinspection JSUnusedLocalSymbols -function mainCommand(sender, command, args) { - return true; -} - -function registerEvent() { - switch (DetectServerType) { - case ServerType.Bukkit: - event.on(self, 'AsyncPlayerChatEvent', handlerBukkitChat); - break; - case ServerType.Sponge: - Player = org.spongepowered.api.entity.living.player.Player; - event.on(self, 'MessageChannelEvent.Chat', handlerSpongeChat); - break; - } -} - -function handlerBukkitChat(event) { - sendChat(event.player, event.message, function() { - event.setCancelled(true); - }); -} - -function handlerSpongeChat(event) { - var player = event.getCause().first(Player.class).orElse(null); - if (player == null) { - return; - } - var plain = event.getRawMessage().toPlain(); - if (plain.startsWith(tellraw.duplicateChar)) { - return; - } - sendChat(player, plain, function() { - event.setMessageCancelled(true) - }); -} - -function sendChat(player, plain, callback) { - var chat_format = getChatFormat(player); - if (!chat_format) { - console.debug('未获得用户', player.name, '的 ChatRule 跳过执行...'); - return; - } - callback(); - var tr = tellraw.create(); - chat_format.format_list.forEach(function setStyle(format) { - var style = style_formats[format]; - if (style) { - tr.then(replace(player, style.text)); - if (style.hover) { - tr.tip(replace(player, style.hover)); - } - if (style.click && style.click.type && style.click.command) { - var command = replace(player, style.click.command); - switch (style.click.type) { - case "COMMAND": - tr.command(command); - break; - case "OPENURL": - tr.link(command); - break; - case "SUGGEST": - tr.suggest(command); - break; - default: - } - } - } else { - tr.then(replace(player, format)); - } - }); - tr.then(replace(player, plain)).sendAll(); -} - -function getChatFormat(player) { - for (var i in chat_formats) { - var format = chat_formats[i]; - if (player.hasPermission(format.permission)) { - return format; - } - } - return null; -} - -function replace(player, target) { - if (toString.call(target) === "[object Array]") { - for (var i in target) { - target[i] = replaceStr(player, target[i]); - } - } else { - target = replaceStr(player, target); - } - return target; -} - -function replaceStr(player, target) { - return papi.$(player, target); -} - -function disable() { - console.log('卸载', description.name, '插件!'); -} - -module.exports = { - description: description, - load: load, - enable: enable, - disable: disable -}; diff --git a/src/main/resources/dev-plugins/bukkit/Lottery.js b/src/main/resources/dev-plugins/bukkit/Lottery.js deleted file mode 100644 index 5d2e150..0000000 --- a/src/main/resources/dev-plugins/bukkit/Lottery.js +++ /dev/null @@ -1,231 +0,0 @@ -'use strict'; -/** - * Hello Wrold 测试插件 - */ -/*global Java, base, module, exports, require*/ - -var event = require('api/event'); -var command = require('api/command'); -var bukkit = require('api/server'); -var item = require('api/item'); - -var Arrays = Java.type('java.util.Arrays'); -var ItemStackArray = Java.type('org.bukkit.inventory.ItemStack[]'); - -var PANE = 'STAINED_GLASS_PANE' - -var description = { - name: 'Lottery', - version: '1.0', - author: 'MiaoWoo', - commands: { - 'lottery': { - description: 'Lottery主命令' - } - }, - config: { - title: '§m§s§a幸运抽奖', - control: { - panel: PANE + ':13', - ok: PANE + ':14', - no: PANE + ':15', - }, - list: [ - { - box: { - id: PANE, - damage: 1, - name: '§a箱子', - lore: [ - '这是箱子的Lore' - ] - }, - key: { - id: PANE, - damage: 2, - name: '§b钥匙', - lore: [ - '这是钥匙的Lore' - ] - }, - result: [ - { - percent: 10, - command: 'money give %player% 100', - item: { - id: PANE, - damage: 3, - name: '§c奖品1', - lore: [ - '这是奖品1的Lore' - ] - } - }, - { - percent: 20, - command: 'money give %player% 200', - item: { - id: PANE, - damage: 4, - name: '§c奖品2', - lore: [ - '这是奖品2的Lore' - ] - } - } - ] - } - ] - } -}; - -var panel; -var config; -var items; - -function load() { - config = this.config; - panel = newItemFromString(config.control.panel || PANE + ':13') - items = new ItemStackArray(54); - item.setName(panel, ''); - var ok = newItemFromString(config.control.ok || PANE + ':14') - item.setName(ok, '§a确定抽奖'); - var no = newItemFromString(config.control.no || PANE + ':15') - item.setName(no, '§c取消抽奖'); - Arrays.fill(items, 0, 10, panel); - Arrays.fill(items, 11, 16, panel); - Arrays.fill(items, 17, 29, panel); - items[29] = no; - Arrays.fill(items, 30, 33, panel); - items[33] = ok; - Arrays.fill(items, 34, 40, panel); - Arrays.fill(items, 41, 54, panel); -} - -function isTargetItem(item, config) { - return item.typeId === config.id && - item.itemMeta && - item.itemMeta.displayName === config.name && - item.itemMeta.lore && Java.from(item.itemMeta.lore).toJson() === config.lore.toJson() -} - -function newItem(name, sub) { - return item.create(name, 1, sub || 0); -} - -function newItemFromString(str) { - var arr = str.split(':'); - if (arr.length === 2) { - return newItem(arr[0], arr[1]); - } else { - return newItem(arr[0]); - } -} - -function newItemFromConfig(config) { - var i = newItem(config.id, config.damage); - if (config.name) item.setName(i, config.name); - if (config.lore) item.setLore(i, config.lore); - return i; -} - -function enable() { - // noinspection JSUnusedLocalSymbols - command.on(this, 'l', { - cmd: function(sender, command, args) { - sender.inventory.addItem(newItemFromConfig(config.list[0].box)) - sender.inventory.addItem(newItemFromConfig(config.list[0].key)) - if (!sender.openInventory) { - console.sender(sender, "§4当前用户无法使用该命令!"); - } - var inv = MServer.createInventory(null, 54, config.title); - inv.setContents(items); - sender.openInventory(inv); - return true; - } - }); - event.on(this, 'InventoryClick', function click(event) { - var inv = event.inventory; - if (inv && inv.title !== config.title) return; - var player = event.whoClicked; - var slot = event.rawSlot; - if (slot > 53 || slot < 0) { - return; - } - event.cancelled = true; - switch (slot) { - case 10: - case 16: - case 40: - event.cancelled = false; - break; - case 29: - // TODO 关闭界面 - player.closeInventory(); - break; - case 33: - var temp = inv.getItem(40); - if (temp && temp.typeId !== 0) { - console.sender(player, '§c请先取走奖品!'); - return; - } - var litem; - var box = inv.getItem(10); - if (!box) { - console.sender(player, '§c请先放入抽奖物品和钥匙!'); - return; - } - var key = inv.getItem(16); - if (box && box.typeId !== 0 && key && key.typeId !== 0) { - for (var i = 0; i < config.list.length; i++) { - var r = config.list[i]; - if (isTargetItem(box, r.box)) { - litem = r; - break; - } - } - } - // TODO 抽奖 - if (!litem) { - console.sender(player, '§c请先放入抽奖物品和钥匙!'); - return; - } - if (!isTargetItem(key, litem.key)) { - console.sender(player, '§c抽奖物品和钥匙不匹配!'); - return; - } - var resultList = []; - litem.result.forEach(function(t) { - for (var i = 0; i < t.percent; i++) { - resultList.push(t); - } - }); - var ri = random(resultList.length); - var result = resultList[ri]; - box.amount = box.amount - 1; - key.amount = key.amount - 1; - inv.setItem(10, box); - inv.setItem(16, key); - inv.setItem(40, newItemFromConfig(result.item)); - bukkit.console(result.command.replace('%player%', player.name)); - break; - default: - event.cancelled = true; - } - }); -} - -function random(max, min) { - min = min === undefined ? 0 : min; - return Math.floor(Math.random() * (max - min) + min); -}; - -function disable() { -} - -module.exports = { - description: description, - load: load, - enable: enable, - disable: disable -}; \ No newline at end of file diff --git a/src/main/resources/dev-plugins/bukkit/MiaoTag.js b/src/main/resources/dev-plugins/bukkit/MiaoTag.js deleted file mode 100644 index a1a79c6..0000000 --- a/src/main/resources/dev-plugins/bukkit/MiaoTag.js +++ /dev/null @@ -1,188 +0,0 @@ -'use strict'; -/** - * MiaoTag - * 可兼容任何记分板 - */ -/*global Java, base, module, exports, require*/ -var event = require('api/event'); -var bukkit = require('api/server'); -var command = require('api/command'); - -var fakeTag; - -var description = { - name: 'MiaoTag', - version: '1.1', - author: 'MiaoWoo', - config: { - format: '§4§l❤' - }, - commands: { - 'mtag': { - description: 'MiaoTag主命令', - usage: '', - permission: 'MiaoTag.admin' - } - }, - permissions: { - 'MiaoTag.default': { - default: true, - description: '默认权限 赋予玩家' - }, - 'MiaoTag.admin': { - default: false, - description: '管理权限' - } - } -}; - -var config; - -function load() { - config = self.getConfig(); -} - -function enable() { - registryCommand() - fakeTag = new FakeTag(config.format); - registryEvent() -} - -function registryCommand() { - command.on(self, 'mtag', { - cmd: function cmd(sender, command, args) { - var subCommand = args[0]; - switch (subCommand) { - case 'reload': - self.reloadConfig(); - fakeTag = new FakeTag(config.format); - console.sender(sender, "§a配置文件重载完成!"); - break; - } - }, - tab: function tab(sender, command, args) { - return ['reload']; - } - }); -} - -function registryEvent() { - bukkit.players(function(p) { fakeTag.set(p) }); - event.on(self, 'PlayerJoin', function(event) { fakeTag.set(event.player) }); - event.on(self, 'EntityRegainHealth', entityUpdate, false); - event.on(self, 'EntityDamage', entityUpdate, false); - event.on(self, 'EntityRegainHealth', entityUpdate, false); - event.on(self, 'PlayerRespawn', entityUpdate, false); -} - -function entityUpdate(event) { - var player = event.entity || event.player; - if (player instanceof org.bukkit.entity.Player) { - setTimeout(function() { - fakeTag.update(player); - }, 1); - } -}; - -function disable() { - if (fakeTag) { fakeTag.disable() }; -} - -function FakeTag(name) { - var ver1_13 = false; - // NMS CLASS - try { - var ScoreboardBaseCriteria = bukkit.nmsCls('ScoreboardBaseCriteria'); - } catch (ex) { - try { - var IScoreboardCriteria = bukkit.nmsCls('IScoreboardCriteria'); - var ScoreboardServer = bukkit.nmsCls("ScoreboardServer"); - var ChatComponentText = bukkit.nmsCls('ChatComponentText'); - ver1_13 = true; - } catch (ex) { - console.log(ex); - throw ex; - } - } - var PacketPlayOutScoreboardScore = bukkit.nmsCls('PacketPlayOutScoreboardScore'); - var PacketPlayOutScoreboardObjective = bukkit.nmsCls('PacketPlayOutScoreboardObjective'); - var PacketPlayOutScoreboardDisplayObjective = bukkit.nmsCls('PacketPlayOutScoreboardDisplayObjective'); - - var scoreboardManager = bukkit.$.scoreboardManager; - var mainScoreboard = scoreboardManager.mainScoreboard.handle; - - // 注销对象 - var objective = mainScoreboard.getObjective(name); - if (objective) { - mainScoreboard.unregisterObjective(objective); - } - - try { - if (!ver1_13) { - // 注册tag对象 - objective = mainScoreboard.registerObjective(name, new ScoreboardBaseCriteria(name)); - } else { - // 注册tag对象 - objective = mainScoreboard.registerObjective(name, - IScoreboardCriteria.HEALTH, - new ChatComponentText(name), - IScoreboardCriteria.EnumScoreboardHealthDisplay.HEARTS); - } - } catch (ex) { - throw ex - // ignore 忽略创建错误 eg: java.lang.IllegalArgumentException: An objective with the name 'xxxxx' already exists! - } - - if (!objective) { - throw Error("Error Can't Found MainScoreboard Objective " + name) - } - - // 缓存虚拟的tag包 - var cache = { - objective: new PacketPlayOutScoreboardObjective(objective, 0), - display: new PacketPlayOutScoreboardDisplayObjective(2, objective) - }; - - function sendPacket(player, p) { - player.handle.playerConnection.sendPacket(p); - } - - this.set = function(player) { - sendPacket(player, cache.objective); - sendPacket(player, cache.display); - this.update(player); - }; - - function createScore(player) { - if (!ver1_13) { - var score = mainScoreboard.getPlayerScoreForObjective(player.name, objective); - score.setScore(player.health); - return new PacketPlayOutScoreboardScore(score); - } else { - return new PacketPlayOutScoreboardScore(ScoreboardServer.Action.CHANGE, name, player.name, player.health) - } - } - - this.update = function update(player) { - var scorePack = createScore(player); - //把其他玩家缓存的包发给这个玩家 - bukkit.players(function(t) { - sendPacket(t, scorePack); - if (t.name !== player.name) { - sendPacket(player, createScore(t)); - } - }); - }; - - this.disable = function() { - // 注销tag对象 - mainScoreboard.unregisterObjective(objective); - } -} - -module.exports = { - description: description, - load: load, - enable: enable, - disable: disable -}; \ No newline at end of file diff --git a/src/main/resources/dev-plugins/bukkit/WorldEdit.js b/src/main/resources/dev-plugins/bukkit/WorldEdit.js deleted file mode 100644 index 3983239..0000000 --- a/src/main/resources/dev-plugins/bukkit/WorldEdit.js +++ /dev/null @@ -1,48 +0,0 @@ -'use strict'; -/** - * WorldEdit 插件 - */ -/*global Java, base, module, exports, require*/ -var item = require('/api/item'); -var command = require('api/command'); -var Material = Java.type("org.bukkit.Material"); - -var description = { - name: 'WorldEdit', - version: '1.0', - author: 'MiaoWoo', - commands: { - '/up': { - description: 'Up Player And Set Block' - } - } -}; - -function load() { -} - -function enable() { - command.on(this, '/up', { - cmd: function(sender, command, args) { - if (!sender.openInventory) { - return; - } - var player = sender; - var location = player.location; - var type = item.type(args[0], 'STONE'); - player.velocity = player.velocity.setY(0.5); - setTimeout(function() { - location.block.type = type - }, 6); - return true; - }, - tab: function(sender, command, args) { - - } - }); -} - -module.exports = { - description: description, - enable: enable -}; diff --git a/src/main/resources/dev-plugins/markdown/MiaoChat.md b/src/main/resources/dev-plugins/markdown/MiaoChat.md deleted file mode 100644 index 66656cd..0000000 --- a/src/main/resources/dev-plugins/markdown/MiaoChat.md +++ /dev/null @@ -1,32 +0,0 @@ -## MiaoChat for MiaoScript - -![](https://dn-coding-net-production-pp.qbox.me/f459067b-7829-45ec-9713-bb559d1e0118.png) - -> 注意: MiaoScript 在Windows环境下 暂不支持 reload 所以 Windows 环境请重启服务器 -> 注意: MiaoScript 将不会计划兼容 非 `Sponge` 的MOD端 - -- 基于 `MiaoScript` 开发 同时兼容 `Sponge` 和 `Bukkit` -- 支持PAPI - - `Bukkit` 为 `me.clip.placeholderapi.PlaceholderAPI` - - `Sponge` 为 `me.rojo8399.placeholderapi.PlaceholderService` -- 支持悬浮提示 -- 支持点击执行命令 -- 支持点击命令补全 - -### Feature(开发规划) -- 悬浮物品提示 -- 兼容 `BungeeCord` 支持跨服聊天 -- 兼容其他聊天插件 保护插件 - -### 安装教程 -- 下载 MiaoChat 本体并安装 - - [下载地址-论坛](http://www.mcbbs.net/thread-774401-1-1.html) - - [下载地址-备用](https://git.yumc.pw/502647092/MiaoScript/releases) -- 安装到服务端对应的目录 - - Bukkit => plugins - - Sponge => mods -- 重启服务器 -- 下载 安装 `MiaoScriptPackageManager` - - [安装教程](http://www.mcbbs.net/thread-774797-1-1.html) -- 使用 `MiaoScriptPackageManager` 安装插件 - - 执行 `mpm install MiaoChat` 即可安装成功 \ No newline at end of file diff --git a/src/main/resources/dev-plugins/sponge/MiaoBoard.js b/src/main/resources/dev-plugins/sponge/MiaoBoard.js deleted file mode 100644 index d07fb47..0000000 --- a/src/main/resources/dev-plugins/sponge/MiaoBoard.js +++ /dev/null @@ -1,220 +0,0 @@ -'use strict'; -/** - * MiaoBoard 喵式聊天插件 - */ -/*global Java, base, module, exports, require*/ -var task = require('api/task'); -var event = require('api/event'); -var server = require('api/server'); -var command = require('api/command'); - -var papi = require('papi'); - -var Player; - -var boards = []; - -var description = { - name: 'MiaoBoard', - version: '1.0', - author: 'MiaoWoo', - commands: { - 'mboard': { - description: '喵式记分板主命令' - } - }, - permissions: { - 'mb.default': { - default: true, - description: '默认权限 赋予玩家' - }, - 'mb.admin': { - default: false, - description: '管理权限' - } - }, - config: { - "Version": 2, - "UpdateTime": 10, - "DisableWorld": [ - "WorldName" - ], - "Boards": { - "default": { - "index": 50, - "time": { - "start": "2016-01-01 00:00:00", - "end": "2020-01-01 00:00:00" - }, - "title": "玩家信息", - "permission": "mb.default", - "lines": [ - "&6名 称: &a%player_displayname%", - "&6世 界: &b%player_world%", - "&6位 置: &3%player_x%,%player_y%,%player_z%", - "&6等 级: &e%player_level%", - "&6血 量: &c%player_health%", - "&6模 式: &4%player_gamemode%" - ] - }, - "admin": { - "index": 49, - "title": "服务器信息", - "permission": "mb.reload", - "lines": [ - "&6名 称: &aMiaoBoard", - "&6版 本: &b1.0.0", - "&6作 者: &cMiaoWoo", - "&6人 数: &c%server_online%/%server_max%", - "&6内 存: &a%server_ram_used%/%server_ram_total%/%server_ram_max%" - ] - } - } - } -} - -var update_task; -var board_formats; - -function load() { - board_formats = self.config.Boards; -} - -function enable() { - registerCommand(); - registerEvent(); - registerTask(); - updatePlayers() -} - -function registerCommand() { - command.on(self, 'mboard', { - cmd: mainCommand - }); -} - -function mainCommand(sender, command, args) { - if (!args[0]) { - return; - } - switch (args[0]) { - case "reload": - self.reloadConfig(); - load(); - break; - } -} - -function registerEvent() { - switch (DetectServerType) { - case ServerType.Bukkit: - //event.on(self, 'PlayerLoginEvent', handlerPlayerJoin); - break; - case ServerType.Sponge: - Player = org.spongepowered.api.entity.living.player.Player; - event.on(self, 'ClientConnectionEvent.Join', handlerPlayerJoin); - event.on(self, 'ClientConnectionEvent.Disconnect', handlerPlayerQuit); - break; - } -} - -function updatePlayers() { - switch (DetectServerType) { - case ServerType.Bukkit: - //event.on(self, 'PlayerLoginEvent', handlerPlayerJoin); - break; - case ServerType.Sponge: - server.players(function(player) { - boards[player.name] = new MiaoBoard(player); - }) - break; - } -} - -function handlerPlayerJoin(event) { - var player = event.player || event.targetEntity; - boards[player.name] = new MiaoBoard(player); -} - -function handlerPlayerQuit(event) { - var player = event.player || event.targetEntity; - delete boards[player.name]; -} - -function registerTask() { - update_task = task.timerAsync(updateBoard, self.config.UpdateTime); -} - -function updateBoard() { - for (var i in boards) { - var player = server.player(i); - if (player.isOnline()) { - var format = getBoardFormat(player); - if (format) { - boards[i].update(papi.$(player, format.title), papi.$(player, format.lines)); - } else { - boards[i].clear(); - } - } else { - delete boards[i]; - } - } -} - -function getBoardFormat(player) { - for (var i in board_formats) { - var format = board_formats[i]; - if (player.hasPermission(format.permission)) { - return format; - } - } - return null; -} - -function disable() { - if (update_task) { update_task.cancel(); } -} - -function MiaoBoard(player) { - var Scoreboard = Java.type('org.spongepowered.api.scoreboard.Scoreboard'); - var Objective = Java.type('org.spongepowered.api.scoreboard.objective.Objective'); - var Criteria = Java.type('org.spongepowered.api.scoreboard.critieria.Criteria'); - var Text = Java.type('org.spongepowered.api.text.Text'); - var DisplaySlots = Java.type('org.spongepowered.api.scoreboard.displayslot.DisplaySlots'); - - var uuid = player.uniqueId; - var scoreboard = Scoreboard.builder().build(); - var sidebar = Objective.builder().criterion(Criteria.DUMMY).displayName(Text.EMPTY).name("Sidebar").build(); - - var origin = []; - - scoreboard.addObjective(sidebar); - player.setScoreboard(scoreboard); - - this.update = function(title, lines) { - this.updateBuffer(title, lines); - } - - this.updateBuffer = function(title, lines) { - sidebar.scores.values().forEach(function removeScore(score) { - sidebar.removeScore(score); - }) - var i = 0; - sidebar.setDisplayName(Text.of(title)); - lines.forEach(function addScore(line) { - sidebar.getOrCreateScore(Text.of(line)).setScore(lines.length - i++); - }) - scoreboard.updateDisplaySlot(sidebar, DisplaySlots.SIDEBAR); - } - - this.clear = function() { - player.setScoreboard(Scoreboard.builder().build()); - } -} - -module.exports = { - description: description, - load: load, - enable: enable, - disable: disable -};