Updated alias command to create aliases without 'jsp' prefix and added 'console' global variable
This commit is contained in:
parent
a7a4bf79a1
commit
e0f8f0dc0f
6 changed files with 341 additions and 291 deletions
|
@ -530,6 +530,30 @@ To unregister a listener *outside* of the listener function...
|
||||||
[buk2]: http://wiki.bukkit.org/Event_API_Reference
|
[buk2]: http://wiki.bukkit.org/Event_API_Reference
|
||||||
[buk]: http://jd.bukkit.org/dev/apidocs/index.html?org/bukkit/event/Event.html
|
[buk]: http://jd.bukkit.org/dev/apidocs/index.html?org/bukkit/event/Event.html
|
||||||
|
|
||||||
|
## console global variable
|
||||||
|
|
||||||
|
ScriptCraft provides a `console` global variable with the followng methods...
|
||||||
|
|
||||||
|
* log()
|
||||||
|
* info()
|
||||||
|
* warn()
|
||||||
|
* error()
|
||||||
|
|
||||||
|
The ScriptCraft console methods work like the Web API implementation.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
console.log('Hello %s', 'world');
|
||||||
|
|
||||||
|
Basic variable substitution is supported (ScriptCraft's implementation
|
||||||
|
of console uses the Bukkit Plugin [Logger][lgr] under the hood and
|
||||||
|
uses [java.lang.String.format()][strfmt] for variable
|
||||||
|
substitution. All output will be sent to the server console (not
|
||||||
|
in-game).
|
||||||
|
|
||||||
|
[lgr]: http://jd.bukkit.org/beta/apidocs/org/bukkit/plugin/PluginLogger.html
|
||||||
|
[strfmt]: http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#format(java.lang.String, java.lang.Object...)
|
||||||
|
|
||||||
http.request() function
|
http.request() function
|
||||||
====================
|
====================
|
||||||
The http.request() function will fetch a web address asynchronously (on a
|
The http.request() function will fetch a web address asynchronously (on a
|
||||||
|
@ -1677,6 +1701,56 @@ The arrows mod adds fancy arrows to the game. Arrows which...
|
||||||
All of the above functions can take an optional player object or name as
|
All of the above functions can take an optional player object or name as
|
||||||
a parameter. For example: `/js arrows.explosive('player23')` makes player23's arrows explosive.
|
a parameter. For example: `/js arrows.explosive('player23')` makes player23's arrows explosive.
|
||||||
|
|
||||||
|
## alias Module
|
||||||
|
|
||||||
|
The alias module lets players and server admins create their own
|
||||||
|
per-player or global custom in-game command aliases.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
To set a command alias which is only visible to the current player
|
||||||
|
(per-player alias)...
|
||||||
|
|
||||||
|
/jsp alias set cw = time set {1} ; weather {2}
|
||||||
|
|
||||||
|
... Creates a new custom command only usable by the player who set
|
||||||
|
it called `cw` (short for set Clock and Weather) which when invoked...
|
||||||
|
|
||||||
|
/cw 4000 sun
|
||||||
|
|
||||||
|
... will perform the following commands...
|
||||||
|
|
||||||
|
/time set 4000
|
||||||
|
/weather sun
|
||||||
|
|
||||||
|
Aliases can use paramters as above. On the right hand side of the `=`, the
|
||||||
|
`{1}` refers to the first parameter provided with the `cw` alias, `{2}`
|
||||||
|
refers to the second parameter and so on. So `cw 4000 sun` is converted to
|
||||||
|
`time set 4000` and `weather sun`.
|
||||||
|
|
||||||
|
To set a global command alias usable by all (only operators can create
|
||||||
|
such an alias)...
|
||||||
|
|
||||||
|
/jsp alias global stormy = time 18000; weather storm
|
||||||
|
|
||||||
|
To delete an alias ...
|
||||||
|
|
||||||
|
/jsp alias delete cw
|
||||||
|
|
||||||
|
... deletes the 'cw' alias from the appropriate alias map.
|
||||||
|
|
||||||
|
To get a list of aliases currently defined...
|
||||||
|
|
||||||
|
/jsp alias list
|
||||||
|
|
||||||
|
To get help on the `jsp alias` command:
|
||||||
|
|
||||||
|
/jsp alias help
|
||||||
|
|
||||||
|
Aliases can be used at the in-game prompt by players or in the server
|
||||||
|
console. Aliases will not be able to avail of command autocompletion
|
||||||
|
(pressing the TAB key will have no effect).
|
||||||
|
|
||||||
Classroom Module
|
Classroom Module
|
||||||
================
|
================
|
||||||
The `classroom` object contains a couple of utility functions for use
|
The `classroom` object contains a couple of utility functions for use
|
||||||
|
@ -1718,9 +1792,9 @@ To disallow scripting (and prevent players who join the server from using the co
|
||||||
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.
|
||||||
|
|
||||||
### Commando Plugin
|
# Commando Plugin
|
||||||
|
|
||||||
#### Description
|
## Description
|
||||||
|
|
||||||
commando is a plugin which can be used to add completely new commands
|
commando is a plugin which can be used to add completely new commands
|
||||||
to Minecraft. Normally ScriptCraft only allows for provision of new
|
to Minecraft. Normally ScriptCraft only allows for provision of new
|
||||||
|
@ -1751,9 +1825,8 @@ configuration file. It makes approving plugins easier and ensures that
|
||||||
craftbukkit plugins behave well together. While it is possible to
|
craftbukkit plugins behave well together. While it is possible to
|
||||||
override other plugins' commands, the CraftBukkit team do not
|
override other plugins' commands, the CraftBukkit team do not
|
||||||
recommend this. However, as ScriptCraft users have suggested, it
|
recommend this. However, as ScriptCraft users have suggested, it
|
||||||
should be at the discretion of server administrators and plugin
|
should be at the discretion of server administrators as to when
|
||||||
authors as to when overriding or adding new commands to the global
|
overriding or adding new commands to the global namespace is good.
|
||||||
namespace is good.
|
|
||||||
|
|
||||||
So this is where `commando()` comes in. It uses the exact same
|
So this is where `commando()` comes in. It uses the exact same
|
||||||
signature as the core `command()` function but will also make the
|
signature as the core `command()` function but will also make the
|
||||||
|
@ -1762,7 +1835,7 @@ type `/jsp hi` for the above command example, players simply type
|
||||||
`/hi` . This functionality is provided as a plugin rather than as part
|
`/hi` . This functionality is provided as a plugin rather than as part
|
||||||
of the ScriptCraft core.
|
of the ScriptCraft core.
|
||||||
|
|
||||||
#### Example hi-command.js
|
## Example hi-command.js
|
||||||
|
|
||||||
var commando = require('../commando');
|
var commando = require('../commando');
|
||||||
commando('hi', function(){
|
commando('hi', function(){
|
||||||
|
@ -1771,17 +1844,17 @@ of the ScriptCraft core.
|
||||||
|
|
||||||
...Displays a greeting to any player who issues the `/hi` command.
|
...Displays a greeting to any player who issues the `/hi` command.
|
||||||
|
|
||||||
#### Example - timeofday-command.js
|
## Example - timeofday-command.js
|
||||||
|
|
||||||
var times = {Dawn: 0, Midday: 6000, Dusk: 12000, Midnight:18000};
|
var times = {Dawn: 0, Midday: 6000, Dusk: 12000, Midnight:18000};
|
||||||
commando('timeofday', function(params){
|
commando('timeofday', function(params){
|
||||||
self.location.world.setTime(times[params[0]]);
|
self.location.world.setTime(times[params[0]]);
|
||||||
}
|
},
|
||||||
['Dawn','Midday','Dusk','Midnight']);
|
['Dawn','Midday','Dusk','Midnight']);
|
||||||
|
|
||||||
... changes the time of day using a new `/timeofday` command (options are Dawn, Midday, Dusk, Midnight)
|
... changes the time of day using a new `/timeofday` command (options are Dawn, Midday, Dusk, Midnight)
|
||||||
|
|
||||||
#### Caveats
|
## Caveats
|
||||||
|
|
||||||
Since commands registered using commando are really just appendages to
|
Since commands registered using commando are really just appendages to
|
||||||
the `/jsp` command and are not actually registered globally (it just
|
the `/jsp` command and are not actually registered globally (it just
|
||||||
|
|
|
@ -1,3 +1,14 @@
|
||||||
|
# 2013 12 27
|
||||||
|
|
||||||
|
## Updated 'jsp alias' command.
|
||||||
|
|
||||||
|
The 'jsp alias' command now lets players define their own shortcuts which don't require the 'jsp ' prefix.
|
||||||
|
|
||||||
|
## Added console global variable.
|
||||||
|
|
||||||
|
ScriptCraft now has a `console` global variable which can be used for logging (to the server console).
|
||||||
|
The `console` variable uses the ScriptCraft plugin Logger object.
|
||||||
|
|
||||||
# 2013 12 26
|
# 2013 12 26
|
||||||
|
|
||||||
Made the `events` variable global because it is use by modules and
|
Made the `events` variable global because it is use by modules and
|
||||||
|
|
|
@ -84,7 +84,14 @@ var _command = function(name,func,options,intercepts)
|
||||||
for (var i =1; i < __cmdArgs.length;i++){
|
for (var i =1; i < __cmdArgs.length;i++){
|
||||||
params.push("" + __cmdArgs[i]);
|
params.push("" + __cmdArgs[i]);
|
||||||
}
|
}
|
||||||
return func(params);
|
var result = null;
|
||||||
|
try {
|
||||||
|
result = func(params);
|
||||||
|
}catch (e){
|
||||||
|
logger.severe("Error while trying to execute command: " + JSON.stringify(params));
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
if (typeof options == "undefined")
|
if (typeof options == "undefined")
|
||||||
|
|
|
@ -416,207 +416,7 @@ var server = org.bukkit.Bukkit.server;
|
||||||
if (!config)
|
if (!config)
|
||||||
config = {verbose: false};
|
config = {verbose: false};
|
||||||
global.config = config;
|
global.config = config;
|
||||||
/*
|
|
||||||
Tab Completion of the /js and /jsp commands
|
|
||||||
*/
|
|
||||||
var _isJavaObject = function(o){
|
|
||||||
var result = false;
|
|
||||||
try {
|
|
||||||
o.hasOwnProperty("testForJava");
|
|
||||||
}catch (e){
|
|
||||||
// java will throw an error when an attempt is made to access the
|
|
||||||
// hasOwnProperty method. (it won't exist for Java objects)
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
var _javaLangObjectMethods = ["equals","getClass","class","getClass","hashCode","notify","notifyAll","toString","wait","clone","finalize"];
|
|
||||||
|
|
||||||
var _getProperties = function(o)
|
|
||||||
{
|
|
||||||
var result = [];
|
|
||||||
if (_isJavaObject(o))
|
|
||||||
{
|
|
||||||
propertyLoop:
|
|
||||||
for (var i in o)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// don't include standard Object methods
|
|
||||||
//
|
|
||||||
var isObjectMethod = false;
|
|
||||||
for (var j = 0;j < _javaLangObjectMethods.length; j++)
|
|
||||||
if (_javaLangObjectMethods[j] == i)
|
|
||||||
continue propertyLoop;
|
|
||||||
var typeofProperty = null;
|
|
||||||
try {
|
|
||||||
typeofProperty = typeof o[i];
|
|
||||||
}catch( e ){
|
|
||||||
if (e.message == "java.lang.IllegalStateException: Entity not leashed"){
|
|
||||||
// wph 20131020 fail silently for Entity leashing in craftbukkit
|
|
||||||
}else{
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (typeofProperty == "function" )
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result.sort();
|
|
||||||
};
|
|
||||||
/*
|
|
||||||
Tab completion for the /jsp commmand
|
|
||||||
*/
|
|
||||||
var __onTabCompleteJSP = function() {
|
|
||||||
var result = global.__onTC_result;
|
|
||||||
var args = global.__onTC_args;
|
|
||||||
var cmdInput = args[0];
|
|
||||||
var cmd = _commands[cmdInput];
|
|
||||||
if (cmd){
|
|
||||||
var opts = cmd.options;
|
|
||||||
var len = opts.length;
|
|
||||||
if (args.length == 1){
|
|
||||||
for (var i = 0;i < len; i++)
|
|
||||||
result.add(opts[i]);
|
|
||||||
}else{
|
|
||||||
// partial e.g. /jsp chat_color dar
|
|
||||||
for (var i = 0;i < len; i++){
|
|
||||||
if (opts[i].indexOf(args[1]) == 0){
|
|
||||||
result.add(opts[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
if (args.length == 0){
|
|
||||||
for (var i in _commands)
|
|
||||||
result.add(i);
|
|
||||||
}else{
|
|
||||||
// partial e.g. /jsp al
|
|
||||||
// should tabcomplete to alias
|
|
||||||
//
|
|
||||||
for (var c in _commands){
|
|
||||||
if (c.indexOf(cmdInput) == 0){
|
|
||||||
result.add(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
var _commands;
|
|
||||||
/*
|
|
||||||
Tab completion for the /js command
|
|
||||||
*/
|
|
||||||
var __onTabCompleteJS = function()
|
|
||||||
{
|
|
||||||
if (__onTC_cmd.name == "jsp")
|
|
||||||
return __onTabCompleteJSP()
|
|
||||||
|
|
||||||
var _globalSymbols = _getProperties(global)
|
|
||||||
var result = global.__onTC_result;
|
|
||||||
var args = global.__onTC_args;
|
|
||||||
var lastArg = args.length?args[args.length-1]+"":null;
|
|
||||||
var propsOfLastArg = [];
|
|
||||||
var statement = args.join(" ");
|
|
||||||
|
|
||||||
statement = statement.replace(/^\s+/,"").replace(/\s+$/,"");
|
|
||||||
|
|
||||||
|
|
||||||
if (statement.length == 0)
|
|
||||||
propsOfLastArg = _globalSymbols;
|
|
||||||
else{
|
|
||||||
var statementSyms = statement.split(/[^\$a-zA-Z0-9_\.]/);
|
|
||||||
var lastSymbol = statementSyms[statementSyms.length-1];
|
|
||||||
//print("DEBUG: lastSymbol=[" + lastSymbol + "]");
|
|
||||||
//
|
|
||||||
// try to complete the object ala java IDEs.
|
|
||||||
//
|
|
||||||
var parts = lastSymbol.split(/\./);
|
|
||||||
var name = parts[0];
|
|
||||||
var symbol = global[name];
|
|
||||||
var lastGoodSymbol = symbol;
|
|
||||||
if (typeof symbol != "undefined")
|
|
||||||
{
|
|
||||||
for (var 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"){
|
|
||||||
//
|
|
||||||
// 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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (var i = 0;i < propsOfLastArg.length; i++)
|
|
||||||
result.add(propsOfLastArg[i]);
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Unload Handlers
|
Unload Handlers
|
||||||
|
@ -736,7 +536,7 @@ See [issue #69][issue69] for more information.
|
||||||
global.alert = _echo;
|
global.alert = _echo;
|
||||||
global.load = _load;
|
global.load = _load;
|
||||||
global.logger = __plugin.logger;
|
global.logger = __plugin.logger;
|
||||||
global._onTabComplete = __onTabCompleteJS;
|
|
||||||
global.addUnloadHandler = _addUnloadHandler;
|
global.addUnloadHandler = _addUnloadHandler;
|
||||||
|
|
||||||
var fnRequire = load(jsPluginsRootDirName + '/lib/require.js',true);
|
var fnRequire = load(jsPluginsRootDirName + '/lib/require.js',true);
|
||||||
|
@ -752,11 +552,14 @@ See [issue #69][issue69] for more information.
|
||||||
modulePaths);
|
modulePaths);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var plugins = require('plugin');
|
var plugins = require('plugin');
|
||||||
_commands = plugins.commands;
|
global._onTabComplete = require('tabcomplete');
|
||||||
|
|
||||||
global.plugin = plugins.plugin;
|
global.plugin = plugins.plugin;
|
||||||
global.command = plugins.command;
|
global.command = plugins.command;
|
||||||
global.save = plugins.save;
|
global.save = plugins.save;
|
||||||
|
global.console = require('console');
|
||||||
|
|
||||||
var events = require('events');
|
var events = require('events');
|
||||||
events.on('server.PluginDisableEvent',function(l,e){
|
events.on('server.PluginDisableEvent',function(l,e){
|
||||||
|
|
|
@ -1,80 +1,230 @@
|
||||||
|
/*************************************************************************
|
||||||
|
## alias Module
|
||||||
|
|
||||||
var _store = {players: {}};
|
The alias module lets players and server admins create their own
|
||||||
|
per-player or global custom in-game command aliases.
|
||||||
|
|
||||||
var alias = plugin("alias", {
|
### Examples
|
||||||
help: function(){
|
|
||||||
return [
|
|
||||||
"/jsp alias set <alias> <commands> : Set a shortcut/alias for one or more commands (separated by ';')\n" +
|
|
||||||
"For example: '/jsp alias set sunny time set 4000; weather clear'\n" +
|
|
||||||
"/jsp sunny (is the same as..\n/time set 4000\n/weather clear",
|
|
||||||
"/jsp alias delete <alias> : Removes a shortcut/alias",
|
|
||||||
"/jsp alias list : shows a list of the player's command aliases",
|
|
||||||
"/jsp alias help : Shows this message"
|
|
||||||
];
|
|
||||||
},
|
|
||||||
set: function(player, alias, commands){
|
|
||||||
var aliases = _store.players;
|
|
||||||
var name = player.name;
|
|
||||||
if (typeof aliases[name] == "undefined")
|
|
||||||
aliases[name] = {};
|
|
||||||
aliases[name][alias] = commands;
|
|
||||||
},
|
|
||||||
remove: function(player, alias){
|
|
||||||
var aliases = _store.players;
|
|
||||||
if (aliases[player.name])
|
|
||||||
delete aliases[player.name][alias];
|
|
||||||
},
|
|
||||||
list: function(player){
|
|
||||||
var result = [];
|
|
||||||
var aliases = _store.players[player.name];
|
|
||||||
for (var a in aliases)
|
|
||||||
result.push(a + " = " + aliases[a].join(";"));
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
store: _store
|
|
||||||
},true);
|
|
||||||
|
|
||||||
exports.alias = alias;
|
To set a command alias which is only visible to the current player
|
||||||
|
(per-player alias)...
|
||||||
|
|
||||||
command("alias", function ( params ) {
|
/jsp alias set cw = time set {1} ; weather {2}
|
||||||
|
|
||||||
|
... Creates a new custom command only usable by the player who set
|
||||||
|
it called `cw` (short for set Clock and Weather) which when invoked...
|
||||||
|
|
||||||
|
/cw 4000 sun
|
||||||
|
|
||||||
|
... will perform the following commands...
|
||||||
|
|
||||||
|
/time set 4000
|
||||||
|
/weather sun
|
||||||
|
|
||||||
|
Aliases can use paramters as above. On the right hand side of the `=`, the
|
||||||
|
`{1}` refers to the first parameter provided with the `cw` alias, `{2}`
|
||||||
|
refers to the second parameter and so on. So `cw 4000 sun` is converted to
|
||||||
|
`time set 4000` and `weather sun`.
|
||||||
|
|
||||||
|
To set a global command alias usable by all (only operators can create
|
||||||
|
such an alias)...
|
||||||
|
|
||||||
|
/jsp alias global stormy = time 18000; weather storm
|
||||||
|
|
||||||
|
To delete an alias ...
|
||||||
|
|
||||||
|
/jsp alias delete cw
|
||||||
|
|
||||||
|
... deletes the 'cw' alias from the appropriate alias map.
|
||||||
|
|
||||||
|
To get a list of aliases currently defined...
|
||||||
|
|
||||||
|
/jsp alias list
|
||||||
|
|
||||||
|
To get help on the `jsp alias` command:
|
||||||
|
|
||||||
|
/jsp alias help
|
||||||
|
|
||||||
|
Aliases can be used at the in-game prompt by players or in the server
|
||||||
|
console. Aliases will not be able to avail of command autocompletion
|
||||||
|
(pressing the TAB key will have no effect).
|
||||||
|
|
||||||
|
***/
|
||||||
|
|
||||||
|
var _usage = "\
|
||||||
|
/jsp alias set {alias} = {comand-1} ;{command-2}\n \
|
||||||
|
/jsp alias global {alias} = {command-1} ; {command-2}\n \
|
||||||
|
/jsp alias list\n \
|
||||||
|
/jsp alias delete {alias}\n \
|
||||||
|
Create a new alias : \n \
|
||||||
|
/jsp alias set cw = time set {1} ; weather {2}\n \
|
||||||
|
Execute the alias : \n \
|
||||||
|
/cw 4000 sun \n \
|
||||||
|
...is the same as '/time set 4000' and '/weather sun'";
|
||||||
|
/*
|
||||||
|
persist aliases
|
||||||
|
*/
|
||||||
|
var _store = {
|
||||||
|
players: {},
|
||||||
|
global: {}
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
turns 'cw = time set {1} ; weather {2}' into {cmd: 'cw', aliases: ['time set {1}', 'weather {2}']}
|
||||||
|
_processParams is a private function which takes an array of parameters
|
||||||
|
used for the 'set' and 'global' options.
|
||||||
|
*/
|
||||||
|
var _processParams = function(params){
|
||||||
|
var paramStr = params.join(' ');
|
||||||
|
var eqPos = paramStr.indexOf('=');
|
||||||
|
var aliasCmd = paramStr.substring(0,eqPos).trim();
|
||||||
|
var aliasValue = paramStr.substring(eqPos+1).trim();
|
||||||
|
return { cmd: aliasCmd, aliases: aliasValue.split(/\s*;\s*/) };
|
||||||
|
};
|
||||||
|
|
||||||
|
var _set = function(player, params){
|
||||||
|
var playerAliases = _store.players[player.name];
|
||||||
|
if (!playerAliases){
|
||||||
|
playerAliases = {};
|
||||||
|
}
|
||||||
|
var o = _processParams(params);
|
||||||
|
playerAliases[o.cmd] = o.aliases;
|
||||||
|
_store.players[player.name] = playerAliases;
|
||||||
|
player.sendMessage("Alias '" + o.cmd + "' created.");
|
||||||
|
};
|
||||||
|
|
||||||
|
var _delete = function(player, params){
|
||||||
|
if (_store.players[player.name] &&
|
||||||
|
_store.players[player.name][params[0]]){
|
||||||
|
delete _store.players[player.name][params[0]];
|
||||||
|
player.sendMessage("Alias '" + params[0] + "' deleted.");
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
player.sendMessage("Alias '" + params[0] + "' does not exist.");
|
||||||
|
}
|
||||||
|
if (player.op){
|
||||||
|
if (_store.global[params[0]])
|
||||||
|
delete _store.global[params[0]];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var _global = function(player, params){
|
||||||
|
if (!player.op){
|
||||||
|
player.sendMessage("Only operators can set global aliases. " +
|
||||||
|
"You need to be an operator to perform this command.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var o = _processParams(params);
|
||||||
|
_store.global[o.cmd] = o.aliases;
|
||||||
|
player.sendMessage("Global alias '" + o.cmd + "' created.");
|
||||||
|
};
|
||||||
|
|
||||||
|
var _list = function(player){
|
||||||
|
try {
|
||||||
|
var alias = 0;
|
||||||
|
if (_store.players[player.name]){
|
||||||
|
player.sendMessage("Your aliases:");
|
||||||
|
for (alias in _store.players[player.name]){
|
||||||
|
player.sendMessage(alias + " = " +
|
||||||
|
JSON.stringify(_store.players[player.name][alias]));
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
player.sendMessage("You have no player-specific aliases.");
|
||||||
|
}
|
||||||
|
player.sendMessage("Global aliases:");
|
||||||
|
for (alias in _store.global){
|
||||||
|
player.sendMessage(alias + " = " + JSON.stringify(_store.global[alias]) );
|
||||||
|
}
|
||||||
|
}catch(e){
|
||||||
|
logger.severe("Error in list function: " + e.message);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var alias = plugin('alias', {
|
||||||
|
"store": _store,
|
||||||
|
"set": _set,
|
||||||
|
"global": _global,
|
||||||
|
"delete": _delete,
|
||||||
|
"list": _list,
|
||||||
|
"help": function(player){ player.sendMessage("Usage:\n" + _usage);}
|
||||||
|
}, true );
|
||||||
|
|
||||||
|
|
||||||
|
var aliasCmd = command('alias', function(params){
|
||||||
|
var operation = params[0];
|
||||||
|
if (!operation){
|
||||||
|
self.sendMessage("Usage:\n" + _usage);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (alias[operation])
|
||||||
|
alias[operation](self, params.slice(1));
|
||||||
|
else
|
||||||
|
self.sendMessage("Usage:\n" + _usage);
|
||||||
|
});
|
||||||
|
|
||||||
|
var _intercept = function( msg, invoker, exec)
|
||||||
|
{
|
||||||
|
var msgParts = msg.split(' ');
|
||||||
|
var command = msg.match(/^\/*([^\s]+)/)[1];
|
||||||
|
|
||||||
|
var template = [], isAlias = false, cmds = [];
|
||||||
|
|
||||||
|
if (_store.global[command]){
|
||||||
|
template = _store.global[command];
|
||||||
|
isAlias = true;
|
||||||
|
}else{
|
||||||
|
if (config.verbose){
|
||||||
|
logger.info("No global alias found for command: " + command);
|
||||||
|
}
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
this function also intercepts command options for /jsp
|
allows player-specific aliases to override global aliases
|
||||||
*/
|
*/
|
||||||
if (params[0] === "help"){
|
if (_store.players[invoker] &&
|
||||||
self.sendMessage(alias.help());
|
_store.players[invoker][command])
|
||||||
return;
|
{
|
||||||
|
template = _store.players[invoker][command];
|
||||||
|
isAlias = true;
|
||||||
|
}else{
|
||||||
|
if (config.verbose){
|
||||||
|
logger.info("No player alias found for command: " + command);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (params[0] === "set"){
|
for (var i = 0;i < template.length; i++)
|
||||||
var aliasCmd = params[1];
|
{
|
||||||
var cmdStr = params.slice(2).join(' ');
|
var filledinCommand = template[i].replace(/{([0-9]+)}/g, function (match,index){
|
||||||
var cmds = cmdStr.split(';');
|
index = parseInt(index,10);
|
||||||
alias.set(self,aliasCmd,cmds);
|
if (msgParts[index])
|
||||||
return;
|
return msgParts[index]
|
||||||
|
else
|
||||||
|
return match;
|
||||||
|
});
|
||||||
|
cmds.push(filledinCommand);
|
||||||
}
|
}
|
||||||
if (params[0] === "delete"){
|
|
||||||
alias.remove(self,params[1]);
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
if (params[0] === "list"){
|
|
||||||
self.sendMessage(alias.list(self));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (params.length == 0)
|
|
||||||
return self.sendMessage(alias.help());
|
|
||||||
|
|
||||||
var playerHasAliases = _store.players[self.name];
|
for (var i = 0; i< cmds.length; i++){
|
||||||
if (!playerHasAliases)
|
exec(cmds[i]);
|
||||||
return false;
|
|
||||||
// is it an alias?
|
|
||||||
var commands = playerHasAliases[params[0]];
|
|
||||||
if (!commands)
|
|
||||||
return false;
|
|
||||||
for (var i = 0;i < commands.length; i++){
|
|
||||||
// fill in template
|
|
||||||
var cmd = commands[i];
|
|
||||||
cmd = cmd.replace(/{([0-9]*)}/g,function(dummy,index){ return params[index] ? params[index] : "";})
|
|
||||||
self.performCommand(cmd);
|
|
||||||
}
|
}
|
||||||
return true;
|
return isAlias;
|
||||||
|
|
||||||
},["help","set","delete","list"],true);
|
};
|
||||||
|
/*
|
||||||
|
Intercept all command processing and replace with aliased commands if the
|
||||||
|
command about to be issued matches an alias.
|
||||||
|
*/
|
||||||
|
events.on('player.PlayerCommandPreprocessEvent', function(listener,evt){
|
||||||
|
var invoker = evt.player;
|
||||||
|
var exec = function(cmd){ invoker.performCommand(cmd);};
|
||||||
|
var isAlias = _intercept(''+evt.message, ''+invoker.name, exec);
|
||||||
|
if (isAlias)
|
||||||
|
evt.cancelled = true;
|
||||||
|
|
||||||
|
});
|
||||||
|
/* define a 'void' command because ServerCommandEvent can't be canceled */
|
||||||
|
command('void',function(){});
|
||||||
|
events.on('server.ServerCommandEvent', function(listener,evt){
|
||||||
|
var invoker = evt.sender;
|
||||||
|
var exec = function(cmd){ invoker.server.dispatchCommand(invoker, cmd); };
|
||||||
|
var isAlias = _intercept(''+evt.command, ''+ invoker.name, exec);
|
||||||
|
if (isAlias)
|
||||||
|
evt.command = "jsp void";
|
||||||
|
});
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
### Commando Plugin
|
# Commando Plugin
|
||||||
|
|
||||||
#### Description
|
## Description
|
||||||
|
|
||||||
commando is a plugin which can be used to add completely new commands
|
commando is a plugin which can be used to add completely new commands
|
||||||
to Minecraft. Normally ScriptCraft only allows for provision of new
|
to Minecraft. Normally ScriptCraft only allows for provision of new
|
||||||
|
@ -32,9 +32,8 @@ configuration file. It makes approving plugins easier and ensures that
|
||||||
craftbukkit plugins behave well together. While it is possible to
|
craftbukkit plugins behave well together. While it is possible to
|
||||||
override other plugins' commands, the CraftBukkit team do not
|
override other plugins' commands, the CraftBukkit team do not
|
||||||
recommend this. However, as ScriptCraft users have suggested, it
|
recommend this. However, as ScriptCraft users have suggested, it
|
||||||
should be at the discretion of server administrators and plugin
|
should be at the discretion of server administrators as to when
|
||||||
authors as to when overriding or adding new commands to the global
|
overriding or adding new commands to the global namespace is good.
|
||||||
namespace is good.
|
|
||||||
|
|
||||||
So this is where `commando()` comes in. It uses the exact same
|
So this is where `commando()` comes in. It uses the exact same
|
||||||
signature as the core `command()` function but will also make the
|
signature as the core `command()` function but will also make the
|
||||||
|
@ -43,7 +42,7 @@ type `/jsp hi` for the above command example, players simply type
|
||||||
`/hi` . This functionality is provided as a plugin rather than as part
|
`/hi` . This functionality is provided as a plugin rather than as part
|
||||||
of the ScriptCraft core.
|
of the ScriptCraft core.
|
||||||
|
|
||||||
#### Example hi-command.js
|
## Example hi-command.js
|
||||||
|
|
||||||
var commando = require('../commando');
|
var commando = require('../commando');
|
||||||
commando('hi', function(){
|
commando('hi', function(){
|
||||||
|
@ -52,17 +51,17 @@ of the ScriptCraft core.
|
||||||
|
|
||||||
...Displays a greeting to any player who issues the `/hi` command.
|
...Displays a greeting to any player who issues the `/hi` command.
|
||||||
|
|
||||||
#### Example - timeofday-command.js
|
## Example - timeofday-command.js
|
||||||
|
|
||||||
var times = {Dawn: 0, Midday: 6000, Dusk: 12000, Midnight:18000};
|
var times = {Dawn: 0, Midday: 6000, Dusk: 12000, Midnight:18000};
|
||||||
commando('timeofday', function(params){
|
commando('timeofday', function(params){
|
||||||
self.location.world.setTime(times[params[0]]);
|
self.location.world.setTime(times[params[0]]);
|
||||||
}
|
},
|
||||||
['Dawn','Midday','Dusk','Midnight']);
|
['Dawn','Midday','Dusk','Midnight']);
|
||||||
|
|
||||||
... changes the time of day using a new `/timeofday` command (options are Dawn, Midday, Dusk, Midnight)
|
... changes the time of day using a new `/timeofday` command (options are Dawn, Midday, Dusk, Midnight)
|
||||||
|
|
||||||
#### Caveats
|
## Caveats
|
||||||
|
|
||||||
Since commands registered using commando are really just appendages to
|
Since commands registered using commando are really just appendages to
|
||||||
the `/jsp` command and are not actually registered globally (it just
|
the `/jsp` command and are not actually registered globally (it just
|
||||||
|
@ -77,8 +76,8 @@ global commands for a plugin, please let me know.
|
||||||
[pcppevt]: http://jd.bukkit.org/dev/apidocs/org/bukkit/event/player/PlayerCommandPreprocessEvent.html
|
[pcppevt]: http://jd.bukkit.org/dev/apidocs/org/bukkit/event/player/PlayerCommandPreprocessEvent.html
|
||||||
|
|
||||||
***/
|
***/
|
||||||
|
|
||||||
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;
|
||||||
|
@ -92,3 +91,10 @@ events.on('player.PlayerCommandPreprocessEvent', function(l,e){
|
||||||
e.message = "/jsp " + msg.substring(1);
|
e.message = "/jsp " + msg.substring(1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
events.on('server.ServerCommandEvent', function(l,e){
|
||||||
|
var msg = "" + e.command;
|
||||||
|
var command = msg.match(/^\/*([^\s]+)/)[1];
|
||||||
|
if (commands[command]){
|
||||||
|
e.command = "/jsp " + msg.substring(1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
Reference in a new issue