2014-04-03 02:08:50 +00:00
|
|
|
/*
|
2014-04-04 22:03:18 +00:00
|
|
|
* WorldEdit, a Minecraft world manipulation toolkit
|
|
|
|
* Copyright (C) sk89q <http://www.sk89q.com>
|
|
|
|
* Copyright (C) WorldEdit team and contributors
|
2014-04-03 02:08:50 +00:00
|
|
|
*
|
2014-04-04 22:03:18 +00:00
|
|
|
* This program is free software: you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU Lesser General Public License as published by the
|
|
|
|
* Free Software Foundation, either version 3 of the License, or
|
2014-04-03 02:08:50 +00:00
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
2014-04-04 22:03:18 +00:00
|
|
|
* 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 Lesser General Public License
|
|
|
|
* for more details.
|
2014-04-03 02:08:50 +00:00
|
|
|
*
|
2014-04-04 22:03:18 +00:00
|
|
|
* You should have received a copy of the GNU Lesser General Public License
|
2014-04-03 02:08:50 +00:00
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2014-04-04 22:03:18 +00:00
|
|
|
*/
|
2014-04-03 02:08:50 +00:00
|
|
|
|
|
|
|
package com.sk89q.worldedit.command;
|
|
|
|
|
2019-07-06 00:46:48 +00:00
|
|
|
import static com.google.common.base.Preconditions.checkNotNull;
|
|
|
|
import static com.sk89q.worldedit.command.util.Logging.LogMode.ALL;
|
|
|
|
|
2019-04-06 23:13:23 +00:00
|
|
|
import com.boydti.fawe.config.BBC;
|
2018-08-12 14:03:07 +00:00
|
|
|
import com.boydti.fawe.wrappers.LocationMaskedPlayerWrapper;
|
2019-07-18 20:03:27 +00:00
|
|
|
import org.enginehub.piston.inject.InjectedValueAccess;
|
2014-06-28 08:01:49 +00:00
|
|
|
import com.sk89q.worldedit.LocalSession;
|
|
|
|
import com.sk89q.worldedit.WorldEdit;
|
|
|
|
import com.sk89q.worldedit.WorldEditException;
|
2019-07-06 00:46:48 +00:00
|
|
|
import com.sk89q.worldedit.command.util.CommandPermissions;
|
|
|
|
import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
|
|
|
|
import com.sk89q.worldedit.command.util.Logging;
|
2014-06-28 08:01:49 +00:00
|
|
|
import com.sk89q.worldedit.entity.Player;
|
2019-06-12 13:45:41 +00:00
|
|
|
import com.sk89q.worldedit.extension.platform.Actor;
|
2019-04-14 12:46:01 +00:00
|
|
|
import com.sk89q.worldedit.extension.platform.Capability;
|
2019-07-06 00:46:48 +00:00
|
|
|
import com.sk89q.worldedit.extension.platform.PlatformCommandManager;
|
2019-04-14 12:46:01 +00:00
|
|
|
import com.sk89q.worldedit.scripting.CraftScriptContext;
|
2018-08-12 14:03:07 +00:00
|
|
|
import com.sk89q.worldedit.scripting.CraftScriptEngine;
|
|
|
|
import com.sk89q.worldedit.scripting.RhinoCraftScriptEngine;
|
2019-07-06 00:46:48 +00:00
|
|
|
import java.io.DataInputStream;
|
|
|
|
import java.io.File;
|
|
|
|
import java.io.FileInputStream;
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.InputStream;
|
|
|
|
import java.nio.charset.StandardCharsets;
|
2018-08-12 14:03:07 +00:00
|
|
|
import java.util.HashMap;
|
2019-07-06 00:46:48 +00:00
|
|
|
import java.util.List;
|
2018-08-12 14:03:07 +00:00
|
|
|
import java.util.Map;
|
2019-06-12 13:45:41 +00:00
|
|
|
import java.util.function.Function;
|
2019-07-06 00:46:48 +00:00
|
|
|
import java.util.stream.Stream;
|
|
|
|
import javax.annotation.Nullable;
|
|
|
|
import javax.script.ScriptException;
|
|
|
|
import org.enginehub.piston.annotation.Command;
|
|
|
|
import org.enginehub.piston.annotation.CommandContainer;
|
|
|
|
import org.enginehub.piston.annotation.param.Arg;
|
|
|
|
import org.mozilla.javascript.NativeJavaObject;
|
2014-06-28 08:01:49 +00:00
|
|
|
|
|
|
|
|
2014-04-03 02:08:50 +00:00
|
|
|
/**
|
2014-06-28 08:01:49 +00:00
|
|
|
* Commands related to scripting.
|
2014-04-03 02:08:50 +00:00
|
|
|
*/
|
2019-07-06 00:46:48 +00:00
|
|
|
@CommandContainer(superTypes = CommandPermissionsConditionGenerator.Registration.class)
|
2014-04-03 02:08:50 +00:00
|
|
|
public class ScriptingCommands {
|
|
|
|
|
2014-06-28 08:01:49 +00:00
|
|
|
private final WorldEdit worldEdit;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a new instance.
|
|
|
|
*
|
|
|
|
* @param worldEdit reference to WorldEdit
|
|
|
|
*/
|
2019-07-06 00:46:48 +00:00
|
|
|
public ScriptingCommands(WorldEdit worldEdit) {
|
2014-06-28 08:01:49 +00:00
|
|
|
checkNotNull(worldEdit);
|
|
|
|
this.worldEdit = worldEdit;
|
2014-04-03 02:08:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Command(
|
2019-07-06 00:46:48 +00:00
|
|
|
name = "setupdispatcher",
|
|
|
|
desc = ""
|
2014-04-03 02:08:50 +00:00
|
|
|
)
|
2019-06-12 22:48:40 +00:00
|
|
|
@CommandPermissions("fawe.setupdispatcher")
|
2019-07-18 20:03:27 +00:00
|
|
|
public void setupdispatcher(Player player, LocalSession session, final InjectedValueAccess args) throws WorldEditException {
|
2019-07-06 00:46:48 +00:00
|
|
|
PlatformCommandManager.getInstance().setupDispatcher();
|
2018-08-12 14:03:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public static <T> T runScript(Player player, File f, String[] args) throws WorldEditException {
|
2019-06-12 13:45:41 +00:00
|
|
|
return runScript(player, f, args, null);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static <T> T runScript(Actor actor, File f, String[] args, @Nullable Function<String, String> processor) throws WorldEditException {
|
2018-08-12 14:03:07 +00:00
|
|
|
String filename = f.getPath();
|
|
|
|
int index = filename.lastIndexOf(".");
|
2019-06-12 13:45:41 +00:00
|
|
|
String ext = filename.substring(index + 1, filename.length());
|
2018-08-12 14:03:07 +00:00
|
|
|
|
|
|
|
if (!ext.equalsIgnoreCase("js")) {
|
2019-06-12 21:12:12 +00:00
|
|
|
actor.printError("Only .js scripts are currently supported");
|
2018-08-12 14:03:07 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
String script;
|
|
|
|
|
|
|
|
try {
|
|
|
|
InputStream file;
|
|
|
|
|
|
|
|
if (!f.exists()) {
|
|
|
|
file = WorldEdit.class.getResourceAsStream("craftscripts/" + filename);
|
|
|
|
|
|
|
|
if (file == null) {
|
2019-06-12 21:12:12 +00:00
|
|
|
actor.printError("Script does not exist: " + filename);
|
2018-08-12 14:03:07 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
file = new FileInputStream(f);
|
|
|
|
}
|
|
|
|
|
2019-06-12 13:45:41 +00:00
|
|
|
DataInputStream in = new DataInputStream(file);
|
|
|
|
byte[] data = new byte[in.available()];
|
|
|
|
in.readFully(data);
|
|
|
|
in.close();
|
2019-07-06 00:46:48 +00:00
|
|
|
script = new String(data, 0, data.length, StandardCharsets.UTF_8);
|
2018-08-12 14:03:07 +00:00
|
|
|
} catch (IOException e) {
|
2019-06-12 21:12:12 +00:00
|
|
|
actor.printError("Script read error: " + e.getMessage());
|
2018-08-12 14:03:07 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2019-06-12 13:45:41 +00:00
|
|
|
if (processor != null) {
|
|
|
|
script = processor.apply(script);
|
|
|
|
}
|
|
|
|
|
|
|
|
WorldEdit worldEdit = WorldEdit.getInstance();
|
|
|
|
LocalSession session = worldEdit.getSessionManager().get(actor);
|
2018-08-12 14:03:07 +00:00
|
|
|
|
2019-06-12 13:45:41 +00:00
|
|
|
CraftScriptEngine engine = null;
|
2018-08-12 14:03:07 +00:00
|
|
|
|
|
|
|
Object result = null;
|
|
|
|
try {
|
|
|
|
|
|
|
|
engine = new RhinoCraftScriptEngine();
|
|
|
|
} catch (NoClassDefFoundError e) {
|
2019-06-12 13:45:41 +00:00
|
|
|
actor.printError("Failed to find an installed script engine.");
|
|
|
|
actor.printError("Download: https://github.com/downloads/mozilla/rhino/rhino1_7R4.zip");
|
|
|
|
actor.printError("Extract: `js.jar` to `plugins` or `mods` directory`");
|
|
|
|
actor.printError("More info: https://github.com/boy0001/CraftScripts/");
|
2018-08-12 14:03:07 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2019-06-12 13:45:41 +00:00
|
|
|
engine.setTimeLimit(worldEdit.getConfiguration().scriptTimeout);
|
2018-08-12 14:03:07 +00:00
|
|
|
|
2019-06-12 13:45:41 +00:00
|
|
|
Player player = actor instanceof Player ? (Player) actor : null;
|
|
|
|
CraftScriptContext scriptContext = new CraftScriptContext(worldEdit, WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.USER_COMMANDS),
|
|
|
|
WorldEdit.getInstance().getConfiguration(), session, player, args);
|
2019-04-14 12:46:01 +00:00
|
|
|
|
2019-02-16 02:46:10 +00:00
|
|
|
Map<String, Object> vars = new HashMap<>();
|
2018-08-12 14:03:07 +00:00
|
|
|
vars.put("argv", args);
|
2019-04-14 12:46:01 +00:00
|
|
|
vars.put("context", scriptContext);
|
2019-06-12 13:45:41 +00:00
|
|
|
vars.put("actor", actor);
|
2019-04-14 12:46:01 +00:00
|
|
|
vars.put("player", player);
|
2018-08-12 14:03:07 +00:00
|
|
|
|
|
|
|
try {
|
|
|
|
result = engine.evaluate(script, filename, vars);
|
|
|
|
} catch (ScriptException e) {
|
|
|
|
e.printStackTrace();
|
2019-06-12 21:12:12 +00:00
|
|
|
actor.printError("Failed to execute:");
|
2019-06-12 13:45:41 +00:00
|
|
|
actor.printRaw(e.getMessage());
|
2019-07-06 00:46:48 +00:00
|
|
|
} catch (NumberFormatException | WorldEditException e) {
|
2018-08-12 14:03:07 +00:00
|
|
|
throw e;
|
|
|
|
} catch (Throwable e) {
|
2019-06-12 21:12:12 +00:00
|
|
|
actor.printError("Failed to execute (see console):");
|
2019-06-12 13:45:41 +00:00
|
|
|
actor.printRaw(e.getClass().getCanonicalName());
|
2019-04-14 12:46:01 +00:00
|
|
|
e.printStackTrace();
|
2018-08-12 14:03:07 +00:00
|
|
|
}
|
|
|
|
if (result instanceof NativeJavaObject) {
|
|
|
|
return (T) ((NativeJavaObject) result).unwrap();
|
|
|
|
}
|
|
|
|
return (T) result;
|
|
|
|
}
|
|
|
|
|
2019-07-06 00:46:48 +00:00
|
|
|
@Command(
|
|
|
|
name = "cs",
|
|
|
|
desc = "Execute a CraftScript"
|
|
|
|
)
|
2014-04-03 02:08:50 +00:00
|
|
|
@CommandPermissions("worldedit.scripting.execute")
|
|
|
|
@Logging(ALL)
|
2019-07-18 20:03:27 +00:00
|
|
|
public void execute(Player player, LocalSession session, InjectedValueAccess args) throws WorldEditException {
|
2019-06-12 13:45:41 +00:00
|
|
|
final String[] scriptArgs = args.getSlice(1);
|
2019-07-06 00:46:48 +00:00
|
|
|
final String filename = args.getString(0);
|
2014-04-03 02:08:50 +00:00
|
|
|
|
2019-07-06 00:46:48 +00:00
|
|
|
if (!player.hasPermission("worldedit.scripting.execute." + filename)) {
|
2019-04-06 23:13:23 +00:00
|
|
|
BBC.SCRIPTING_NO_PERM.send(player);
|
2014-04-03 02:08:50 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-07-06 00:46:48 +00:00
|
|
|
session.setLastScript(filename);
|
2014-04-03 02:08:50 +00:00
|
|
|
|
2019-07-06 00:46:48 +00:00
|
|
|
File dir = worldEdit.getWorkingDirectoryFile(worldEdit.getConfiguration().scriptsDir);
|
|
|
|
File f = worldEdit.getSafeOpenFile(player, dir, filename, "js", "js");
|
2018-08-12 14:03:07 +00:00
|
|
|
try {
|
|
|
|
new RhinoCraftScriptEngine();
|
|
|
|
} catch (NoClassDefFoundError e) {
|
|
|
|
player.printError("Failed to find an installed script engine.");
|
|
|
|
player.printError("Download: https://github.com/downloads/mozilla/rhino/rhino1_7R4.zip");
|
|
|
|
player.printError("Extract: `js.jar` to `plugins` or `mods` directory`");
|
|
|
|
player.printError("More info: https://github.com/boy0001/CraftScripts/");
|
|
|
|
return;
|
|
|
|
}
|
2019-04-01 12:50:16 +00:00
|
|
|
runScript(LocationMaskedPlayerWrapper.unwrap(player), f, scriptArgs);
|
2014-04-03 02:08:50 +00:00
|
|
|
}
|
|
|
|
|
2019-07-06 00:46:48 +00:00
|
|
|
@Command(
|
|
|
|
name = ".s",
|
|
|
|
desc = "Execute last CraftScript"
|
|
|
|
)
|
2014-04-03 02:08:50 +00:00
|
|
|
@CommandPermissions("worldedit.scripting.execute")
|
|
|
|
@Logging(ALL)
|
2019-07-06 00:46:48 +00:00
|
|
|
public void executeLast(Player player, LocalSession session,
|
|
|
|
@Arg(desc = "Arguments to the CraftScript", def = "", variable = true)
|
|
|
|
List<String> args) throws WorldEditException {
|
2019-06-12 21:12:12 +00:00
|
|
|
|
2014-04-03 02:08:50 +00:00
|
|
|
String lastScript = session.getLastScript();
|
|
|
|
|
|
|
|
if (!player.hasPermission("worldedit.scripting.execute." + lastScript)) {
|
2019-04-06 23:13:23 +00:00
|
|
|
BBC.SCRIPTING_NO_PERM.send(player);
|
2014-04-03 02:08:50 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lastScript == null) {
|
2019-04-06 23:13:23 +00:00
|
|
|
BBC.SCRIPTING_CS.send(player);
|
2014-04-03 02:08:50 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-07-06 00:46:48 +00:00
|
|
|
File dir = worldEdit.getWorkingDirectoryFile(worldEdit.getConfiguration().scriptsDir);
|
|
|
|
File f = worldEdit.getSafeOpenFile(player, dir, lastScript, "js", "js");
|
2018-08-12 14:03:07 +00:00
|
|
|
|
2019-07-06 00:46:48 +00:00
|
|
|
worldEdit.runScript(player, f, Stream.concat(Stream.of(lastScript), args.stream())
|
|
|
|
.toArray(String[]::new));
|
2018-08-12 14:03:07 +00:00
|
|
|
}
|
2014-04-03 02:08:50 +00:00
|
|
|
}
|