'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.
This commit is contained in:
walterhiggins 2013-12-30 21:33:12 +00:00
parent fc440654b8
commit f88d1f0428
17 changed files with 239 additions and 220 deletions

View file

@ -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.

View file

@ -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.

View file

@ -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<String> result = new ArrayList<String>();
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,39 +133,16 @@ 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;
}

View file

@ -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;

View file

@ -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;
};
}

View file

@ -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){

View file

@ -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(' ');

View file

@ -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++)

View file

@ -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]);
}

View file

@ -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);

View file

@ -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) {

View file

@ -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']);

View file

@ -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;
}
});

View file

@ -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());
}
}
//

View file

@ -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;
};

View file

@ -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);

View file

@ -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();
}
};