New classes which separate out functionality of the JS interpreter and Minecraft impl and Command processor.
This commit is contained in:
parent
c9f30382d6
commit
9df8b30fff
3 changed files with 386 additions and 0 deletions
12
IScriptCraft.java
Normal file
12
IScriptCraft.java
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
package net.minecraft.src;
|
||||||
|
|
||||||
|
public interface IScriptCraft
|
||||||
|
{
|
||||||
|
public double[] getPlayerPos();
|
||||||
|
public double[] getMousePos();
|
||||||
|
public void putSign(String[] texts,int x, int y, int z, int block, int meta);
|
||||||
|
public void putBlock(int x, int y, int z, int blockId, int meta);
|
||||||
|
public String getBlock(int x, int y, int z);
|
||||||
|
public void notifyAdministrators(String message);
|
||||||
|
public void setInvoker(Object invoker);
|
||||||
|
}
|
265
ScriptCraftEvaluator.java
Normal file
265
ScriptCraftEvaluator.java
Normal file
|
@ -0,0 +1,265 @@
|
||||||
|
package net.minecraft.src;
|
||||||
|
|
||||||
|
import org.mozilla.javascript.*;
|
||||||
|
import java.util.List;
|
||||||
|
import java.io.*;
|
||||||
|
import javax.swing.JFileChooser;
|
||||||
|
|
||||||
|
public class ScriptCraftEvaluator
|
||||||
|
{
|
||||||
|
protected static IScriptCraft sc = null;
|
||||||
|
protected Context ctx = null;
|
||||||
|
protected Scriptable scope = null;
|
||||||
|
|
||||||
|
public static class MCScope extends ImporterTopLevel{
|
||||||
|
public MCScope(Context ctx){
|
||||||
|
super(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public ScriptCraftEvaluator(IScriptCraft scImpl)
|
||||||
|
{
|
||||||
|
ScriptCraftEvaluator.sc = scImpl;
|
||||||
|
this.ctx = Context.enter();
|
||||||
|
ScriptableObject importer = new ScriptCraftEvaluator.MCScope(ctx);
|
||||||
|
this.scope = this.ctx.initStandardObjects(importer);
|
||||||
|
//
|
||||||
|
// for mcp debug only
|
||||||
|
//ctx.evaluateString(scope,"importPackage(net.minecraft.src)","<cmd>",1,null);
|
||||||
|
//
|
||||||
|
String[] names = {
|
||||||
|
"print"
|
||||||
|
,"load"
|
||||||
|
,"help"
|
||||||
|
,"getPlayerPos"
|
||||||
|
,"getMousePos"
|
||||||
|
,"putBlock"
|
||||||
|
,"getBlock"
|
||||||
|
,"putSign"
|
||||||
|
};
|
||||||
|
importer.defineFunctionProperties(names,
|
||||||
|
ScriptCraftEvaluator.class,
|
||||||
|
ScriptableObject.DONTENUM);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* So clients can add their own properties ...
|
||||||
|
*
|
||||||
|
* evaluator.getScope().defineProperty("jsVarName",javaObject);
|
||||||
|
*/
|
||||||
|
public ScriptableObject getScope()
|
||||||
|
{
|
||||||
|
return (ScriptableObject)this.scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object eval(String javascript, Object invoker)
|
||||||
|
{
|
||||||
|
ScriptCraftEvaluator.sc.setInvoker(invoker);
|
||||||
|
ScriptCraftEvaluator.sc.notifyAdministrators("js> " + javascript);
|
||||||
|
Object result = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result = ctx.evaluateString(this.scope, javascript, "<cmd>", 1, null);
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace(System.err);
|
||||||
|
ScriptCraftEvaluator.sc.notifyAdministrators("Exception: " + e.getMessage());
|
||||||
|
}
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
ScriptCraftEvaluator.sc.notifyAdministrators(Context.toString(result));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a javascript source file and evaluate its contents.
|
||||||
|
*/
|
||||||
|
public static Object load(Context cx, Scriptable thisObj, Object[] args, Function funObj)
|
||||||
|
{
|
||||||
|
Object result = null;
|
||||||
|
|
||||||
|
File scriptFile = null;
|
||||||
|
String filename = null;
|
||||||
|
|
||||||
|
if (args.length == 0)
|
||||||
|
{
|
||||||
|
JFileChooser fc = new javax.swing.JFileChooser();
|
||||||
|
int rc = fc.showOpenDialog(null);
|
||||||
|
if (rc ==JFileChooser.APPROVE_OPTION){
|
||||||
|
scriptFile = fc.getSelectedFile();
|
||||||
|
}else{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
scriptFile = new File((String)args[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
FileReader in = null;
|
||||||
|
try {
|
||||||
|
in = new FileReader(scriptFile);
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException ex)
|
||||||
|
{
|
||||||
|
ex.printStackTrace(System.err);
|
||||||
|
ScriptCraftEvaluator.sc.notifyAdministrators( "Error - File not found " + args[0]);
|
||||||
|
Context.reportError("Couldn't open file \"" + scriptFile + "\".");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
filename = scriptFile.getAbsolutePath();
|
||||||
|
System.out.println("ScripCraftEvaluator: filename=" + filename);
|
||||||
|
File parentFile = scriptFile.getParentFile();
|
||||||
|
String filedir = null;
|
||||||
|
if (parentFile !=null){
|
||||||
|
filedir = parentFile.getAbsolutePath();
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// setup the special script-context-only variables
|
||||||
|
//
|
||||||
|
((ScriptableObject)thisObj).defineProperty("$SCRIPT",filename,ScriptableObject.DONTENUM);
|
||||||
|
((ScriptableObject)thisObj).defineProperty("$SCRIPT_DIR",filedir==null?"":filedir,ScriptableObject.DONTENUM);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Here we evalute the entire contents of the file as
|
||||||
|
// a script. Text is printed only if the print() function
|
||||||
|
// is called.
|
||||||
|
ScriptCraftEvaluator.sc.notifyAdministrators( "Loading " + filename);
|
||||||
|
result = cx.evaluateReader(thisObj, in, filename, 1, null);
|
||||||
|
ScriptCraftEvaluator.sc.notifyAdministrators( "Successfully loaded " + filename);
|
||||||
|
}
|
||||||
|
catch (WrappedException we) {
|
||||||
|
we.printStackTrace(System.err);
|
||||||
|
String wes = we.getWrappedException().toString();
|
||||||
|
ScriptCraftEvaluator.sc.notifyAdministrators("WrappedException while loading " + filename + ": " + wes);
|
||||||
|
System.err.println(wes);
|
||||||
|
we.printStackTrace();
|
||||||
|
}
|
||||||
|
catch (EvaluatorException ee) {
|
||||||
|
ee.printStackTrace(System.err);
|
||||||
|
System.err.println("js: " + ee.getMessage());
|
||||||
|
ScriptCraftEvaluator.sc.notifyAdministrators( "EvaluatorException while loading " + filename + ": " + ee.getMessage());
|
||||||
|
}
|
||||||
|
catch (JavaScriptException jse) {
|
||||||
|
jse.printStackTrace(System.err);
|
||||||
|
System.err.println("js: " + jse.getMessage());
|
||||||
|
ScriptCraftEvaluator.sc.notifyAdministrators("JavascriptException while loading " + filename + ": " + jse.getMessage());
|
||||||
|
}
|
||||||
|
catch (IOException ioe) {
|
||||||
|
ioe.printStackTrace(System.err);
|
||||||
|
System.err.println(ioe.toString());
|
||||||
|
ScriptCraftEvaluator.sc.notifyAdministrators( "IOException while loading " + filename + ": " + ioe.getMessage());
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
try {
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
catch (IOException ioe) {
|
||||||
|
System.err.println(ioe.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
public static void help(Context cx, Scriptable thisObj, Object[] args, Function funObj)
|
||||||
|
{
|
||||||
|
String cwd = java.lang.System.getProperty("user.dir");
|
||||||
|
String[] helpArgs = {"Current Working Directory: " + cwd,
|
||||||
|
"load('path-to-script.js')",
|
||||||
|
"load() (with no params) lets you choose a script file",
|
||||||
|
"getPlayerPos() returns player coords",
|
||||||
|
"getMousePos() returns mouse/crosshair coords",
|
||||||
|
"getBlock(x,y,z) returns the block and metadata e.g. '98' for a stone block or '98:2' for a mossy stone block",
|
||||||
|
"putBlock(x,y,z,blockId,meta) e.g. putBlock(100,2,50,44,2) puts a sandstone slab (44:2) at position 100,2,50. See http://www.minecraftinfo.com/idlist.htm for block ids"
|
||||||
|
};
|
||||||
|
print(cx,thisObj,helpArgs,funObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void print(Context cx, Scriptable thisObj,Object[] args, Function funObj)
|
||||||
|
{
|
||||||
|
for (int i=0; i < args.length; i++) {
|
||||||
|
if (i > 0){
|
||||||
|
System.out.print(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the arbitrary JavaScript value into a string form.
|
||||||
|
String s = Context.toString(args[i]);
|
||||||
|
ScriptCraftEvaluator.sc.notifyAdministrators(s);
|
||||||
|
System.out.print(s);
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
public static double[] getPlayerPos(Context cx, Scriptable thisObj,Object[] args, Function funObj)
|
||||||
|
{
|
||||||
|
return ScriptCraftEvaluator.sc.getPlayerPos();
|
||||||
|
}
|
||||||
|
public static double[] getMousePos(Context cx, Scriptable thisObj,Object[] args, Function funObj)
|
||||||
|
{
|
||||||
|
return ScriptCraftEvaluator.sc.getMousePos();
|
||||||
|
}
|
||||||
|
public static void putBlock(Context cx, Scriptable thisObj,Object[] args, Function funObj)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int z;
|
||||||
|
int b;
|
||||||
|
int m;
|
||||||
|
|
||||||
|
if (args.length == 2){
|
||||||
|
double[] mousePos = ScriptCraftEvaluator.sc.getMousePos();
|
||||||
|
if (mousePos != null){
|
||||||
|
x = (int)mousePos[0];
|
||||||
|
y = (int)mousePos[1];
|
||||||
|
z = (int)mousePos[2];
|
||||||
|
b = new Double(args[0].toString()).intValue();
|
||||||
|
m = new Double(args[1].toString()).intValue();
|
||||||
|
}else{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
x = new Double(args[0].toString()).intValue();
|
||||||
|
y = new Double(args[1].toString()).intValue();
|
||||||
|
z = new Double(args[2].toString()).intValue();
|
||||||
|
b = new Double(args[3].toString()).intValue();
|
||||||
|
m = new Double(args[4].toString()).intValue();
|
||||||
|
}
|
||||||
|
ScriptCraftEvaluator.sc.putBlock(x,y,z,b,m);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// gets the blockId and metadata at the given coords
|
||||||
|
// if no coords are provided then the mouse position is used instead.
|
||||||
|
//
|
||||||
|
public static String getBlock(Context cx, Scriptable thisObj,Object[] args, Function funObj){
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int z;
|
||||||
|
|
||||||
|
if (args.length != 0){
|
||||||
|
x = new Double(args[0].toString()).intValue();
|
||||||
|
y = new Double(args[1].toString()).intValue();
|
||||||
|
z = new Double(args[2].toString()).intValue();
|
||||||
|
}else{
|
||||||
|
double[] mousePos = ScriptCraftEvaluator.sc.getMousePos();
|
||||||
|
if (mousePos != null){
|
||||||
|
x = (int)mousePos[0];
|
||||||
|
y = (int)mousePos[1];
|
||||||
|
z = (int)mousePos[2];
|
||||||
|
}else{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ScriptCraftEvaluator.sc.getBlock(x,y,z);
|
||||||
|
}
|
||||||
|
public static void putSign(Context cx, Scriptable thisObj,Object[] args, Function funObj){
|
||||||
|
List jsArray = (List)args[0];
|
||||||
|
|
||||||
|
String[] texts = new String[4];
|
||||||
|
for (int i = 0; i < jsArray.size() && i <= 3;i++){
|
||||||
|
texts[i] = (String)jsArray.get(i);
|
||||||
|
}
|
||||||
|
int x = new Double(args[1].toString()).intValue();
|
||||||
|
int y = new Double(args[2].toString()).intValue();
|
||||||
|
int z = new Double(args[3].toString()).intValue();
|
||||||
|
int b = new Double(args[4].toString()).intValue();
|
||||||
|
int m = new Double(args[5].toString()).intValue();
|
||||||
|
ScriptCraftEvaluator.sc.putSign(texts,x,y,z,b,m);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
109
ScriptCraftMCP.java
Normal file
109
ScriptCraftMCP.java
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
package net.minecraft.src;
|
||||||
|
import net.minecraft.client.*;
|
||||||
|
/**
|
||||||
|
* An implementation of the IScriptCraft interface for
|
||||||
|
* Minecraft Coder Pack-style install
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ScriptCraftMCP implements IScriptCraft
|
||||||
|
{
|
||||||
|
protected CommandBase command = null;
|
||||||
|
|
||||||
|
public ScriptCraftMCP(CommandBase mcpCommand){
|
||||||
|
this.command = mcpCommand;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ICommandSender invoker;
|
||||||
|
//
|
||||||
|
// following code depends on MCP
|
||||||
|
//
|
||||||
|
public double[] getPlayerPos()
|
||||||
|
{
|
||||||
|
double[] result = new double[4];
|
||||||
|
if (this.invoker instanceof EntityPlayer){
|
||||||
|
EntityPlayer player = (EntityPlayer)this.invoker;
|
||||||
|
result[0] = player.posX;
|
||||||
|
result[1] = player.posY;
|
||||||
|
result[2] = player.posZ;
|
||||||
|
result[3] = player.rotationYaw;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public double[] getMousePos()
|
||||||
|
{
|
||||||
|
Minecraft mc = net.minecraft.client.Minecraft.getMinecraft();
|
||||||
|
MovingObjectPosition omo = mc.objectMouseOver;
|
||||||
|
if (omo == null){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
double[] result = new double[4];
|
||||||
|
result[0] = omo.blockX;
|
||||||
|
result[1] = omo.blockY;
|
||||||
|
result[2] = omo.blockZ;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
public void putSign(String[] texts, int x, int y, int z, int block, int meta)
|
||||||
|
{
|
||||||
|
this.putBlock(x,y,z,block,meta);
|
||||||
|
EntityPlayer player = (EntityPlayer)this.invoker;
|
||||||
|
World world = player.worldObj;
|
||||||
|
TileEntitySign sign = (TileEntitySign)world.getBlockTileEntity(x,y,z);
|
||||||
|
for (int i=0 ; i < texts.length && i <= 3;i++){
|
||||||
|
String text = texts[i];
|
||||||
|
if (text != null){
|
||||||
|
if (text.length() > 15){
|
||||||
|
text = text.substring(0,15);
|
||||||
|
}
|
||||||
|
sign.signText[i] = text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sign.onInventoryChanged();
|
||||||
|
world.markBlockForUpdate(x,y,z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void putBlock(int x, int y, int z, int blockId, int meta)
|
||||||
|
{
|
||||||
|
World world = null;
|
||||||
|
if (this.invoker instanceof EntityPlayer)
|
||||||
|
{
|
||||||
|
world = ((EntityPlayer)(this.invoker)).worldObj;
|
||||||
|
}
|
||||||
|
else if (this.invoker instanceof TileEntity)
|
||||||
|
{
|
||||||
|
world = ((TileEntity)(this.invoker)).getWorldObj();
|
||||||
|
}
|
||||||
|
world.setBlockAndMetadata(x,y,z,blockId,meta);
|
||||||
|
|
||||||
|
switch (blockId)
|
||||||
|
{
|
||||||
|
case 6:
|
||||||
|
((BlockSapling)Block.sapling).growTree(world,x,y,z,world.rand);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// returns the block id and metadata at a given location in the world
|
||||||
|
// e.g. returns "98" for a stone block or "98:2" for a mossy stone block.
|
||||||
|
//
|
||||||
|
public String getBlock(int x, int y, int z)
|
||||||
|
{
|
||||||
|
EntityPlayer player = (EntityPlayer)this.invoker;
|
||||||
|
World world = player.worldObj;
|
||||||
|
int blockId = world.getBlockId(x,y,z);
|
||||||
|
int metadata = world.getBlockMetadata(x,y,z);
|
||||||
|
if (metadata !=0){
|
||||||
|
return "" + blockId + ":" + metadata;
|
||||||
|
}else{
|
||||||
|
return "" + blockId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void notifyAdministrators(String message)
|
||||||
|
{
|
||||||
|
this.command.notifyAdmins(this.invoker,message,(Object[])null);
|
||||||
|
}
|
||||||
|
public void setInvoker(Object invoker)
|
||||||
|
{
|
||||||
|
this.invoker = (ICommandSender)invoker;
|
||||||
|
}
|
||||||
|
}
|
Reference in a new issue