2013-01-08 00:48:43 +01:00
|
|
|
package net.walterhiggins.scriptcraft;
|
|
|
|
|
|
|
|
import java.io.File;
|
|
|
|
import java.io.FileReader;
|
2013-01-08 03:33:18 +01:00
|
|
|
import java.io.FileOutputStream;
|
|
|
|
import java.io.IOException;
|
2013-01-08 00:48:43 +01:00
|
|
|
import javax.script.*;
|
2013-01-08 03:33:18 +01:00
|
|
|
import java.util.zip.ZipEntry;
|
|
|
|
import java.util.zip.ZipInputStream;
|
2013-01-09 22:58:11 +01:00
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.Arrays;
|
2013-01-13 22:06:46 +01:00
|
|
|
import java.util.List;
|
|
|
|
import java.util.ArrayList;
|
2013-01-08 00:48:43 +01:00
|
|
|
|
|
|
|
import org.bukkit.plugin.java.JavaPlugin;
|
|
|
|
import org.bukkit.command.*;
|
2013-01-25 00:46:28 +01:00
|
|
|
import org.bukkit.Bukkit;
|
2013-02-22 16:49:42 +01:00
|
|
|
import org.bukkit.event.Listener;
|
2013-01-08 00:48:43 +01:00
|
|
|
|
2013-02-22 16:49:42 +01:00
|
|
|
public class ScriptCraftPlugin extends JavaPlugin implements Listener
|
2013-01-08 00:48:43 +01:00
|
|
|
{
|
|
|
|
// right now all ops share the same JS context/scope
|
|
|
|
// need to look at possibly having context/scope per operator
|
|
|
|
//protected Map<CommandSender,ScriptCraftEvaluator> playerContexts = new HashMap<CommandSender,ScriptCraftEvaluator>();
|
|
|
|
protected ScriptEngine engine = null;
|
2014-01-01 22:02:11 +01:00
|
|
|
private static final String JS_PLUGINS_DIR = "plugins/scriptcraft";
|
|
|
|
private static final String JS_PLUGINS_ZIP = "scriptcraft.zip";
|
|
|
|
|
2013-01-13 22:06:46 +01:00
|
|
|
/**
|
|
|
|
* Unzips bundled javascript code.
|
|
|
|
*/
|
2014-01-12 12:26:26 +01:00
|
|
|
private void unzipJS() throws IOException
|
2013-01-08 03:33:18 +01:00
|
|
|
{
|
|
|
|
//
|
|
|
|
// does the js-plugins directory exist?
|
|
|
|
//
|
|
|
|
File jsPlugins = new File(JS_PLUGINS_DIR);
|
|
|
|
if (!jsPlugins.exists())
|
|
|
|
{
|
2014-01-12 12:26:26 +01:00
|
|
|
getLogger().info("Directory " + jsPlugins.getCanonicalPath() + " does not exist.");
|
|
|
|
getLogger().info("Initializing " + jsPlugins.getCanonicalPath() + " directory with contents from plugin archive.");
|
|
|
|
try{
|
|
|
|
jsPlugins.mkdirs();
|
|
|
|
}catch(Exception e){
|
|
|
|
throw new RuntimeException("Failed to create directory " + jsPlugins.getCanonicalPath() + ":" + e.getMessage());
|
|
|
|
}
|
2013-01-19 18:00:22 +01:00
|
|
|
}
|
|
|
|
|
2014-01-01 22:02:11 +01:00
|
|
|
ZipInputStream zis = new ZipInputStream(getResource(JS_PLUGINS_ZIP));
|
2013-01-19 18:00:22 +01:00
|
|
|
ZipEntry entry;
|
|
|
|
try {
|
|
|
|
while ( ( entry = zis.getNextEntry() ) != null)
|
|
|
|
{
|
|
|
|
String filename = entry.getName();
|
2014-01-12 12:26:26 +01:00
|
|
|
|
2014-01-01 22:02:11 +01:00
|
|
|
File newFile = new File(jsPlugins, filename);
|
2013-01-19 18:00:22 +01:00
|
|
|
|
|
|
|
//create all non exists folders
|
|
|
|
//else you will hit FileNotFoundException for compressed folder
|
|
|
|
if (entry.isDirectory()){
|
|
|
|
newFile.mkdirs();
|
|
|
|
}else{
|
|
|
|
//
|
|
|
|
// only write out to file if zip entry is newer than file
|
|
|
|
//
|
2014-01-12 12:26:26 +01:00
|
|
|
String reason = null;
|
2013-01-19 18:00:22 +01:00
|
|
|
long zTime = entry.getTime();
|
|
|
|
boolean unzip = false;
|
2014-01-12 12:26:26 +01:00
|
|
|
if (!newFile.exists()){
|
|
|
|
reason = "NE";
|
2013-01-19 18:00:22 +01:00
|
|
|
unzip = true;
|
2014-01-12 12:26:26 +01:00
|
|
|
}
|
2013-01-19 18:00:22 +01:00
|
|
|
else{
|
|
|
|
long fTime = newFile.lastModified();
|
2014-01-12 12:26:26 +01:00
|
|
|
if (zTime > fTime){
|
|
|
|
reason = "" + new Long((zTime-fTime)/3600000) + "h";
|
2013-01-19 18:00:22 +01:00
|
|
|
unzip = true;
|
2014-01-12 12:26:26 +01:00
|
|
|
}
|
|
|
|
|
2013-01-19 18:00:22 +01:00
|
|
|
}
|
|
|
|
if (unzip){
|
2014-01-12 12:26:26 +01:00
|
|
|
getLogger().info("Unzipping " + newFile.getCanonicalPath() + " (" + reason + ")" );
|
2013-01-08 03:33:18 +01:00
|
|
|
FileOutputStream fout = new FileOutputStream(newFile);
|
|
|
|
for (int c = zis.read(); c != -1; c = zis.read()) {
|
|
|
|
fout.write(c);
|
|
|
|
}
|
|
|
|
fout.close();
|
|
|
|
}
|
2013-01-19 18:00:22 +01:00
|
|
|
|
2013-01-08 03:33:18 +01:00
|
|
|
}
|
2013-01-19 18:00:22 +01:00
|
|
|
zis.closeEntry();
|
2013-01-08 03:33:18 +01:00
|
|
|
}
|
2013-01-19 18:00:22 +01:00
|
|
|
zis.close();
|
|
|
|
}catch (IOException ioe){
|
|
|
|
getLogger().warning(ioe.getMessage());
|
|
|
|
ioe.printStackTrace();
|
2013-01-08 03:33:18 +01:00
|
|
|
}
|
2013-01-13 22:06:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onEnable()
|
|
|
|
{
|
2013-03-09 17:50:12 +01:00
|
|
|
FileReader reader = null;
|
|
|
|
try{
|
2014-01-12 12:26:26 +01:00
|
|
|
unzipJS();
|
2013-03-09 17:50:12 +01:00
|
|
|
ScriptEngineManager factory = new ScriptEngineManager();
|
2013-12-30 22:33:12 +01:00
|
|
|
File bootScript = new File(JS_PLUGINS_DIR + "/lib/scriptcraft.js");
|
2013-03-09 17:50:12 +01:00
|
|
|
this.engine = factory.getEngineByName("JavaScript");
|
2013-12-30 22:33:12 +01:00
|
|
|
reader = new FileReader(bootScript);
|
2013-08-11 20:22:36 +02:00
|
|
|
this.engine.eval(reader);
|
2013-12-30 22:33:12 +01:00
|
|
|
Invocable inv = (Invocable)this.engine;
|
|
|
|
inv.invokeFunction("__onEnable", engine, this, bootScript);
|
2013-08-11 20:22:36 +02:00
|
|
|
|
2013-03-09 17:50:12 +01:00
|
|
|
}catch(Exception e){
|
|
|
|
e.printStackTrace();
|
2014-01-12 12:26:26 +01:00
|
|
|
this.getLogger().severe(e.getMessage());
|
2013-03-09 17:50:12 +01:00
|
|
|
}finally {
|
|
|
|
if (reader != null){
|
|
|
|
try {
|
|
|
|
reader.close();
|
|
|
|
}catch(IOException ioe){
|
|
|
|
// fail silently
|
2013-02-18 20:33:21 +01:00
|
|
|
}
|
2013-01-08 00:48:43 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-01-13 22:06:46 +01:00
|
|
|
public List<String> onTabComplete(CommandSender sender, Command cmd,
|
|
|
|
String alias,
|
|
|
|
String[] args)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// delegate to javascript
|
|
|
|
//
|
|
|
|
List<String> result = new ArrayList<String>();
|
|
|
|
try {
|
2013-12-30 22:33:12 +01:00
|
|
|
Invocable inv = (Invocable)this.engine;
|
|
|
|
inv.invokeFunction("__onTabComplete", result, sender, cmd, alias, args);
|
2013-01-13 22:06:46 +01:00
|
|
|
}catch (Exception e){
|
|
|
|
sender.sendMessage(e.getMessage());
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2013-01-08 00:48:43 +01:00
|
|
|
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args)
|
|
|
|
{
|
2013-01-16 00:09:43 +01:00
|
|
|
boolean result = false;
|
|
|
|
String javascriptCode = "";
|
2013-12-30 22:33:12 +01:00
|
|
|
Object jsResult = null;
|
|
|
|
try {
|
|
|
|
jsResult = ((Invocable)this.engine).invokeFunction("__onCommand", sender, cmd, label, args);
|
|
|
|
}catch (Exception se){
|
|
|
|
this.getLogger().severe(se.toString());
|
|
|
|
se.printStackTrace();
|
|
|
|
sender.sendMessage(se.getMessage());
|
2013-01-16 00:09:43 +01:00
|
|
|
}
|
2013-12-30 22:33:12 +01:00
|
|
|
if (jsResult != null){
|
|
|
|
return ((Boolean)jsResult).booleanValue();
|
2013-01-16 00:09:43 +01:00
|
|
|
}
|
2013-12-30 22:33:12 +01:00
|
|
|
return result;
|
2013-01-08 00:48:43 +01:00
|
|
|
}
|
|
|
|
}
|