Minecraft(我的世界)中文论坛

标题: [编程][上古之石] Scriptful —— 告别Java与IDE,用脚本语言写插件[1.8.x-1.9.4]

作者: 青木源    时间: 2016-8-29 20:29
本帖最后由 XIAOMM 于 2016-8-31 15:54 编辑

玩什么JAVA来玩C++
作者: Olurbo    时间: 2016-8-29 20:30
无比的强大!
作者: duang2333    时间: 2016-8-29 20:32
javascript?
作者: CustomStuff2    时间: 2016-8-29 20:35
标题: [编程][上古之石] Scriptful —— 告别Java与IDE,用脚本语言写插件[1.8.x-1.9.4]
本帖最后由 1582952890 于 2017-9-16 18:58 编辑

0. 前言
插件程序员想起了那些年被插件支配的恐怖。
创建一个Java工程,多痛苦。
添加依赖库,多痛苦。
创建一个继承自JavaPlugin的类,多痛苦。
写plugin.yml,多痛苦。
导出一个jar,多痛苦。
如果中间还要debug,更痛苦了。
打开IDE,多痛苦。

于是,脚本语言创造了懒惰。
而一个号称最懒惰的程序员,创造这个插件。

本插件开源(GPLv3):https://github.com/aegistudio/Scriptful

1. 程序员怎么使用?
1.1. 一个最简单的插件

1.2 需要监听器?

1.3 接受指令

1.4 多个文件?

1.5 支持其他脚本语言

1.6 Unload Hook

1.7 Scheduler


2. 服主怎么使用?
寻找用脚本写的插件,拖进plugin/Scriptful文件夹下面,即可。

3. 权限与指令
/script
: 列出所有script下的指令及用法。(执行script指令均需要script.command权限!)
/script unload <name>: 卸载指定的插件(插件必须已经加载)。
/script reload <name>: 重新加载指定的插件(插件必须已经加载)。
/script load <name>: 加载指定的插件(插件刚被卸载,或刚被拖进Scriptful目录下)。
/script exec <name> <code>: 在某一插件环境下执行语句(debug福利!)。

4. 更新日志
v0.04b (2016.12.11)

v0.03b (2016.8.31)

v0.02b (2016.8.30)

v0.01b (2016.8.29)



更新中!
作者: 117779284    时间: 2016-8-29 20:38
这里应该有更详细的教材。。。
感谢上古做的贡献。希望能更加完善
作者: CustomStuff2    时间: 2016-8-29 20:41
XIAOMM 发表于 2016-8-29 20:29
完全告别JAVA的前提,先告别JAVA版的MC。
所以来玩C++的Win10版吧(滑稽)

“告别Java与IDE,用脚本语言写插件”
这句子断句是
“告别Java与IDE写插件,用脚本语言写插件”
作者: 凛    时间: 2016-8-29 20:43
新人都是怪物系列
作者: CustomStuff2    时间: 2016-8-29 20:45
duang2333 发表于 2016-8-29 20:32
javascript?

不仅可以支持js,还可以支持比如lua等语言。。
我教程还没写到。
作者: 酷车手BB弹    时间: 2016-8-29 20:51
我去,这是2级所做的?
新人都是怪物系列。
作者: yaojiajie    时间: 2016-8-29 20:58
提示: 作者被禁止或删除 内容自动屏蔽
作者: 914554688wyt    时间: 2016-8-29 21:01
姆书记又发插件 精华预备
作者: 1344641274    时间: 2016-8-29 21:07
新人都进上古之石了!
作者: HotPe_e    时间: 2016-8-29 21:17
向dalao势力低头
作者: 白色的奢华、    时间: 2016-8-29 21:17
还是不太懂。。。
作者: x240295600    时间: 2016-8-29 21:18
火钳刘明
作者: CustomStuff2    时间: 2016-8-29 21:31
堕星辰 发表于 2016-8-29 21:35
支持原创!
不过冒昧问一句
我想知道和Skript的差别是?

http://njol.ch/projects/skript/ Skript is a plugin for Bukkit, a popular Minecraft server mod. It allows server admins to easily modify how Minecraft works without programming anything.

也就是说,skript目标是不用编程,而我只是不用java编程罢了。
作者: 堕星辰    时间: 2016-8-29 21:35
支持原创!
不过冒昧问一句
我想知道和Skript的差别是?
作者: 冰封死灵    时间: 2016-8-29 21:47
完全看不懂的感觉
作者: 堕星辰    时间: 2016-8-29 23:07
CustomStuff2 发表于 2016-8-29 14:31
http://njol.ch/projects/skript/ Skript is a plugin for Bukkit, a popular Minecraft server mod. It  ...

这样啊_(:з」∠)_
作者: 云闪    时间: 2016-8-29 23:27
姆书记又来刷精华了_(:_」∠)_

用这个插件写测试插件会方便非常多
期待加入实时编译输出(聊天框)的功能(嗯就像py那样?能计算出结果的就输出){:10_512:}
作者: andylizi    时间: 2016-8-30 10:56
我突然想到有没有可能把js代码转换为原生bukkit插件
作者: CustomStuff2    时间: 2016-8-30 12:51
andylizi 发表于 2016-8-30 10:56
我突然想到有没有可能把js代码转换为原生bukkit插件

导出bytecode弄进jar里么233333
作者: andylizi    时间: 2016-8-30 12:53
CustomStuff2 发表于 2016-8-30 12:51
导出bytecode弄进jar里么233333

。。我的意思是把js写法用程序转换为插件一般写法
作者: zyizhuo    时间: 2016-8-30 13:20
本帖最后由 zyizhuo 于 2016-9-3 13:05 编辑

这是用js编的是吗

作者: Lam_h    时间: 2016-8-30 13:47
这个插件方便的地方就是可以将PvPin制作的插件丢进去运行...吧?(似乎用法与Pvpin不一样的说....)
作者: 爱琴炫彩    时间: 2016-8-30 14:26
本帖最后由 爱琴炫彩 于 2016-8-30 14:32 编辑

看起来很不错! 那么效率如何呢?

比如监听了比如ItemMove的事件,那么最终的调用过程会是怎样的?
话说用脚本直接写的话,会少一样东西,那就是..代码提示...,不看代码提示直接写代码的大佬,估计用java写会更快...


没代码提示我觉得还是比较难受的...

作者: 980378314    时间: 2016-8-30 15:13
这个很棒简单省事
作者: 翼LOVE·小爱    时间: 2016-8-30 15:31
直接放入插件源代码可以执行吗?(窝真的不会编程_(:з」∠)_)

作者: CustomStuff2    时间: 2016-8-30 15:42
爱琴炫彩 发表于 2016-8-30 14:26
看起来很不错! 那么效率如何呢?

比如监听了比如ItemMove的事件,那么最终的调用过程会是怎样的?

效率不用问了,基本上你见到的脚本引擎都有JIT功能,java跑多快,你脚本就该跑多快。

过程和一般插件一样吧,根据注册的优先级被调用。不会因为用js写而有功能上的损失。

代码提示指哪种?语法检查的话,应该找有语法检查功能的文本编辑器。
要用什么类这个应该看javadoc。
作者: andylizi    时间: 2016-8-30 18:09
诶等等我发现一件事诶
监听器的定义里怎么没有ignoreCancelled
作者: CustomStuff2    时间: 2016-8-30 18:10
更新

v0.02b (2016.8.30)
支持直接将引擎jar文件放进插件文件夹
修复一个指令相关的bug
作者: CustomStuff2    时间: 2016-8-30 18:33
andylizi 发表于 2016-8-30 18:09
诶等等我发现一件事诶
监听器的定义里怎么没有ignoreCancelled

手残,下个版本加上
作者: ak1115284886    时间: 2016-8-31 03:52
简直一万个好评!
作为超级懒的程序员感觉重新获得生活的希望
作者: QQ1357288463    时间: 2016-9-1 12:20
5级的有新人勋章的大神...
我想静静
作者: 罗海鸿    时间: 2016-9-2 21:41
感觉很那个啊……还有点看不懂……{:10_493:}
作者: RE_OVO    时间: 2016-9-3 06:50
支持姆书记。
使用前置呢?比如Vault PL....
作者: Green_stone    时间: 2016-9-3 11:28
话说这本身是插件还是什么?
作者: 司马缸砸光    时间: 2016-9-3 12:26
开创插件开发新时代
作者: xiari_    时间: 2016-9-3 12:33
依旧看不懂233 我不会呀 dalao
作者: zyizhuo    时间: 2016-9-3 13:02
XIAOMM 发表于 2016-8-29 20:29
玩什么JAVA来玩C++

这个我支持。。问题是c++咋写mc插件啊?
作者: CustomStuff2    时间: 2016-9-3 14:31
本帖最后由 CustomStuff2 于 2016-9-3 14:46 编辑
jebme 发表于 2016-9-3 06:50
支持姆书记。
使用前置呢?比如Vault PL....

self.getServer().getServicesManager().getRegistration(XXXXX.class)
作者: a66344512    时间: 2016-9-4 09:38
这不错可以拿来偷懒,方便很多.赞
作者: 夜喵星球    时间: 2016-9-4 18:36
没看懂啊~但是好像很厉害的样子{:10_525:}
作者: Iratu    时间: 2016-9-10 11:27
1344641274 发表于 2016-8-29 21:07
新人都进上古之石了!

小号没人看出来系列
作者: qq245271830    时间: 2016-9-10 12:12
要是不会java是不是就不能用了啊
作者: CustomStuff    时间: 2016-9-10 19:01
qq245271830 发表于 2016-9-10 12:12
要是不会java是不是就不能用了啊

如果是程序员会js且会看javadoc即可,如果是服主两样都不用会
作者: qq245271830    时间: 2016-9-11 01:03
CustomStuff 发表于 2016-9-10 19:01
如果是程序员会js且会看javadoc即可,如果是服主两样都不用会

好吧  看来是无缘了   我想请问一下  如果想学写插件应该怎么学习java   有基础
作者: 远古工作室    时间: 2016-9-12 21:07
C++不好么?
作者: TFPS·妖魅    时间: 2016-9-15 08:06
我还是不会
作者: qt819762430    时间: 2016-9-15 21:28
666  60个绿宝石亮了  大神啊
作者: Ant繁星飞跃    时间: 2016-9-17 07:47
支持上古之石  你们简直无敌了~
作者: Tao_qi~    时间: 2016-9-18 12:43
水一下。。。。。233333333333333
作者: 边陲镇长    时间: 2016-9-19 20:15
加油~兄弟  看好
作者: ___5    时间: 2016-9-22 22:56
能发个 加入游戏离开游戏,准备大厅,团队,队友无伤的语言吗(类似起床,饥饿游戏,起码让我参考,亲,谢谢拜托了)
作者: DGai    时间: 2016-9-27 18:51
新人表示茫然...
作者: 1692236385    时间: 2016-9-27 19:38
不知道怎么用 不过看起来太6了
作者: andylizi    时间: 2016-12-11 11:36
本帖最后由 andylizi 于 2016-12-11 11:43 编辑
拖进plugin/Scriptful文件夹下面,即可。

应为 plugins


paperspig0t-1.8.8
Scriptful v0.03-beta
插件第一次启动,还没有配置文件夹时
重启一下就好了

判断为你忘了
  1. getDataFolder().mkdirs()
复制代码


另外在主类第153行,应该指定加载js使用的编码,不然java自动使用系统默认编码,在不同系统环境下会不一样
作者: andylizi    时间: 2016-12-11 11:53
还有一个极其严重的bug:假设你监听 EntityDamageByEntityEvent ,那么它的父类 EntityDamageEvent 也能触发这个监听器。

还有一个极其严重的问题:这里面怎么使用JDK类库?import?
作者: 117779284    时间: 2016-12-11 20:04
1.7MOD服确实不能用
作者: CustomStuff2    时间: 2016-12-11 22:46
andylizi 发表于 2016-12-11 11:53
还有一个极其严重的bug:假设你监听 EntityDamageByEntityEvent ,那么它的父类 EntityDamageEvent 也能触 ...

已修复(虽然群里已经说过了,我怕放在这里影响不好)
作者: CustomStuff2    时间: 2016-12-11 22:47
117779284 发表于 2016-12-11 20:04
1.7MOD服确实不能用

如何不能用法,至少要像楼上上的梨子一样,给个截图之类的。
作者: 117779284    时间: 2016-12-11 23:59
CustomStuff2 发表于 2016-12-11 22:47
如何不能用法,至少要像楼上上的梨子一样,给个截图之类的。

[Scriptful] LoadFail
java.lang.Exception: No engine for js
        at net.aegistudio.scriptful.Scriptful.makeScript(Scriptful.java:168) ~[scriptful.jar:?]
        at net.aegistudio.scriptful.Scriptful.loadFile(Scriptful.java:129) ~[scriptful.jar:?]
        at net.aegistudio.scriptful.Scriptful.onEnable(Scriptful.java:100) [scriptful.jar:?]
        at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:316) [JavaPlugin.class:1.7.10-1614.46]
        at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:368) [JavaPluginLoader.class:1.7.10-1614.46]
        at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:410) [SimplePluginManager.class:1.7.10-1614.46]
        at org.bukkit.craftbukkit.v1_7_R4.CraftServer.loadPlugin(CraftServer.java:415) [CraftServer.class:1.7.10-1614.46]
        at org.bukkit.craftbukkit.v1_7_R4.CraftServer.enablePlugins(CraftServer.java:349) [CraftServer.class:1.7.10-1614.46]
        at net.minecraft.server.MinecraftServer.func_71243_i(MinecraftServer.java:513) [MinecraftServer.class:?]
        at net.minecraft.server.MinecraftServer.func_71222_d(MinecraftServer.java:487) [MinecraftServer.class:?]
        at net.minecraft.server.MinecraftServer.func_71247_a(MinecraftServer.java:447) [MinecraftServer.class:?]
        at net.minecraft.server.dedicated.DedicatedServer.func_71197_b(DedicatedServer.java:336) [lt.class:?]
        at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:633) [MinecraftServer.class:?]
        at java.lang.Thread.run(Unknown Source) [?:1.8.0_102]
[23:56:25] [Server thread/INFO]: Server permissions file permissions.yml is empty, ignoring it
作者: 117779284    时间: 2016-12-12 00:25
CustomStuff2 发表于 2016-12-12 00:32
喔,你是梨子今天说的那个服主么。
我猜这个可能和jre有关(没有js引擎),你可以尝试。

1.10测试是正常的
1.7.10不可以的·
确实是不可以吧。。我也只是实验一下1.8以下是否支持。
不管如何都试试嘛·
作者: CustomStuff2    时间: 2016-12-12 00:32
117779284 发表于 2016-12-11 23:59
[Scriptful] LoadFail
java.lang.Exception: No engine for js
        at net.aegistudio.scriptful.Scriptful. ...

喔,你是梨子今天说的那个服主么。
我猜这个可能和jre有关(没有js引擎),你可以尝试。

[del]1. 下个jdk并用jdk的java启动服务器。[/del]
2. 下载Rhino(https://github.com/mozilla/rhino ... EASE/rhino1_7R5.zip),解压,把里面的两个jar(除了javadoc.jar以外的另外两个)放在%JAVA_HOME%\lib(windows)或者$JAVA_HOME/lib下。

后者可能相对可行,但我还没试过,毕竟我这没有出现过丢js引擎的情况。

作者: CustomStuff2    时间: 2016-12-12 11:57
本帖最后由 CustomStuff2 于 2016-12-12 11:58 编辑
117779284 发表于 2016-12-12 00:25
1.10测试是正常的
1.7.10不可以的·
确实是不可以吧。。我也只是实验一下1.8以下是否支持。

wait!
为啥1.10下能跑而1.7.10下不能,你运行两个服务器用的是同一个jre嘛?

(这个现象有趣了,可以研究下)

作者: 117779284    时间: 2016-12-12 17:13
CustomStuff2 发表于 2016-12-12 11:57
wait!
为啥1.10下能跑而1.7.10下不能,你运行两个服务器用的是同一个jre嘛?

当然一个JAR啦。那里有个报错信息 给你发信息啦···
作者: wobo    时间: 2017-6-7 23:32
我是特意来点赞加收藏的,这是一个真心很好的插件,像我们这种半吊子JAVA的人,还是用Python比较顺手,哈哈~~~~~
作者: 子德    时间: 2017-6-8 22:42
请问新人如果想通过这个方式入坑插件有什么办法?(懂得C++)
作者: 婲样的女孩    时间: 2018-6-26 19:00
XIAOMM 发表于 2016-8-29 20:29
玩什么JAVA来玩C++

我觉得“易语言”不错
作者: 1046402434    时间: 2018-8-28 12:19
MCBBS有你更精彩~~
作者: Reliable_han    时间: 2018-8-28 16:37
好高端 感谢发布
作者: deepdra    时间: 2018-8-31 19:24
sssssssssssssssssssssss
作者: 粉云    时间: 2018-8-31 20:43
滋瓷原创, 什么时候能有依赖项之类的操作呢, 这样的话不就方便开发相关lib了吗
作者: 萝卜石头    时间: 2019-8-18 15:23
能支持1.14.4吗?
楼主啥时候更新啊?
作者: 萝卜石头    时间: 2019-8-18 16:30
请问有脚本编写文档吗?
作者: 萝卜石头    时间: 2019-11-3 10:31
所以,有文档吗?
作者: 萝卜石头    时间: 2019-11-3 10:43
我要文档啊啊啊
作者: 萝卜石头    时间: 2019-12-8 10:17
用python写聊天事件时,发生如下报错:
javax.script.ScriptException: TypeError: 'NoneType' object is not callable in <script> at line number 9
at org.python.jsr223.PyScriptEngine.scriptException(PyScriptEngine.java:222) ~[?:?]
at org.python.jsr223.PyScriptEngine.eval(PyScriptEngine.java:59) ~[?:?]
at org.python.jsr223.PyScriptEngine.eval(PyScriptEngine.java:64) ~[?:?]
at javax.script.AbstractScriptEngine.eval(Unknown Source) ~[?:1.8.0_111]
at net.aegistudio.scriptful.Scriptful.makeScript(Scriptful.java:173) ~[%5B脚本%5Dscriptful.jar:?]
at net.aegistudio.scriptful.Scriptful.loadFile(Scriptful.java:129) ~[%5B脚本%5Dscriptful.jar:?]
at net.aegistudio.scriptful.ScriptfulCommand$2.execute(ScriptfulCommand.java:56) [%5B脚本%5Dscriptful.jar:?]
at net.aegistudio.scriptful.ScriptfulCommand.execute(ScriptfulCommand.java:161) [%5B脚本%5Dscriptful.jar:?]
at net.aegistudio.scriptful.Scriptful.onCommand(Scriptful.java:199) [%5B脚本%5Dscriptful.jar:?]
at org.bukkit.command.PluginCommand.execute(PluginCommand.java:45) [spigot-1.14.4.jar:git-Spigot-9de398a-9c887d4]
at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:149) [spigot-1.14.4.jar:git-Spigot-9de398a-9c887d4]
at org.bukkit.craftbukkit.v1_14_R1.CraftServer.dispatchCommand(CraftServer.java:710) [spigot-1.14.4.jar:git-Spigot-9de398a-9c887d4]
at org.bukkit.craftbukkit.v1_14_R1.CraftServer.dispatchServerCommand(CraftServer.java:695) [spigot-1.14.4.jar:git-Spigot-9de398a-9c887d4]
at net.minecraft.server.v1_14_R1.DedicatedServer.handleCommandQueue(DedicatedServer.java:433) [spigot-1.14.4.jar:git-Spigot-9de398a-9c887d4]
at net.minecraft.server.v1_14_R1.DedicatedServer.b(DedicatedServer.java:397) [spigot-1.14.4.jar:git-Spigot-9de398a-9c887d4]
at net.minecraft.server.v1_14_R1.MinecraftServer.a(MinecraftServer.java:971) [spigot-1.14.4.jar:git-Spigot-9de398a-9c887d4]
at net.minecraft.server.v1_14_R1.MinecraftServer.run(MinecraftServer.java:816) [spigot-1.14.4.jar:git-Spigot-9de398a-9c887d4]
at java.lang.Thread.run(Unknown Source) [?:1.8.0_111]
Caused by: org.python.core.PyException
at org.python.core.Py.TypeError(Py.java:265) ~[?:?]
at org.python.core.PyObject.__call__(PyObject.java:409) ~[?:?]
at org.python.core.PyObject.__call__(PyObject.java:464) ~[?:?]
at org.python.core.PyDictionaryDerived.hashCode(PyDictionaryDerived.java:810) ~[?:?]
at net.aegistudio.scriptful.execution.MethodExecutor.compareTo(MethodExecutor.java:25) ~[?:?]
at net.aegistudio.scriptful.execution.MethodExecutor.compareTo(MethodExecutor.java:1) ~[?:?]
at net.aegistudio.scriptful.abstraction.ListenerAbstract.compareTo(ListenerAbstract.java:45) ~[?:?]
at net.aegistudio.scriptful.abstraction.ListenerAbstract.compareTo(ListenerAbstract.java:1) ~[?:?]
at java.util.TreeMap.compare(Unknown Source) ~[?:1.8.0_111]
at java.util.TreeMap.put(Unknown Source) ~[?:1.8.0_111]
at java.util.TreeSet.add(Unknown Source) ~[?:1.8.0_111]
at net.aegistudio.scriptful.ScriptSurrogator.registerListener(ScriptSurrogator.java:112) ~[?:?]
at net.aegistudio.scriptful.ScriptSurrogator.registerListener(ScriptSurrogator.java:137) ~[?:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_111]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_111]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_111]
at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_111]
at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:188) ~[?:?]
at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:206) ~[?:?]
at org.python.core.PyObject.__call__(PyObject.java:497) ~[?:?]
at org.python.core.PyObject.__call__(PyObject.java:501) ~[?:?]
at org.python.core.PyMethod.__call__(PyMethod.java:141) ~[?:?]
at org.python.pycode._pyx12.f$0(<script>:9) ~[?:?]
at org.python.pycode._pyx12.call_function(<script>) ~[?:?]
at org.python.core.PyTableCode.call(PyTableCode.java:171) ~[?:?]
at org.python.core.PyCode.call(PyCode.java:18) ~[?:?]
at org.python.core.Py.runCode(Py.java:1614) ~[?:?]
at org.python.core.__builtin__.eval(__builtin__.java:497) ~[?:?]
at org.python.core.__builtin__.eval(__builtin__.java:501) ~[?:?]
at org.python.util.PythonInterpreter.eval(PythonInterpreter.java:259) ~[?:?]
at org.python.jsr223.PyScriptEngine.eval(PyScriptEngine.java:57) ~[?:?]
... 16 more

代码如下:
class chatListener(dict):
    def __init__(this):
        this["event"] = "PlayerChatEvent"
        this["handle"] = handle
    def handle(this, chatEvent):
        chatEvent.getPlayer().sendMessage("You speak!")
        return True
        
self.registerListener(chatListener())


作者: catserver    时间: 2019-12-12 22:32
貌似给新人福利,插件很友好呢
作者: a888kay    时间: 2020-4-14 09:14
刚好懂得JAVA感觉不难学习
作者: 428751434    时间: 2020-5-5 12:35
mcbbs有你精彩
作者: 老李小号    时间: 2020-9-14 19:39
HotPe_e 发表于 2016-8-29 21:17
向dalao势力低头

5级=大佬,9级=萌新