Compare commits
87 Commits
1.3.0.bate
...
dev
Author | SHA1 | Date | |
---|---|---|---|
ebf218e534 | |||
fd5c2aa087 | |||
ea8e62b696 | |||
367b732f7c | |||
9bcd4cd748 | |||
2ed9614bc4 | |||
00287ff80a | |||
2a891c1117 | |||
46925f9b52 | |||
57926ba788 | |||
8933afeb71 | |||
0b0cea9e50 | |||
1c21792572 | |||
31351fc393 | |||
c859605738 | |||
388e1e9135 | |||
996a63ba2d | |||
548c76f154 | |||
8be38800b0 | |||
0dfe04040e | |||
7dad0e7abc | |||
96639d0978 | |||
0df2d2b71f | |||
de18b0f628 | |||
bbf08816ba | |||
160e7f4118 | |||
2d4bc3dd24 | |||
c5b7a45605 | |||
4653bbc091 | |||
565419a292 | |||
a28386401c | |||
a78e6482e8 | |||
03129b8797 | |||
c2d0c05bcf | |||
b611da5e27 | |||
93d7389047 | |||
a875a6ca8e | |||
135d0f2b90 | |||
8cf8dccbe4 | |||
478bff9599 | |||
2013b3b07c | |||
2dff086a01 | |||
8d5902600f | |||
e455cbf996 | |||
8d40a69ac7 | |||
f98814bf2d | |||
72ae1b4b29 | |||
ee4072526b | |||
2cd6e019c6 | |||
6766c3b0ce | |||
150c18957c | |||
bdc0a62e36 | |||
ccdbd8b683 | |||
c2c17a46d4 | |||
997820d117 | |||
d67f2843b0 | |||
7822803376 | |||
ee496c5bda | |||
324fbee2e5 | |||
c955670658 | |||
33fecc7372 | |||
b33826bbe9 | |||
8e2e2bca82 | |||
5ea78a60e5 | |||
c873031cc2 | |||
9504ec8b12 | |||
abdfbce125 | |||
e6af7b1828 | |||
8f5bae006a | |||
f94fa71f36 | |||
fcc1f18336 | |||
823ff1c70b | |||
2360dd9b0e | |||
f94653249d | |||
c095593c41 | |||
202dc9f00c | |||
88d71abb2a | |||
967e7d1beb | |||
e97de1f8d0 | |||
bc6e07cfc8 | |||
4dec6bca98 | |||
f8ec9b9f6e | |||
1735417887 | |||
9819a82265 | |||
d2ebd8fa7e | |||
0492275eb2 | |||
3fe1feccff |
4
.gitignore
vendored
4
.gitignore
vendored
@ -38,6 +38,7 @@
|
||||
# Eclipse
|
||||
.project
|
||||
.classpath
|
||||
.factorypath
|
||||
.settings
|
||||
|
||||
# Visual Studio Code
|
||||
@ -50,4 +51,5 @@
|
||||
vendor/
|
||||
|
||||
# Minecraft Data
|
||||
/world
|
||||
/world
|
||||
**/node_modules/
|
||||
|
@ -11,7 +11,7 @@
|
||||
- 诞生于 `2016年08月25日` 这是 Git 上的第一个提交 具体啥时候我也忘了
|
||||
- 起初 `MiaoScript` 只是用于服务器其他插件的变量执行 并且依赖于PAPI(不知道是啥的自己百度)
|
||||
- 比如 [`MiaoMenu`](http://w.yumc.pw/zc/MiaoMenu.html) 的部分复杂脚本
|
||||
- 比如 [`MiaoChat`](http://mcbbs.tvt.im/thread-631240-1-1.html) 的聊天变量
|
||||
- 比如 [`MiaoChat`](http://mcbbs.net/thread-631240-1-1.html) 的聊天变量
|
||||
- 突然有一天 圈内的大佬 `QSB` @qiu1995 过来找我 说能不能用脚本监听玩家的事件
|
||||
- PS: 这货自从用过 `DeluxeMenu` 之后就喜欢上了用JS写菜单
|
||||
- 当初感觉没啥问题 就出了第一个简易的 `MiaoScript` 版本 还是用 yml 做的配置文件
|
||||
|
105
obf.dict
105
obf.dict
@ -1,105 +0,0 @@
|
||||
™
|
||||
▄
|
||||
▒
|
||||
░
|
||||
▓
|
||||
™™
|
||||
▄™
|
||||
▒™
|
||||
░™
|
||||
▓™
|
||||
™▄
|
||||
▄▄
|
||||
▒▄
|
||||
░▄
|
||||
▓▄
|
||||
™▒
|
||||
▄▒
|
||||
▒▒
|
||||
░▒
|
||||
▓▒
|
||||
™░
|
||||
▄░
|
||||
▒░
|
||||
░░
|
||||
▓░
|
||||
™▓
|
||||
▄▓
|
||||
▒▓
|
||||
░▓
|
||||
▓▓
|
||||
™
|
||||
™▄
|
||||
™▒
|
||||
™░
|
||||
™▓
|
||||
▄™
|
||||
▄▄
|
||||
▄▒
|
||||
▄░
|
||||
▄▓
|
||||
▒™
|
||||
▒▄
|
||||
▒
|
||||
▒░
|
||||
▒▓
|
||||
░™
|
||||
░▄
|
||||
░▒
|
||||
░
|
||||
░▓
|
||||
▓™
|
||||
▓▄
|
||||
▓▒
|
||||
▓░
|
||||
▓
|
||||
™™™
|
||||
▄™▄
|
||||
▒™▒
|
||||
░™░
|
||||
▓™▓
|
||||
™▄™
|
||||
▄▄▄
|
||||
▒▄▒
|
||||
░▄░
|
||||
▓▄▓
|
||||
™▒™
|
||||
▄▒▄
|
||||
▒▒▒
|
||||
░▒░
|
||||
▓▒▓
|
||||
™░™
|
||||
▄░▄
|
||||
▒░▒
|
||||
░░░
|
||||
▓░▓
|
||||
™▓™
|
||||
▄▓▄
|
||||
▒▓▒
|
||||
░▓░
|
||||
▓▓▓
|
||||
™ ™
|
||||
™▄™
|
||||
™▒™
|
||||
™░™
|
||||
™▓™
|
||||
▄™▄
|
||||
▄ ▄
|
||||
▄▒▄
|
||||
▄░▄
|
||||
▄▓▄
|
||||
▒™▒
|
||||
▒▄▒
|
||||
▒ ▒
|
||||
▒░▒
|
||||
▒▓▒
|
||||
░™░
|
||||
░▄░
|
||||
░▒░
|
||||
░ ░
|
||||
░▓░
|
||||
▓™▓
|
||||
▓▄▓
|
||||
▓▒▓
|
||||
▓░▓
|
||||
▓ ▓
|
171
pom.xml
171
pom.xml
@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>pw.yumc</groupId>
|
||||
<artifactId>MiaoScript</artifactId>
|
||||
<version>1.2.1</version>
|
||||
<version>0.3.1</version>
|
||||
<developers>
|
||||
<developer>
|
||||
<id>502647092</id>
|
||||
@ -18,7 +18,7 @@
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<excludes>
|
||||
<exclude>plugins/**.js</exclude>
|
||||
<exclude>dev-plugins/**</exclude>
|
||||
</excludes>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
@ -27,51 +27,21 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>2.4.3</version>
|
||||
<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>
|
||||
<configuration>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
<minimizeJar>true</minimizeJar>
|
||||
<artifactSet>
|
||||
<includes>
|
||||
<include>pw.yumc:YumCore</include>
|
||||
</includes>
|
||||
</artifactSet>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>pw.yumc.YumCore</pattern>
|
||||
<shadedPattern>${project.groupId}.${project.artifactId}</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.github.wvengen</groupId>
|
||||
<artifactId>proguard-maven-plugin</artifactId>
|
||||
<version>2.0.13</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>proguard</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<options>
|
||||
<option>-repackageclasses \ʼ.ʽ.ʾ.${project.artifactId}</option>
|
||||
<option>-keep class ${project.groupId}.${project.artifactId}.${project.artifactId}</option>
|
||||
<option>-keep class ${project.groupId}.${project.artifactId}.${project.artifactId}Bungee</option>
|
||||
</options>
|
||||
<libs>
|
||||
<lib>${java.home}/lib/rt.jar</lib>
|
||||
</libs>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
@ -79,16 +49,85 @@
|
||||
</build>
|
||||
<ciManagement>
|
||||
<system>Jenkins</system>
|
||||
<url>http://ci.yumc.pw/job/${project.artifactId}/</url>
|
||||
<url>https://ci.yumc.pw/job/Minecraft/job/${project.artifactId}/</url>
|
||||
</ciManagement>
|
||||
<properties>
|
||||
<env.GIT_COMMIT>DEV</env.GIT_COMMIT>
|
||||
<update.changes>
|
||||
§618-01-09 §afeat: 优化加载流程 完善事件注册
|
||||
§618-01-02 §afeat: 新增http网络访问模块
|
||||
§617-12-28 §afeat: 完善Sponge事件注册 新增player封装类
|
||||
§620-03-03 §afeat: require 新增 淘宝镜像源拉取;
|
||||
§620-02-27 §afeat: 异步加载脚本引擎;
|
||||
§620-02-25 §afeat: 新增 Nukkit 的支持;
|
||||
§620-02-16 §afeat: 新增 Source Map 支持;
|
||||
§620-02-02 §afeat: 迁移 ployfill 到 @ms/ployfill;
|
||||
§620-01-14 §afeat: 新增 Bungee 支持;
|
||||
§afeat: 新增 instance 实例获取
|
||||
</update.changes>
|
||||
<update.changelog>
|
||||
§619-09-24 §cremove: 移除 okhttp3 类库;
|
||||
§afeat: 新增require自动下载模块功能;
|
||||
§619-09-21 §afeat: 新增 okhttp3 类库;
|
||||
§619-08-31 §afeat: 新增 tar 类库 支持 tar.gz 解压;
|
||||
§619-08-29 §erefactor: 移动插件文件 默认自带MSPM插件 优化bios;
|
||||
§618-5-20 §afeat: 新增MiaoBoard插件;
|
||||
§618-5-20 §afeat: 新增MiaoAuth插件;
|
||||
§618-5-20 §afeat: 修改初始化函数名称;
|
||||
§618-5-20 §cfix: file.js修复一个语法错误;
|
||||
§618-5-20 §afeat: 新增config默认值绑定 匿名函数添加名称;
|
||||
§618-5-20 §afeat: PAPI支持直接替换数组;
|
||||
§618-5-20 §afeat: 调整Task任务模块;
|
||||
§618-5-20 §afeat: 新增模板预编译插件功能;
|
||||
§618-5-18 §afeat: 清除不必要的代码;
|
||||
§618-5-17 §afeat: 新增MiaoChat插件描述;
|
||||
§618-5-17 §afeat: MiaoScriptPackageManager 新增restart和run方法;
|
||||
§618-5-17 §cfix: 修复Sponge命令参数存在空字符串的问题;
|
||||
§618-5-17 §cfix: 修复混淆导致的重载方法丢失;
|
||||
§618-5-17 §afeat: 新增引擎Shutdown方法 关闭资源;
|
||||
§618-5-17 §afeat: 格式化代码 添加d.ts文件 去除引擎无关代码 清理单元测试;
|
||||
§618-5-17 §cfix: 修复TellRaw类库错误;
|
||||
§618-5-17 §cfix: 修复pkg不存在的问题;
|
||||
§618-5-17 §cfix: 修复下载错误的问题;
|
||||
§618-5-17 §afeat: 更新版本号;
|
||||
§618-05-17 §afeat: 新增Hook提示;
|
||||
§618-05-17 §afeat: 调整列表载入顺序;
|
||||
§618-05-17 §afeat: 完善MiaoChat的PAPI的替换;
|
||||
§618-05-17 §afeat: 完善服务获取类;
|
||||
§618-05-17 §afeat: 新增PAPI代理类;
|
||||
§618-05-17 §afeat: 去除调试代码;
|
||||
§618-05-17 §afeat: 迁移配置 完善reload命令;
|
||||
§618-05-15 §afeat: 分离TellRaw类库;
|
||||
§618-05-15 §afeat: 完善MiaoChat的Bukkit版本;
|
||||
§618-05-15 §afeat: 补全内部引入方法的参数;
|
||||
§618-05-15 §afeat: 调整Event载入提示 完善Bukkit的聊天发送;
|
||||
§618-05-15 §afeat: 调整API引入结构;
|
||||
§618-05-15 §afeat: 新增MiaoChat插件;
|
||||
§618-05-14 §afeat: 更新API相关类;
|
||||
§618-05-14 §afeat: 调整相关API名称;
|
||||
§618-05-14 §afeat: 新增Object.values垫片;
|
||||
§618-05-14 §afeat: 新增工具类;
|
||||
§618-05-14 §afeat: 更新MiaoScriptPackageManager;
|
||||
§618-05-14 §cfix: 修复命令执行相关BUG;
|
||||
§618-05-14 §afeat: 新增聊天相关API;
|
||||
§618-05-14 §afeat: 优化方法调用;
|
||||
§618-03-18 §afeat: 调整get方法 data 参数自动转query;
|
||||
§618-03-18 §afeat: 优化插件代码结构;
|
||||
§618-03-18 §cfix: 修复玩家人数获取错误 更新插件;
|
||||
§618-01-11 §afeat: 更新http类库 server通过orElse返回undefined;
|
||||
§618-01-11 §afeat: 更新基础类库;
|
||||
§618-01-11 §afeat: 新增插件管理模块;
|
||||
§618-01-10 §cfix: 修复主线程加载的BUG;
|
||||
§618-01-10 §afeat: 修复fs相关BUG 优化插件加载 优化命令补全;
|
||||
§618-01-10 §afeat: 更新.gitignore文件;
|
||||
§618-01-10 §afeat: 新增案例插件 更新插件版本;
|
||||
§618-01-09 §afeat: 优化API 修复http模块错误;
|
||||
§618-01-09 §afeat: 更新 fs 类库 优化 require;
|
||||
§618-01-09 §afeat: 安全起见暂时屏蔽load方法和disable方法;
|
||||
§618-01-09 §cfix: 修复调试信息错误;
|
||||
§618-01-08 §afeat: require新增基础目录api;
|
||||
§618-01-08 §3doc: 新增README;
|
||||
§618-01-08 §cfix: 修复重载命令无效的BUG;
|
||||
§618-01-09 §afeat: 优化加载流程 完善事件注册;
|
||||
§618-01-02 §afeat: 新增http网络访问模块;
|
||||
§617-12-28 §afeat: 完善Sponge事件注册 新增player封装类;
|
||||
§617-11-30 §afeat: 新增Sponge的兼容;
|
||||
§617-11-03 §afeat: 新增抽奖插件;
|
||||
§617-10-16 §cfix: 修复关闭MiaoScript时task异常;
|
||||
@ -97,11 +136,12 @@
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<repo.url>https://repo.yumc.pw</repo.url>
|
||||
</properties>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>yumc-repo</id>
|
||||
<url>http://repo.yumc.pw/content/groups/public/</url>
|
||||
<url>${repo.url}/repository/maven-public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>sponge</id>
|
||||
@ -111,33 +151,46 @@
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>yumc-repo</id>
|
||||
<url>http://repo.yumc.pw/content/groups/public/</url>
|
||||
<url>${repo.url}/repository/maven-public/</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>jtb</id>
|
||||
<name>YUMC</name>
|
||||
<url>http://repo.yumc.pw/content/repositories/yumcenter/</url>
|
||||
<url>${repo.url}/repository/yumcenter/</url>
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>pw.yumc</groupId>
|
||||
<artifactId>YumCore</artifactId>
|
||||
<type>jar</type>
|
||||
<version>[1.8,)</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>craftbukkit</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.kamranzafar</groupId>
|
||||
<artifactId>jtar</artifactId>
|
||||
<version>2.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.14.4-R0.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.spongepowered</groupId>
|
||||
<artifactId>spongeapi</artifactId>
|
||||
<version>6.0.0</version>
|
||||
<version>7.1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-api</artifactId>
|
||||
<version>1.12-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.nukkit</groupId>
|
||||
<artifactId>nukkit</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -1,61 +0,0 @@
|
||||
# -----不优化-----
|
||||
-dontoptimize
|
||||
|
||||
# -----忽略所有警告-----
|
||||
-dontwarn
|
||||
-dontnote
|
||||
|
||||
# -----混淆时应用侵入式重载-----
|
||||
-overloadaggressively
|
||||
|
||||
# -----启用混淆字典-----
|
||||
-obfuscationdictionary obf.dict
|
||||
-classobfuscationdictionary obf.dict
|
||||
-packageobfuscationdictionary obf.dict
|
||||
|
||||
# -----保留所有属性
|
||||
-keepattributes **
|
||||
|
||||
# -----保护所有实体中的字段名称-----
|
||||
-keepclassmembers class * implements java.io.Serializable { <fields>; }
|
||||
|
||||
# -----保护监听方法不被清理-----
|
||||
-keepclassmembers class * implements org.bukkit.event.Listener {
|
||||
@org.bukkit.event.EventHandler <methods>;
|
||||
}
|
||||
-keepclassmembers class * implements net.md_5.bungee.api.plugin.Listener {
|
||||
@net.md_5.bungee.event.EventHandler <methods>;
|
||||
}
|
||||
-keepclassmembers class * {
|
||||
@org.spongepowered.api.event.Listener <methods>;
|
||||
}
|
||||
|
||||
# -----保护继承事件不被清理-----
|
||||
-keep class ** extends org.bukkit.event.Event {*;}
|
||||
|
||||
# -----保护枚举方法的完整性-----
|
||||
-keepclassmembers enum * {
|
||||
public static **[] values();
|
||||
public static ** valueOf(java.lang.String);
|
||||
}
|
||||
|
||||
# -----保护配置注入不被清理-----
|
||||
-keepclassmembers class * extends **.config.inject.Inject** {
|
||||
<fields>;
|
||||
public <init>(org.bukkit.configuration.ConfigurationSection);
|
||||
}
|
||||
|
||||
# -----保护注解命令方法不被清理-----
|
||||
-keepclassmembers class **.commands.annotation.** {<methods>;}
|
||||
-keepclassmembers class * implements **.commands.interfaces.Executor {<methods>;}
|
||||
|
||||
# -----保护注解命令方法不被清理-----
|
||||
-keep @org.spongepowered.api.plugin.Plugin class * {*;}
|
||||
|
||||
# -----保护注解NotProguard标记-----
|
||||
-keep class **.NotProguard
|
||||
-keep @**.NotProguard class * {*;}
|
||||
-keepclassmembers class * {
|
||||
@**.NotProguard <fields>;
|
||||
@**.NotProguard <methods>;
|
||||
}
|
@ -7,8 +7,6 @@ import java.nio.file.Path;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import lombok.val;
|
||||
import pw.yumc.YumCore.annotation.NotProguard;
|
||||
import pw.yumc.YumCore.mc.MinecraftTools;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA
|
||||
@ -16,12 +14,25 @@ import pw.yumc.YumCore.mc.MinecraftTools;
|
||||
* @author 喵♂呜
|
||||
* Created on 2017/10/9 12:40.
|
||||
*/
|
||||
@NotProguard
|
||||
public class Base {
|
||||
private Object instance;
|
||||
|
||||
public Base(Object instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
public Class getClass(String name) throws ClassNotFoundException {
|
||||
return Class.forName(name);
|
||||
}
|
||||
|
||||
public Object getInstance() {
|
||||
return this.instance;
|
||||
}
|
||||
|
||||
public Class getProxyClass() {
|
||||
return ProxyClass.class;
|
||||
}
|
||||
|
||||
public String read(String path) throws IOException {
|
||||
return new String(Files.readAllBytes(new File(path).toPath()), "UTF-8");
|
||||
}
|
||||
@ -46,8 +57,4 @@ public class Base {
|
||||
}
|
||||
Files.delete(path);
|
||||
}
|
||||
|
||||
public Class getTools() {
|
||||
return MinecraftTools.class;
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,8 @@
|
||||
package pw.yumc.MiaoScript;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.val;
|
||||
import pw.yumc.YumCore.bukkit.Log;
|
||||
import pw.yumc.YumCore.commands.CommandSub;
|
||||
import pw.yumc.YumCore.commands.annotation.Cmd;
|
||||
import pw.yumc.YumCore.commands.annotation.Help;
|
||||
import pw.yumc.YumCore.commands.interfaces.Executor;
|
||||
|
||||
/**
|
||||
* 喵式脚本
|
||||
@ -21,62 +10,15 @@ import pw.yumc.YumCore.commands.interfaces.Executor;
|
||||
* @author 喵♂呜
|
||||
* @since 2016年8月29日 上午7:50:39
|
||||
*/
|
||||
public class MiaoScript extends JavaPlugin implements Executor {
|
||||
public class MiaoScript extends JavaPlugin {
|
||||
private ScriptEngine engine;
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void onEnable() {
|
||||
new CommandSub("ms", this);
|
||||
engine = new ScriptEngine(getDataFolder().getCanonicalPath(), getLogger());
|
||||
enableEngine();
|
||||
}
|
||||
|
||||
@Cmd
|
||||
@Help("执行 JS 代码")
|
||||
@SneakyThrows
|
||||
public void js(CommandSender sender, String script) {
|
||||
result(sender, engine.getEngine().eval(script));
|
||||
}
|
||||
|
||||
@Cmd
|
||||
@Help("执行 JS 代码文件")
|
||||
@SneakyThrows
|
||||
public void file(CommandSender sender, String file) {
|
||||
result(sender, engine.getEngine().eval("load('" + new File(getDataFolder(), file).getCanonicalPath() + "')"));
|
||||
}
|
||||
|
||||
@Cmd
|
||||
@Help("重启脚本引擎")
|
||||
public void reload(CommandSender sender) {
|
||||
engine.disableEngine();
|
||||
val server = Bukkit.getServer();
|
||||
try {
|
||||
server.getScheduler().cancelTasks(this);
|
||||
server.getServicesManager().unregisterAll(this);
|
||||
HandlerList.unregisterAll(this);
|
||||
server.getMessenger().unregisterIncomingPluginChannel(this);
|
||||
server.getMessenger().unregisterOutgoingPluginChannel(this);
|
||||
} catch (Exception ex) {
|
||||
Log.d("Error reload", ex);
|
||||
}
|
||||
enableEngine();
|
||||
Log.sender(sender, "§bMiaoScript §eEngine §a重启完成!");
|
||||
}
|
||||
|
||||
private void result(CommandSender sender, Object result) {
|
||||
if (result == null) {
|
||||
Log.sender(sender, "§a运行成功! §c没有返回结果!");
|
||||
} else {
|
||||
Log.sender(sender, "§a运行成功! §b数据类型: §r%s §d结果: §r%s", result.getClass().getName(), result);
|
||||
}
|
||||
}
|
||||
|
||||
private void enableEngine() {
|
||||
val origin = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader(getClassLoader());
|
||||
engine = new ScriptEngine(getDataFolder().getCanonicalPath(), getLogger(), this);
|
||||
engine.enableEngine();
|
||||
Thread.currentThread().setContextClassLoader(origin);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
27
src/main/java/pw/yumc/MiaoScript/MiaoScriptBungee.java
Normal file
27
src/main/java/pw/yumc/MiaoScript/MiaoScriptBungee.java
Normal file
@ -0,0 +1,27 @@
|
||||
package pw.yumc.MiaoScript;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA
|
||||
*
|
||||
* @author MiaoWoo
|
||||
* Created on 2020/1/14 16:02.
|
||||
*/
|
||||
public class MiaoScriptBungee extends Plugin {
|
||||
private ScriptEngine engine;
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void onEnable() {
|
||||
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
|
||||
engine = new ScriptEngine(getDataFolder().getCanonicalPath(), getLogger(), this);
|
||||
engine.enableEngine();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
engine.disableEngine();
|
||||
}
|
||||
}
|
182
src/main/java/pw/yumc/MiaoScript/MiaoScriptEngine.java
Normal file
182
src/main/java/pw/yumc/MiaoScript/MiaoScriptEngine.java
Normal file
@ -0,0 +1,182 @@
|
||||
package pw.yumc.MiaoScript;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.Reader;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.HashMap;
|
||||
|
||||
import javax.script.Bindings;
|
||||
import javax.script.Invocable;
|
||||
import javax.script.ScriptContext;
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineFactory;
|
||||
import javax.script.ScriptEngineManager;
|
||||
import javax.script.ScriptException;
|
||||
import javax.script.SimpleBindings;
|
||||
|
||||
import lombok.val;
|
||||
|
||||
/**
|
||||
* 喵式脚本引擎
|
||||
*
|
||||
* @author 喵♂呜
|
||||
* @since 2016年8月29日 上午7:51:43
|
||||
*/
|
||||
public class MiaoScriptEngine implements ScriptEngine, Invocable {
|
||||
private static MiaoScriptEngine DEFAULT;
|
||||
private static ScriptEngineManager manager;
|
||||
private ScriptEngine engine;
|
||||
|
||||
static {
|
||||
manager = new ScriptEngineManager(ClassLoader.getSystemClassLoader());
|
||||
}
|
||||
|
||||
public static void setBindings(Bindings bindings) {
|
||||
manager.setBindings(bindings);
|
||||
}
|
||||
|
||||
public static Bindings getBindings() {
|
||||
return manager.getBindings();
|
||||
}
|
||||
|
||||
public MiaoScriptEngine() {
|
||||
this("js");
|
||||
}
|
||||
|
||||
public MiaoScriptEngine(final String engineType) {
|
||||
this(manager, engineType);
|
||||
}
|
||||
|
||||
public MiaoScriptEngine(ScriptEngineManager engineManager) {
|
||||
this(engineManager, "js");
|
||||
}
|
||||
|
||||
public MiaoScriptEngine(ScriptEngineManager engineManager, final String engineType) {
|
||||
try {
|
||||
engine = engineManager.getEngineByName(engineType);
|
||||
} catch (final NullPointerException ignored) {
|
||||
}
|
||||
if (engine == null) {
|
||||
val dirs = System.getProperty("java.ext.dirs").split(File.pathSeparator);
|
||||
for (String dir : dirs) {
|
||||
File nashorn = new File(dir, "nashorn.jar");
|
||||
if (nashorn.exists()) {
|
||||
try {
|
||||
Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
|
||||
// 设置方法的访问权限
|
||||
method.setAccessible(true);
|
||||
// 获取系统类加载器
|
||||
URL url = nashorn.toURI().toURL();
|
||||
method.invoke(Thread.currentThread().getContextClassLoader(), url);
|
||||
engineManager = new ScriptEngineManager();
|
||||
engine = engineManager.getEngineByName(engineType);
|
||||
} catch (NoSuchMethodException | MalformedURLException | IllegalAccessException | InvocationTargetException | NullPointerException ignored) {
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new UnsupportedOperationException("当前环境不支持 " + engineType + " 脚本类型!");
|
||||
}
|
||||
}
|
||||
|
||||
public static MiaoScriptEngine getDefault() {
|
||||
if (DEFAULT == null) {
|
||||
DEFAULT = new MiaoScriptEngine();
|
||||
}
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bindings createBindings() {
|
||||
return new SimpleBindings(new HashMap<>(engine.getBindings(ScriptContext.GLOBAL_SCOPE)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object eval(final Reader reader) throws ScriptException {
|
||||
return engine.eval(reader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object eval(final Reader reader, final Bindings n) throws ScriptException {
|
||||
return engine.eval(reader, n);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object eval(final Reader reader, final ScriptContext context) throws ScriptException {
|
||||
return engine.eval(reader, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object eval(final String script) throws ScriptException {
|
||||
return engine.eval(script);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object eval(final String script, final Bindings n) throws ScriptException {
|
||||
return engine.eval(script, n);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object eval(final String script, final ScriptContext context) throws ScriptException {
|
||||
return engine.eval(script, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(final String key) {
|
||||
return engine.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bindings getBindings(final int scope) {
|
||||
return engine.getBindings(scope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScriptContext getContext() {
|
||||
return engine.getContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScriptEngineFactory getFactory() {
|
||||
return engine.getFactory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getInterface(final Class<T> clasz) {
|
||||
return ((Invocable) engine).getInterface(clasz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getInterface(final Object thiz, final Class<T> clasz) {
|
||||
return ((Invocable) engine).getInterface(thiz, clasz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invokeFunction(final String name, final Object... args) throws ScriptException, NoSuchMethodException {
|
||||
return ((Invocable) engine).invokeFunction(name, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invokeMethod(final Object thiz, final String name, final Object... args) throws ScriptException, NoSuchMethodException {
|
||||
return ((Invocable) engine).invokeMethod(thiz, name, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(final String key, final Object value) {
|
||||
engine.put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBindings(final Bindings bindings, final int scope) {
|
||||
engine.setBindings(bindings, scope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContext(final ScriptContext context) {
|
||||
engine.setContext(context);
|
||||
}
|
||||
}
|
24
src/main/java/pw/yumc/MiaoScript/MiaoScriptNukkit.java
Normal file
24
src/main/java/pw/yumc/MiaoScript/MiaoScriptNukkit.java
Normal file
@ -0,0 +1,24 @@
|
||||
package pw.yumc.MiaoScript;
|
||||
|
||||
import cn.nukkit.plugin.PluginBase;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
/**
|
||||
* @author MiaoWoo
|
||||
*/
|
||||
public class MiaoScriptNukkit extends PluginBase {
|
||||
private ScriptEngine engine;
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void onEnable() {
|
||||
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
|
||||
engine = new ScriptEngine(getDataFolder().getCanonicalPath(), getLogger(), this);
|
||||
engine.enableEngine();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
engine.disableEngine();
|
||||
}
|
||||
}
|
@ -1,23 +1,14 @@
|
||||
package pw.yumc.MiaoScript;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.script.ScriptException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.spongepowered.api.Sponge;
|
||||
import org.spongepowered.api.command.CommandResult;
|
||||
import org.spongepowered.api.command.CommandSource;
|
||||
import org.spongepowered.api.command.args.GenericArguments;
|
||||
import org.spongepowered.api.command.spec.CommandSpec;
|
||||
import org.spongepowered.api.config.ConfigDir;
|
||||
import org.spongepowered.api.event.Listener;
|
||||
import org.spongepowered.api.event.game.state.GameInitializationEvent;
|
||||
import org.spongepowered.api.event.game.GameReloadEvent;
|
||||
import org.spongepowered.api.event.game.state.GameStartedServerEvent;
|
||||
import org.spongepowered.api.event.game.state.GameStoppingServerEvent;
|
||||
import org.spongepowered.api.plugin.Plugin;
|
||||
import org.spongepowered.api.text.Text;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import lombok.SneakyThrows;
|
||||
@ -38,78 +29,24 @@ public class MiaoScriptSponge {
|
||||
@ConfigDir(sharedRoot = false)
|
||||
private File pluginConfigDir;
|
||||
|
||||
@Listener
|
||||
public void onInit(GameInitializationEvent event) {
|
||||
|
||||
}
|
||||
|
||||
private CommandSpec main() {
|
||||
return CommandSpec.builder()
|
||||
.description(Text.of("喵式脚本主命令"))
|
||||
.permission("MiaoScript.admin")
|
||||
.child(js(), "js")
|
||||
.child(file(), "file")
|
||||
.child(reload(), "reload")
|
||||
.build();
|
||||
}
|
||||
|
||||
private CommandSpec js() {
|
||||
return CommandSpec.builder()
|
||||
.description(Text.of("执行JS命令"))
|
||||
.arguments(GenericArguments.onlyOne(GenericArguments.remainingJoinedStrings(Text.of("js"))))
|
||||
.executor((src, args) -> {
|
||||
try {
|
||||
result(src, engine.getEngine().eval(args.<String>getOne("js").orElse("")));
|
||||
} catch (ScriptException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return CommandResult.success();
|
||||
})
|
||||
.build();
|
||||
}
|
||||
|
||||
private CommandSpec file() {
|
||||
return CommandSpec.builder()
|
||||
.description(Text.of("执行JS文件"))
|
||||
.arguments(GenericArguments.onlyOne(GenericArguments.remainingJoinedStrings(Text.of("js"))))
|
||||
.executor((src, args) -> {
|
||||
try {
|
||||
result(src, engine.getEngine().eval(new FileReader(new File(pluginConfigDir, args.<String>getOne("js").orElse("")))));
|
||||
} catch (ScriptException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return CommandResult.success();
|
||||
})
|
||||
.build();
|
||||
}
|
||||
|
||||
private CommandSpec reload() {
|
||||
return CommandSpec.builder()
|
||||
.description(Text.of("重载 JS 引擎"))
|
||||
.executor((src, args) -> {
|
||||
engine.disableEngine();
|
||||
Sponge.getEventManager().unregisterPluginListeners(this);
|
||||
engine.enableEngine();
|
||||
src.sendMessage(Text.of("§6[§bMiaoScript§6]§r §bMiaoScript §eEngine §a重启完成!"));
|
||||
return CommandResult.success();
|
||||
})
|
||||
.build();
|
||||
}
|
||||
|
||||
private void result(CommandSource sender, Object result) {
|
||||
if (result == null) {
|
||||
sender.sendMessage(Text.of("§a运行成功! §c没有返回结果!"));
|
||||
} else {
|
||||
sender.sendMessage(Text.of(String.format("§a运行成功! §b数据类型: §r%s §d结果: §r%s", result.getClass().getName(), result)));
|
||||
}
|
||||
}
|
||||
|
||||
@Listener
|
||||
@SneakyThrows
|
||||
public void onStart(GameStartedServerEvent event) {
|
||||
Sponge.getServer().getConsole();
|
||||
Sponge.getCommandManager().register(this, main(), "ms", "mscript", "MiaoScript");
|
||||
engine = new ScriptEngine(pluginConfigDir.getCanonicalPath(), logger);
|
||||
engine = new ScriptEngine(pluginConfigDir.getCanonicalPath(), logger, this);
|
||||
engine.enableEngine();
|
||||
}
|
||||
|
||||
@Listener
|
||||
@SneakyThrows
|
||||
public void onStop(GameStoppingServerEvent event) {
|
||||
engine.disableEngine();
|
||||
}
|
||||
|
||||
@Listener
|
||||
@SneakyThrows
|
||||
public void reload(GameReloadEvent event) {
|
||||
engine.disableEngine();
|
||||
engine = new ScriptEngine(pluginConfigDir.getCanonicalPath(), logger, this);
|
||||
engine.enableEngine();
|
||||
}
|
||||
}
|
||||
|
51
src/main/java/pw/yumc/MiaoScript/ProxyClass.java
Normal file
51
src/main/java/pw/yumc/MiaoScript/ProxyClass.java
Normal file
@ -0,0 +1,51 @@
|
||||
package pw.yumc.MiaoScript;
|
||||
|
||||
import javax.script.Bindings;
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptException;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA
|
||||
*
|
||||
* @author MiaoWoo
|
||||
* Created on 2020/1/16 9:04.
|
||||
*/
|
||||
public class ProxyClass {
|
||||
private ScriptEngine engine;
|
||||
private String script;
|
||||
private Bindings bindings;
|
||||
|
||||
public ProxyClass(ScriptEngine engine, String script, Bindings bindings) {
|
||||
this.engine = engine;
|
||||
this.script = script;
|
||||
this.bindings = bindings;
|
||||
}
|
||||
|
||||
public Object method(Object args) throws ScriptException {
|
||||
bindings.put("args", args);
|
||||
return engine.eval(script, bindings);
|
||||
}
|
||||
|
||||
public Object one(Object arg1) throws ScriptException {
|
||||
bindings.put("arg1", arg1);
|
||||
return engine.eval(script, bindings);
|
||||
}
|
||||
|
||||
public Object two(Object arg1, Object arg2) throws ScriptException {
|
||||
bindings.put("arg1", arg1);
|
||||
bindings.put("arg2", arg2);
|
||||
return engine.eval(script, bindings);
|
||||
}
|
||||
|
||||
public Object three(Object arg1, Object arg2, Object arg3) throws ScriptException {
|
||||
bindings.put("arg1", arg1);
|
||||
bindings.put("arg2", arg2);
|
||||
bindings.put("arg3", arg3);
|
||||
return engine.eval(script, bindings);
|
||||
}
|
||||
|
||||
public Object args(Object... args) throws ScriptException {
|
||||
bindings.put("args", args);
|
||||
return engine.eval(script, bindings);
|
||||
}
|
||||
}
|
@ -8,7 +8,6 @@ import java.nio.file.Paths;
|
||||
import javax.script.ScriptEngineManager;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import pw.yumc.YumCore.engine.MiaoScriptEngine;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA
|
||||
@ -19,18 +18,22 @@ import pw.yumc.YumCore.engine.MiaoScriptEngine;
|
||||
public class ScriptEngine {
|
||||
private String root;
|
||||
private Object logger;
|
||||
private Base base;
|
||||
private MiaoScriptEngine engine;
|
||||
private ScriptEngineManager manager;
|
||||
|
||||
public ScriptEngine(String root, Object logger) {
|
||||
public ScriptEngine(String root, Object logger, Object instance) {
|
||||
this.root = root;
|
||||
this.logger = logger;
|
||||
this.base = new Base(instance);
|
||||
this.manager = new ScriptEngineManager();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public void enableEngine() {
|
||||
ScriptEngineManager manager = new ScriptEngineManager();
|
||||
this.engine = new MiaoScriptEngine(manager, "nashorn");
|
||||
this.engine.put("base", new Base());
|
||||
this.engine.put("base", this.base);
|
||||
this.engine.put("ScriptEngineContextHolder", this);
|
||||
Path bios = Paths.get(root, "bios.js");
|
||||
// 如果存在自定义bios就加载自定义的
|
||||
if (Files.exists(bios)) {
|
||||
@ -43,7 +46,8 @@ public class ScriptEngine {
|
||||
|
||||
@SneakyThrows
|
||||
public void disableEngine() {
|
||||
engine.invokeFunction("engineDisable");
|
||||
this.engine.invokeFunction("engineDisable");
|
||||
this.engine = null;
|
||||
}
|
||||
|
||||
public MiaoScriptEngine getEngine() {
|
||||
|
@ -1,51 +0,0 @@
|
||||
package pw.yumc.MiaoScript;
|
||||
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA
|
||||
*
|
||||
* @author 喵♂呜
|
||||
* Created on 2017/9/30 21:32.
|
||||
*/
|
||||
public class ScriptEvent extends Event implements Cancellable {
|
||||
private ScriptObjectMirror mirror;
|
||||
private boolean cancelled = false;
|
||||
|
||||
public ScriptEvent(ScriptObjectMirror mirror) {
|
||||
this.mirror = mirror;
|
||||
}
|
||||
|
||||
public ScriptObjectMirror getMirror() {
|
||||
return mirror;
|
||||
}
|
||||
|
||||
public void setMirror(ScriptObjectMirror mirror) {
|
||||
this.mirror = mirror;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.cancelled = cancel;
|
||||
}
|
||||
|
||||
private static HandlerList handlerList = new HandlerList();
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlerList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlerList;
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
/*global Java, base, module, exports, require*/
|
||||
function ChatHandlerDefault() {
|
||||
this.tellraw = function(sender, raw) {
|
||||
this.json(sender, JSON.stringify(raw));
|
||||
}
|
||||
}
|
||||
var ChatHandler = Object.assign(new ChatHandlerDefault(), requireInternal('chat'));
|
||||
|
||||
exports = module.exports = ChatHandler;
|
@ -1,2 +0,0 @@
|
||||
/*global Java, base, module, exports, require*/
|
||||
module.exports = requireInternal('command');
|
@ -1,158 +0,0 @@
|
||||
'use strict';
|
||||
/**
|
||||
* Bukkit 事件相关类
|
||||
*/
|
||||
/*global Java, base, module, exports, require, __FILE__*/
|
||||
|
||||
function EventHandlerDefault() {
|
||||
var Thread = Java.type("java.lang.Thread");
|
||||
|
||||
this.plugin = require('./server').plugin.self;
|
||||
this.mapEvent = [];
|
||||
this.listenerMap = [];
|
||||
this.baseEventDir = '';
|
||||
|
||||
var self = this;
|
||||
|
||||
/**
|
||||
* 扫描包 org.bukkit.event 下的所有事件
|
||||
* 映射简写名称 org.bukkit.event.player.PlayerLoginEvent => playerloginevent
|
||||
*/
|
||||
this.mapEventName = function mapEventName() {
|
||||
if (this.baseEventDir === "") {
|
||||
throw new Error("事件基础包名为空 无法进行事件映射!");
|
||||
}
|
||||
var count = 0;
|
||||
var dirs = Thread.currentThread().getContextClassLoader().getResources(this.baseEventDir);
|
||||
while (dirs.hasMoreElements()) {
|
||||
var url = dirs.nextElement();
|
||||
var protocol = url.protocol;
|
||||
if (protocol === "jar") {
|
||||
// noinspection JSUnresolvedVariable
|
||||
var jar = url.openConnection().jarFile;
|
||||
var entries = jar.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
var entry = entries.nextElement();
|
||||
var name = entry.name;
|
||||
// 以 org/bukkit/event 开头 并且以 .class 结尾
|
||||
if (name.startsWith(this.baseEventDir) && name.endsWith(".class")) {
|
||||
var i = name.replaceAll('/', '.');
|
||||
try {
|
||||
var clz = base.getClass(i.substring(0, i.length - 6));
|
||||
// 继承于 org.bukkit.event.Event 访问符为Public
|
||||
if (this.isVaildEvent(clz)) {
|
||||
// noinspection JSUnresolvedVariable
|
||||
var simpleName = this.class2Name(clz).toLowerCase();
|
||||
console.debug("Mapping Event [%s] => %s".format(clz.canonicalName, simpleName));
|
||||
this.mapEvent[simpleName] = clz;
|
||||
count++;
|
||||
}
|
||||
} catch (ex) {
|
||||
//ignore already loaded class
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
this.class2Name = function class2Name(clazz) {
|
||||
return clazz.simpleName;
|
||||
}
|
||||
|
||||
this.name2Class = function name2Class(name, event) {
|
||||
var eventCls = this.mapEvent[event.toLowerCase()] || this.mapEvent[event.toLowerCase() + 'event'];
|
||||
if (!eventCls) {
|
||||
try {
|
||||
eventCls = base.getClass(eventCls);
|
||||
this.mapEvent[event] = eventCls;
|
||||
} catch (ex) {
|
||||
console.console("§6插件 §b%s §6注册事件 §c%s §6失败 §4事件未找到!".format(name, event));
|
||||
console.ex(new Error("插件 %s 注册事件 %s 失败 事件未找到!".format(name, event)))
|
||||
return;
|
||||
}
|
||||
}
|
||||
return eventCls;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为一个有效的事件类
|
||||
* @param clz
|
||||
* @returns {*|boolean}
|
||||
*/
|
||||
this.isVaildEvent = function isVaildEvent(clz) {
|
||||
throw new Error("当前服务器不支持事件系统!");
|
||||
}
|
||||
|
||||
this.register = function register(eventCls, exec, priority, ignoreCancel) {
|
||||
throw new Error("当前服务器不支持事件系统!");
|
||||
}
|
||||
|
||||
this.unregister = function unregister(event, listener) {
|
||||
throw new Error("当前服务器不支持事件系统!");
|
||||
}
|
||||
|
||||
this.execute = function execute(name, exec, eventCls) {
|
||||
return function execute() {
|
||||
try {
|
||||
exec(arguments[arguments.length - 1]);
|
||||
} catch (ex) {
|
||||
console.console('§6插件 §b%s §6处理 §d%s §6事件时发生异常 §4%s'.format(name, this.class2Name(eventCls), ex));
|
||||
console.ex(ex);
|
||||
}
|
||||
}.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加事件监听
|
||||
* @param jsp
|
||||
* @param event
|
||||
* @param exec {function}
|
||||
* @param priority [LOWEST,LOW,NORMAL,HIGH,HIGHEST,MONITOR]
|
||||
* @param ignoreCancel
|
||||
*/
|
||||
this.listen = function listen(jsp, event, exec, priority, ignoreCancel) {
|
||||
if (!jsp || !jsp.description || !jsp.description.name) throw new TypeError('插件名称为空 请检查传入参数!');
|
||||
var name = jsp.description.name;
|
||||
var eventCls = this.name2Class(name, event);
|
||||
if (!eventCls) { return; }
|
||||
if (typeof priority === 'boolean') {
|
||||
ignoreCancel = priority;
|
||||
priority = 'NORMAL';
|
||||
}
|
||||
priority = priority || 'NORMAL';
|
||||
ignoreCancel = ignoreCancel || false;
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
var listener = this.register(eventCls, this.execute(name, exec, eventCls), priority, ignoreCancel);
|
||||
var listenerMap = this.listenerMap;
|
||||
// 添加到缓存 用于关闭插件的时候关闭事件
|
||||
if (!listenerMap[name]) listenerMap[name] = [];
|
||||
var offExec = function () {
|
||||
this.unregister(eventCls, listener);
|
||||
console.debug('插件 %s 注销事件 %s'.format(name, this.class2Name(eventCls)));
|
||||
}.bind(this);
|
||||
var off = {
|
||||
event: eventCls,
|
||||
listener: listener,
|
||||
off: offExec
|
||||
};
|
||||
listenerMap[name].push(off);
|
||||
// noinspection JSUnresolvedVariable
|
||||
console.debug('插件 %s 注册事件 %s => %s'.format(name, this.class2Name(eventCls), exec.name === '' ? '匿名方法' : exec.name));
|
||||
return off;
|
||||
}
|
||||
}
|
||||
var EventHandler = Object.assign(new EventHandlerDefault(), requireInternal('event'));
|
||||
// 映射事件名称
|
||||
console.info('%s 事件映射完毕 共计 %s 个事件!'.format(DetectServerType, EventHandler.mapEventName().toFixed(0)));
|
||||
module.exports = {
|
||||
on: EventHandler.listen.bind(EventHandler),
|
||||
disable: function (jsp) {
|
||||
var eventCache = EventHandler.listenerMap[jsp.description.name];
|
||||
if (eventCache) {
|
||||
eventCache.forEach(function (t) t.off.call(EventHandler));
|
||||
delete EventHandler.listenerMap[jsp.description.name];
|
||||
}
|
||||
}
|
||||
};
|
@ -1,2 +0,0 @@
|
||||
/*global Java, base, module, exports, require*/
|
||||
module.exports = requireInternal('item');
|
@ -1,2 +0,0 @@
|
||||
/*global Java, base, module, exports, require*/
|
||||
module.exports = requireInternal('permission', {warnNotFound: false});
|
@ -1,290 +0,0 @@
|
||||
'use strict';
|
||||
/**
|
||||
* MiaoScript脚本插件加载类
|
||||
*/
|
||||
/*global Java, module, exports, require, __FILE__*/
|
||||
// var zip = require("core/zip");
|
||||
var fs = require('core/fs');
|
||||
var yaml = require('modules/yaml');
|
||||
var event = require('./event');
|
||||
var server = require('./server');
|
||||
var command = require('./command');
|
||||
var permission = require('./permission');
|
||||
|
||||
/**
|
||||
* 载入插件
|
||||
* @param dir
|
||||
*/
|
||||
function loadPlugins(dir) {
|
||||
var plugin = fs.file(root, dir);
|
||||
if (!plugin) {
|
||||
console.info("首次加载 创建文件夹 %s ...".format(plugin));
|
||||
} else {
|
||||
console.info("开始扫描 %s 下的插件 ...".format(plugin));
|
||||
createUpdate(plugin);
|
||||
var files = [];
|
||||
fs.list(plugin).forEach(function (file) {
|
||||
files.push(file.toFile());
|
||||
});
|
||||
fs.list(fs.file(plugin, DetectServerType)).forEach(function (file) {
|
||||
files.push(file.toFile());
|
||||
});
|
||||
loadZipPlugins(files);
|
||||
loadJsPlugins(files);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新插件
|
||||
* @param path
|
||||
*/
|
||||
function createUpdate(path) {
|
||||
var update = fs.file(path, "update");
|
||||
if (!update.exists()) {
|
||||
update.mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ZIP类型插件预加载
|
||||
* @param files
|
||||
*/
|
||||
function loadZipPlugins(files) {
|
||||
files.filter(function (file) {
|
||||
return file.name.endsWith(".zip");
|
||||
}).forEach(function (file) {
|
||||
// console.log(file);
|
||||
// console.log(fs.file(file,"!package.json"))
|
||||
// zip.unzip(fs.file(plugins_dir, file));
|
||||
// var dir = new File(plugins_dir, file.name.split(".")[0]);
|
||||
// TODO 添加文件夹类型的插件兼容
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* JS类型插件预加载
|
||||
*/
|
||||
function loadJsPlugins(files) {
|
||||
files.filter(function (file) {
|
||||
return file.name.endsWith(".js")
|
||||
}).forEach(function (file) {
|
||||
loadPlugin(file)
|
||||
})
|
||||
}
|
||||
|
||||
function loadPlugin(file) {
|
||||
try {
|
||||
var plugin = readPlugin(file);
|
||||
initPlugin(plugin);
|
||||
plugins[plugin.description.name] = plugin;
|
||||
return plugin
|
||||
} catch (ex) {
|
||||
console.console('§6插件 §b%s §6初始化时发生错误 §4%s'.format(file.name, ex.message));
|
||||
console.ex(ex);
|
||||
}
|
||||
}
|
||||
|
||||
function readPlugin(file) {
|
||||
var update = fs.file(fs.file(file.parentFile, 'update'), file.name);
|
||||
if (update.exists()) {
|
||||
console.info('自动升级插件 %s'.format(file.name));
|
||||
fs.move(update, file, true);
|
||||
}
|
||||
var plugin = require(file, {
|
||||
cache: false,
|
||||
hook: function (origin) {
|
||||
return beforeLoadHook(origin);
|
||||
}
|
||||
})
|
||||
console.debug("插件编译结果: %s".format(JSON.stringify(plugin)));
|
||||
plugin.__FILE__ = file;
|
||||
return plugin;
|
||||
}
|
||||
|
||||
function initPlugin(plugin) {
|
||||
var desc = plugin.description;
|
||||
if (!desc || !desc.name) {
|
||||
throw new Error("文件 %s 不存在 description 描述信息 无法加载插件!".format(plugin.__FILE__));
|
||||
} else {
|
||||
internalInitPlugin(plugin);
|
||||
afterLoadHook(plugin);
|
||||
console.info('载入插件 %s 版本 %s By %s'.format(desc.name, desc.version || '未知', desc.author || '未知'));
|
||||
}
|
||||
return plugin;
|
||||
}
|
||||
|
||||
function beforeLoadHook(origin) {
|
||||
var result = origin;
|
||||
// 处理 event 为了不影响 正常逻辑 event 还是手动require吧
|
||||
// result = result + 'var event = {}; module.exports.event = event;';
|
||||
// 注入 console 对象 // 给插件注入单独的 console
|
||||
result += '\nvar console = new Console(); module.exports.console = console;';
|
||||
// 插件注入 self 对象
|
||||
result += '\nvar self = {}; module.exports.self = self;';
|
||||
return result;
|
||||
}
|
||||
|
||||
function afterLoadHook(plugin) {
|
||||
// plugin.event.on = event.on.bind(plugin);
|
||||
// 给 console 添加插件名称
|
||||
plugin.console.name = plugin.description.name;
|
||||
// 赋值 self
|
||||
Object.assign(plugin.self, plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化插件内容(提供config,__DATA__等参数)
|
||||
*/
|
||||
function internalInitPlugin(plugin) {
|
||||
// 初始化 __DATA__
|
||||
plugin.__DATA__ = plugin.dataFolder = fs.file(plugin.__FILE__.parentFile, plugin.description.name);
|
||||
// 初始化 getDataFolder()
|
||||
plugin.getDataFolder = function getDataFolder() {
|
||||
return plugin.__DATA__;
|
||||
}
|
||||
// 初始化 getFile()
|
||||
plugin.getFile = plugin.file = function getFile(name) {
|
||||
return fs.file(plugin.getDataFolder(), name);
|
||||
};
|
||||
// 初始化插件配置相关方法
|
||||
initPluginConfig(plugin);
|
||||
|
||||
if (command.enable) command.enable(plugin);
|
||||
if (permission.enable) permission.enable(plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化插件配置
|
||||
*/
|
||||
function initPluginConfig(plugin) {
|
||||
// 初始化 config
|
||||
plugin.configFile = plugin.getFile('config.yml');
|
||||
/**
|
||||
* 获取配置文件
|
||||
* @constructor
|
||||
* @constructor (file|string)
|
||||
*/
|
||||
plugin.getConfig = function () {
|
||||
switch (arguments.length) {
|
||||
case 0:
|
||||
return plugin.config;
|
||||
case 1:
|
||||
var file = arguments[0];
|
||||
if (!file.isFile) {
|
||||
file = plugin.getFile(file);
|
||||
}
|
||||
return yaml.safeLoad(fs.read(file), { json: true });
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 重载配置文件
|
||||
* @constructor
|
||||
* @constructor (file|string)
|
||||
*/
|
||||
plugin.reloadConfig = function () {
|
||||
plugin.config = plugin.getConfig(plugin.configFile);
|
||||
}
|
||||
/**
|
||||
* 保存配置文件
|
||||
* @constructor
|
||||
* @constructor (file, content)
|
||||
*/
|
||||
plugin.saveConfig = function () {
|
||||
// 判断插件目录是否存在 并且不为文件 否则删除重建
|
||||
if (!plugin.configFile.parentFile.isDirectory()) {
|
||||
fs.del(plugin.configFile.parentFile);
|
||||
}
|
||||
plugin.configFile.parentFile.mkdirs();
|
||||
switch (arguments.length) {
|
||||
case 0:
|
||||
fs.save(plugin.configFile, yaml.safeDump(plugin.config));
|
||||
break;
|
||||
case 2:
|
||||
fs.save(fs.file(plugin.__DATA__, arguments[0]), yaml.safeDump(arguments[1]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (plugin.configFile.isFile()) {
|
||||
plugin.config = plugin.getConfig('config.yml');
|
||||
} else if (plugin.description.config) {
|
||||
plugin.config = plugin.description.config;
|
||||
plugin.saveConfig();
|
||||
}
|
||||
}
|
||||
|
||||
function checkAndGet(args) {
|
||||
if (args.length === 0) {
|
||||
return plugins;
|
||||
}
|
||||
var name = args[0];
|
||||
// 如果是插件 则直接返回
|
||||
if (name && name.description) {
|
||||
return [name];
|
||||
}
|
||||
var plugin = exports.plugins[name];
|
||||
if (!plugin) {
|
||||
throw new Error("插件 " + name + " 不存在!");
|
||||
}
|
||||
return [plugin];
|
||||
}
|
||||
|
||||
function checkAndRun(args, name, ext) {
|
||||
var pls = checkAndGet(args);
|
||||
for (var i in pls) {
|
||||
var jsp = pls[i];
|
||||
var exec = jsp[name];
|
||||
try {
|
||||
// 绑定方法的this到插件自身
|
||||
if (typeof exec === "function") exec.call(jsp);
|
||||
if (typeof ext === "function") ext.call(jsp);
|
||||
} catch (ex) {
|
||||
console.console('§6插件 §b%s §6执行 §d%s §6方法时发生错误 §4%s'.format(jsp.description.name, name, ex.message));
|
||||
console.ex(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var plugins = [];
|
||||
|
||||
function init(path) {
|
||||
var plugin = exports.$
|
||||
if (plugin !== null) {
|
||||
// 如果plugin不等于null 则代表是正式环境
|
||||
console.info("初始化 MiaoScript 插件系统: %s".format(plugin));
|
||||
}
|
||||
loadPlugins(path);
|
||||
};
|
||||
|
||||
function load() {
|
||||
checkAndRun(arguments, 'load');
|
||||
};
|
||||
|
||||
function enable() {
|
||||
checkAndRun(arguments, 'enable');
|
||||
};
|
||||
|
||||
function disable() {
|
||||
checkAndRun(arguments, 'disable', function eventDisable() {
|
||||
event.disable(this);
|
||||
});
|
||||
};
|
||||
|
||||
function reload() {
|
||||
checkAndGet(arguments).forEach(function (p) {
|
||||
disable(p);
|
||||
p = loadPlugin(p.__FILE__);
|
||||
load(p);
|
||||
enable(p);
|
||||
});
|
||||
};
|
||||
|
||||
exports = module.exports = {
|
||||
$: server.plugin.self,
|
||||
plugins: plugins,
|
||||
init: init,
|
||||
load: load,
|
||||
enable: enable,
|
||||
disable: disable,
|
||||
reload: reload,
|
||||
loadPlugin: loadPlugin
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
/*global Java, base, module, exports, require*/
|
||||
module.exports = requireInternal('server');
|
@ -1,2 +0,0 @@
|
||||
/*global Java, base, module, exports, require*/
|
||||
module.exports = requireInternal('task');
|
@ -1,5 +0,0 @@
|
||||
/*global Java, base, module, exports, require*/
|
||||
var player = requireInternal('wrapper/player');
|
||||
module.exports = {
|
||||
player: player.$
|
||||
}
|
@ -1,60 +1,64 @@
|
||||
'use strict';
|
||||
var log;
|
||||
var boot;
|
||||
var disable;
|
||||
var engineDisable;
|
||||
var global = this;
|
||||
/**
|
||||
* 初始化框架引擎
|
||||
* Init MiaoScriptEngine Runtime
|
||||
*/
|
||||
(function () {
|
||||
(function() {
|
||||
var loader;
|
||||
boot = function (root, logger) {
|
||||
boot = function(root, logger) {
|
||||
log = logger;
|
||||
// 开发环境下初始化
|
||||
// Development Env Detect
|
||||
root = root || "src/main/resources";
|
||||
if (__FILE__ !== "<eval>") {
|
||||
logger.info('载入自定义 BIOS 文件 ' + __FILE__);
|
||||
logger.info('Loading custom BIOS file ' + __FILE__);
|
||||
global.debug = true;
|
||||
}
|
||||
if (java.nio.file.Files.exists(java.nio.file.Paths.get(root, "debug"))) {
|
||||
logger.info('已开启调试模式!');
|
||||
logger.info('Running in debug mode...');
|
||||
global.debug = true;
|
||||
}
|
||||
// 检查类加载器 防止找不到核心文件
|
||||
loader = checkClassLoader();
|
||||
// 解压文件到根目录 非调试模式直接从jar解压覆盖
|
||||
release(root, '(api|core|internal|modules)+/.*', !global.debug);
|
||||
load(root + '/core/init.js');
|
||||
try {
|
||||
init(root);
|
||||
} catch (ex) {
|
||||
ex.printStackTrace();
|
||||
if (java.nio.file.Files.exists(java.nio.file.Paths.get(root, "level"))) {
|
||||
global.level = base.read(java.nio.file.Paths.get(root, "level"))
|
||||
logger.info('Set system level to [' + global.level + ']...');
|
||||
}
|
||||
// Check Class Loader, Sometimes Server will can't find plugin.yml file
|
||||
loader = checkClassLoader();
|
||||
// Force decompression core|node_modules to folder when not debug mode
|
||||
release(root, '(core)+/.*', !global.debug);
|
||||
// Async Loading MiaoScript Engine
|
||||
new java.lang.Thread(function() {
|
||||
load(root + '/core/ployfill.js')(root, logger);
|
||||
engineDisable = require('@ms/core').default;
|
||||
}, "MiaoScript thread").start()
|
||||
};
|
||||
|
||||
var pluginYml;
|
||||
|
||||
function checkClassLoader() {
|
||||
var classLoader = java.lang.Thread.currentThread().contextClassLoader;
|
||||
pluginYml = classLoader.getResource("plugin.yml");
|
||||
if (pluginYml === null) {
|
||||
log.info("==================== ERROR ====================");
|
||||
log.info("异常的类加载器: " + classLoader.class.name);
|
||||
log.info("==================== ERROR ====================");
|
||||
throw Error('MiaoScript核心类库初始化失败 异常的类加载器!');
|
||||
throw Error("Error class loader: " + classLoader.class.name + " Please contact the author MiaoWoo!");
|
||||
} else {
|
||||
log.info("Class loader compatible: " + classLoader.class.name);
|
||||
if (classLoader.parent) {
|
||||
log.info("Parent class loader: " + classLoader.parent.class.name);
|
||||
}
|
||||
}
|
||||
return classLoader;
|
||||
}
|
||||
|
||||
function release(root, regex, replace) {
|
||||
var upath = pluginYml.getFile().substring(pluginYml.getFile().indexOf("/") + 1);
|
||||
var jarPath = java.net.URLDecoder.decode(upath.substring(0, upath.indexOf('!')));
|
||||
var filePath = pluginYml.getFile().substring(pluginYml.getFile().indexOf("/") + 1);
|
||||
var jarPath = java.net.URLDecoder.decode(filePath.substring(0, filePath.indexOf('!')));
|
||||
if (!java.nio.file.Files.exists(java.nio.file.Paths.get(jarPath))) {
|
||||
jarPath = "/" + jarPath;
|
||||
}
|
||||
var jar = new java.util.jar.JarFile(jarPath);
|
||||
var r = new RegExp(regex);// "[core|modules]/.*"
|
||||
jar.stream().forEach(function (entry) {
|
||||
var r = new RegExp(regex);
|
||||
jar.stream().forEach(function(entry) {
|
||||
try {
|
||||
if (!entry.isDirectory()) {
|
||||
if (r.test(entry.name)) {
|
||||
@ -71,4 +75,4 @@ var global = this;
|
||||
}
|
||||
})
|
||||
}
|
||||
})();
|
||||
})();
|
||||
|
5
src/main/resources/bungee.yml
Normal file
5
src/main/resources/bungee.yml
Normal file
@ -0,0 +1,5 @@
|
||||
name: ${project.artifactId}
|
||||
description: ${project.description}
|
||||
main: ${project.groupId}.${project.artifactId}.${project.artifactId}Bungee
|
||||
version: ${project.version}
|
||||
author: MiaoWoo
|
@ -1,10 +0,0 @@
|
||||
#MySQL数据库配置
|
||||
DataBase:
|
||||
#默认数据库
|
||||
def:
|
||||
#数据库需要自行建立
|
||||
database: minecraft
|
||||
username: root
|
||||
password: root
|
||||
ip: 127.0.0.1
|
||||
port: 3306
|
@ -1,60 +1,29 @@
|
||||
/**
|
||||
* 控制台输出类
|
||||
*/
|
||||
/*global base*/
|
||||
(function (global) {
|
||||
var Arrays = Java.type('java.util.Arrays');
|
||||
var Level = Java.type('java.util.logging.Level');
|
||||
global.ConsoleDefault = function ConsoleDefault(name) {
|
||||
Object.defineProperty(this, 'name', {
|
||||
get: function () {
|
||||
return this._name;
|
||||
}.bind(this),
|
||||
set: function (name) {
|
||||
this._name = name ? '[' + name + '] ' : '';
|
||||
this.prefix = name ? '§6[§cMS§6][§b' + name + '§6]§r ' : '§6[§bMiaoScript§6]§r ';
|
||||
}.bind(this)
|
||||
});
|
||||
this.name = name;
|
||||
this.log = this.info = function () {
|
||||
log.info(this.name + Array.prototype.join.call(arguments, ' '));
|
||||
};
|
||||
this.warn = function () {
|
||||
log.warning(this.name + Array.prototype.join.call(arguments, ' '));
|
||||
};
|
||||
this.error = function () {
|
||||
log.log(Level.SEVERE, this.name + Array.prototype.join.call(arguments, ' '));
|
||||
};
|
||||
this.debug = function () {
|
||||
log.info(this.name + '[DEBUG] ' + Array.prototype.join.call(arguments, ' '));
|
||||
};
|
||||
this.debug = global.debug ? this.debug : global.noop;
|
||||
this.sender = this.info;
|
||||
this.console = this.info;
|
||||
this.object = function (obj) {
|
||||
for (var i in obj) {
|
||||
this.log(i, '=>', obj[i])
|
||||
// @ts-check
|
||||
(
|
||||
/**
|
||||
* @param {{ info: (arg0: string) => void; }} logger
|
||||
*/
|
||||
function(logger) {
|
||||
function log() {
|
||||
logger.info(Array.prototype.join.call(arguments, ' '))
|
||||
}
|
||||
/**
|
||||
* @param {string} prefix
|
||||
*/
|
||||
function _proxy(prefix) {
|
||||
return function() {
|
||||
log('[' + prefix + ']', Array.prototype.join.call(arguments, ' '))
|
||||
}
|
||||
}
|
||||
this.ex = function (message, ex) {
|
||||
if (!ex) {
|
||||
this.console('§4' + message);
|
||||
ex = message;
|
||||
} else {
|
||||
this.console('§4' + message + ' ' + ex);
|
||||
}
|
||||
var track = ex.getStackTrace();
|
||||
if (track.class) {
|
||||
track = Arrays.asList(track)
|
||||
}
|
||||
track.forEach(function (stack) {
|
||||
if (stack.className.startsWith('<')) {
|
||||
this.console(' §e位于§c', stack.fileName, '=>§c', stack.methodName, '§4行', stack.lineNumber);
|
||||
} else {// %s.%s(§4%s:%s§c)
|
||||
this.console(' §e位于§c', stack.className + '.' + stack.methodName + '(§4' + stack.fileName + ':' + stack.lineNumber + '§c)');
|
||||
}
|
||||
}.bind(this));
|
||||
return {
|
||||
log: log,
|
||||
info: log,
|
||||
ex: log,
|
||||
// @ts-ignore
|
||||
trace: global.level === "trace" ? _proxy('TRACE') : global.noop,
|
||||
// @ts-ignore
|
||||
debug: global.debug ? _proxy('DEBUG') : global.noop,
|
||||
warn: _proxy('WARN'),
|
||||
error: _proxy('ERROR')
|
||||
};
|
||||
}
|
||||
global.Console = ConsoleDefault;
|
||||
})(global);
|
||||
})
|
||||
|
@ -1,31 +0,0 @@
|
||||
/**
|
||||
* 服务器探测类
|
||||
*/
|
||||
/*global base*/
|
||||
var ServerType = {
|
||||
Bukkit: 'bukkit',
|
||||
Sponge: 'sponge'
|
||||
};
|
||||
var MServer;
|
||||
var DetectServerType = ServerType.Bukkit;
|
||||
try {
|
||||
MServer = Java.type("org.bukkit.Bukkit");
|
||||
DetectServerType = ServerType.Bukkit;
|
||||
} catch (ex) {
|
||||
// IGNORE
|
||||
}
|
||||
try {
|
||||
MServer = Java.type("org.spongepowered.api.Sponge");
|
||||
DetectServerType = ServerType.Sponge;
|
||||
} catch (ex) {
|
||||
// IGNORE
|
||||
}
|
||||
/**
|
||||
* 尝试加载特殊的Console类
|
||||
*/
|
||||
try {
|
||||
load(root + '/internal/' + DetectServerType + '/console.js');
|
||||
} catch (ex) {
|
||||
// IGNORE
|
||||
}
|
||||
global.console = new global.Console();
|
@ -1,39 +0,0 @@
|
||||
/*global Java, base, module, exports, require, __FILE__*/
|
||||
/**
|
||||
* 菜单基础扩展脚本
|
||||
* Created by 蒋天蓓 on 2017/2/8 0008.
|
||||
*/
|
||||
var ext = {};
|
||||
/**
|
||||
* 获得静态类
|
||||
* @param name 类名
|
||||
* @returns {*}
|
||||
*/
|
||||
ext.getStatic = function (name) {
|
||||
return base.getClass(name).static;
|
||||
};
|
||||
/**
|
||||
* 获得随机数
|
||||
* @param max 最大值
|
||||
* @param min 最小值
|
||||
*/
|
||||
ext.random = function (max, min) {
|
||||
min = min === undefined ? 0 : min;
|
||||
return Math.floor(Math.random() * (max - min) + min);
|
||||
};
|
||||
/**
|
||||
* 判断对象是否为Null
|
||||
* @param obj 对象
|
||||
* @returns {boolean} notNull返回True
|
||||
*/
|
||||
ext.notNull = function (obj) {
|
||||
return obj !== undefined && obj !== null;
|
||||
};
|
||||
/**
|
||||
* 判断对象是否为Null
|
||||
* @param obj 对象
|
||||
* @returns {boolean} Null返回True
|
||||
*/
|
||||
ext.isNull = function (obj) {
|
||||
return obj === undefined || obj === null;
|
||||
};
|
@ -1,158 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/*global Java, base, module, exports, require, __FILE__*/
|
||||
var File = Java.type("java.io.File");
|
||||
var Files = Java.type("java.nio.file.Files");
|
||||
var separatorChar = File.separatorChar;
|
||||
var StandardCopyOption = Java.type("java.nio.file.StandardCopyOption");
|
||||
var _toString = function (obj) {
|
||||
return Object.prototype.toString.call(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用文件分割符合并路径
|
||||
*/
|
||||
function concat() {
|
||||
return Array.prototype.join.call(arguments, separatorChar);
|
||||
};
|
||||
/**
|
||||
* 获得文件
|
||||
* @constructor(file)
|
||||
* @constructor(dir,file)
|
||||
* @returns {*}
|
||||
*/
|
||||
function file() {
|
||||
if (!arguments[0]) {
|
||||
console.warn("文件名称不得为 undefined 或者 null !");
|
||||
}
|
||||
switch (arguments.length) {
|
||||
case 1:
|
||||
var f = arguments[0]
|
||||
if (f instanceof File) {
|
||||
return f;
|
||||
}
|
||||
if (typeof f === "string") {
|
||||
return new File(f);
|
||||
}
|
||||
if (f instanceof Path) {
|
||||
return f.toFile();
|
||||
}
|
||||
case 2:
|
||||
return new File(exports.file(arguments[0]), arguments[1]);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 创建目录
|
||||
* @param file
|
||||
*/
|
||||
function mkdirs(path) {
|
||||
// noinspection JSUnresolvedVariable
|
||||
fs.file(path).parentFile.mkdirs();
|
||||
};
|
||||
/**
|
||||
* 创建文件
|
||||
* @param file
|
||||
*/
|
||||
function create(path) {
|
||||
var file = fs.file(path)
|
||||
if (!file.exists()) {
|
||||
mkdirs(file);
|
||||
file.createNewFile();
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 获得文件规范路径
|
||||
* @param file
|
||||
* @returns {*}
|
||||
*/
|
||||
function path(file) {
|
||||
// noinspection JSUnresolvedVariable
|
||||
return fs.file(file).canonicalPath;
|
||||
};
|
||||
/**
|
||||
* 复制文件
|
||||
* @param inputStream 输入流
|
||||
* @param target 目标文件
|
||||
* @param override 是否覆盖
|
||||
*/
|
||||
function copy(inputStream, target, override) {
|
||||
Files.copy(inputStream, target.toPath(), StandardCopyOption[override ? 'REPLACE_EXISTING' : 'ATOMIC_MOVE']);
|
||||
};
|
||||
/**
|
||||
* 读取文件
|
||||
* @param path 文件路径
|
||||
*/
|
||||
function read(path) {
|
||||
var file = fs.file(path);
|
||||
if (!file.exists()) {
|
||||
console.warn('读取文件', file, '错误 文件不存在!');
|
||||
return;
|
||||
}
|
||||
// noinspection JSPrimitiveTypeWrapperUsage
|
||||
return new java.lang.String(Files.readAllBytes(file.toPath()), "UTF-8");
|
||||
};
|
||||
/**
|
||||
* 保存内容文件
|
||||
* @param path 路径
|
||||
* @param content 内容
|
||||
* @param override 是否覆盖
|
||||
*/
|
||||
function save(path, content, override) {
|
||||
var file = fs.file(path);
|
||||
file.getParentFile().mkdirs();
|
||||
Files.write(file.toPath(), new java.lang.String(content).getBytes("UTF-8"));
|
||||
};
|
||||
/**
|
||||
* 列出目录文件
|
||||
* @param path
|
||||
*/
|
||||
function list(path) {
|
||||
var dir = file(path);
|
||||
if (dir.isDirectory()) {
|
||||
return Files.list(dir.toPath());
|
||||
}
|
||||
console.debug('路径', path, '不是一个目录 返回空数组!');
|
||||
return [];
|
||||
};
|
||||
/**
|
||||
* 移动文件
|
||||
* @param src 原始目录
|
||||
* @param des 目标目录
|
||||
* @param override 是否覆盖
|
||||
*/
|
||||
function move(src, des, override) {
|
||||
Files.move(fs.file(src).toPath(), fs.file(des).toPath(),
|
||||
override ? StandardCopyOption['REPLACE_EXISTING'] : StandardCopyOption['ATOMIC_MOVE'])
|
||||
};
|
||||
|
||||
function del(file) {
|
||||
file = fs.file(file);
|
||||
if (!file.exists()) { return; }
|
||||
if (file.isDirectory()) {
|
||||
Files.list(file.toPath()).collect(Collectors.toList()).forEach(function (f) { del(f); })
|
||||
}
|
||||
Files.delete(file.toPath());
|
||||
}
|
||||
|
||||
function exists(file) {
|
||||
return fs.file(file).exists()
|
||||
}
|
||||
|
||||
var fs = {};
|
||||
|
||||
fs.path = fs.canonical = fs.realpath = path
|
||||
fs.write = fs.save = save
|
||||
fs.readdir = fs.list = list
|
||||
fs.rename = fs.move = move
|
||||
fs.delete = fs.del = del
|
||||
|
||||
Object.assign(fs, {
|
||||
concat: concat,
|
||||
create: create,
|
||||
mkdirs: mkdirs,
|
||||
file: file,
|
||||
copy: copy,
|
||||
read: read
|
||||
})
|
||||
|
||||
exports = module.exports = fs
|
@ -1,107 +0,0 @@
|
||||
'use strict';
|
||||
/*global base*/
|
||||
|
||||
(function (global) {
|
||||
// noinspection JSUnusedLocalSymbols
|
||||
global.init = function init(root) {
|
||||
global.root = root;
|
||||
global.noop = function () {
|
||||
};
|
||||
loadCore();
|
||||
loadPatch();
|
||||
loadRequire();
|
||||
try {
|
||||
loadServerLib();
|
||||
loadPlugins();
|
||||
} catch (ex) {
|
||||
console.console("§4初始化插件基础系统库错误:§c", ex);
|
||||
console.ex(ex);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 初始化核心
|
||||
*/
|
||||
function loadCore() {
|
||||
// 加载基础模块
|
||||
load(root + '/core/ext.js');
|
||||
// 加载Console
|
||||
load(root + '/core/console.js');
|
||||
// 探测服务器类型
|
||||
load(root + '/core/detect.js');
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化模块
|
||||
*/
|
||||
function loadRequire() {
|
||||
global.engineLoad = load;
|
||||
global.load = function __denyGlobalLoad__() {
|
||||
throw new Error('系统内部不许允许使用 load 如需执行脚本 请使用 engineLoad !');
|
||||
}
|
||||
// 初始化加载器
|
||||
global.require = engineLoad(root + '/core/require.js')(root);
|
||||
global.requireInternal = function requireInternal(name) {
|
||||
return require(root + '/internal/' + DetectServerType + '/' + name + '.js', arguments[1]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载补丁
|
||||
*/
|
||||
function loadPatch() {
|
||||
java.nio.file.Files.list(new java.io.File(root, 'core/patch').toPath()).forEach(function (path) {
|
||||
console.log('加载扩展类库', path);
|
||||
try {
|
||||
load(path.toFile());
|
||||
} catch (ex) {
|
||||
console.ex(ex);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载系统类库
|
||||
*/
|
||||
function loadServerLib() {
|
||||
var task = require('api/task');
|
||||
global.setTimeout = function setTimeout(func, time, _async) {
|
||||
return _async ? task.laterAsync(func, time) : task.later(func, time);
|
||||
};
|
||||
global.clearTimeout = function clearTimeout(task) {
|
||||
task.cancel();
|
||||
};
|
||||
global.setInterval = function setInterval(func, time, _async) {
|
||||
return _async ? task.timerAsync(func, time) : task.timer(func, time);
|
||||
};
|
||||
global.clearInterval = function clearInterval(task) {
|
||||
task.cancel();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载JS插件
|
||||
*/
|
||||
function loadPlugins() {
|
||||
// 初始化本体插件
|
||||
global.manager = require('api/plugin');
|
||||
if (global.manager && global.manager.$) {
|
||||
global.manager.init('plugins');
|
||||
// 只有当在正式环境运行的时候才加载
|
||||
global.manager.load();
|
||||
global.manager.enable();
|
||||
} else {
|
||||
console.console('§4当前服务器不支持使用MiaoScript插件系统!');
|
||||
}
|
||||
}
|
||||
|
||||
// noinspection JSUnusedLocalSymbols
|
||||
/**
|
||||
* 关闭插件Hook
|
||||
*/
|
||||
global.engineDisable = function disable() {
|
||||
if (global.manager && global.manager.$) {
|
||||
global.manager.disable();
|
||||
}
|
||||
}
|
||||
})(global);
|
@ -1,18 +0,0 @@
|
||||
/**
|
||||
* 补丁和方法扩展
|
||||
*/
|
||||
(function () {
|
||||
if (!Array.prototype.copyPartialMatches) {
|
||||
Object.defineProperty(Array.prototype, "copyPartialMatches", {
|
||||
enumerable: false,
|
||||
value: function (token, array) {
|
||||
this.forEach(function (e) {
|
||||
if (e.toLowerCase().startsWith(token.toLowerCase())) {
|
||||
array.push(e)
|
||||
}
|
||||
})
|
||||
return array
|
||||
}
|
||||
});
|
||||
}
|
||||
})();
|
@ -1,30 +0,0 @@
|
||||
/**
|
||||
* 补丁和方法扩展
|
||||
*/
|
||||
|
||||
(function () {
|
||||
/**
|
||||
* 日期格式化
|
||||
* 例: new Date().format('yyyy-MM-dd hh:mm:ss.s') => "2017-08-24 16:15:40.693"
|
||||
* @param fmt 格式化字符串
|
||||
* @returns {*}
|
||||
*/
|
||||
Date.prototype.format = function (fmt) { //author: meizz
|
||||
var o = {
|
||||
"M+": this.getMonth() + 1, //月份
|
||||
"d+": this.getDate(), //日
|
||||
"h+": this.getHours(), //小时
|
||||
"m+": this.getMinutes(), //分
|
||||
"s+": this.getSeconds(), //秒
|
||||
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
|
||||
"S": this.getMilliseconds() //毫秒
|
||||
};
|
||||
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
|
||||
for (var k in o) {
|
||||
if (new RegExp("(" + k + ")").test(fmt)) {
|
||||
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? o[k] : (("00" + o[k]).substr(("" + o[k]).length)));
|
||||
}
|
||||
}
|
||||
return fmt;
|
||||
};
|
||||
})();
|
@ -1,71 +0,0 @@
|
||||
/**
|
||||
* 补丁和方法扩展
|
||||
*/
|
||||
|
||||
(function () {
|
||||
// Object.assign Polyfill
|
||||
if (!Object.assign) {
|
||||
Object.defineProperty(Object, "assign", {
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: function(target) {
|
||||
"use strict";
|
||||
if (target === undefined || target === null)
|
||||
throw new TypeError("Cannot convert first argument to object");
|
||||
var to = Object(target);
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
var nextSource = arguments[i];
|
||||
if (nextSource === undefined || nextSource === null) continue;
|
||||
var keysArray = Object.keys(Object(nextSource));
|
||||
for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
|
||||
var nextKey = keysArray[nextIndex];
|
||||
var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
|
||||
if (desc !== undefined && desc.enumerable) to[nextKey] = nextSource[nextKey];
|
||||
}
|
||||
}
|
||||
return to;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!Object.values) {
|
||||
Object.defineProperty(Object, "values", {
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: function(target) {
|
||||
"use strict";
|
||||
var vals = [];
|
||||
for (var key in target) {
|
||||
var desc = Object.getOwnPropertyDescriptor(target, key);
|
||||
if (desc !== undefined && desc.enumerable) vals.push(target[key]);
|
||||
}
|
||||
return vals;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// JSON快捷方法
|
||||
if(!Object.toJson){
|
||||
Object.defineProperty(Object.prototype, "toJson", {
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: function() {
|
||||
return JSON.stringify(this);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Object.prototype.toJson = function () {
|
||||
// return JSON.stringify(this);
|
||||
// };
|
||||
|
||||
// // YAML快速生成
|
||||
// var yaml = require('modules/yaml');
|
||||
// Object.prototype.toYaml = function () {
|
||||
// return yaml.safeDump(this);
|
||||
// };
|
||||
})();
|
@ -1,11 +0,0 @@
|
||||
/**
|
||||
* 补丁和方法扩展
|
||||
*/
|
||||
|
||||
(function () {
|
||||
// Java格式化方法
|
||||
var str = Java.type('java.lang.String');
|
||||
String.prototype.format = function () {
|
||||
return str.format(this, Array.prototype.slice.call(arguments, 0))
|
||||
};
|
||||
})();
|
21
src/main/resources/core/ployfill.js
Normal file
21
src/main/resources/core/ployfill.js
Normal file
@ -0,0 +1,21 @@
|
||||
(
|
||||
/**
|
||||
* @param {string} root
|
||||
* @param {any} logger
|
||||
*/
|
||||
function(root, logger) {
|
||||
// Init Global Value
|
||||
global.root = root;
|
||||
global.logger = logger;
|
||||
global.NashornEngineStartTime = new Date().getTime()
|
||||
global.engineLoad = load;
|
||||
global.noop = global.engineDisable = engineDisable = function() { };
|
||||
global.load = load = function __PreventGlobalLoadFunction__() { throw new Error('Internal engine system not allow use `load` function!'); }
|
||||
global.setGlobal = function(key, value) { global[key] = value; };
|
||||
// Init console and require
|
||||
global.console = engineLoad(global.root + '/core/console.js')(logger);
|
||||
console.log("Loading Engine at Thread", java.lang.Thread.currentThread().name)
|
||||
global.require = engineLoad(global.root + '/core/require.js')(root);
|
||||
require('@ms/ployfill')
|
||||
}
|
||||
);
|
@ -9,7 +9,7 @@
|
||||
* 2. 如果模块以 `./` `../` 开头
|
||||
* a. 尝试使用 resolveAsFile(dir/xx) 加载文件
|
||||
* b. 尝试使用 resolveAsDirectory(dir/xx) 加载目录
|
||||
* 3. 尝试去 root root/core root/modules => xx 加载模块
|
||||
* 3. 尝试去 root root/node_modules => xx 加载模块
|
||||
* a. 尝试使用 resolveAsFile(xx/xx) 加载文件
|
||||
* b. 尝试使用 resolveAsDirectory(xx/xx) 加载目录
|
||||
* 4. 抛出 not found 异常
|
||||
@ -23,247 +23,372 @@
|
||||
* 2. 如果 xx/index.js 存在 则使用 resolveAsFile(xx/index.js) 加载
|
||||
* 3. 如果 xx/index.json 存在 则使用 `xx/index.json` 解析为对象加载 并停止执行
|
||||
* 暂不支持 4. 如果 xx/index.msm 是一个文件 则使用MScript解析器解析 并停止执行
|
||||
* 注: MiaoScript 暂不支持多层 modules 加载 暂时不需要(估计以后也不会需要)
|
||||
*/
|
||||
/*global Java, base*/
|
||||
(function (parent) {
|
||||
'use strict';
|
||||
var File = Java.type("java.io.File");
|
||||
var separatorChar = File.separatorChar;
|
||||
var cacheDir = parent + separatorChar + "runtime";
|
||||
var paths = [parent, parent + separatorChar + 'core', parent + separatorChar + 'api', parent + separatorChar + 'modules'];
|
||||
|
||||
try{
|
||||
base.delete(cacheDir);
|
||||
} catch (ex) {
|
||||
console.ex(ex);
|
||||
}
|
||||
|
||||
// @ts-check
|
||||
/// <reference types="@ms/nashorn" />
|
||||
(
|
||||
/**
|
||||
* 判断是否为一个文件
|
||||
* @param file
|
||||
* @returns {*}
|
||||
* @private
|
||||
* @param {any} parent
|
||||
*/
|
||||
function _isFile(file) {
|
||||
return file.isFile && file.isFile();
|
||||
}
|
||||
function(parent) {
|
||||
'use strict';
|
||||
var File = Java.type('java.io.File');
|
||||
var Paths = Java.type('java.nio.file.Paths');
|
||||
var Files = Java.type('java.nio.file.Files');
|
||||
var StandardCopyOption = Java.type('java.nio.file.StandardCopyOption');
|
||||
var FileNotFoundException = Java.type('java.io.FileNotFoundException');
|
||||
|
||||
/**
|
||||
* 获得文件规范路径
|
||||
* @param file
|
||||
* @returns {*}
|
||||
* @private
|
||||
*/
|
||||
function _canonical(file) {
|
||||
// noinspection JSUnresolvedVariable
|
||||
return file.canonicalPath;
|
||||
}
|
||||
var TarInputStream = Java.type('org.kamranzafar.jtar.TarInputStream');
|
||||
var GZIPInputStream = Java.type('java.util.zip.GZIPInputStream');
|
||||
var BufferedInputStream = Java.type('java.io.BufferedInputStream');
|
||||
|
||||
/**
|
||||
* 获得缓存的文件名称
|
||||
* @param file
|
||||
* @returns {string}
|
||||
* @private
|
||||
*/
|
||||
function _cacheFile(file) {
|
||||
return _canonical(file).replace(parent, cacheDir);
|
||||
}
|
||||
var URL = Java.type('java.net.URL')
|
||||
var JavaString = Java.type('java.lang.String')
|
||||
var separatorChar = File.separatorChar;
|
||||
|
||||
/**
|
||||
* 解析模块名称为文件
|
||||
* 按照下列顺序查找
|
||||
* 当前目录 ./
|
||||
* 父目录 ../
|
||||
* 核心目录 /core
|
||||
* 模块目录 /modules
|
||||
* @param name 模块名称
|
||||
* @param parent 父目录
|
||||
*/
|
||||
function resolve(name, parent) {
|
||||
name = _canonical(name) || name;
|
||||
// 解析本地目录
|
||||
if (name.startsWith('./') || name.startsWith('../')) {
|
||||
return resolveAsFile(parent, name) || resolveAsDirectory(parent, name) || undefined;
|
||||
} else {
|
||||
// 查找可能存在的路径
|
||||
for (var i in paths) {
|
||||
var path = paths[i];
|
||||
var result = resolveAsFile(path, name) || resolveAsDirectory(path, name);
|
||||
if (result) {
|
||||
return result;
|
||||
var CoreModules = ['assert', 'async_hooks', 'child_process', 'cluster', 'crypto', 'dns', 'domain', 'events', 'fs', 'http', 'http2', 'https', 'inspector', 'net', 'os', 'path', 'vm', 'url', 'util', 'zlib', 'worker_threads']
|
||||
|
||||
/**
|
||||
* @param {...object} t
|
||||
*/
|
||||
function __assign(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
if (s === undefined) { continue; };
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
|
||||
/**
|
||||
* 判断是否为一个文件
|
||||
* @param {any} file
|
||||
* @returns {*}
|
||||
*/
|
||||
function _isFile(file) {
|
||||
return file.isFile && file.isFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得文件规范路径
|
||||
* @param {any} file
|
||||
* @returns {*}
|
||||
*/
|
||||
function _canonical(file) {
|
||||
return file.canonicalPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得文件绝对路径
|
||||
* @param {any} file
|
||||
* @returns {*}
|
||||
*/
|
||||
function _absolute(file) {
|
||||
return file.absolutePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析模块名称为文件
|
||||
* 按照下列顺序查找
|
||||
* 当前目录 ./
|
||||
* 父目录 ../
|
||||
* 模块目录 /node_modules
|
||||
* @param {string} name 模块名称
|
||||
* @param {string} parent 父目录
|
||||
*/
|
||||
function resolve(name, parent) {
|
||||
name = _canonical(name) || name;
|
||||
// 解析本地目录
|
||||
if (name.startsWith('./') || name.startsWith('../')) {
|
||||
return resolveAsFile(name, parent) || resolveAsDirectory(name, parent) || undefined;
|
||||
} else {
|
||||
// 解析Node目录
|
||||
var dir = [parent, 'node_modules'].join(separatorChar);
|
||||
if (cacheModuleIds[name]) return cacheModuleIds[name]
|
||||
cacheModuleIds[name] = resolveAsFile(name, dir) || resolveAsDirectory(name, dir) ||
|
||||
// @ts-ignore
|
||||
(parent && parent.toString().startsWith(root) ? resolve(name, new File(parent).getParent()) : undefined);
|
||||
return cacheModuleIds[name];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析文件
|
||||
* @param {string} file 文件
|
||||
* @param {string | undefined} dir 目录
|
||||
* @returns {*}
|
||||
*/
|
||||
function resolveAsFile(file, dir) {
|
||||
file = dir != undefined ? new File(dir, file) : new File(file);
|
||||
// 直接文件
|
||||
// @ts-ignore
|
||||
if (file.isFile()) {
|
||||
return file;
|
||||
}
|
||||
// JS文件
|
||||
var js = new File(normalizeName(_absolute(file), '.js'));
|
||||
if (js.isFile()) {
|
||||
return js;
|
||||
}
|
||||
// JSON文件
|
||||
var json = new File(normalizeName(_absolute(file), '.json'));
|
||||
if (json.isFile()) {
|
||||
return json;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析目录
|
||||
* @param {string} file 文件
|
||||
* @param {string | undefined} dir 目录
|
||||
* @returns {*}
|
||||
*/
|
||||
function resolveAsDirectory(file, dir) {
|
||||
dir = dir != undefined ? new File(dir, file) : new File(file);
|
||||
var _package = new File(dir, 'package.json');
|
||||
if (_package.exists()) {
|
||||
// @ts-ignore
|
||||
var json = JSON.parse(base.read(_package));
|
||||
if (json.main) {
|
||||
return resolveAsFile(json.main, dir);
|
||||
}
|
||||
}
|
||||
// if no package or package.main exists, look for index.js
|
||||
return resolveAsFile('index.js', dir);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析文件
|
||||
* @returns {*}
|
||||
*/
|
||||
function resolveAsFile(dir, file) {
|
||||
file = ext.notNull(dir) ? new File(dir, file) : new File(file);
|
||||
// 直接文件
|
||||
if (file.isFile()) {
|
||||
return file;
|
||||
}
|
||||
// JS文件
|
||||
var js = new File(normalizeName(_canonical(file), ".js"));
|
||||
if (js.isFile()) {
|
||||
return js;
|
||||
}
|
||||
// JSON文件
|
||||
var json = new File(normalizeName(_canonical(file), ".json"));
|
||||
if (json.isFile()) {
|
||||
return json;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析目录
|
||||
* @returns {*}
|
||||
*/
|
||||
function resolveAsDirectory(dir, file) {
|
||||
dir = ext.notNull(dir) ? new File(dir, file) : new File(file);
|
||||
var _package = new File(dir, 'package.json');
|
||||
if (_package.exists()) {
|
||||
var json = JSON.parse(base.read(_package));
|
||||
if (json.main) {
|
||||
return resolveAsFile(dir, json.main);
|
||||
/**
|
||||
* 后缀检测和添加
|
||||
* @param {string} fileName 文件名称
|
||||
* @param {string} ext 后缀
|
||||
* @returns {*}
|
||||
*/
|
||||
function normalizeName(fileName, ext) {
|
||||
var extension = ext || '.js';
|
||||
if (fileName.endsWith(extension)) {
|
||||
return fileName;
|
||||
}
|
||||
return fileName + extension;
|
||||
}
|
||||
// if no package or package.main exists, look for index.js
|
||||
return resolveAsFile(dir, 'index.js');
|
||||
}
|
||||
|
||||
/**
|
||||
* 后缀检测和添加
|
||||
* @param fileName 文件名称
|
||||
* @param ext 后缀
|
||||
* @returns {*}
|
||||
*/
|
||||
function normalizeName(fileName, ext) {
|
||||
var extension = ext || '.js';
|
||||
if (fileName.endsWith(extension)) {
|
||||
return fileName;
|
||||
/**
|
||||
* 检查模块缓存
|
||||
* @param {string} id 模块ID
|
||||
* @param {string} name 模块名称
|
||||
* @param {any} file 模块文件
|
||||
* @param {any} optional 附加选项
|
||||
* @returns {Object}
|
||||
*/
|
||||
function getCacheModule(id, name, file, optional) {
|
||||
var module = cacheModules[id];
|
||||
if (optional.cache && module) {
|
||||
return module;
|
||||
}
|
||||
return createModule(id, name, file, optional)
|
||||
}
|
||||
return fileName + extension;
|
||||
}
|
||||
|
||||
/**
|
||||
* 编译模块
|
||||
* @param id 模块ID
|
||||
* @param name 模块名称
|
||||
* @param file 模块文件
|
||||
* @param optional 附加选项
|
||||
* @returns {Object}
|
||||
*/
|
||||
function getCacheModule(id, name, file, optional) {
|
||||
var module = cacheModules[id];
|
||||
if (optional.cache && module) {
|
||||
/**
|
||||
* 编译模块
|
||||
* @param {string} id 模块ID
|
||||
* @param {string} name 模块名称
|
||||
* @param {any} file 模块文件
|
||||
* @param {any} optional 附加选项
|
||||
* @returns {Object}
|
||||
*/
|
||||
function createModule(id, name, file, optional) {
|
||||
console.trace('Loading module', name + '(' + id + ')', 'Optional', JSON.stringify(optional));
|
||||
var module = {
|
||||
id: id,
|
||||
exports: {},
|
||||
loaded: false,
|
||||
require: getRequire(file.parentFile, id)
|
||||
};
|
||||
cacheModules[id] = module;
|
||||
var cfile = _canonical(file);
|
||||
if (cfile.endsWith('.js')) {
|
||||
compileJs(module, file, optional);
|
||||
} else if (cfile.endsWith('.json')) {
|
||||
compileJson(module, file);
|
||||
} else if (cfile.endsWith('.msm')) {
|
||||
throw Error('Unsupported MiaoScript module!');
|
||||
} else {
|
||||
throw Error('Unknown file type ' + cfile);
|
||||
}
|
||||
return module;
|
||||
}
|
||||
console.debug('加载模块', name, '位于', id, 'Optional', JSON.stringify(optional));
|
||||
// noinspection JSUnresolvedVariable
|
||||
module = {
|
||||
id: id,
|
||||
exports: {},
|
||||
loaded: false,
|
||||
require: exports(file.parentFile)
|
||||
};
|
||||
cacheModules[id] = module;
|
||||
try {
|
||||
if (_canonical(file).endsWith('.js')) {
|
||||
compileJs(module, file, optional);
|
||||
|
||||
/**
|
||||
* 预编译JS
|
||||
* @param {any} module JS模块
|
||||
* @param {any} file JS文件
|
||||
* @param {any} optional 附加选项
|
||||
* @returns {void}
|
||||
*/
|
||||
function compileJs(module, file, optional) {
|
||||
// @ts-ignore
|
||||
var origin = base.read(file);
|
||||
if (optional.hook) {
|
||||
origin = optional.hook(origin);
|
||||
}
|
||||
if (_canonical(file).endsWith('.json')) {
|
||||
compileJson(module, file, optional);
|
||||
// 2019-09-19 使用 扩展函数直接 load 无需保存/删除文件
|
||||
// 2020-02-16 结尾新增换行 防止有注释导致加载失败
|
||||
// @ts-ignore
|
||||
var compiledWrapper = engineLoad({ script: '(function $(module, exports, require, __dirname, __filename) {' + origin + '\n});', name: file });
|
||||
compiledWrapper.apply(module.exports, [
|
||||
module, module.exports, module.require, file.parentFile, file
|
||||
]);
|
||||
module.loaded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 预编译Json
|
||||
* @param {{ id?: string | null; exports?: {}; loaded: any; require?: any; }} module Json模块
|
||||
* @param {any} file Json 文件
|
||||
* @returns {void}
|
||||
*/
|
||||
function compileJson(module, file) {
|
||||
// @ts-ignore
|
||||
module.exports = JSON.parse(base.read(file));
|
||||
module.loaded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 尝试从网络下载依赖包
|
||||
* @param {string} name 包名称
|
||||
*/
|
||||
function download(name) {
|
||||
// handle name es6-map/implement => es6-map @ms/common/dist/reflect => @ms/common
|
||||
var name_arr = name.split('/');
|
||||
var module_name = name.startsWith('@') ? name_arr[0] + '/' + name_arr[1] : name_arr[0];
|
||||
// at windows need replace file name java.lang.IllegalArgumentException: Invalid prefix or suffix
|
||||
var tempFile = Files.createTempFile(module_name.replace('/', '_'), '.json');
|
||||
var info = fetchPackageInfo(module_name, tempFile);
|
||||
var url = info.versions[info['dist-tags']['latest']].dist.tarball;
|
||||
console.log('fetch node_module ' + module_name + ' from ' + url + ' waiting...')
|
||||
var tis = new TarInputStream(new BufferedInputStream(new GZIPInputStream(new URL(url).openStream())));
|
||||
// @ts-ignore
|
||||
var entry; var target = root + separatorChar + 'node_modules' + separatorChar + module_name;
|
||||
while ((entry = tis.getNextEntry()) != null) {
|
||||
var targetPath = Paths.get(target + separatorChar + entry.getName().substring(8));
|
||||
targetPath.toFile().getParentFile().mkdirs();
|
||||
Files.copy(tis, targetPath, StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
if (_canonical(file).endsWith('.msm')) {
|
||||
throw Error("暂不支持解析 MiaoScript 模块");
|
||||
return name;
|
||||
}
|
||||
|
||||
function fetchPackageInfo(module_name, tempFile) {
|
||||
try {
|
||||
Files.copy(new URL('https://registry.npm.taobao.org/' + module_name).openStream(), tempFile, StandardCopyOption.REPLACE_EXISTING);
|
||||
} catch (ex) {
|
||||
console.debug('can\'t fetch package ' + module_name + ' from taobao registry. try fetch from yumc registry...')
|
||||
Files.copy(new URL('https://repo.yumc.pw/repository/npm/' + module_name).openStream(), tempFile, StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
} catch (ex) {
|
||||
console.console('§4警告! §c模块§a', name, '§c编译失败! §4ERR:', ex);
|
||||
console.ex(ex);
|
||||
tempFile.toFile().deleteOnExit();
|
||||
return JSON.parse(new JavaString(Files.readAllBytes(tempFile), 'UTF-8'));
|
||||
}
|
||||
return module;
|
||||
}
|
||||
|
||||
/**
|
||||
* 预编译JS
|
||||
* @param file JS文件
|
||||
* @param optional 附加选项
|
||||
* @returns {Object}
|
||||
*/
|
||||
function compileJs(module, file, optional) {
|
||||
var cacheFile = _cacheFile(file);
|
||||
var origin = base.read(file);
|
||||
if (optional.hook) {
|
||||
origin = optional.hook(origin);
|
||||
}
|
||||
base.save(cacheFile, "(function __init__(module, exports, require, __dirname, __filename) {" + origin + "});");
|
||||
// 使用 load 可以保留行号和文件名称
|
||||
var compiledWrapper = engineLoad(cacheFile);
|
||||
try {
|
||||
base.delete(cacheFile);
|
||||
} catch (ex) {
|
||||
cacheFile.deleteOnExit();
|
||||
}
|
||||
compiledWrapper.apply(module.exports, [
|
||||
module, module.exports, module.require, file.parentFile, file
|
||||
]);
|
||||
module.loaded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 预编译Json
|
||||
* @param file Json 文件
|
||||
* @param optional 附加选项
|
||||
* @returns {Object}
|
||||
*/
|
||||
function compileJson(module, file, optional) {
|
||||
module.exports = JSON.parse(base.read(file));
|
||||
module.loaded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载模块
|
||||
* @param name 模块名称
|
||||
* @param path 路径
|
||||
* @param optional 附加选项
|
||||
* @returns {*}
|
||||
* @private
|
||||
*/
|
||||
function _require(name, path, optional) {
|
||||
var file = new File(name);
|
||||
file = _isFile(file) ? file : resolve(name, path);
|
||||
optional = Object.assign({cache: true, warnNotFound: true}, optional);
|
||||
if (file === undefined) {
|
||||
if (optional.warnNotFound) {
|
||||
console.console('§c目录§b', path, '§c下模块§a', name, '§c加载失败! §4未找到该模块!');
|
||||
/**
|
||||
* 检查核心模块
|
||||
* @param {string} name
|
||||
*/
|
||||
function checkCoreModule(name) {
|
||||
if (CoreModules.indexOf(name) != -1) {
|
||||
throw new Error("Can't load nodejs core module " + name + " . maybe later will auto replace to @ms/" + name + ' to compatible...')
|
||||
}
|
||||
return {exports: {}};
|
||||
}
|
||||
// 重定向文件名称和类型
|
||||
return getCacheModule(_canonical(file), file.name.split(".")[0], file, optional);
|
||||
}
|
||||
|
||||
/**
|
||||
* 闭包方法
|
||||
* @param parent 父目录
|
||||
* @returns {Function}
|
||||
*/
|
||||
function exports(parent) {
|
||||
return function (path, optional) {
|
||||
return _require(path, parent, optional).exports;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* 加载模块
|
||||
* @param {string} name 模块名称
|
||||
* @param {string} path 路径
|
||||
* @param {any} optional 附加选项
|
||||
* @returns {*}
|
||||
*/
|
||||
function _require(name, path, optional) {
|
||||
checkCoreModule(name);
|
||||
var file = new File(name);
|
||||
file = _isFile(file) ? file : resolve(name, path);
|
||||
optional = __assign({ cache: true }, optional);
|
||||
if (file === undefined) {
|
||||
try {
|
||||
// excloud local dir, prevent too many recursive call and cache not found module
|
||||
if (name.startsWith('.') || name.startsWith('/') || optional.recursive || notFoundModules[name]) {
|
||||
console.log(name, path, optional, notFoundModules[name])
|
||||
throw new Error("Can't found module " + name + '(' + JSON.stringify(optional) + ') at local ' + path + ' or network!')
|
||||
}
|
||||
optional.recursive = true;
|
||||
return _require(download(name), path, optional);
|
||||
} catch (ex) {
|
||||
notFoundModules[name] = true;
|
||||
throw new FileNotFoundException("Can't found module " + name + ' in directory ' + path + ' ERROR: ' + ex)
|
||||
}
|
||||
}
|
||||
// 重定向文件名称和类型
|
||||
return getCacheModule(_canonical(file), file.name.split('.')[0], file, optional);
|
||||
}
|
||||
|
||||
if (typeof parent === "string") {
|
||||
parent = new File(parent);
|
||||
}
|
||||
var cacheModules = [];
|
||||
console.debug("初始化 require 模块组件 父目录 ", _canonical(parent));
|
||||
return exports(parent);
|
||||
});
|
||||
/**
|
||||
* 闭包方法
|
||||
* @param {string} parent 父目录
|
||||
* @param {string} parentId
|
||||
* @returns {Function}
|
||||
*/
|
||||
function exports(parent, parentId) {
|
||||
var __DynamicRequire__ =
|
||||
/**
|
||||
* @param {string} path
|
||||
* @param {any} optional
|
||||
*/
|
||||
function __DynamicRequire__(path, optional) {
|
||||
return _require(path, parent, __assign({ parentId: parentId }, optional)).exports;
|
||||
}
|
||||
return __DynamicRequire__
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} parent
|
||||
* @param {string} parentId
|
||||
*/
|
||||
function getRequire(parent, parentId) {
|
||||
/**
|
||||
* @type {any} require
|
||||
*/
|
||||
var require = exports(parent, parentId)
|
||||
require.resolve =
|
||||
/**
|
||||
* @param {string} name
|
||||
*/
|
||||
function __DynamicResolve__(name) {
|
||||
return _canonical(new File(resolve(name, parent)))
|
||||
}
|
||||
require.clear =
|
||||
/**
|
||||
* @param {string} name
|
||||
*/
|
||||
function __DynamicClear__(name) {
|
||||
var moduleId = require.resolve(name)
|
||||
console.trace('Clear module ' + name + '(' + moduleId + ') ...')
|
||||
return delete cacheModules[moduleId]
|
||||
}
|
||||
return require;
|
||||
}
|
||||
|
||||
if (typeof parent === 'string') {
|
||||
parent = new File(parent);
|
||||
}
|
||||
/**
|
||||
* @type {{[key:string]:any}} cacheModules
|
||||
*/
|
||||
var cacheModules = {};
|
||||
/**
|
||||
* @type {{[key:string]:string}} cacheModules
|
||||
*/
|
||||
var cacheModuleIds = {};
|
||||
/**
|
||||
* @type {{[key:string]:boolean}} cacheModules
|
||||
*/
|
||||
var notFoundModules = {};
|
||||
console.info('Initialization require module. ParentDir:', _canonical(parent));
|
||||
return getRequire(parent, "null");
|
||||
});
|
||||
|
@ -13,6 +13,7 @@ var fs = require('fs');
|
||||
var description = {
|
||||
name: 'HelloWorld',
|
||||
version: '1.0',
|
||||
author: 'MiaoWoo',
|
||||
commands: {
|
||||
'hello': {
|
||||
description: 'HelloWorld主命令'
|
||||
@ -25,8 +26,9 @@ function load() {
|
||||
}
|
||||
|
||||
function enable() {
|
||||
// noinspection JSUnusedLocalSymbols
|
||||
command.on(this, 'hello', {
|
||||
cmd: function (sender, command, args) {
|
||||
cmd: function(sender, command, args) {
|
||||
engineLoad(fs.file(root, 'test.js'));
|
||||
return true;
|
||||
}
|
||||
@ -34,23 +36,22 @@ function enable() {
|
||||
console.log('启用 Hello World 测试插件!');
|
||||
switch (DetectServerType) {
|
||||
case ServerType.Bukkit:
|
||||
event.on(this, 'playerloginevent', function join(event) {
|
||||
event.on(this, 'PlayerLoginEvent', function join(event) {
|
||||
send(event, wrapper.player(event.player));
|
||||
});
|
||||
break;
|
||||
case ServerType.Sponge:
|
||||
// clientconnectionevent.join
|
||||
event.on(this, 'clientconnectionevent.join', function join(event) {
|
||||
event.on(this, 'ClientConnectionEvent.Join', function join(event) {
|
||||
send(event, wrapper.player(event.targetEntity));
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function send(event, player){
|
||||
function send(event, player) {
|
||||
// noinspection JSUnresolvedVariable
|
||||
console.debug('玩家', player.getName(), "触发事件", event.class.simpleName);
|
||||
setTimeout(function () {
|
||||
setTimeout(function() {
|
||||
// noinspection JSUnresolvedVariable
|
||||
player.sendMessage("§a欢迎来到 §bMiaoScript §a的世界! 当前在线: " + server.players().length)
|
||||
}, 10);
|
@ -1,7 +1,5 @@
|
||||
'use strict';
|
||||
/*global Java, base, module, exports, require*/
|
||||
|
||||
var server = require('api/server');
|
||||
var event = require('api/event');
|
||||
var task = require('api/task');
|
||||
var http = require('http');
|
||||
@ -12,14 +10,14 @@ var Keys;
|
||||
var description = {
|
||||
name: 'ItemTag',
|
||||
version: '1.0',
|
||||
author: '喵♂呜'
|
||||
author: 'MiaoWoo'
|
||||
};
|
||||
|
||||
var itemConfig;
|
||||
|
||||
function load() {
|
||||
var itemFile = self.file('item.yml');
|
||||
task.async(function () {
|
||||
task.async(function() {
|
||||
if (!itemFile.exists()) {
|
||||
fs.save(itemFile, http.get('https://data.yumc.pw/config/Item_zh_CN.yml'))
|
||||
}
|
||||
@ -30,41 +28,43 @@ function load() {
|
||||
function enable() {
|
||||
switch (DetectServerType) {
|
||||
case ServerType.Bukkit:
|
||||
event.on(self, 'ItemMergeEvent', function (event) {
|
||||
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) {
|
||||
});
|
||||
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) {
|
||||
event.on(self, 'ItemMergeItemEvent', function(event) {
|
||||
// Sponge 暂未实现当前事件
|
||||
})
|
||||
event.on(self, 'SpawnEntityEvent', function (event) {
|
||||
event.entities.forEach(function (entity) {
|
||||
});
|
||||
event.on(self, 'SpawnEntityEvent', function(event) {
|
||||
event.entities.forEach(function(entity) {
|
||||
if (entity.type.name === "item") sponge(entity);
|
||||
})
|
||||
})
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function bukkit(item , amount) {
|
||||
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);
|
||||
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);
|
||||
entity.offer(Keys['DISPLAY_NAME'], org.spongepowered.api.text.Text.of(itemName));
|
||||
entity.offer(Keys['CUSTOM_NAME_VISIBLE'], true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,8 +72,12 @@ function getItemName(name) {
|
||||
return itemConfig[(name + '').toUpperCase()] || name;
|
||||
}
|
||||
|
||||
function getItemCount(amount){
|
||||
return amount == 1 ? "" : "*" + amount;
|
||||
function getItemCount(amount) {
|
||||
return amount === 1 ? "" : "*" + amount;
|
||||
}
|
||||
|
||||
function disable() {
|
||||
console.log('卸载', description.name, '插件!');
|
||||
}
|
||||
|
||||
module.exports = {
|
70
src/main/resources/dev-plugins/MiaoAuth.js
Normal file
70
src/main/resources/dev-plugins/MiaoAuth.js
Normal file
@ -0,0 +1,70 @@
|
||||
'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
|
||||
};
|
@ -5,18 +5,18 @@
|
||||
/*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 tellraw = require('tellraw');
|
||||
var utils = require('utils')
|
||||
var papi = require('papi');
|
||||
var utils = require('utils');
|
||||
|
||||
var Player;
|
||||
|
||||
var description = {
|
||||
name: 'MiaoChat',
|
||||
version: '1.0',
|
||||
author: '喵呜',
|
||||
author: 'MiaoWoo',
|
||||
commands: {
|
||||
'mchat': {
|
||||
description: 'MiaoChat登录命令'
|
||||
@ -33,45 +33,45 @@ var description = {
|
||||
}
|
||||
},
|
||||
config: {
|
||||
"Version":"1.8.5",
|
||||
"BungeeCord":true,
|
||||
"Server":"生存服",
|
||||
"ChatFormats":{
|
||||
"default":{
|
||||
"index":50,
|
||||
"permission":"MiaoChat.default",
|
||||
"range":0,
|
||||
"format":"[world][player]: ",
|
||||
"item":true,
|
||||
"itemformat":"&6[&b%s&6]&r"
|
||||
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]: ",
|
||||
"range":0,
|
||||
"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":[
|
||||
"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%"
|
||||
"click": {
|
||||
"type": "COMMAND",
|
||||
"command": "/tpa %player_name%"
|
||||
}
|
||||
},
|
||||
"player":{
|
||||
"text":"&b%player_name%",
|
||||
"hover":[
|
||||
"player": {
|
||||
"text": "&b%player_name%",
|
||||
"hover": [
|
||||
"&6玩家名称: &b%player_name%",
|
||||
"&6玩家等级: &a%player_level%",
|
||||
"&6玩家血量: &c%player_health%",
|
||||
@ -80,22 +80,22 @@ var description = {
|
||||
"",
|
||||
"&c点击与我聊天"
|
||||
],
|
||||
"click":{
|
||||
"type":"SUGGEST",
|
||||
"command":"/tell %player_name%"
|
||||
"click": {
|
||||
"type": "SUGGEST",
|
||||
"command": "/tell %player_name%"
|
||||
}
|
||||
},
|
||||
"admin":{
|
||||
"text":"&6[&c管理员&6]"
|
||||
"admin": {
|
||||
"text": "&6[&c管理员&6]"
|
||||
},
|
||||
"help":{
|
||||
"text":"&4[求助]",
|
||||
"hover":[
|
||||
"help": {
|
||||
"text": "&4[求助]",
|
||||
"hover": [
|
||||
"点击求助OP"
|
||||
],
|
||||
"click":{
|
||||
"type":"COMMAND",
|
||||
"command":"管理员@%player_name% 我需要你的帮助!"
|
||||
"click": {
|
||||
"type": "COMMAND",
|
||||
"command": "管理员@%player_name% 我需要你的帮助!"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -116,14 +116,14 @@ function load() {
|
||||
var FORMAT_PATTERN = /[\[]([^\[\]]+)[\]]/ig;
|
||||
|
||||
function initFormat(chat_formats) {
|
||||
chat_formats.forEach(function (chat_format) {
|
||||
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)) {
|
||||
var r;
|
||||
while (r = FORMAT_PATTERN.exec(chat_format_str)) {
|
||||
temp.push(r[1]);
|
||||
}
|
||||
var format_list = []
|
||||
var format_list = [];
|
||||
temp.forEach(function splitStyle(t) {
|
||||
var arr = chat_format_str.split('[' + t + ']', 2);
|
||||
if (arr[0]) {
|
||||
@ -146,11 +146,12 @@ function enable() {
|
||||
|
||||
function registerCommand() {
|
||||
command.on(self, 'mchat', {
|
||||
cmd: mchat
|
||||
cmd: mainCommand
|
||||
});
|
||||
}
|
||||
|
||||
function mchat(sender, command, args) {
|
||||
// noinspection JSUnusedLocalSymbols
|
||||
function mainCommand(sender, command, args) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -160,29 +161,36 @@ function registerEvent() {
|
||||
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); });
|
||||
sendChat(event.player, event.message, function() {
|
||||
event.setCancelled(true);
|
||||
});
|
||||
}
|
||||
|
||||
function handlerSpongeChat(event) {
|
||||
var player = event.getCause().first(org.spongepowered.api.entity.living.player.Player.class).orElse(null);
|
||||
if (player == null) { return; }
|
||||
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) });
|
||||
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 跳过执行...')
|
||||
console.debug('未获得用户', player.name, '的 ChatRule 跳过执行...');
|
||||
return;
|
||||
}
|
||||
callback();
|
||||
@ -190,33 +198,34 @@ function sendChat(player, plain, callback) {
|
||||
chat_format.format_list.forEach(function setStyle(format) {
|
||||
var style = style_formats[format];
|
||||
if (style) {
|
||||
tr.then(style.text);
|
||||
if (style.hover) {
|
||||
tr.tip(style.hover);
|
||||
}
|
||||
if (style.click && style.click.type && style.click.command) {
|
||||
switch (style.click.type) {
|
||||
case "COMMAND":
|
||||
tr.command(style.click.command);
|
||||
break;
|
||||
case "OPENURL":
|
||||
tr.link(style.click.command);
|
||||
break;
|
||||
case "SUGGEST":
|
||||
tr.suggest(style.click.command);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
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(format);
|
||||
tr.then(replace(player, format));
|
||||
}
|
||||
})
|
||||
tr.then(plain).sendAll();
|
||||
});
|
||||
tr.then(replace(player, plain)).sendAll();
|
||||
}
|
||||
|
||||
function getChatFormat(player) {
|
||||
for (var i in chat_formats){
|
||||
for (var i in chat_formats) {
|
||||
var format = chat_formats[i];
|
||||
if (player.hasPermission(format.permission)) {
|
||||
return format;
|
||||
@ -225,19 +234,19 @@ function getChatFormat(player) {
|
||||
return null;
|
||||
}
|
||||
|
||||
function replace(target) {
|
||||
function replace(player, target) {
|
||||
if (toString.call(target) === "[object Array]") {
|
||||
for (var i in target) {
|
||||
target[i] = replaceStr(target[i]);
|
||||
target[i] = replaceStr(player, target[i]);
|
||||
}
|
||||
} else {
|
||||
target = replaceStr(target);
|
||||
target = replaceStr(player, target);
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
function replaceStr(target) {
|
||||
return target;
|
||||
function replaceStr(player, target) {
|
||||
return papi.$(player, target);
|
||||
}
|
||||
|
||||
function disable() {
|
@ -12,9 +12,12 @@ 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主命令'
|
||||
@ -22,11 +25,15 @@ var description = {
|
||||
},
|
||||
config: {
|
||||
title: '§m§s§a幸运抽奖',
|
||||
panel: '160:13',
|
||||
control: {
|
||||
panel: PANE + ':13',
|
||||
ok: PANE + ':14',
|
||||
no: PANE + ':15',
|
||||
},
|
||||
list: [
|
||||
{
|
||||
box: {
|
||||
id: 160,
|
||||
id: PANE,
|
||||
damage: 1,
|
||||
name: '§a箱子',
|
||||
lore: [
|
||||
@ -34,7 +41,7 @@ var description = {
|
||||
]
|
||||
},
|
||||
key: {
|
||||
id: 160,
|
||||
id: PANE,
|
||||
damage: 2,
|
||||
name: '§b钥匙',
|
||||
lore: [
|
||||
@ -46,7 +53,7 @@ var description = {
|
||||
percent: 10,
|
||||
command: 'money give %player% 100',
|
||||
item: {
|
||||
id: 160,
|
||||
id: PANE,
|
||||
damage: 3,
|
||||
name: '§c奖品1',
|
||||
lore: [
|
||||
@ -58,7 +65,7 @@ var description = {
|
||||
percent: 20,
|
||||
command: 'money give %player% 200',
|
||||
item: {
|
||||
id: 160,
|
||||
id: PANE,
|
||||
damage: 4,
|
||||
name: '§c奖品2',
|
||||
lore: [
|
||||
@ -72,25 +79,18 @@ var description = {
|
||||
}
|
||||
};
|
||||
|
||||
var panel = item.create(160, 1, 13);
|
||||
var panel;
|
||||
var config;
|
||||
var items;
|
||||
|
||||
function load() {
|
||||
config = this.config;
|
||||
if (config.panel) {
|
||||
var arr = config.panel.split(':');
|
||||
if (arr.length === 2) {
|
||||
panel = newItem(arr[0], arr[1]);
|
||||
} else {
|
||||
panel = newItem(arr[0]);
|
||||
}
|
||||
}
|
||||
panel = newItemFromString(config.control.panel || PANE + ':13')
|
||||
items = new ItemStackArray(54);
|
||||
item.setName(panel, '');
|
||||
var ok = newItem(160, 14);
|
||||
var ok = newItemFromString(config.control.ok || PANE + ':14')
|
||||
item.setName(ok, '§a确定抽奖');
|
||||
var no = newItem(160, 15);
|
||||
var no = newItemFromString(config.control.no || PANE + ':15')
|
||||
item.setName(no, '§c取消抽奖');
|
||||
Arrays.fill(items, 0, 10, panel);
|
||||
Arrays.fill(items, 11, 16, panel);
|
||||
@ -113,6 +113,15 @@ 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);
|
||||
@ -121,12 +130,15 @@ function newItemFromConfig(config) {
|
||||
}
|
||||
|
||||
function enable() {
|
||||
// noinspection JSUnusedLocalSymbols
|
||||
command.on(this, 'l', {
|
||||
cmd: function (sender, command, args) {
|
||||
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 = bukkit.$.createInventory(null, 54, config.title);
|
||||
var inv = MServer.createInventory(null, 54, config.title);
|
||||
inv.setContents(items);
|
||||
sender.openInventory(inv);
|
||||
return true;
|
||||
@ -134,7 +146,7 @@ function enable() {
|
||||
});
|
||||
event.on(this, 'InventoryClick', function click(event) {
|
||||
var inv = event.inventory;
|
||||
if (inv.title !== config.title) return;
|
||||
if (inv && inv.title !== config.title) return;
|
||||
var player = event.whoClicked;
|
||||
var slot = event.rawSlot;
|
||||
if (slot > 53 || slot < 0) {
|
||||
@ -159,6 +171,10 @@ function enable() {
|
||||
}
|
||||
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++) {
|
||||
@ -178,14 +194,14 @@ function enable() {
|
||||
console.sender(player, '§c抽奖物品和钥匙不匹配!');
|
||||
return;
|
||||
}
|
||||
var resultlist = [];
|
||||
litem.result.forEach(function (t) {
|
||||
var resultList = [];
|
||||
litem.result.forEach(function(t) {
|
||||
for (var i = 0; i < t.percent; i++) {
|
||||
resultlist.push(t);
|
||||
resultList.push(t);
|
||||
}
|
||||
});
|
||||
var ri = ext.random(resultlist.length);
|
||||
var result = resultlist[ri];
|
||||
var ri = random(resultList.length);
|
||||
var result = resultList[ri];
|
||||
box.amount = box.amount - 1;
|
||||
key.amount = key.amount - 1;
|
||||
inv.setItem(10, box);
|
||||
@ -199,6 +215,11 @@ function enable() {
|
||||
});
|
||||
}
|
||||
|
||||
function random(max, min) {
|
||||
min = min === undefined ? 0 : min;
|
||||
return Math.floor(Math.random() * (max - min) + min);
|
||||
};
|
||||
|
||||
function disable() {
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ var fakeTag;
|
||||
var description = {
|
||||
name: 'MiaoTag',
|
||||
version: '1.1',
|
||||
author: '喵♂呜',
|
||||
author: 'MiaoWoo',
|
||||
config: {
|
||||
format: '§4§l❤'
|
||||
},
|
||||
@ -40,18 +40,23 @@ var config;
|
||||
|
||||
function load() {
|
||||
config = self.getConfig();
|
||||
fakeTag = new FakeTag(config.format);
|
||||
}
|
||||
|
||||
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) {
|
||||
var subCommand = args[0];
|
||||
switch (subCommand) {
|
||||
case 'reload':
|
||||
self.reloadConfig();
|
||||
fakeTag = new FakeTag(config.format);
|
||||
console.sender(sender, "§a配置文件重载完成!", "TEST");
|
||||
console.sender(sender, "§a配置文件重载完成!");
|
||||
break;
|
||||
}
|
||||
},
|
||||
@ -59,30 +64,46 @@ function enable() {
|
||||
return ['reload'];
|
||||
}
|
||||
});
|
||||
bukkit.players(function (p) fakeTag.set(p));
|
||||
event.on(self, 'PlayerJoin', function (event) fakeTag.set(event.player));
|
||||
var entityUpdate = function (event) {
|
||||
var player = event.entity || event.player;
|
||||
if (player instanceof org.bukkit.entity.Player) {
|
||||
setTimeout(function () {
|
||||
fakeTag.update(player);
|
||||
}, 1);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
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);
|
||||
//event.on(this, 'playerquitevent', function quit(event) removeTask(event.player));
|
||||
}
|
||||
|
||||
function entityUpdate(event) {
|
||||
var player = event.entity || event.player;
|
||||
if (player instanceof org.bukkit.entity.Player) {
|
||||
setTimeout(function() {
|
||||
fakeTag.update(player);
|
||||
}, 1);
|
||||
}
|
||||
};
|
||||
|
||||
function disable() {
|
||||
fakeTag.disable();
|
||||
if (fakeTag) { fakeTag.disable() };
|
||||
}
|
||||
|
||||
function FakeTag(name) {
|
||||
var ver1_13 = false;
|
||||
// NMS CLASS
|
||||
var ScoreboardBaseCriteria = bukkit.nmsCls('ScoreboardBaseCriteria');
|
||||
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');
|
||||
@ -90,13 +111,31 @@ function FakeTag(name) {
|
||||
var scoreboardManager = bukkit.$.scoreboardManager;
|
||||
var mainScoreboard = scoreboardManager.mainScoreboard.handle;
|
||||
|
||||
// 注销对象
|
||||
var objective = mainScoreboard.getObjective(name);
|
||||
if (objective) {
|
||||
mainScoreboard.unregisterObjective(objective);
|
||||
}
|
||||
|
||||
try {
|
||||
// 注册tag对象
|
||||
mainScoreboard.registerObjective(name, new ScoreboardBaseCriteria(name));
|
||||
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!
|
||||
}
|
||||
var objective = mainScoreboard.getObjective(name);
|
||||
|
||||
if (!objective) {
|
||||
throw Error("Error Can't Found MainScoreboard Objective " + name)
|
||||
}
|
||||
|
||||
// 缓存虚拟的tag包
|
||||
var cache = {
|
||||
@ -108,28 +147,34 @@ function FakeTag(name) {
|
||||
player.handle.playerConnection.sendPacket(p);
|
||||
}
|
||||
|
||||
this.set = function (player) {
|
||||
this.set = function(player) {
|
||||
sendPacket(player, cache.objective);
|
||||
sendPacket(player, cache.display);
|
||||
this.update(player);
|
||||
};
|
||||
|
||||
this.update = function (player) {
|
||||
var score = mainScoreboard.getPlayerScoreForObjective(player.name, objective);
|
||||
score.setScore(player.getHealth());
|
||||
var scorePack = new PacketPlayOutScoreboardScore(score);
|
||||
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) {
|
||||
bukkit.players(function(t) {
|
||||
sendPacket(t, scorePack);
|
||||
if (t.name !== player.name) {
|
||||
var outher = mainScoreboard.getPlayerScoreForObjective(t.name, objective);
|
||||
outher.setScore(t.getHealth());
|
||||
sendPacket(player, new PacketPlayOutScoreboardScore(outher));
|
||||
sendPacket(player, createScore(t));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
this.disable = function () {
|
||||
this.disable = function() {
|
||||
// 注销tag对象
|
||||
mainScoreboard.unregisterObjective(objective);
|
||||
}
|
48
src/main/resources/dev-plugins/bukkit/WorldEdit.js
Normal file
48
src/main/resources/dev-plugins/bukkit/WorldEdit.js
Normal file
@ -0,0 +1,48 @@
|
||||
'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
|
||||
};
|
32
src/main/resources/dev-plugins/markdown/MiaoChat.md
Normal file
32
src/main/resources/dev-plugins/markdown/MiaoChat.md
Normal file
@ -0,0 +1,32 @@
|
||||
## MiaoChat for MiaoScript
|
||||
|
||||

|
||||
|
||||
> 注意: 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` 即可安装成功
|
220
src/main/resources/dev-plugins/sponge/MiaoBoard.js
Normal file
220
src/main/resources/dev-plugins/sponge/MiaoBoard.js
Normal file
@ -0,0 +1,220 @@
|
||||
'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
|
||||
};
|
@ -1,52 +0,0 @@
|
||||
/*global Java, base, module, exports, require*/
|
||||
var bukkit = require('api/server');
|
||||
|
||||
var nmsChatSerializerClass;
|
||||
var nmsIChatBaseComponentClass;
|
||||
var packetTypeClass;
|
||||
var nmsChatMessageTypeClass;
|
||||
|
||||
var chatMessageTypes;
|
||||
|
||||
var String = Java.type('java.lang.String');
|
||||
|
||||
function init () {
|
||||
nmsChatSerializerClass = bukkit.nmsCls(bukkit.nmsVersion.split("_")[1] > 7 ? "IChatBaseComponent$ChatSerializer" : "ChatSerializer");
|
||||
nmsIChatBaseComponentClass = bukkit.nmsCls('IChatBaseComponent');
|
||||
packetTypeClass = bukkit.nmsCls("PacketPlayOutChat");
|
||||
var packetTypeConstructor;
|
||||
Java.from(packetTypeClass.class.constructors).forEach(function (c) {
|
||||
if (c.parameterTypes.length == 2) { packetTypeConstructor = c };
|
||||
})
|
||||
nmsChatMessageTypeClass = packetTypeConstructor.parameterTypes[1];
|
||||
if (nmsChatMessageTypeClass.isEnum()) {
|
||||
chatMessageTypes = nmsChatMessageTypeClass.getEnumConstants();
|
||||
} else {
|
||||
switch (nmsChatMessageTypeClass.name) {
|
||||
case "int":
|
||||
nmsChatMessageTypeClass = java.lang.Integer;
|
||||
case "byte":
|
||||
nmsChatMessageTypeClass = java.lang.Byte;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function json(sender, json) {
|
||||
send(sender, json, 0);
|
||||
}
|
||||
|
||||
function send(sender, json, type) {
|
||||
var serialized = nmsChatSerializerClass.a(json)
|
||||
var typeObj = chatMessageTypes == null ? nmsChatMessageTypeClass.valueOf(String.valueOf(type)) : chatMessageTypes[type];
|
||||
sendPacket(sender, new packetTypeClass(serialized, typeObj))
|
||||
}
|
||||
|
||||
function sendPacket(player, p) {
|
||||
player.handle.playerConnection.sendPacket(p);
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
exports = module.exports = {
|
||||
json: json
|
||||
};
|
@ -1,100 +0,0 @@
|
||||
'use strict';
|
||||
/**
|
||||
* Bukkit 命令相关类
|
||||
*/
|
||||
|
||||
/*global Java, base, module, exports, require, __FILE__*/
|
||||
var ref = require('modules/reflect');
|
||||
var bukkit = require('./server');
|
||||
var plugin = bukkit.plugin.self;
|
||||
var commandMap = ref.on(bukkit.plugin.manager).get('commandMap').get();
|
||||
var PluginCommand = Java.type('org.bukkit.command.PluginCommand');
|
||||
|
||||
var StringUtil = Java.type('org.bukkit.util.StringUtil');
|
||||
|
||||
var ArrayList = Java.type('java.util.ArrayList');
|
||||
var Arrays = Java.type('java.util.Arrays');
|
||||
|
||||
function enable(jsp) {
|
||||
var commands = jsp.description.commands;
|
||||
if (commands) {
|
||||
var pluginCmds = [];
|
||||
for (var name in commands) {
|
||||
var command = commands[name];
|
||||
if (typeof command !== 'object') continue;
|
||||
var newCmd = create(jsp, name);
|
||||
if (command.description) newCmd.setDescription(command.description);
|
||||
if (command.usage) newCmd.setUsage(command.usage);
|
||||
if (command.aliases) newCmd.setAliases(Arrays.asList(command.aliases));
|
||||
if (command.permission) newCmd.setPermission(command.permission);
|
||||
if (command['permission-message']) newCmd.setPermissionMessage(command['permission-message']);
|
||||
pluginCmds.push(newCmd);
|
||||
console.debug('插件 %s 注册命令 %s ...'.format(jsp.description.name, name));
|
||||
}
|
||||
commandMap.registerAll(jsp.description.name, Arrays.asList(pluginCmds));
|
||||
}
|
||||
}
|
||||
|
||||
function disable(jsp) {
|
||||
var commands = jsp.description.commands;
|
||||
if (commands) {
|
||||
for (var name in commands) {
|
||||
//TODO 删除插件命令
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function get(name) {
|
||||
return commandMap.getCommand(name);
|
||||
}
|
||||
|
||||
function create(jsp, name) {
|
||||
return register(jsp, ref.on(PluginCommand).create(name, plugin).get());
|
||||
}
|
||||
|
||||
function register(jsp, cmd) {
|
||||
commandMap.register(jsp.description.name, cmd);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
function on(jsp, name, exec) {
|
||||
var c = get(name) || create(jsp, name);
|
||||
console.debug('插件 %s 设置命令 %s(%s) 执行器 ...'.format(jsp.description.name, name, c));
|
||||
if (exec.cmd) {
|
||||
// 必须指定需要实现的接口类型 否则MOD服会报错
|
||||
c.setExecutor(new org.bukkit.command.CommandExecutor({
|
||||
onCommand: function (sender, cmd, command, args) {
|
||||
try {
|
||||
return exec.cmd(sender, command, args);
|
||||
} catch (ex) {
|
||||
console.console('§6玩家 §a%s §6执行 §b%s §6插件 §d%s %s §6命令时发生异常 §4%s'
|
||||
.format(sender.name, jsp.description.name, command, Java.from(args).join(' '), ex));
|
||||
console.ex(ex);
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
if (exec.tab) {
|
||||
// 必须指定需要实现的接口类型 否则MOD服会报错
|
||||
c.setTabCompleter(new org.bukkit.command.TabCompleter({
|
||||
onTabComplete: function (sender, cmd, command, args) {
|
||||
try {
|
||||
var token = args[args.length - 1];
|
||||
var complate = exec.tab(sender, command, args) || []
|
||||
return Arrays.asList(complate.copyPartialMatches(token, []));
|
||||
} catch (ex) {
|
||||
console.console('§6玩家 §a%s §6执行 §b%s §6插件 §d%s %s §6补全时发生异常 §4%s'
|
||||
.format(sender.name, jsp.description.name, command, Java.from(args).join(' '), ex));
|
||||
console.ex(ex);
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
exports.enable = enable;
|
||||
|
||||
exports.on = on;
|
||||
exports.off = function () {
|
||||
|
||||
};
|
@ -1,17 +0,0 @@
|
||||
/*global Java, base, module, exports, require, __FILE__*/
|
||||
(function (global) {
|
||||
global.Console = function BukkitConsole() {
|
||||
ConsoleDefault.call(this);
|
||||
this.sender = function () {
|
||||
var sender = arguments[0];
|
||||
if (!(sender instanceof org.bukkit.command.CommandSender)) {
|
||||
this.error("第一个参数未实现 org.bukkit.command.CommandSender 无法发送消息!")
|
||||
}
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
sender.sendMessage(console.prefix + args.join(' '));
|
||||
};
|
||||
this.console = function () {
|
||||
this.sender(MServer.consoleSender, Array.prototype.join.call(arguments, ' '));
|
||||
};
|
||||
};
|
||||
})(global);
|
@ -1,50 +0,0 @@
|
||||
'use strict';
|
||||
/**
|
||||
* Sponge 事件相关类
|
||||
*/
|
||||
/*global Java, base, module, exports, require, __FILE__*/
|
||||
var ref = require('reflect');
|
||||
var Event = Java.type("org.bukkit.event.Event");
|
||||
var Modifier = Java.type("java.lang.reflect.Modifier");
|
||||
var Listener = Java.type("org.bukkit.event.Listener");
|
||||
var EventPriority = Java.type("org.bukkit.event.EventPriority");
|
||||
var EventExecutor = Java.type("org.bukkit.plugin.EventExecutor");
|
||||
|
||||
/**
|
||||
* 判断是否为一个有效的事件类
|
||||
* @param clz
|
||||
* @returns {*|boolean}
|
||||
*/
|
||||
function isVaildEvent(clz) {
|
||||
// noinspection JSUnresolvedVariable 继承于 org.bukkit.event.Event
|
||||
return Event.class.isAssignableFrom(clz) &&
|
||||
// 访问符为Public
|
||||
Modifier.isPublic(clz.getModifiers()) &&
|
||||
// 不是抽象类
|
||||
!Modifier.isAbstract(clz.getModifiers());
|
||||
}
|
||||
|
||||
function register(eventCls, exec, priority, ignoreCancel) {
|
||||
var listener = new Listener({});
|
||||
MServer.getPluginManager().registerEvent(
|
||||
eventCls,
|
||||
listener,
|
||||
EventPriority[priority],
|
||||
new EventExecutor({
|
||||
execute: exec
|
||||
}),
|
||||
this.plugin,
|
||||
ignoreCancel);
|
||||
return listener;
|
||||
}
|
||||
|
||||
function unregister(event, listener) {
|
||||
ref.on(event).call('getHandlerList').get().unregister(listener);
|
||||
}
|
||||
|
||||
exports = module.exports = {
|
||||
baseEventDir: 'org/bukkit/event',
|
||||
isVaildEvent: isVaildEvent,
|
||||
register: register,
|
||||
unregister: unregister
|
||||
};
|
@ -1,99 +0,0 @@
|
||||
'use strict';
|
||||
/**
|
||||
* 物品快速生成类
|
||||
* Created by 蒋天蓓 on 2017/2/9 0009.
|
||||
*/
|
||||
/*global Java, base, module, exports, require, __FILE__*/
|
||||
var Bukkit = MServer;
|
||||
var item = {};
|
||||
var ItemStack = Java.type("org.bukkit.inventory.ItemStack");
|
||||
var Material = Java.type('org.bukkit.Material');
|
||||
|
||||
/**
|
||||
* 创建一个物品
|
||||
* @constructor (ID)
|
||||
* @constructor (ID,数量)
|
||||
* @constructor (ID,数量,子ID)
|
||||
*/
|
||||
item.create = function () {
|
||||
var idOrType = arguments[0];
|
||||
if (isNaN(Number(idOrType))) {
|
||||
idOrType = Material[idOrType];
|
||||
}
|
||||
switch (arguments.length) {
|
||||
case 1:
|
||||
return new ItemStack(idOrType);
|
||||
case 2:
|
||||
return new ItemStack(idOrType, arguments[1]);
|
||||
case 3:
|
||||
return new ItemStack(idOrType, arguments[1], arguments[2]);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 创建一个头颅
|
||||
* @constructor (玩家名称)
|
||||
*/
|
||||
item.head = function (name) {
|
||||
var head = item.create(397, 1, 3);
|
||||
var skullMeta = head.getItemMeta();
|
||||
skullMeta.setOwner(name);
|
||||
head.setItemMeta(skullMeta);
|
||||
return head;
|
||||
};
|
||||
/**
|
||||
* 给玩家添加物品
|
||||
* @param player 玩家
|
||||
* @param items 物品数组
|
||||
* @param drop 满背包是否掉落
|
||||
*/
|
||||
item.add = function (player, items, drop) {
|
||||
var drops = player.getInventory().addItem(items).values();
|
||||
if (drops.size() !== 0 && drop) {
|
||||
drops.forEach(function (itemStack) {
|
||||
item.drop(player.getLocation(), itemStack);
|
||||
});
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 指定地点掉落物品
|
||||
* @param loc 地点
|
||||
* @param item 物品
|
||||
*/
|
||||
item.drop = function (loc, item) {
|
||||
setTimeout(function () {
|
||||
loc.getWorld().dropItem(loc, item);
|
||||
}, 1);
|
||||
};
|
||||
/**
|
||||
* 设置物品名称
|
||||
* @param item 物品
|
||||
* @param name
|
||||
* @returns {*}
|
||||
*/
|
||||
item.setName = function (item, name) {
|
||||
if (item.getType().name() !== "AIR") {
|
||||
var meta = item.hasItemMeta() ? item.getItemMeta() : Bukkit.getItemFactory().getItemMeta(item.getType());
|
||||
meta.setDisplayName(name);
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
return item;
|
||||
};
|
||||
/**
|
||||
* 设置物品Lore
|
||||
* @param item 物品
|
||||
* @param lores Lore
|
||||
* @returns {*} 物品
|
||||
*/
|
||||
item.setLore = item.setLores = function (item, lores) {
|
||||
if (item.getType().name() !== "AIR") {
|
||||
var meta = item.hasItemMeta() ? item.getItemMeta() : Bukkit.getItemFactory().getItemMeta(item.getType());
|
||||
if (typeof(lores) === 'string') {
|
||||
lores = lores.split("\n")
|
||||
}
|
||||
meta.setLore(lores);
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
return item;
|
||||
};
|
||||
|
||||
module.exports = item;
|
@ -1,48 +0,0 @@
|
||||
'use strict';
|
||||
/**
|
||||
* Bukkit 权限相关类
|
||||
*/
|
||||
|
||||
/*global Java, base, module, exports, require, __FILE__*/
|
||||
var manager = require('./server').plugin.manager;
|
||||
|
||||
/**
|
||||
* Permission(String name, String description)
|
||||
*/
|
||||
var Permission = Java.type("org.bukkit.permissions.Permission");
|
||||
var PermissionDefault = Java.type('org.bukkit.permissions.PermissionDefault');
|
||||
|
||||
function enable(plugin) {
|
||||
var permissions = plugin.description.permissions;
|
||||
if (permissions) {
|
||||
for (var name in permissions) {
|
||||
var permission = permissions[name];
|
||||
if (typeof permission !== 'object') continue;
|
||||
var desc = permission.description;
|
||||
var def = permission.default || 'OP';
|
||||
try {
|
||||
manager.addPermission(new Permission(name, desc, PermissionDefault.getByName(def)));
|
||||
} catch (ex) {
|
||||
// ignore eg: java.lang.IllegalArgumentException: The permission xxxxxx.default is already defined!
|
||||
}
|
||||
console.debug('插件 %s 注册权限 %s Default %s ...'.format(plugin.description.name, name, def));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function disable(plugin) {
|
||||
var permissions = plugin.description.permissions;
|
||||
if (permissions) {
|
||||
for (var name in permissions) {
|
||||
try {
|
||||
manager.removePermission(name);
|
||||
} catch (ex) {
|
||||
// ignore eg: java.lang.IllegalArgumentException: The permission xxxxxx.default is already defined!
|
||||
}
|
||||
console.debug('插件 %s 注销权限 %s ...'.format(plugin.description.name, name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exports.enable = enable;
|
||||
exports.disable = disable;
|
@ -1,118 +0,0 @@
|
||||
'use strict';
|
||||
/**
|
||||
* Bukkit基础操作
|
||||
* Created by 蒋天蓓 on 2017/2/9 0009.
|
||||
*/
|
||||
|
||||
/*global Java, base, module, exports, require, __FILE__*/
|
||||
var Bukkit = MServer;
|
||||
var Server = Bukkit.server;
|
||||
var PluginManager = Server.pluginManager;
|
||||
exports.$ = Bukkit;
|
||||
/**
|
||||
* 获取NMS版本
|
||||
*/
|
||||
exports.nmsVersion = Bukkit.server.class.name.split('.')[3];
|
||||
/**
|
||||
* 获取NMS类
|
||||
*/
|
||||
exports.nmsCls = function (name) {
|
||||
return Java.type(['net.minecraft.server', exports.nmsVersion, name].join('.'));
|
||||
};
|
||||
/**
|
||||
* 获取OBC类
|
||||
*/
|
||||
exports.obcCls = function (name) {
|
||||
return Java.type(['org.bukkit.craftbukkit', exports.nmsVersion, name].join('.'));
|
||||
};
|
||||
/**
|
||||
* 获取玩家
|
||||
*/
|
||||
exports.player = function () {
|
||||
switch (arguments.length) {
|
||||
case 0:
|
||||
return undefined;
|
||||
case 1:
|
||||
return Server.getPlayer(arguments[0]);
|
||||
default:
|
||||
return Server.getPlayerExtra(arguments[0]);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 获取在线玩家
|
||||
*/
|
||||
exports.players = function () {
|
||||
switch (arguments.length) {
|
||||
case 1:
|
||||
return Server.onlinePlayers.forEach(arguments[0]);
|
||||
default:
|
||||
return Server.onlinePlayers;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 插件管理
|
||||
* @type {{manager: *, get: exports.plugin.get, load: exports.plugin.load}}
|
||||
*/
|
||||
exports.plugin = {
|
||||
/**
|
||||
* 插件管理工具
|
||||
*/
|
||||
manager: PluginManager,
|
||||
/**
|
||||
* 获得插件实例
|
||||
* @param name 插件名称
|
||||
* @returns {*}
|
||||
*/
|
||||
get: function (name) {
|
||||
return PluginManager.getPlugin(name);
|
||||
},
|
||||
/**
|
||||
* 载入插件 并且返回结果
|
||||
* @param name 插件名称
|
||||
* @returns {*}
|
||||
*/
|
||||
load: function (name) {
|
||||
var plugin = this.get(name);
|
||||
if (ext.notNull(plugin) && !plugin.isEnabled()) {
|
||||
PluginManager.enablePlugin(plugin);
|
||||
}
|
||||
return PluginManager.isPluginEnabled(name);
|
||||
},
|
||||
self: PluginManager.getPlugin('MiaoScript')
|
||||
};
|
||||
/**
|
||||
* 公告
|
||||
* @param message 消息
|
||||
*/
|
||||
exports.broadcast = function (message) {
|
||||
Bukkit.broadcastMessage(message);
|
||||
};
|
||||
/**
|
||||
* 执行名称
|
||||
* @param player 玩家
|
||||
* @param command 命令
|
||||
*/
|
||||
exports.command = function (player, command) {
|
||||
Bukkit.dispatchCommand(player, command);
|
||||
};
|
||||
/**
|
||||
* 执行控制台命令
|
||||
* @param command 命令
|
||||
*/
|
||||
exports.console = function (command) {
|
||||
exports.command(Bukkit.getConsoleSender(), command);
|
||||
};
|
||||
/**
|
||||
* 玩家以OP权限执行命令
|
||||
* @param player
|
||||
* @param exper
|
||||
*/
|
||||
exports.opcommand = function (player, exper) {
|
||||
var origin = player.isOp();
|
||||
player.setOp(true);
|
||||
try {
|
||||
exports.command(player, exper);
|
||||
} finally {
|
||||
player.setOp(origin);
|
||||
}
|
||||
};
|
@ -1,71 +0,0 @@
|
||||
'use strict';
|
||||
/*global Java, base, module, exports, require, __FILE__*/
|
||||
/**
|
||||
* 任务计划
|
||||
* Created by 蒋天蓓 on 2017/2/9 0009.
|
||||
*/
|
||||
var plugin = require('./server').plugin.self;
|
||||
var BukkitRunnable = Java.type("org.bukkit.scheduler.BukkitRunnable");
|
||||
/**
|
||||
* 创建任务对象
|
||||
* @param func 任务
|
||||
*/
|
||||
exports.create = function (func) {
|
||||
return new BukkitRunnable(func);
|
||||
};
|
||||
/**
|
||||
* 运行任务
|
||||
* @param func 任务
|
||||
*/
|
||||
exports.run = function (func) {
|
||||
return exports.create(func).runTask(plugin);
|
||||
};
|
||||
/**
|
||||
* 延时运行任务
|
||||
* @param func 任务
|
||||
* @param time 延时时间
|
||||
*/
|
||||
exports.later = function (func, time) {
|
||||
return exports.create(func).runTaskLater(plugin, time);
|
||||
};
|
||||
/**
|
||||
* 运行循环任务
|
||||
* @constructor (任务,执行间隔).
|
||||
* @constructor (任务,首次延时,执行间隔)
|
||||
*/
|
||||
exports.timer = function () {
|
||||
switch (arguments.length) {
|
||||
case 2:
|
||||
return exports.create(arguments[0]).runTaskTimer(plugin, 0, arguments[1]);
|
||||
case 3:
|
||||
return exports.create(arguments[0]).runTaskTimer(plugin, arguments[1], arguments[2]);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 运行异步任务
|
||||
* @param func function 任务
|
||||
*/
|
||||
exports.async = function (func) {
|
||||
return exports.create(func).runTaskAsynchronously(plugin);
|
||||
};
|
||||
/**
|
||||
* 延时运行异步任务
|
||||
* @param func 任务
|
||||
* @param time 延时时间
|
||||
*/
|
||||
exports.laterAsync = function (func, time) {
|
||||
return exports.create(func).runTaskLaterAsynchronously(plugin, time);
|
||||
};
|
||||
/**
|
||||
* 运行异步循环任务
|
||||
* @constructor (任务,执行间隔).
|
||||
* @constructor (任务,首次延时,执行间隔)
|
||||
*/
|
||||
exports.timerAsync = function () {
|
||||
switch (arguments.length) {
|
||||
case 2:
|
||||
return exports.create(arguments[0]).runTaskTimerAsynchronously(plugin, 0, arguments[1]);
|
||||
case 3:
|
||||
return exports.create(arguments[0]).runTaskTimerAsynchronously(plugin, arguments[1], arguments[2]);
|
||||
}
|
||||
};
|
@ -1,18 +0,0 @@
|
||||
/**
|
||||
* Bukkit 玩家方法代理类
|
||||
* Created by 蒋天蓓 on 2018/1/5 0009.
|
||||
*/
|
||||
/*global Java, base, module, exports, require*/
|
||||
var ref = require('reflect');
|
||||
var Player = {
|
||||
createNew: function createNew(inner) {
|
||||
var player = {};
|
||||
player.handler = inner;
|
||||
player.sendMessage = function (msg) {
|
||||
this.handler.sendMessage(msg);
|
||||
};
|
||||
return Object.assign(ref.mapToObject(inner), player);
|
||||
}
|
||||
};
|
||||
|
||||
exports.$ = Player.createNew;
|
@ -1,9 +0,0 @@
|
||||
/*global Java, base, module, exports, require*/
|
||||
var TextSerializers = Java.type('org.spongepowered.api.text.serializer.TextSerializers');
|
||||
function json(sender, json) {
|
||||
sender.sendMessage(TextSerializers.JSON.deserialize(json));
|
||||
}
|
||||
|
||||
exports = module.exports = {
|
||||
json: json
|
||||
};
|
@ -1,132 +0,0 @@
|
||||
'use strict';
|
||||
/**
|
||||
* Sponge 命令相关类
|
||||
*/
|
||||
|
||||
/*global Java, base, module, exports, require, __FILE__*/
|
||||
var Sponge = MServer;
|
||||
var server = require('./server');
|
||||
var plugin = server.plugin.self;
|
||||
|
||||
var CommandManager = server.CommandManager;
|
||||
|
||||
var CommandSpec = Java.type('org.spongepowered.api.command.spec.CommandSpec');
|
||||
var CommandCallable = Java.type('org.spongepowered.api.command.CommandCallable');
|
||||
var CommandResult = Java.type('org.spongepowered.api.command.CommandResult');
|
||||
|
||||
var Text = Java.type('org.spongepowered.api.text.Text');
|
||||
|
||||
var Optional = Java.type('java.util.Optional');
|
||||
|
||||
var ArrayList = Java.type('java.util.ArrayList');
|
||||
var Arrays = Java.type('java.util.Arrays');
|
||||
|
||||
var commandMap=[];
|
||||
|
||||
var SimpleCommandCallable = function (command) {
|
||||
var that = this;
|
||||
this.name = command.name;
|
||||
this.cmd = noop;
|
||||
this.tab = function() { return new ArrayList(); };
|
||||
this.callable = new CommandCallable({
|
||||
//CommandResult process(CommandSource source, String arguments) throws CommandException;
|
||||
process: function (src, args) {
|
||||
return that.cmd(src, that.name, args.length === 0 ? [] : args.split(" ")) ? CommandResult.success() : CommandResult.empty();
|
||||
},
|
||||
//List<String> getSuggestions(CommandSource source, String arguments, @Nullable Location<World> targetPosition) throws CommandException;
|
||||
getSuggestions: function (src, args, target) {
|
||||
return that.tab(src, that.name, args.length === 0 ? [] : args.split(" "));
|
||||
},
|
||||
//boolean testPermission(CommandSource source);
|
||||
testPermission: function () {
|
||||
return true;
|
||||
},
|
||||
//Optional<Text> getShortDescription(CommandSource source);
|
||||
getShortDescription: function () {
|
||||
return Optional.of(Text.of(command.description || '暂无描述!'));
|
||||
},
|
||||
//Optional<Text> getHelp(CommandSource source);
|
||||
getHelp: function () {
|
||||
return Optional.of(Text.of(""));
|
||||
},
|
||||
//Text getUsage(CommandSource source);
|
||||
getUsage: function () {
|
||||
return Text.of('');
|
||||
}
|
||||
});
|
||||
this.setExecutor = function (exec) {
|
||||
that.cmd = exec;
|
||||
};
|
||||
this.setTabCompleter = function (exec) {
|
||||
that.tab = exec;
|
||||
}
|
||||
}
|
||||
|
||||
function enable(jsp) {
|
||||
var pname = jsp.description.name;
|
||||
var commands = jsp.description.commands;
|
||||
if (commands) {
|
||||
var pluginCmds = [];
|
||||
for (var name in commands) {
|
||||
var command = commands[name];
|
||||
if (typeof command !== 'object') continue;
|
||||
command.name = name
|
||||
create(jsp, command)
|
||||
console.debug('插件 %s 注册命令 %s ...'.format(jsp.description.name, name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function get(name) {
|
||||
}
|
||||
|
||||
function create(jsp, command) {
|
||||
var commandKey = jsp.description.name.toLowerCase() + ":" + command.name;
|
||||
if(!commandMap[commandKey]){
|
||||
commandMap[commandKey] = new SimpleCommandCallable(command);
|
||||
Sponge.getCommandManager().register(plugin, commandMap[commandKey].callable, command.name, commandKey);
|
||||
}
|
||||
return commandMap[commandKey];
|
||||
}
|
||||
|
||||
function on(jsp, name, exec) {
|
||||
var c = create(jsp, {name: name});
|
||||
console.debug('插件 %s 设置命令 %s 执行器 ...'.format(jsp.description.name, name));
|
||||
if (exec.cmd) {
|
||||
c.setExecutor(function execCmd(sender, command, args) {
|
||||
try {
|
||||
return exec.cmd(sender, command, args);
|
||||
} catch (ex) {
|
||||
console.console('§6玩家 §a%s §6执行 §b%s §6插件 §d%s %s §6命令时发生异常'
|
||||
.format(sender.name, jsp.description.name, command, args.join(' ')));
|
||||
console.ex(ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (exec.tab) {
|
||||
c.setTabCompleter(function execTab(sender, command, args) {
|
||||
try {
|
||||
var token = args[args.length - 1];
|
||||
var complate = exec.tab(sender, command, args) || []
|
||||
return Arrays.asList(complate.copyPartialMatches(token, []));
|
||||
} catch (ex) {
|
||||
console.console('§6玩家 §a%s §6执行 §b%s §6插件 §d%s %s §6补全时发生异常'
|
||||
.format(sender.name, jsp.description.name, command, args.join(' ')));
|
||||
console.ex(ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var exist = Sponge.getCommandManager().getOwnedBy(plugin);
|
||||
exist.forEach(function(commandMapping) {
|
||||
if (!commandMapping.getAllAliases().contains("ms")) {
|
||||
Sponge.getCommandManager().removeMapping(commandMapping);
|
||||
}
|
||||
});
|
||||
|
||||
exports = module.exports = {
|
||||
enable: enable,
|
||||
on: on,
|
||||
off: noop
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
/*global Java, base, module, exports, require, __FILE__*/
|
||||
(function (global) {
|
||||
global.Console = function SpongeConsole() {
|
||||
ConsoleDefault.call(this);
|
||||
this.sender = function () {
|
||||
var Text = Java.type("org.spongepowered.api.text.Text");
|
||||
var sender = arguments[0];
|
||||
if (!(sender instanceof org.spongepowered.api.command.CommandSource)) {
|
||||
this.error("第一个参数未实现 org.spongepowered.api.command.CommandSource 无法发送消息!")
|
||||
}
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
sender.sendMessage(Text.of(console.prefix + args.join(' ')));
|
||||
};
|
||||
this.console = function () {
|
||||
this.sender(MServer.server.console, Array.prototype.join.call(arguments, ' '));
|
||||
};
|
||||
this.warn = function () {
|
||||
log.warn(this.name + Array.prototype.join.call(arguments, ' '));
|
||||
};
|
||||
};
|
||||
})(global);
|
@ -1,55 +0,0 @@
|
||||
'use strict';
|
||||
/**
|
||||
* Sponge 事件相关类
|
||||
*/
|
||||
/*global Java, base, module, exports, require, __FILE__*/
|
||||
var Modifier = Java.type("java.lang.reflect.Modifier");
|
||||
var Order = Java.type("org.spongepowered.api.event.Order");
|
||||
var Event = Java.type("org.spongepowered.api.event.Event");
|
||||
var EventListener = Java.type("org.spongepowered.api.event.EventListener");
|
||||
|
||||
var priorityMap = {
|
||||
'LOWEST': 'PRE',
|
||||
'LOW': 'FIRST',
|
||||
'NORMAL': 'DEFAULT',
|
||||
'HIGH': 'LATE',
|
||||
'HIGHEST': 'LAST',
|
||||
'MONITOR': 'POST'
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为一个有效的事件类
|
||||
* @param clz
|
||||
* @returns {*|boolean}
|
||||
*/
|
||||
function isVaildEvent(clz) {
|
||||
// noinspection JSUnresolvedVariable 继承于 org.spongepowered.api.event.Event
|
||||
return Event.class.isAssignableFrom(clz) &&
|
||||
// 访问符为Public
|
||||
Modifier.isPublic(clz.getModifiers()) &&
|
||||
// Sponge的事件都是接口
|
||||
Modifier.isAbstract(clz.getModifiers());
|
||||
}
|
||||
|
||||
function class2Name(clazz) {
|
||||
return clazz.canonicalName.substring(clazz.name.lastIndexOf(".") + 1);
|
||||
}
|
||||
|
||||
function register(eventCls, exec, priority, ignoreCancel) {
|
||||
var listener = new EventListener({
|
||||
handle: exec
|
||||
});
|
||||
MServer.getEventManager().registerListener(this.plugin, eventCls, Order[priorityMap[priority]], listener);
|
||||
return listener;
|
||||
}
|
||||
|
||||
function unregister(event, listener) {
|
||||
MServer.getEventManager().unregisterListeners(listener);
|
||||
}
|
||||
exports = module.exports = {
|
||||
baseEventDir: 'org/spongepowered/api/event',
|
||||
isVaildEvent: isVaildEvent,
|
||||
class2Name: class2Name,
|
||||
register: register,
|
||||
unregister: unregister
|
||||
};
|
@ -1,68 +0,0 @@
|
||||
'use strict';
|
||||
/**
|
||||
* Sponge基础操作
|
||||
* Created by 蒋天蓓 on 2017/10/27 0009.
|
||||
*/
|
||||
|
||||
/*global Java, base, module, exports, require, __FILE__*/
|
||||
var Sponge = MServer;
|
||||
var Server = Sponge.server;
|
||||
var PluginManager = Sponge.pluginManager;
|
||||
exports.$ = Sponge;
|
||||
/**
|
||||
* 插件管理
|
||||
* @type {{manager: *, get: exports.plugin.get, load: exports.plugin.load}}
|
||||
*/
|
||||
exports.plugin = {
|
||||
/**
|
||||
* 插件管理工具
|
||||
*/
|
||||
manager: PluginManager,
|
||||
/**
|
||||
* 获得插件实例
|
||||
* @param name 插件名称
|
||||
* @returns {*}
|
||||
*/
|
||||
get: function (name) {
|
||||
return PluginManager.getPlugin(name).orElse(undefined);
|
||||
},
|
||||
/**
|
||||
* 载入插件 并且返回结果
|
||||
* @param name 插件名称
|
||||
* @returns {*}
|
||||
*/
|
||||
load: function (name) {
|
||||
var plugin = this.get(name);
|
||||
if (ext.notNull(plugin) && !plugin.isEnabled()) {
|
||||
PluginManager.enablePlugin(plugin);
|
||||
}
|
||||
return PluginManager.isPluginEnabled(name);
|
||||
},
|
||||
self: PluginManager.getPlugin('miaoscript').orElse(undefined)
|
||||
};
|
||||
/**
|
||||
* 获取玩家
|
||||
*/
|
||||
exports.player = function () {
|
||||
switch (arguments.length) {
|
||||
case 0:
|
||||
return undefined;
|
||||
case 1:
|
||||
return Server.getPlayer(arguments[0]).orElse(undefined);
|
||||
default:
|
||||
return Server.getPlayer(arguments[0]).orElse(undefined);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 获取在线玩家
|
||||
*/
|
||||
exports.players = function () {
|
||||
switch (arguments.length) {
|
||||
case 1:
|
||||
// 此处的forEach是Collection接口的
|
||||
return Server.onlinePlayers.forEach(arguments[0]);
|
||||
default:
|
||||
// 此处会转换为JS原生的Array
|
||||
return Java.from(Server.onlinePlayers.toArray());
|
||||
}
|
||||
};
|
@ -1,78 +0,0 @@
|
||||
'use strict';
|
||||
/*global Java, base, module, exports, require, __FILE__*/
|
||||
/**
|
||||
* 任务计划
|
||||
* Created by 蒋天蓓 on 2017/2/9 0009.
|
||||
*/
|
||||
var plugin = require('./server').plugin.self;
|
||||
var Comsumer = Java.type('java.util.function.Consumer');
|
||||
var Task = Java.type("org.spongepowered.api.scheduler.Task");
|
||||
/**
|
||||
* 创建任务对象
|
||||
* @param func 任务
|
||||
*/
|
||||
exports.create = function (func) {
|
||||
return Task.builder().execute(new Comsumer(function () {
|
||||
try {
|
||||
func();
|
||||
} catch (ex) {
|
||||
console.ex('§4插件执行任务时发生错误', ex);
|
||||
}
|
||||
}));
|
||||
};
|
||||
/**
|
||||
* 运行任务
|
||||
* @param func 任务
|
||||
*/
|
||||
exports.run = function (func) {
|
||||
return exports.create(func).submit(plugin);
|
||||
};
|
||||
/**
|
||||
* 延时运行任务
|
||||
* @param func 任务
|
||||
* @param time 延时时间
|
||||
*/
|
||||
exports.later = function (func, time) {
|
||||
return exports.create(func).delayTicks(time).submit(plugin);
|
||||
};
|
||||
/**
|
||||
* 运行循环任务
|
||||
* @constructor (任务,执行间隔).
|
||||
* @constructor (任务,首次延时,执行间隔)
|
||||
*/
|
||||
exports.timer = function () {
|
||||
switch (arguments.length) {
|
||||
case 2:
|
||||
return exports.create(arguments[0]).intervalTicks(arguments[1]).submit(plugin);
|
||||
case 3:
|
||||
return exports.create(arguments[0]).delayTicks(arguments[1]).intervalTicks(arguments[2]).submit(plugin);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 运行异步任务
|
||||
* @param func function 任务
|
||||
*/
|
||||
exports.async = function (func) {
|
||||
return exports.create(func).async().submit(plugin);
|
||||
};
|
||||
/**
|
||||
* 延时运行异步任务
|
||||
* @param func 任务
|
||||
* @param time 延时时间
|
||||
*/
|
||||
exports.laterAsync = function (func, time) {
|
||||
return exports.create(func).async().delayTicks(time).submit(plugin);
|
||||
};
|
||||
/**
|
||||
* 运行异步循环任务
|
||||
* @constructor (任务,执行间隔).
|
||||
* @constructor (任务,首次延时,执行间隔)
|
||||
*/
|
||||
exports.timerAsync = function () {
|
||||
switch (arguments.length) {
|
||||
case 2:
|
||||
return exports.create(arguments[0]).async().intervalTicks(arguments[1]).submit(plugin);
|
||||
case 3:
|
||||
return exports.create(arguments[0]).async().delayTicks(arguments[1]).intervalTicks(arguments[2]).submit(plugin);
|
||||
}
|
||||
};
|
@ -1,19 +0,0 @@
|
||||
/**
|
||||
* Sponge 玩家方法代理类
|
||||
* Created by 蒋天蓓 on 2018/1/5 0009.
|
||||
*/
|
||||
/*global Java, base, module, exports, require*/
|
||||
var ref = require('reflect');
|
||||
var Text = Java.type('org.spongepowered.api.text.Text');
|
||||
var Player = {
|
||||
createNew: function createNew(inner) {
|
||||
var player = {};
|
||||
player.handler = inner;
|
||||
player.sendMessage = function (msg) {
|
||||
this.handler.sendMessage(Text.of(msg));
|
||||
};
|
||||
return Object.assign(ref.mapToObject(inner), player);
|
||||
}
|
||||
};
|
||||
|
||||
exports.$ = Player.createNew;
|
@ -1,225 +0,0 @@
|
||||
/*
|
||||
* $Id: base64.js,v 2.15 2014/04/05 12:58:57 dankogai Exp dankogai $
|
||||
*
|
||||
* Licensed under the BSD 3-Clause License.
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
* References:
|
||||
* http://en.wikipedia.org/wiki/Base64
|
||||
*/
|
||||
|
||||
(function (global) {
|
||||
'use strict';
|
||||
// existing version for noConflict()
|
||||
var _Base64 = global.Base64;
|
||||
var version = "2.3.2";
|
||||
// if node.js, we use Buffer
|
||||
var buffer;
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
try {
|
||||
buffer = require('buffer').Buffer;
|
||||
} catch (err) {
|
||||
}
|
||||
}
|
||||
// constants
|
||||
var b64chars
|
||||
= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
||||
var b64tab = function (bin) {
|
||||
var t = {};
|
||||
for (var i = 0, l = bin.length; i < l; i++) t[bin.charAt(i)] = i;
|
||||
return t;
|
||||
}(b64chars);
|
||||
var fromCharCode = String.fromCharCode;
|
||||
// encoder stuff
|
||||
var cb_utob = function (c) {
|
||||
if (c.length < 2) {
|
||||
var cc = c.charCodeAt(0);
|
||||
return cc < 0x80 ? c
|
||||
: cc < 0x800 ? (fromCharCode(0xc0 | (cc >>> 6))
|
||||
+ fromCharCode(0x80 | (cc & 0x3f)))
|
||||
: (fromCharCode(0xe0 | ((cc >>> 12) & 0x0f))
|
||||
+ fromCharCode(0x80 | ((cc >>> 6) & 0x3f))
|
||||
+ fromCharCode(0x80 | ( cc & 0x3f)));
|
||||
} else {
|
||||
var ccc = 0x10000
|
||||
+ (c.charCodeAt(0) - 0xD800) * 0x400
|
||||
+ (c.charCodeAt(1) - 0xDC00);
|
||||
return (fromCharCode(0xf0 | ((ccc >>> 18) & 0x07))
|
||||
+ fromCharCode(0x80 | ((ccc >>> 12) & 0x3f))
|
||||
+ fromCharCode(0x80 | ((ccc >>> 6) & 0x3f))
|
||||
+ fromCharCode(0x80 | ( ccc & 0x3f)));
|
||||
}
|
||||
};
|
||||
var re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g;
|
||||
var utob = function (u) {
|
||||
return u.replace(re_utob, cb_utob);
|
||||
};
|
||||
var cb_encode = function (ccc) {
|
||||
var padlen = [0, 2, 1][ccc.length % 3],
|
||||
ord = ccc.charCodeAt(0) << 16
|
||||
| ((ccc.length > 1 ? ccc.charCodeAt(1) : 0) << 8)
|
||||
| ((ccc.length > 2 ? ccc.charCodeAt(2) : 0)),
|
||||
chars = [
|
||||
b64chars.charAt(ord >>> 18),
|
||||
b64chars.charAt((ord >>> 12) & 63),
|
||||
padlen >= 2 ? '=' : b64chars.charAt((ord >>> 6) & 63),
|
||||
padlen >= 1 ? '=' : b64chars.charAt(ord & 63)
|
||||
];
|
||||
return chars.join('');
|
||||
};
|
||||
var btoa = global.btoa ? function (b) {
|
||||
return global.btoa(b);
|
||||
} : function (b) {
|
||||
return b.replace(/[\s\S]{1,3}/g, cb_encode);
|
||||
};
|
||||
var _encode = buffer ?
|
||||
buffer.from && buffer.from !== Uint8Array.from ? function (u) {
|
||||
return (u.constructor === buffer.constructor ? u : buffer.from(u))
|
||||
.toString('base64')
|
||||
}
|
||||
: function (u) {
|
||||
return (u.constructor === buffer.constructor ? u : new buffer(u))
|
||||
.toString('base64')
|
||||
}
|
||||
: function (u) {
|
||||
return btoa(utob(u))
|
||||
}
|
||||
;
|
||||
var encode = function (u, urisafe) {
|
||||
return !urisafe
|
||||
? _encode(String(u))
|
||||
: _encode(String(u)).replace(/[+\/]/g, function (m0) {
|
||||
return m0 === '+' ? '-' : '_';
|
||||
}).replace(/=/g, '');
|
||||
};
|
||||
var encodeURI = function (u) {
|
||||
return encode(u, true)
|
||||
};
|
||||
// decoder stuff
|
||||
var re_btou = new RegExp([
|
||||
'[\xC0-\xDF][\x80-\xBF]',
|
||||
'[\xE0-\xEF][\x80-\xBF]{2}',
|
||||
'[\xF0-\xF7][\x80-\xBF]{3}'
|
||||
].join('|'), 'g');
|
||||
var cb_btou = function (cccc) {
|
||||
switch (cccc.length) {
|
||||
case 4:
|
||||
var cp = ((0x07 & cccc.charCodeAt(0)) << 18)
|
||||
| ((0x3f & cccc.charCodeAt(1)) << 12)
|
||||
| ((0x3f & cccc.charCodeAt(2)) << 6)
|
||||
| (0x3f & cccc.charCodeAt(3)),
|
||||
offset = cp - 0x10000;
|
||||
return (fromCharCode((offset >>> 10) + 0xD800)
|
||||
+ fromCharCode((offset & 0x3FF) + 0xDC00));
|
||||
case 3:
|
||||
return fromCharCode(
|
||||
((0x0f & cccc.charCodeAt(0)) << 12)
|
||||
| ((0x3f & cccc.charCodeAt(1)) << 6)
|
||||
| (0x3f & cccc.charCodeAt(2))
|
||||
);
|
||||
default:
|
||||
return fromCharCode(
|
||||
((0x1f & cccc.charCodeAt(0)) << 6)
|
||||
| (0x3f & cccc.charCodeAt(1))
|
||||
);
|
||||
}
|
||||
};
|
||||
var btou = function (b) {
|
||||
return b.replace(re_btou, cb_btou);
|
||||
};
|
||||
var cb_decode = function (cccc) {
|
||||
var len = cccc.length,
|
||||
padlen = len % 4,
|
||||
n = (len > 0 ? b64tab[cccc.charAt(0)] << 18 : 0)
|
||||
| (len > 1 ? b64tab[cccc.charAt(1)] << 12 : 0)
|
||||
| (len > 2 ? b64tab[cccc.charAt(2)] << 6 : 0)
|
||||
| (len > 3 ? b64tab[cccc.charAt(3)] : 0),
|
||||
chars = [
|
||||
fromCharCode(n >>> 16),
|
||||
fromCharCode((n >>> 8) & 0xff),
|
||||
fromCharCode(n & 0xff)
|
||||
];
|
||||
chars.length -= [0, 0, 2, 1][padlen];
|
||||
return chars.join('');
|
||||
};
|
||||
var atob = global.atob ? function (a) {
|
||||
return global.atob(a);
|
||||
} : function (a) {
|
||||
return a.replace(/[\s\S]{1,4}/g, cb_decode);
|
||||
};
|
||||
var _decode = buffer ?
|
||||
buffer.from && buffer.from !== Uint8Array.from ? function (a) {
|
||||
return (a.constructor === buffer.constructor
|
||||
? a : buffer.from(a, 'base64')).toString();
|
||||
}
|
||||
: function (a) {
|
||||
return (a.constructor === buffer.constructor
|
||||
? a : new buffer(a, 'base64')).toString();
|
||||
}
|
||||
: function (a) {
|
||||
return btou(atob(a))
|
||||
};
|
||||
var decode = function (a) {
|
||||
return _decode(
|
||||
String(a).replace(/[-_]/g, function (m0) {
|
||||
return m0 === '-' ? '+' : '/'
|
||||
})
|
||||
.replace(/[^A-Za-z0-9+\/]/g, '')
|
||||
);
|
||||
};
|
||||
var noConflict = function () {
|
||||
var Base64 = global.Base64;
|
||||
global.Base64 = _Base64;
|
||||
return Base64;
|
||||
};
|
||||
// export Base64
|
||||
global.Base64 = {
|
||||
VERSION: version,
|
||||
atob: atob,
|
||||
btoa: btoa,
|
||||
fromBase64: decode,
|
||||
toBase64: encode,
|
||||
utob: utob,
|
||||
encode: encode,
|
||||
encodeURI: encodeURI,
|
||||
btou: btou,
|
||||
decode: decode,
|
||||
noConflict: noConflict
|
||||
};
|
||||
// if ES5 is available, make Base64.extendString() available
|
||||
if (typeof Object.defineProperty === 'function') {
|
||||
var noEnum = function (v) {
|
||||
return {value: v, enumerable: false, writable: true, configurable: true};
|
||||
};
|
||||
global.Base64.extendString = function () {
|
||||
Object.defineProperty(
|
||||
String.prototype, 'fromBase64', noEnum(function () {
|
||||
return decode(this)
|
||||
}));
|
||||
Object.defineProperty(
|
||||
String.prototype, 'toBase64', noEnum(function (urisafe) {
|
||||
return encode(this, urisafe)
|
||||
}));
|
||||
Object.defineProperty(
|
||||
String.prototype, 'toBase64URI', noEnum(function () {
|
||||
return encode(this, true)
|
||||
}));
|
||||
};
|
||||
}
|
||||
// module.exports and AMD are mutually exclusive.
|
||||
// module.exports has precedence.
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = global.Base64;
|
||||
}
|
||||
else if (typeof define === 'function' && define.amd) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define([], function () {
|
||||
return global.Base64
|
||||
});
|
||||
}
|
||||
// that's it!
|
||||
})(typeof self !== 'undefined' ? self
|
||||
: typeof window !== 'undefined' ? window
|
||||
: typeof global !== 'undefined' ? global
|
||||
: this
|
||||
);
|
@ -1,145 +0,0 @@
|
||||
'use strict';
|
||||
/**
|
||||
* HTTP 网络类
|
||||
* Created by 蒋天蓓 on 2017/2/9 0009.
|
||||
*/
|
||||
|
||||
/*global Java, base, module, exports, require, __FILE__*/
|
||||
|
||||
var URL = Java.type("java.net.URL");
|
||||
var Files = Java.type("java.nio.file.Files");
|
||||
var Paths = Java.type("java.nio.file.Paths");
|
||||
var String = Java.type("java.lang.String");
|
||||
|
||||
var HttpURLConnection = Java.type("java.net.HttpURLConnection");
|
||||
var HttpsURLConnection = Java.type("javax.net.ssl.HttpsURLConnection");
|
||||
var SSLContext = Java.type("javax.net.ssl.SSLContext");
|
||||
|
||||
var HostnameVerifier = Java.type("javax.net.ssl.HostnameVerifier");
|
||||
var X509TrustManager = Java.type("javax.net.ssl.X509TrustManager");
|
||||
|
||||
var TrustAnyHostnameVerifier = new HostnameVerifier({
|
||||
verify: function (hostname, session) {
|
||||
return true;
|
||||
}
|
||||
})
|
||||
|
||||
var SSLSocketFactory = function initSSLSocketFactory() {
|
||||
var sslContext = SSLContext.getInstance("TLS");
|
||||
sslContext.init(null, [new X509TrustManager({
|
||||
getAcceptedIssuers: function () {
|
||||
return null;
|
||||
},
|
||||
checkClientTrusted: function (chain, authType) {},
|
||||
checkServerTrusted: function (chain, authType) {}
|
||||
})], new java.security.SecureRandom());
|
||||
return sslContext.getSocketFactory();
|
||||
}();
|
||||
|
||||
var config = {
|
||||
Charset: 'UTF-8',
|
||||
ConnectTimeout: 10000,
|
||||
ReadTimeout: 10000,
|
||||
Debug: false
|
||||
}
|
||||
|
||||
function open(url, method, header) {
|
||||
// conn.setRequestProperty
|
||||
var conn = new URL(url).openConnection();
|
||||
if (conn instanceof HttpsURLConnection) {
|
||||
conn.setHostnameVerifier(TrustAnyHostnameVerifier);
|
||||
conn.setSSLSocketFactory(SSLSocketFactory);
|
||||
}
|
||||
conn.setRequestMethod(method);
|
||||
conn.setDoOutput(true);
|
||||
conn.setDoInput(true);
|
||||
conn.setConnectTimeout(config.ConnectTimeout);
|
||||
conn.setReadTimeout(config.ReadTimeout);
|
||||
if (header) {
|
||||
for (var key in header) {
|
||||
conn.setRequestProperty(key, header[key]);
|
||||
}
|
||||
}
|
||||
return conn;
|
||||
}
|
||||
|
||||
function buildUrl(url, params) {
|
||||
if (params && Object.keys(params).length > 0) {
|
||||
var queryStart = url.indexOf('?');
|
||||
if (queryStart == -1) {
|
||||
url += '?';
|
||||
}
|
||||
return url += object2URLSearchParams(params);
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
function request(config) {
|
||||
var conn = open(buildUrl(config.url, config.query), config.method, config.header);
|
||||
try {
|
||||
conn.connect();
|
||||
var data = config.data;
|
||||
if (data) {
|
||||
var out = conn.getOutputStream();
|
||||
if (typeof data === "object") {
|
||||
var type = config.header['Content-Type'];
|
||||
switch (type) {
|
||||
case "application/x-www-form-urlencoded":
|
||||
data = object2URLSearchParams(params);
|
||||
default:
|
||||
data = JSON.stringify(data)
|
||||
}
|
||||
}
|
||||
out.write(new String(data).getBytes(config.Charset));
|
||||
out.flush();
|
||||
out.close();
|
||||
}
|
||||
return response(conn);
|
||||
} finally {
|
||||
conn.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
function response (conn) {
|
||||
var temp = Paths.get(java.lang.System.getProperty("java.io.tmpdir"), java.util.UUID.randomUUID().toString());
|
||||
Files.copy(conn.getInputStream(), temp);
|
||||
var result = new String(Files.readAllBytes(temp), config.Charset);
|
||||
var tempFile = temp.toFile();
|
||||
tempFile.delete() || tempFile.deleteOnExit();
|
||||
return result;
|
||||
}
|
||||
|
||||
function object2URLSearchParams (params) {
|
||||
var temp = []
|
||||
for (var key in params) {
|
||||
temp.push('%s=%s'.format(encodeURIComponent(key), encodeURIComponent(params[key])))
|
||||
}
|
||||
return temp.join('&')
|
||||
}
|
||||
|
||||
var http = {
|
||||
config: config,
|
||||
request: request
|
||||
};
|
||||
|
||||
['GET', 'DELETE', 'HEAD', 'OPTIONS'].forEach(function (method) {
|
||||
http[method.toLowerCase()] = function __likeGet__(url, data, config) {
|
||||
return this.request(Object.assign(config || {}, {
|
||||
url: url,
|
||||
method: method,
|
||||
query: data
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
['POST', 'PUT', 'PATCH'].forEach(function (method) {
|
||||
http[method.toLowerCase()] = function __likePost__(url, data, config) {
|
||||
return this.request(Object.assign(config || {}, {
|
||||
url: url,
|
||||
method: method,
|
||||
data: data
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
exports = module.exports = http;
|
@ -1,185 +0,0 @@
|
||||
'use strict';
|
||||
/**
|
||||
* 反射工具类
|
||||
* Created by 蒋天蓓 on 2017/2/9 0009.
|
||||
*/
|
||||
|
||||
/*global Java, base, module, exports, require, __FILE__*/
|
||||
var Class = Java.type('java.lang.Class');
|
||||
var NoSuchFieldException = Java.type('java.lang.NoSuchFieldException');
|
||||
var methodCache = [];
|
||||
|
||||
function Reflect(obj) {
|
||||
if (obj instanceof Class) {
|
||||
this.obj = null;
|
||||
this.class = obj;
|
||||
} else {
|
||||
this.obj = obj;
|
||||
this.class = obj.class;
|
||||
}
|
||||
|
||||
this.field = function (name) {
|
||||
try {
|
||||
// Try getting a public field
|
||||
var field = this.class.field(name);
|
||||
return on(field.get(this.obj));
|
||||
} catch (ex) {
|
||||
// Try again, getting a non-public field
|
||||
try {
|
||||
return on(accessible(declaredField(this.class, name)).get(this.obj));
|
||||
} catch (ex) {
|
||||
throw new NoSuchFieldException(ex);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.call = function () {
|
||||
var name = arguments[0];
|
||||
var params = Array.prototype.slice.call(arguments, 1);
|
||||
var method = declaredMethod(this.class, name, types(params));
|
||||
return on(method.invoke(this.get(), params));
|
||||
};
|
||||
|
||||
this.get = function () {
|
||||
return arguments.length === 1 ? this.field(arguments[0]) : this.obj;
|
||||
};
|
||||
|
||||
this.set = function (name, value) {
|
||||
accessible(declaredField(this.class, name)).set(this.obj, value);
|
||||
return this;
|
||||
};
|
||||
|
||||
this.create = function () {
|
||||
var param = Array.prototype.slice.call(arguments);
|
||||
return on(declaredConstructor(this.class, param).newInstance(param));
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of types for an array of objects
|
||||
*/
|
||||
function types(values, def) {
|
||||
if (values === null) {
|
||||
return [];
|
||||
}
|
||||
var result = [];
|
||||
values.forEach(function (t) {
|
||||
result.push((t || def) ? Object.class : t instanceof Class ? t : t.class)
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
function accessible(accessible) {
|
||||
if (accessible === null) {
|
||||
return null;
|
||||
}
|
||||
if (!accessible.isAccessible()) {
|
||||
accessible.setAccessible(true);
|
||||
}
|
||||
return accessible;
|
||||
}
|
||||
|
||||
function declaredConstructor(clazz, param) {
|
||||
var constructor;
|
||||
try {
|
||||
constructor = clazz.getDeclaredConstructor(types(param));
|
||||
} catch (ex) {
|
||||
try {
|
||||
constructor = clazz.getDeclaredConstructor(types(param, true));
|
||||
} catch (ex) {
|
||||
constructor = clazz.getDeclaredConstructors()[0];
|
||||
}
|
||||
}
|
||||
return accessible(constructor);
|
||||
}
|
||||
|
||||
function declaredField(clazz, name) {
|
||||
var field = null;
|
||||
// noinspection JSUnresolvedVariable
|
||||
while (clazz !== java.lang.Object.class) {
|
||||
try {
|
||||
field = clazz.getDeclaredField(name);
|
||||
if (field !== null) {
|
||||
break;
|
||||
}
|
||||
} catch (e) {
|
||||
clazz = clazz.getSuperclass();
|
||||
}
|
||||
}
|
||||
if (field === null) {
|
||||
throw new NoSuchFieldException(name + " is not found in " + clazz.name);
|
||||
}
|
||||
return field;
|
||||
}
|
||||
|
||||
function declaredMethod(clazz, name, clazzs) {
|
||||
var mkey = clazz.name + '.' + name + ':' + (clazzs || []).join(':');
|
||||
if (!methodCache[mkey]) {
|
||||
try {
|
||||
methodCache[mkey] = clazz.getMethod(name, clazzs);
|
||||
} catch (ex) {
|
||||
methodCache[mkey] = clazz.getDeclaredMethod(name, clazzs);
|
||||
}
|
||||
}
|
||||
return methodCache[mkey];
|
||||
}
|
||||
|
||||
function declaredMethod(clazz, name, clazzs) {
|
||||
var mkey = clazz.name + '.' + name + ':' + (clazzs || []).join(':');
|
||||
if (!methodCache[mkey]) {
|
||||
try {
|
||||
methodCache[mkey] = clazz.getMethod(name, clazzs);
|
||||
} catch (ex) {
|
||||
methodCache[mkey] = clazz.getDeclaredMethod(name, clazzs);
|
||||
}
|
||||
}
|
||||
return methodCache[mkey];
|
||||
}
|
||||
|
||||
function declaredMethods(clazz) {
|
||||
return clazz.declaredMethods;
|
||||
}
|
||||
|
||||
var classMethodsCache = [];
|
||||
|
||||
function mapToObject(javaObj) {
|
||||
if (!javaObj || !javaObj.class) { throw new TypeError('参数 %s 不是一个Java对象!'.format(javaObj)) }
|
||||
var target = {};
|
||||
getJavaObjectMethods(javaObj).forEach(function proxyMethod(t){ mapMethod(target, javaObj, t) })
|
||||
return target;
|
||||
}
|
||||
|
||||
function getJavaObjectMethods(javaObj) {
|
||||
var className = javaObj.class.name
|
||||
if (!classMethodsCache[className]) {
|
||||
var names = [];
|
||||
var methods = javaObj.class.methods;
|
||||
for (var i in methods){
|
||||
names.push(methods[i].name);
|
||||
}
|
||||
classMethodsCache[className] = names;
|
||||
}
|
||||
return classMethodsCache[className];
|
||||
}
|
||||
|
||||
function mapMethod (target, source, name) {
|
||||
target[name] = function __SimpleDynamicMethod__() {
|
||||
if (arguments.length > 0) {
|
||||
return source[name](Array.prototype.slice.call(arguments));
|
||||
} else {
|
||||
return source[name]();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function on(obj) {
|
||||
if (!obj || !obj.class) { throw new TypeError('参数 %s 不是一个Java对象!'.format(obj)) }
|
||||
return new Reflect(obj);
|
||||
}
|
||||
|
||||
exports = module.exports = {
|
||||
on: on,
|
||||
accessible: accessible,
|
||||
declaredMethods: declaredMethods,
|
||||
mapToObject: mapToObject
|
||||
}
|
@ -1,139 +0,0 @@
|
||||
/*global Java, base, module, exports, require*/
|
||||
var chat = require('api/chat');
|
||||
|
||||
var ChatMessagePart = function () {
|
||||
var text;
|
||||
var clickEventAction;
|
||||
var clickEventValue;
|
||||
var hoverEventAction;
|
||||
var hoverEventValue;
|
||||
var insertion;
|
||||
|
||||
this.click = function (action, value) {
|
||||
this.clickEventAction = action;
|
||||
this.clickEventValue = value;
|
||||
}
|
||||
|
||||
this.hover = function (action, value) {
|
||||
this.hoverEventAction = action;
|
||||
this.hoverEventValue = value;
|
||||
console.log(this.toJson());
|
||||
}
|
||||
|
||||
this.convert = function () {
|
||||
var str = {};
|
||||
if (this.text) {
|
||||
str.text = this.text;
|
||||
}
|
||||
if (this.clickEventAction) {
|
||||
str.clickEvent = {
|
||||
"action": this.clickEventAction,
|
||||
"value": this.clickEventValue
|
||||
}
|
||||
}
|
||||
if (this.hoverEventAction) {
|
||||
str.hoverEvent = {
|
||||
"action": this.hoverEventAction,
|
||||
"value": this.hoverEventValue
|
||||
}
|
||||
}
|
||||
if (this.insertion) {
|
||||
str.insertion = this.insertion;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
var Tellraw = function () {
|
||||
var parts = [new ChatMessagePart()];
|
||||
var self = this;
|
||||
var cache = null;
|
||||
|
||||
this.then = function (part) {
|
||||
if (typeof part === "string") {
|
||||
var newPart = new ChatMessagePart();
|
||||
newPart.text = part;
|
||||
this.then(newPart);
|
||||
return self;
|
||||
}
|
||||
var last = this.latest();
|
||||
if (!last.text) {
|
||||
last.text = part.text;
|
||||
} else {
|
||||
parts.push(part);
|
||||
}
|
||||
this.cache = null;
|
||||
}
|
||||
|
||||
this.text = function (text) {
|
||||
this.latest().text = text;
|
||||
return this;
|
||||
}
|
||||
|
||||
this.tip = function (str) {
|
||||
if (toString.call(str) === "[object Array]") {
|
||||
str = str.join("\n");
|
||||
}
|
||||
this.latest().hover("show_text", str);
|
||||
return this;
|
||||
}
|
||||
|
||||
this.item = function (str) {
|
||||
this.latest().hover("show_item", str);
|
||||
return this;
|
||||
}
|
||||
|
||||
this.cmd = this.command = function (command) {
|
||||
this.latest().click("run_command", command);
|
||||
return this;
|
||||
}
|
||||
|
||||
this.suggest = function (url) {
|
||||
this.latest().click("suggest_command", url);
|
||||
return this;
|
||||
}
|
||||
|
||||
this.file = function (path) {
|
||||
this.latest().click("open_file", path);
|
||||
return this;
|
||||
}
|
||||
|
||||
this.link = function (url) {
|
||||
this.latest().click("open_url", url);
|
||||
return this;
|
||||
}
|
||||
|
||||
this.latest = function () {
|
||||
return parts[parts.length - 1];
|
||||
}
|
||||
|
||||
this.json = function () {
|
||||
if (!this.cache) {
|
||||
var temp = [];
|
||||
parts.forEach(function (t) {
|
||||
temp.push(t.convert());
|
||||
})
|
||||
this.cache = JSON.stringify(temp);
|
||||
console.debug(this.cache);
|
||||
}
|
||||
return this.cache;
|
||||
}
|
||||
|
||||
this.send = function (player) {
|
||||
chat.json(player, self.json());
|
||||
}
|
||||
|
||||
this.sendAll = function () {
|
||||
server.players(function sendAllMessage(p) {
|
||||
self.send(p);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Tellraw.create = function () {
|
||||
return new Tellraw().then(Tellraw.duplicateChar);
|
||||
}
|
||||
|
||||
Tellraw.duplicateChar = '§卐';
|
||||
|
||||
exports = module.exports = Tellraw;
|
@ -1,35 +0,0 @@
|
||||
'use strict';
|
||||
/**
|
||||
* 常用工具类
|
||||
* Created by 蒋天蓓 on 2018/5/12 0009.
|
||||
*/
|
||||
/*global Java, base, module, exports, require, __FILE__*/
|
||||
var Arrays = Java.type('java.util.Arrays');
|
||||
|
||||
function toStr(obj) {
|
||||
if (obj.class) {
|
||||
return Arrays.toString()
|
||||
}
|
||||
}
|
||||
|
||||
function compare(prop) {
|
||||
return function (obj1, obj2) {
|
||||
var val1 = obj1[prop];
|
||||
var val2 = obj2[prop];
|
||||
if (!isNaN(Number(val1)) && !isNaN(Number(val2))) {
|
||||
val1 = Number(val1);
|
||||
val2 = Number(val2);
|
||||
}
|
||||
if (val1 < val2) {
|
||||
return -1;
|
||||
} else if (val1 > val2) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exports = module.exports = {
|
||||
compare: compare
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
|
||||
var loader = require('./js-yaml/loader');
|
||||
var dumper = require('./js-yaml/dumper');
|
||||
|
||||
|
||||
function deprecated(name) {
|
||||
return function () {
|
||||
throw new Error('Function ' + name + ' is deprecated and cannot be used.');
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
module.exports.Type = require('./js-yaml/type');
|
||||
module.exports.Schema = require('./js-yaml/schema');
|
||||
module.exports.FAILSAFE_SCHEMA = require('./js-yaml/schema/failsafe');
|
||||
module.exports.JSON_SCHEMA = require('./js-yaml/schema/json');
|
||||
module.exports.CORE_SCHEMA = require('./js-yaml/schema/core');
|
||||
module.exports.DEFAULT_SAFE_SCHEMA = require('./js-yaml/schema/default_safe');
|
||||
module.exports.DEFAULT_FULL_SCHEMA = require('./js-yaml/schema/default_full');
|
||||
module.exports.load = loader.load;
|
||||
module.exports.loadAll = loader.loadAll;
|
||||
module.exports.safeLoad = loader.safeLoad;
|
||||
module.exports.safeLoadAll = loader.safeLoadAll;
|
||||
module.exports.dump = dumper.dump;
|
||||
module.exports.safeDump = dumper.safeDump;
|
||||
module.exports.YAMLException = require('./js-yaml/exception');
|
||||
|
||||
// Deprecated schema names from JS-YAML 2.0.x
|
||||
module.exports.MINIMAL_SCHEMA = require('./js-yaml/schema/failsafe');
|
||||
module.exports.SAFE_SCHEMA = require('./js-yaml/schema/default_safe');
|
||||
module.exports.DEFAULT_SCHEMA = require('./js-yaml/schema/default_full');
|
||||
|
||||
// Deprecated functions from JS-YAML 1.x.x
|
||||
module.exports.scan = deprecated('scan');
|
||||
module.exports.parse = deprecated('parse');
|
||||
module.exports.compose = deprecated('compose');
|
||||
module.exports.addConstructor = deprecated('addConstructor');
|
@ -1,59 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
|
||||
function isNothing(subject) {
|
||||
return (typeof subject === 'undefined') || (subject === null);
|
||||
}
|
||||
|
||||
|
||||
function isObject(subject) {
|
||||
return (typeof subject === 'object') && (subject !== null);
|
||||
}
|
||||
|
||||
|
||||
function toArray(sequence) {
|
||||
if (Array.isArray(sequence)) return sequence;
|
||||
else if (isNothing(sequence)) return [];
|
||||
|
||||
return [ sequence ];
|
||||
}
|
||||
|
||||
|
||||
function extend(target, source) {
|
||||
var index, length, key, sourceKeys;
|
||||
|
||||
if (source) {
|
||||
sourceKeys = Object.keys(source);
|
||||
|
||||
for (index = 0, length = sourceKeys.length; index < length; index += 1) {
|
||||
key = sourceKeys[index];
|
||||
target[key] = source[key];
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
|
||||
function repeat(string, count) {
|
||||
var result = '', cycle;
|
||||
|
||||
for (cycle = 0; cycle < count; cycle += 1) {
|
||||
result += string;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
function isNegativeZero(number) {
|
||||
return (number === 0) && (Number.NEGATIVE_INFINITY === 1 / number);
|
||||
}
|
||||
|
||||
|
||||
module.exports.isNothing = isNothing;
|
||||
module.exports.isObject = isObject;
|
||||
module.exports.toArray = toArray;
|
||||
module.exports.repeat = repeat;
|
||||
module.exports.isNegativeZero = isNegativeZero;
|
||||
module.exports.extend = extend;
|
@ -1,819 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/*eslint-disable no-use-before-define*/
|
||||
|
||||
var common = require('./common');
|
||||
var YAMLException = require('./exception');
|
||||
var DEFAULT_FULL_SCHEMA = require('./schema/default_full');
|
||||
var DEFAULT_SAFE_SCHEMA = require('./schema/default_safe');
|
||||
|
||||
var _toString = Object.prototype.toString;
|
||||
var _hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
|
||||
var CHAR_TAB = 0x09; /* Tab */
|
||||
var CHAR_LINE_FEED = 0x0A; /* LF */
|
||||
var CHAR_SPACE = 0x20; /* Space */
|
||||
var CHAR_EXCLAMATION = 0x21; /* ! */
|
||||
var CHAR_DOUBLE_QUOTE = 0x22; /* " */
|
||||
var CHAR_SHARP = 0x23; /* # */
|
||||
var CHAR_PERCENT = 0x25; /* % */
|
||||
var CHAR_AMPERSAND = 0x26; /* & */
|
||||
var CHAR_SINGLE_QUOTE = 0x27; /* ' */
|
||||
var CHAR_ASTERISK = 0x2A; /* * */
|
||||
var CHAR_COMMA = 0x2C; /* , */
|
||||
var CHAR_MINUS = 0x2D; /* - */
|
||||
var CHAR_COLON = 0x3A; /* : */
|
||||
var CHAR_GREATER_THAN = 0x3E; /* > */
|
||||
var CHAR_QUESTION = 0x3F; /* ? */
|
||||
var CHAR_COMMERCIAL_AT = 0x40; /* @ */
|
||||
var CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */
|
||||
var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */
|
||||
var CHAR_GRAVE_ACCENT = 0x60; /* ` */
|
||||
var CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */
|
||||
var CHAR_VERTICAL_LINE = 0x7C; /* | */
|
||||
var CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */
|
||||
|
||||
var ESCAPE_SEQUENCES = {};
|
||||
|
||||
ESCAPE_SEQUENCES[0x00] = '\\0';
|
||||
ESCAPE_SEQUENCES[0x07] = '\\a';
|
||||
ESCAPE_SEQUENCES[0x08] = '\\b';
|
||||
ESCAPE_SEQUENCES[0x09] = '\\t';
|
||||
ESCAPE_SEQUENCES[0x0A] = '\\n';
|
||||
ESCAPE_SEQUENCES[0x0B] = '\\v';
|
||||
ESCAPE_SEQUENCES[0x0C] = '\\f';
|
||||
ESCAPE_SEQUENCES[0x0D] = '\\r';
|
||||
ESCAPE_SEQUENCES[0x1B] = '\\e';
|
||||
ESCAPE_SEQUENCES[0x22] = '\\"';
|
||||
ESCAPE_SEQUENCES[0x5C] = '\\\\';
|
||||
ESCAPE_SEQUENCES[0x85] = '\\N';
|
||||
ESCAPE_SEQUENCES[0xA0] = '\\_';
|
||||
ESCAPE_SEQUENCES[0x2028] = '\\L';
|
||||
ESCAPE_SEQUENCES[0x2029] = '\\P';
|
||||
|
||||
var DEPRECATED_BOOLEANS_SYNTAX = [
|
||||
'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON',
|
||||
'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF'
|
||||
];
|
||||
|
||||
function compileStyleMap(schema, map) {
|
||||
var result, keys, index, length, tag, style, type;
|
||||
|
||||
if (map === null) return {};
|
||||
|
||||
result = {};
|
||||
keys = Object.keys(map);
|
||||
|
||||
for (index = 0, length = keys.length; index < length; index += 1) {
|
||||
tag = keys[index];
|
||||
style = String(map[tag]);
|
||||
|
||||
if (tag.slice(0, 2) === '!!') {
|
||||
tag = 'tag:yaml.org,2002:' + tag.slice(2);
|
||||
}
|
||||
type = schema.compiledTypeMap['fallback'][tag];
|
||||
|
||||
if (type && _hasOwnProperty.call(type.styleAliases, style)) {
|
||||
style = type.styleAliases[style];
|
||||
}
|
||||
|
||||
result[tag] = style;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function encodeHex(character) {
|
||||
var string, handle, length;
|
||||
|
||||
string = character.toString(16).toUpperCase();
|
||||
|
||||
if (character <= 0xFF) {
|
||||
handle = 'x';
|
||||
length = 2;
|
||||
} else if (character <= 0xFFFF) {
|
||||
handle = 'u';
|
||||
length = 4;
|
||||
} else if (character <= 0xFFFFFFFF) {
|
||||
handle = 'U';
|
||||
length = 8;
|
||||
} else {
|
||||
throw new YAMLException('code point within a string may not be greater than 0xFFFFFFFF');
|
||||
}
|
||||
|
||||
return '\\' + handle + common.repeat('0', length - string.length) + string;
|
||||
}
|
||||
|
||||
function State(options) {
|
||||
this.schema = options['schema'] || DEFAULT_FULL_SCHEMA;
|
||||
this.indent = Math.max(1, (options['indent'] || 2));
|
||||
this.skipInvalid = options['skipInvalid'] || false;
|
||||
this.flowLevel = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']);
|
||||
this.styleMap = compileStyleMap(this.schema, options['styles'] || null);
|
||||
this.sortKeys = options['sortKeys'] || false;
|
||||
this.lineWidth = options['lineWidth'] || 80;
|
||||
this.noRefs = options['noRefs'] || false;
|
||||
this.noCompatMode = options['noCompatMode'] || false;
|
||||
this.condenseFlow = options['condenseFlow'] || false;
|
||||
|
||||
this.implicitTypes = this.schema.compiledImplicit;
|
||||
this.explicitTypes = this.schema.compiledExplicit;
|
||||
|
||||
this.tag = null;
|
||||
this.result = '';
|
||||
|
||||
this.duplicates = [];
|
||||
this.usedDuplicates = null;
|
||||
}
|
||||
|
||||
// Indents every line in a string. Empty lines (\n only) are not indented.
|
||||
function indentString(string, spaces) {
|
||||
var ind = common.repeat(' ', spaces),
|
||||
position = 0,
|
||||
next = -1,
|
||||
result = '',
|
||||
line,
|
||||
length = string.length;
|
||||
|
||||
while (position < length) {
|
||||
next = string.indexOf('\n', position);
|
||||
if (next === -1) {
|
||||
line = string.slice(position);
|
||||
position = length;
|
||||
} else {
|
||||
line = string.slice(position, next + 1);
|
||||
position = next + 1;
|
||||
}
|
||||
|
||||
if (line.length && line !== '\n') result += ind;
|
||||
|
||||
result += line;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function generateNextLine(state, level) {
|
||||
return '\n' + common.repeat(' ', state.indent * level);
|
||||
}
|
||||
|
||||
function testImplicitResolving(state, str) {
|
||||
var index, length, type;
|
||||
|
||||
for (index = 0, length = state.implicitTypes.length; index < length; index += 1) {
|
||||
type = state.implicitTypes[index];
|
||||
|
||||
if (type.resolve(str)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// [33] s-white ::= s-space | s-tab
|
||||
function isWhitespace(c) {
|
||||
return c === CHAR_SPACE || c === CHAR_TAB;
|
||||
}
|
||||
|
||||
// Returns true if the character can be printed without escaping.
|
||||
// From YAML 1.2: "any allowed characters known to be non-printable
|
||||
// should also be escaped. [However,] This isn’t mandatory"
|
||||
// Derived from nb-char - \t - #x85 - #xA0 - #x2028 - #x2029.
|
||||
function isPrintable(c) {
|
||||
return (0x00020 <= c && c <= 0x00007E)
|
||||
|| ((0x000A1 <= c && c <= 0x00D7FF) && c !== 0x2028 && c !== 0x2029)
|
||||
|| ((0x0E000 <= c && c <= 0x00FFFD) && c !== 0xFEFF /* BOM */)
|
||||
|| (0x10000 <= c && c <= 0x10FFFF);
|
||||
}
|
||||
|
||||
// Simplified test for values allowed after the first character in plain style.
|
||||
function isPlainSafe(c) {
|
||||
// Uses a subset of nb-char - c-flow-indicator - ":" - "#"
|
||||
// where nb-char ::= c-printable - b-char - c-byte-order-mark.
|
||||
return isPrintable(c) && c !== 0xFEFF
|
||||
// - c-flow-indicator
|
||||
&& c !== CHAR_COMMA
|
||||
&& c !== CHAR_LEFT_SQUARE_BRACKET
|
||||
&& c !== CHAR_RIGHT_SQUARE_BRACKET
|
||||
&& c !== CHAR_LEFT_CURLY_BRACKET
|
||||
&& c !== CHAR_RIGHT_CURLY_BRACKET
|
||||
// - ":" - "#"
|
||||
&& c !== CHAR_COLON
|
||||
&& c !== CHAR_SHARP;
|
||||
}
|
||||
|
||||
// Simplified test for values allowed as the first character in plain style.
|
||||
function isPlainSafeFirst(c) {
|
||||
// Uses a subset of ns-char - c-indicator
|
||||
// where ns-char = nb-char - s-white.
|
||||
return isPrintable(c) && c !== 0xFEFF
|
||||
&& !isWhitespace(c) // - s-white
|
||||
// - (c-indicator ::=
|
||||
// “-” | “?” | “:” | “,” | “[” | “]” | “{” | “}”
|
||||
&& c !== CHAR_MINUS
|
||||
&& c !== CHAR_QUESTION
|
||||
&& c !== CHAR_COLON
|
||||
&& c !== CHAR_COMMA
|
||||
&& c !== CHAR_LEFT_SQUARE_BRACKET
|
||||
&& c !== CHAR_RIGHT_SQUARE_BRACKET
|
||||
&& c !== CHAR_LEFT_CURLY_BRACKET
|
||||
&& c !== CHAR_RIGHT_CURLY_BRACKET
|
||||
// | “#” | “&” | “*” | “!” | “|” | “>” | “'” | “"”
|
||||
&& c !== CHAR_SHARP
|
||||
&& c !== CHAR_AMPERSAND
|
||||
&& c !== CHAR_ASTERISK
|
||||
&& c !== CHAR_EXCLAMATION
|
||||
&& c !== CHAR_VERTICAL_LINE
|
||||
&& c !== CHAR_GREATER_THAN
|
||||
&& c !== CHAR_SINGLE_QUOTE
|
||||
&& c !== CHAR_DOUBLE_QUOTE
|
||||
// | “%” | “@” | “`”)
|
||||
&& c !== CHAR_PERCENT
|
||||
&& c !== CHAR_COMMERCIAL_AT
|
||||
&& c !== CHAR_GRAVE_ACCENT;
|
||||
}
|
||||
|
||||
var STYLE_PLAIN = 1,
|
||||
STYLE_SINGLE = 2,
|
||||
STYLE_LITERAL = 3,
|
||||
STYLE_FOLDED = 4,
|
||||
STYLE_DOUBLE = 5;
|
||||
|
||||
// Determines which scalar styles are possible and returns the preferred style.
|
||||
// lineWidth = -1 => no limit.
|
||||
// Pre-conditions: str.length > 0.
|
||||
// Post-conditions:
|
||||
// STYLE_PLAIN or STYLE_SINGLE => no \n are in the string.
|
||||
// STYLE_LITERAL => no lines are suitable for folding (or lineWidth is -1).
|
||||
// STYLE_FOLDED => a line > lineWidth and can be folded (and lineWidth != -1).
|
||||
function chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth, testAmbiguousType) {
|
||||
var i;
|
||||
var char;
|
||||
var hasLineBreak = false;
|
||||
var hasFoldableLine = false; // only checked if shouldTrackWidth
|
||||
var shouldTrackWidth = lineWidth !== -1;
|
||||
var previousLineBreak = -1; // count the first line correctly
|
||||
var plain = isPlainSafeFirst(string.charCodeAt(0))
|
||||
&& !isWhitespace(string.charCodeAt(string.length - 1));
|
||||
|
||||
if (singleLineOnly) {
|
||||
// Case: no block styles.
|
||||
// Check for disallowed characters to rule out plain and single.
|
||||
for (i = 0; i < string.length; i++) {
|
||||
char = string.charCodeAt(i);
|
||||
if (!isPrintable(char)) {
|
||||
return STYLE_DOUBLE;
|
||||
}
|
||||
plain = plain && isPlainSafe(char);
|
||||
}
|
||||
} else {
|
||||
// Case: block styles permitted.
|
||||
for (i = 0; i < string.length; i++) {
|
||||
char = string.charCodeAt(i);
|
||||
if (char === CHAR_LINE_FEED) {
|
||||
hasLineBreak = true;
|
||||
// Check if any line can be folded.
|
||||
if (shouldTrackWidth) {
|
||||
hasFoldableLine = hasFoldableLine ||
|
||||
// Foldable line = too long, and not more-indented.
|
||||
(i - previousLineBreak - 1 > lineWidth &&
|
||||
string[previousLineBreak + 1] !== ' ');
|
||||
previousLineBreak = i;
|
||||
}
|
||||
} else if (!isPrintable(char)) {
|
||||
return STYLE_DOUBLE;
|
||||
}
|
||||
plain = plain && isPlainSafe(char);
|
||||
}
|
||||
// in case the end is missing a \n
|
||||
hasFoldableLine = hasFoldableLine || (shouldTrackWidth &&
|
||||
(i - previousLineBreak - 1 > lineWidth &&
|
||||
string[previousLineBreak + 1] !== ' '));
|
||||
}
|
||||
// Although every style can represent \n without escaping, prefer block styles
|
||||
// for multiline, since they're more readable and they don't add empty lines.
|
||||
// Also prefer folding a super-long line.
|
||||
if (!hasLineBreak && !hasFoldableLine) {
|
||||
// Strings interpretable as another type have to be quoted;
|
||||
// e.g. the string 'true' vs. the boolean true.
|
||||
return plain && !testAmbiguousType(string)
|
||||
? STYLE_PLAIN : STYLE_SINGLE;
|
||||
}
|
||||
// Edge case: block indentation indicator can only have one digit.
|
||||
if (string[0] === ' ' && indentPerLevel > 9) {
|
||||
return STYLE_DOUBLE;
|
||||
}
|
||||
// At this point we know block styles are valid.
|
||||
// Prefer literal style unless we want to fold.
|
||||
return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL;
|
||||
}
|
||||
|
||||
// Note: line breaking/folding is implemented for only the folded style.
|
||||
// NB. We drop the last trailing newline (if any) of a returned block scalar
|
||||
// since the dumper adds its own newline. This always works:
|
||||
// • No ending newline => unaffected; already using strip "-" chomping.
|
||||
// • Ending newline => removed then restored.
|
||||
// Importantly, this keeps the "+" chomp indicator from gaining an extra line.
|
||||
function writeScalar(state, string, level, iskey) {
|
||||
state.dump = (function () {
|
||||
if (string.length === 0) {
|
||||
return "''";
|
||||
}
|
||||
if (!state.noCompatMode &&
|
||||
DEPRECATED_BOOLEANS_SYNTAX.indexOf(string) !== -1) {
|
||||
return "'" + string + "'";
|
||||
}
|
||||
|
||||
var indent = state.indent * Math.max(1, level); // no 0-indent scalars
|
||||
// As indentation gets deeper, let the width decrease monotonically
|
||||
// to the lower bound min(state.lineWidth, 40).
|
||||
// Note that this implies
|
||||
// state.lineWidth ≤ 40 + state.indent: width is fixed at the lower bound.
|
||||
// state.lineWidth > 40 + state.indent: width decreases until the lower bound.
|
||||
// This behaves better than a constant minimum width which disallows narrower options,
|
||||
// or an indent threshold which causes the width to suddenly increase.
|
||||
var lineWidth = state.lineWidth === -1
|
||||
? -1 : Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent);
|
||||
|
||||
// Without knowing if keys are implicit/explicit, assume implicit for safety.
|
||||
var singleLineOnly = iskey
|
||||
// No block styles in flow mode.
|
||||
|| (state.flowLevel > -1 && level >= state.flowLevel);
|
||||
function testAmbiguity(string) {
|
||||
return testImplicitResolving(state, string);
|
||||
}
|
||||
|
||||
switch (chooseScalarStyle(string, singleLineOnly, state.indent, lineWidth, testAmbiguity)) {
|
||||
case STYLE_PLAIN:
|
||||
return string;
|
||||
case STYLE_SINGLE:
|
||||
return "'" + string.replace(/'/g, "''") + "'";
|
||||
case STYLE_LITERAL:
|
||||
return '|' + blockHeader(string, state.indent)
|
||||
+ dropEndingNewline(indentString(string, indent));
|
||||
case STYLE_FOLDED:
|
||||
return '>' + blockHeader(string, state.indent)
|
||||
+ dropEndingNewline(indentString(foldString(string, lineWidth), indent));
|
||||
case STYLE_DOUBLE:
|
||||
return '"' + escapeString(string, lineWidth) + '"';
|
||||
default:
|
||||
throw new YAMLException('impossible error: invalid scalar style');
|
||||
}
|
||||
}());
|
||||
}
|
||||
|
||||
// Pre-conditions: string is valid for a block scalar, 1 <= indentPerLevel <= 9.
|
||||
function blockHeader(string, indentPerLevel) {
|
||||
var indentIndicator = (string[0] === ' ') ? String(indentPerLevel) : '';
|
||||
|
||||
// note the special case: the string '\n' counts as a "trailing" empty line.
|
||||
var clip = string[string.length - 1] === '\n';
|
||||
var keep = clip && (string[string.length - 2] === '\n' || string === '\n');
|
||||
var chomp = keep ? '+' : (clip ? '' : '-');
|
||||
|
||||
return indentIndicator + chomp + '\n';
|
||||
}
|
||||
|
||||
// (See the note for writeScalar.)
|
||||
function dropEndingNewline(string) {
|
||||
return string[string.length - 1] === '\n' ? string.slice(0, -1) : string;
|
||||
}
|
||||
|
||||
// Note: a long line without a suitable break point will exceed the width limit.
|
||||
// Pre-conditions: every char in str isPrintable, str.length > 0, width > 0.
|
||||
function foldString(string, width) {
|
||||
// In folded style, $k$ consecutive newlines output as $k+1$ newlines—
|
||||
// unless they're before or after a more-indented line, or at the very
|
||||
// beginning or end, in which case $k$ maps to $k$.
|
||||
// Therefore, parse each chunk as newline(s) followed by a content line.
|
||||
var lineRe = /(\n+)([^\n]*)/g;
|
||||
|
||||
// first line (possibly an empty line)
|
||||
var result = (function () {
|
||||
var nextLF = string.indexOf('\n');
|
||||
nextLF = nextLF !== -1 ? nextLF : string.length;
|
||||
lineRe.lastIndex = nextLF;
|
||||
return foldLine(string.slice(0, nextLF), width);
|
||||
}());
|
||||
// If we haven't reached the first content line yet, don't add an extra \n.
|
||||
var prevMoreIndented = string[0] === '\n' || string[0] === ' ';
|
||||
var moreIndented;
|
||||
|
||||
// rest of the lines
|
||||
var match;
|
||||
while ((match = lineRe.exec(string))) {
|
||||
var prefix = match[1], line = match[2];
|
||||
moreIndented = (line[0] === ' ');
|
||||
result += prefix
|
||||
+ (!prevMoreIndented && !moreIndented && line !== ''
|
||||
? '\n' : '')
|
||||
+ foldLine(line, width);
|
||||
prevMoreIndented = moreIndented;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Greedy line breaking.
|
||||
// Picks the longest line under the limit each time,
|
||||
// otherwise settles for the shortest line over the limit.
|
||||
// NB. More-indented lines *cannot* be folded, as that would add an extra \n.
|
||||
function foldLine(line, width) {
|
||||
if (line === '' || line[0] === ' ') return line;
|
||||
|
||||
// Since a more-indented line adds a \n, breaks can't be followed by a space.
|
||||
var breakRe = / [^ ]/g; // note: the match index will always be <= length-2.
|
||||
var match;
|
||||
// start is an inclusive index. end, curr, and next are exclusive.
|
||||
var start = 0, end, curr = 0, next = 0;
|
||||
var result = '';
|
||||
|
||||
// Invariants: 0 <= start <= length-1.
|
||||
// 0 <= curr <= next <= max(0, length-2). curr - start <= width.
|
||||
// Inside the loop:
|
||||
// A match implies length >= 2, so curr and next are <= length-2.
|
||||
while ((match = breakRe.exec(line))) {
|
||||
next = match.index;
|
||||
// maintain invariant: curr - start <= width
|
||||
if (next - start > width) {
|
||||
end = (curr > start) ? curr : next; // derive end <= length-2
|
||||
result += '\n' + line.slice(start, end);
|
||||
// skip the space that was output as \n
|
||||
start = end + 1; // derive start <= length-1
|
||||
}
|
||||
curr = next;
|
||||
}
|
||||
|
||||
// By the invariants, start <= length-1, so there is something left over.
|
||||
// It is either the whole string or a part starting from non-whitespace.
|
||||
result += '\n';
|
||||
// Insert a break if the remainder is too long and there is a break available.
|
||||
if (line.length - start > width && curr > start) {
|
||||
result += line.slice(start, curr) + '\n' + line.slice(curr + 1);
|
||||
} else {
|
||||
result += line.slice(start);
|
||||
}
|
||||
|
||||
return result.slice(1); // drop extra \n joiner
|
||||
}
|
||||
|
||||
// Escapes a double-quoted string.
|
||||
function escapeString(string) {
|
||||
var result = '';
|
||||
var char, nextChar;
|
||||
var escapeSeq;
|
||||
|
||||
for (var i = 0; i < string.length; i++) {
|
||||
char = string.charCodeAt(i);
|
||||
// Check for surrogate pairs (reference Unicode 3.0 section "3.7 Surrogates").
|
||||
if (char >= 0xD800 && char <= 0xDBFF/* high surrogate */) {
|
||||
nextChar = string.charCodeAt(i + 1);
|
||||
if (nextChar >= 0xDC00 && nextChar <= 0xDFFF/* low surrogate */) {
|
||||
// Combine the surrogate pair and store it escaped.
|
||||
result += encodeHex((char - 0xD800) * 0x400 + nextChar - 0xDC00 + 0x10000);
|
||||
// Advance index one extra since we already used that char here.
|
||||
i++; continue;
|
||||
}
|
||||
}
|
||||
escapeSeq = ESCAPE_SEQUENCES[char];
|
||||
result += !escapeSeq && isPrintable(char)
|
||||
? string[i]
|
||||
: escapeSeq || encodeHex(char);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function writeFlowSequence(state, level, object) {
|
||||
var _result = '',
|
||||
_tag = state.tag,
|
||||
index,
|
||||
length;
|
||||
|
||||
for (index = 0, length = object.length; index < length; index += 1) {
|
||||
// Write only valid elements.
|
||||
if (writeNode(state, level, object[index], false, false)) {
|
||||
if (index !== 0) _result += ',' + (!state.condenseFlow ? ' ' : '');
|
||||
_result += state.dump;
|
||||
}
|
||||
}
|
||||
|
||||
state.tag = _tag;
|
||||
state.dump = '[' + _result + ']';
|
||||
}
|
||||
|
||||
function writeBlockSequence(state, level, object, compact) {
|
||||
var _result = '',
|
||||
_tag = state.tag,
|
||||
index,
|
||||
length;
|
||||
|
||||
for (index = 0, length = object.length; index < length; index += 1) {
|
||||
// Write only valid elements.
|
||||
if (writeNode(state, level + 1, object[index], true, true)) {
|
||||
if (!compact || index !== 0) {
|
||||
_result += generateNextLine(state, level);
|
||||
}
|
||||
|
||||
if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {
|
||||
_result += '-';
|
||||
} else {
|
||||
_result += '- ';
|
||||
}
|
||||
|
||||
_result += state.dump;
|
||||
}
|
||||
}
|
||||
|
||||
state.tag = _tag;
|
||||
state.dump = _result || '[]'; // Empty sequence if no valid values.
|
||||
}
|
||||
|
||||
function writeFlowMapping(state, level, object) {
|
||||
var _result = '',
|
||||
_tag = state.tag,
|
||||
objectKeyList = Object.keys(object),
|
||||
index,
|
||||
length,
|
||||
objectKey,
|
||||
objectValue,
|
||||
pairBuffer;
|
||||
|
||||
for (index = 0, length = objectKeyList.length; index < length; index += 1) {
|
||||
pairBuffer = state.condenseFlow ? '"' : '';
|
||||
|
||||
if (index !== 0) pairBuffer += ', ';
|
||||
|
||||
objectKey = objectKeyList[index];
|
||||
objectValue = object[objectKey];
|
||||
|
||||
if (!writeNode(state, level, objectKey, false, false)) {
|
||||
continue; // Skip this pair because of invalid key;
|
||||
}
|
||||
|
||||
if (state.dump.length > 1024) pairBuffer += '? ';
|
||||
|
||||
pairBuffer += state.dump + (state.condenseFlow ? '"' : '') + ':' + (state.condenseFlow ? '' : ' ');
|
||||
|
||||
if (!writeNode(state, level, objectValue, false, false)) {
|
||||
continue; // Skip this pair because of invalid value.
|
||||
}
|
||||
|
||||
pairBuffer += state.dump;
|
||||
|
||||
// Both key and value are valid.
|
||||
_result += pairBuffer;
|
||||
}
|
||||
|
||||
state.tag = _tag;
|
||||
state.dump = '{' + _result + '}';
|
||||
}
|
||||
|
||||
function writeBlockMapping(state, level, object, compact) {
|
||||
var _result = '',
|
||||
_tag = state.tag,
|
||||
objectKeyList = Object.keys(object),
|
||||
index,
|
||||
length,
|
||||
objectKey,
|
||||
objectValue,
|
||||
explicitPair,
|
||||
pairBuffer;
|
||||
|
||||
// Allow sorting keys so that the output file is deterministic
|
||||
if (state.sortKeys === true) {
|
||||
// Default sorting
|
||||
objectKeyList.sort();
|
||||
} else if (typeof state.sortKeys === 'function') {
|
||||
// Custom sort function
|
||||
objectKeyList.sort(state.sortKeys);
|
||||
} else if (state.sortKeys) {
|
||||
// Something is wrong
|
||||
throw new YAMLException('sortKeys must be a boolean or a function');
|
||||
}
|
||||
|
||||
for (index = 0, length = objectKeyList.length; index < length; index += 1) {
|
||||
pairBuffer = '';
|
||||
|
||||
if (!compact || index !== 0) {
|
||||
pairBuffer += generateNextLine(state, level);
|
||||
}
|
||||
|
||||
objectKey = objectKeyList[index];
|
||||
objectValue = object[objectKey];
|
||||
|
||||
if (!writeNode(state, level + 1, objectKey, true, true, true)) {
|
||||
continue; // Skip this pair because of invalid key.
|
||||
}
|
||||
|
||||
explicitPair = (state.tag !== null && state.tag !== '?') ||
|
||||
(state.dump && state.dump.length > 1024);
|
||||
|
||||
if (explicitPair) {
|
||||
if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {
|
||||
pairBuffer += '?';
|
||||
} else {
|
||||
pairBuffer += '? ';
|
||||
}
|
||||
}
|
||||
|
||||
pairBuffer += state.dump;
|
||||
|
||||
if (explicitPair) {
|
||||
pairBuffer += generateNextLine(state, level);
|
||||
}
|
||||
|
||||
if (!writeNode(state, level + 1, objectValue, true, explicitPair)) {
|
||||
continue; // Skip this pair because of invalid value.
|
||||
}
|
||||
|
||||
if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {
|
||||
pairBuffer += ':';
|
||||
} else {
|
||||
pairBuffer += ': ';
|
||||
}
|
||||
|
||||
pairBuffer += state.dump;
|
||||
|
||||
// Both key and value are valid.
|
||||
_result += pairBuffer;
|
||||
}
|
||||
|
||||
state.tag = _tag;
|
||||
state.dump = _result || '{}'; // Empty mapping if no valid pairs.
|
||||
}
|
||||
|
||||
function detectType(state, object, explicit) {
|
||||
var _result, typeList, index, length, type, style;
|
||||
|
||||
typeList = explicit ? state.explicitTypes : state.implicitTypes;
|
||||
|
||||
for (index = 0, length = typeList.length; index < length; index += 1) {
|
||||
type = typeList[index];
|
||||
|
||||
if ((type.instanceOf || type.predicate) &&
|
||||
(!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) &&
|
||||
(!type.predicate || type.predicate(object))) {
|
||||
|
||||
state.tag = explicit ? type.tag : '?';
|
||||
|
||||
if (type.represent) {
|
||||
style = state.styleMap[type.tag] || type.defaultStyle;
|
||||
|
||||
if (_toString.call(type.represent) === '[object Function]') {
|
||||
_result = type.represent(object, style);
|
||||
} else if (_hasOwnProperty.call(type.represent, style)) {
|
||||
_result = type.represent[style](object, style);
|
||||
} else {
|
||||
throw new YAMLException('!<' + type.tag + '> tag resolver accepts not "' + style + '" style');
|
||||
}
|
||||
|
||||
state.dump = _result;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Serializes `object` and writes it to global `result`.
|
||||
// Returns true on success, or false on invalid object.
|
||||
//
|
||||
function writeNode(state, level, object, block, compact, iskey) {
|
||||
state.tag = null;
|
||||
state.dump = object;
|
||||
|
||||
if (!detectType(state, object, false)) {
|
||||
detectType(state, object, true);
|
||||
}
|
||||
|
||||
var type = _toString.call(state.dump);
|
||||
|
||||
if (block) {
|
||||
block = (state.flowLevel < 0 || state.flowLevel > level);
|
||||
}
|
||||
|
||||
var objectOrArray = type === '[object Object]' || type === '[object Array]',
|
||||
duplicateIndex,
|
||||
duplicate;
|
||||
|
||||
if (objectOrArray) {
|
||||
duplicateIndex = state.duplicates.indexOf(object);
|
||||
duplicate = duplicateIndex !== -1;
|
||||
}
|
||||
|
||||
if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) {
|
||||
compact = false;
|
||||
}
|
||||
|
||||
if (duplicate && state.usedDuplicates[duplicateIndex]) {
|
||||
state.dump = '*ref_' + duplicateIndex;
|
||||
} else {
|
||||
if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) {
|
||||
state.usedDuplicates[duplicateIndex] = true;
|
||||
}
|
||||
if (type === '[object Object]') {
|
||||
if (block && (Object.keys(state.dump).length !== 0)) {
|
||||
writeBlockMapping(state, level, state.dump, compact);
|
||||
if (duplicate) {
|
||||
state.dump = '&ref_' + duplicateIndex + state.dump;
|
||||
}
|
||||
} else {
|
||||
writeFlowMapping(state, level, state.dump);
|
||||
if (duplicate) {
|
||||
state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;
|
||||
}
|
||||
}
|
||||
} else if (type === '[object Array]') {
|
||||
if (block && (state.dump.length !== 0)) {
|
||||
writeBlockSequence(state, level, state.dump, compact);
|
||||
if (duplicate) {
|
||||
state.dump = '&ref_' + duplicateIndex + state.dump;
|
||||
}
|
||||
} else {
|
||||
writeFlowSequence(state, level, state.dump);
|
||||
if (duplicate) {
|
||||
state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;
|
||||
}
|
||||
}
|
||||
} else if (type === '[object String]') {
|
||||
if (state.tag !== '?') {
|
||||
writeScalar(state, state.dump, level, iskey);
|
||||
}
|
||||
} else {
|
||||
if (state.skipInvalid) return false;
|
||||
throw new YAMLException('unacceptable kind of an object to dump ' + type);
|
||||
}
|
||||
|
||||
if (state.tag !== null && state.tag !== '?') {
|
||||
state.dump = '!<' + state.tag + '> ' + state.dump;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function getDuplicateReferences(object, state) {
|
||||
var objects = [],
|
||||
duplicatesIndexes = [],
|
||||
index,
|
||||
length;
|
||||
|
||||
inspectNode(object, objects, duplicatesIndexes);
|
||||
|
||||
for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) {
|
||||
state.duplicates.push(objects[duplicatesIndexes[index]]);
|
||||
}
|
||||
state.usedDuplicates = new Array(length);
|
||||
}
|
||||
|
||||
function inspectNode(object, objects, duplicatesIndexes) {
|
||||
var objectKeyList,
|
||||
index,
|
||||
length;
|
||||
|
||||
if (object !== null && typeof object === 'object') {
|
||||
index = objects.indexOf(object);
|
||||
if (index !== -1) {
|
||||
if (duplicatesIndexes.indexOf(index) === -1) {
|
||||
duplicatesIndexes.push(index);
|
||||
}
|
||||
} else {
|
||||
objects.push(object);
|
||||
|
||||
if (Array.isArray(object)) {
|
||||
for (index = 0, length = object.length; index < length; index += 1) {
|
||||
inspectNode(object[index], objects, duplicatesIndexes);
|
||||
}
|
||||
} else {
|
||||
objectKeyList = Object.keys(object);
|
||||
|
||||
for (index = 0, length = objectKeyList.length; index < length; index += 1) {
|
||||
inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function dump(input, options) {
|
||||
options = options || {};
|
||||
|
||||
var state = new State(options);
|
||||
|
||||
if (!state.noRefs) getDuplicateReferences(input, state);
|
||||
|
||||
if (writeNode(state, 0, input, true, true)) return state.dump + '\n';
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
function safeDump(input, options) {
|
||||
return dump(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options));
|
||||
}
|
||||
|
||||
module.exports.dump = dump;
|
||||
module.exports.safeDump = safeDump;
|
@ -1,43 +0,0 @@
|
||||
// YAML error class. http://stackoverflow.com/questions/8458984
|
||||
//
|
||||
'use strict';
|
||||
|
||||
function YAMLException(reason, mark) {
|
||||
// Super constructor
|
||||
Error.call(this);
|
||||
|
||||
this.name = 'YAMLException';
|
||||
this.reason = reason;
|
||||
this.mark = mark;
|
||||
this.message = (this.reason || '(unknown reason)') + (this.mark ? ' ' + this.mark.toString() : '');
|
||||
|
||||
// Include stack trace in error object
|
||||
if (Error.captureStackTrace) {
|
||||
// Chrome and NodeJS
|
||||
Error.captureStackTrace(this, this.constructor);
|
||||
} else {
|
||||
// FF, IE 10+ and Safari 6+. Fallback for others
|
||||
this.stack = (new Error()).stack || '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Inherit from Error
|
||||
YAMLException.prototype = Object.create(Error.prototype);
|
||||
YAMLException.prototype.constructor = YAMLException;
|
||||
|
||||
|
||||
YAMLException.prototype.toString = function toString(compact) {
|
||||
var result = this.name + ': ';
|
||||
|
||||
result += this.reason || '(unknown reason)';
|
||||
|
||||
if (!compact && this.mark) {
|
||||
result += ' ' + this.mark.toString();
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
module.exports = YAMLException;
|
File diff suppressed because it is too large
Load Diff
@ -1,76 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
|
||||
var common = require('./common');
|
||||
|
||||
|
||||
function Mark(name, buffer, position, line, column) {
|
||||
this.name = name;
|
||||
this.buffer = buffer;
|
||||
this.position = position;
|
||||
this.line = line;
|
||||
this.column = column;
|
||||
}
|
||||
|
||||
|
||||
Mark.prototype.getSnippet = function getSnippet(indent, maxLength) {
|
||||
var head, start, tail, end, snippet;
|
||||
|
||||
if (!this.buffer) return null;
|
||||
|
||||
indent = indent || 4;
|
||||
maxLength = maxLength || 75;
|
||||
|
||||
head = '';
|
||||
start = this.position;
|
||||
|
||||
while (start > 0 && '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(start - 1)) === -1) {
|
||||
start -= 1;
|
||||
if (this.position - start > (maxLength / 2 - 1)) {
|
||||
head = ' ... ';
|
||||
start += 5;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tail = '';
|
||||
end = this.position;
|
||||
|
||||
while (end < this.buffer.length && '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(end)) === -1) {
|
||||
end += 1;
|
||||
if (end - this.position > (maxLength / 2 - 1)) {
|
||||
tail = ' ... ';
|
||||
end -= 5;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
snippet = this.buffer.slice(start, end);
|
||||
|
||||
return common.repeat(' ', indent) + head + snippet + tail + '\n' +
|
||||
common.repeat(' ', indent + this.position - start + head.length) + '^';
|
||||
};
|
||||
|
||||
|
||||
Mark.prototype.toString = function toString(compact) {
|
||||
var snippet, where = '';
|
||||
|
||||
if (this.name) {
|
||||
where += 'in "' + this.name + '" ';
|
||||
}
|
||||
|
||||
where += 'at line ' + (this.line + 1) + ', column ' + (this.column + 1);
|
||||
|
||||
if (!compact) {
|
||||
snippet = this.getSnippet();
|
||||
|
||||
if (snippet) {
|
||||
where += ':\n' + snippet;
|
||||
}
|
||||
}
|
||||
|
||||
return where;
|
||||
};
|
||||
|
||||
|
||||
module.exports = Mark;
|
@ -1,108 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/*eslint-disable max-len*/
|
||||
|
||||
var common = require('./common');
|
||||
var YAMLException = require('./exception');
|
||||
var Type = require('./type');
|
||||
|
||||
|
||||
function compileList(schema, name, result) {
|
||||
var exclude = [];
|
||||
|
||||
schema.include.forEach(function (includedSchema) {
|
||||
result = compileList(includedSchema, name, result);
|
||||
});
|
||||
|
||||
schema[name].forEach(function (currentType) {
|
||||
result.forEach(function (previousType, previousIndex) {
|
||||
if (previousType.tag === currentType.tag && previousType.kind === currentType.kind) {
|
||||
exclude.push(previousIndex);
|
||||
}
|
||||
});
|
||||
|
||||
result.push(currentType);
|
||||
});
|
||||
|
||||
return result.filter(function (type, index) {
|
||||
return exclude.indexOf(index) === -1;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function compileMap(/* lists... */) {
|
||||
var result = {
|
||||
scalar: {},
|
||||
sequence: {},
|
||||
mapping: {},
|
||||
fallback: {}
|
||||
}, index, length;
|
||||
|
||||
function collectType(type) {
|
||||
result[type.kind][type.tag] = result['fallback'][type.tag] = type;
|
||||
}
|
||||
|
||||
for (index = 0, length = arguments.length; index < length; index += 1) {
|
||||
arguments[index].forEach(collectType);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
function Schema(definition) {
|
||||
this.include = definition.include || [];
|
||||
this.implicit = definition.implicit || [];
|
||||
this.explicit = definition.explicit || [];
|
||||
|
||||
this.implicit.forEach(function (type) {
|
||||
if (type.loadKind && type.loadKind !== 'scalar') {
|
||||
throw new YAMLException('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.');
|
||||
}
|
||||
});
|
||||
|
||||
this.compiledImplicit = compileList(this, 'implicit', []);
|
||||
this.compiledExplicit = compileList(this, 'explicit', []);
|
||||
this.compiledTypeMap = compileMap(this.compiledImplicit, this.compiledExplicit);
|
||||
}
|
||||
|
||||
|
||||
Schema.DEFAULT = null;
|
||||
|
||||
|
||||
Schema.create = function createSchema() {
|
||||
var schemas, types;
|
||||
|
||||
switch (arguments.length) {
|
||||
case 1:
|
||||
schemas = Schema.DEFAULT;
|
||||
types = arguments[0];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
schemas = arguments[0];
|
||||
types = arguments[1];
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new YAMLException('Wrong number of arguments for Schema.create function');
|
||||
}
|
||||
|
||||
schemas = common.toArray(schemas);
|
||||
types = common.toArray(types);
|
||||
|
||||
if (!schemas.every(function (schema) { return schema instanceof Schema; })) {
|
||||
throw new YAMLException('Specified list of super schemas (or a single Schema object) contains a non-Schema object.');
|
||||
}
|
||||
|
||||
if (!types.every(function (type) { return type instanceof Type; })) {
|
||||
throw new YAMLException('Specified list of YAML types (or a single Type object) contains a non-Type object.');
|
||||
}
|
||||
|
||||
return new Schema({
|
||||
include: schemas,
|
||||
explicit: types
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
module.exports = Schema;
|
@ -1,18 +0,0 @@
|
||||
// Standard YAML's Core schema.
|
||||
// http://www.yaml.org/spec/1.2/spec.html#id2804923
|
||||
//
|
||||
// NOTE: JS-YAML does not support schema-specific tag resolution restrictions.
|
||||
// So, Core schema has no distinctions from JSON schema is JS-YAML.
|
||||
|
||||
|
||||
'use strict';
|
||||
|
||||
|
||||
var Schema = require('../schema');
|
||||
|
||||
|
||||
module.exports = new Schema({
|
||||
include: [
|
||||
require('./json')
|
||||
]
|
||||
});
|
@ -1,25 +0,0 @@
|
||||
// JS-YAML's default schema for `load` function.
|
||||
// It is not described in the YAML specification.
|
||||
//
|
||||
// This schema is based on JS-YAML's default safe schema and includes
|
||||
// JavaScript-specific types: !!js/undefined, !!js/regexp and !!js/function.
|
||||
//
|
||||
// Also this schema is used as default base schema at `Schema.create` function.
|
||||
|
||||
|
||||
'use strict';
|
||||
|
||||
|
||||
var Schema = require('../schema');
|
||||
|
||||
|
||||
module.exports = Schema.DEFAULT = new Schema({
|
||||
include: [
|
||||
require('./default_safe')
|
||||
],
|
||||
explicit: [
|
||||
require('../type/js/undefined'),
|
||||
require('../type/js/regexp'),
|
||||
require('../type/js/function')
|
||||
]
|
||||
});
|
@ -1,28 +0,0 @@
|
||||
// JS-YAML's default schema for `safeLoad` function.
|
||||
// It is not described in the YAML specification.
|
||||
//
|
||||
// This schema is based on standard YAML's Core schema and includes most of
|
||||
// extra types described at YAML tag repository. (http://yaml.org/type/)
|
||||
|
||||
|
||||
'use strict';
|
||||
|
||||
|
||||
var Schema = require('../schema');
|
||||
|
||||
|
||||
module.exports = new Schema({
|
||||
include: [
|
||||
require('./core')
|
||||
],
|
||||
implicit: [
|
||||
require('../type/timestamp'),
|
||||
require('../type/merge')
|
||||
],
|
||||
explicit: [
|
||||
require('../type/binary'),
|
||||
require('../type/omap'),
|
||||
require('../type/pairs'),
|
||||
require('../type/set')
|
||||
]
|
||||
});
|
@ -1,17 +0,0 @@
|
||||
// Standard YAML's Failsafe schema.
|
||||
// http://www.yaml.org/spec/1.2/spec.html#id2802346
|
||||
|
||||
|
||||
'use strict';
|
||||
|
||||
|
||||
var Schema = require('../schema');
|
||||
|
||||
|
||||
module.exports = new Schema({
|
||||
explicit: [
|
||||
require('../type/str'),
|
||||
require('../type/seq'),
|
||||
require('../type/map')
|
||||
]
|
||||
});
|
@ -1,25 +0,0 @@
|
||||
// Standard YAML's JSON schema.
|
||||
// http://www.yaml.org/spec/1.2/spec.html#id2803231
|
||||
//
|
||||
// NOTE: JS-YAML does not support schema-specific tag resolution restrictions.
|
||||
// So, this schema is not such strict as defined in the YAML specification.
|
||||
// It allows numbers in binary notaion, use `Null` and `NULL` as `null`, etc.
|
||||
|
||||
|
||||
'use strict';
|
||||
|
||||
|
||||
var Schema = require('../schema');
|
||||
|
||||
|
||||
module.exports = new Schema({
|
||||
include: [
|
||||
require('./failsafe')
|
||||
],
|
||||
implicit: [
|
||||
require('../type/null'),
|
||||
require('../type/bool'),
|
||||
require('../type/int'),
|
||||
require('../type/float')
|
||||
]
|
||||
});
|
@ -1,61 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var YAMLException = require('./exception');
|
||||
|
||||
var TYPE_CONSTRUCTOR_OPTIONS = [
|
||||
'kind',
|
||||
'resolve',
|
||||
'construct',
|
||||
'instanceOf',
|
||||
'predicate',
|
||||
'represent',
|
||||
'defaultStyle',
|
||||
'styleAliases'
|
||||
];
|
||||
|
||||
var YAML_NODE_KINDS = [
|
||||
'scalar',
|
||||
'sequence',
|
||||
'mapping'
|
||||
];
|
||||
|
||||
function compileStyleAliases(map) {
|
||||
var result = {};
|
||||
|
||||
if (map !== null) {
|
||||
Object.keys(map).forEach(function (style) {
|
||||
map[style].forEach(function (alias) {
|
||||
result[String(alias)] = style;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function Type(tag, options) {
|
||||
options = options || {};
|
||||
|
||||
Object.keys(options).forEach(function (name) {
|
||||
if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) {
|
||||
throw new YAMLException('Unknown option "' + name + '" is met in definition of "' + tag + '" YAML type.');
|
||||
}
|
||||
});
|
||||
|
||||
// TODO: Add tag format check.
|
||||
this.tag = tag;
|
||||
this.kind = options['kind'] || null;
|
||||
this.resolve = options['resolve'] || function () { return true; };
|
||||
this.construct = options['construct'] || function (data) { return data; };
|
||||
this.instanceOf = options['instanceOf'] || null;
|
||||
this.predicate = options['predicate'] || null;
|
||||
this.represent = options['represent'] || null;
|
||||
this.defaultStyle = options['defaultStyle'] || null;
|
||||
this.styleAliases = compileStyleAliases(options['styleAliases'] || null);
|
||||
|
||||
if (YAML_NODE_KINDS.indexOf(this.kind) === -1) {
|
||||
throw new YAMLException('Unknown kind "' + this.kind + '" is specified for "' + tag + '" YAML type.');
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Type;
|
@ -1,138 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/*eslint-disable no-bitwise*/
|
||||
|
||||
var NodeBuffer;
|
||||
|
||||
// try {
|
||||
// // A trick for browserified version, to not include `Buffer` shim
|
||||
// var _require = require;
|
||||
// NodeBuffer = _require('buffer').Buffer;
|
||||
// } catch (__) {}
|
||||
|
||||
var Type = require('../type');
|
||||
|
||||
|
||||
// [ 64, 65, 66 ] -> [ padding, CR, LF ]
|
||||
var BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r';
|
||||
|
||||
|
||||
function resolveYamlBinary(data) {
|
||||
if (data === null) return false;
|
||||
|
||||
var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP;
|
||||
|
||||
// Convert one by one.
|
||||
for (idx = 0; idx < max; idx++) {
|
||||
code = map.indexOf(data.charAt(idx));
|
||||
|
||||
// Skip CR/LF
|
||||
if (code > 64) continue;
|
||||
|
||||
// Fail on illegal characters
|
||||
if (code < 0) return false;
|
||||
|
||||
bitlen += 6;
|
||||
}
|
||||
|
||||
// If there are any bits left, source was corrupted
|
||||
return (bitlen % 8) === 0;
|
||||
}
|
||||
|
||||
function constructYamlBinary(data) {
|
||||
var idx, tailbits,
|
||||
input = data.replace(/[\r\n=]/g, ''), // remove CR/LF & padding to simplify scan
|
||||
max = input.length,
|
||||
map = BASE64_MAP,
|
||||
bits = 0,
|
||||
result = [];
|
||||
|
||||
// Collect by 6*4 bits (3 bytes)
|
||||
|
||||
for (idx = 0; idx < max; idx++) {
|
||||
if ((idx % 4 === 0) && idx) {
|
||||
result.push((bits >> 16) & 0xFF);
|
||||
result.push((bits >> 8) & 0xFF);
|
||||
result.push(bits & 0xFF);
|
||||
}
|
||||
|
||||
bits = (bits << 6) | map.indexOf(input.charAt(idx));
|
||||
}
|
||||
|
||||
// Dump tail
|
||||
|
||||
tailbits = (max % 4) * 6;
|
||||
|
||||
if (tailbits === 0) {
|
||||
result.push((bits >> 16) & 0xFF);
|
||||
result.push((bits >> 8) & 0xFF);
|
||||
result.push(bits & 0xFF);
|
||||
} else if (tailbits === 18) {
|
||||
result.push((bits >> 10) & 0xFF);
|
||||
result.push((bits >> 2) & 0xFF);
|
||||
} else if (tailbits === 12) {
|
||||
result.push((bits >> 4) & 0xFF);
|
||||
}
|
||||
|
||||
// Wrap into Buffer for NodeJS and leave Array for browser
|
||||
if (NodeBuffer) {
|
||||
// Support node 6.+ Buffer API when available
|
||||
return NodeBuffer.from ? NodeBuffer.from(result) : new NodeBuffer(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function representYamlBinary(object /*, style*/) {
|
||||
var result = '', bits = 0, idx, tail,
|
||||
max = object.length,
|
||||
map = BASE64_MAP;
|
||||
|
||||
// Convert every three bytes to 4 ASCII characters.
|
||||
|
||||
for (idx = 0; idx < max; idx++) {
|
||||
if ((idx % 3 === 0) && idx) {
|
||||
result += map[(bits >> 18) & 0x3F];
|
||||
result += map[(bits >> 12) & 0x3F];
|
||||
result += map[(bits >> 6) & 0x3F];
|
||||
result += map[bits & 0x3F];
|
||||
}
|
||||
|
||||
bits = (bits << 8) + object[idx];
|
||||
}
|
||||
|
||||
// Dump tail
|
||||
|
||||
tail = max % 3;
|
||||
|
||||
if (tail === 0) {
|
||||
result += map[(bits >> 18) & 0x3F];
|
||||
result += map[(bits >> 12) & 0x3F];
|
||||
result += map[(bits >> 6) & 0x3F];
|
||||
result += map[bits & 0x3F];
|
||||
} else if (tail === 2) {
|
||||
result += map[(bits >> 10) & 0x3F];
|
||||
result += map[(bits >> 4) & 0x3F];
|
||||
result += map[(bits << 2) & 0x3F];
|
||||
result += map[64];
|
||||
} else if (tail === 1) {
|
||||
result += map[(bits >> 2) & 0x3F];
|
||||
result += map[(bits << 4) & 0x3F];
|
||||
result += map[64];
|
||||
result += map[64];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function isBinary(object) {
|
||||
return NodeBuffer && NodeBuffer.isBuffer(object);
|
||||
}
|
||||
|
||||
module.exports = new Type('tag:yaml.org,2002:binary', {
|
||||
kind: 'scalar',
|
||||
resolve: resolveYamlBinary,
|
||||
construct: constructYamlBinary,
|
||||
predicate: isBinary,
|
||||
represent: representYamlBinary
|
||||
});
|
@ -1,35 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var Type = require('../type');
|
||||
|
||||
function resolveYamlBoolean(data) {
|
||||
if (data === null) return false;
|
||||
|
||||
var max = data.length;
|
||||
|
||||
return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) ||
|
||||
(max === 5 && (data === 'false' || data === 'False' || data === 'FALSE'));
|
||||
}
|
||||
|
||||
function constructYamlBoolean(data) {
|
||||
return data === 'true' ||
|
||||
data === 'True' ||
|
||||
data === 'TRUE';
|
||||
}
|
||||
|
||||
function isBoolean(object) {
|
||||
return Object.prototype.toString.call(object) === '[object Boolean]';
|
||||
}
|
||||
|
||||
module.exports = new Type('tag:yaml.org,2002:bool', {
|
||||
kind: 'scalar',
|
||||
resolve: resolveYamlBoolean,
|
||||
construct: constructYamlBoolean,
|
||||
predicate: isBoolean,
|
||||
represent: {
|
||||
lowercase: function (object) { return object ? 'true' : 'false'; },
|
||||
uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; },
|
||||
camelcase: function (object) { return object ? 'True' : 'False'; }
|
||||
},
|
||||
defaultStyle: 'lowercase'
|
||||
});
|
@ -1,116 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var common = require('../common');
|
||||
var Type = require('../type');
|
||||
|
||||
var YAML_FLOAT_PATTERN = new RegExp(
|
||||
// 2.5e4, 2.5 and integers
|
||||
'^(?:[-+]?(?:0|[1-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?' +
|
||||
// .2e4, .2
|
||||
// special case, seems not from spec
|
||||
'|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?' +
|
||||
// 20:59
|
||||
'|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*' +
|
||||
// .inf
|
||||
'|[-+]?\\.(?:inf|Inf|INF)' +
|
||||
// .nan
|
||||
'|\\.(?:nan|NaN|NAN))$');
|
||||
|
||||
function resolveYamlFloat(data) {
|
||||
if (data === null) return false;
|
||||
|
||||
if (!YAML_FLOAT_PATTERN.test(data) ||
|
||||
// Quick hack to not allow integers end with `_`
|
||||
// Probably should update regexp & check speed
|
||||
data[data.length - 1] === '_') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function constructYamlFloat(data) {
|
||||
var value, sign, base, digits;
|
||||
|
||||
value = data.replace(/_/g, '').toLowerCase();
|
||||
sign = value[0] === '-' ? -1 : 1;
|
||||
digits = [];
|
||||
|
||||
if ('+-'.indexOf(value[0]) >= 0) {
|
||||
value = value.slice(1);
|
||||
}
|
||||
|
||||
if (value === '.inf') {
|
||||
return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
|
||||
|
||||
} else if (value === '.nan') {
|
||||
return NaN;
|
||||
|
||||
} else if (value.indexOf(':') >= 0) {
|
||||
value.split(':').forEach(function (v) {
|
||||
digits.unshift(parseFloat(v, 10));
|
||||
});
|
||||
|
||||
value = 0.0;
|
||||
base = 1;
|
||||
|
||||
digits.forEach(function (d) {
|
||||
value += d * base;
|
||||
base *= 60;
|
||||
});
|
||||
|
||||
return sign * value;
|
||||
|
||||
}
|
||||
return sign * parseFloat(value, 10);
|
||||
}
|
||||
|
||||
|
||||
var SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/;
|
||||
|
||||
function representYamlFloat(object, style) {
|
||||
var res;
|
||||
|
||||
if (isNaN(object)) {
|
||||
switch (style) {
|
||||
case 'lowercase': return '.nan';
|
||||
case 'uppercase': return '.NAN';
|
||||
case 'camelcase': return '.NaN';
|
||||
}
|
||||
} else if (Number.POSITIVE_INFINITY === object) {
|
||||
switch (style) {
|
||||
case 'lowercase': return '.inf';
|
||||
case 'uppercase': return '.INF';
|
||||
case 'camelcase': return '.Inf';
|
||||
}
|
||||
} else if (Number.NEGATIVE_INFINITY === object) {
|
||||
switch (style) {
|
||||
case 'lowercase': return '-.inf';
|
||||
case 'uppercase': return '-.INF';
|
||||
case 'camelcase': return '-.Inf';
|
||||
}
|
||||
} else if (common.isNegativeZero(object)) {
|
||||
return '-0.0';
|
||||
}
|
||||
|
||||
res = object.toString(10);
|
||||
|
||||
// JS stringifier can build scientific format without dots: 5e-100,
|
||||
// while YAML requres dot: 5.e-100. Fix it with simple hack
|
||||
|
||||
return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res;
|
||||
}
|
||||
|
||||
function isFloat(object) {
|
||||
return (Object.prototype.toString.call(object) === '[object Number]') &&
|
||||
(object % 1 !== 0 || common.isNegativeZero(object));
|
||||
}
|
||||
|
||||
module.exports = new Type('tag:yaml.org,2002:float', {
|
||||
kind: 'scalar',
|
||||
resolve: resolveYamlFloat,
|
||||
construct: constructYamlFloat,
|
||||
predicate: isFloat,
|
||||
represent: representYamlFloat,
|
||||
defaultStyle: 'lowercase'
|
||||
});
|
@ -1,172 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var common = require('../common');
|
||||
var Type = require('../type');
|
||||
|
||||
function isHexCode(c) {
|
||||
return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) ||
|
||||
((0x41/* A */ <= c) && (c <= 0x46/* F */)) ||
|
||||
((0x61/* a */ <= c) && (c <= 0x66/* f */));
|
||||
}
|
||||
|
||||
function isOctCode(c) {
|
||||
return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */));
|
||||
}
|
||||
|
||||
function isDecCode(c) {
|
||||
return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */));
|
||||
}
|
||||
|
||||
function resolveYamlInteger(data) {
|
||||
if (data === null) return false;
|
||||
|
||||
var max = data.length,
|
||||
index = 0,
|
||||
hasDigits = false,
|
||||
ch;
|
||||
|
||||
if (!max) return false;
|
||||
|
||||
ch = data[index];
|
||||
|
||||
// sign
|
||||
if (ch === '-' || ch === '+') {
|
||||
ch = data[++index];
|
||||
}
|
||||
|
||||
if (ch === '0') {
|
||||
// 0
|
||||
if (index + 1 === max) return true;
|
||||
ch = data[++index];
|
||||
|
||||
// base 2, base 8, base 16
|
||||
|
||||
if (ch === 'b') {
|
||||
// base 2
|
||||
index++;
|
||||
|
||||
for (; index < max; index++) {
|
||||
ch = data[index];
|
||||
if (ch === '_') continue;
|
||||
if (ch !== '0' && ch !== '1') return false;
|
||||
hasDigits = true;
|
||||
}
|
||||
return hasDigits && ch !== '_';
|
||||
}
|
||||
|
||||
|
||||
if (ch === 'x') {
|
||||
// base 16
|
||||
index++;
|
||||
|
||||
for (; index < max; index++) {
|
||||
ch = data[index];
|
||||
if (ch === '_') continue;
|
||||
if (!isHexCode(data.charCodeAt(index))) return false;
|
||||
hasDigits = true;
|
||||
}
|
||||
return hasDigits && ch !== '_';
|
||||
}
|
||||
|
||||
// base 8
|
||||
for (; index < max; index++) {
|
||||
ch = data[index];
|
||||
if (ch === '_') continue;
|
||||
if (!isOctCode(data.charCodeAt(index))) return false;
|
||||
hasDigits = true;
|
||||
}
|
||||
return hasDigits && ch !== '_';
|
||||
}
|
||||
|
||||
// base 10 (except 0) or base 60
|
||||
|
||||
// value should not start with `_`;
|
||||
if (ch === '_') return false;
|
||||
|
||||
for (; index < max; index++) {
|
||||
ch = data[index];
|
||||
if (ch === '_') continue;
|
||||
if (ch === ':') break;
|
||||
if (!isDecCode(data.charCodeAt(index))) {
|
||||
return false;
|
||||
}
|
||||
hasDigits = true;
|
||||
}
|
||||
|
||||
// Should have digits and should not end with `_`
|
||||
if (!hasDigits || ch === '_') return false;
|
||||
|
||||
// if !base60 - done;
|
||||
if (ch !== ':') return true;
|
||||
|
||||
// base60 almost not used, no needs to optimize
|
||||
return /^(:[0-5]?[0-9])+$/.test(data.slice(index));
|
||||
}
|
||||
|
||||
function constructYamlInteger(data) {
|
||||
var value = data, sign = 1, ch, base, digits = [];
|
||||
|
||||
if (value.indexOf('_') !== -1) {
|
||||
value = value.replace(/_/g, '');
|
||||
}
|
||||
|
||||
ch = value[0];
|
||||
|
||||
if (ch === '-' || ch === '+') {
|
||||
if (ch === '-') sign = -1;
|
||||
value = value.slice(1);
|
||||
ch = value[0];
|
||||
}
|
||||
|
||||
if (value === '0') return 0;
|
||||
|
||||
if (ch === '0') {
|
||||
if (value[1] === 'b') return sign * parseInt(value.slice(2), 2);
|
||||
if (value[1] === 'x') return sign * parseInt(value, 16);
|
||||
return sign * parseInt(value, 8);
|
||||
}
|
||||
|
||||
if (value.indexOf(':') !== -1) {
|
||||
value.split(':').forEach(function (v) {
|
||||
digits.unshift(parseInt(v, 10));
|
||||
});
|
||||
|
||||
value = 0;
|
||||
base = 1;
|
||||
|
||||
digits.forEach(function (d) {
|
||||
value += (d * base);
|
||||
base *= 60;
|
||||
});
|
||||
|
||||
return sign * value;
|
||||
|
||||
}
|
||||
|
||||
return sign * parseInt(value, 10);
|
||||
}
|
||||
|
||||
function isInteger(object) {
|
||||
return (Object.prototype.toString.call(object)) === '[object Number]' &&
|
||||
(object % 1 === 0 && !common.isNegativeZero(object));
|
||||
}
|
||||
|
||||
module.exports = new Type('tag:yaml.org,2002:int', {
|
||||
kind: 'scalar',
|
||||
resolve: resolveYamlInteger,
|
||||
construct: constructYamlInteger,
|
||||
predicate: isInteger,
|
||||
represent: {
|
||||
binary: function (object) { return '0b' + object.toString(2); },
|
||||
octal: function (object) { return '0' + object.toString(8); },
|
||||
decimal: function (object) { return object.toString(10); },
|
||||
hexadecimal: function (object) { return '0x' + object.toString(16).toUpperCase(); }
|
||||
},
|
||||
defaultStyle: 'decimal',
|
||||
styleAliases: {
|
||||
binary: [ 2, 'bin' ],
|
||||
octal: [ 8, 'oct' ],
|
||||
decimal: [ 10, 'dec' ],
|
||||
hexadecimal: [ 16, 'hex' ]
|
||||
}
|
||||
});
|
@ -1,84 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var esprima;
|
||||
|
||||
// Browserified version does not have esprima
|
||||
//
|
||||
// 1. For node.js just require module as deps
|
||||
// 2. For browser try to require mudule via external AMD system.
|
||||
// If not found - try to fallback to window.esprima. If not
|
||||
// found too - then fail to parse.
|
||||
//
|
||||
// try {
|
||||
// // workaround to exclude package from browserify list.
|
||||
// var _require = require;
|
||||
// esprima = _require('esprima');
|
||||
// } catch (_) {
|
||||
// /*global window */
|
||||
// if (typeof window !== 'undefined') esprima = window.esprima;
|
||||
// }
|
||||
|
||||
var Type = require('../../type');
|
||||
|
||||
function resolveJavascriptFunction(data) {
|
||||
if (data === null) return false;
|
||||
|
||||
try {
|
||||
var source = '(' + data + ')',
|
||||
ast = esprima.parse(source, { range: true });
|
||||
|
||||
if (ast.type !== 'Program' ||
|
||||
ast.body.length !== 1 ||
|
||||
ast.body[0].type !== 'ExpressionStatement' ||
|
||||
ast.body[0].expression.type !== 'FunctionExpression') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function constructJavascriptFunction(data) {
|
||||
/*jslint evil:true*/
|
||||
|
||||
var source = '(' + data + ')',
|
||||
ast = esprima.parse(source, { range: true }),
|
||||
params = [],
|
||||
body;
|
||||
|
||||
if (ast.type !== 'Program' ||
|
||||
ast.body.length !== 1 ||
|
||||
ast.body[0].type !== 'ExpressionStatement' ||
|
||||
ast.body[0].expression.type !== 'FunctionExpression') {
|
||||
throw new Error('Failed to resolve function');
|
||||
}
|
||||
|
||||
ast.body[0].expression.params.forEach(function (param) {
|
||||
params.push(param.name);
|
||||
});
|
||||
|
||||
body = ast.body[0].expression.body.range;
|
||||
|
||||
// Esprima's ranges include the first '{' and the last '}' characters on
|
||||
// function expressions. So cut them out.
|
||||
/*eslint-disable no-new-func*/
|
||||
return new Function(params, source.slice(body[0] + 1, body[1] - 1));
|
||||
}
|
||||
|
||||
function representJavascriptFunction(object /*, style*/) {
|
||||
return object.toString();
|
||||
}
|
||||
|
||||
function isFunction(object) {
|
||||
return Object.prototype.toString.call(object) === '[object Function]';
|
||||
}
|
||||
|
||||
module.exports = new Type('tag:yaml.org,2002:js/function', {
|
||||
kind: 'scalar',
|
||||
resolve: resolveJavascriptFunction,
|
||||
construct: constructJavascriptFunction,
|
||||
predicate: isFunction,
|
||||
represent: representJavascriptFunction
|
||||
});
|
@ -1,60 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var Type = require('../../type');
|
||||
|
||||
function resolveJavascriptRegExp(data) {
|
||||
if (data === null) return false;
|
||||
if (data.length === 0) return false;
|
||||
|
||||
var regexp = data,
|
||||
tail = /\/([gim]*)$/.exec(data),
|
||||
modifiers = '';
|
||||
|
||||
// if regexp starts with '/' it can have modifiers and must be properly closed
|
||||
// `/foo/gim` - modifiers tail can be maximum 3 chars
|
||||
if (regexp[0] === '/') {
|
||||
if (tail) modifiers = tail[1];
|
||||
|
||||
if (modifiers.length > 3) return false;
|
||||
// if expression starts with /, is should be properly terminated
|
||||
if (regexp[regexp.length - modifiers.length - 1] !== '/') return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function constructJavascriptRegExp(data) {
|
||||
var regexp = data,
|
||||
tail = /\/([gim]*)$/.exec(data),
|
||||
modifiers = '';
|
||||
|
||||
// `/foo/gim` - tail can be maximum 4 chars
|
||||
if (regexp[0] === '/') {
|
||||
if (tail) modifiers = tail[1];
|
||||
regexp = regexp.slice(1, regexp.length - modifiers.length - 1);
|
||||
}
|
||||
|
||||
return new RegExp(regexp, modifiers);
|
||||
}
|
||||
|
||||
function representJavascriptRegExp(object /*, style*/) {
|
||||
var result = '/' + object.source + '/';
|
||||
|
||||
if (object.global) result += 'g';
|
||||
if (object.multiline) result += 'm';
|
||||
if (object.ignoreCase) result += 'i';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function isRegExp(object) {
|
||||
return Object.prototype.toString.call(object) === '[object RegExp]';
|
||||
}
|
||||
|
||||
module.exports = new Type('tag:yaml.org,2002:js/regexp', {
|
||||
kind: 'scalar',
|
||||
resolve: resolveJavascriptRegExp,
|
||||
construct: constructJavascriptRegExp,
|
||||
predicate: isRegExp,
|
||||
represent: representJavascriptRegExp
|
||||
});
|
@ -1,28 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var Type = require('../../type');
|
||||
|
||||
function resolveJavascriptUndefined() {
|
||||
return true;
|
||||
}
|
||||
|
||||
function constructJavascriptUndefined() {
|
||||
/*eslint-disable no-undefined*/
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function representJavascriptUndefined() {
|
||||
return '';
|
||||
}
|
||||
|
||||
function isUndefined(object) {
|
||||
return typeof object === 'undefined';
|
||||
}
|
||||
|
||||
module.exports = new Type('tag:yaml.org,2002:js/undefined', {
|
||||
kind: 'scalar',
|
||||
resolve: resolveJavascriptUndefined,
|
||||
construct: constructJavascriptUndefined,
|
||||
predicate: isUndefined,
|
||||
represent: representJavascriptUndefined
|
||||
});
|
@ -1,8 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var Type = require('../type');
|
||||
|
||||
module.exports = new Type('tag:yaml.org,2002:map', {
|
||||
kind: 'mapping',
|
||||
construct: function (data) { return data !== null ? data : {}; }
|
||||
});
|
@ -1,12 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var Type = require('../type');
|
||||
|
||||
function resolveYamlMerge(data) {
|
||||
return data === '<<' || data === null;
|
||||
}
|
||||
|
||||
module.exports = new Type('tag:yaml.org,2002:merge', {
|
||||
kind: 'scalar',
|
||||
resolve: resolveYamlMerge
|
||||
});
|
@ -1,34 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var Type = require('../type');
|
||||
|
||||
function resolveYamlNull(data) {
|
||||
if (data === null) return true;
|
||||
|
||||
var max = data.length;
|
||||
|
||||
return (max === 1 && data === '~') ||
|
||||
(max === 4 && (data === 'null' || data === 'Null' || data === 'NULL'));
|
||||
}
|
||||
|
||||
function constructYamlNull() {
|
||||
return null;
|
||||
}
|
||||
|
||||
function isNull(object) {
|
||||
return object === null;
|
||||
}
|
||||
|
||||
module.exports = new Type('tag:yaml.org,2002:null', {
|
||||
kind: 'scalar',
|
||||
resolve: resolveYamlNull,
|
||||
construct: constructYamlNull,
|
||||
predicate: isNull,
|
||||
represent: {
|
||||
canonical: function () { return '~'; },
|
||||
lowercase: function () { return 'null'; },
|
||||
uppercase: function () { return 'NULL'; },
|
||||
camelcase: function () { return 'Null'; }
|
||||
},
|
||||
defaultStyle: 'lowercase'
|
||||
});
|
@ -1,44 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var Type = require('../type');
|
||||
|
||||
var _hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
var _toString = Object.prototype.toString;
|
||||
|
||||
function resolveYamlOmap(data) {
|
||||
if (data === null) return true;
|
||||
|
||||
var objectKeys = [], index, length, pair, pairKey, pairHasKey,
|
||||
object = data;
|
||||
|
||||
for (index = 0, length = object.length; index < length; index += 1) {
|
||||
pair = object[index];
|
||||
pairHasKey = false;
|
||||
|
||||
if (_toString.call(pair) !== '[object Object]') return false;
|
||||
|
||||
for (pairKey in pair) {
|
||||
if (_hasOwnProperty.call(pair, pairKey)) {
|
||||
if (!pairHasKey) pairHasKey = true;
|
||||
else return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pairHasKey) return false;
|
||||
|
||||
if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey);
|
||||
else return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function constructYamlOmap(data) {
|
||||
return data !== null ? data : [];
|
||||
}
|
||||
|
||||
module.exports = new Type('tag:yaml.org,2002:omap', {
|
||||
kind: 'sequence',
|
||||
resolve: resolveYamlOmap,
|
||||
construct: constructYamlOmap
|
||||
});
|
@ -1,53 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var Type = require('../type');
|
||||
|
||||
var _toString = Object.prototype.toString;
|
||||
|
||||
function resolveYamlPairs(data) {
|
||||
if (data === null) return true;
|
||||
|
||||
var index, length, pair, keys, result,
|
||||
object = data;
|
||||
|
||||
result = new Array(object.length);
|
||||
|
||||
for (index = 0, length = object.length; index < length; index += 1) {
|
||||
pair = object[index];
|
||||
|
||||
if (_toString.call(pair) !== '[object Object]') return false;
|
||||
|
||||
keys = Object.keys(pair);
|
||||
|
||||
if (keys.length !== 1) return false;
|
||||
|
||||
result[index] = [ keys[0], pair[keys[0]] ];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function constructYamlPairs(data) {
|
||||
if (data === null) return [];
|
||||
|
||||
var index, length, pair, keys, result,
|
||||
object = data;
|
||||
|
||||
result = new Array(object.length);
|
||||
|
||||
for (index = 0, length = object.length; index < length; index += 1) {
|
||||
pair = object[index];
|
||||
|
||||
keys = Object.keys(pair);
|
||||
|
||||
result[index] = [ keys[0], pair[keys[0]] ];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
module.exports = new Type('tag:yaml.org,2002:pairs', {
|
||||
kind: 'sequence',
|
||||
resolve: resolveYamlPairs,
|
||||
construct: constructYamlPairs
|
||||
});
|
@ -1,8 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var Type = require('../type');
|
||||
|
||||
module.exports = new Type('tag:yaml.org,2002:seq', {
|
||||
kind: 'sequence',
|
||||
construct: function (data) { return data !== null ? data : []; }
|
||||
});
|
@ -1,29 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var Type = require('../type');
|
||||
|
||||
var _hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
|
||||
function resolveYamlSet(data) {
|
||||
if (data === null) return true;
|
||||
|
||||
var key, object = data;
|
||||
|
||||
for (key in object) {
|
||||
if (_hasOwnProperty.call(object, key)) {
|
||||
if (object[key] !== null) return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function constructYamlSet(data) {
|
||||
return data !== null ? data : {};
|
||||
}
|
||||
|
||||
module.exports = new Type('tag:yaml.org,2002:set', {
|
||||
kind: 'mapping',
|
||||
resolve: resolveYamlSet,
|
||||
construct: constructYamlSet
|
||||
});
|
@ -1,8 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var Type = require('../type');
|
||||
|
||||
module.exports = new Type('tag:yaml.org,2002:str', {
|
||||
kind: 'scalar',
|
||||
construct: function (data) { return data !== null ? data : ''; }
|
||||
});
|
@ -1,88 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var Type = require('../type');
|
||||
|
||||
var YAML_DATE_REGEXP = new RegExp(
|
||||
'^([0-9][0-9][0-9][0-9])' + // [1] year
|
||||
'-([0-9][0-9])' + // [2] month
|
||||
'-([0-9][0-9])$'); // [3] day
|
||||
|
||||
var YAML_TIMESTAMP_REGEXP = new RegExp(
|
||||
'^([0-9][0-9][0-9][0-9])' + // [1] year
|
||||
'-([0-9][0-9]?)' + // [2] month
|
||||
'-([0-9][0-9]?)' + // [3] day
|
||||
'(?:[Tt]|[ \\t]+)' + // ...
|
||||
'([0-9][0-9]?)' + // [4] hour
|
||||
':([0-9][0-9])' + // [5] minute
|
||||
':([0-9][0-9])' + // [6] second
|
||||
'(?:\\.([0-9]*))?' + // [7] fraction
|
||||
'(?:[ \\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour
|
||||
'(?::([0-9][0-9]))?))?$'); // [11] tz_minute
|
||||
|
||||
function resolveYamlTimestamp(data) {
|
||||
if (data === null) return false;
|
||||
if (YAML_DATE_REGEXP.exec(data) !== null) return true;
|
||||
if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function constructYamlTimestamp(data) {
|
||||
var match, year, month, day, hour, minute, second, fraction = 0,
|
||||
delta = null, tz_hour, tz_minute, date;
|
||||
|
||||
match = YAML_DATE_REGEXP.exec(data);
|
||||
if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data);
|
||||
|
||||
if (match === null) throw new Error('Date resolve error');
|
||||
|
||||
// match: [1] year [2] month [3] day
|
||||
|
||||
year = +(match[1]);
|
||||
month = +(match[2]) - 1; // JS month starts with 0
|
||||
day = +(match[3]);
|
||||
|
||||
if (!match[4]) { // no hour
|
||||
return new Date(Date.UTC(year, month, day));
|
||||
}
|
||||
|
||||
// match: [4] hour [5] minute [6] second [7] fraction
|
||||
|
||||
hour = +(match[4]);
|
||||
minute = +(match[5]);
|
||||
second = +(match[6]);
|
||||
|
||||
if (match[7]) {
|
||||
fraction = match[7].slice(0, 3);
|
||||
while (fraction.length < 3) { // milli-seconds
|
||||
fraction += '0';
|
||||
}
|
||||
fraction = +fraction;
|
||||
}
|
||||
|
||||
// match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute
|
||||
|
||||
if (match[9]) {
|
||||
tz_hour = +(match[10]);
|
||||
tz_minute = +(match[11] || 0);
|
||||
delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds
|
||||
if (match[9] === '-') delta = -delta;
|
||||
}
|
||||
|
||||
date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction));
|
||||
|
||||
if (delta) date.setTime(date.getTime() - delta);
|
||||
|
||||
return date;
|
||||
}
|
||||
|
||||
function representYamlTimestamp(object /*, style*/) {
|
||||
return object.toISOString();
|
||||
}
|
||||
|
||||
module.exports = new Type('tag:yaml.org,2002:timestamp', {
|
||||
kind: 'scalar',
|
||||
resolve: resolveYamlTimestamp,
|
||||
construct: constructYamlTimestamp,
|
||||
instanceOf: Date,
|
||||
represent: representYamlTimestamp
|
||||
});
|
@ -1,38 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/*global Java, base, module, exports, require, __FILE__*/
|
||||
|
||||
var ZipFile = Java.type("java.util.zip.ZipFile");
|
||||
var fs = require('core/fs');
|
||||
|
||||
/**
|
||||
* 解压文件
|
||||
* @param zipFile 压缩文件
|
||||
* @param target 目标目录(不传则为zip文件同级目录)
|
||||
*/
|
||||
function unzip(zipFile, target) {
|
||||
if (!zipFile.exists()) {
|
||||
console.warn("解压文件 %s 错误 文件不存在!".format(zipFile));
|
||||
return;
|
||||
}
|
||||
if (target === undefined) {
|
||||
var fname = zipFile.name;
|
||||
// noinspection JSUnresolvedVariable
|
||||
target = fs.file(zipFile.parentFile.canonicalPath, fname.substring(0, fname.length() - 4));
|
||||
}
|
||||
console.debug("解压文件 %s 到目录 %s".format(zipFile.canonicalPath, target));
|
||||
var zipObj = new ZipFile(zipFile);
|
||||
var e = zipObj.entries();
|
||||
while (e.hasMoreElements()) {
|
||||
var entry = e.nextElement();
|
||||
if (entry.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
var destinationFilePath = fs.file(target, entry.name);
|
||||
destinationFilePath.parentFile.mkdirs();
|
||||
fs.copy(zipObj.getInputStream(entry), destinationFilePath, true);
|
||||
}
|
||||
zipObj.close();
|
||||
}
|
||||
|
||||
exports.unzip = unzip;
|
6
src/main/resources/nukkit.yml
Normal file
6
src/main/resources/nukkit.yml
Normal file
@ -0,0 +1,6 @@
|
||||
name: ${project.artifactId}
|
||||
description: ${project.description}
|
||||
main: ${project.groupId}.${project.artifactId}.${project.artifactId}Nukkit
|
||||
version: ${project.version}
|
||||
api: "1.0.0"
|
||||
author: MiaoWoo
|
@ -1,26 +1,10 @@
|
||||
name: ${project.artifactId}
|
||||
description: ${project.description}
|
||||
main: ${project.groupId}.${project.artifactId}.${project.artifactId}
|
||||
version: ${project.version}-git-${env.GIT_COMMIT}
|
||||
author: 喵♂呜
|
||||
version: ${project.version}
|
||||
author: MiaoWoo
|
||||
website: ${ciManagement.url}
|
||||
load: STARTUP
|
||||
softdepend:
|
||||
- PlaceholderAPI
|
||||
commands:
|
||||
${project.artifactId}:
|
||||
description: ${project.artifactId} - ${project.description}
|
||||
aliases:
|
||||
- ms
|
||||
- mjs
|
||||
- script
|
||||
- mscript
|
||||
usage: §b使用/${project.artifactId} help 查看帮助!
|
||||
permission: ${project.artifactId}.reload
|
||||
permission-message: §c你没有 <permission> 的权限来执行此命令!
|
||||
permissions:
|
||||
${project.artifactId}.use:
|
||||
description: ${project.artifactId} 使用!
|
||||
default: true
|
||||
${project.artifactId}.reload:
|
||||
description: 重新载入插件!
|
||||
default: op
|
||||
- Vault
|
||||
|
@ -1,162 +0,0 @@
|
||||
'use strict'
|
||||
/*global Java, base, module, exports, require*/
|
||||
|
||||
var wrapper = require('api/wrapper')
|
||||
var command = require('api/command')
|
||||
var manager = require('api/plugin')
|
||||
var task = require('api/task')
|
||||
|
||||
var http = require('http')
|
||||
var fs = require('fs')
|
||||
|
||||
var pluginCache = []
|
||||
var packageCache = []
|
||||
var packageNameCache = []
|
||||
|
||||
var description = {
|
||||
name: 'MiaoScriptPackageManager',
|
||||
version: '1.0',
|
||||
author: '喵♂呜',
|
||||
description: 'MiaoScript包管理工具',
|
||||
commands: {
|
||||
'mpm': {
|
||||
description: 'MiaoScriptPackageManager主命令'
|
||||
}
|
||||
},
|
||||
config: {
|
||||
center: 'https://ms.yumc.pw/api/package/list'
|
||||
}
|
||||
}
|
||||
|
||||
var help = [
|
||||
'§6========= §a' + description.name + ' §6帮助 §aBy §b喵♂呜 §6=========',
|
||||
'§6/mpm §ainstall <插件名称> §6- §3安装插件',
|
||||
'§6/mpm §alist §6- §3列出仓库插件',
|
||||
'§6/mpm §aupdate <插件名称> §6- §3更新插件(无插件名称则更新源)',
|
||||
'§6/mpm §aupgrade <插件名称> §6- §3及时更新插件(update需要重启生效)',
|
||||
'§6/mpm §areload <插件名称> §6- §3重载插件(无插件名称则重载自生)',
|
||||
]
|
||||
|
||||
function load() {
|
||||
task.async(function () {
|
||||
JSON.parse(http.get(self.config.center)).data.forEach(function cachePackageName(pkg) {
|
||||
packageCache[pkg.name] = pkg
|
||||
packageNameCache.push(pkg.name)
|
||||
})
|
||||
pluginCache = Object.keys(manager.plugins)
|
||||
})
|
||||
}
|
||||
|
||||
function enable() {
|
||||
command.on(this, 'mpm', {
|
||||
cmd: function (sender, command, args) {
|
||||
if (args.length > 0) {
|
||||
switch (args[0]) {
|
||||
case "list":
|
||||
console.sender(sender, '§6当前 §bMiaoScriptPackageCenter §6中存在下列插件:')
|
||||
for (var pkgName in packageCache) {
|
||||
var pkg = packageCache[pkgName]
|
||||
console.sender(sender, '§6插件名称: §b%s §6版本: §a%s'.format(pkg.name, pkg.version))
|
||||
}
|
||||
break
|
||||
case "install":
|
||||
if (args.length > 1) {
|
||||
download(sender, args[1]);
|
||||
} else {
|
||||
console.sender(sender, '§c请输入插件名称!')
|
||||
}
|
||||
break
|
||||
case "update":
|
||||
if (args.length > 1) {
|
||||
update(sender, args[1]);
|
||||
} else {
|
||||
load();
|
||||
console.sender(sender, "§a仓库缓存刷新成功 共存在 §b" + pluginCache.length + " §a个插件!")
|
||||
}
|
||||
break
|
||||
case "upgrade":
|
||||
break
|
||||
case "delete":
|
||||
if (args.length > 1) {
|
||||
del(sender, args[1]);
|
||||
} else {
|
||||
console.sender(sender, '§c请输入插件名称!')
|
||||
}
|
||||
break
|
||||
case "reload":
|
||||
if (args.length > 1) {
|
||||
var pname = args[1]
|
||||
if (pluginCache.indexOf(pname) !== -1) {
|
||||
manager.reload(pname)
|
||||
} else {
|
||||
console.sender(sender, '§c插件 %s 不存在!'.format(pname))
|
||||
}
|
||||
} else {
|
||||
self.reloadConfig();
|
||||
load();
|
||||
}
|
||||
break
|
||||
case "help":
|
||||
sendHelp(sender);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
sendHelp(sender);
|
||||
}
|
||||
},
|
||||
tab: function (sender, command, args) {
|
||||
if (args.length === 1) return ['list', 'install', 'update', 'upgrade', 'reload']
|
||||
if (args.length > 1) {
|
||||
switch (args[0]) {
|
||||
case "install":
|
||||
return packageNameCache;
|
||||
case "update":
|
||||
case "upgrade":
|
||||
case "reload":
|
||||
return pluginCache;
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function sendHelp(sender){
|
||||
help.forEach(function (msg) {
|
||||
console.sender(sender, msg);
|
||||
})
|
||||
}
|
||||
|
||||
function del(sender, name) {
|
||||
if (pluginCache.indexOf(name) !== -1) {
|
||||
console.sender(sender, '§c插件 %s 不存在!'.format(name));
|
||||
return;
|
||||
}
|
||||
manager.disable(name);
|
||||
fs.delete(plugin.__FILE__);
|
||||
}
|
||||
|
||||
function download(sender, name) {
|
||||
var plugin = packageCache[name];
|
||||
if (!plugin) {
|
||||
console.sender(sender, '§c插件§b', name, '§c不存在')
|
||||
return;
|
||||
}
|
||||
var pfile = fs.file(__dirname, pname + '.js')
|
||||
console.sender(sender, '§6开始下载插件: §b%s'.format(pkg.name))
|
||||
console.sender(sender, '§6插件下载地址: §b%s'.format(pkg.url))
|
||||
fs.save(pfile, http.get(pkg.url))
|
||||
console.sender(sender, '§6插件 §b%s §a下载完毕 开始加载 ...'.format(pname))
|
||||
manager.loadPlugin(pfile)
|
||||
console.sender(sender, '§6插件 §b%s §a安装成功!'.format(pname))
|
||||
}
|
||||
|
||||
function disable() {
|
||||
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
description: description,
|
||||
load: load,
|
||||
enable: enable,
|
||||
disable: disable
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user