API文档
代码方块帮助文档
CodeblockMOD介绍
-
代码方块
这个方块可执行编写的代码,只能用'代码方块钥匙'才能打开。 您可以通过此方块调用CodeAPI,也可以直接调用游戏代码。 当然,最明显的一点就是,可以持久化数据(保存数据),和更多的高效计算方法。
运行的代码是JS脚本语言,您需要掌握JS的语法;使用为Java8的'nashorn'脚本引擎执行代码;
请参考CodeBlock代码特殊语法结构。 -
代码方块钥匙
功能如名,'代码方块'的钥匙,用'铁砧'修改名字后可锁定打开过的'代码方块'。
不同代码钥匙(名字区别),分别有不同的运行环境和脚本引擎。(相同的代码钥匙打开过的代码方块,他们是共用一个脚本引擎,请注意同一个脚本引擎的全局变量的使用)
更多的视频介绍
我为CodeBlockMOD做了一个教学视频,您可以点击这个链接,去B站观看我上传的教程。
CodeblockMOD原理
'代码方块MOD'代码运行的核心是Java8的Nashorn脚本引擎,这个引擎的特点可以通过'Java.type(ClassName);'方法获取当前运行Java的类,'代码方块MOD'利用这个引擎去执行玩家编写的代码。
'代码方块MOD'在脚本引擎原有的基础上,创建了import语法,他是'Java.type(ClassName);'变异体,在执行前会被翻译成'Java.type()'的代码。
'代码方块'代码的代码和'CodeVar'变量,都被保存在'代码方块'的NBT标签里,会得到游戏保存。
内置的代码编辑器,使用易语言编译的程序,代码编辑框核心是火花代码编辑框;双方通过Socket进行通信,代码通过文件读写来进行交互。
代码特殊语法
-
import导包功能
'import'关键词在JS语法结构中,它只是保留关键词,在这里我们将这段代码进行了转义,让它拥有了类似导包的功能。
您可以用import导入一些Java类使用新语法结构:
import 类路径;
例子:import java.lang.System;
原理: 在代码执行前,您的代码会交给CodeMOD的代码转义器,如将
import java.lang.System;
转义为var System = Java.type("java.lang.System");
('Java.type()'方法是nashorn脚本引擎加载Java对象的方法)PS: import导包后将会覆盖变量,如果包类名和现有变量重名,请定义别名。
如: 导入'red.stu.mc.api.Code'包,则'Code'变量会被覆盖;如想保留原有变量,以'Code'为例,可以参考以下方式:/* 方式一 */ var CodeApi = Code; import red.stu.mc.api.Code; // CodeApi > 内置Java对象变量,只能调用对象(非静态)方法 // Code > 通过导包加载的,只能调用类(静态)方法。 /* 方式二 */ // Code; 内置初始化对象 var codeStatic = Java.type("red.stu.mc.api.Code"); // Code > 内置Java对象变量,只能调用对象(非静态)方法 // codeStatic > 通过'Java.type()'加载的,只能调用类(静态)方法。
-
内置变量:
全局变量 (请注意全局变量的线程安全)
'Code'内置变量: Code对象变量封装了一些代码方块的API,您可以点击这条链接去查看所有API。此变量您能直接在代码方块内调用.
'System'内置变量: Java的System对象,您可以调出系统输出(
System.out.println("hi");
)'CodeVar'内置变量: 每个代码方块独有的变量,这个变量在代码执行前会去找代码方块储存的变量(默认:"{}"空json),在代码执行后,又会将值保存到代码方块里。 您可以用这个变量来完成数据持久化操作。
自定义全局变量:
在代码中,如果您的'import'和变量的定义如果没有在方法function里面,那这个将会是自定义全局变量。这个变量将会被同一组(分类方法>代码方块钥匙的名字)代码方块共享。 -
main方法function
您应该尽量避免定义全局变量,您可以将代码写在方法里面;这样一定程度上不会干扰别的代码方块的变量。
可以参考下面示例代码,这是推荐的标准结构:main(); function main() { import net.minecraft.block.Block; Code.sendMsg("ID为0的方块是:" + Block.getBlockById(0)); }
代码接口CodeAPI
此列举方块,可通过'Code'变量对象调用,已内置初始化,无需导包。
特别注意: 所有 static 静态Code方法 不能被'Code'变量直接调用,您需要手动导入'import red.stu.mc.api.Code;'包,才能使用这些静态方法;但是如果您导入'import red.stu.mc.api.Code;'包后,原有'Code'变量更能就会消失!
原因参阅:代码特殊语法-import原理
/* 可直接调用变量 */
public IBlockState iBlockState; // 执行此代码的'代码方块'
public World worldIn; // '代码方块'所处World
public BlockPos blockPos; // '代码方块'位置
public Block blockIn; // '代码方块'对象
public BlockPos fromBlockPos; // 红石信号来源位置
/* static 静态Code方法 */
/**
* 获取当前Minecraft实例对象
* 此对象执行的效果不会被保存,意味执行修改一旦遭到刷新就会被修复。
* 如果您想实际修改,请直接使用'worldIn'变量
* @return Minecraft
*/
public static Minecraft getMC() {
return Minecraft.getMinecraft();
}
/**
* 根据方块名字获取方块对象
* @param name 方块名字 如空气"air"
* @return Block
*/
public static Block getBlockFromName(String name) {
return Block.getBlockFromName(name);
}
/**
* 根据方块ID获取方块对象
* @param id 方块数字ID
* @return Block
*/
public static Block getBlockById(int id) {
return Block.getBlockById(id);
}
/**
* 根据方块物品获取方块对象
* @param itemIn 方块物品
* @return Block
*/
public static Block getBlockFromItem(Item itemIn) {
return Block.getBlockFromItem(itemIn);
}
/* Code普通方法 */
/**
* 给当前世界所有玩家发送消息 (缩写方法名)
* @param message 消息内容
*/
public void sendMsg(String message) {
sendMessage(message);
}
/**
* 给当前世界所有玩家发送消息
* @param message
*/
public void sendMessage(String message) {
List list = worldIn.playerEntities;
if (list == null)
return;
ITextComponent component = new TextComponentString(message);
for (EntityPlayer player : list) {
player.sendMessage(component);
}
}
/**
* 放置方块
* @param state 方块状态 如:Block.getBlockFromName("air").getDefaultState();
* @param x X坐标
* @param y Y坐标
* @param z Z坐标
* @return boolean 是否放置成功
*/
public boolean setBlock(IBlockState state, int x, int y, int z) {
return worldIn.setBlockState(new BlockPos(x, y, z), state);
}
/**
* 放置空气方块
* @param x X坐标
* @param y Y坐标
* @param z Z坐标
* @return boolean 是否放置成功
*/
public boolean setBlockToAir(int x, int y, int z) {
return worldIn.setBlockToAir(new BlockPos(x, y, z));
}
/**
* 获取方块状态
* @param x X坐标
* @param y Y坐标
* @param z Z坐标
* @return IBlockState
*/
public IBlockState getBlockState(int x, int y, int z) {
return worldIn.getBlockState(new BlockPos(x, y, z));
}
/**
* 获取方块不透明度
* @param x X坐标
* @param y Y坐标
* @param z Z坐标
* @return
*/
public int getBlockLightOpacity(int x, int y, int z) {
return worldIn.getBlockLightOpacity(new BlockPos(x, y, z));
}
/**
* 获取当前方块世界类型
* @return WorldType
*/
public WorldType getWorldType() {
return worldIn.getWorldType();
}