API文档

代码方块帮助文档

CodeblockMOD介绍

  1. 代码方块代码方块

    这个方块可执行编写的代码,只能用'代码方块钥匙'才能打开。 您可以通过此方块调用CodeAPI,也可以直接调用游戏代码。 当然,最明显的一点就是,可以持久化数据(保存数据),和更多的高效计算方法。

    运行的代码是JS脚本语言,您需要掌握JS的语法;使用为Java8的'nashorn'脚本引擎执行代码;
    请参考CodeBlock代码特殊语法结构

  2. 代码方块钥匙代码方块钥匙

    功能如名,'代码方块'的钥匙,用'铁砧'修改名字后可锁定打开过的'代码方块'。

    不同代码钥匙(名字区别),分别有不同的运行环境和脚本引擎。(相同的代码钥匙打开过的代码方块,他们是共用一个脚本引擎,请注意同一个脚本引擎的全局变量的使用)

更多的视频介绍

我为CodeBlockMOD做了一个教学视频,您可以点击这个链接,去B站观看我上传的教程。


CodeblockMOD原理

'代码方块MOD'代码运行的核心是Java8的Nashorn脚本引擎,这个引擎的特点可以通过'Java.type(ClassName);'方法获取当前运行Java的类,'代码方块MOD'利用这个引擎去执行玩家编写的代码。

'代码方块MOD'在脚本引擎原有的基础上,创建了import语法,他是'Java.type(ClassName);'变异体,在执行前会被翻译成'Java.type()'的代码。

'代码方块'代码的代码和'CodeVar'变量,都被保存在'代码方块'的NBT标签里,会得到游戏保存。

内置的代码编辑器,使用易语言编译的程序,代码编辑框核心是火花代码编辑框;双方通过Socket进行通信,代码通过文件读写来进行交互。

代码特殊语法

  1. 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()'加载的,只能调用类(静态)方法。
    
    											

  2. 内置变量:

    全局变量 (请注意全局变量的线程安全)

    'Code'内置变量: Code对象变量封装了一些代码方块的API,您可以点击这条链接去查看所有API。此变量您能直接在代码方块内调用.

    'System'内置变量: Java的System对象,您可以调出系统输出(System.out.println("hi");)

    'CodeVar'内置变量: 每个代码方块独有的变量,这个变量在代码执行前会去找代码方块储存的变量(默认:"{}"空json),在代码执行后,又会将值保存到代码方块里。 您可以用这个变量来完成数据持久化操作。

    自定义全局变量:
    在代码中,如果您的'import'和变量的定义如果没有在方法function里面,那这个将会是自定义全局变量。这个变量将会被同一组(分类方法>代码方块钥匙的名字)代码方块共享。

  3. 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();
	}


还有疑问? 欢迎加群讨论-QQ群807477954