package net.walterhiggins.scriptcraft; import java.io.File; import java.io.FileReader; import java.io.FileOutputStream; import java.io.IOException; import javax.script.*; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.Collection; import java.util.Arrays; import java.util.List; import java.util.ArrayList; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.command.*; import org.bukkit.Bukkit; import org.bukkit.event.Listener; public class ScriptCraftPlugin extends JavaPlugin implements Listener { // right now all ops share the same JS context/scope // need to look at possibly having context/scope per operator //protected Map playerContexts = new HashMap(); protected ScriptEngine engine = null; private static final String JS_PLUGINS_DIR = "js-plugins"; /** * Unzips bundled javascript code. */ private void unzipJS() { // // does the js-plugins directory exist? // File jsPlugins = new File(JS_PLUGINS_DIR); if (!jsPlugins.exists()) { getLogger().finest("Directory " + JS_PLUGINS_DIR + " does not exist."); getLogger().finest("Initializing " + JS_PLUGINS_DIR + " directory with contents from plugin archive."); jsPlugins.mkdir(); } ZipInputStream zis = new ZipInputStream(getResource(JS_PLUGINS_DIR + ".zip")); ZipEntry entry; try { while ( ( entry = zis.getNextEntry() ) != null) { String filename = entry.getName(); File newFile = new File(jsPlugins.getName() + File.separator + filename); //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 // long zTime = entry.getTime(); boolean unzip = false; if (!newFile.exists()) unzip = true; else{ long fTime = newFile.lastModified(); if (zTime > fTime) unzip = true; } if (unzip){ getLogger().info("Unzipping " + filename); FileOutputStream fout = new FileOutputStream(newFile); for (int c = zis.read(); c != -1; c = zis.read()) { fout.write(c); } fout.close(); } } zis.closeEntry(); } zis.close(); }catch (IOException ioe){ getLogger().warning(ioe.getMessage()); ioe.printStackTrace(); } } @Override public void onEnable() { unzipJS(); FileReader reader = null; try{ ScriptEngineManager factory = new ScriptEngineManager(); File boot = new File(JS_PLUGINS_DIR + "/core/_scriptcraft.js"); this.engine = factory.getEngineByName("JavaScript"); this.engine.put("__engine",engine); this.engine.put("__plugin",this); this.engine.put("__script",boot.getCanonicalPath().replaceAll("\\\\","/")); reader = new FileReader(boot); this.engine.eval(reader); // Load the CoffeeScript compiler File coffeescript = new File(JS_PLUGINS_DIR + "/core/_coffeescript.js"); this.engine.eval(new FileReader(coffeescript)); }catch(Exception e){ e.printStackTrace(); }finally { if (reader != null){ try { reader.close(); }catch(IOException ioe){ // fail silently } } } } public List onTabComplete(CommandSender sender, Command cmd, String alias, String[] args) { // // delegate to javascript // List result = new ArrayList(); try { this.engine.put("__onTC_result",result); this.engine.put("__onTC_sender",sender); this.engine.put("__onTC_cmd",cmd); this.engine.put("__onTC_alias",alias); this.engine.put("__onTC_args",args); this.engine.eval("_onTabComplete()"); }catch (Exception e){ sender.sendMessage(e.getMessage()); e.printStackTrace(); } return result; } public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { boolean result = false; String javascriptCode = ""; if(cmd.getName().equalsIgnoreCase("js")){ for (int i = 0;i < args.length; i++){ javascriptCode = javascriptCode + args[i] + " "; } result = true; } else if (cmd.getName().equalsIgnoreCase("jsp")){ javascriptCode = "command()"; this.engine.put("__cmdArgs",args); result = true; } else if (cmd.getName().equalsIgnoreCase("coffee")) { for (int i = 0;i < args.length; i++) javascriptCode += args[i] + " "; javascriptCode = "eval(CoffeeScript.compile(\""+javascriptCode+"\", {bare: true}))"; result = true; } if (result){ this.engine.put("self",sender); try{ Object resultObj = this.engine.eval(javascriptCode); if (resultObj != null){ if (resultObj instanceof java.util.Collection){ java.util.Collection collection = (java.util.Collection)resultObj; sender.sendMessage(Arrays.toString(collection.toArray())); }else{ sender.sendMessage(resultObj.toString()); } } }catch (Exception e){ sender.sendMessage(e.getMessage()); e.printStackTrace(); } } return result; } }