Changed formatting to use idiomatic style. (like glasses-mode in emacs)

This commit is contained in:
walterhiggins 2014-01-29 19:49:15 +00:00
parent 7a7767c83c
commit 7457cd58b8
54 changed files with 4161 additions and 3849 deletions

View file

@ -787,7 +787,7 @@ To call the fireworks.firework() function directly, you must provide a
location. For example... location. For example...
/js var fireworks = require('fireworks'); /js var fireworks = require('fireworks');
/js fireworks.firework(self.location); /js fireworks.firework( self.location );
![firework example](img/firework.png) ![firework example](img/firework.png)
@ -829,11 +829,14 @@ The following example illustrates how to use http.request to make a request to a
... The following example illustrates a more complex use-case POSTing parameters to a CGI process on a server... ... The following example illustrates a more complex use-case POSTing parameters to a CGI process on a server...
var http = require('./http/request'); var http = require('./http/request');
http.request({ url: "http://pixenate.com/pixenate/pxn8.pl", http.request(
method: "POST", {
params: {script: "[]"} url: 'http://pixenate.com/pixenate/pxn8.pl',
}, function( responseCode, responseBody){ method: 'POST',
var jsObj = eval("(" + responseBody + ")"); params: {script: '[]'}
},
function( responseCode, responseBody ) {
var jsObj = eval('(' + responseBody + ')');
}); });
## sc-mqtt module ## sc-mqtt module
@ -870,24 +873,24 @@ present in the CraftBukkit classpath. To use this module, you should
// create a new client // create a new client
var client = mqtt.client('tcp://localhost:1883', 'uniqueClientId'); var client = mqtt.client( 'tcp://localhost:1883', 'uniqueClientId' );
// connect to the broker // connect to the broker
client.connect({ keepAliveInterval: 15 }); client.connect( { keepAliveInterval: 15 } );
// publish a message to the broker // publish a message to the broker
client.publish('minecraft','loaded'); client.publish( 'minecraft', 'loaded' );
// subscribe to messages on 'arduino' topic // subscribe to messages on 'arduino' topic
client.subscribe('arduino'); client.subscribe( 'arduino' );
// do something when an incoming message arrives... // do something when an incoming message arrives...
client.onMessageArrived(function(topic, message){ client.onMessageArrived( function( topic, message ) {
console.log('Message arrived: topic=' + topic + ', message=' + message); console.log( 'Message arrived: topic=' + topic + ', message=' + message );
}); });
The `sc-mqtt` module provides a very simple minimal wrapper around the The `sc-mqtt` module provides a very simple minimal wrapper around the
@ -1023,7 +1026,7 @@ Example
------- -------
/js var boldGoldText = "Hello World".bold().gold(); /js var boldGoldText = "Hello World".bold().gold();
/js self.sendMessage(boldGoldText); /js self.sendMessage( boldGoldText );
<p style="color:gold;font-weight:bold">Hello World</p> <p style="color:gold;font-weight:bold">Hello World</p>
@ -1173,7 +1176,7 @@ package for scheduling processing of arrays.
- object : Additional (optional) information passed into the foreach method. - object : Additional (optional) information passed into the foreach method.
- array : The entire array. - array : The entire array.
* object (optional) : An object which may be used by the callback. * context (optional) : An object which may be used by the callback.
* delay (optional, numeric) : If a delay is specified (in ticks - 20 * delay (optional, numeric) : If a delay is specified (in ticks - 20
ticks = 1 second), then the processing will be scheduled so that ticks = 1 second), then the processing will be scheduled so that
each item will be processed in turn with a delay between the completion of each each item will be processed in turn with a delay between the completion of each
@ -1273,9 +1276,9 @@ To warn players when night is approaching...
utils.at( '19:00', function() { utils.at( '19:00', function() {
utils.foreach( server.onlinePlayers, function(player){ utils.foreach( server.onlinePlayers, function( player ) {
player.chat('The night is dark and full of terrors!'); player.chat( 'The night is dark and full of terrors!' );
}); });
}); });
@ -1410,7 +1413,7 @@ Drones can be created in any of the following ways...
block is broken at the block's location you would do so like block is broken at the block's location you would do so like
this... this...
events.on('block.BlockBreakEvent',function(listener,event){ events.on('block.BlockBreakEvent',function( listener,event) {
var location = event.block.location; var location = event.block.location;
var drone = new Drone(location); var drone = new Drone(location);
// do more stuff with the drone here... // do more stuff with the drone here...
@ -1552,7 +1555,7 @@ Markers are created and returned to using the followng two methods...
// //
// the drone can now go off on a long excursion // the drone can now go off on a long excursion
// //
for (i = 0; i< 100; i++){ for ( i = 0; i< 100; i++) {
drone.fwd(12).box(6); drone.fwd(12).box(6);
} }
// //
@ -1624,11 +1627,11 @@ arc() takes a single parameter - an object with the following named properties..
* radius - The radius of the arc. * radius - The radius of the arc.
* blockType - The type of block to use - this is the block Id only (no meta). See [Data Values][dv]. * blockType - The type of block to use - this is the block Id only (no meta). See [Data Values][dv].
* meta - The metadata value. See [Data Values][dv]. * meta - The metadata value. See [Data Values][dv].
* orientation (default: 'horizontal') - the orientation of the arc - can be 'vertical' or 'horizontal'. * orientation (default: 'horizontal' ) - the orientation of the arc - can be 'vertical' or 'horizontal'.
* stack (default: 1) - the height or length of the arc (depending on * stack (default: 1 ) - the height or length of the arc (depending on
the orientation - if orientation is horizontal then this parameter the orientation - if orientation is horizontal then this parameter
refers to the height, if vertical then it refers to the length). refers to the height, if vertical then it refers to the length ).
* strokeWidth (default: 1) - the width of the stroke (how many * strokeWidth (default: 1 ) - the width of the stroke (how many
blocks) - if drawing nested arcs it's usually a good idea to set blocks) - if drawing nested arcs it's usually a good idea to set
strokeWidth to at least 2 so that there are no gaps between each strokeWidth to at least 2 so that there are no gaps between each
arc. The arc method uses a [bresenham algorithm][bres] to plot arc. The arc method uses a [bresenham algorithm][bres] to plot
@ -1652,7 +1655,7 @@ To draw a 1/4 circle (top right quadrant only) with a radius of 10 and stroke wi
orientation: 'vertical', orientation: 'vertical',
stack: 1, stack: 1,
fill: false fill: false
}); } );
![arc example 1](img/arcex1.png) ![arc example 1](img/arcex1.png)
@ -1715,7 +1718,7 @@ To create a free-standing sign...
... to create a wall mounted sign... ... to create a wall mounted sign...
drone.sign(["Welcome","to","Scriptopia"], 68); drone.sign(["Welcome","to","Scriptopia"], 68 );
![wall sign](img/signex2.png) ![wall sign](img/signex2.png)
@ -1730,13 +1733,13 @@ To create a free-standing sign...
To create 4 trees in a row, point the cross-hairs at the ground then type `/js ` and ... To create 4 trees in a row, point the cross-hairs at the ground then type `/js ` and ...
up().oak().right(8).spruce().right(8).birch().right(8).jungle(); up( ).oak( ).right(8 ).spruce( ).right(8 ).birch( ).right(8 ).jungle( );
Trees won't always generate unless the conditions are right. You Trees won't always generate unless the conditions are right. You
should use the tree methods when the drone is directly above the should use the tree methods when the drone is directly above the
ground. Trees will usually grow if the drone's current location is ground. Trees will usually grow if the drone's current location is
occupied by Air and is directly above an area of grass (That is why occupied by Air and is directly above an area of grass (That is why
the `up()` method is called first). the `up( )` method is called first).
![tree example](img/treeex1.png) ![tree example](img/treeex1.png)
@ -1795,7 +1798,7 @@ pasting the copied area elsewhere...
#### Example #### Example
drone.copy('somethingCool',10,5,10).right(12).paste('somethingCool'); drone.copy('somethingCool',10,5,10 ).right(12 ).paste('somethingCool' );
### Drone.paste() method ### Drone.paste() method
@ -1807,9 +1810,9 @@ To copy a 10x5x10 area (using the drone's coordinates as the starting
point) into memory. the copied area can be referenced using the name point) into memory. the copied area can be referenced using the name
'somethingCool'. The drone moves 12 blocks right then pastes the copy. 'somethingCool'. The drone moves 12 blocks right then pastes the copy.
drone.copy('somethingCool',10,5,10) drone.copy('somethingCool',10,5,10 )
.right(12) .right(12 )
.paste('somethingCool'); .paste('somethingCool' );
### Chaining ### Chaining
@ -1866,9 +1869,9 @@ Use this method to add new methods (which also become chainable global functions
#### Example #### Example
// submitted by [edonaldson][edonaldson] // submitted by [edonaldson][edonaldson]
Drone.extend('pyramid', function(block,height){ Drone.extend('pyramid', function( block,height) {
this.chkpt('pyramid'); this.chkpt('pyramid');
for (var i = height; i > 0; i -= 2) { for ( var i = height; i > 0; i -= 2) {
this.box(block, i, 1, i).up().right().fwd(); this.box(block, i, 1, i).up().right().fwd();
} }
return this.move('pyramid'); return this.move('pyramid');
@ -1931,7 +1934,7 @@ Say you want to do the same thing over and over. You have a couple of options...
* You can use a for loop... * You can use a for loop...
d = new Drone(); for (var i =0;i < 4; i++){ d.cottage().right(8); } d = new Drone(); for ( var i =0;i < 4; i++) { d.cottage().right(8); }
While this will fit on the in-game prompt, it's awkward. You need to While this will fit on the in-game prompt, it's awkward. You need to
declare a new Drone object first, then write a for loop to create the declare a new Drone object first, then write a for loop to create the
@ -1940,7 +1943,7 @@ syntax for what should really be simple.
* You can use a while loop... * You can use a while loop...
d = new Drone(); var i=4; while (i--){ d.cottage().right(8); } d = new Drone(); var i=4; while (i--) { d.cottage().right(8); }
... which is slightly shorter but still too much syntax. Each of the ... which is slightly shorter but still too much syntax. Each of the
above statements is fine for creating a 1-dimensional array of above statements is fine for creating a 1-dimensional array of
@ -2218,9 +2221,9 @@ This example demonstrates adding and using parameters in commands.
This differs from example 3 in that the greeting can be changed from This differs from example 3 in that the greeting can be changed from
a fixed 'Hello ' to anything you like by passing a parameter. a fixed 'Hello ' to anything you like by passing a parameter.
command('hello-params', function (parameters, player) { command( 'hello-params', function ( parameters, player ) {
var salutation = parameters[0] ; var salutation = parameters[0] ;
player.sendMessage( salutation + ' ' + player.name); player.sendMessage( salutation + ' ' + player.name );
}); });
## Example Plugin #5 - Re-use - Using your own and others modules. ## Example Plugin #5 - Re-use - Using your own and others modules.
@ -2253,8 +2256,8 @@ this example, we use that module...
Source Code... Source Code...
var greetings = require('./example-1-hello-module'); var greetings = require('./example-1-hello-module');
command('hello-module', function( parameters, player ){ command( 'hello-module', function( parameters, player ) {
greetings.hello(player); greetings.hello( player );
}); });
## Example Plugin #6 - Re-use - Using 'utils' to get Player objects. ## Example Plugin #6 - Re-use - Using 'utils' to get Player objects.
@ -2290,13 +2293,14 @@ Source Code ...
var utils = require('utils'); var utils = require('utils');
var greetings = require('./example-1-hello-module'); var greetings = require('./example-1-hello-module');
command('hello-byname', function( parameters, sender ) { command( 'hello-byname', function( parameters, sender ) {
var playerName = parameters[0]; var playerName = parameters[0];
var recipient = utils.player(playerName); var recipient = utils.player( playerName );
if (recipient) if ( recipient ) {
greetings.hello(recipient); greetings.hello( recipient );
else } else {
sender.sendMessage('Player ' + playerName + ' not found.'); sender.sendMessage( 'Player ' + playerName + ' not found.' );
}
}); });
## Example Plugin #7 - Listening for events, Greet players when they join the game. ## Example Plugin #7 - Listening for events, Greet players when they join the game.
@ -2379,10 +2383,10 @@ cleaner and more readable. Similarly where you see a method like
[bksaf]: http://jd.bukkit.org/dev/apidocs/org/bukkit/entity/Player.html#setAllowFlight() [bksaf]: http://jd.bukkit.org/dev/apidocs/org/bukkit/entity/Player.html#setAllowFlight()
[bkapi]: http://jd.bukkit.org/dev/apidocs/ [bkapi]: http://jd.bukkit.org/dev/apidocs/
events.on('player.PlayerJoinEvent', function (listener, event){ events.on( 'player.PlayerJoinEvent', function( listener, event ) {
if (event.player.op) { if ( event.player.op ) {
event.player.sendMessage('Welcome to ' + __plugin); event.player.sendMessage('Welcome to ' + __plugin);
} }
}); });
## Arrows Plugin ## Arrows Plugin
@ -2506,11 +2510,11 @@ to every student in a Minecraft classroom environment.
To allow all players (and any players who connect to the server) to To allow all players (and any players who connect to the server) to
use the `js` and `jsp` commands... use the `js` and `jsp` commands...
/js classroom.allowScripting(true,self) /js classroom.allowScripting( true, self )
To disallow scripting (and prevent players who join the server from using the commands)... To disallow scripting (and prevent players who join the server from using the commands)...
/js classroom.allowScripting(false,self) /js classroom.allowScripting( false, self )
Only ops users can run the classroom.allowScripting() function - this is so that students 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. don't try to bar themselves and each other from scripting.

View file

@ -2,45 +2,53 @@
/* /*
command management - allow for non-ops to execute approved javascript code. command management - allow for non-ops to execute approved javascript code.
*/ */
var _commands = {}; var _commands = {},
var _cmdInterceptors = []; _cmdInterceptors = [];
/* /*
execute a JSP command. execute a JSP command.
*/ */
var executeCmd = function(args, player){ var executeCmd = function( args, player ) {
if (args.length === 0) var name,
cmd,
intercepted,
result = null;
if ( args.length === 0 ) {
throw new Error('Usage: jsp command-name command-parameters'); throw new Error('Usage: jsp command-name command-parameters');
var name = args[0]; }
var cmd = _commands[name]; name = args[0];
if (typeof cmd === 'undefined'){ cmd = _commands[name];
if ( typeof cmd === 'undefined' ) {
// it's not a global command - pass it on to interceptors // it's not a global command - pass it on to interceptors
var intercepted = false; intercepted = false;
for (var i = 0;i < _cmdInterceptors.length;i++){ for ( var i = 0; i < _cmdInterceptors.length; i++ ) {
if (_cmdInterceptors[i](args,player)) if ( _cmdInterceptors[i]( args, player ) )
intercepted = true; intercepted = true;
} }
if (!intercepted) if ( !intercepted ) {
console.warn('Command %s is not recognised',name); console.warn( 'Command %s is not recognised', name );
}
}else{ }else{
var result = null;
try { try {
result = cmd.callback(args.slice(1),player); result = cmd.callback( args.slice(1), player );
}catch (e){ } catch ( e ) {
console.error('Error while trying to execute command: ' + JSON.stringify(args)); console.error( 'Error while trying to execute command: ' + JSON.stringify( args ) );
throw e; throw e;
} }
return result;
} }
return result;
}; };
/* /*
define a new JSP command. define a new JSP command.
*/ */
var defineCmd = function(name, func, options, intercepts) { var defineCmd = function( name, func, options, intercepts ) {
if (typeof options == 'undefined') if ( typeof options == 'undefined' ) {
options = []; options = [];
_commands[name] = {callback: func, options: options}; }
if (intercepts) _commands[name] = { callback: func, options: options };
if ( intercepts ) {
_cmdInterceptors.push(func); _cmdInterceptors.push(func);
}
return func; return func;
}; };
exports.command = defineCmd; exports.command = defineCmd;

View file

@ -35,35 +35,39 @@ ScriptCraft uses Java's [String.format()][strfmt] so any string substitution ide
[webcons]: https://developer.mozilla.org/en-US/docs/Web/API/console [webcons]: https://developer.mozilla.org/en-US/docs/Web/API/console
***/ ***/
var logger = __plugin.logger; var logger = __plugin.logger,
var argsToArray = function(args){ logMethodName = 'log(java.util.logging.Level,java.lang.String)';
var result = []; var argsToArray = function( args ) {
for (var i =0;i < args.length; i++) var result = [];
result.push(args[i]); for ( var i =0; i < args.length; i++ ) {
return result; result.push(args[i]);
}
return result;
} }
var log = function(level, restOfArgs){ var log = function( level, restOfArgs ) {
var args = argsToArray(restOfArgs); var args = argsToArray( restOfArgs );
if (args.length > 1){ if ( args.length > 1 ) {
var msg = java.lang.String.format(args[0],args.slice(1)); var msg = java.lang.String.format( args[0], args.slice(1) );
logger['log(java.util.logging.Level,java.lang.String)'](level,msg); logger[logMethodName]( level, msg );
}else{ } else {
logger['log(java.util.logging.Level,java.lang.String)'](level, args[0]); logger[logMethodName]( level, args[0] );
} }
}; };
var Level = java.util.logging.Level; var Level = java.util.logging.Level;
exports.log = function(){ exports.log = function( ) {
log(Level.INFO, arguments); log( Level.INFO, arguments );
}; };
exports.info = function(){ exports.info = function( ) {
log(Level.INFO, arguments); log( Level.INFO, arguments );
}
exports.warn = function(){
log(Level.WARNING, arguments);
}; };
exports.error = function(){
log(Level.SEVERE, arguments); exports.warn = function( ) {
log( Level.WARNING, arguments );
};
exports.error = function( ) {
log( Level.SEVERE, arguments );
}; };

View file

@ -75,53 +75,55 @@ To listen for events using a full class name as the `eventName` parameter...
***/ ***/
var bkEvent = org.bukkit.event; var bkEvent = org.bukkit.event,
var bkEvtExecutor = org.bukkit.plugin.EventExecutor; bkEvtExecutor = org.bukkit.plugin.EventExecutor,
var bkRegListener = org.bukkit.plugin.RegisteredListener; bkRegListener = org.bukkit.plugin.RegisteredListener;
exports.on = function( exports.on = function(
/* String or java Class */ /* String or java Class */
eventType, eventType,
/* function( registeredListener, event) */ /* function( registeredListener, event) */
handler, handler,
/* (optional) String (HIGH, HIGHEST, LOW, LOWEST, NORMAL, MONITOR), */ /* (optional) String (HIGH, HIGHEST, LOW, LOWEST, NORMAL, MONITOR), */
priority ) { priority ) {
var handlerList,
listener = {},
eventExecutor;
if (typeof priority == "undefined"){ if ( typeof priority == 'undefined' ) {
priority = bkEvent.EventPriority.HIGHEST; priority = bkEvent.EventPriority.HIGHEST;
}else{ } else {
priority = bkEvent.EventPriority[priority]; priority = bkEvent.EventPriority[priority];
}
if ( typeof eventType == 'string' ) {
/*
Nashorn doesn't support bracket notation for accessing packages.
E.g. java.net will work but java['net'] won't.
https://bugs.openjdk.java.net/browse/JDK-8031715
*/
if ( typeof Java != 'undefined' ) {
// nashorn environment
eventType = Java.type( 'org.bukkit.event.' + eventType );
} else {
eventType = eval( 'org.bukkit.event.' + eventType );
} }
if (typeof eventType == "string"){ }
/* handlerList = eventType.getHandlerList( );
Nashorn doesn't support bracket notation for accessing packages. eventExecutor = new bkEvtExecutor( ) {
E.g. java.net will work but java['net'] won't. execute: function( l, e ) {
handler( listener.reg, e );
https://bugs.openjdk.java.net/browse/JDK-8031715 }
*/ };
if (typeof Java != 'undefined'){ /*
// nashorn environment wph 20130222 issue #64 bad interaction with Essentials plugin
eventType = Java.type('org.bukkit.event.' + eventType); if another plugin tries to unregister a Listener (not a Plugin or a RegisteredListener)
} else { then BOOM! the other plugin will throw an error because Rhino can't coerce an
eventType = eval('org.bukkit.event.' + eventType); equals() method from an Interface.
} The workaround is to make the ScriptCraftPlugin java class a Listener.
} Should only unregister() registered plugins in ScriptCraft js code.
var handlerList = eventType.getHandlerList(); */
var listener = {}; listener.reg = new bkRegListener( __plugin, eventExecutor, priority, __plugin, true );
var eventExecutor = new bkEvtExecutor(){ handlerList.register( listener.reg );
execute: function(l,e){ return listener.reg;
handler(listener.reg,e);
}
};
/*
wph 20130222 issue #64 bad interaction with Essentials plugin
if another plugin tries to unregister a Listener (not a Plugin or a RegisteredListener)
then BOOM! the other plugin will throw an error because Rhino can't coerce an
equals() method from an Interface.
The workaround is to make the ScriptCraftPlugin java class a Listener.
Should only unregister() registered plugins in ScriptCraft js code.
*/
listener.reg = new bkRegListener( __plugin, eventExecutor, priority, __plugin, true);
handlerList.register(listener.reg);
return listener.reg;
}; };

View file

@ -1,33 +1,36 @@
module.exports = function($){ module.exports = function( $ ) {
// wph 20140105 trim not availabe in String on Mac OS. // wph 20140105 trim not availabe in String on Mac OS.
if (typeof String.prototype.trim == 'undefined'){ if ( typeof String.prototype.trim == 'undefined' ) {
String.prototype.trim = function(){ String.prototype.trim = function( ) {
return this.replace(/^\s+|\s+$/g,''); return this.replace( /^\s+|\s+$/g, '' );
}; };
} }
$.setTimeout = function( callback, delayInMillis){ $.setTimeout = function( callback, delayInMillis ) {
/* /*
javascript programmers familiar with setTimeout know that it expects javascript programmers familiar with setTimeout know that it expects
a delay in milliseconds. However, bukkit's scheduler expects a delay in ticks a delay in milliseconds. However, bukkit's scheduler expects a delay in ticks
(where 1 tick = 1/20th second) (where 1 tick = 1/20th second)
*/ */
var bukkitTask = server.scheduler.runTaskLater(__plugin, callback, delayInMillis/50); var bukkitTask = server.scheduler.runTaskLater( __plugin, callback, delayInMillis/50 );
return bukkitTask; return bukkitTask;
}; };
$.clearTimeout = function(bukkitTask){
bukkitTask.cancel(); $.clearTimeout = function( bukkitTask ) {
}; bukkitTask.cancel();
};
$.setInterval = function(callback, intervalInMillis){ $.setInterval = function( callback, intervalInMillis ) {
var delay = intervalInMillis/ 50; var delay = intervalInMillis/ 50;
var bukkitTask = server.scheduler.runTaskTimer(__plugin, callback, delay, delay); var bukkitTask = server.scheduler.runTaskTimer( __plugin, callback, delay, delay );
return bukkitTask; return bukkitTask;
}; };
$.clearInterval = function(bukkitTask){
bukkitTask.cancel(); $.clearInterval = function( bukkitTask ) {
}; bukkitTask.cancel();
};
}; };

View file

@ -1,37 +1,50 @@
var _dataDir = null,
_persistentData = {};
var _dataDir = null; module.exports = function( rootDir, $ ) {
var _persistentData = {};
module.exports = function( rootDir, $ ){ var _load = function( name ) {
$.scload( _dataDir.canonicalPath + '/' + name + '-store.json' );
};
var _save = function( name, data ) {
$.scsave( data, _dataDir.canonicalPath + '/' + name + '-store.json' );
};
_dataDir = new java.io.File( rootDir, 'data'); _dataDir = new java.io.File( rootDir, 'data' );
$.persist = function(name, data, write){ $.persist = function( name, data, write ) {
var i, dataFromFile; var i,
if (typeof data == 'undefined') dataFromFile;
data = {}; if ( typeof data == 'undefined' ) {
if (typeof write == 'undefined') data = {};
write = false; }
if (!write){ if ( typeof write == 'undefined' ) {
dataFromFile = $.scload(_dataDir.canonicalPath + '/' + name + '-store.json'); write = false;
if (dataFromFile){ }
for (i in dataFromFile){ if ( !write ) {
data[i] = dataFromFile[i]; dataFromFile = _load( name );
} if ( dataFromFile ) {
} for ( i in dataFromFile ) {
}else{ data[i] = dataFromFile[i];
// flush data to file
$.scsave(data, _dataDir.canonicalPath + '/' + name + '-store.json');
} }
_persistentData[name] = data; }
return data; } else {
}; // flush data to file
_save( name, data );
$.addUnloadHandler(function(){ }
for (var name in _persistentData){ _persistentData[name] = data;
var data = _persistentData[name]; return data;
$.scsave(data, _dataDir.canonicalPath + '/' + name + '-store.json'); };
} /*
}); persist on shutdown
*/
$.addUnloadHandler( function( ) {
var name,
data;
for ( name in _persistentData ) {
data = _persistentData[name];
_save( name, data );
}
});
}; };

View file

@ -1,4 +1,5 @@
'use strict'; 'use strict';
var console = require('./console'), var console = require('./console'),
File = java.io.File, File = java.io.File,
FileWriter = java.io.FileWriter, FileWriter = java.io.FileWriter,
@ -8,22 +9,22 @@ var console = require('./console'),
*/ */
var _plugins = {}; var _plugins = {};
var _plugin = function(/* String */ moduleName, /* Object */ moduleObject, isPersistent) var _plugin = function(/* String */ moduleName, /* Object */ moduleObject, isPersistent ) {
{
// //
// don't load plugin more than once // don't load plugin more than once
// //
if (typeof _plugins[moduleName] != 'undefined') if ( typeof _plugins[moduleName] != 'undefined' ) {
return _plugins[moduleName].module; return _plugins[moduleName].module;
}
var pluginData = {persistent: isPersistent, module: moduleObject}; var pluginData = { persistent: isPersistent, module: moduleObject };
if (typeof moduleObject.store == 'undefined') if ( typeof moduleObject.store == 'undefined' ) {
moduleObject.store = {}; moduleObject.store = {};
}
_plugins[moduleName] = pluginData; _plugins[moduleName] = pluginData;
if (isPersistent){ if ( isPersistent ) {
moduleObject.store = persist(moduleName, moduleObject.store); moduleObject.store = persist( moduleName, moduleObject.store );
} }
return moduleObject; return moduleObject;
}; };
@ -34,30 +35,31 @@ var scriptCraftDir = null;
var pluginDir = null; var pluginDir = null;
var dataDir = null; var dataDir = null;
exports.autoload = function(dir,logger) { exports.autoload = function( dir, logger ) {
scriptCraftDir = dir; scriptCraftDir = dir;
pluginDir = new File(dir, 'plugins'); pluginDir = new File( dir, 'plugins' );
dataDir = new File(dir, 'data'); dataDir = new File( dir, 'data' );
var _canonize = function(file){ var _canonize = function( file ) {
return '' + file.canonicalPath.replaceAll('\\\\','/'); return '' + file.canonicalPath.replaceAll('\\\\','/');
}; };
/* /*
recursively walk the given directory and return a list of all .js files recursively walk the given directory and return a list of all .js files
*/ */
var _listSourceFiles = function(store,dir) var _listSourceFiles = function( store, dir ) {
{ var files = dir.listFiles(),
var files = dir.listFiles(); file;
if (!files) if ( !files ) {
return; return;
for (var i = 0;i < files.length; i++) { }
var file = files[i]; for ( var i = 0; i < files.length; i++ ) {
if (file.isDirectory()){ file = files[i];
_listSourceFiles(store,file); if ( file.isDirectory( ) ) {
_listSourceFiles( store, file );
}else{ }else{
if ( file.canonicalPath.endsWith('.js') ){ if ( file.canonicalPath.endsWith( '.js' ) ) {
store.push(file); store.push( file );
} }
} }
} }
@ -65,30 +67,33 @@ exports.autoload = function(dir,logger) {
/* /*
Reload all of the .js files in the given directory Reload all of the .js files in the given directory
*/ */
var _reload = function(pluginDir) (function( pluginDir ) {
{ var sourceFiles = [],
var sourceFiles = []; property,
_listSourceFiles(sourceFiles,pluginDir); module,
pluginPath;
_listSourceFiles( sourceFiles, pluginDir );
var len = sourceFiles.length; var len = sourceFiles.length;
if (config.verbose) if ( config.verbose ) {
console.info(len + ' scriptcraft plugins found.'); console.info( len + ' scriptcraft plugins found.' );
for (var i = 0;i < len; i++){ }
var pluginPath = _canonize(sourceFiles[i]); for ( var i = 0; i < len; i++ ) {
var module = {}; pluginPath = _canonize( sourceFiles[i] );
module = {};
try { try {
module = require(pluginPath); module = require( pluginPath );
for (var property in module){ for ( property in module ) {
/* /*
all exports in plugins become global all exports in plugins become global
*/ */
global[property] = module[property]; global[property] = module[property];
} }
}catch (e){ } catch ( e ) {
logger.severe('Plugin ' + pluginPath + ' ' + e); logger.severe( 'Plugin ' + pluginPath + ' ' + e );
} }
} }
}; }(pluginDir));
_reload(pluginDir);
}; };

View file

@ -54,46 +54,45 @@ module specification, the '.js' suffix is optional.
[cjsmodules]: http://wiki.commonjs.org/wiki/Modules/1.1.1. [cjsmodules]: http://wiki.commonjs.org/wiki/Modules/1.1.1.
***/ ***/
(function (rootDir, modulePaths, hooks) { (function ( rootDir, modulePaths, hooks ) {
var File = java.io.File; var File = java.io.File;
var readModuleFromDirectory = function(dir){ var readModuleFromDirectory = function( dir ) {
// look for a package.json file // look for a package.json file
var pkgJsonFile = new File(dir, './package.json'); var pkgJsonFile = new File( dir, './package.json' );
if (pkgJsonFile.exists()){ if ( pkgJsonFile.exists() ) {
var pkg = scload(pkgJsonFile); var pkg = scload( pkgJsonFile );
var mainFile = new File(dir, pkg.main); var mainFile = new File( dir, pkg.main );
if (mainFile.exists()){ if ( mainFile.exists() ) {
return mainFile; return mainFile;
} else { } else {
return null; return null;
} }
}else{ } else {
// look for an index.js file // look for an index.js file
var indexJsFile = new File(dir + './index.js'); var indexJsFile = new File( dir + './index.js' );
if (indexJsFile.exists()){ if ( indexJsFile.exists() ) {
return indexJsFile; return indexJsFile;
} else { } else {
return null; return null;
} }
} }
}; };
var fileExists = function(file) { var fileExists = function( file ) {
if (file.isDirectory()){ if ( file.isDirectory() ) {
return readModuleFromDirectory(file); return readModuleFromDirectory( file );
}else { } else {
return file; return file;
} }
}; };
var _canonize = function(file){ var _canonize = function(file){
return "" + file.canonicalPath.replaceAll("\\\\","/"); return "" + file.canonicalPath.replaceAll("\\\\","/");
}; };
var resolveModuleToFile = function(moduleName, parentDir) {
/********************************************************************** /**********************************************************************
### module name resolution ### module name resolution
@ -128,48 +127,49 @@ When resolving module names to file paths, ScriptCraft uses the following rules.
3.2 if no package.json file exists then look for an index.js file in the directory 3.2 if no package.json file exists then look for an index.js file in the directory
***/ ***/
var file = new File(moduleName); var resolveModuleToFile = function ( moduleName, parentDir ) {
var file = new File(moduleName);
if (file.exists()){ if ( file.exists() ) {
return fileExists(file); return fileExists(file);
}
if ( moduleName.match( /^[^\.\/]/ ) ) {
// it's a module named like so ... 'events' , 'net/http'
//
var resolvedFile;
for (var i = 0;i < modulePaths.length; i++){
resolvedFile = new File(modulePaths[i] + moduleName);
if (resolvedFile.exists()){
return fileExists(resolvedFile);
}else{
// try appending a .js to the end
resolvedFile = new File(modulePaths[i] + moduleName + '.js');
if (resolvedFile.exists())
return resolvedFile;
} }
if (moduleName.match(/^[^\.\/]/)){ }
// it's a module named like so ... 'events' , 'net/http' } else {
// // it's of the form ./path
var resolvedFile; file = new File(parentDir, moduleName);
for (var i = 0;i < modulePaths.length; i++){ if (file.exists()){
resolvedFile = new File(modulePaths[i] + moduleName); return fileExists(file);
if (resolvedFile.exists()){ }else {
return fileExists(resolvedFile);
}else{
// try appending a .js to the end
resolvedFile = new File(modulePaths[i] + moduleName + '.js');
if (resolvedFile.exists())
return resolvedFile;
}
}
} else {
// it's of the form ./path
file = new File(parentDir, moduleName);
if (file.exists()){
return fileExists(file);
}else {
// try appending a .js to the end // try appending a .js to the end
var pathWithJSExt = file.canonicalPath + '.js'; var pathWithJSExt = file.canonicalPath + '.js';
file = new File( parentDir, pathWithJSExt); file = new File( parentDir, pathWithJSExt);
if (file.exists()) if (file.exists())
return file; return file;
else{ else{
file = new File(pathWithJSExt); file = new File(pathWithJSExt);
if (file.exists()) if (file.exists())
return file; return file;
}
}
} }
return null;
}; }
}
return null;
};
/* /*
wph 20131215 Experimental wph 20131215 Experimental
*/ */

View file

@ -413,238 +413,257 @@ var server = org.bukkit.Bukkit.server;
/* /*
private implementation private implementation
*/ */
function __onEnable (__engine, __plugin, __script) function __onEnable ( __engine, __plugin, __script )
{ {
var File = java.io.File var File = java.io.File,
,FileReader = java.io.FileReader FileReader = java.io.FileReader,
,BufferedReader = java.io.BufferedReader BufferedReader = java.io.BufferedReader,
,PrintWriter = java.io.PrintWriter PrintWriter = java.io.PrintWriter,
,FileWriter = java.io.FileWriter; FileWriter = java.io.FileWriter;
var _canonize = function(file){ var _canonize = function( file ) {
return "" + file.getCanonicalPath().replaceAll("\\\\","/"); return '' + file.getCanonicalPath().replaceAll( '\\\\', '/' );
}; };
// lib (assumes scriptcraft.js is in craftbukkit/plugins/scriptcraft/lib directory
var libDir = __script.parentFile; // lib (assumes scriptcraft.js is in craftbukkit/plugins/scriptcraft/lib directory var libDir = __script.parentFile,
var jsPluginsRootDir = libDir.parentFile; // scriptcraft jsPluginsRootDir = libDir.parentFile, // scriptcraft
var jsPluginsRootDirName = _canonize(jsPluginsRootDir); jsPluginsRootDirName = _canonize(jsPluginsRootDir),
var logger = __plugin.logger; logger = __plugin.logger;
/* /*
Save a javascript object to a file (saves using JSON notation) Save a javascript object to a file (saves using JSON notation)
*/ */
var _save = function(object, filename){ var _save = function( object, filename ) {
var objectToStr = null; var objectToStr = null,
try{ f,
objectToStr = JSON.stringify(object,null,2); out;
}catch(e){ try {
print("ERROR: " + e.getMessage() + " while saving " + filename); objectToStr = JSON.stringify( object, null, 2 );
return; } catch( e ) {
} print( 'ERROR: ' + e.getMessage() + ' while saving ' + filename );
var f = (filename instanceof File) ? filename : new File(filename); return;
var out = new PrintWriter(new FileWriter(f));
out.println( objectToStr );
out.close();
};
/*
make sure eval is present
*/
if (typeof eval == 'undefined'){
global.eval = function(str){
return __engine.eval(str);
};
} }
f = (filename instanceof File) ? filename : new File(filename);
/* out = new PrintWriter(new FileWriter(f));
Load the contents of the file and evaluate as javascript out.println( objectToStr );
*/ out.close();
var _load = function(filename,warnOnFileNotFound) };
/*
make sure eval is present
*/
if ( typeof eval == 'undefined' ) {
global.eval = function( str ) {
return __engine.eval( str );
};
}
/*
Load the contents of the file and evaluate as javascript
*/
var _load = function( filename, warnOnFileNotFound )
{
var result = null,
file = filename,
r,
parent,
reader,
br,
code,
wrappedCode;
if ( !( filename instanceof File ) ) {
file = new File(filename);
}
var canonizedFilename = _canonize( file );
if ( file.exists() ) {
parent = file.getParentFile();
reader = new FileReader( file );
br = new BufferedReader( reader );
code = '';
try {
while ( (r = br.readLine()) !== null ) {
code += r + '\n';
}
wrappedCode = '(' + code + ')';
result = __engine.eval( wrappedCode );
// issue #103 avoid side-effects of || operator on Mac Rhino
} catch ( e ) {
logger.severe( 'Error evaluating ' + canonizedFilename + ', ' + e );
}
finally {
try {
reader.close();
} catch ( re ) {
// fail silently on reader close error
}
}
} else {
if ( warnOnFileNotFound ) {
logger.warning( canonizedFilename + ' not found' );
}
}
return result;
};
/*
now that load is defined, use it to load a global config object
*/
var config = _load( new File(jsPluginsRootDir, 'data/global-config.json' ) );
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.
*/
(function(){
var jsonFileReader = new FileReader( new File( jsPluginsRootDirName + '/lib/json2.js' ) );
var jsonLoaded = __engine['eval(java.io.Reader)']( jsonFileReader );
}());
/*
Unload Handlers
*/
var unloadHandlers = [];
var _addUnloadHandler = function( f ) {
unloadHandlers.push( f );
};
var _runUnloadHandlers = function() {
for ( var i = 0; i < unloadHandlers.length; i++ ) {
unloadHandlers[i]( );
}
};
global.addUnloadHandler = _addUnloadHandler;
global.refresh = function( ) {
__plugin.pluginLoader.disablePlugin( __plugin );
__plugin.pluginLoader.enablePlugin( __plugin );
};
var _echo = function ( msg ) {
if ( typeof self == 'undefined' ) {
return;
}
self.sendMessage( msg );
};
global.echo = _echo;
global.alert = _echo;
global.scload = _load;
global.scsave = _save;
var configRequire = _load( jsPluginsRootDirName + '/lib/require.js', true );
/*
setup paths to search for modules
*/
var modulePaths = [ jsPluginsRootDirName + '/lib/',
jsPluginsRootDirName + '/modules/' ];
if ( config.verbose ) {
logger.info( 'Setting up CommonJS-style module system. Root Directory: ' + jsPluginsRootDirName );
logger.info( 'Module paths: ' + JSON.stringify(modulePaths) );
}
var requireHooks = {
loading: function( path ) {
if ( config.verbose ) {
logger.info( 'loading ' + path );
}
},
loaded: function( path ) {
if ( config.verbose ) {
logger.info( 'loaded ' + path );
}
}
};
global.require = configRequire( jsPluginsRootDirName, modulePaths, requireHooks );
require('js-patch')( global );
global.console = require('console');
/*
setup persistence
*/
require('persistence')( jsPluginsRootDir, global );
var cmdModule = require('command');
global.command = cmdModule.command;
var plugins = require('plugin');
global.__onTabComplete = require('tabcomplete');
global.plugin = plugins.plugin;
var events = require('events');
events.on( 'server.PluginDisableEvent', function( l, e ) {
// save config
_save( global.config, new File( jsPluginsRootDir, 'data/global-config.json' ) );
_runUnloadHandlers();
org.bukkit.event.HandlerList['unregisterAll(org.bukkit.plugin.Plugin)'](__plugin);
});
// wph 20131226 - make events global as it is used by many plugins/modules
global.events = events;
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')
{ {
var result = null result = true;
,file = filename var fnBody = jsArgs.join(' ');
,r = undefined; global.self = sender;
global.__engine = __engine;
if (!(filename instanceof File)) try {
file = new File(filename); var jsResult = __engine.eval(fnBody);
if ( jsResult ) {
var canonizedFilename = _canonize(file); sender.sendMessage(jsResult);
}
if (file.exists()) { } catch ( e ) {
var parent = file.getParentFile(); logger.severe( 'Error while trying to evaluate javascript: ' + fnBody + ', Error: '+ e );
var reader = new FileReader(file); throw e;
var br = new BufferedReader(reader); } finally {
var code = ""; delete global.self;
var wrappedCode; delete global.__engine;
try{ }
while ((r = br.readLine()) !== null)
code += r + "\n";
wrappedCode = "(" + code + ")";
result = __engine.eval(wrappedCode);
// issue #103 avoid side-effects of || operator on Mac Rhino
}catch (e){
logger.severe("Error evaluating " + canonizedFilename + ", " + e );
}
finally {
try {
reader.close();
}catch (re){
// fail silently on reader close error
}
}
}else{
if (warnOnFileNotFound)
logger.warning(canonizedFilename + " not found");
}
return result;
};
/*
now that load is defined, use it to load a global config object
*/
var config = _load(new File(jsPluginsRootDir, 'data/global-config.json' ));
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.
*/
var jsonLoaded = __engine["eval(java.io.Reader)"](new FileReader(new File(jsPluginsRootDirName + '/lib/json2.js')));
/*
Unload Handlers
*/
var unloadHandlers = [];
var _addUnloadHandler = function(f) {
unloadHandlers.push(f);
};
var _runUnloadHandlers = function() {
for (var i = 0; i < unloadHandlers.length; i++) {
unloadHandlers[i]();
}
};
global.refresh = function(){
__plugin.pluginLoader.disablePlugin(__plugin);
__plugin.pluginLoader.enablePlugin(__plugin);
};
var _echo = function (msg) {
if (typeof self == "undefined"){
return;
}
self.sendMessage(msg);
};
global.echo = _echo;
global.alert = _echo;
global.scload = _load;
global.scsave = _save;
global.addUnloadHandler = _addUnloadHandler;
var configRequire = _load(jsPluginsRootDirName + '/lib/require.js',true);
/*
setup paths to search for modules
*/
var modulePaths = [jsPluginsRootDirName + '/lib/',
jsPluginsRootDirName + '/modules/'];
if (config.verbose){
logger.info('Setting up CommonJS-style module system. Root Directory: ' + jsPluginsRootDirName);
logger.info('Module paths: ' + JSON.stringify(modulePaths));
} }
var requireHooks = { if ( cmdName == 'jsp' ) {
loading: function(path){ cmdModule.exec( jsArgs, sender );
if (config.verbose) result = true;
logger.info('loading ' + path);
},
loaded: function(path){
if (config.verbose)
logger.info('loaded ' + path);
}
};
global.require = configRequire(jsPluginsRootDirName, modulePaths,requireHooks );
require('js-patch')(global);
global.console = require('console');
/*
setup persistence
*/
require('persistence')(jsPluginsRootDir,global);
var cmdModule = require('command');
global.command = cmdModule.command;
var plugins = require('plugin');
global.__onTabComplete = require('tabcomplete');
global.plugin = plugins.plugin;
var events = require('events');
events.on('server.PluginDisableEvent',function(l,e){
// save config
_save(global.config, new File(jsPluginsRootDir, 'data/global-config.json' ));
_runUnloadHandlers();
org.bukkit.event.HandlerList['unregisterAll(org.bukkit.plugin.Plugin)'](__plugin);
});
// wph 20131226 - make events global as it is used by many plugins/modules
global.events = events;
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(fnBody);
if (jsResult)
sender.sendMessage(jsResult);
}catch (e){
logger.severe("Error while trying to evaluate javascript: " + fnBody + ", Error: "+ e);
throw e;
}finally{
delete global.self;
delete global.__engine;
}
}
if (cmdName == 'jsp'){
cmdModule.exec(jsArgs, sender);
result = true;
}
return result;
};
plugins.autoload(jsPluginsRootDir,logger);
/*
wph 20140102 - warn if legacy 'craftbukkit/js-plugins' or 'craftbukkit/scriptcraft' directories are present
*/
var cbPluginsDir = jsPluginsRootDir.parentFile;
var cbDir = new File(cbPluginsDir.canonicalPath).parentFile;
var legacyDirs = [
new File(cbDir, 'js-plugins'),
new File(cbDir, 'scriptcraft')
];
var legacyExists = false;
for (var i = 0; i < legacyDirs.length; i++){
if (legacyDirs[i].exists() && legacyDirs[i].isDirectory()){
legacyExists = true;
console.warn('Legacy ScriptCraft directory %s was found. This directory is no longer used.',
legacyDirs[i].canonicalPath);
}
} }
if (legacyExists){ return result;
console.info('Please note that the working directory for %s is %s', };
__plugin, jsPluginsRootDir.canonicalPath);
plugins.autoload( jsPluginsRootDir, logger );
/*
wph 20140102 - warn if legacy 'craftbukkit/js-plugins' or 'craftbukkit/scriptcraft' directories are present
*/
(function(){
var cbPluginsDir = jsPluginsRootDir.parentFile,
cbDir = new File(cbPluginsDir.canonicalPath).parentFile,
legacyExists = false,
legacyDirs = [new File( cbDir, 'js-plugins' ),
new File( cbDir, 'scriptcraft' )];
for ( var i = 0; i < legacyDirs.length; i++ ) {
if ( legacyDirs[i].exists()
&& legacyDirs[i].isDirectory() ) {
legacyExists = true;
console.warn('Legacy ScriptCraft directory %s was found. This directory is no longer used.',
legacyDirs[i].canonicalPath);
}
} }
if ( legacyExists ) {
console.info( 'Please note that the working directory for %s is %s',
__plugin, jsPluginsRootDir.canonicalPath );
}
})();
} }

View file

@ -3,39 +3,45 @@ var _commands = require('command').commands;
/* /*
Tab completion for the /jsp commmand Tab completion for the /jsp commmand
*/ */
var __onTabCompleteJSP = function( result, cmdSender, pluginCmd, cmdAlias, cmdArgs) { var __onTabCompleteJSP = function( result, cmdSender, pluginCmd, cmdAlias, cmdArgs ) {
var cmdInput = cmdArgs[0]; var cmdInput = cmdArgs[0],
var cmd = _commands[cmdInput]; opts,
if (cmd){ cmd,
var opts = cmd.options; len,
var len = opts.length; i;
if (cmdArgs.length == 1){ cmd = _commands[cmdInput];
for (var i = 0;i < len; i++) if ( cmd ) {
result.add(opts[i]); opts = cmd.options;
}else{ len = opts.length;
// partial e.g. /jsp chat_color dar if ( cmdArgs.length == 1 ) {
for (var i = 0;i < len; i++){ for ( i = 0; i < len; i++ ) {
if (opts[i].indexOf(cmdArgs[1]) == 0){ result.add( opts[i] );
result.add(opts[i]); }
} } else {
} // partial e.g. /jsp chat_color dar
} for ( i = 0; i < len; i++ ) {
}else{ if ( opts[i].indexOf( cmdArgs[1] ) == 0 ) {
if (cmdArgs.length == 0){ result.add( opts[i] );
for (var i in _commands)
result.add(i);
}else{
// partial e.g. /jsp ho
// should tabcomplete to home
//
for (var c in _commands){
if (c.indexOf(cmdInput) == 0){
result.add(c);
}
}
} }
}
} }
return result; } else {
if ( cmdArgs.length == 0 ) {
for ( i in _commands ) {
result.add( i );
}
} else {
// partial e.g. /jsp ho
// should tabcomplete to home
//
for ( i in _commands ) {
if ( i.indexOf( cmdInput ) == 0 ) {
result.add( i );
}
}
}
}
return result;
}; };
module.exports = __onTabCompleteJSP; module.exports = __onTabCompleteJSP;

View file

@ -6,7 +6,7 @@ var tabCompleteJSP = require('tabcomplete-jsp');
var _isJavaObject = function(o){ var _isJavaObject = function(o){
var result = false; var result = false;
try { try {
o.hasOwnProperty("testForJava"); o.hasOwnProperty( 'testForJava' );
}catch (e){ }catch (e){
// java will throw an error when an attempt is made to access the // java will throw an error when an attempt is made to access the
// hasOwnProperty method. (it won't exist for Java objects) // hasOwnProperty method. (it won't exist for Java objects)
@ -15,165 +15,180 @@ var _isJavaObject = function(o){
return result; return result;
}; };
var _javaLangObjectMethods = [ var _javaLangObjectMethods = [
'equals' 'equals'
,'getClass' ,'getClass'
,'class' ,'class'
,'getClass' ,'getClass'
,'hashCode' ,'hashCode'
,'notify' ,'notify'
,'notifyAll' ,'notifyAll'
,'toString' ,'toString'
,'wait' ,'wait'
,'clone' ,'clone'
,'finalize' ,'finalize'
]; ];
var _getProperties = function(o) var _getProperties = function( o ) {
{ var result = [],
var result = []; i,
if (_isJavaObject(o)) j,
{ isObjectMethod,
propertyLoop: typeofProperty;
for (var i in o) if ( _isJavaObject( o ) ) {
{ propertyLoop:
// for ( i in o ) {
// don't include standard Object methods //
// // don't include standard Object methods
var isObjectMethod = false; //
for (var j = 0;j < _javaLangObjectMethods.length; j++) isObjectMethod = false;
if (_javaLangObjectMethods[j] == i) for ( j = 0; j < _javaLangObjectMethods.length; j++ ) {
continue propertyLoop; if ( _javaLangObjectMethods[j] == i ) {
var typeofProperty = null; continue propertyLoop;
try { }
typeofProperty = typeof o[i]; }
}catch( e ){ typeofProperty = null;
if (e.message == 'java.lang.IllegalStateException: Entity not leashed'){ try {
// wph 20131020 fail silently for Entity leashing in craftbukkit typeofProperty = typeof o[i];
}else{ } catch( e ) {
throw e; if ( e.message == 'java.lang.IllegalStateException: Entity not leashed' ) {
} // wph 20131020 fail silently for Entity leashing in craftbukkit
} } else {
if (typeofProperty == 'function' ) throw e;
result.push(i+'()');
else
result.push(i);
}
}else{
if (o.constructor == Array)
return result;
for (var i in o){
if (i.match(/^[^_]/)){
if (typeof o[i] == 'function')
result.push(i+'()');
else
result.push(i);
}
} }
}
if ( typeofProperty == 'function' ) {
result.push( i+'()' );
} else {
result.push( i );
}
} }
return result.sort(); } else {
if ( o.constructor == Array ) {
return result;
}
for ( i in o ) {
if ( i.match( /^[^_]/ ) ) {
if ( typeof o[i] == 'function' ) {
result.push( i+'()' );
} else {
result.push( i );
}
}
}
}
return result.sort();
}; };
var onTabCompleteJS = function( result, cmdSender, pluginCmd, cmdAlias, cmdArgs) { var onTabCompleteJS = function( result, cmdSender, pluginCmd, cmdAlias, cmdArgs ) {
cmdArgs = Array.prototype.slice.call(cmdArgs, 0); var _globalSymbols,
lastArg,
propsOfLastArg,
statement,
statementSyms,
lastSymbol,
parts,
name,
symbol,
lastGoodSymbol,
i,
objectProps,
candidate,
re,
li,
possibleCompletion;
if (pluginCmd.name == 'jsp') cmdArgs = Array.prototype.slice.call( cmdArgs, 0 );
return tabCompleteJSP( result, cmdSender, pluginCmd, cmdAlias, cmdArgs );
global.self = cmdSender; // bring in self just for autocomplete if ( pluginCmd.name == 'jsp' ) {
return tabCompleteJSP( result, cmdSender, pluginCmd, cmdAlias, cmdArgs );
}
global.self = cmdSender; // bring in self just for autocomplete
var _globalSymbols = _getProperties(global) _globalSymbols = _getProperties(global);
var lastArg = cmdArgs.length?cmdArgs[cmdArgs.length-1]+'':null; lastArg = cmdArgs.length?cmdArgs[cmdArgs.length-1]+'':null;
var propsOfLastArg = []; propsOfLastArg = [];
var statement = cmdArgs.join(' '); statement = cmdArgs.join(' ');
statement = statement.replace(/^\s+/,'').replace(/\s+$/,''); statement = statement.replace(/^\s+/,'').replace(/\s+$/,'');
if ( statement.length == 0 ) {
if (statement.length == 0) propsOfLastArg = _globalSymbols;
propsOfLastArg = _globalSymbols; } else {
else{ statementSyms = statement.split(/[^\$a-zA-Z0-9_\.]/);
var statementSyms = statement.split(/[^\$a-zA-Z0-9_\.]/); lastSymbol = statementSyms[statementSyms.length-1];
var lastSymbol = statementSyms[statementSyms.length-1]; //print('DEBUG: lastSymbol=[' + lastSymbol + ']');
//print('DEBUG: lastSymbol=[' + lastSymbol + ']'); //
// try to complete the object ala java IDEs.
//
parts = lastSymbol.split(/\./);
name = parts[0];
symbol = global[name];
lastGoodSymbol = symbol;
if ( typeof symbol != 'undefined' ) {
for ( i = 1; i < parts.length; i++ ) {
name = parts[i];
symbol = symbol[name];
if ( typeof symbol == 'undefined' ) {
break;
}
lastGoodSymbol = symbol;
}
//print('debug:name['+name+']lastSymbol['+lastSymbol+']symbol['+symbol+']');
if ( typeof symbol == 'undefined' ) {
// //
// try to complete the object ala java IDEs. // look up partial matches against last good symbol
// //
var parts = lastSymbol.split(/\./); objectProps = _getProperties( lastGoodSymbol );
var name = parts[0]; if ( name == '' ) {
var symbol = global[name]; // if the last symbol looks like this..
var lastGoodSymbol = symbol; // ScriptCraft.
if (typeof symbol != 'undefined') //
{
for (var i = 1; i < parts.length;i++){ for ( i =0; i < objectProps.length; i++ ) {
name = parts[i]; candidate = lastSymbol + objectProps[i];
symbol = symbol[name]; re = new RegExp( lastSymbol + '$', 'g' );
if (typeof symbol == 'undefined') propsOfLastArg.push( lastArg.replace( re, candidate ) );
break; }
lastGoodSymbol = symbol;
} else {
// it looks like this..
// ScriptCraft.co
//
//print('debug:case Y: ScriptCraft.co');
li = statement.lastIndexOf(name);
for ( i = 0; i < objectProps.length; i++ ) {
if ( objectProps[i].indexOf(name) == 0 ) {
candidate = lastSymbol.substring( 0, lastSymbol.lastIndexOf( name ) );
candidate = candidate + objectProps[i];
re = new RegExp( lastSymbol + '$', 'g' );
propsOfLastArg.push( lastArg.replace( re, candidate ) );
} }
//print('debug:name['+name+']lastSymbol['+lastSymbol+']symbol['+symbol+']'); }
if (typeof symbol == 'undefined'){
//
// look up partial matches against last good symbol
//
var objectProps = _getProperties(lastGoodSymbol);
if (name == ''){
// if the last symbol looks like this..
// ScriptCraft.
//
for (var i =0;i < objectProps.length;i++){
var candidate = lastSymbol + objectProps[i];
var re = new RegExp(lastSymbol + '$','g');
propsOfLastArg.push(lastArg.replace(re,candidate));
}
}else{
// it looks like this..
// ScriptCraft.co
//
//print('debug:case Y: ScriptCraft.co');
var li = statement.lastIndexOf(name);
for (var i = 0; i < objectProps.length;i++){
if (objectProps[i].indexOf(name) == 0)
{
var candidate = lastSymbol.substring(0,lastSymbol.lastIndexOf(name));
candidate = candidate + objectProps[i];
var re = new RegExp(lastSymbol+ '$','g');
//print('DEBUG: re=' + re + ',lastSymbol='+lastSymbol+',lastArg=' + lastArg + ',candidate=' + candidate);
propsOfLastArg.push(lastArg.replace(re,candidate));
}
}
}
}else{
//print('debug:case Z:ScriptCraft');
var objectProps = _getProperties(symbol);
for (var i = 0; i < objectProps.length; i++){
var re = new RegExp(lastSymbol+ '$','g');
propsOfLastArg.push(lastArg.replace(re,lastSymbol + '.' + objectProps[i]));
}
}
}else{
//print('debug:case AB:ScriptCr');
// loop thru globalSymbols looking for a good match
for (var i = 0;i < _globalSymbols.length; i++){
if (_globalSymbols[i].indexOf(lastSymbol) == 0){
var possibleCompletion = _globalSymbols[i];
var re = new RegExp(lastSymbol+ '$','g');
propsOfLastArg.push(lastArg.replace(re,possibleCompletion));
}
}
} }
} else {
objectProps = _getProperties( symbol );
for ( i = 0; i < objectProps.length; i++ ) {
re = new RegExp( lastSymbol+ '$', 'g' );
propsOfLastArg.push( lastArg.replace( re, lastSymbol + '.' + objectProps[i] ) );
}
}
} else {
for ( i = 0; i < _globalSymbols.length; i++ ) {
if ( _globalSymbols[i].indexOf(lastSymbol) == 0 ) {
possibleCompletion = _globalSymbols[i];
re = new RegExp( lastSymbol+ '$', 'g' );
propsOfLastArg.push( lastArg.replace( re, possibleCompletion ) );
}
}
} }
for (var i = 0;i < propsOfLastArg.length; i++) }
result.add(propsOfLastArg[i]); for ( i = 0; i < propsOfLastArg.length; i++ ) {
result.add( propsOfLastArg[i] );
}
delete global.self; // delete self when no longer needed for autocomplete delete global.self; // delete self when no longer needed for autocomplete
}; };
module.exports = onTabCompleteJS; module.exports = onTabCompleteJS;

View file

@ -21,261 +21,261 @@ The blocks module is globally exported by the Drone module.
***/ ***/
var blocks = { var blocks = {
air: 0, air: 0,
stone: 1, stone: 1,
grass: 2, grass: 2,
dirt: 3, dirt: 3,
cobblestone: 4, cobblestone: 4,
oak: 5, oak: 5,
spruce: '5:1', spruce: '5:1',
birch: '5:2', birch: '5:2',
jungle: '5:3', jungle: '5:3',
sapling: { sapling: {
oak: 6, oak: 6,
spruce: '6:1', spruce: '6:1',
birch: '6:2', birch: '6:2',
jungle: '6:3' jungle: '6:3'
}, },
bedrock: 7, bedrock: 7,
water: 8, water: 8,
water_still: 9, water_still: 9,
lava: 10, lava: 10,
lava_still: 11, lava_still: 11,
sand: 12, sand: 12,
gravel: 13, gravel: 13,
gold_ore: 14, gold_ore: 14,
iron_ore: 15, iron_ore: 15,
coal_ore: 16, coal_ore: 16,
wood: 17, wood: 17,
leaves: 18, leaves: 18,
sponge: 19, sponge: 19,
glass: 20, glass: 20,
lapis_lazuli_ore: 21, lapis_lazuli_ore: 21,
lapis_lazuli_block: 22, lapis_lazuli_block: 22,
dispenser: 23, dispenser: 23,
sandstone: 24, sandstone: 24,
note: 25, note: 25,
bed: 26, bed: 26,
powered_rail: 27, powered_rail: 27,
detector_rail: 28, detector_rail: 28,
sticky_piston: 29, sticky_piston: 29,
cobweb: 30, cobweb: 30,
grass_tall: 31, grass_tall: 31,
dead_bush: 32, dead_bush: 32,
piston: 33, piston: 33,
piston_extn: 34, piston_extn: 34,
wool: { wool: {
white: 35 // All other colors added below white: 35 // All other colors added below
}, },
dandelion: 37, dandelion: 37,
flower_yellow: 37, flower_yellow: 37,
rose: 38, rose: 38,
flower_red: 38, flower_red: 38,
mushroom_brown: 39, mushroom_brown: 39,
mushroom_red: 40, mushroom_red: 40,
gold: 41, gold: 41,
iron: 42, iron: 42,
tnt: 46, tnt: 46,
bookshelf: 47, bookshelf: 47,
moss_stone: 48, moss_stone: 48,
obsidian: 49, obsidian: 49,
torch: 50, torch: 50,
fire: 51, fire: 51,
monster_spawner: 52, monster_spawner: 52,
stairs: { stairs: {
oak: 53, oak: 53,
cobblestone: 67, cobblestone: 67,
brick: 108, brick: 108,
stone: 109, stone: 109,
nether: 114, nether: 114,
sandstone: 128, sandstone: 128,
spruce: 134, spruce: 134,
birch: 135, birch: 135,
jungle: 136, jungle: 136,
quartz: 156 quartz: 156
}, },
chest: 54, chest: 54,
redstone_wire: 55, redstone_wire: 55,
diamond_ore: 56, diamond_ore: 56,
diamond: 57, diamond: 57,
crafting_table: 58, crafting_table: 58,
wheat_seeds: 59, wheat_seeds: 59,
farmland: 60, farmland: 60,
furnace: 61, furnace: 61,
furnace_burning: 62, furnace_burning: 62,
sign_post: 63, sign_post: 63,
door_wood: 64, door_wood: 64,
ladder: 65, ladder: 65,
rail: 66, rail: 66,
sign: 68, sign: 68,
lever: 69, lever: 69,
pressure_plate_stone: 70, pressure_plate_stone: 70,
door_iron: 71, door_iron: 71,
pressure_plate_wood: 72, pressure_plate_wood: 72,
redstone_ore: 73, redstone_ore: 73,
redstone_ore_glowing: 74, redstone_ore_glowing: 74,
torch_redstone: 75, torch_redstone: 75,
torch_redstone_active: 76, torch_redstone_active: 76,
stone_button: 77, stone_button: 77,
ice: 79, ice: 79,
snow: 80, snow: 80,
cactus: 81, cactus: 81,
clay: 82, clay: 82,
sugar_cane: 83, sugar_cane: 83,
jukebox: 84, jukebox: 84,
fence: 85, fence: 85,
pumpkin: 86, pumpkin: 86,
netherrack: 87, netherrack: 87,
soulsand: 88, soulsand: 88,
glowstone: 89, glowstone: 89,
netherportal: 90, netherportal: 90,
jackolantern: 91, jackolantern: 91,
cake: 92, cake: 92,
redstone_repeater: 93, redstone_repeater: 93,
redeston_repeater_active: 94, redeston_repeater_active: 94,
chest_locked: 95, chest_locked: 95,
trapdoor: 96, trapdoor: 96,
monster_egg: 97, monster_egg: 97,
brick: { brick: {
stone: 98, stone: 98,
mossy: '98:1', mossy: '98:1',
cracked: '98:2', cracked: '98:2',
chiseled: '98:3', chiseled: '98:3',
red: 45 red: 45
}, },
mushroom_brown_huge: 99, mushroom_brown_huge: 99,
mushroom_red_huge: 100, mushroom_red_huge: 100,
iron_bars: 101, iron_bars: 101,
glass_pane: 102, glass_pane: 102,
melon: 103, melon: 103,
pumpkin_stem: 104, pumpkin_stem: 104,
melon_stem: 105, melon_stem: 105,
vines: 106, vines: 106,
fence_gate: 107, fence_gate: 107,
mycelium: 110, mycelium: 110,
lily_pad: 111, lily_pad: 111,
nether: 112, nether: 112,
nether_fence: 113, nether_fence: 113,
netherwart: 115, netherwart: 115,
table_enchantment: 116, table_enchantment: 116,
brewing_stand: 117, brewing_stand: 117,
cauldron: 118, cauldron: 118,
endportal: 119, endportal: 119,
endportal_frame: 120, endportal_frame: 120,
endstone: 121, endstone: 121,
dragon_egg: 122, dragon_egg: 122,
redstone_lamp: 123, redstone_lamp: 123,
redstone_lamp_active: 124, redstone_lamp_active: 124,
slab: { slab: {
snow: 78, snow: 78,
stone: 44, stone: 44,
sandstone: '44:1', sandstone: '44:1',
wooden: '44:2', wooden: '44:2',
cobblestone: '44:3', cobblestone: '44:3',
brick: '44:4', brick: '44:4',
stonebrick: '44:5', stonebrick: '44:5',
netherbrick:'44:6', netherbrick:'44:6',
quartz: '44:7', quartz: '44:7',
oak: 126, oak: 126,
spruce: '126:1', spruce: '126:1',
birch: '126:2', birch: '126:2',
jungle: '126:3', jungle: '126:3',
upper: { upper: {
stone: '44:8', stone: '44:8',
sandstone: '44:9', sandstone: '44:9',
wooden: '44:10', wooden: '44:10',
cobblestone: '44:11', cobblestone: '44:11',
brick: '44:12', brick: '44:12',
stonebrick: '44:13', stonebrick: '44:13',
netherbrick:'44:14', netherbrick:'44:14',
quartz: '44:15', quartz: '44:15',
oak: '126:8', oak: '126:8',
spruce: '126:9', spruce: '126:9',
birch: '126:10', birch: '126:10',
jungle: '126:11', jungle: '126:11'
} }
}, },
cocoa: 127, cocoa: 127,
emerald_ore: 129, emerald_ore: 129,
enderchest: 130, enderchest: 130,
tripwire_hook: 131, tripwire_hook: 131,
tripwire: 132, tripwire: 132,
emerald: 133, emerald: 133,
command: 137, command: 137,
beacon: 138, beacon: 138,
cobblestone_wall: 139, cobblestone_wall: 139,
flowerpot: 140, flowerpot: 140,
carrots: 141, carrots: 141,
potatoes: 142, potatoes: 142,
button_wood: 143, button_wood: 143,
mobhead: 144, mobhead: 144,
anvil: 145, anvil: 145,
chest_trapped: 146, chest_trapped: 146,
pressure_plate_weighted_light: 147, pressure_plate_weighted_light: 147,
pressure_plate_weighted_heavy: 148, pressure_plate_weighted_heavy: 148,
redstone_comparator: 149, redstone_comparator: 149,
redstone_comparator_active: 150, redstone_comparator_active: 150,
daylight_sensor: 151, daylight_sensor: 151,
redstone: 152, redstone: 152,
netherquartzore: 153, netherquartzore: 153,
hopper: 154, hopper: 154,
quartz: 155, quartz: 155,
rail_activator: 157, rail_activator: 157,
dropper: 158, dropper: 158,
stained_clay: { stained_clay: {
white: 159 // All other colors added below white: 159 // All other colors added below
}, },
hay: 170, hay: 170,
carpet: { carpet: {
white: 171 // All other colors added below white: 171 // All other colors added below
}, },
hardened_clay: 172, hardened_clay: 172,
coal_block: 173 coal_block: 173
}; };
// Add all available colors to colorized block collections // Add all available colors to colorized block collections
var colors = { var colors = {
orange: ':1', orange: ':1',
magenta: ':2', magenta: ':2',
lightblue: ':3', lightblue: ':3',
yellow: ':4', yellow: ':4',
lime: ':5', lime: ':5',
pink: ':6', pink: ':6',
gray: ':7', gray: ':7',
lightgray: ':8', lightgray: ':8',
cyan: ':9', cyan: ':9',
purple: ':10', purple: ':10',
blue: ':11', blue: ':11',
brown: ':12', brown: ':12',
green: ':13', green: ':13',
red: ':14', red: ':14',
black: ':15' black: ':15'
}; };
var colorized_blocks = ["wool", "stained_clay", "carpet"]; var colorized_blocks = ['wool', 'stained_clay', 'carpet'];
for (var i = 0, len = colorized_blocks.length; i < len; i++) { for (var i = 0, len = colorized_blocks.length; i < len; i++) {
var block = colorized_blocks[i], var block = colorized_blocks[i],
data_value = blocks[block].white; data_value = blocks[block].white;
for (var color in colors) { for (var color in colors) {
blocks[block][color] = data_value + colors[color]; blocks[block][color] = data_value + colors[color];
} }
}; };
/* /*
rainbow colors - a convenience rainbow colors - a convenience
Color aliased properties that were a direct descendant of the blocks Color aliased properties that were a direct descendant of the blocks
object are no longer used to avoid confusion with carpet and stained object are no longer used to avoid confusion with carpet and stained
clay blocks. clay blocks.
*/ */
blocks.rainbow = [blocks.wool.red, blocks.rainbow = [
blocks.wool.orange, blocks.wool.red,
blocks.wool.yellow, blocks.wool.orange,
blocks.wool.lime, blocks.wool.yellow,
blocks.wool.lightblue, blocks.wool.lime,
blocks.wool.blue, blocks.wool.lightblue,
blocks.wool.purple]; blocks.wool.blue,
blocks.wool.purple];
module.exports = blocks; module.exports = blocks;

View file

@ -27,7 +27,7 @@ To call the fireworks.firework() function directly, you must provide a
location. For example... location. For example...
/js var fireworks = require('fireworks'); /js var fireworks = require('fireworks');
/js fireworks.firework(self.location); /js fireworks.firework( self.location );
![firework example](img/firework.png) ![firework example](img/firework.png)
@ -36,44 +36,45 @@ location. For example...
/* /*
create a firework at the given location create a firework at the given location
*/ */
var firework = function(location){ var firework = function( location ) {
var Color = org.bukkit.Color; var Color = org.bukkit.Color;
var FireworkEffect = org.bukkit.FireworkEffect; var FireworkEffect = org.bukkit.FireworkEffect;
var EntityType = org.bukkit.entity.EntityType; var EntityType = org.bukkit.entity.EntityType;
var randInt = function(n){ var randInt = function( n ) {
return Math.floor(Math.random() * n); return Math.floor( Math.random() * n );
}; };
var getColor = function(i){ var getColor = function( i ) {
var colors = [ var colors = [
Color.AQUA, Color.BLACK, Color.BLUE, Color.FUCHSIA, Color.GRAY, Color.AQUA, Color.BLACK, Color.BLUE, Color.FUCHSIA, Color.GRAY,
Color.GREEN, Color.LIME, Color.MAROON, Color.NAVY, Color.OLIVE, Color.GREEN, Color.LIME, Color.MAROON, Color.NAVY, Color.OLIVE,
Color.ORANGE, Color.PURPLE, Color.RED, Color.SILVER, Color.TEAL, Color.ORANGE, Color.PURPLE, Color.RED, Color.SILVER, Color.TEAL,
Color.WHITE, Color.YELLOW]; Color.WHITE, Color.YELLOW];
return colors[i]; return colors[i];
}; };
var fw = location.world.spawnEntity(location, EntityType.FIREWORK); var fw = location.world.spawnEntity(location, EntityType.FIREWORK);
var fwm = fw.getFireworkMeta(); var fwm = fw.getFireworkMeta();
var fwTypes = [FireworkEffect.Type.BALL, var fwTypes = [FireworkEffect.Type.BALL,
FireworkEffect.Type.BALL_LARGE, FireworkEffect.Type.BALL_LARGE,
FireworkEffect.Type.BURST, FireworkEffect.Type.BURST,
FireworkEffect.Type.CREEPER, FireworkEffect.Type.CREEPER,
FireworkEffect.Type.STAR]; FireworkEffect.Type.STAR];
var type = fwTypes[randInt(5)]; var type = fwTypes[ randInt( 5 ) ];
var r1i = randInt(17); var r1i = randInt( 17 );
var r2i = randInt(17); var r2i = randInt( 17 );
var c1 = getColor(r1i); var c1 = getColor( r1i );
var c2 = getColor(r2i); var c2 = getColor( r2i );
var effectBuilder = FireworkEffect.builder() var effectBuilder = FireworkEffect.builder()
.flicker(Math.round(Math.random())==0) .flicker( Math.round( Math.random() ) == 0 )
.withColor(c1) .withColor( c1 )
.withFade(c2).trail(Math.round(Math.random())==0); .withFade( c2 )
effectBuilder['with'](type); .trail( Math.round( Math.random() ) == 0 );
var effect = effectBuilder.build(); effectBuilder['with']( type );
fwm.addEffect(effect); var effect = effectBuilder.build();
fwm.setPower(randInt(2)+1); fwm.addEffect( effect );
fw.setFireworkMeta(fwm); fwm.setPower( randInt( 2 ) + 1 );
fw.setFireworkMeta( fwm );
}; };
exports.firework = firework; exports.firework = firework;

View file

@ -37,74 +37,76 @@ The following example illustrates how to use http.request to make a request to a
... The following example illustrates a more complex use-case POSTing parameters to a CGI process on a server... ... The following example illustrates a more complex use-case POSTing parameters to a CGI process on a server...
var http = require('./http/request'); var http = require('./http/request');
http.request({ url: "http://pixenate.com/pixenate/pxn8.pl", http.request(
method: "POST", {
params: {script: "[]"} url: 'http://pixenate.com/pixenate/pxn8.pl',
}, function( responseCode, responseBody){ method: 'POST',
var jsObj = eval("(" + responseBody + ")"); params: {script: '[]'}
},
function( responseCode, responseBody ) {
var jsObj = eval('(' + responseBody + ')');
}); });
***/ ***/
exports.request = function( request, callback) exports.request = function( request, callback ) {
{ var paramsToString = function( params ) {
var paramsToString = function(params){ var result = '',
var result = ""; paramNames = [],
var paramNames = []; i;
for (var i in params){ for ( i in params ) {
paramNames.push(i); paramNames.push( i );
} }
for (var i = 0;i < paramNames.length;i++){ for ( i = 0; i < paramNames.length; i++ ) {
result += paramNames[i] + "=" + encodeURI(params[paramNames[i]]); result += paramNames[i] + '=' + encodeURI( params[ paramNames[i] ] );
if (i < paramNames.length-1) if ( i < paramNames.length-1 )
result += "&"; result += '&';
} }
return result; return result;
}; };
server.scheduler.runTaskAsynchronously(__plugin,function() server.scheduler.runTaskAsynchronously( __plugin, function() {
{ var url, paramsAsString, conn, requestMethod;
var url, paramsAsString, conn, requestMethod; if (typeof request === 'string'){
if (typeof request === "string"){ url = request;
url = request; requestMethod = 'GET';
requestMethod = "GET"; }else{
}else{ paramsAsString = paramsToString( request.params );
paramsAsString = paramsToString(request.params); if ( request.method ) {
if (request.method) requestMethod = request.method;
requestMethod = request.method } else {
else requestMethod = 'GET';
requestMethod = "GET"; }
if ( requestMethod == 'GET' && request.params ) {
// append each parameter to the URL
url = request.url + '?' + paramsAsString;
}
}
conn = new java.net.URL( url ).openConnection();
conn.requestMethod = requestMethod;
conn.doOutput = true;
conn.instanceFollowRedirects = false;
if (requestMethod == "GET" && request.params){ if ( conn.requestMethod == 'POST' ) {
// append each parameter to the URL conn.doInput = true;
url = request.url + "?" + paramsAsString; // put each parameter in the outputstream
} conn.setRequestProperty('Content-Type', 'application/x-www-form-urlencoded');
} conn.setRequestProperty('charset', 'utf-8');
conn = new java.net.URL(url).openConnection(); conn.setRequestProperty('Content-Length', '' + paramsAsString.length);
conn.requestMethod = requestMethod; conn.useCaches =false ;
conn.doOutput = true; wr = new java.io.DataOutputStream(conn.getOutputStream ());
conn.instanceFollowRedirects = false; wr.writeBytes(paramsAsString);
wr.flush();
if (conn.requestMethod == "POST"){ wr.close();
conn.doInput = true; }
// put each parameter in the outputstream var rc = conn.responseCode;
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); var response;
conn.setRequestProperty("charset", "utf-8"); var stream;
conn.setRequestProperty("Content-Length", "" + paramsAsString.length); if ( rc == 200 ) {
conn.useCaches =false ; stream = conn.getInputStream();
wr = new java.io.DataOutputStream(conn.getOutputStream ()); response = new java.util.Scanner( stream ).useDelimiter("\\A").next();
wr.writeBytes(paramsAsString); }
wr.flush(); server.scheduler.runTask( __plugin, function( ) {
wr.close(); callback( rc, response );
}
var rc = conn.responseCode;
var response;
var stream;
if (rc == 200){
stream = conn.getInputStream();
response = new java.util.Scanner(stream).useDelimiter("\\A").next();
}
server.scheduler.runTask(__plugin,function(){
callback(rc,response);
});
}); });
});
}; };

View file

@ -2,44 +2,49 @@
The scoreboard is a simple wrapper around the Bukkit Scoreboard API. The scoreboard is a simple wrapper around the Bukkit Scoreboard API.
It's only concerned with display of scores, not maintaining them - that's the game's job. It's only concerned with display of scores, not maintaining them - that's the game's job.
*/ */
module.exports = function(options){ module.exports = function( options ) {
var temp = {}; var temp = {};
var ccScoreboard; var ccScoreboard;
var DisplaySlot = org.bukkit.scoreboard.DisplaySlot; var DisplaySlot = org.bukkit.scoreboard.DisplaySlot;
return { return {
start: function(){ start: function( ) {
var objective, slot; var objective,
ccScoreboard = server.scoreboardManager.getNewScoreboard(); slot,
for (objective in options){ ccObj;
var ccObj = ccScoreboard.registerNewObjective(objective,'dummy'); ccScoreboard = server.scoreboardManager.getNewScoreboard();
for (slot in options[objective]){ for ( objective in options ) {
ccObj.displaySlot = DisplaySlot[slot]; ccObj = ccScoreboard.registerNewObjective( objective, 'dummy' );
ccObj.displayName = options[objective][slot]; for ( slot in options[ objective ] ) {
} ccObj.displaySlot = DisplaySlot[ slot ];
} ccObj.displayName = options[ objective ][ slot ];
},
stop: function(){
var objective, slot;
for (objective in options){
ccScoreboard.getObjective(objective).unregister();
for (slot in options[objective]){
ccScoreboard.clearSlot(DisplaySlot[slot]);
}
}
},
update: function(objective,player,score){
if (player.scoreboard && player.scoreboard != ccScoreboard)
{
temp[player.name] = player.scoreboard;
player.scoreboard = ccScoreboard;
}
ccScoreboard.getObjective(objective).getScore(player).score = score;
},
restore: function(player){
// offlineplayers don't have a scoreboard
if (player.scoreboard)
player.scoreboard = temp[player.name];
} }
}; }
},
stop: function(){
var objective, slot;
for ( objective in options ) {
ccScoreboard.getObjective(objective).unregister();
for ( slot in options[ objective ] ) {
ccScoreboard.clearSlot( DisplaySlot[ slot ] );
}
}
},
update: function( objective, player, score ) {
if ( player.scoreboard && player.scoreboard != ccScoreboard ) {
temp[player.name] = player.scoreboard;
player.scoreboard = ccScoreboard;
}
ccScoreboard
.getObjective( objective )
.getScore( player )
.score = score;
},
restore: function( player ) {
// offlineplayers don't have a scoreboard
if ( player.scoreboard ) {
player.scoreboard = temp[ player.name ];
}
}
};
}; };

View file

@ -1,14 +0,0 @@
/**
* Create a partial function
*
* Parameters:
* func - base function
* [remaining arguments] - arguments bound to the partial function
*/
module.exports = function (func /*, 0..n args */) {
var args = Array.prototype.slice.call(arguments, 1);
return function() {
var allArguments = args.concat(Array.prototype.slice.call(arguments));
return func.apply(this, allArguments);
};
}

View file

@ -34,24 +34,24 @@ present in the CraftBukkit classpath. To use this module, you should
// create a new client // create a new client
var client = mqtt.client('tcp://localhost:1883', 'uniqueClientId'); var client = mqtt.client( 'tcp://localhost:1883', 'uniqueClientId' );
// connect to the broker // connect to the broker
client.connect({ keepAliveInterval: 15 }); client.connect( { keepAliveInterval: 15 } );
// publish a message to the broker // publish a message to the broker
client.publish('minecraft','loaded'); client.publish( 'minecraft', 'loaded' );
// subscribe to messages on 'arduino' topic // subscribe to messages on 'arduino' topic
client.subscribe('arduino'); client.subscribe( 'arduino' );
// do something when an incoming message arrives... // do something when an incoming message arrives...
client.onMessageArrived(function(topic, message){ client.onMessageArrived( function( topic, message ) {
console.log('Message arrived: topic=' + topic + ', message=' + message); console.log( 'Message arrived: topic=' + topic + ', message=' + message );
}); });
The `sc-mqtt` module provides a very simple minimal wrapper around the The `sc-mqtt` module provides a very simple minimal wrapper around the
@ -66,35 +66,34 @@ var MISSING_MQTT = '\nMissing class org.walterhiggins.scriptcraft.ScriptCraftMqt
'Make sure sc-mqtt.jar is in the classpath.\n' + 'Make sure sc-mqtt.jar is in the classpath.\n' +
'See http://github.com/walterhiggins/scriptcraft-extras-mqtt for details.\n'; 'See http://github.com/walterhiggins/scriptcraft-extras-mqtt for details.\n';
function Client(brokerUrl, clientId){ function Client( brokerUrl, clientId ) {
var Callback = org.walterhiggins.scriptcraft.ScriptCraftMqttCallback; var Callback = org.walterhiggins.scriptcraft.ScriptCraftMqttCallback;
var MqttClient = org.eclipse.paho.client.mqttv3.MqttClient; var MqttClient = org.eclipse.paho.client.mqttv3.MqttClient;
var callback = new Callback( var callback = new Callback(
function(err){ function( err ) {
console.log('connectionLost: ' + err); console.log( 'connectionLost: ' + err );
}, },
function(topic, message){ function( topic, message ) {
console.log('messageArrived ' + topic + '> ' + message); console.log( 'messageArrived ' + topic + '> ' + message );
}, },
function(token){ function( token ) {
console.log('deliveryComplete:' + token); console.log( 'deliveryComplete:' + token );
} }
); );
if (!brokerUrl){ if ( !brokerUrl ) {
brokerUrl = 'tcp://localhost:1883'; brokerUrl = 'tcp://localhost:1883';
} }
if (!clientId){ if ( !clientId ) {
clientId = 'scriptcraft' + new Date().getTime(); clientId = 'scriptcraft' + new Date().getTime();
} }
var client = new MqttClient(brokerUrl, clientId, null); var client = new MqttClient( brokerUrl, clientId, null );
client.setCallback(callback); client.setCallback( callback );
return { return {
connect: function( options ) {
connect: function(options){ if ( typeof options === 'undefined' ) {
if (typeof options === 'undefined'){
client.connect(); client.connect();
}else{ }else{
client.connect(options); client.connect(options);
@ -102,17 +101,18 @@ function Client(brokerUrl, clientId){
return client; return client;
}, },
disconnect: function(quiesceTimeout){ disconnect: function( quiesceTimeout ) {
if (typeof quiesceTimeout == 'undefined') if ( typeof quiesceTimeout == 'undefined' ) {
client.disconnect(); client.disconnect();
else } else {
client.disconnect(quiesceTimeout); client.disconnect( quiesceTimeout );
}
return client; return client;
}, },
publish: function(topic, message, qos, retained){ publish: function( topic, message, qos, retained ) {
if (typeof message == 'string'){ if ( typeof message == 'string' ) {
message = new java.lang.String(message).bytes; message = new java.lang.String( message ).bytes;
} }
if (typeof qos == 'undefined'){ if (typeof qos == 'undefined'){
qos = 1; qos = 1;
@ -120,41 +120,43 @@ function Client(brokerUrl, clientId){
if (typeof retained == 'undefined'){ if (typeof retained == 'undefined'){
retained = false; retained = false;
} }
client.publish(topic, message,qos, retained); client.publish( topic, message,qos, retained );
return client; return client;
}, },
subscribe: function(topic){ subscribe: function( topic ) {
client.subscribe(topic); client.subscribe( topic );
return client; return client;
}, },
unsubscribe: function(topic){ unsubscribe: function( topic ) {
client.unsubscribe(topic); client.unsubscribe( topic );
return client; return client;
}, },
onMessageArrived: function(fn){ onMessageArrived: function( fn ) {
callback.setMesgArrived(fn); callback.setMesgArrived( fn );
return client; return client;
}, },
onDeliveryComplete: function(fn){ onDeliveryComplete: function( fn ) {
callback.setDeliveryComplete(fn); callback.setDeliveryComplete( fn );
return client; return client;
}, },
onConnectionLost: function(fn){ onConnectionLost: function( fn ) {
callback.setConnLost(fn); callback.setConnLost( fn );
return client; return client;
} }
}; };
} }
/*
exports.client = function(brokerUrl, clientId, options){ Return a new MQTT Client
if (typeof org.walterhiggins.scriptcraft.ScriptCraftMqttCallback != 'function'){ */
exports.client = function( brokerUrl, clientId, options ) {
if ( typeof org.walterhiggins.scriptcraft.ScriptCraftMqttCallback != 'function' ) {
throw MISSING_MQTT; throw MISSING_MQTT;
} }
return new Client(brokerUrl, clientId, options); return new Client( brokerUrl, clientId, options );
}; };

View file

@ -8,35 +8,39 @@ var _store = {};
*/ */
var signs = plugin("signs", { var signs = plugin("signs", {
/* /*
construct an interactive menu which can then be attached to a Sign. construct an interactive menu which can then be attached to a Sign.
*/ */
menu: function( menu: function(
/* String */ label, /* String */ label,
/* Array */ options, /* Array */ options,
/* Function */ onInteract, /* Function */ onInteract,
/* Number */ defaultSelection ){}, /* Number */ defaultSelection ){},
store: _store store: _store
},true); },
true);
module.exports = signs; module.exports = signs;
/* /*
redraw a menu sign redraw a menu sign
*/ */
var _redrawMenuSign = function(p_sign,p_selectedIndex,p_displayOptions) var _redrawMenuSign = function( p_sign, p_selectedIndex, p_displayOptions ) {
{ var optLen = p_displayOptions.length,
var optLen = p_displayOptions.length; i,
// the offset is where the menu window begins text;
var offset = Math.max(0, Math.min(optLen-3, Math.floor(p_selectedIndex/3) * 3)); // the offset is where the menu window begins
for (var i = 0;i < 3; i++){ var offset = Math.max( 0, Math.min( optLen-3, Math.floor( p_selectedIndex/3 ) * 3) );
var text = ""; for ( i = 0;i < 3; i++ ) {
if (offset+i < optLen) text = "";
text = p_displayOptions[offset+i]; if ( offset+i < optLen ) {
if (offset+i == p_selectedIndex) text = p_displayOptions[offset+i];
text = ("" + text).replace(/^ /,">");
p_sign.setLine(i+1,text);
} }
p_sign.update(true); if ( offset+i == p_selectedIndex ) {
text = ('' + text).replace(/^ /,">");
}
p_sign.setLine( i+1, text );
}
p_sign.update( true );
}; };
var _updaters = {}; var _updaters = {};
@ -44,152 +48,153 @@ var _updaters = {};
construct an interactive menu to be subsequently attached to construct an interactive menu to be subsequently attached to
one or more Signs. one or more Signs.
*/ */
signs.menu = function( signs.menu = function( /* String */ label, /* Array */ options, /* Function */ callback, /* Number */ selectedIndex ) {
/* String */ label,
/* Array */ options, if ( typeof selectedIndex == "undefined" ) {
/* Function */ callback, selectedIndex = 0;
/* Number */ selectedIndex }
) //
{ // variables common to all instances of this menu can go here
//
if (typeof selectedIndex == "undefined") var labelPadding = "---------------";
selectedIndex = 0; var optionPadding = " ";
// var i;
// variables common to all instances of this menu can go here var paddedLabel = ( labelPadding + label + labelPadding)
// .substr( ( ( label.length+30 ) / 2 ) - 7, 15 );
var labelPadding = "---------------"; var optLen = options.length;
var optionPadding = " "; var displayOptions = [];
for ( i = 0; i < options.length; i++ ) {
var paddedLabel = (labelPadding+label+labelPadding).substr(((label.length+30)/2)-7,15); displayOptions[i] = (" " + options[i] + optionPadding).substring(0,15);
var optLen = options.length; }
var displayOptions = []; /*
for (var i =0;i < options.length;i++){ this function is returned by signs.menu and when it is invoked it will
displayOptions[i] = (" " + options[i] + optionPadding).substring(0,15); attach menu behaviour to an existing sign in the world.
signs.menu is for use by Plugin Authors.
The function returned by signs.menu is for use by admins/ops.
*/
var convertToMenuSign = function(/* Sign */ sign, save) {
var mouseLoc;
if (typeof save == "undefined") {
save = true;
} }
/* /*
this function is returned by signs.menu and when it is invoked it will @deprecated start
attach menu behaviour to an existing sign in the world. all calls should explicitly provide a [org.bukkit.block.Sign][buksign] parameter.
signs.menu is for use by Plugin Authors. */
The function returned by signs.menu is for use by admins/ops. if ( typeof sign == "undefined" ) {
*/ mouseLoc = utils.getMousePos();
var convertToMenuSign = function(/* Sign */ sign, save) if ( mouseLoc ) {
{ sign = mouseLoc.block.state;
if (typeof save == "undefined") if ( !( sign && sign.setLine ) ) {
save = true; throw new Error("You must first provide a sign!");
/*
@deprecated start
all calls should explicitly provide a [org.bukkit.block.Sign][buksign] parameter.
*/
if (typeof sign == "undefined"){
var mouseLoc = utils.getMousePos();
if (mouseLoc){
sign = mouseLoc.block.state;
if (!(sign && sign.setLine)){
throw new Error("You must first provide a sign!");
}
}else{
throw new Error("You must first provide a sign!");
}
} }
/* } else {
@deprecated end throw new Error("You must first provide a sign!");
*/ }
// }
// per-sign variables go here /*
// @deprecated end
var cSelectedIndex = selectedIndex; */
sign.setLine(0,paddedLabel.bold()); //
var _updateSign = function(p_player,p_sign) { // per-sign variables go here
cSelectedIndex = (cSelectedIndex+1) % optLen; //
_redrawMenuSign(p_sign,cSelectedIndex,displayOptions); var cSelectedIndex = selectedIndex;
var signSelectionEvent = {player: p_player, sign.setLine( 0, paddedLabel.bold() );
sign: p_sign, var _updateSign = function( p_player, p_sign ) {
text: options[cSelectedIndex], cSelectedIndex = ( cSelectedIndex + 1 ) % optLen;
number:cSelectedIndex}; _redrawMenuSign( p_sign, cSelectedIndex, displayOptions );
var signSelectionEvent = {
callback(signSelectionEvent); player: p_player,
}; sign: p_sign,
text: options[ cSelectedIndex ],
/* number: cSelectedIndex
get a unique ID for this particular sign instance };
*/ callback( signSelectionEvent );
var signLoc = sign.block.location;
var menuSignSaveData = utils.locationToJSON(signLoc);
var menuSignUID = JSON.stringify(menuSignSaveData);
/*
keep a reference to the update function for use by the event handler
*/
_updaters[menuSignUID] = _updateSign;
// initialize the sign
_redrawMenuSign(sign,cSelectedIndex,displayOptions);
/*
whenever a sign is placed somewhere in the world
(which is what this function does)
save its location for loading and initialization
when the server starts up again.
*/
if (save){
if (typeof _store.menus == "undefined")
_store.menus = {};
var signLocations = _store.menus[label];
if (typeof signLocations == "undefined")
signLocations = _store.menus[label] = [];
signLocations.push(menuSignSaveData);
}
return sign;
}; };
/*
get a unique ID for this particular sign instance
*/
var signLoc = sign.block.location;
var menuSignSaveData = utils.locationToJSON( signLoc );
var menuSignUID = JSON.stringify( menuSignSaveData );
/* /*
a new sign definition - need to store (in-memory only) keep a reference to the update function for use by the event handler
its behaviour and bring back to life other signs of the */
same type in the world. Look for other static signs in the _updaters[ menuSignUID ] = _updateSign;
world with this same label and make dynamic again.
*/
if (_store.menus && _store.menus[label]) // initialize the sign
{ _redrawMenuSign( sign, cSelectedIndex, displayOptions );
var signsOfSameLabel = _store.menus[label];
var defragged = []; /*
var len = signsOfSameLabel.length; whenever a sign is placed somewhere in the world
for (var i = 0; i < len ; i++) (which is what this function does)
{ save its location for loading and initialization
var loc = signsOfSameLabel[i]; when the server starts up again.
var world = org.bukkit.Bukkit.getWorld(loc.world); */
if (!world) if ( save ) {
continue; if ( typeof _store.menus == "undefined") {
var block = world.getBlockAt(loc.x,loc.y,loc.z); _store.menus = {};
if (block.state instanceof org.bukkit.block.Sign){ }
convertToMenuSign(block.state,false); var signLocations = _store.menus[label];
defragged.push(loc); if ( typeof signLocations == "undefined" ) {
} signLocations = _store.menus[label] = [];
} }
/* signLocations.push( menuSignSaveData );
remove data for signs which no longer exist.
*/
if (defragged.length != len){
_store.menus[label] = defragged;
}
} }
return convertToMenuSign; return sign;
};
/*
a new sign definition - need to store (in-memory only)
its behaviour and bring back to life other signs of the
same type in the world. Look for other static signs in the
world with this same label and make dynamic again.
*/
if ( _store.menus && _store.menus[label] ) {
var signsOfSameLabel = _store.menus[ label ];
var defragged = [];
var len = signsOfSameLabel.length;
for ( i = 0; i < len; i++ ) {
var loc = signsOfSameLabel[i];
var world = org.bukkit.Bukkit.getWorld(loc.world);
if ( !world ) {
continue;
}
var block = world.getBlockAt( loc.x, loc.y, loc.z );
if ( block.state instanceof org.bukkit.block.Sign ) {
convertToMenuSign( block.state, false );
defragged.push( loc );
}
}
/*
remove data for signs which no longer exist.
*/
if ( defragged.length != len ) {
_store.menus[label] = defragged;
}
}
return convertToMenuSign;
}; };
// //
// update it every time player interacts with it. // update it every time player interacts with it.
// //
events.on('player.PlayerInteractEvent',function(listener, event) { events.on( 'player.PlayerInteractEvent', function( listener, event ) {
/* /*
look up our list of menu signs. If there's a matching location and there's look up our list of menu signs. If there's a matching location and there's
a sign, then update it. a sign, then update it.
*/ */
if (! event.clickedBlock.state instanceof org.bukkit.block.Sign) if ( ! event.clickedBlock.state instanceof org.bukkit.block.Sign ) {
return; return;
var evtLocStr = utils.locationToString(event.clickedBlock.location); }
var signUpdater = _updaters[evtLocStr] var evtLocStr = utils.locationToString(event.clickedBlock.location);
if (signUpdater) var signUpdater = _updaters[evtLocStr];
signUpdater(event.player, event.clickedBlock.state); if ( signUpdater ) {
signUpdater( event.player, event.clickedBlock.state );
}
}); });

View file

@ -92,16 +92,18 @@ the entity has targeted. It is a utility function for use by plugin authors.
var utils = require('utils'); var utils = require('utils');
var menu = require('./menu'); var menu = require('./menu');
// include all menu exports // include all menu exports
for (var i in menu){ for ( var i in menu ) {
exports[i] = menu[i]; exports[i] = menu[i];
} }
exports.getTargetedBy = function( livingEntity ){ exports.getTargetedBy = function( livingEntity ) {
var location = utils.getMousePos( livingEntity ); var location = utils.getMousePos( livingEntity );
if (!location) if ( !location ) {
return null; return null;
var state = location.block.state; }
if (!(state || state.setLine)) var state = location.block.state;
return null; if ( ! (state || state.setLine) ) {
return state; return null;
}
return state;
}; };

View file

@ -37,43 +37,43 @@ Example
------- -------
/js var boldGoldText = "Hello World".bold().gold(); /js var boldGoldText = "Hello World".bold().gold();
/js self.sendMessage(boldGoldText); /js self.sendMessage( boldGoldText );
<p style="color:gold;font-weight:bold">Hello World</p> <p style="color:gold;font-weight:bold">Hello World</p>
***/ ***/
var c = org.bukkit.ChatColor; var c = org.bukkit.ChatColor;
var formattingCodes = { var formattingCodes = {
aqua: c.AQUA, aqua: c.AQUA,
black: c.BLACK, black: c.BLACK,
blue: c.BLUE, blue: c.BLUE,
bold: c.BOLD, bold: c.BOLD,
brightgreen: c.GREEN, brightgreen: c.GREEN,
darkaqua: c.DARK_AQUA, darkaqua: c.DARK_AQUA,
darkblue: c.DARK_BLUE, darkblue: c.DARK_BLUE,
darkgray: c.DARK_GRAY, darkgray: c.DARK_GRAY,
darkgreen: c.DARK_GREEN, darkgreen: c.DARK_GREEN,
purple: c.LIGHT_PURPLE, purple: c.LIGHT_PURPLE,
darkpurple: c.DARK_PURPLE, darkpurple: c.DARK_PURPLE,
darkred: c.DARK_RED, darkred: c.DARK_RED,
gold: c.GOLD, gold: c.GOLD,
gray: c.GRAY, gray: c.GRAY,
green: c.GREEN, green: c.GREEN,
italic: c.ITALIC, italic: c.ITALIC,
lightpurple: c.LIGHT_PURPLE, lightpurple: c.LIGHT_PURPLE,
indigo: c.BLUE, indigo: c.BLUE,
red: c.RED, red: c.RED,
pink: c.LIGHT_PURPLE, pink: c.LIGHT_PURPLE,
yellow: c.YELLOW, yellow: c.YELLOW,
white: c.WHITE, white: c.WHITE,
strike: c.STRIKETHROUGH, strike: c.STRIKETHROUGH,
random: c.MAGIC, random: c.MAGIC,
magic: c.MAGIC, magic: c.MAGIC,
underline: c.UNDERLINE, underline: c.UNDERLINE,
reset: c.RESET reset: c.RESET
}; };
for (var method in formattingCodes){ for ( var method in formattingCodes ) {
String.prototype[method] = function(c){ String.prototype[method] = function( c ) {
return function(){return c+this;}; return function(){ return c + this; };
}(formattingCodes[method]); }( formattingCodes[method] );
} }

View file

@ -36,18 +36,18 @@ String, then it tries to find the player with that name.
***/ ***/
var _player = function ( playerName ) { var _player = function ( playerName ) {
if (typeof playerName == 'undefined'){ if ( typeof playerName == 'undefined' ) {
if (typeof self == 'undefined'){ if ( typeof self == 'undefined' ) {
return null; return null;
} else { } else {
return self; return self;
}
} else {
if (typeof playerName == 'string')
return org.bukkit.Bukkit.getPlayer(playerName);
else
return playerName; // assumes it's a player object
} }
} else {
if ( typeof playerName == 'string' )
return org.bukkit.Bukkit.getPlayer( playerName );
else
return playerName; // assumes it's a player object
}
}; };
/************************************************************************* /*************************************************************************
### utils.locationToJSON() function ### utils.locationToJSON() function
@ -73,15 +73,15 @@ This can be useful if you write a plugin that needs to store location data since
A JSON object in the above form. A JSON object in the above form.
***/ ***/
var _locationToJSON = function(location){ var _locationToJSON = function( location ) {
return { return {
world: ''+location.world.name, world: ''+location.world.name,
x: location.x, x: location.x,
y: location.y, y: location.y,
z: location.z, z: location.z,
yaw: location.yaw, yaw: location.yaw,
pitch: location.pitch pitch: location.pitch
}; };
}; };
/************************************************************************* /*************************************************************************
### utils.locationToString() function ### utils.locationToString() function
@ -102,8 +102,8 @@ keys in a lookup table.
lookupTable[key] = player.name; lookupTable[key] = player.name;
***/ ***/
exports.locationToString = function(location){ exports.locationToString = function( location ) {
return JSON.stringify(_locationToJSON(location)); return JSON.stringify( _locationToJSON( location ) );
}; };
exports.locationToJSON = _locationToJSON; exports.locationToJSON = _locationToJSON;
@ -117,21 +117,23 @@ returned by locationToJSON() and reconstructs and returns a bukkit
Location object. Location object.
***/ ***/
exports.locationFromJSON = function(json){ exports.locationFromJSON = function( json ) {
if (json.constuctor == Array){ var world;
// for support of legacy format if ( json.constuctor == Array ) {
var world = org.bukkit.Bukkit.getWorld(json[0]); // for support of legacy format
return new org.bukkit.Location(world, json[1], json[2] , json[3]); world = org.bukkit.Bukkit.getWorld( json[0] );
}else{ return new org.bukkit.Location( world, json[1], json[2] , json[3] );
var world = org.bukkit.Bukkit.getWorld(json.world); } else {
return new org.bukkit.Location(world, json.x, json.y , json.z, json.yaw, json.pitch); world = org.bukkit.Bukkit.getWorld( json.world );
} return new org.bukkit.Location( world, json.x, json.y , json.z, json.yaw, json.pitch );
}
}; };
exports.player = _player; exports.player = _player;
exports.getPlayerObject = function(player){
console.warn('utils.getPlayerObject() is deprecated. Use utils.player() instead.'); exports.getPlayerObject = function( player ) {
return _player(player); console.warn( 'utils.getPlayerObject() is deprecated. Use utils.player() instead.' );
return _player(player);
}; };
/************************************************************************* /*************************************************************************
### utils.getPlayerPos() function ### utils.getPlayerPos() function
@ -153,15 +155,14 @@ An [org.bukkit.Location][bkloc] object.
[bksndr]: http://jd.bukkit.org/dev/apidocs/index.html?org/bukkit/command/CommandSender.html [bksndr]: http://jd.bukkit.org/dev/apidocs/index.html?org/bukkit/command/CommandSender.html
***/ ***/
exports.getPlayerPos = function( player ) { exports.getPlayerPos = function( player ) {
player = _player(player); player = _player( player );
if (player){ if ( player ) {
if (player instanceof org.bukkit.command.BlockCommandSender) if ( player instanceof org.bukkit.command.BlockCommandSender )
return player.block.location; return player.block.location;
else
return player.location;
}
else else
return null; return player.location;
}
return null;
}; };
/************************************************************************ /************************************************************************
### utils.getMousePos() function ### utils.getMousePos() function
@ -186,19 +187,21 @@ The following code will strike lightning at the location the player is looking a
} }
***/ ***/
exports.getMousePos = function (player) { exports.getMousePos = function( player ) {
player = _player(player); player = _player(player);
if (!player) if ( !player ) {
return null; return null;
// player might be CONSOLE or a CommandBlock }
if (!player.getTargetBlock) // player might be CONSOLE or a CommandBlock
return null; if ( !player.getTargetBlock ) {
var targetedBlock = player.getTargetBlock(null,5); return null;
if (targetedBlock == null || targetedBlock.isEmpty()){ }
return null; var targetedBlock = player.getTargetBlock( null, 5 );
} if ( targetedBlock == null || targetedBlock.isEmpty() ) {
return targetedBlock.location; return null;
}
return targetedBlock.location;
}; };
/************************************************************************ /************************************************************************
### utils.foreach() function ### utils.foreach() function
@ -228,7 +231,7 @@ package for scheduling processing of arrays.
- object : Additional (optional) information passed into the foreach method. - object : Additional (optional) information passed into the foreach method.
- array : The entire array. - array : The entire array.
* object (optional) : An object which may be used by the callback. * context (optional) : An object which may be used by the callback.
* delay (optional, numeric) : If a delay is specified (in ticks - 20 * delay (optional, numeric) : If a delay is specified (in ticks - 20
ticks = 1 second), then the processing will be scheduled so that ticks = 1 second), then the processing will be scheduled so that
each item will be processed in turn with a delay between the completion of each each item will be processed in turn with a delay between the completion of each
@ -286,20 +289,26 @@ without hogging CPU usage...
utils.foreach (a, processItem, null, 10, onDone); utils.foreach (a, processItem, null, 10, onDone);
***/ ***/
var _foreach = function(array, callback, object, delay, onCompletion) { var _foreach = function( array, callback, context, delay, onCompletion ) {
if (array instanceof java.util.Collection) if ( array instanceof java.util.Collection ) {
array = array.toArray(); array = array.toArray();
var i = 0; }
var len = array.length; var i = 0;
if (delay){ var len = array.length;
var next = function(){ callback(array[i],i,object,array); i++;}; if ( delay ) {
var hasNext = function(){return i < len;}; var next = function( ) {
_nicely(next,hasNext,onCompletion,delay); callback(array[i], i, context, array);
}else{ i++;
for (;i < len; i++){ };
callback(array[i],i,object,array); var hasNext = function( ) {
} return i < len;
};
_nicely( next, hasNext, onCompletion, delay );
} else {
for ( ;i < len; i++ ) {
callback( array[i], i, context, array );
} }
}
}; };
exports.foreach = _foreach; exports.foreach = _foreach;
/************************************************************************ /************************************************************************
@ -327,16 +336,17 @@ function and the start of the next `next()` function.
See the source code to utils.foreach for an example of how utils.nicely is used. See the source code to utils.foreach for an example of how utils.nicely is used.
***/ ***/
var _nicely = function(next, hasNext, onDone, delay){ var _nicely = function( next, hasNext, onDone, delay ) {
if (hasNext()){ if ( hasNext() ){
next(); next();
server.scheduler.runTaskLater(__plugin,function(){ server.scheduler.runTaskLater( __plugin, function() {
_nicely(next,hasNext,onDone,delay); _nicely( next, hasNext, onDone, delay );
},delay); }, delay );
}else{ }else{
if (onDone) if ( onDone ) {
onDone(); onDone();
} }
}
}; };
exports.nicely = _nicely; exports.nicely = _nicely;
/************************************************************************ /************************************************************************
@ -360,34 +370,34 @@ To warn players when night is approaching...
utils.at( '19:00', function() { utils.at( '19:00', function() {
utils.foreach( server.onlinePlayers, function(player){ utils.foreach( server.onlinePlayers, function( player ) {
player.chat('The night is dark and full of terrors!'); player.chat( 'The night is dark and full of terrors!' );
}); });
}); });
***/ ***/
exports.at = function(time24hr, callback, worlds) { exports.at = function( time24hr, callback, worlds ) {
var forever = function(){ return true;}; var forever = function(){ return true; };
var timeParts = time24hr.split(':'); var timeParts = time24hr.split( ':' );
var hrs = ((timeParts[0] * 1000) + 18000) % 24000; var hrs = ( (timeParts[0] * 1000) + 18000 ) % 24000;
var mins; var mins;
if (timeParts.length > 1) if ( timeParts.length > 1 ) {
mins = (timeParts[1] / 60) * 1000; mins = ( timeParts[1] / 60 ) * 1000;
}
var timeMc = hrs + mins; var timeMc = hrs + mins;
if (typeof worlds == 'undefined'){ if ( typeof worlds == 'undefined' ) {
worlds = server.worlds; worlds = server.worlds;
} }
_nicely(function(){ _nicely( function() {
_foreach (worlds, function (world){ _foreach( worlds, function ( world ) {
var time = world.getTime(); var time = world.getTime();
var diff = timeMc - time; var diff = timeMc - time;
if (diff > 0 && diff < 100){ if ( diff > 0 && diff < 100 ) {
callback(); callback();
} }
}); });
},forever, null, 100); }, forever, null, 100 );
}; };
/************************************************************************ /************************************************************************
@ -411,25 +421,25 @@ a given directory and recursiving trawling all sub-directories.
}); });
***/ ***/
exports.find = function( dir , filter){ exports.find = function( dir , filter ) {
var result = []; var result = [];
var recurse = function(dir, store){ var recurse = function( dir, store ) {
var files, dirfile = new java.io.File(dir); var files, dirfile = new java.io.File( dir );
if (typeof filter == 'undefined') if ( typeof filter == 'undefined' ) {
files = dirfile.list(); files = dirfile.list();
else } else {
files = dirfile.list(filter); files = dirfile.list(filter);
_foreach(files, function (file){
file = new java.io.File(dir + '/' + file);
if (file.isDirectory()){
recurse(file.canonicalPath, store);
}else{
store.push(file.canonicalPath);
}
});
} }
recurse(dir,result); _foreach( files, function( file ) {
return result; file = new java.io.File( dir + '/' + file );
} if ( file.isDirectory() ) {
recurse( file.canonicalPath, store );
} else {
store.push( file.canonicalPath );
}
});
};
recurse( dir, result );
return result;
};

View file

@ -52,7 +52,7 @@ console. Aliases will not be able to avail of command autocompletion
***/ ***/
var _usage = "\ var _usage = '\
/jsp alias set {alias} = {comand-1} ;{command-2}\n \ /jsp alias set {alias} = {comand-1} ;{command-2}\n \
/jsp alias global {alias} = {command-1} ; {command-2}\n \ /jsp alias global {alias} = {command-1} ; {command-2}\n \
/jsp alias list\n \ /jsp alias list\n \
@ -61,7 +61,7 @@ Create a new alias : \n \
/jsp alias set cw = time set {1} ; weather {2}\n \ /jsp alias set cw = time set {1} ; weather {2}\n \
Execute the alias : \n \ Execute the alias : \n \
/cw 4000 sun \n \ /cw 4000 sun \n \
...is the same as '/time set 4000' and '/weather sun'"; ...is the same as \'/time set 4000\' and \'/weather sun\'';
/* /*
persist aliases persist aliases
*/ */
@ -74,80 +74,80 @@ var _store = {
_processParams is a private function which takes an array of parameters _processParams is a private function which takes an array of parameters
used for the 'set' and 'global' options. used for the 'set' and 'global' options.
*/ */
var _processParams = function(params){ var _processParams = function( params ) {
var paramStr = params.join(' '), var paramStr = params.join(' '),
eqPos = paramStr.indexOf('='), eqPos = paramStr.indexOf('='),
aliasCmd = paramStr.substring(0,eqPos).trim(), aliasCmd = paramStr.substring( 0, eqPos).trim(),
aliasValue = paramStr.substring(eqPos+1).trim(); aliasValue = paramStr.substring( eqPos + 1 ).trim();
return { return {
cmd: aliasCmd, cmd: aliasCmd,
aliases: aliasValue.split(/\s*;\s*/) aliases: aliasValue.split( /\s*;\s*/ )
}; };
}; };
var _set = function(params, player){ var _set = function( params, player ) {
var playerAliases = _store.players[player.name]; var playerAliases = _store.players[player.name];
if (!playerAliases){ if (!playerAliases ) {
playerAliases = {}; playerAliases = {};
} }
var o = _processParams(params); var o = _processParams( params );
playerAliases[o.cmd] = o.aliases; playerAliases[o.cmd] = o.aliases;
_store.players[player.name] = playerAliases; _store.players[player.name] = playerAliases;
player.sendMessage("Alias '" + o.cmd + "' created."); player.sendMessage( 'Alias ' + o.cmd + ' created.' );
}; };
var _remove = function(params, player){ var _remove = function( params, player ) {
if (_store.players[player.name] && if ( _store.players[player.name] && _store.players[player.name][ params[0] ] ) {
_store.players[player.name][params[0]]){
delete _store.players[player.name][params[0]]; delete _store.players[player.name][params[0]];
player.sendMessage("Alias '" + params[0] + "' removed."); player.sendMessage( 'Alias ' + params[0] + ' removed.' );
} }
else{ else{
player.sendMessage("Alias '" + params[0] + "' does not exist."); player.sendMessage( 'Alias ' + params[0] + ' does not exist.' );
} }
if (player.op){ if ( player.op ) {
if (_store.global[params[0]]) if ( _store.global[params[0]] ) {
delete _store.global[params[0]]; delete _store.global[params[0]];
}
} }
}; };
var _global = function(params, player){ var _global = function( params, player ) {
if (!player.op){ if ( !player.op ) {
player.sendMessage("Only operators can set global aliases. " + player.sendMessage( 'Only operators can set global aliases. ' +
"You need to be an operator to perform this command."); 'You need to be an operator to perform this command.' );
return; return;
} }
var o = _processParams(params); var o = _processParams( params );
_store.global[o.cmd] = o.aliases; _store.global[o.cmd] = o.aliases;
player.sendMessage("Global alias '" + o.cmd + "' created."); player.sendMessage( 'Global alias ' + o.cmd + ' created.' );
}; };
var _list = function(params, player){ var _list = function( params, player ) {
var alias = 0; var alias = 0;
try { try {
if (_store.players[player.name]){ if ( _store.players[player.name] ) {
player.sendMessage("Your aliases:"); player.sendMessage('Your aliases:');
for (alias in _store.players[player.name]){ for ( alias in _store.players[player.name] ) {
player.sendMessage(alias + " = " + player.sendMessage( alias + ' = ' +
JSON.stringify(_store.players[player.name][alias])); JSON.stringify( _store.players[player.name][alias] ) );
} }
}else{ } else {
player.sendMessage("You have no player-specific aliases."); player.sendMessage( 'You have no player-specific aliases.' );
} }
player.sendMessage("Global aliases:"); player.sendMessage( 'Global aliases:' );
for (alias in _store.global){ for ( alias in _store.global ) {
player.sendMessage(alias + " = " + JSON.stringify(_store.global[alias]) ); player.sendMessage( alias + ' = ' + JSON.stringify( _store.global[alias] ) );
} }
}catch(e){ } catch( e ) {
console.error("Error in list function: " + e.message); console.error( 'Error in list function: ' + e.message );
throw e; throw e;
} }
}; };
var _help = function(params, player){ var _help = function( params, player ) {
player.sendMessage('Usage:\n' + _usage); player.sendMessage( 'Usage:\n' + _usage );
}; };
var alias = plugin('alias', { var alias = plugin( 'alias', {
store: _store, store: _store,
set: _set, set: _set,
global: _global, global: _global,
@ -156,11 +156,11 @@ var alias = plugin('alias', {
help: _help help: _help
}, true ); }, true );
var aliasCmd = command('alias', function( params, invoker ) { var aliasCmd = command( 'alias', function( params, invoker ) {
var operation = params[0], var operation = params[0],
fn; fn;
if (!operation){ if ( !operation ) {
invoker.sendMessage('Usage:\n' + _usage); invoker.sendMessage( 'Usage:\n' + _usage );
return; return;
} }
/* /*
@ -168,53 +168,53 @@ var aliasCmd = command('alias', function( params, invoker ) {
accessing object properties by array index notation accessing object properties by array index notation
in JRE8 alias[operation] returns null - definitely a bug in Nashorn. in JRE8 alias[operation] returns null - definitely a bug in Nashorn.
*/ */
for (var key in alias){ for ( var key in alias ) {
if (key == operation){ if ( key == operation ) {
fn = alias[key]; fn = alias[key];
fn(params.slice(1),invoker); fn( params.slice(1), invoker );
return; return;
} }
} }
invoker.sendMessage('Usage:\n' + _usage); invoker.sendMessage( 'Usage:\n' + _usage );
}); });
var _intercept = function( msg, invoker, exec) var _intercept = function( msg, invoker, exec ) {
{ if ( msg.trim().length == 0 )
if (msg.trim().length == 0)
return false; return false;
var msgParts = msg.split(' '), var msgParts = msg.split(' '),
command = msg.match(/^\/*([^\s]+)/)[1], command = msg.match( /^\/*([^\s]+)/ )[1],
template = [], isAlias = false, cmds = [], template = [],
isAlias = false,
cmds = [],
commandObj, commandObj,
filledinCommand; filledinCommand,
i;
if (_store.global[command]){ if ( _store.global[command] ) {
template = _store.global[command]; template = _store.global[command];
isAlias = true; isAlias = true;
} }
/* /*
allows player-specific aliases to override global aliases allows player-specific aliases to override global aliases
*/ */
if (_store.players[invoker] && if ( _store.players[invoker] && _store.players[invoker][command] ) {
_store.players[invoker][command])
{
template = _store.players[invoker][command]; template = _store.players[invoker][command];
isAlias = true; isAlias = true;
} }
for (var i = 0;i < template.length; i++) for ( i = 0; i < template.length; i++) {
{ filledinCommand = template[i].replace( /{([0-9]+)}/g, function( match, index ) {
filledinCommand = template[i].replace(/{([0-9]+)}/g, function (match,index){ index = parseInt( index, 10 );
index = parseInt(index,10); if ( msgParts[index] ) {
if (msgParts[index])
return msgParts[index]; return msgParts[index];
else } else {
return match; return match;
}
}); });
cmds.push(filledinCommand); cmds.push( filledinCommand );
} }
for (var i = 0; i< cmds.length; i++){ for (i = 0; i< cmds.length; i++ ) {
exec(cmds[i]); exec( cmds[i] );
} }
return isAlias; return isAlias;
@ -223,20 +223,27 @@ var _intercept = function( msg, invoker, exec)
Intercept all command processing and replace with aliased commands if the Intercept all command processing and replace with aliased commands if the
command about to be issued matches an alias. command about to be issued matches an alias.
*/ */
events.on('player.PlayerCommandPreprocessEvent', function(listener,evt){ events.on( 'player.PlayerCommandPreprocessEvent', function( listener, evt ) {
var invoker = evt.player; var invoker = evt.player;
var exec = function(cmd){ invoker.performCommand(cmd);}; var exec = function( cmd ) {
var isAlias = _intercept(''+evt.message, ''+invoker.name, exec); invoker.performCommand(cmd);
if (isAlias) };
var isAlias = _intercept( ''+evt.message, ''+invoker.name, exec);
if ( isAlias ) {
evt.cancelled = true; evt.cancelled = true;
}
}); });
/* define a 'void' command because ServerCommandEvent can't be canceled */ /* define a 'void' command because ServerCommandEvent can't be canceled */
command('void',function(){}); command('void',function( ) {
} );
events.on('server.ServerCommandEvent', function(listener,evt){ events.on( 'server.ServerCommandEvent', function( listener, evt ) {
var invoker = evt.sender; var invoker = evt.sender;
var exec = function(cmd){ invoker.server.dispatchCommand(invoker, cmd); }; var exec = function( cmd ) {
var isAlias = _intercept(''+evt.command, ''+ invoker.name, exec); invoker.server.dispatchCommand( invoker, cmd);
if (isAlias) };
var isAlias = _intercept( ''+evt.command, ''+ invoker.name, exec );
if ( isAlias ) {
evt.command = 'jsp void'; evt.command = 'jsp void';
}
}); });

View file

@ -25,130 +25,98 @@ player23's arrows explosive.
***/ ***/
var signs = require('signs'); var signs = require('signs'),
var fireworks = require('fireworks'); fireworks = require('fireworks'),
var utils = require('utils'); utils = require('utils'),
EXPLOSIVE_YIELD = 2.5,
var _store = {players: {}}; _store = { players: { } },
arrows = plugin( 'arrows', { store: _store }, true ),
var arrows = plugin("arrows",{ i,
/* type,
turn a sign into a menu of arrow choices _types = [ 'Normal', 'Explosive', 'Teleport', 'Flourish', 'Lightning', 'Firework' ];
*/
sign: function(sign){},
/*
change player's arrows to normal
*/
normal: function(player){},
/*
change player's arrows to explode on impact
*/
explosive: function(player){},
/*
change player's arrows to teleporting
*/
teleport: function(player){},
/*
change player's arrows to plant trees where they land
*/
flourish: function(player){},
/*
change player's arrows to strike lightning where they land
*/
lightning: function(player){},
/*
launch a firework where the arrow lands
*/
explosiveYield: 2.5,
store: _store
},true);
exports.arrows = arrows; exports.arrows = arrows;
//
// setup functions for the arrow types for ( i = 0; i < _types.length; i++ ) {
// type = _types[i].toLowerCase();
var _types = {normal: 0, explosive: 1, teleport: 2, flourish: 3, lightning: 4, firework: 5}; // iife (immediately-invoked function expression)
for (var type in _types) arrows[ type ] = ( function( n ) {
{ return function( player ) {
arrows[type] = (function(n){ player = utils.player( player );
return function(player){ if ( player ) {
player = utils.player(player); arrows.store.players[ player.name ] = n;
if (player) } else {
arrows.store.players[player.name] = n; console.warn('arrows.' + n + ' No player ' + player);
else }
console.warn('arrows.' + n + ' No player ' + player); };
}; } )( i );
})(_types[type]);
} }
/* /*
called when the player chooses an arrow option from a menu sign called when the player chooses an arrow option from a menu sign
*/ */
var _onMenuChoice = function(event){ var _onMenuChoice = function( event ) {
arrows.store.players[event.player.name] = event.number; arrows.store.players[ event.player.name ] = event.number;
}; };
var convertToArrowSign = signs.menu( var convertToArrowSign = signs.menu( 'Arrow', _types, _onMenuChoice );
"Arrow",
["Normal","Explosive","Teleport","Flourish","Lightning","Firework"],
_onMenuChoice);
arrows.sign = function(cmdSender) /*
{ turn a sign into a menu of arrow choices
var sign = signs.getTargetedBy(cmdSender); */
if (!sign){ arrows.sign = function( cmdSender ) {
throw new Error('You must first look at a sign!'); var sign = signs.getTargetedBy( cmdSender );
} if ( !sign ) {
return convertToArrowSign(sign,true); throw new Error( 'You must first look at a sign!' );
}
return convertToArrowSign( sign, true );
}; };
/* /*
event handler called when a projectile hits something event handler called when a projectile hits something
*/ */
var _onArrowHit = function(listener,event) var _onArrowHit = function( listener, event ) {
{ var projectile = event.entity,
var projectile = event.entity; world = projectile.world,
var world = projectile.world; shooter = projectile.shooter,
var shooter = projectile.shooter; fireworkCount = 5,
var fireworkCount = 5; arrowType,
if (projectile instanceof org.bukkit.entity.Arrow && TeleportCause = org.bukkit.event.player.PlayerTeleportEvent.TeleportCause,
shooter instanceof org.bukkit.entity.Player) launch = function( ) {
{ fireworks.firework( projectile.location );
var arrowType = arrows.store.players[shooter.name]; if ( --fireworkCount ) {
setTimeout( launch, 2000 );
}
};
switch (arrowType){ if (projectile instanceof org.bukkit.entity.Arrow
case 1: && shooter instanceof org.bukkit.entity.Player) {
projectile.remove();
world.createExplosion(projectile.location,arrows.explosiveYield); arrowType = arrows.store.players[ shooter.name ];
break;
case 2: switch ( arrowType ) {
projectile.remove(); case 1:
var teleportCause =org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; projectile.remove();
shooter.teleport(projectile.location, world.createExplosion( projectile.location, EXPLOSIVE_YIELD );
teleportCause.PLUGIN); break;
break; case 2:
case 3: projectile.remove();
projectile.remove(); shooter.teleport( projectile.location, TeleportCause.PLUGIN );
world.generateTree(projectile.location, org.bukkit.TreeType.BIG_TREE); break;
break; case 3:
case 4: projectile.remove();
projectile.remove(); world.generateTree( projectile.location, org.bukkit.TreeType.BIG_TREE );
world.strikeLightning(projectile.location); break;
break; case 4:
case 5: projectile.remove();
projectile.remove(); world.strikeLightning( projectile.location );
var launch = function(){ break;
fireworks.firework(projectile.location); case 5:
if (--fireworkCount) projectile.remove();
setTimeout(launch,2000); launch();
}; break;
launch();
break;
}
} }
}
}; };
events.on('entity.ProjectileHitEvent',_onArrowHit); events.on( 'entity.ProjectileHitEvent', _onArrowHit );

View file

@ -1,54 +1,72 @@
/* /*
TODO: Document this module TODO: Document this module
*/ */
var _store = {players: {}}; var _store = { players: { } },
colorCodes = {},
i,
colors = [
'black',
'blue',
'darkgreen',
'darkaqua',
'darkred',
'purple',
'gold',
'gray',
'darkgray',
'indigo',
'brightgreen',
'aqua',
'red',
'pink',
'yellow',
'white'
],
foreach = require('utils').foreach;
/* /*
declare a new javascript plugin for changing chat text color declare a new javascript plugin for changing chat text color
*/ */
exports.chat = plugin("chat", { exports.chat = plugin( 'chat', {
/* /*
set the color of text for a given player set the color of text for a given player
*/ */
setColor: function(player, color){ setColor: function( player, color ) {
_store.players[player.name] = color; _store.players[ player.name ] = color;
}, },
store: _store store: _store
},true); },true);
var colors = [ foreach( colors, function ( color, i ) {
"black", "blue", "darkgreen", "darkaqua", "darkred", colorCodes[color] = i.toString( 16 );
"purple", "gold", "gray", "darkgray", "indigo", } );
"brightgreen", "aqua", "red", "pink", "yellow", "white"
];
var colorCodes = {};
for (var i =0;i < colors.length;i++) {
var hexCode = i.toString(16);
colorCodes[colors[i]] = hexCode;
}
events.on("player.AsyncPlayerChatEvent",function(l,e){ events.on( 'player.AsyncPlayerChatEvent', function( l, e ) {
var player = e.player; var player = e.player;
var playerChatColor = _store.players[player.name]; var playerChatColor = _store.players[ player.name ];
if (playerChatColor){ if ( playerChatColor ) {
e.message = "§" + colorCodes[playerChatColor] + e.message; e.message = '§' + colorCodes[ playerChatColor ] + e.message;
} }
}); });
var listColors = function(params,sender){
var colorNamesInColor = []; var listColors = function( params, sender ) {
for (var i = 0;i < colors.length;i++) var colorNamesInColor = [];
colorNamesInColor[i] = "§"+colorCodes[colors[i]] + colors[i]; foreach (colors, function( color ) {
sender.sendMessage("valid chat colors are " + colorNamesInColor.join(", ")); colorNamesInColor.push( '§' + colorCodes[color] + color );
}; } );
command("list_colors", listColors); sender.sendMessage( 'valid chat colors are ' + colorNamesInColor.join( ', ') );
command("chat_color",function(params,sender){ };
var color = params[0];
if (colorCodes[color]){ command( 'list_colors', listColors );
chat.setColor(sender,color); command( 'chat_color', function( params, sender ) {
}else{ var color = params[0];
sender.sendMessage(color + " is not a valid color"); if ( colorCodes[color] ) {
listColors(); chat.setColor( sender, color );
} } else {
},colors); sender.sendMessage( color + ' is not a valid color' );
listColors();
}
}, colors );

View file

@ -1,4 +1,4 @@
var utils = require('utils'); var foreach = require('utils').foreach;
/************************************************************************ /************************************************************************
## Classroom Plugin ## Classroom Plugin
@ -32,59 +32,61 @@ to every student in a Minecraft classroom environment.
To allow all players (and any players who connect to the server) to To allow all players (and any players who connect to the server) to
use the `js` and `jsp` commands... use the `js` and `jsp` commands...
/js classroom.allowScripting(true,self) /js classroom.allowScripting( true, self )
To disallow scripting (and prevent players who join the server from using the commands)... To disallow scripting (and prevent players who join the server from using the commands)...
/js classroom.allowScripting(false,self) /js classroom.allowScripting( false, self )
Only ops users can run the classroom.allowScripting() function - this is so that students 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. don't try to bar themselves and each other from scripting.
***/ ***/
var _store = {enableScripting: false}; var _store = { enableScripting: false };
var classroom = plugin("classroom", { var classroom = plugin('classroom', {
allowScripting: function (/* boolean: true or false */ canScript, sender) { allowScripting: function (/* boolean: true or false */ canScript, sender ) {
if (typeof sender == 'undefined'){ if ( typeof sender == 'undefined' ) {
console.log("Attempt to set classroom scripting without credentials"); console.log( 'Attempt to set classroom scripting without credentials' );
console.log("classroom.allowScripting(boolean, sender)"); console.log( 'classroom.allowScripting(boolean, sender)' );
return; return;
} }
if (!sender.op){ if ( !sender.op ) {
console.log("Attempt to set classroom scripting without credentials: " + sender.name); console.log( 'Attempt to set classroom scripting without credentials: ' + sender.name );
return; return;
} }
/* /*
only operators should be allowed run this function only operators should be allowed run this function
*/ */
if (!sender.isOp()) if ( !sender.isOp() ) {
return; return;
if (canScript){ }
utils.foreach( server.onlinePlayers, function (player) { if ( canScript ) {
player.addAttachment(__plugin, "scriptcraft.*", true); foreach( server.onlinePlayers, function( player ) {
}); player.addAttachment( __plugin, 'scriptcraft.*', true );
}else{ });
utils.foreach( server.onlinePlayers, function(player) { } else {
utils.foreach(player.getEffectivePermissions(), function(perm) { foreach( server.onlinePlayers, function( player ) {
if ((""+perm.permission).indexOf("scriptcraft.") == 0){ foreach( player.getEffectivePermissions(), function( perm ) {
if (perm.attachment) if ( (''+perm.permission).indexOf( 'scriptcraft.' ) == 0 ) {
perm.attachment.remove(); if ( perm.attachment ) {
} perm.attachment.remove();
}); }
}); }
} });
_store.enableScripting = canScript; });
}, }
store: _store _store.enableScripting = canScript;
},
store: _store
}, true); }, true);
exports.classroom = classroom; exports.classroom = classroom;
events.on('player.PlayerLoginEvent', function(listener, event) { events.on( 'player.PlayerLoginEvent', function( listener, event ) {
var player = event.player; var player = event.player;
if (_store.enableScripting){ if ( _store.enableScripting ) {
player.addAttachment(__plugin, "scriptcraft.*", true); player.addAttachment( __plugin, 'scriptcraft.*', true );
} }
}, 'HIGHEST'); }, 'HIGHEST');

View file

@ -1,21 +1,22 @@
/* /*
A test of the commando plugin. A test of the commando plugin.
Adds a new `/scriptcrafttimeofday` command with 4 possible options: Dawn, Midday, Dusk, Midnight Adds a new `/js-time` command with 4 possible options: Dawn, Midday, Dusk, Midnight
*/ */
var commando = require('./commando').commando; var commando = require('./commando').commando,
var times = { times = ['Dawn','Midday','Dusk','Midnight'];
Dawn: 0,
Midday: 6000, commando( 'js-time' , function( params, sender ) {
Dusk: 12000, var time = ''+params[0].toLowerCase(),
Midnight: 18000 i = 0;
}; if ( sender.location ) {
commando('scriptcrafttimeofday',function(params,sender){ for ( ; i < 4; i++ ) {
if (config.verbose){ if ( times.toLowerCase() == time ) {
console.log('scriptcrafttimeofday.params=%s',JSON.stringify(params)); sender.location.world.setTime( i * 6000 );
break;
}
} }
if (sender.location) } else {
sender.location.world.setTime(times[params[0]]); sender.sendMessage('This command only works in-world');
else }
sender.sendMessage('This command only works in-world');
},['Dawn','Midday','Dusk','Midnight']); },times);

View file

@ -78,37 +78,41 @@ global commands for a plugin, please let me know.
***/ ***/
var commands = {}; var commands = {};
exports.commando = function(name, func, options, intercepts){ exports.commando = function( name, func, options, intercepts ) {
var result = command(name, func, options, intercepts); var result = command( name, func, options, intercepts );
commands[name] = result; commands[name] = result;
return result; return result;
}; };
events.on('player.PlayerCommandPreprocessEvent', function(l,e){ events.on( 'player.PlayerCommandPreprocessEvent', function( l, e ) {
var msg = '' + e.message; var msg = '' + e.message;
var parts = msg.match(/^\/([^\s]+)/); var parts = msg.match( /^\/([^\s]+)/ );
if (!parts) if ( !parts ) {
return; return;
if (parts.length < 2) }
return; if ( parts.length < 2 ) {
var command = parts[1]; return;
if (commands[command]){ }
e.message = "/jsp " + msg.replace(/^\//,""); var command = parts[1];
} if ( commands[command] ) {
}); e.message = '/jsp ' + msg.replace( /^\//, '' );
events.on('server.ServerCommandEvent', function(l,e){ }
var msg = '' + e.command; } );
var parts = msg.match(/^\/*([^\s]+)/); events.on( 'server.ServerCommandEvent', function( l, e ) {
if (!parts) var msg = '' + e.command;
return; var parts = msg.match( /^\/*([^\s]+)/ );
if (parts.length < 2) if ( !parts ) {
return; return;
var command = parts[1]; }
if (commands[command]){ if ( parts.length < 2 ) {
var newCmd = "jsp " + msg.replace(/^\//,""); return;
if (config.verbose){ }
console.log('Redirecting to : %s',newCmd); var command = parts[1];
} if ( commands[ command ] ) {
e.command = newCmd; var newCmd = 'jsp ' + msg.replace( /^\//, '' );
if ( config.verbose ) {
console.log( 'Redirecting to : %s', newCmd );
} }
e.command = newCmd;
}
}); });

View file

@ -307,16 +307,24 @@ var bitmaps = {
/* /*
wph 20130121 compute the width, and x,y coords of pixels ahead of time wph 20130121 compute the width, and x,y coords of pixels ahead of time
*/ */
for (var c in bitmaps.raw){ var c,
var bits = bitmaps.raw[c]; bits,
var width = bits.length/5; width,
var bmInfo = {"width": width,"pixels":[]} bmInfo,
bitmaps.computed[c] = bmInfo; j;
for (var j = 0; j < bits.length; j++){ for ( c in bitmaps.raw ) {
if (bits.charAt(j) != ' '){ bits = bitmaps.raw[c];
bmInfo.pixels.push([j%width,Math.ceil(j/width)]); width = bits.length/5;
} bmInfo = { width: width, pixels:[] };
bitmaps.computed[c] = bmInfo;
for ( j = 0; j < bits.length; j++ ) {
if ( bits.charAt(j) != ' ' ) {
bmInfo.pixels.push( [
j % width,
Math.ceil( j / width )
] );
} }
}
} }
@ -328,46 +336,72 @@ for (var c in bitmaps.raw){
// bg // bg
// background material, optional. The negative space within the bounding box of the text. // background material, optional. The negative space within the bounding box of the text.
// //
Drone.extend('blocktype', function(message,fg,bg){ Drone.extend('blocktype', function( message, fg, bg ) {
this.chkpt('blocktext'); var bmfg,
bmbg,
lines,
lineCount,
h,
line,
i,
x,
y,
ch,
bits,
charWidth,
j;
if (typeof fg == "undefined") this.chkpt('blocktext');
fg = blocks.wool.black;
var bmfg = this._getBlockIdAndMeta(fg); if ( typeof fg == 'undefined' ) {
var bmbg = null; fg = blocks.wool.black;
if (typeof bg != "undefined") }
bmbg = this._getBlockIdAndMeta(bg);
var lines = message.split("\n"); bmfg = this._getBlockIdAndMeta( fg );
var lineCount = lines.length; bmbg = null;
for (var h = 0;h < lineCount; h++) { if ( typeof bg != 'undefined' ) {
var line = lines[h]; bmbg = this._getBlockIdAndMeta( bg );
line = line.toLowerCase().replace(/[^0-9a-z \.\-\+\/\;\'\:\!]/g,""); }
this.up(7*(lineCount-(h+1))); lines = message.split( '\n' );
lineCount = lines.length;
for (var i =0;i < line.length; i++) {
var ch = line.charAt(i) for ( h = 0; h < lineCount; h++) {
var bits = bitmaps.computed[ch];
if (typeof bits == "undefined"){ line = lines[h];
bits = bitmaps.computed[' ']; line = line.toLowerCase().replace( /[^0-9a-z \.\-\+\/\;\'\:\!]/g, '' );
} this.up( 7 * ( lineCount - ( h + 1 ) ) );
var charWidth = bits.width;
if (typeof bg != "undefined")
this.cuboidX(bmbg[0],bmbg[1],charWidth,7,1);
for (var j = 0;j < bits.pixels.length;j++){
this.chkpt('btbl');
var x = bits.pixels[j][0];
var y = bits.pixels[j][1];
this.up(6-y).right(x).cuboidX(bmfg[0],bmfg[1]);
this.move('btbl');
}
this.right(charWidth-1);
}
this.move('blocktext');
}
return this.move('blocktext'); for ( i =0; i < line.length; i++) {
ch = line.charAt( i );
bits = bitmaps.computed[ ch ];
if ( typeof bits == 'undefined' ) {
bits = bitmaps.computed[' '];
}
charWidth = bits.width;
if ( typeof bg != 'undefined' ) {
this.cuboidX( bmbg[0], bmbg[1], charWidth, 7, 1 );
}
for ( j = 0; j < bits.pixels.length; j++ ) {
this.chkpt( 'btbl' );
x = bits.pixels[ j ][ 0 ];
y = bits.pixels[ j ][ 1] ;
this.up( 6 - y ).right( x ).cuboidX( bmfg[ 0 ], bmfg[ 1 ] );
this.move( 'btbl' );
}
this.right( charWidth - 1 );
}
this.move( 'blocktext' );
}
return this.move( 'blocktext' );
}); });

View file

@ -3,49 +3,47 @@ var Drone = require('../drone').Drone;
// //
// a castle is just a big wide fort with 4 taller forts at each corner // a castle is just a big wide fort with 4 taller forts at each corner
// //
Drone.extend('castle', function(side, height) Drone.extend('castle', function( side, height ) {
{ //
// // use sensible default parameter values
// use sensible default parameter values // if no parameters are supplied
// if no parameters are supplied //
// if ( typeof side == "undefined" )
if (typeof side == "undefined") side = 24;
side = 24; if ( typeof height == "undefined" )
if (typeof height == "undefined") height = 10;
height = 10; if ( height < 8 || side < 20 )
if (height < 8 || side < 20) throw new java.lang.RuntimeException("Castles must be at least 20 wide X 8 tall");
throw new java.lang.RuntimeException("Castles must be at least 20 wide X 8 tall"); //
// // remember where the drone is so it can return 'home'
// remember where the drone is so it can return 'home' //
// this.chkpt('castle');
this.chkpt('castle'); //
// // how big the towers at each corner will be...
// how big the towers at each corner will be... //
// var towerSide = 10;
var towerSide = 10; var towerHeight = height+4;
var towerHeight = height+4;
// //
// the main castle building will be front and right of the first tower // the main castle building will be front and right of the first tower
// //
this.fwd(towerSide/2).right(towerSide/2); this.fwd(towerSide/2).right(towerSide/2);
// //
// the castle is really just a big fort with 4 smaller 'tower' forts at each corner // the castle is really just a big fort with 4 smaller 'tower' forts at each corner
// //
this.fort(side,height); this.fort(side,height);
// //
// move back to start position // move back to start position
// //
this.move('castle'); this.move('castle');
// //
// now place 4 towers at each corner (each tower is another fort) // now place 4 towers at each corner (each tower is another fort)
// //
for (var corner = 0; corner < 4; corner++) for ( var corner = 0; corner < 4; corner++ ) {
{ // construct a 'tower' fort
// construct a 'tower' fort this.fort(towerSide,towerHeight);
this.fort(towerSide,towerHeight); // move forward the length of the castle then turn right
// move forward the length of the castle then turn right this.fwd(side+towerSide-1).turn();
this.fwd(side+towerSide-1).turn(); }
} return this.move('castle');
return this.move('castle');
}); });

View file

@ -10,27 +10,29 @@ var blocks = require('blocks');
* width - width of the chessboard * width - width of the chessboard
* height - height of the chessboard * height - height of the chessboard
*/ */
Drone.extend("chessboard", function(whiteBlock, blackBlock, width, depth) { Drone.extend('chessboard', function( whiteBlock, blackBlock, width, depth ) {
this.chkpt('chessboard-start'); var i,
if (typeof whiteBlock == "undefined") j,
whiteBlock = blocks.wool.white; block;
if (typeof blackBlock == "undefined")
blackBlock = blocks.wool.black;
if (typeof width == "undefined")
width = 8;
if (typeof depth == "undefined")
depth = width;
for(var i = 0; i < width; ++i) { this.chkpt('chessboard-start');
for(var j = 0; j < depth; ++j) {
var block = blackBlock; if ( typeof whiteBlock == 'undefined' ) {
if((i+j)%2 == 1) { whiteBlock = blocks.wool.white;
block = whiteBlock; }
} if ( typeof blackBlock == 'undefined' ) {
this.box(block); blackBlock = blocks.wool.black;
this.right(); }
} if ( typeof width == 'undefined' ) {
this.move('chessboard-start').fwd(i+1); width = 8;
} }
return this.move('chessboard-start'); if ( typeof depth == 'undefined' ) {
depth = width;
}
var wb = [ blackBlock, whiteBlock ];
for ( i = 0; i < depth; i++ ) {
this.boxa( wb, width, 1, 1).fwd();
wb = wb.reverse();
}
return this.move('chessboard-start');
}); });

View file

@ -11,69 +11,67 @@ var Drone = require('../drone').Drone;
// /js drone.cottage(); // /js drone.cottage();
// //
Drone.extend('cottage',function () Drone.extend('cottage',function ( ) {
{ this.chkpt('cottage')
this.chkpt('cottage') .box0(48,7,2,6) // 4 walls
.box0(48,7,2,6) // 4 walls .right(3).door() // door front and center
.right(3).door() // door front and center .up(1).left(2).box(102) // windows to left and right
.up(1).left(2).box(102) // windows to left and right .right(4).box(102)
.right(4).box(102) .left(5).up().prism0(53,7,6);
.left(5).up().prism0(53,7,6);
// //
// put up a sign near door. // put up a sign near door.
// //
this.down().right(4).sign(["Home","Sweet","Home"],68); this.down().right(4)
.sign(['Home','Sweet','Home'],68);
return this.move('cottage'); return this.move('cottage');
}); });
// //
// a more complex script that builds an tree-lined avenue with // a more complex script that builds an tree-lined avenue with
// cottages on both sides. // cottages on both sides.
// //
Drone.extend('cottage_road', function(numberCottages) Drone.extend('cottage_road', function( numberCottages ) {
{ if (typeof numberCottages == 'undefined'){
if (typeof numberCottages == "undefined"){ numberCottages = 6;
numberCottages = 6; }
} var i=0, distanceBetweenTrees = 11;
var i=0, distanceBetweenTrees = 11; //
// // step 1 build the road.
// step 1 build the road. //
// var cottagesPerSide = Math.floor(numberCottages/2);
var cottagesPerSide = Math.floor(numberCottages/2); this
.chkpt('cottage_road') // make sure the drone's state is saved.
.box(43,3,1,cottagesPerSide*(distanceBetweenTrees+1)) // build the road
.up().right() // now centered in middle of road
.chkpt('cr'); // will be returning to this position later
//
// step 2 line the road with trees
//
for ( ; i < cottagesPerSide+1;i++ ) {
this this
.chkpt("cottage_road") // make sure the drone's state is saved. .left(5).oak()
.box(43,3,1,cottagesPerSide*(distanceBetweenTrees+1)) // build the road .right(10).oak()
.up().right() // now centered in middle of road .left(5) // return to middle of road
.chkpt("cr"); // will be returning to this position later .fwd(distanceBetweenTrees+1); // move forward.
}
this.move('cr').back(6); // move back 1/2 the distance between trees
// // this function builds a path leading to a cottage.
// step 2 line the road with trees function pathAndCottage( d ) {
// return d.down().box(43,1,1,5).fwd(5).left(3).up().cottage();
for (; i < cottagesPerSide+1;i++){ };
this //
.left(5).oak() // step 3 build cottages on each side
.right(10).oak() //
.left(5) // return to middle of road for ( i = 0; i < cottagesPerSide; i++ ) {
.fwd(distanceBetweenTrees+1); // move forward. this.fwd(distanceBetweenTrees+1).chkpt('r'+i);
} // build cottage on left
this.move("cr").back(6); // move back 1/2 the distance between trees pathAndCottage( this.turn(3) ).move( 'r' + i );
// build cottage on right
// this function builds a path leading to a cottage. pathAndCottage(this.turn()).move( 'r' + i );
function pathAndCottage(d){ }
return d.down().box(43,1,1,5).fwd(5).left(3).up().cottage(); // return drone to where it was at start of function
}; return this.move('cottage_road');
//
// step 3 build cottages on each side
//
for (i = 0;i < cottagesPerSide; i++)
{
this.fwd(distanceBetweenTrees+1).chkpt("r"+i);
// build cottage on left
pathAndCottage(this.turn(3)).move("r"+i);
// build cottage on right
pathAndCottage(this.turn()).move("r"+i);
}
// return drone to where it was at start of function
return this.move("cottage_road");
}); });

View file

@ -3,66 +3,69 @@ var Drone = require('../drone').Drone;
// //
// constructs a medieval fort // constructs a medieval fort
// //
Drone.extend('fort', function(side, height) Drone.extend('fort', function( side, height ) {
{ if ( typeof side == 'undefined' ) {
if (typeof side == "undefined") side = 18;
side = 18; }
if (typeof height == "undefined") if ( typeof height == 'undefined' ) {
height = 6; height = 6;
// make sure side is even }
if (side%2) // make sure side is even
side++; if ( side % 2 ) {
if (height < 4 || side < 10) side++;
throw new java.lang.RuntimeException("Forts must be at least 10 wide X 4 tall"); }
var brick = 98; if ( height < 4 || side < 10 ) {
// throw new java.lang.RuntimeException('Forts must be at least 10 wide X 4 tall');
// build walls. }
// var brick = 98;
this.chkpt('fort').box0(brick,side,height-1,side); //
// // build walls.
// build battlements //
// this.chkpt('fort').box0(brick,side,height-1,side);
this.up(height-1); //
for (i = 0;i <= 3;i++){ // build battlements
var turret = []; //
this.box(brick) // solid brick corners this.up(height-1);
.up().box('50:5').down() // light a torch on each corner for ( i = 0; i <= 3; i++ ) {
.fwd(); var turret = [];
turret.push('109:'+ Drone.PLAYER_STAIRS_FACING[this.dir]); this.box(brick) // solid brick corners
turret.push('109:'+ Drone.PLAYER_STAIRS_FACING[(this.dir+2)%4]); .up().box('50:5').down() // light a torch on each corner
try{ .fwd();
this.boxa(turret,1,1,side-2).fwd(side-2).turn(); turret.push('109:'+ Drone.PLAYER_STAIRS_FACING[this.dir]);
}catch(e){ turret.push('109:'+ Drone.PLAYER_STAIRS_FACING[(this.dir+2)%4]);
console.log("ERROR: " + e.toString()); try {
} this.boxa(turret,1,1,side-2).fwd(side-2).turn();
} catch( e ) {
console.log('ERROR: ' + e.toString());
} }
// }
// build battlement's floor //
// // build battlement's floor
this.move('fort'); //
this.up(height-2).fwd().right().box('126:0',side-2,1,side-2); this.move('fort');
var battlementWidth = 3; this.up(height-2).fwd().right().box('126:0',side-2,1,side-2);
if (side <= 12) var battlementWidth = 3;
battlementWidth = 2; if ( side <= 12 ) {
battlementWidth = 2;
this.fwd(battlementWidth).right(battlementWidth) }
.box(0,side-((1+battlementWidth)*2),1,side-((1+battlementWidth)*2)); this.fwd(battlementWidth).right(battlementWidth)
// .box(0,side-((1+battlementWidth)*2),1,side-((1+battlementWidth)*2));
// add door //
// // add door
var torch = '50:' + Drone.PLAYER_TORCH_FACING[this.dir]; //
this.move('fort').right((side/2)-1).door2() // double doors var torch = '50:' + Drone.PLAYER_TORCH_FACING[this.dir];
.back().left().up() this.move('fort').right((side/2)-1).door2() // double doors
.box(torch) // left torch .back().left().up()
.right(3) .box(torch) // left torch
.box(torch); // right torch .right(3)
// .box(torch); // right torch
// add ladder up to battlements //
// // add ladder up to battlements
var ladder = '65:' + Drone.PLAYER_SIGN_FACING[(this.dir+2)%4]; //
this.move('fort').right((side/2)-3).fwd(1) // move inside fort var ladder = '65:' + Drone.PLAYER_SIGN_FACING[(this.dir+2)%4];
.box(ladder, 1,height-1,1); this.move('fort').right((side/2)-3).fwd(1) // move inside fort
return this.move('fort'); .box(ladder, 1,height-1,1);
return this.move('fort');
}); });

View file

@ -17,21 +17,21 @@ exports.LCDClock = function(drone, fgColor,bgColor,border) {
world = drone.world, world = drone.world,
intervalId = -1; intervalId = -1;
if (typeof bgColor == 'undefined') if ( typeof bgColor == 'undefined' ) {
bgColor = '35:15'; // black wool bgColor = '35:15'; // black wool
}
if (typeof fgColor == 'undefined') if ( typeof fgColor == 'undefined' ) {
fgColor = 35 ; // white wool fgColor = 35 ; // white wool
}
if (border){ if ( border ) {
drone.box(border,21,9,1); drone.box(border,21,9,1);
drone.up().right(); drone.up().right();
} }
drone.blocktype('00:00',fgColor,bgColor); drone.blocktype('00:00',fgColor,bgColor);
return { return {
start24: function(){ start24: function( ) {
var clock = this; var clock = this;
function tick(){ function tick() {
var rolloverMins = 24*60; var rolloverMins = 24*60;
var timeOfDayInMins = Math.floor(((world.time + 6000) % 24000) / 16.6667); var timeOfDayInMins = Math.floor(((world.time + 6000) % 24000) / 16.6667);
timeOfDayInMins = timeOfDayInMins % rolloverMins; timeOfDayInMins = timeOfDayInMins % rolloverMins;
@ -40,10 +40,10 @@ exports.LCDClock = function(drone, fgColor,bgColor,border) {
}; };
intervalId = setInterval(tick, 800); intervalId = setInterval(tick, 800);
}, },
stop24: function(){ stop24: function() {
clearInterval(intervalId); clearInterval( intervalId );
}, },
update: function(secs){ update: function(secs) {
var digits = [0,0,0,0], var digits = [0,0,0,0],
s = secs % 60; s = secs % 60;
m = (secs - s) / 60; m = (secs - s) / 60;

View file

@ -19,24 +19,29 @@ Creates a Rainbow.
***/ ***/
Drone.extend('rainbow', function(radius){ Drone.extend('rainbow', function(radius){
if (typeof radius == "undefined") var i,
radius = 18; colors,
bm;
this.chkpt('rainbow');
this.down(radius); if ( typeof radius == "undefined" ) {
// copy blocks.rainbow and add air at end (to compensate for strokewidth) radius = 18;
var colors = blocks.rainbow.slice(0); }
colors.push(blocks.air);
for (var i = 0;i < colors.length; i++) { this.chkpt('rainbow');
var bm = this._getBlockIdAndMeta(colors[i]); this.down(radius);
this.arc({ // copy blocks.rainbow and add air at end (to compensate for strokewidth)
blockType: bm[0], colors = blocks.rainbow.slice(0);
meta: bm[1], colors.push(blocks.air);
radius: radius-i, for ( i = 0; i < colors.length; i++ ) {
strokeWidth: 2, bm = this._getBlockIdAndMeta( colors[i] );
quadrants: {topright: true, this.arc({
topleft: true}, blockType: bm[0],
orientation: 'vertical'}).right().up(); meta: bm[1],
} radius: radius-i,
return this.move('rainbow'); strokeWidth: 2,
quadrants: {topright: true,
topleft: true},
orientation: 'vertical'}).right().up();
}
return this.move('rainbow');
}); });

View file

@ -12,23 +12,23 @@ var Drone = require('../drone').Drone;
* depth - (Optional) depth of the cube, defaults to width * depth - (Optional) depth of the cube, defaults to width
*/ */
Drone.extend("rboxcall", function(callback, probability, width, height, depth) { Drone.extend("rboxcall", function( callback, probability, width, height, depth ) {
this.chkpt('rboxcall-start'); this.chkpt('rboxcall-start');
for(var i = 0; i < width; ++i) { for(var i = 0; i < width; ++i) {
this.move('rboxcall-start').right(i); this.move('rboxcall-start').right(i);
for(var j = 0; j < depth; ++j) { for(var j = 0; j < depth; ++j) {
this.move('rboxcall-start').right(i).fwd(j); this.move('rboxcall-start').right(i).fwd(j);
for(var k = 0; k < height; ++k) { for(var k = 0; k < height; ++k) {
if(Math.random()*100 < probability) { if(Math.random()*100 < probability) {
callback.call(null, new Drone(this.x, this.y, this.z)); callback.call(null, new Drone(this.x, this.y, this.z));
} }
this.up(); this.up();
}
} }
} }
}
this.move('rboxcall-start'); this.move('rboxcall-start');
return this; return this;
}); });

View file

@ -1,18 +1,18 @@
var Drone = require('../drone').Drone; var Drone = require('../drone').Drone;
var blocks = require('blocks'); var blocks = require('blocks');
Drone.extend('skyscraper',function(floors){ Drone.extend('skyscraper', function( floors ) {
var i = 0;
if (typeof floors == "undefined") if ( typeof floors == 'undefined' ) {
floors = 10; floors = 10;
this.chkpt('skyscraper'); }
for (var i = 0;i < floors; i++) this.chkpt('skyscraper');
{ for ( i = 0; i < floors; i++ ) {
this this // w h d
.box(blocks.iron,20,1,20) .box( blocks.iron, 20, 1, 20) // iron floor
.up() .up() // w h d
.box0(blocks.glass_pane,20,3,20) .box0(blocks.glass_pane, 20, 3, 20) // glass walls
.up(3); .up(3);
} }
return this.move('skyscraper'); return this.move('skyscraper');
}); });

View file

@ -7,25 +7,25 @@ var Drone = require('../drone').Drone;
* dir - "up", "down", "left", "right", "fwd", "back * dir - "up", "down", "left", "right", "fwd", "back
* maxIterations - (Optional) maximum number of cubes to generate, defaults to 1000 * maxIterations - (Optional) maximum number of cubes to generate, defaults to 1000
*/ */
Drone.extend("streamer", function(block, dir, maxIterations) { Drone.extend('streamer', function(block, dir, maxIterations) {
if (typeof maxIterations == "undefined") if (typeof maxIterations == 'undefined')
maxIterations = 1000; maxIterations = 1000;
var usage = "Usage: streamer({block-type}, {direction: 'up', 'down', 'fwd', 'back', 'left', 'right'}, {maximum-iterations: default 1000})\nE.g.\n" + var usage = "Usage: streamer({block-type}, {direction: 'up', 'down', 'fwd', 'back', 'left', 'right'}, {maximum-iterations: default 1000})\nE.g.\n" +
"streamer(5, 'up', 200)"; "streamer(5, 'up', 200)";
if (typeof dir == "undefined"){ if (typeof dir == 'undefined'){
throw new Error(usage); throw new Error(usage);
}
if (typeof block == 'undefined') {
throw new Error(usage);
}
for ( var i = 0; i < maxIterations || 1000; ++i ) {
this.box(block);
this[dir].call(this);
var block = this.world.getBlockAt(this.x, this.y, this.z);
if ( block.typeId != 0 && block.data != 0) {
break;
} }
if (typeof block == "undefined") { }
throw new Error(usage); return this;
}
for ( var i = 0; i < maxIterations||1000; ++i ) {
this.box(block);
this[dir].call(this);
var block = this.world.getBlockAt(this.x, this.y, this.z);
if ( block.typeId != 0 && block.data != 0) {
break
}
}
return this;
}); });

View file

@ -3,19 +3,19 @@ var Drone = require('../drone').Drone;
// constructs a mayan temple // constructs a mayan temple
// //
Drone.extend('temple', function(side) { Drone.extend('temple', function(side) {
if (!side) { if ( !side ) {
side = 20; side = 20;
} }
var stone = '98:1'; var stone = '98:1';
var stair = '109:' + Drone.PLAYER_STAIRS_FACING[this.dir]; var stair = '109:' + Drone.PLAYER_STAIRS_FACING[ this.dir ];
this.chkpt('temple'); this.chkpt('temple');
while (side > 4) { while ( side > 4 ) {
var middle = Math.round((side-2)/2); var middle = Math.round( (side-2) / 2 );
this.chkpt('corner') this.chkpt('corner')
.box(stone, side, 1, side) .box( stone, side, 1, side )
.right(middle).box(stair).right().box(stair) .right( middle ).box( stair ).right().box( stair )
.move('corner').up().fwd().right(); .move('corner').up().fwd().right();
side = side - 2; side = side - 2;
} }

View file

@ -1,6 +1,6 @@
var fireworks = require('fireworks'); var fireworks = require('fireworks');
var Drone = require('./drone').Drone; var Drone = require('./drone').Drone;
Drone.extend('firework',function() { Drone.extend( 'firework', function( ) {
fireworks.firework(this.getLocation()); fireworks.firework( this.getLocation() );
}); });

File diff suppressed because it is too large Load diff

View file

@ -22,49 +22,64 @@ Spheres are time-consuming to make. You *can* make large spheres (250 radius) bu
server to be very busy for a couple of minutes while doing so. server to be very busy for a couple of minutes while doing so.
***/ ***/
Drone.extend('sphere', function(block,radius) Drone.extend( 'sphere', function( block, radius ) {
{ var lastRadius = radius,
var lastRadius = radius; slices = [ [ radius , 0 ] ],
var slices = [[radius,0]]; diameter = radius * 2,
var diameter = radius*2; bm = this._getBlockIdAndMeta( block ),
var bm = this._getBlockIdAndMeta(block); r2 = radius * radius,
i = 0,
newRadius,
yOffset,
sr,
sh,
v,
h;
var r2 = radius*radius; for ( i = 0; i <= radius; i++ ) {
for (var i = 0; i <= radius;i++){ newRadius = Math.round( Math.sqrt( r2 - i * i ) );
var newRadius = Math.round(Math.sqrt(r2 - i*i)); if ( newRadius == lastRadius ) {
if (newRadius == lastRadius) slices[ slices.length - 1 ][ 1 ]++;
slices[slices.length-1][1]++; } else {
else slices.push( [ newRadius , 1 ] );
slices.push([newRadius,1]);
lastRadius = newRadius;
} }
this.chkpt('sphere'); lastRadius = newRadius;
// }
// mid section this.chkpt( 'sphere' );
// //
this.up(radius - slices[0][1]) // mid section
.cylinder(block,radius,(slices[0][1]*2)-1,{blockType: bm[0],meta: bm[1]}) //
.down(radius-slices[0][1]); this.up( radius - slices[0][1] )
.cylinder( block, radius, ( slices[0][1]*2 ) - 1, { blockType: bm[0], meta: bm[1] } )
.down( radius - slices[0][1] );
yOffset = -1;
for ( i = 1; i < slices.length; i++ ) {
yOffset += slices[i-1][1];
sr = slices[i][0];
sh = slices[i][1];
v = radius + yOffset;
h = radius - sr;
// northern hemisphere
this.up( v )
.fwd( h )
.right( h )
.cylinder( block, sr, sh, { blockType: bm[0], meta: bm[1] } )
.left( h )
.back( h )
.down( v );
var yOffset = -1; // southern hemisphere
for (var i = 1; i < slices.length;i++) v = radius - ( yOffset + sh + 1 );
{ this.up( v )
yOffset += slices[i-1][1]; .fwd( h )
var sr = slices[i][0]; .right( h )
var sh = slices[i][1]; .cylinder( block, sr, sh, { blockType: bm[0], meta: bm[1] } )
var v = radius + yOffset, h = radius-sr; .left( h )
// northern hemisphere .back( h )
this.up(v).fwd(h).right(h) .down( v );
.cylinder(block,sr,sh,{blockType: bm[0],meta: bm[1]}) }
.left(h).back(h).down(v); return this.move( 'sphere' );
// southern hemisphere
v = radius - (yOffset+sh+1);
this.up(v).fwd(h).right(h)
.cylinder(block,sr,sh,{blockType: bm[0],meta: bm[1]})
.left(h).back(h). down(v);
}
return this.move('sphere');
}); });
/************************************************************************ /************************************************************************
### Drone.sphere0() method ### Drone.sphere0() method
@ -88,81 +103,80 @@ server to be very busy for a couple of minutes while doing so.
***/ ***/
Drone.extend('sphere0', function(block,radius) Drone.extend('sphere0', function(block,radius)
{ {
/* var lastRadius = radius,
this.sphere(block,radius) slices = [ [ radius, 0 ] ],
.fwd().right().up() diameter = radius * 2,
.sphere(0,radius-1) bm = this._getBlockIdAndMeta( block ),
.back().left().down(); r2 = radius*radius,
i,
newRadius,
sr,
sh,
v,
h,
len,
yOffset;
*/ for ( i = 0; i <= radius; i++ ) {
newRadius = Math.round( Math.sqrt( r2 - i * i ) );
var lastRadius = radius; if ( newRadius == lastRadius ) {
var slices = [[radius,0]]; slices[ slices.length - 1 ][ 1 ]++;
var diameter = radius*2; } else {
var bm = this._getBlockIdAndMeta(block); slices.push( [ newRadius, 1 ] );
var r2 = radius*radius;
for (var i = 0; i <= radius;i++){
var newRadius = Math.round(Math.sqrt(r2 - i*i));
if (newRadius == lastRadius)
slices[slices.length-1][1]++;
else
slices.push([newRadius,1]);
lastRadius = newRadius;
} }
this.chkpt('sphere0'); lastRadius = newRadius;
// }
// mid section this.chkpt( 'sphere0' );
// //
//.cylinder(block,radius,(slices[0][1]*2)-1,{blockType: bm[0],meta: bm[1]}) // mid section
this.up(radius - slices[0][1]) //
.arc({blockType: bm[0], this.up( radius - slices[0][1] )
meta: bm[1], .arc({ blockType: bm[0],
radius: radius, meta: bm[1],
strokeWidth: 2, radius: radius,
stack: (slices[0][1]*2)-1, strokeWidth: 2,
fill: false stack: (slices[0][1]*2)-1,
}) fill: false
.down(radius-slices[0][1]); })
.down( radius - slices[0][1] );
yOffset = -1;
len = slices.length;
for ( i = 1; i < len; i++ ) {
yOffset += slices[i-1][1];
sr = slices[i][0];
sh = slices[i][1];
v = radius + yOffset;
h = radius-sr;
// northern hemisphere
// .cylinder(block,sr,sh,{blockType: bm[0],meta: bm[1]})
this.up( v ).fwd( h ).right( h )
.arc({
blockType: bm[0],
meta: bm[1],
radius: sr,
stack: sh,
fill: false,
strokeWidth: i < len - 1 ? 1 + ( sr - slices[ i + 1 ][ 0 ] ) : 1
})
.left( h ).back( h ).down( v );
var yOffset = -1; // southern hemisphere
var len = slices.length; v = radius - ( yOffset + sh + 1 );
for (var i = 1; i < len;i++) this.up( v ).fwd( h ).right( h )
{ .arc({
yOffset += slices[i-1][1]; blockType: bm[0],
var sr = slices[i][0]; meta: bm[1],
var sh = slices[i][1]; radius: sr,
var v = radius + yOffset, h = radius-sr; stack: sh,
// northern hemisphere fill: false,
// .cylinder(block,sr,sh,{blockType: bm[0],meta: bm[1]}) strokeWidth: i < len - 1 ? 1 + ( sr - slices[ i + 1 ][ 0 ] ) : 1
this.up(v).fwd(h).right(h) })
.arc({ .left( h ).back( h ). down( v );
blockType: bm[0], }
meta: bm[1], this.move( 'sphere0' );
radius: sr,
stack: sh,
fill: false,
strokeWidth: i<len-1?1+(sr-slices[i+1][0]):1
})
.left(h).back(h).down(v);
// southern hemisphere
v = radius - (yOffset+sh+1);
//.cylinder(block,sr,sh,{blockType: bm[0],meta: bm[1]})
this.up(v).fwd(h).right(h)
.arc({
blockType: bm[0],
meta: bm[1],
radius: sr,
stack: sh,
fill: false,
strokeWidth: i<len-1?1+(sr-slices[i+1][0]):1
})
.left(h).back(h). down(v);
}
this.move('sphere0');
return this; return this;
}); });
/************************************************************************ /************************************************************************
@ -185,55 +199,55 @@ To create a wood 'north' hemisphere with a radius of 7 blocks...
![hemisphere example](img/hemisphereex1.png) ![hemisphere example](img/hemisphereex1.png)
***/ ***/
Drone.extend('hemisphere', function(block,radius, northSouth){ Drone.extend( 'hemisphere', function( block, radius, northSouth ) {
var lastRadius = radius; var lastRadius = radius,
var slices = [[radius,0]]; slices = [ [ radius, 0 ] ],
var diameter = radius*2; diameter = radius * 2,
var bm = this._getBlockIdAndMeta(block); bm = this._getBlockIdAndMeta(block),
r2 = radius * radius,
var r2 = radius*radius; i = 0,
for (var i = 0; i <= radius;i++){ newRadius;
var newRadius = Math.round(Math.sqrt(r2 - i*i)); for ( i = 0; i <= radius; i++ ) {
if (newRadius == lastRadius) newRadius = Math.round( Math.sqrt( r2 - i * i ) );
slices[slices.length-1][1]++; if ( newRadius == lastRadius ) {
else slices[ slices.length - 1 ][ 1 ]++;
slices.push([newRadius,1]);
lastRadius = newRadius;
}
this.chkpt('hsphere');
//
// mid section
//
if (northSouth == "north"){
this.cylinder(block,radius,slices[0][1],{blockType: bm[0],meta: bm[1]});
} else { } else {
this.up(radius - slices[0][1]) slices.push( [ newRadius, 1 ] );
.cylinder(block,radius,slices[0][1],{blockType: bm[0],meta: bm[1]})
.down(radius - slices[0][1]);
} }
lastRadius = newRadius;
var yOffset = -1; }
for (var i = 1; i < slices.length;i++) this.chkpt( 'hsphere' );
{ //
yOffset += slices[i-1][1]; // mid section
var sr = slices[i][0]; //
var sh = slices[i][1]; if ( northSouth == 'north' ) {
var v = yOffset, h = radius-sr; this.cylinder( block, radius, slices[0][1], { blockType: bm[0], meta: bm[1] } );
if (northSouth == "north") { } else {
// northern hemisphere this.up( radius - slices[0][1] )
this.up(v).fwd(h).right(h) .cylinder( block, radius, slices[0][1], { blockType: bm[0], meta: bm[1] } )
.cylinder(block,sr,sh,{blockType: bm[0],meta: bm[1]}) .down( radius - slices[0][1] );
.left(h).back(h).down(v); }
}else{
// southern hemisphere var yOffset = -1;
v = radius - (yOffset+sh+1); for ( i = 1; i < slices.length; i++ ) {
this.up(v).fwd(h).right(h) yOffset += slices[i-1][1];
.cylinder(block,sr,sh,{blockType: bm[0],meta: bm[1]}) var sr = slices[i][0];
.left(h).back(h). down(v); var sh = slices[i][1];
} var v = yOffset, h = radius-sr;
if ( northSouth == 'north' ) {
// northern hemisphere
this.up( v ).fwd( h ).right( h )
.cylinder( block, sr, sh, { blockType: bm[0], meta: bm[1] } )
.left( h ).back( h ).down( v );
} else {
// southern hemisphere
v = radius - ( yOffset + sh + 1 );
this.up( v ).fwd( h ).right( h )
.cylinder( block, sr, sh, { blockType: bm[0], meta: bm[1] } )
.left( h ).back( h ).down( v );
} }
return this.move('hsphere'); }
return this.move( 'hsphere' );
}); });
/************************************************************************ /************************************************************************
### Drone.hemisphere0() method ### Drone.hemisphere0() method
@ -255,9 +269,9 @@ To create a glass 'north' hemisphere with a radius of 20 blocks...
![hemisphere example](img/hemisphereex2.png) ![hemisphere example](img/hemisphereex2.png)
***/ ***/
Drone.extend('hemisphere0', function(block,radius,northSouth){ Drone.extend( 'hemisphere0', function( block, radius, northSouth ) {
return this.hemisphere(block,radius,northSouth) return this.hemisphere( block, radius, northSouth)
.fwd().right().up(northSouth=="north"?0:1) .fwd().right().up( northSouth == 'north' ? 0 : 1 )
.hemisphere(0,radius-1,northSouth) .hemisphere( 0, radius-1, northSouth )
.back().left().down(northSouth=="north"?0:1); .back().left().down( northSouth == 'north' ? 0 : 1 );
}); });

View file

@ -25,6 +25,6 @@ permission since it relies on the `/js` command to execute.
}; };
***/ ***/
exports.hello = function(player){ exports.hello = function( player ) {
player.sendMessage('Hello ' + player.name); player.sendMessage( 'Hello ' + player.name );
}; };

View file

@ -27,6 +27,6 @@ command does not evaluate javascript code so this command is much more secure.
***/ ***/
command('hello', function (parameters, player) { command( 'hello', function( parameters, player ) {
player.sendMessage('Hello ' + player.name); player.sendMessage( 'Hello ' + player.name );
}); });

View file

@ -30,13 +30,13 @@ message for operators.
}); });
***/ ***/
command('op-hello', function (parameters, player) { command( 'op-hello', function( parameters, player ) {
/* /*
this is how you limit based on player privileges this is how you limit based on player privileges
*/ */
if (!player.op){ if ( !player.op ) {
player.sendMessage('Only operators can do this.'); player.sendMessage( 'Only operators can do this.' );
return; return;
} }
player.sendMessage('Hello ' + player.name); player.sendMessage( 'Hello ' + player.name );
}); });

View file

@ -19,22 +19,22 @@ This example demonstrates adding and using parameters in commands.
This differs from example 3 in that the greeting can be changed from This differs from example 3 in that the greeting can be changed from
a fixed 'Hello ' to anything you like by passing a parameter. a fixed 'Hello ' to anything you like by passing a parameter.
command('hello-params', function (parameters, player) { command( 'hello-params', function ( parameters, player ) {
var salutation = parameters[0] ; var salutation = parameters[0] ;
player.sendMessage( salutation + ' ' + player.name); player.sendMessage( salutation + ' ' + player.name );
}); });
***/ ***/
command('hello-params', function (parameters, player) { command('hello-params', function( parameters, player ) {
/* /*
parameters is an array (or list) of strings. parameters[0] parameters is an array (or list) of strings. parameters[0]
refers to the first element in the list. Arrays in Javascript refers to the first element in the list. Arrays in Javascript
are 0-based. That is, the 1st element is parameters[0], the 2nd are 0-based. That is, the 1st element is parameters[0], the 2nd
element is parameters[1], the 3rd element is parameters[2] and element is parameters[1], the 3rd element is parameters[2] and
so on. In this example, parameters[1] refers to the first word so on. In this example, parameters[1] refers to the first word
which appears after `jsp hello-params `. which appears after `jsp hello-params `.
*/ */
var salutation = parameters[0] ; var salutation = parameters[0] ;
player.sendMessage( salutation + ' ' + player.name); player.sendMessage( salutation + ' ' + player.name );
}); });

View file

@ -29,13 +29,13 @@ this example, we use that module...
Source Code... Source Code...
var greetings = require('./example-1-hello-module'); var greetings = require('./example-1-hello-module');
command('hello-module', function( parameters, player ){ command( 'hello-module', function( parameters, player ) {
greetings.hello(player); greetings.hello( player );
}); });
***/ ***/
var greetings = require('./example-1-hello-module'); var greetings = require('./example-1-hello-module');
command('hello-module', function( parameters, player ){ command( 'hello-module', function( parameters, player ) {
greetings.hello(player); greetings.hello( player );
}); });

View file

@ -32,13 +32,14 @@ Source Code ...
var utils = require('utils'); var utils = require('utils');
var greetings = require('./example-1-hello-module'); var greetings = require('./example-1-hello-module');
command('hello-byname', function( parameters, sender ) { command( 'hello-byname', function( parameters, sender ) {
var playerName = parameters[0]; var playerName = parameters[0];
var recipient = utils.player(playerName); var recipient = utils.player( playerName );
if (recipient) if ( recipient ) {
greetings.hello(recipient); greetings.hello( recipient );
else } else {
sender.sendMessage('Player ' + playerName + ' not found.'); sender.sendMessage( 'Player ' + playerName + ' not found.' );
}
}); });
***/ ***/
@ -46,11 +47,12 @@ Source Code ...
var utils = require('utils'); var utils = require('utils');
var greetings = require('./example-1-hello-module'); var greetings = require('./example-1-hello-module');
command('hello-byname', function( parameters, sender ) { command( 'hello-byname', function( parameters, sender ) {
var playerName = parameters[0]; var playerName = parameters[0];
var recipient = utils.player(playerName); var recipient = utils.player( playerName );
if (recipient) if ( recipient ) {
greetings.hello(recipient); greetings.hello( recipient );
else } else {
sender.sendMessage('Player ' + playerName + ' not found.'); sender.sendMessage( 'Player ' + playerName + ' not found.' );
}
}); });

View file

@ -79,15 +79,15 @@ cleaner and more readable. Similarly where you see a method like
[bksaf]: http://jd.bukkit.org/dev/apidocs/org/bukkit/entity/Player.html#setAllowFlight() [bksaf]: http://jd.bukkit.org/dev/apidocs/org/bukkit/entity/Player.html#setAllowFlight()
[bkapi]: http://jd.bukkit.org/dev/apidocs/ [bkapi]: http://jd.bukkit.org/dev/apidocs/
events.on('player.PlayerJoinEvent', function (listener, event){ events.on( 'player.PlayerJoinEvent', function( listener, event ) {
if (event.player.op) { if ( event.player.op ) {
event.player.sendMessage('Welcome to ' + __plugin); event.player.sendMessage('Welcome to ' + __plugin);
} }
}); });
***/ ***/
events.on('player.PlayerJoinEvent', function (listener, event){ events.on( 'player.PlayerJoinEvent', function( listener, event ) {
if (event.player.op) { if ( event.player.op ) {
event.player.sendMessage('Welcome to ' + __plugin); event.player.sendMessage( 'Welcome to ' + __plugin );
} }
}); });

View file

@ -59,281 +59,345 @@ The following administration options can only be used by server operators...
blocks are destroyed by this command. blocks are destroyed by this command.
***/ ***/
var utils = require('utils'); var utils = require('utils'),
var _store = { TeleportCause = org.bukkit.event.player.PlayerTeleportEvent.TeleportCause,
houses: {}, _store = {
openHouses: {}, houses: { },
invites: {} openHouses: { },
}; invites: { }
};
/* /*
*/ */
var homes = plugin("homes", { var homes = plugin( 'homes', {
help: function(){
return [
/* basic functions */
"/jsp home : Return to your own home",
"/jsp home <player> : Go to player's home",
"/jsp home set : Set your current location as home",
"/jsp home delete : Delete your home location",
/* social */ help: function( ) {
"/jsp home list : List homes you can visit", return [
"/jsp home ilist : List players who can visit your home", /* basic functions */
"/jsp home invite <player> : Invite <player> to your home", '/jsp home : Return to your own home',
"/jsp home uninvite <player> : Uninvite <player> to your home", '/jsp home <player> : Go to player home',
"/jsp home public : Open your home to all players", '/jsp home set : Set your current location as home',
"/jsp home private : Make your home private", '/jsp home delete : Delete your home location',
/* administration */ /* social */
"/jsp home listall : Show all houses (ops only)", '/jsp home list : List homes you can visit',
"/jsp home clear <player> : Clears player's home location (ops only)" '/jsp home ilist : List players who can visit your home',
]; '/jsp home invite <player> : Invite <player> to your home',
}, '/jsp home uninvite <player> : Uninvite <player> to your home',
/* ======================================================================== '/jsp home public : Open your home to all players',
basic functions '/jsp home private : Make your home private',
======================================================================== */
go: function(guest, host){ /* administration */
if (typeof host == "undefined") '/jsp home listall : Show all houses (ops only)',
host = guest; '/jsp home clear <player> : Clears player home location (ops only)'
guest = utils.player(guest); ];
host = utils.player(host); },
var loc = _store.houses[host.name]; /* ========================================================================
if (!loc){ basic functions
guest.sendMessage(host.name + " has no home"); ======================================================================== */
return;
} go: function( guest, host ) {
if (!this._canVisit(guest,host)){ var loc,
guest.sendMessage("You can't visit " + host.name + "'s home yet"); homeLoc;
return; if ( typeof host == 'undefined' ) {
} host = guest;
var teleportCause = org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; }
var homeLoc = utils.locationFromJSON(loc); guest = utils.player( guest );
guest.teleport(homeLoc, teleportCause.PLUGIN); host = utils.player( host );
}, loc = _store.houses[ host.name ];
/* if ( !loc ) {
determine whether a guest is allow visit a host's home guest.sendMessage( host.name + ' has no home' );
*/ return;
_canVisit: function(guest, host){ }
if (guest == host) if ( !this._canVisit( guest, host ) ) {
return true; guest.sendMessage( 'You can not visit ' + host.name + "'s home yet" );
if (_store.openHouses[host.name]) return;
return true; }
var invitations = _store.invites[host.name]; homeLoc = utils.locationFromJSON( loc );
if (invitations) guest.teleport(homeLoc, TeleportCause.PLUGIN);
for (var i = 0;i < invitations.length;i++) },
if (invitations[i] == guest.name) /*
return true; determine whether a guest is allow visit a host's home
return false; */
}, _canVisit: function( guest, host ) {
set: function(player){ var invitations,
player = utils.player(player); i;
var loc = player.location; if ( guest == host ) {
_store.houses[player.name] = utils.locationToJSON(loc); return true;
}, }
remove: function(player){ if ( _store.openHouses[ host.name ] ) {
player = utils.player(player); return true;
delete _store.houses[player.name]; }
}, invitations = _store.invites[ host.name ];
/* ======================================================================== if ( invitations ) {
social functions for ( i = 0; i < invitations.length; i++ ) {
======================================================================== */ if ( invitations[i] == guest.name ) {
return true;
/* }
list homes which the player can visit }
*/ }
list: function(player){ return false;
var result = []; },
for (var ohp in _store.openHouses)
result.push(ohp); set: function( player ) {
player = utils.player(player); player = utils.player( player );
for (var host in _store.invites){ var loc = player.location;
var guests = _store.invites[host]; _store.houses[player.name] = utils.locationToJSON( loc );
for (var i = 0;i < guests.length; i++) },
if (guests[i] == player.name)
result.push(host); remove: function( player ) {
} player = utils.player( player );
return result; delete _store.houses[ player.name ];
}, },
/* /* ========================================================================
list who can visit the player's home social functions
*/ ======================================================================== */
ilist: function(player){
player = utils.player(player); /*
var result = []; list homes which the player can visit
// if home is public - all players */
if (_store.openHouses[player.name]){ list: function( player ) {
var online = org.bukkit.Bukkit.getOnlinePlayers(); var result = [],
for (var i = 0;i < online.length; i++) ohp,
if (online[i].name != player.name) host,
result.push(online[i].name); guests,
}else{ i;
if (_store.invites[player.name]) for ( ohp in _store.openHouses ) {
result = _store.invites[player.name]; result.push(ohp);
else }
result = []; player = utils.player(player);
} for ( host in _store.invites ) {
return result; guests = _store.invites[host];
}, for ( i = 0; i < guests.length; i++ ) {
/* if ( guests[i] == player.name ) {
Invite a player to the home result.push(host);
*/ }
invite: function(host, guest){ }
host = utils.player(host); }
guest = utils.player(guest); return result;
var invitations = []; },
if (_store.invites[host.name]) /*
invitations = _store.invites[host.name]; list who can visit the player home
invitations.push(guest.name); */
_store.invites[host.name] = invitations; ilist: function( player ) {
guest.sendMessage(host.name + " has invited you to their home."); var result = [],
guest.sendMessage("type '/jsp home " + host.name + "' to accept"); onlinePlayers,
}, i;
/* player = utils.player( player );
Uninvite someone to the home // if home is public - all players
*/ if ( _store.openHouses[player.name] ) {
uninvite: function(host, guest){ onlinePlayers = org.bukkit.Bukkit.getOnlinePlayers();
host = utils.player(host); for ( i = 0; i < onlinePlayers.length; i++ ) {
guest = utils.player(guest); if ( onlinePlayers[i].name != player.name) {
var invitations = _store.invites[host.name]; result.push( onlinePlayers[i].name );
if (!invitations) }
return; }
var revisedInvites = []; } else {
for (var i =0;i < invitations.length; i++) if ( _store.invites[player.name] ) {
if (invitations[i] != guest.name) result = _store.invites[ player.name ];
revisedInvites.push(invitations[i]); } else {
_store.invites[host.name] = revisedInvites; result = [];
}, }
/* }
make the player's house public return result;
*/ },
open: function(player, optionalMsg){ /*
player = utils.player(player); Invite a player to the home
_store.openHouses[player.name] = true; */
if (typeof optionalMsg != "undefined") invite: function( host, guest ) {
__plugin.server.broadcastMessage(optionalMsg); host = utils.player( host );
}, guest = utils.player( guest );
/* var invitations = [];
make the player's house private if ( _store.invites[host.name] ) {
*/ invitations = _store.invites[host.name];
close: function(player){ }
player = utils.player(player); invitations.push( guest.name );
delete _store.openHouses[player.name]; _store.invites[host.name] = invitations;
}, guest.sendMessage( host.name + ' has invited you to their home.' );
/* ======================================================================== guest.sendMessage( 'type "/jsp home ' + host.name + '" to accept' );
admin functions },
======================================================================== */ /*
listall: function(){ Uninvite someone to the home
var result = []; */
for (var home in _store.houses) uninvite: function( host, guest ) {
result.push(home); var invitations,
return result; revisedInvites,
}, i;
clear: function(player){ host = utils.player( host );
player = utils.player(player); guest = utils.player( guest );
delete _store.houses[player.name]; invitations = _store.invites[ host.name ];
delete _store.openHouses[player.name]; if ( !invitations ) {
}, return;
store: _store }
}, true); revisedInvites = [];
for ( i = 0; i < invitations.length; i++ ) {
if ( invitations[i] != guest.name ) {
revisedInvites.push( invitations[i] );
}
}
_store.invites[host.name] = revisedInvites;
},
/*
make the player house public
*/
open: function( player, optionalMsg ) {
player = utils.player( player );
_store.openHouses[ player.name ] = true;
if ( typeof optionalMsg != 'undefined' ) {
__plugin.server.broadcastMessage( optionalMsg );
}
},
/*
make the player house private
*/
close: function( player ) {
player = utils.player( player );
delete _store.openHouses[ player.name ];
},
/* ========================================================================
admin functions
======================================================================== */
listall: function( ) {
var result = [];
for ( var home in _store.houses ) {
result.push(home);
}
return result;
},
clear: function( player ) {
player = utils.player( player );
delete _store.houses[ player.name ];
delete _store.openHouses[ player.name ];
},
store: _store
}, true );
exports.homes = homes; exports.homes = homes;
/* /*
define a set of command options that can be used by players define a set of command options that can be used by players
*/ */
var options = { var options = {
'set': function(params, sender){ homes.set(sender); },
'delete': function(params, sender ){ homes.remove(sender);}, 'set': function( params, sender ) {
'help': function(params, sender){ sender.sendMessage(homes.help());}, homes.set( sender );
'list': function(params, sender){ },
var visitable = homes.list();
if (visitable.length == 0){ 'delete': function( params, sender ) {
sender.sendMessage("There are no homes to visit"); homes.remove( sender );
return; },
}else{
sender.sendMessage([ 'help': function( params, sender ) {
"You can visit any of these " + visitable.length + " homes" sender.sendMessage( homes.help() );
,visitable.join(", ") },
]);
} 'list': function( params, sender ) {
}, var visitable = homes.list();
'ilist': function(params, sender){ if ( visitable.length == 0 ) {
var potentialVisitors = homes.ilist(); sender.sendMessage( 'There are no homes to visit' );
if (potentialVisitors.length == 0) return;
sender.sendMessage("No one can visit your home"); } else {
else sender.sendMessage([
sender.sendMessage([ 'You can visit any of these ' + visitable.length + ' homes'
"These " + potentialVisitors.length + "players can visit your home", ,visitable.join(', ')
potentialVisitors.join(", ")]); ]);
},
'invite': function(params,sender){
if (params.length == 1){
sender.sendMessage("You must provide a player's name");
return;
}
var playerName = params[1];
var guest = utils.player(playerName);
if (!guest)
sender.sendMessage(playerName + " is not here");
else
homes.invite(sender,guest);
},
'uninvite': function(params,sender){
if (params.length == 1){
sender.sendMessage("You must provide a player's name");
return;
}
var playerName = params[1];
var guest = utils.player(playerName);
if (!guest)
sender.sendMessage(playerName + " is not here");
else
homes.uninvite(sender,guest);
},
'public': function(params,sender){
homes.open(sender,params.slice(1).join(' '));
sender.sendMessage("Your home is open to the public");
},
'private': function(params, sender){
homes.close(sender);
sender.sendMessage("Your home is closed to the public");
},
'listall': function(params, sender){
if (!sender.isOp())
sender.sendMessage("Only operators can do this");
else
sender.sendMessage(homes.listall().join(", "));
},
'clear': function(params,sender){
if (!sender.isOp())
sender.sendMessage("Only operators can do this");
else
homes.clear(params[1], sender);
} }
},
'ilist': function( params, sender ) {
var potentialVisitors = homes.ilist();
if ( potentialVisitors.length == 0 ) {
sender.sendMessage('No one can visit your home');
} else {
sender.sendMessage([
'These ' + potentialVisitors.length + 'players can visit your home',
potentialVisitors.join(', ')]);
}
},
'invite': function( params, sender ) {
if ( params.length == 1 ) {
sender.sendMessage( 'You must provide a player name' );
return;
}
var playerName = params[1];
var guest = utils.player( playerName );
if ( !guest ) {
sender.sendMessage( playerName + ' is not here' );
} else {
homes.invite( sender, guest );
}
},
'uninvite': function( params, sender ) {
if ( params.length == 1 ) {
sender.sendMessage( 'You must provide a player name' );
return;
}
var playerName = params[1];
var guest = utils.player( playerName );
if ( !guest ) {
sender.sendMessage( playerName + ' is not here' );
} else {
homes.uninvite( sender, guest );
}
},
'public': function( params, sender ) {
homes.open( sender, params.slice( 1 ).join(' ') );
sender.sendMessage( 'Your home is open to the public' );
},
'private': function( params, sender ) {
homes.close( sender );
sender.sendMessage( 'Your home is closed to the public' );
},
'listall': function( params, sender ) {
if ( !sender.isOp() ) {
sender.sendMessage( 'Only operators can do this' );
} else {
sender.sendMessage( homes.listall().join(', ') );
}
},
'clear': function( params, sender ) {
if ( !sender.isOp() ) {
sender.sendMessage( 'Only operators can do this' );
} else {
homes.clear( params[1], sender );
}
}
}; };
var optionList = []; var optionList = [];
for (var o in options) for ( var o in options ) {
optionList.push(o); optionList.push(o);
}
/* /*
Expose a set of commands that players can use at the in-game command prompt Expose a set of commands that players can use at the in-game command prompt
*/ */
command("home", function ( params , sender) { command( 'home', function ( params , sender) {
if (params.length == 0){ var option,
homes.go(sender,sender); host;
return; if ( params.length == 0 ) {
homes.go( sender, sender );
return;
}
option = options[ params[0] ];
if ( option ) {
option( params, sender );
} else {
host = utils.player( params[0] );
if ( !host ) {
sender.sendMessage( params[0] + ' is not here' );
} else {
homes.go( sender, host );
} }
var option = options[params[0]]; }
if (option) }, optionList );
option(params,sender);
else{
var host = utils.player(params[0]);
if (!host)
sender.sendMessage(params[0] + " is not here");
else
homes.go(sender,host);
}
},optionList);

View file

@ -15,64 +15,73 @@ Once the game begins, guess a number by typing the `/` character
followed by a number between 1 and 10. followed by a number between 1 and 10.
***/ ***/
var Prompt = org.bukkit.conversations.Prompt,
ConversationFactory = org.bukkit.conversations.ConversationFactory,
ConversationPrefix = org.bukkit.conversations.ConversationPrefix;
var sb = function(cmd){ var sb = function( cmd ) {
org.bukkit.Bukkit.dispatchCommand(server.consoleSender, 'scoreboard ' + cmd) org.bukkit.Bukkit.dispatchCommand( server.consoleSender, 'scoreboard ' + cmd ) ;
}; };
exports.Game_NumberGuess = { exports.Game_NumberGuess = {
start: function(sender) { start: function( sender ) {
var guesses = 0; var guesses = 0;
sb('objectives add NumberGuess dummy Guesses'); sb( 'objectives add NumberGuess dummy Guesses' );
sb('players set ' + sender.name + ' NumberGuess ' + guesses); sb( 'players set ' + sender.name + ' NumberGuess ' + guesses );
sb('objectives setdisplay sidebar NumberGuess'); sb( 'objectives setdisplay sidebar NumberGuess' );
var Prompt = org.bukkit.conversations.Prompt;
var ConversationFactory = org.bukkit.conversations.ConversationFactory;
var ConversationPrefix = org.bukkit.conversations.ConversationPrefix;
var number = Math.ceil(Math.random() * 10); var number = Math.ceil( Math.random() * 10 );
var prompt = new Prompt() var prompt = new Prompt( ) {
{
getPromptText: function(ctx){ getPromptText: function( ctx ) {
var hint = ""; var hint = '';
var h = ctx.getSessionData("hint"); var h = ctx.getSessionData( 'hint' );
if (h){ if ( h ) {
hint = h; hint = h;
} }
return hint + "Think of a number between 1 and 10"; return hint + 'Think of a number between 1 and 10';
}, },
acceptInput: function(ctx, s)
{ acceptInput: function( ctx, s ) {
s = s.replace(/^[^0-9]+/,""); // strip leading non-numeric characters (e.g. '/' ) s = s.replace( /^[^0-9]+/, '' ); // strip leading non-numeric characters (e.g. '/' )
s = parseInt(s); s = parseInt( s );
if (s == number){ if ( s == number ) {
setTimeout(function(){ setTimeout(function( ) {
ctx.forWhom.sendRawMessage("You guessed Correct!"); ctx.forWhom.sendRawMessage( 'You guessed Correct!' );
sb('objectives remove NumberGuess'); sb( 'objectives remove NumberGuess' );
},100); }, 100 );
return null; return null;
}else{ } else {
if (s < number) if ( s < number ) {
ctx.setSessionData("hint","too low\n"); ctx.setSessionData( 'hint', 'too low\n' );
if (s > number) }
ctx.setSessionData("hint","too high\n"); if ( s > number ) {
guesses++; ctx.setSessionData( 'hint', 'too high\n' );
sb('players set ' + sender.name + ' NumberGuess ' + guesses); }
guesses++;
return prompt; sb( 'players set ' + sender.name + ' NumberGuess ' + guesses );
}
}, return prompt;
blocksForInput: function(ctx){ return true; } }
}; },
var cf = new ConversationFactory(__plugin);
var conv = cf.withModality(true) blocksForInput: function( ctx ) {
.withFirstPrompt(prompt) return true;
.withPrefix(new ConversationPrefix(){ getPrefix: function(ctx){ return "[1-10] ";} }) }
.buildConversation(sender); };
conv.begin(); var convPrefix = new ConversationPrefix( ) {
} getPrefix: function( ctx ) {
return '[1-10] ';
}
};
new ConversationFactory( __plugin )
.withModality( true )
.withFirstPrompt( prompt )
.withPrefix( convPrefix )
.buildConversation( sender )
.begin( );
}
}; };

View file

@ -42,141 +42,170 @@ cover to make the game more fun.
***/ ***/
var _startGame = function(gameState){ var GameMode = org.bukkit.GameMode,
// don't let game start if already in progress (wait for game to finish) EntityDamageByEntityEvent = org.bukkit.event.entity.EntityDamageByEntityEvent,
if (gameState.inProgress){ ItemStack = org.bukkit.inventory.ItemStack,
return; Material = org.bukkit.Material,
} Snowball = org.bukkit.entity.Snowball;
gameState.inProgress = true;
// reset timer
gameState.duration = gameState.originalDuration;
// put all players in survival mode and give them each 200 snowballs
// 64 snowballs for every 30 seconds should be more than enough
for (var i = 10;i < gameState.duration;i+=10)
gameState.ammo.push(gameState.ammo[0]);
for (var teamName in gameState.teams)
{
gameState.teamScores[teamName] = 0;
var team = gameState.teams[teamName];
for (var i = 0;i < team.length;i++) {
var player = server.getPlayer(team[i]);
gameState.savedModes[player.name] = player.gameMode;
player.gameMode = org.bukkit.GameMode.SURVIVAL;
player.inventory.addItem(gameState.ammo);
}
}
};
/*
end the game
*/
var _endGame = function(gameState){
var scores = [];
var leaderBoard = [];
for (var tn in gameState.teamScores){
leaderBoard.push([tn,gameState.teamScores[tn]]);
}
leaderBoard.sort(function(a,b){ return b[1] - a[1];});
for (var i = 0;i < leaderBoard.length; i++){
scores.push("Team " + leaderBoard[i][0] + " scored " + leaderBoard[i][1]);
}
for (var teamName in gameState.teams) {
var team = gameState.teams[teamName];
for (var i = 0;i < team.length;i++) {
// restore player's previous game mode and take back snowballs
var player = server.getPlayer(team[i]);
player.gameMode = gameState.savedModes[player.name];
player.inventory.removeItem(gameState.ammo);
player.sendMessage("GAME OVER.");
player.sendMessage(scores);
}
}
var handlerList = org.bukkit.event.entity.EntityDamageByEntityEvent.getHandlerList();
handlerList.unregister(gameState.listener);
gameState.inProgress = false;
};
/*
get the team the player belongs to
*/
var _getTeam = function(player,pteams) {
for (var teamName in pteams) {
var team = pteams[teamName];
for (var i = 0;i < team.length; i++)
if (team[i] == player.name)
return teamName;
}
return null;
};
/*
construct a new game
*/
var createGame = function(duration, teams) {
var _snowBalls = new org.bukkit.inventory.ItemStack(org.bukkit.Material.SNOW_BALL, 64);
var _gameState = { var _startGame = function( gameState ) {
teams: teams, var i,
duration: duration, teamName,
originalDuration: duration, team,
inProgress: false, player;
teamScores: {},
listener: null, // don't let game start if already in progress (wait for game to finish)
savedModes: {}, if ( gameState.inProgress ) {
ammo: [_snowBalls] return;
}; }
if (typeof duration == "undefined"){ gameState.inProgress = true;
duration = 60; // reset timer
gameState.duration = gameState.originalDuration;
// put all players in survival mode and give them each 200 snowballs
// 64 snowballs for every 30 seconds should be more than enough
for ( i = 10; i < gameState.duration; i += 10 ) {
gameState.ammo.push( gameState.ammo[ 0 ] );
}
for ( teamName in gameState.teams ) {
gameState.teamScores[teamName] = 0;
team = gameState.teams[ teamName ];
for ( i = 0; i < team.length; i++ ) {
player = server.getPlayer( team[i] );
gameState.savedModes[ player.name ] = player.gameMode;
player.gameMode = GameMode.SURVIVAL;
player.inventory.addItem( gameState.ammo );
} }
if (typeof teams == "undefined"){ }
/* };
wph 20130511 use all players /*
*/ end the game
teams = []; */
var players = server.onlinePlayers; var _endGame = function( gameState ) {
for (var i = 0;i < players.length; i++){ var scores = [],
teams.push(players[i].name); leaderBoard = [],
} tn,
i,
teamName,
team,
player,
handlerList;
leaderBoard = [];
for ( tn in gameState.teamScores){
leaderBoard.push([tn,gameState.teamScores[tn]]);
}
leaderBoard.sort(function(a,b){ return b[1] - a[1];});
for ( i = 0; i < leaderBoard.length; i++ ) {
scores.push( 'Team ' + leaderBoard[i][0] + ' scored ' + leaderBoard[i][1] );
}
for ( teamName in gameState.teams ) {
team = gameState.teams[teamName];
for ( i = 0; i < team.length; i++ ) {
// restore player's previous game mode and take back snowballs
player = server.getPlayer( team[i] );
player.gameMode = gameState.savedModes[ player.name ];
player.inventory.removeItem( gameState.ammo );
player.sendMessage( 'GAME OVER.' );
player.sendMessage( scores );
} }
// }
// allow for teams param to be either {red:['player1','player2'],blue:['player3']} or handlerList = EntityDamageByEntityEvent.getHandlerList();
// ['player1','player2','player3'] if all players are against each other (no teams) handlerList.unregister( gameState.listener );
// gameState.inProgress = false;
if (teams instanceof Array){ };
_gameState.teams = {}; /*
for (var i = 0;i < teams.length; i++) get the team the player belongs to
_gameState.teams[teams[i]] = [teams[i]]; */
var _getTeam = function( player, pteams ) {
var teamName,
team,
i;
for ( teamName in pteams ) {
team = pteams[ teamName ];
for ( i = 0; i < team.length; i++ ) {
if ( team[i] == player.name ) {
return teamName;
}
} }
}
return null;
};
/*
construct a new game
*/
var createGame = function( duration, teams ) {
var players,
i,
_snowBalls = new ItemStack( Material.SNOW_BALL, 64 );
var _gameState = {
teams: teams,
duration: duration,
originalDuration: duration,
inProgress: false,
teamScores: {},
listener: null,
savedModes: {},
ammo: [ _snowBalls ]
};
if ( typeof duration == 'undefined' ) {
duration = 60;
}
if ( typeof teams == 'undefined' ) {
/* /*
this function is called every time a player is damaged by another entity/player wph 20130511 use all players
*/ */
var _onSnowballHit = function(l,event){ teams = [];
var snowball = event.damager; players = server.onlinePlayers;
if (!snowball || !(snowball instanceof org.bukkit.entity.Snowball)) for ( i = 0; i < players.length; i++ ) {
return; teams.push( players[i].name );
var throwersTeam = _getTeam(snowball.shooter,_gameState.teams); }
var damageeTeam = _getTeam(event.entity,_gameState.teams); }
if (!throwersTeam || !damageeTeam) //
return; // thrower/damagee wasn't in game // allow for teams param to be either {red:['player1','player2'],blue:['player3']} or
if (throwersTeam != damageeTeam) // ['player1','player2','player3'] if all players are against each other (no teams)
_gameState.teamScores[throwersTeam]++; //
else if ( teams instanceof Array ) {
_gameState.teamScores[throwersTeam]--; _gameState.teams = {};
}; for ( i = 0;i < teams.length; i++ ) {
_gameState.teams[ teams[i] ] = [ teams[i] ];
return { }
start: function() { }
_startGame(_gameState); /*
_gameState.listener = events.on('entity.EntityDamageByEntityEvent',_onSnowballHit); this function is called every time a player is damaged by another entity/player
new java.lang.Thread(function(){ */
while (_gameState.duration--) var _onSnowballHit = function( l, event ) {
java.lang.Thread.sleep(1000); // sleep 1,000 millisecs (1 second) var snowball = event.damager;
_endGame(_gameState); if ( !snowball || !( snowball instanceof Snowball ) ) {
}).start(); return;
} }
}; var throwersTeam = _getTeam( snowball.shooter, _gameState.teams );
var damageeTeam = _getTeam( event.entity, _gameState.teams);
if ( !throwersTeam || !damageeTeam ) {
return; // thrower/damagee wasn't in game
}
if ( throwersTeam != damageeTeam ) {
_gameState.teamScores[ throwersTeam ]++;
} else {
_gameState.teamScores[ throwersTeam ]--;
}
};
return {
start: function( ) {
_startGame( _gameState );
_gameState.listener = events.on('entity.EntityDamageByEntityEvent',_onSnowballHit);
new java.lang.Thread( function( ) {
while ( _gameState.duration-- ) {
java.lang.Thread.sleep( 1000 ); // sleep 1,000 millisecs (1 second)
}
_endGame(_gameState);
} ).start( );
}
};
}; };
exports.Game_SnowballFight = createGame; exports.Game_SnowballFight = createGame;

View file

@ -41,139 +41,161 @@ your own mini-game...
***/ ***/
var store = {}; var store = {},
Bukkit = org.bukkit.Bukkit,
var scoreboardConfig = { Cow = org.bukkit.entity.Cow,
cowclicker: {SIDEBAR: 'Cows Clicked'} Sound = org.bukkit.Sound,
}; OfflinePlayer = org.bukkit.OfflinePlayer,
scoreboardConfig = {
cowclicker: {
SIDEBAR: 'Cows Clicked'
}
};
var scoreboard = require('minigames/scoreboard')(scoreboardConfig); var scoreboard = require('minigames/scoreboard')(scoreboardConfig);
var _onPlayerInteract = function(listener, event){ var _onPlayerInteract = function( listener, event ) {
var player = event.player; var player = event.player,
var Bukkit = org.bukkit.Bukkit; clickedEntity = event.rightClicked,
loc = clickedEntity.location;
if ( !store[ player.name ] ) {
return;
}
var sound = function( snd, vol, pitch ) {
loc.world.playSound( loc, snd, vol, pitch );
};
if ( clickedEntity instanceof Cow) {
store[ player.name ].score++;
scoreboard.update( 'cowclicker', player, store[ player.name ].score );
if (!store[player.name]) Bukkit.dispatchCommand( player, 'me clicked a cow!' );
return; sound( Sound.CLICK, 1, 1 );
setTimeout( function( ) {
var clickedEntity = event.rightClicked; sound( Sound.COW_HURT, 10, 0.85 ) ;
var loc = clickedEntity.location; }, 200 );
var sound = function(snd,vol,pitch){ }
loc.world.playSound(loc,snd,vol,pitch); };
}; var _onPlayerQuit = function( listener, event ) {
if (clickedEntity instanceof org.bukkit.entity.Cow) _removePlayer( event.player );
{ };
store[player.name].score++; var _onPlayerJoin = function( listener, event ) {
scoreboard.update('cowclicker', player, store[player.name].score); var gamePlayer = store[event.player.name];
if ( gamePlayer ) {
Bukkit.dispatchCommand(player, 'me clicked a cow!'); _addPlayer( event.player, gamePlayer.score );
sound(org.bukkit.Sound.CLICK,1,1); }
setTimeout(function(){ };
sound(org.bukkit.Sound.COW_HURT,10,0.85)
},200); var _startGame = function( ) {
var p,
player;
if ( config.verbose ) {
console.log('Staring game: Cow Clicker');
}
events.on( 'player.PlayerQuitEvent', _onPlayerQuit );
events.on( 'player.PlayerJoinEvent', _onPlayerJoin );
events.on( 'player.PlayerInteractEntityEvent', _onPlayerInteract );
scoreboard.start();
store = persist( 'cowclicker', store );
for ( p in store ) {
player = server.getPlayer( p );
if ( player ) {
/*
only add online players
*/
var score = store[p].score;
_addPlayer( player, score );
} }
}; }
var _onPlayerQuit = function(listener, event){
_removePlayer(event.player)
};
var _onPlayerJoin = function(listener, event){
var gamePlayer = store[event.player.name];
if (gamePlayer)
_addPlayer(event.player, gamePlayer.score);
}; };
var _startGame = function(){ var _addPlayer = function( player, score ) {
if (config.verbose) if ( config.verbose ) {
console.log('Staring game: Cow Clicker'); console.log( 'Adding player %s to Cow Clicker game', player );
}
events.on('player.PlayerQuitEvent', _onPlayerQuit); if ( typeof score == 'undefined' ) {
events.on('player.PlayerJoinEvent', _onPlayerJoin); score = 0;
events.on('player.PlayerInteractEntityEvent', _onPlayerInteract); }
store[ player.name ] = { score: score };
scoreboard.update( 'cowclicker', player, store[ player.name ].score);
player.sendMessage( 'Go forth and click some cows!' );
};
scoreboard.start(); var _removePlayer = function( player, notify ) {
store = persist('cowclicker',store); if ( player instanceof OfflinePlayer && player.player ) {
for (var p in store){ player = player.player;
var player = server.getPlayer(p); }
if (player){
/* if ( !store[player.name] ) {
only add online players return;
*/ }
var score = store[p].score; if ( config.verbose ) {
_addPlayer(player, score); console.log( 'Removing player %s from Cow Clicker', player );
} }
var playerScore = store[ player.name ].score;
scoreboard.restore( player );
delete store[ player.name ];
if ( notify && player ) {
player.sendMessage( 'You clicked ' + playerScore + ' cows! ' +
'You must be tired after all that clicking.' );
}
};
var _removeAllPlayers = function( notify ) {
if ( typeof notify == 'undefined' ) {
notify = false;
}
for ( var p in store ) {
var player = server.getOfflinePlayer( p );
if ( player ) {
_removePlayer( player, notify );
} }
}; delete store[p];
var _addPlayer = function(player,score){ }
if (config.verbose)
console.log('Adding player %s to Cow Clicker game',player);
if (typeof score == 'undefined')
score = 0;
store[player.name] = {score: score};
scoreboard.update('cowclicker', player,store[player.name].score);
player.sendMessage('Go forth and click some cows!');
}; };
var _removePlayer = function(player,notify){ var _stopGame = function( removePlayers ) {
if ( typeof removePlayers == 'undefined' ) {
if (player instanceof org.bukkit.OfflinePlayer && player.player) removePlayers = true;
player = player.player; }
if ( config.verbose ) {
if (!store[player.name]) console.log( 'Stopping game: Cow Clicker' );
return; }
if (config.verbose) scoreboard.stop();
console.log('Removing player %s from Cow Clicker', player); if ( !removePlayers ) {
return;
var playerScore = store[player.name].score; }
_removeAllPlayers( false );
scoreboard.restore(player); persist( 'cowclicker', store.pers, 'w' );
delete store[player.name];
if (notify && player){
player.sendMessage('You clicked ' + playerScore + ' cows! ' +
'You must be tired after all that clicking.');
}
};
var _removeAllPlayers = function(notify){
if (typeof notify == 'undefined')
notify = false;
for (var p in store){
var player = server.getOfflinePlayer(p);
if (player)
_removePlayer(player,notify);
delete store[p];
}
}
var _stopGame = function(removePlayers){
if (typeof removePlayers == 'undefined')
removePlayers = true;
if (config.verbose)
console.log('Stopping game: Cow Clicker');
scoreboard.stop();
if (!removePlayers)
return;
_removeAllPlayers(false);
persist('cowclicker',store.pers,'w');
}; };
/* /*
start the game automatically when this module is loaded. start the game automatically when this module is loaded.
*/ */
_startGame(); _startGame();
/* /*
players can join and leave the game by typing `jsp cowclicker` players can join and leave the game by typing `jsp cowclicker`
*/ */
command('cowclicker', function(params, sender){ command( 'cowclicker', function( params, sender ) {
if (!store[sender.name]) if ( !store[sender.name] ) {
_addPlayer(sender); _addPlayer( sender );
else } else {
_removePlayer(sender); _removePlayer( sender );
}
}); });
/* /*
stop the game when ScriptCraft is unloaded. stop the game when ScriptCraft is unloaded.
*/ */
addUnloadHandler(function(){ addUnloadHandler( function( ) {
_stopGame(false); _stopGame( false );
}); } );

View file

@ -16,20 +16,21 @@ press TAB. Visit
for a list of possible entities (creatures) which can be spawned. for a list of possible entities (creatures) which can be spawned.
***/ ***/
var entities = []; var entities = [],
var Types = org.bukkit.entity.EntityType EntityType = org.bukkit.entity.EntityType;
for (var t in Types){
if (Types[t] && Types[t].ordinal){ for ( var t in EntityType ) {
entities.push(t); if ( EntityType[t] && EntityType[t].ordinal ) {
} entities.push(t);
}
} }
command('spawn', function(parameters, sender){ command( 'spawn', function( parameters, sender ) {
if (!sender.op){ if ( !sender.op ) {
sender.sendMessage('Only operators can perform this command'); sender.sendMessage( 'Only operators can perform this command' );
return; return;
} }
var location = sender.location; var location = sender.location;
var world = location.world; var world = location.world;
var type = ('' + parameters[0]).toUpperCase(); var type = ('' + parameters[0]).toUpperCase();
world.spawnEntity(location, org.bukkit.entity.EntityType[type]); world.spawnEntity( location, EntityType[type] );
},entities); }, entities );

View file

@ -1,76 +1,87 @@
/* /*
This file is the first and only file executed directly from the Java Plugin. This file is the first and only file executed directly from the Java Plugin.
*/ */
var __scboot = null; var __scboot = null;
(function(){ (function(){
var File = java.io.File var File = java.io.File,
,FileReader = java.io.FileReader FileReader = java.io.FileReader,
,FileOutputStream = java.io.FileOutputStream FileOutputStream = java.io.FileOutputStream,
,ZipInputStream = java.util.zip.ZipInputStream ZipInputStream = java.util.zip.ZipInputStream,
,jsPlugins = new File('plugins/scriptcraft') jsPlugins = new File('plugins/scriptcraft'),
,initScript = 'lib/scriptcraft.js'; initScript = 'lib/scriptcraft.js';
var unzip = function(path, logger, plugin) { var unzip = function(path, logger, plugin) {
var zis = new ZipInputStream(plugin.getResource(path)) var zis = new ZipInputStream(plugin.getResource(path)),
, entry , reason = null, unzipFile = false, zTime = 0 entry,
, fTime = 0, fout = null, c, newFile; reason = null,
unzipFile = false,
zTime = 0,
fTime = 0,
fout = null,
c,
newFile;
while ( ( entry = zis.nextEntry ) != null ) { while ( ( entry = zis.nextEntry ) != null ) {
newFile = new File(jsPlugins, entry.name); newFile = new File(jsPlugins, entry.name);
if (entry.isDirectory()){ if (entry.isDirectory()){
newFile.mkdirs(); newFile.mkdirs();
zis.closeEntry(); zis.closeEntry();
continue; continue;
} }
reason = null; reason = null;
zTime = entry.time; zTime = entry.time;
unzipFile = false; unzipFile = false;
if (!newFile.exists()) { if (!newFile.exists()) {
reason = 'NE'; reason = 'NE';
unzipFile = true; unzipFile = true;
}else{ }else{
fTime = newFile.lastModified(); fTime = newFile.lastModified();
if (zTime > fTime) { if (zTime > fTime) {
reason = ((zTime - fTime) / 3600000) + "h"; reason = ((zTime - fTime) / 3600000) + "h";
unzipFile = true; unzipFile = true;
}
}
if (unzipFile) {
logger.info('Unzipping ' + newFile.canonicalPath + ' (' + reason + ')' );
fout = new FileOutputStream(newFile);
for (c = zis.read(); c != -1; c = zis.read()) {
fout.write(c);
}
fout.close();
}
zis.closeEntry();
} }
zis.close(); }
}; if (unzipFile) {
logger.info('Unzipping ' + newFile.canonicalPath + ' (' + reason + ')' );
fout = new FileOutputStream(newFile);
for (c = zis.read(); c != -1; c = zis.read()) {
fout.write(c);
}
fout.close();
}
zis.closeEntry();
}
zis.close();
};
/*
Called from Java plugin
*/
__scboot = function ( plugin, engine )
{
var logger = plugin.logger,
cfg = plugin.config,
cfgName,
initScriptFile = new File(jsPlugins,initScript),
zips = ['lib','plugins','modules'],
i = 0,
len = zips.length;
if (!jsPlugins.exists()){
logger.info('Directory ' + jsPlugins.canonicalPath + ' does not exist.');
logger.info('Initializing ' + jsPlugins.canonicalPath + ' directory with contents from plugin archive.');
jsPlugins.mkdirs();
}
for (i = 0; i < len;i++){
cfgName = 'extract-js.' + zips[i];
if (cfg.getBoolean(cfgName)){
unzip( zips[i] + '.zip',logger,plugin);
}
}
plugin.saveDefaultConfig();
__scboot = function ( plugin, engine ) engine.eval(new FileReader(initScriptFile));
{ __onEnable(engine, plugin, initScriptFile);
var logger = plugin.logger, cfg = plugin.config };
,cfgName, initScriptFile = new File(jsPlugins,initScript)
,zips = ['lib','plugins','modules']
,i = 0 ,len = zips.length;
if (!jsPlugins.exists()){
logger.info('Directory ' + jsPlugins.canonicalPath + ' does not exist.');
logger.info('Initializing ' + jsPlugins.canonicalPath + ' directory with contents from plugin archive.');
jsPlugins.mkdirs();
}
for (i = 0; i < len;i++){
cfgName = 'extract-js.' + zips[i];
if (cfg.getBoolean(cfgName)){
unzip( zips[i] + '.zip',logger,plugin);
}
}
plugin.saveDefaultConfig();
engine.eval(new FileReader(initScriptFile));
__onEnable(engine, plugin, initScriptFile);
};
})(); })();