Re-added scripting support.

This commit is contained in:
sk89q 2011-01-22 02:41:08 -08:00
parent ea6dca393b
commit e0121cf88a
3 changed files with 193 additions and 3 deletions

View File

@ -246,9 +246,10 @@ commands:
brush:
description: Switch to the sphere brush tool
usage: /<command> <id> [radius] [no-replace?]
reloadwe:
description: Switch to the replacing sphere brush tool
usage: /<command> <id> [radius]
cs:
description: Execute a CraftScript
usage: /<command> <filename> [arg1 [args2 [arg3 [...]]]]
reloadwe:
description: Reload WorldEdit's configuration

View File

@ -27,11 +27,15 @@ import java.util.HashSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.io.*;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import com.sk89q.util.StringUtil;
import com.sk89q.worldedit.bags.BlockBag;
import com.sk89q.worldedit.blocks.*;
import com.sk89q.worldedit.data.*;
import com.sk89q.worldedit.filters.*;
import com.sk89q.worldedit.scripting.ScriptContext;
import com.sk89q.worldedit.snapshots.*;
import com.sk89q.worldedit.superpickaxe.*;
import com.sk89q.worldedit.regions.*;
@ -173,6 +177,8 @@ public class WorldEditController {
commands.put("/repl", "[ID] - Switch to the block replacer tool");
commands.put("/brush", "[ID] <Radius> <NoReplace?> - Switch to the sphere brush tool");
commands.put("/rbrush", "[ID] <Radius> - Switch to the replacing sphere brush tool");
commands.put("/cs", "[Filename] <args...> - Execute a CraftScript");
}
/**
@ -1700,6 +1706,17 @@ public class WorldEditController {
}
}
return true;
// CraftScript
} else if (split[0].equalsIgnoreCase("/cs")) {
checkArgs(split, 1, -1, split[0]);
String[] args = new String[split.length - 1];
System.arraycopy(split, 1, args, 0, split.length - 1);
runScript(player, split[1], args);
return true;
}
@ -2091,4 +2108,86 @@ public class WorldEditController {
return true;
}
/**
* Executes a WorldEdit script.
*
* @param player
* @param filename
* @param args
*/
public void runScript(LocalPlayer player, String filename, String[] args) {
File dir = new File("craftscripts");
File f = new File(dir, filename);
if (!filename.matches("^[A-Za-z0-9_\\- \\./\\\\'\\$@~!%\\^\\*\\(\\)\\[\\]\\+\\{\\},\\?]+\\.[A-Za-z0-9]+$")) {
player.printError("Invalid filename. Don't forget the extension.");
return;
}
int index = filename.lastIndexOf(".");
String ext = filename.substring(index + 1, filename.length());
if (!ext.equalsIgnoreCase("js")) {
player.printError("Only .js scripts are currently supported");
return;
}
try {
String filePath = f.getCanonicalPath();
String dirPath = dir.getCanonicalPath();
if (!filePath.substring(0, dirPath.length()).equals(dirPath)) {
player.printError("Script could not read or it does not exist.");
return;
}
} catch (IOException e) {
player.printError("Script could not read or it does not exist: " + e.getMessage());
return;
}
String script;
try {
FileInputStream file = new FileInputStream(f);
DataInputStream in = new DataInputStream (file);
byte[] data = new byte[in.available()];
in.readFully(data);
in.close ();
script = new String(data, 0, data.length, "utf-8");
} catch (FileNotFoundException e) {
player.printError("Script does not exist: " + filename);
return;
} catch (IOException e) {
player.printError("Script read error: " + e.getMessage());
return;
}
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByExtension(ext);
if (engine == null) {
player.printError("Failed to load the scripting engine.");
return;
}
LocalSession session = getSession(player);
ScriptContext context = new ScriptContext(this, server, config, session, player);
engine.put("argv", args);
engine.put("ctx", context);
engine.put("player", player);
try {
engine.eval(script);
} catch (ScriptException e) {
e.printStackTrace();
player.printError("Script encountered an error: " + e.getMessage());
return;
} finally {
for (EditSession editSession : context._getEditSessions()) {
session.remember(editSession);
}
}
}
}

View File

@ -0,0 +1,90 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.scripting;
import java.util.ArrayList;
import java.util.List;
import com.sk89q.worldedit.DisallowedItemException;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalPlayer;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.ServerInterface;
import com.sk89q.worldedit.UnknownItemException;
import com.sk89q.worldedit.WorldEditController;
import com.sk89q.worldedit.blocks.BaseBlock;
public class ScriptContext {
private WorldEditController controller;
private LocalPlayer player;
private LocalConfiguration config;
private LocalSession session;
private ServerInterface server;
private List<EditSession> editSessions = new ArrayList<EditSession>();
public ScriptContext(WorldEditController controller, ServerInterface server,
LocalConfiguration config, LocalSession session, LocalPlayer player) {
this.controller = controller;
this.player = player;
this.config = config;
this.server = server;
this.session = session;
}
public EditSession startEditSession() {
EditSession editSession =
new EditSession(server, player.getWorld(),
session.getBlockChangeLimit(), session.getBlockBag(player));
editSessions.add(editSession);
return editSession;
}
public LocalPlayer getPlayer() {
return player;
}
public LocalSession getSession() {
return session;
}
public LocalConfiguration getConfiguration() {
return config;
}
public List<EditSession> _getEditSessions() {
return editSessions;
}
public void print(String msg) {
player.print(msg);
}
public void error(String msg) {
player.printError(msg);
}
public BaseBlock getBlock(String arg) throws UnknownItemException, DisallowedItemException {
return controller.getBlock(player, arg, false);
}
public BaseBlock getAnyBlock(String arg) throws UnknownItemException, DisallowedItemException {
return controller.getBlock(player, arg, true);
}
}