From f88d1f0428ece3990f2a4e9aa37c4724cad33887 Mon Sep 17 00:00:00 2001 From: walterhiggins Date: Mon, 30 Dec 2013 21:33:12 +0000 Subject: [PATCH] 'Buddha' Release : The annihilation of 'self' variable. use of 'self' should be limited only to in-game or console commands. It should not be used in the context of a module. --- docs/API-Reference.md | 53 +++++++----- ...YoungPersonsGuideToProgrammingMinecraft.md | 48 +++++------ .../scriptcraft/ScriptCraftPlugin.java | 67 ++++----------- src/main/javascript/lib/command.js | 16 +--- src/main/javascript/lib/scriptcraft.js | 83 +++++++++++++------ src/main/javascript/lib/tabcomplete-jsp.js | 6 +- src/main/javascript/lib/tabcomplete.js | 9 +- src/main/javascript/plugins/alias/alias.js | 8 +- src/main/javascript/plugins/arrows.js | 25 +++--- src/main/javascript/plugins/chat/color.js | 10 +-- .../javascript/plugins/classroom/classroom.js | 23 +++-- .../plugins/commando/commando-test.js | 11 ++- .../javascript/plugins/commando/commando.js | 20 +++-- .../javascript/plugins/drone/contrib/fort.js | 2 +- src/main/javascript/plugins/drone/drone.js | 4 +- src/main/javascript/plugins/homes/homes.js | 68 +++++++-------- .../plugins/minigames/NumberGuess.js | 6 +- 17 files changed, 239 insertions(+), 220 deletions(-) diff --git a/docs/API-Reference.md b/docs/API-Reference.md index 47068b8..352f8f5 100644 --- a/docs/API-Reference.md +++ b/docs/API-Reference.md @@ -18,7 +18,7 @@ loads the module circle.js in the same directory. The contents of foo.js: var circle = require('./circle.js'); - echo( 'The area of a circle of radius 4 is ' + console.log( 'The area of a circle of radius 4 is ' + circle.area(4)); The contents of circle.js: @@ -71,14 +71,14 @@ module in the `plugins` directory exports becomes a global variable. For example, if you have a module greeting.js in the plugins directory.... - exports.greet = function() { - echo('Hello ' + self.name); + exports.greet = function(player) { + player.sendMessage('Hello ' + player.name); }; ... then `greet` becomes a global function and can be used at the in-game (or server) command prompt like so... - /js greet() + /js greet(self) ... This differs from how modules (in NodeJS and commonJS environments) normally work. If you want your module to be exported @@ -138,7 +138,16 @@ The ScriptCraft JavaPlugin object. The Minecraft Server object ### self variable -The current player. (Note - this value should not be used in multi-threaded scripts or event-handling code - it's not thread-safe) +The current player. (Note - this value should not be used in +multi-threaded scripts or event-handling code - it's not +thread-safe). This variable is only safe to use at the in-game prompt +and should *never* be used in modules. For example you can use it here... + + /js console.log(self.name) + +... but not in any javascript module you create yourself or in any +event handling code. `self` is a temporary short-lived variable which +only exists in the context of the in-game or server command prompts. ### config variable ScriptCraft configuration - this object is loaded and saved at startup/shutdown. @@ -239,7 +248,7 @@ load() will return the result of the last statement evaluated in the file. #### Example - load(__folder + "myFile.js"); // loads a javascript file and evaluates it. + load("myFile.js"); // loads a javascript file and evaluates it. var myData = load("myData.json"); // loads a javascript file and evaluates it - eval'd contents are returned. @@ -939,7 +948,7 @@ Drones can be created in any of the following ways... var d = new Drone().box( blocks.oak ) - ... All of the Drone's methods return `this` (self) so you can chain operations together like this... + ... All of the Drone's methods return `this` so you can chain operations together like this... var d = box( blocks.oak ) .up() @@ -1742,13 +1751,13 @@ The arrows mod adds fancy arrows to the game. Arrows which... ### Usage: - * `/js arrows.firework()` - A firework launches where the the arrow lands. - * `/js arrows.lightning()` - lightning strikes where the arrow lands. - * `/js arrows.teleport()` - makes player teleport to where arrow has landed. - * `/js arrows.flourish()` - makes a tree grow where the arrow lands. - * `/js arrows.explosive()` - makes arrows explode. - * `/js arrows.normal()` sets arrow type to normal. - * `/js arrows.sign()` turns a targeted sign into a Arrows menu + * `/js arrows.firework(self)` - A firework launches where the the arrow lands. + * `/js arrows.lightning(self)` - lightning strikes where the arrow lands. + * `/js arrows.teleport(self)` - makes player teleport to where arrow has landed. + * `/js arrows.flourish(self)` - makes a tree grow where the arrow lands. + * `/js arrows.explosive(self)` - makes arrows explode. + * `/js arrows.normal(self)` sets arrow type to normal. + * `/js arrows.sign(self)` turns a targeted sign into a Arrows menu All of the above functions can take an optional player object or name as a parameter. For example: `/js arrows.explosive('player23')` makes @@ -1835,11 +1844,11 @@ to every student in a Minecraft classroom environment. To allow all players (and any players who connect to the server) to use the `js` and `jsp` commands... - /js classroom.allowScripting(true) + /js classroom.allowScripting(true,self) To disallow scripting (and prevent players who join the server from using the commands)... - /js classroom.allowScripting(false) + /js classroom.allowScripting(false,self) Only ops users can run the classroom.allowScripting() function - this is so that students don't try to bar themselves and each other from scripting. @@ -1853,7 +1862,7 @@ to Minecraft. Normally ScriptCraft only allows for provision of new commands as extensions to the jsp command. For example, to create a new simple command for use by all players... - /js command('hi', function(){ echo('Hi ' + self.name); }); + /js command('hi', function(args,player){ player.sendMessage('Hi ' + player.name); }); ... then players can use this command by typing... @@ -1890,8 +1899,8 @@ of the ScriptCraft core. ### Example hi-command.js var commando = require('../commando'); - commando('hi', function(){ - echo('Hi ' + self.name); + commando('hi', function(args,player){ + player.sendMessage('Hi ' + player.name); }); ...Displays a greeting to any player who issues the `/hi` command. @@ -1899,8 +1908,8 @@ of the ScriptCraft core. ### Example - timeofday-command.js var times = {Dawn: 0, Midday: 6000, Dusk: 12000, Midnight:18000}; - commando('timeofday', function(params){ - self.location.world.setTime(times[params[0]]); + commando('timeofday', function(params,player){ + player.location.world.setTime(times[params[0]]); }, ['Dawn','Midday','Dusk','Midnight']); @@ -2030,7 +2039,7 @@ code is to demonstrate use of Bukkit's Conversation API. ### Example - /js Game_NumberGuess.start() + /js Game_NumberGuess.start(self) Once the game begins, guess a number by typing the `/` character followed by a number between 1 and 10. diff --git a/docs/YoungPersonsGuideToProgrammingMinecraft.md b/docs/YoungPersonsGuideToProgrammingMinecraft.md index a402487..4772adf 100644 --- a/docs/YoungPersonsGuideToProgrammingMinecraft.md +++ b/docs/YoungPersonsGuideToProgrammingMinecraft.md @@ -439,8 +439,8 @@ object can do, let's use that knowledge to create a Minecraft Mod! Once you've installed Notepad++, Launch it, create a new file and type the following... - exports.greet = function(){ - echo("Hi " + self.name); + exports.greet = function(player){ + player.sendMessage("Hi " + player.name); } ... then save the file in a new directory @@ -479,16 +479,16 @@ one or more functions, objects or variables. For example... #### thrower.js - exports.egg = function(){ - self.throwEgg(); + exports.egg = function(player){ + player.throwEgg(); } - exports.snowball = function(){ - self.throwSnowball(); + exports.snowball = function(player){ + player.throwSnowball(); } ... is a plugin which provides 2 javascript functions called `egg()` and `snowball()` which can be invoked from the in-game prompt like -this `/js egg()` or `/js snowball()`. +this `/js egg(self)` or `/js snowball(self)`. ### Parameters If you want to change the `greet()` function so that it displays a @@ -501,18 +501,18 @@ differently each time it is called. Change the `greet()` function so that it looks like this... - exports.greet = function ( greeting ) { - echo( greeting + self.name ); + exports.greet = function ( greeting , player) { + player.sendMessage( greeting + player.name ); } ... Save your greet.js file and issue the `/js refresh()` command in minecraft. Now enter the following command in Minecraft... - greet("Hello "); + greet("Hello ",self); ... Now try ... - greet("Dia Dhuit "); + greet("Dia Dhuit ",self); ... you should see the following messages in your chat window... @@ -716,7 +716,7 @@ loop. The following `while` loop counts to 100... var i = 1; while (i <= 100){ - echo( i ); + console.log( i ); i = i + 1; } @@ -743,7 +743,7 @@ the server... var players = server.onlinePlayers; var i = 0; while ( i < players.length ) { - echo( players[i] ); + console.log( players[i] ); i = i + 1; } @@ -765,17 +765,17 @@ loops. utils.foreach() takes two parameters... 2. A function which will be called for each item in the array. ...that's right, you can pass functions as parameters in javascript! -Let's see it in action, the following code will `echo()` (print) the -name of each online player... +Let's see it in action, the following code will `console.log()` (print) the +name of each online player in the server console window... - utils.foreach( server.onlinePlayers, echo ); + utils.foreach( server.onlinePlayers, console.log ); ... in the above example, the list of online players is processed one -at a time and each item (player) is passed to the `echo` -function. Note here that I used `echo` not `echo()`. The round braces +at a time and each item (player) is passed to the `console.log` +function. Note here that I used `console.log` not `console.log()`. The round braces () are used to call the function. If I want to pass the function as a parameter, I just use the function name without the round braces. The -above example uses a named function which already exists ( `echo` ), +above example uses a named function which already exists ( `console.log` ), you can also create new functions on-the-fly and pass them to the utils.foreach() function... @@ -930,20 +930,20 @@ flying or not? This is where the `if - else` construct comes in handy. Open your favorite editor and type the following code into a new file in your scriptcraft/plugins directory... - function flightStatus() + function flightStatus(player) { - if ( self.flying ) + if ( player.flying ) { - echo( "Hey, You are flying!" ); + player.sendMessage( 'Hey, You are flying!' ); } else { - echo( "You are not flying." ); + player.sendMessage( 'You are not flying.' ); } } ... now type `/reload` at the in-game prompt then type `/js -flightStatus()` and an appropriate message will appear based on +flightStatus(self)` and an appropriate message will appear based on whether or not you're currently flying. Type the `/js flightStatus()` command while on the ground and while flying. The message displayed in each case should be different. diff --git a/src/main/java/net/walterhiggins/scriptcraft/ScriptCraftPlugin.java b/src/main/java/net/walterhiggins/scriptcraft/ScriptCraftPlugin.java index 64bac6a..4cbe96a 100644 --- a/src/main/java/net/walterhiggins/scriptcraft/ScriptCraftPlugin.java +++ b/src/main/java/net/walterhiggins/scriptcraft/ScriptCraftPlugin.java @@ -92,20 +92,12 @@ public class ScriptCraftPlugin extends JavaPlugin implements Listener FileReader reader = null; try{ ScriptEngineManager factory = new ScriptEngineManager(); - File boot = new File(JS_PLUGINS_DIR + "/lib/scriptcraft.js"); + File bootScript = new File(JS_PLUGINS_DIR + "/lib/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); + reader = new FileReader(bootScript); this.engine.eval(reader); - /* - wph 20130811 Need to disable coffeescript support until issues loading and evaluating it are resolved. - See issue #92 - // Load the CoffeeScript compiler - File coffeescript = new File(JS_PLUGINS_DIR + "/lib/coffeescript.js"); - this.engine.eval(new FileReader(coffeescript)); - */ + Invocable inv = (Invocable)this.engine; + inv.invokeFunction("__onEnable", engine, this, bootScript); }catch(Exception e){ e.printStackTrace(); @@ -128,12 +120,8 @@ public class ScriptCraftPlugin extends JavaPlugin implements Listener // 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()"); + Invocable inv = (Invocable)this.engine; + inv.invokeFunction("__onTabComplete", result, sender, cmd, alias, args); }catch (Exception e){ sender.sendMessage(e.getMessage()); e.printStackTrace(); @@ -145,40 +133,17 @@ public class ScriptCraftPlugin extends JavaPlugin implements Listener { 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; + 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()); } - - 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(); - } + if (jsResult != null){ + return ((Boolean)jsResult).booleanValue(); } - return result; + return result; } } diff --git a/src/main/javascript/lib/command.js b/src/main/javascript/lib/command.js index 568bc12..67b6ace 100644 --- a/src/main/javascript/lib/command.js +++ b/src/main/javascript/lib/command.js @@ -22,15 +22,11 @@ var executeCmd = function(args, player){ console.warn('Command %s is not recognised',name); }else{ func = cmd.callback; - var params = []; - for (var i =1; i < args.length;i++){ - params.push("" + args[i]); - } var result = null; try { - result = func(params,player); + result = func(args.slice(1),player); }catch (e){ - console.error("Error while trying to execute command: " + JSON.stringify(params)); + console.error("Error while trying to execute command: " + JSON.stringify(args)); throw e; } return result; @@ -48,12 +44,8 @@ var defineCmd = function(name, func, options, intercepts) { return func; }; var _command = function(name, func, options, intercepts) { - if (typeof name == "undefined"){ - // it's an invocation from the Java Plugin! - return executeCmd(__cmdArgs, self); - }else{ - return defineCmd(name, func, options, intercepts); - } + return defineCmd(name, func, options, intercepts); }; +_command.exec = executeCmd; exports.command = _command; exports.commands = _commands; diff --git a/src/main/javascript/lib/scriptcraft.js b/src/main/javascript/lib/scriptcraft.js index 7eecf94..ec34e01 100644 --- a/src/main/javascript/lib/scriptcraft.js +++ b/src/main/javascript/lib/scriptcraft.js @@ -19,7 +19,7 @@ loads the module circle.js in the same directory. The contents of foo.js: var circle = require('./circle.js'); - echo( 'The area of a circle of radius 4 is ' + console.log( 'The area of a circle of radius 4 is ' + circle.area(4)); The contents of circle.js: @@ -72,14 +72,14 @@ module in the `plugins` directory exports becomes a global variable. For example, if you have a module greeting.js in the plugins directory.... - exports.greet = function() { - echo('Hello ' + self.name); + exports.greet = function(player) { + player.sendMessage('Hello ' + player.name); }; ... then `greet` becomes a global function and can be used at the in-game (or server) command prompt like so... - /js greet() + /js greet(self) ... This differs from how modules (in NodeJS and commonJS environments) normally work. If you want your module to be exported @@ -139,7 +139,16 @@ The ScriptCraft JavaPlugin object. The Minecraft Server object ### self variable -The current player. (Note - this value should not be used in multi-threaded scripts or event-handling code - it's not thread-safe) +The current player. (Note - this value should not be used in +multi-threaded scripts or event-handling code - it's not +thread-safe). This variable is only safe to use at the in-game prompt +and should *never* be used in modules. For example you can use it here... + + /js console.log(self.name) + +... but not in any javascript module you create yourself or in any +event handling code. `self` is a temporary short-lived variable which +only exists in the context of the in-game or server command prompts. ### config variable ScriptCraft configuration - this object is loaded and saved at startup/shutdown. @@ -240,7 +249,7 @@ load() will return the result of the last statement evaluated in the file. #### Example - load(__folder + "myFile.js"); // loads a javascript file and evaluates it. + load("myFile.js"); // loads a javascript file and evaluates it. var myData = load("myData.json"); // loads a javascript file and evaluates it - eval'd contents are returned. @@ -413,8 +422,8 @@ var server = org.bukkit.Bukkit.server; /* private implementation */ -(function(){ - +function __onEnable (__engine, __plugin, __script) +{ /* don't execute this more than once */ @@ -428,9 +437,8 @@ var server = org.bukkit.Bukkit.server; return "" + file.getCanonicalPath().replaceAll("\\\\","/"); }; - var _originalScript = __script; - var parentFileObj = new File(__script).getParentFile(); - var jsPluginsRootDir = parentFileObj.getParentFile(); + var parentFileObj = __script.parentFile; + var jsPluginsRootDir = parentFileObj.parentFile; var jsPluginsRootDirName = _canonize(jsPluginsRootDir); var _loaded = {}; @@ -457,19 +465,11 @@ var server = org.bukkit.Bukkit.server; var parent = file.getParentFile(); var reader = new FileReader(file); var br = new BufferedReader(reader); - __engine.put("__script",canonizedFilename); - __engine.put("__folder",(parent?_canonize(parent):"")+"/"); - var code = ""; try{ - if (file.getCanonicalPath().endsWith(".coffee")) { - while ((r = br.readLine()) !== null) code += "\"" + r + "\" +\n"; - code += "\"\""; - var code = "load(__folder + \"../core/_coffeescript.js\"); var ___code = "+code+"; eval(CoffeeScript.compile(___code, {bare: true}))"; - } else { - while ((r = br.readLine()) !== null) - code += r + "\n"; - } + while ((r = br.readLine()) !== null) + code += r + "\n"; + result = __engine.eval("(" + code + ")"); // issue #103 avoid side-effects of || operator on Mac Rhino _loaded[canonizedFilename] = result ; @@ -498,6 +498,7 @@ var server = org.bukkit.Bukkit.server; if (!config) config = {verbose: false}; global.config = config; + global.__plugin = __plugin; /* wph 20131229 Issue #103 JSON is not bundled with javax.scripting / Rhino on Mac. */ @@ -567,7 +568,8 @@ var server = org.bukkit.Bukkit.server; global.console = require('console'); global.command = require('command').command; var plugins = require('plugin'); - global._onTabComplete = require('tabcomplete'); + + global.__onTabComplete = require('tabcomplete'); global.plugin = plugins.plugin; global.save = plugins.save; @@ -584,4 +586,37 @@ var server = org.bukkit.Bukkit.server; global.events = events; plugins.autoload(jsPluginsRootDir); -}()); + + global.__onCommand = function( sender, cmd, label, args) { + var jsArgs = []; + var i = 0; + for (;i < args.length; i++) jsArgs.push('' + args[i]); + + var result = false; + var cmdName = ('' + cmd.name).toLowerCase(); + if (cmdName == 'js') + { + result = true; + var fnBody = jsArgs.join(' '); + global.self = sender; + global.__engine = __engine; + try { + //var jsResult = __engine["eval(java.lang.String,javax.script.Bindings)"]( fnBody, bindings ); + var jsResult = __engine.eval(fnBody); + if (jsResult) + sender.sendMessage(jsResult); + }catch (e){ + __plugin.logger.severe("Error while trying to evaluate javascript: " + fnBody + ", Error: "+ e); + throw e; + }finally{ + delete global.self; + delete global.__engine; + } + } + if (cmdName == 'jsp'){ + command.exec(jsArgs, sender); + result = true; + } + return result; + }; +} diff --git a/src/main/javascript/lib/tabcomplete-jsp.js b/src/main/javascript/lib/tabcomplete-jsp.js index b75e883..8a0c129 100644 --- a/src/main/javascript/lib/tabcomplete-jsp.js +++ b/src/main/javascript/lib/tabcomplete-jsp.js @@ -2,9 +2,9 @@ var _commands = require('command').commands; /* Tab completion for the /jsp commmand */ -var __onTabCompleteJSP = function() { - var result = global.__onTC_result; - var args = global.__onTC_args; +var __onTabCompleteJSP = function( __onTC_result, __onTC_sender, __onTC_cmd, __onTC_alias, __onTC_args) { + var result = __onTC_result; + var args = __onTC_args; var cmdInput = args[0]; var cmd = _commands[cmdInput]; if (cmd){ diff --git a/src/main/javascript/lib/tabcomplete.js b/src/main/javascript/lib/tabcomplete.js index 37e0bbc..885f6d0 100644 --- a/src/main/javascript/lib/tabcomplete.js +++ b/src/main/javascript/lib/tabcomplete.js @@ -73,12 +73,13 @@ var _getProperties = function(o) return result.sort(); }; -var onTabCompleteJS = function() { +var onTabCompleteJS = function( __onTC_result, __onTC_sender, __onTC_cmd, __onTC_alias, __onTC_args) { if (__onTC_cmd.name == 'jsp') - return tabCompleteJSP() + return tabCompleteJSP( __onTC_result, __onTC_sender, __onTC_cmd, __onTC_alias, __onTC_args ); + var _globalSymbols = _getProperties(global) - var result = global.__onTC_result; - var args = global.__onTC_args; + var result = __onTC_result; + var args = __onTC_args; var lastArg = args.length?args[args.length-1]+'':null; var propsOfLastArg = []; var statement = args.join(' '); diff --git a/src/main/javascript/plugins/alias/alias.js b/src/main/javascript/plugins/alias/alias.js index 1d325e1..ca7eb2e 100644 --- a/src/main/javascript/plugins/alias/alias.js +++ b/src/main/javascript/plugins/alias/alias.js @@ -175,7 +175,9 @@ var _intercept = function( msg, invoker, exec) isAlias = true; }else{ if (config.verbose){ - console.info("No global alias found for command: " + command); + var commandObj = server.commandMap.getCommand(command); + if (!commandObj) + console.info("No global alias found for command: " + command); } } /* @@ -188,7 +190,9 @@ var _intercept = function( msg, invoker, exec) isAlias = true; }else{ if (config.verbose){ - console.info("No player alias found for command: " + command); + var commandObj = server.commandMap.getCommand(command); + if (!commandObj) + console.info("No player alias found for command: " + command); } } for (var i = 0;i < template.length; i++) diff --git a/src/main/javascript/plugins/arrows.js b/src/main/javascript/plugins/arrows.js index fb0d73d..9cf7783 100644 --- a/src/main/javascript/plugins/arrows.js +++ b/src/main/javascript/plugins/arrows.js @@ -11,13 +11,13 @@ The arrows mod adds fancy arrows to the game. Arrows which... ### Usage: - * `/js arrows.firework()` - A firework launches where the the arrow lands. - * `/js arrows.lightning()` - lightning strikes where the arrow lands. - * `/js arrows.teleport()` - makes player teleport to where arrow has landed. - * `/js arrows.flourish()` - makes a tree grow where the arrow lands. - * `/js arrows.explosive()` - makes arrows explode. - * `/js arrows.normal()` sets arrow type to normal. - * `/js arrows.sign()` turns a targeted sign into a Arrows menu + * `/js arrows.firework(self)` - A firework launches where the the arrow lands. + * `/js arrows.lightning(self)` - lightning strikes where the arrow lands. + * `/js arrows.teleport(self)` - makes player teleport to where arrow has landed. + * `/js arrows.flourish(self)` - makes a tree grow where the arrow lands. + * `/js arrows.explosive(self)` - makes arrows explode. + * `/js arrows.normal(self)` sets arrow type to normal. + * `/js arrows.sign(self)` turns a targeted sign into a Arrows menu All of the above functions can take an optional player object or name as a parameter. For example: `/js arrows.explosive('player23')` makes @@ -27,6 +27,7 @@ player23's arrows explosive. var signs = require('signs'); var fireworks = require('fireworks'); +var utils = require('utils'); var _store = {players: {}}; @@ -75,14 +76,8 @@ for (var type in _types) { arrows[type] = (function(n){ return function(player){ - if (typeof player == "undefined") - player = self; - var playerName = null; - if (typeof player == "string") - playerName = player; - else - playerName = player.name; - arrows.store.players[playerName] = n; + player = utils.getPlayerObject(player); + arrows.store.players[player.name] = n; }; })(_types[type]); } diff --git a/src/main/javascript/plugins/chat/color.js b/src/main/javascript/plugins/chat/color.js index 62493e7..3d0000f 100644 --- a/src/main/javascript/plugins/chat/color.js +++ b/src/main/javascript/plugins/chat/color.js @@ -35,19 +35,19 @@ events.on("player.AsyncPlayerChatEvent",function(l,e){ e.message = "§" + colorCodes[playerChatColor] + e.message; } }); -var listColors = function(params){ +var listColors = function(params,sender){ var colorNamesInColor = []; for (var i = 0;i < colors.length;i++) colorNamesInColor[i] = "§"+colorCodes[colors[i]] + colors[i]; - self.sendMessage("valid chat colors are " + colorNamesInColor.join(", ")); + sender.sendMessage("valid chat colors are " + colorNamesInColor.join(", ")); }; command("list_colors", listColors); -command("chat_color",function(params){ +command("chat_color",function(params,sender){ var color = params[0]; if (colorCodes[color]){ - chat.setColor(self,color); + chat.setColor(sender,color); }else{ - self.sendMessage(color + " is not a valid color"); + sender.sendMessage(color + " is not a valid color"); listColors(); } },colors); diff --git a/src/main/javascript/plugins/classroom/classroom.js b/src/main/javascript/plugins/classroom/classroom.js index a1f07fe..04f8d62 100644 --- a/src/main/javascript/plugins/classroom/classroom.js +++ b/src/main/javascript/plugins/classroom/classroom.js @@ -32,11 +32,11 @@ to every student in a Minecraft classroom environment. To allow all players (and any players who connect to the server) to use the `js` and `jsp` commands... - /js classroom.allowScripting(true) + /js classroom.allowScripting(true,self) To disallow scripting (and prevent players who join the server from using the commands)... - /js classroom.allowScripting(false) + /js classroom.allowScripting(false,self) Only ops users can run the classroom.allowScripting() function - this is so that students don't try to bar themselves and each other from scripting. @@ -44,16 +44,25 @@ don't try to bar themselves and each other from scripting. ***/ var _store = {enableScripting: false}; var classroom = plugin("classroom", { - allowScripting: function (/* boolean: true or false */ canScript) { + allowScripting: function (/* boolean: true or false */ canScript, sender) { + if (typeof sender == 'undefined'){ + console.log("Attempt to set classroom scripting without credentials"); + return; + } + if (!sender.op){ + console.log("Attempt to set classroom scripting without credentials: " + sender.name); + return; + } + /* only operators should be allowed run this function */ - if (!self.isOp()) + if (!sender.isOp()) return; if (canScript){ - utils.foreach( server.onlinePlayers, function (player) { - player.addAttachment(__plugin, "scriptcraft.*", true); - }); + utils.foreach( server.onlinePlayers, function (player) { + player.addAttachment(__plugin, "scriptcraft.*", true); + }); }else{ utils.foreach( server.onlinePlayers, function(player) { utils.foreach(player.getEffectivePermissions(), function(perm) { diff --git a/src/main/javascript/plugins/commando/commando-test.js b/src/main/javascript/plugins/commando/commando-test.js index 0f17784..56900b4 100644 --- a/src/main/javascript/plugins/commando/commando-test.js +++ b/src/main/javascript/plugins/commando/commando-test.js @@ -9,6 +9,13 @@ var times = { Dusk: 12000, Midnight: 18000 }; -commando('scriptcrafttimeofday',function(params){ - self.location.world.setTime(times[params[0]]); +commando('scriptcrafttimeofday',function(params,sender){ + if (config.verbose){ + console.log('scriptcrafttimeofday.params=%s',JSON.stringify(params)); + } + if (sender.location) + sender.location.world.setTime(times[params[0]]); + else + sender.sendMessage('This command only works in-world'); + },['Dawn','Midday','Dusk','Midnight']); diff --git a/src/main/javascript/plugins/commando/commando.js b/src/main/javascript/plugins/commando/commando.js index 2943a22..6f2694a 100644 --- a/src/main/javascript/plugins/commando/commando.js +++ b/src/main/javascript/plugins/commando/commando.js @@ -8,7 +8,7 @@ to Minecraft. Normally ScriptCraft only allows for provision of new commands as extensions to the jsp command. For example, to create a new simple command for use by all players... - /js command('hi', function(){ echo('Hi ' + self.name); }); + /js command('hi', function(args,player){ player.sendMessage('Hi ' + player.name); }); ... then players can use this command by typing... @@ -45,8 +45,8 @@ of the ScriptCraft core. ### Example hi-command.js var commando = require('../commando'); - commando('hi', function(){ - echo('Hi ' + self.name); + commando('hi', function(args,player){ + player.sendMessage('Hi ' + player.name); }); ...Displays a greeting to any player who issues the `/hi` command. @@ -54,8 +54,8 @@ of the ScriptCraft core. ### Example - timeofday-command.js var times = {Dawn: 0, Midday: 6000, Dusk: 12000, Midnight:18000}; - commando('timeofday', function(params){ - self.location.world.setTime(times[params[0]]); + commando('timeofday', function(params,player){ + player.location.world.setTime(times[params[0]]); }, ['Dawn','Midday','Dusk','Midnight']); @@ -85,7 +85,7 @@ exports.commando = function(name, func, options, intercepts){ }; events.on('player.PlayerCommandPreprocessEvent', function(l,e){ - var msg = "" + e.message; + var msg = '' + e.message; var parts = msg.match(/^\/([^\s]+)/); if (!parts) return; @@ -97,7 +97,7 @@ events.on('player.PlayerCommandPreprocessEvent', function(l,e){ } }); events.on('server.ServerCommandEvent', function(l,e){ - var msg = "" + e.command; + var msg = '' + e.command; var parts = msg.match(/^\/*([^\s]+)/); if (!parts) return; @@ -105,6 +105,10 @@ events.on('server.ServerCommandEvent', function(l,e){ return; var command = parts[1]; if (commands[command]){ - e.command = "jsp " + msg.replace(/^\//,""); + var newCmd = "jsp " + msg.replace(/^\//,""); + if (config.verbose){ + console.log('Redirecting to : %s',newCmd); + } + e.command = newCmd; } }); diff --git a/src/main/javascript/plugins/drone/contrib/fort.js b/src/main/javascript/plugins/drone/contrib/fort.js index d6477dd..90686c7 100644 --- a/src/main/javascript/plugins/drone/contrib/fort.js +++ b/src/main/javascript/plugins/drone/contrib/fort.js @@ -33,7 +33,7 @@ Drone.extend('fort', function(side, height) try{ this.boxa(turret,1,1,side-2).fwd(side-2).turn(); }catch(e){ - self.sendMessage("ERROR: " + e.toString()); + console.log("ERROR: " + e.toString()); } } // diff --git a/src/main/javascript/plugins/drone/drone.js b/src/main/javascript/plugins/drone/drone.js index 014cf2a..497a8b3 100644 --- a/src/main/javascript/plugins/drone/drone.js +++ b/src/main/javascript/plugins/drone/drone.js @@ -46,7 +46,7 @@ Drones can be created in any of the following ways... var d = new Drone().box( blocks.oak ) - ... All of the Drone's methods return `this` (self) so you can chain operations together like this... + ... All of the Drone's methods return `this` so you can chain operations together like this... var d = box( blocks.oak ) .up() @@ -727,8 +727,6 @@ Drone = function(x,y,z,dir,world) this.chkpt('start'); this.record = true; this.history = []; - // for debugging - // self.sendMessage("New Drone " + this.toString()); return this; }; diff --git a/src/main/javascript/plugins/homes/homes.js b/src/main/javascript/plugins/homes/homes.js index b7af5d6..9c493cd 100644 --- a/src/main/javascript/plugins/homes/homes.js +++ b/src/main/javascript/plugins/homes/homes.js @@ -251,71 +251,71 @@ exports.homes = homes; var options = { 'set': function(){homes.set();}, 'delete': function(){ homes.remove();}, - 'help': function(){ self.sendMessage(homes.help());}, - 'list': function(){ + 'help': function(params, sender){ sender.sendMessage(homes.help());}, + 'list': function(params, sender){ var visitable = homes.list(); if (visitable.length == 0){ - self.sendMessage("There are no homes to visit"); + sender.sendMessage("There are no homes to visit"); return; }else{ - self.sendMessage([ + sender.sendMessage([ "You can visit any of these " + visitable.length + " homes" ,visitable.join(", ") ]); } }, - 'ilist': function(){ + 'ilist': function(params, sender){ var potentialVisitors = homes.ilist(); if (potentialVisitors.length == 0) - self.sendMessage("No one can visit your home"); + sender.sendMessage("No one can visit your home"); else - self.sendMessage([ + sender.sendMessage([ "These " + potentialVisitors.length + "players can visit your home", potentialVisitors.join(", ")]); }, - 'invite': function(params){ + 'invite': function(params,sender){ if (params.length == 1){ - self.sendMessage("You must provide a player's name"); + sender.sendMessage("You must provide a player's name"); return; } var playerName = params[1]; var guest = utils.getPlayerObject(playerName); if (!guest) - self.sendMessage(playerName + " is not here"); + sender.sendMessage(playerName + " is not here"); else - homes.invite(self,guest); + homes.invite(sender,guest); }, - 'uninvite': function(params){ + 'uninvite': function(params,sender){ if (params.length == 1){ - self.sendMessage("You must provide a player's name"); + sender.sendMessage("You must provide a player's name"); return; } var playerName = params[1]; var guest = utils.getPlayerObject(playerName); if (!guest) - self.sendMessage(playerName + " is not here"); + sender.sendMessage(playerName + " is not here"); else - homes.uninvite(self,guest); + homes.uninvite(sender,guest); }, - 'public': function(params){ - homes.open(self,params.slice(1).join(' ')); - self.sendMessage("Your home is open to the public"); + 'public': function(params,sender){ + homes.open(sender,params.slice(1).join(' ')); + sender.sendMessage("Your home is open to the public"); }, - 'private': function(){ - homes.close(); - self.sendMessage("Your home is closed to the public"); + 'private': function(params, sender){ + homes.close(sender); + sender.sendMessage("Your home is closed to the public"); }, - 'listall': function(){ - if (!self.isOp()) - self.sendMessage("Only operators can do this"); + 'listall': function(params, sender){ + if (!sender.isOp()) + sender.sendMessage("Only operators can do this"); else - self.sendMessage(homes.listall().join(", ")); + sender.sendMessage(homes.listall().join(", ")); }, - 'clear': function(params){ - if (!self.isOp()) - self.sendMessage("Only operators can do this"); + 'clear': function(params,sender){ + if (!sender.isOp()) + sender.sendMessage("Only operators can do this"); else - homes.clear(params[1]); + homes.clear(params[1], sender); } }; var optionList = []; @@ -324,20 +324,20 @@ for (var o in options) /* Expose a set of commands that players can use at the in-game command prompt */ -command("home", function ( params ) { +command("home", function ( params , sender) { if (params.length == 0){ - homes.go(); + homes.go(sender,sender); return; } var option = options[params[0]]; if (option) - option(params); + option(params,sender); else{ var host = utils.getPlayerObject(params[0]); if (!host) - self.sendMessage(params[0] + " is not here"); + sender.sendMessage(params[0] + " is not here"); else - homes.go(self,host); + homes.go(sender,host); } },optionList); diff --git a/src/main/javascript/plugins/minigames/NumberGuess.js b/src/main/javascript/plugins/minigames/NumberGuess.js index d03d7f2..01424a4 100644 --- a/src/main/javascript/plugins/minigames/NumberGuess.js +++ b/src/main/javascript/plugins/minigames/NumberGuess.js @@ -9,14 +9,14 @@ code is to demonstrate use of Bukkit's Conversation API. ### Example - /js Game_NumberGuess.start() + /js Game_NumberGuess.start(self) Once the game begins, guess a number by typing the `/` character followed by a number between 1 and 10. ***/ exports.Game_NumberGuess = { - start: function() { + start: function(sender) { importPackage(org.bukkit.conversations); var number = Math.ceil(Math.random() * 10); @@ -54,7 +54,7 @@ exports.Game_NumberGuess = { var conv = cf.withModality(true) .withFirstPrompt(prompt) .withPrefix(new ConversationPrefix(){ getPrefix: function(ctx){ return "[1-10] ";} }) - .buildConversation(self); + .buildConversation(sender); conv.begin(); } };