Command Parser

SMS Command Parser

Some of the features here (Economy support, permission elevation and permission group checking) will only work if the Vault plugin is installed, along with a suitable economy and/or permissions plugin (see the Vault page for a list of the supported plugins).


Command Preprocessing

Several special variables are substituted into the command string before any other parsing is done:

  • <X>, <Y> & <Z> are replaced with the player's current X, Y & Z co-ordinates respectively
  • <WORLD> is replaced with the player's current world name
  • <NAME> & <N> are replaced with the player's name
  • <UUID> is replaced with the player's UUID
  • <I> is replaced with the item ID of whatever the player is currently holding in their hand (note: this is considered deprecated and will be removed in a later release)
  • <INAME> is relaced with the item name (e.g. STONE, COBBLESTONE...) of whatever the player is currently holding in their hand
  • <LABEL> is replaced with the menu item's label text, with any formatting codes removed (this is only done if the command is run from a menu which is using a default command)
  • <RAWLABEL> is replaced with the menu item's label text, without any formatting codes removed (this is only done if the command is run from a menu which is using a default command)
  • <VIEW> is replaced with the name of the view that was used to trigger the command
  • <MONEY> is replaced with a formatted string showing how much money the player has (only if Vault is installed)
  • <EXP> is replaced with the player's current experience total
  • <COOLDOWN> is replaced with a printable remaining cooldown time, only for commands run via the COOLDOWN special command
  • <$varname[=default]> is substituted with the user variable varname with an optional default if the variable doesn't exist - see User Variables for more information
  • <$v:varname=default> is substituted with the view variable varname (or default if the variable is doesn't exist in this view) - see Usage / Managing Views for more information
  • <$:some-text-prompt> first prompts the user (with some-text-prompt) to type in a string, and then substitutes that string into the command

Basic Command Execution

To have a command executed, just specify it as you would normally type it on the command line, e.g.:

/sms add mymenu "Get Help" /help

Now whenever someone executes the "Get Help" menu item, "/help" is run just as if they had typed it.

If you prefix the command text with "\" instead of "/", it becomes a chat string that the player says, e.g.:

/sms add mymenu "Say Hello" "\hello world!"

And if you prefix the command text with "\\", it becomes a chat string which is privately messaged to the player, e.g.:

/sms add mymenu "Where am I?" "\\You are on <WORLD> at <X>,<Y>,<Z>"

Note that if the command (or item label) contains any whitespace, then you must enclose it with quotation marks, either single or double.


Permission Elevation

It is possible to run commands with elevated privileges, i.e. allowing users to run commands via SMS menus that they would not otherwise have access to.

To make this work, you will need to do the following:

  • Use the elevation.nodes configuration setting to list the permission nodes that are needed for the commands you will be running. These nodes will be temporarily added to the player, and removed as soon as the command is run.
  • If you need to run commands from plugins which don't support superperms, then you will need to set the elevation.grant_op setting to true (it is false by default). If true, the player will be temporarily given op status before running the command, and de-opped immediately afterwards.

To run a command with elevated privileges, place an @ symbol after the /, like this:

/sms add mymenu Daytime "/@time day"
/sms add mymenu "Get Gold" "/@i ironblock 10"

Assuming we're using the General plugin here, the following would be needed to allow elevation for the above two commands:

/sms set elevation.nodes general.time.set
/sms set elevation.nodes general.give
/sms set elevation.nodes general.give.any

(Note that elevation.nodes is a list item - new values are appended by default. See Configuration for information on managing list items).

There are a couple of relevant permission nodes:

  • scrollingmenusign.create.elevated: players must have this node to add any menu item which allows permission elevation. This is included in the scrollingmenusign.admin node.
  • scrollingmenusign.execute.elevated: players must have this node to execute any menu item which uses permission elevation. All users have this by default, but you might wish to remove this node from a "guest" group, for example.

Console Commands

There is an alternative method of permission elevation: running commands as if from the console (you will need ScrollingMenuSign v0.8.1+ for this). To do this, place a # symbol after the /, like this:

/sms add mymenu "Get Permission" "/#pex user <NAME> timed add some.permission.node 10"

Now the pex user ... command will be run as it was typed on the console. No extra nodes need to be added in elevation.nodes for this, and elevation.grant_op doesn't need to be true. Plugins (in general) allow console commands without any special permission checks.

However, for this to work, the command must actually be usable on the console in the first place. E.g. the /i command from General gives the calling player an item, but that won't work from the console (since there's no player to give the item to).

When to use the /#command style? If the command you're running doesn't support superperms permissions and won't work even if the player is an Op, then this method should always work - as long as the command can be run from the console. The PermissionEX pex command is an example of such a command.

You will need the scrollingmenusign.create.elevated permission node to add such commands to menus, and the scrollingmenusign.execute.elevated permission node to execute such commands, the same as for /@ elevated commands (see above).


Command Costs and Economy Support

It is possible to assign costs to commands. E.g.

/sms add mymenu "Iron to Gold" "$iron_block,3;gold_block,-1" -feedback "Swapped 3 iron for 1 gold"

Any command which starts with a dollar sign ($) is a costed command.

  • A cost is a material name, potion effect name, or single letter (see below) followed by a comma, then a numeric quantity. Note that numeric item ID's are accepted for now but considered deprecated; material names should be used instead. As of SMS v2.3.0, using a numeric ID will cause a warning to be logged on the console & server.log
  • A positive quantity takes the item from the player. A negative quantity gives the item to the player.
  • For potion effects, a zero or negative quantity removes that effect type from the player, and a positive quantity applies the effect for that number of seconds.
  • The material/effect can also include a data value, e.g. wool:3,2 means "2 green wool", speed:4 means the "Speed IV" potion effect.
  • Multiple costs can be specified by separating costs with a semicolon (;) - they are processed in order, and if any cost is not affordable, none of the costs are applied.
  • Any command following the cost will only be executed if the player can afford to pay that cost.
  • See http://jd.bukkit.org/dev/apidocs/org/bukkit/Material.html for a list of all valid material names to use in item costs. You can use upper or lower case, and the underscores are optional, e.g. any of IRON_SWORD, iron_sword, ironsword or IronSword are fine.

So the above example $iron_block,3;gold_block,-1 means "take three iron blocks away, and if that succeeded, give one gold block to the player".

Another example:

/sms add mymenu "Heal me" "$E,50 /@heal"
/sms add mymenu "Speed II" "$E,50;speed:2,120"

The first entry charges the player 50 economy credits (from whatever economy plugin you're using) then, if that was affordable, uses permission elevation to heal them to full (we're assuming this is what the /heal command does here). The second entry charges the player 50 credits, then applies the "Speed II" potion effect for 120 seconds.

If a cost is not met, command processing stops immediately and the rest of the command is ignored. Note that it's quite valid to have no command after the cost, as in the "Iron to Gold" example above.

Costs can refer to quantities other than items, by using certain letters instead of item IDs. The following cost types are supported:

TypeFunctionExample
<material-name>[:<data>],amountCharge/grant the specified items$cobblestone,1;stone,-1 \\swapped cobblestone for stone
<material-name>,amount,DCharge/grant durability from the specified item (if the item doesn't have durability this will fail and stop further processing)$<INAME>,-10,D;E,1 && \\repaired your <INAME> - you have <MONEY> left
<potion-effect>[:<amplitude>],durationApply the named potion effect with the specified amplitude (default: 1) for duration seconds.$jump:4,30 \\You have Jump IV for 30 seconds
E,amountCharge/grant economy credits$E,50 /@heal
H,amountCharge/grant health$H,-1 \\you feel a bit better
F,amountCharge/grant food$F,2 \\you feel hungrier!
X,amountCharge/grant experience$X,-100 \\you feel more experienced!
  • Note how the <INAME> substitution was used in the item durability example to refer to the player's held item.
  • $E can take a decimal value to allow for "cents" to be specified, e.g. "$E,1.50" is one "dollar" and fifty "cents".
  • $H and $F will not reduce your health or food to 0, i.e. you can't kill yourself with these commands.

There is one relevant permission node:

  • scrollingmenusign.create.cost: users must have this node to add any menu item which uses costs. This is included in the scrollingmenusign.admin node.

Restricting Command Execution

The '@' symbol can be used to impose certain conditions which must be met before the following command is run:

RestrictorFunctionExample
@p:player-nameThe player must be named player-name@p:desht $E,-10000 \\You're rich!
@w:world-nameThe player must be in the world world-name@w:creative \\You are in the creative world!
@i:materialThe player must be holding an item of type material in their hand@i:glass \\You are holding glass!
@n:nodeThe player must have the permission node node@n:healableUser $H,-20 \\You are healed!
@g:groupThe player must be in the permission group group@g:admins \\You are an admin
@v:variable-comparisonThe specified variable comparison must succeed - see User Variables@v:status=good \\All is well! $$ \\Problem! <$status=unknown>

In addition, any condition can be reversed by putting a '!' after the '@', e.g. @!w:world-name will allow execution if the player's world is not "world-name".

Example:

/sms add mymenu "Get Iron" "@n:canHazIron /@i iron_block 10"

This gives the calling player 10 iron blocks but only if he has the "canHazIron" permission node.

/sms add mymenu "Get stuff" "@w:creative /@kit coolstuff"

This gives the calling player a kit with lots of nice stuff (whatever coolstuff is) but only if they are in the "creative" world.

Note that both restrictions and costs can be placed before a command. In this case, restrictions are always checked first, before any costs are applied, even if the restriction was specified after the cost. E.g. see the @n:healableUser check in the table above. The permission node is checked before the health modification is applied.


Chaining Commands

It is possible to run multiple commands from one command string. These are the command separators:

  • $$ stops execution of the current command string, if the command before it actually ran (the $ and/or @ checks might have prevented it from running).
  • $$$ is like $$ but also stops the execution of any macro that it's running under.
  • && starts a new command in the current command string, if thecommand before it actually ran.

Examples:

/sms add mymenu Hello "\Hello world && \pleased to meet you!"

will make the player say "Hello world" and then say "pleased to meet you!"

/sms add mymenu "Give me stuff" "@n:isAllowedNiceStuff $stone,-10;gold_block,-10 $$ /zap <NAME>"

If the player has the "isAllowedNiceStuff" permission node, he is given 10 stone and 10 gold blocks, and the command is stopped. But if doesn't have that node, the "/zap <NAME>" command is run (I don't know what /zap does but it doesn't sound good :) ).

The important thing to notice there is that the "$$" terminator only takes effect if the command before it actually ran - if the command didn't run because a restriction stopped it, or a cost was not met, then the terminator is ignored, and any command following it is run. This provides a rudimentary flow control.

More flow control is possible using macros, e.g.

/sms macro add m1 @n:isAdminUser \\Well done, you're an admin! $$$
/sms macro add m1 @n:isVipUser \\You're not an admin, but you are a VIP! $$$
/sms macro add m1 \\You're no one important, sorry!
/sms add mymenu "Am I admin?" %m1

If the player has permission "isAdminUser", the first line of the macro will be executed, and the "$$$" terminator will stop the entire macro. Otherwise the macro continues, and the second line of the macro is executed. Again permissions are is checked, this time for node "isVipUser", and again the "$$$" terminator will stop the macro if the player has that node. Otherwise the third line of the macro is executed, since the player has neither of the above nodes.


Other Built-in Special Commands

There are a few special menu commands which have a specific effect. These must always be typed entirely UPPERCASE:

CommandDescriptionFor More Information
SUBMENUOpen a new menu in this view.Submenus
POPUPPop up a view. This only works for inventory and spout views.Submenus
SCRIPTCall out to an external script.Scripting
AFTERRun the command after a given delay (in 50ms server ticks)Warmups and Cooldowns
COOLDOWNRun the command with a configurable cooldown until the next invocationWarmups and Cooldowns

Summary of Special Commands

Character SequenceMeaningExample
/A regular command/time day
/@An elevated command, run as the player, but with temporary permission from the elevation.nodes configuration setting/@time day
/*Synonym for /@
/#An elevated command, run as the console. Obviously this only works for commands which support being run from the console/#time day
@A restriction - only run following command if condition is met@n:weatherController /@weather sunny
@!A negated restriction - only run following command if condition is not met@!w:world_nether /@i water
$item $E $H $F $XA costed command - charge/grant the player items, money, health, food or experience and only run following command if the cost was met$E,50 /@heal
\ (or no special character)Have the player say the following string\Hello world!
\\Privately message the following string to the player@w:creative \\You are in the creative world!
%Run a macro named with the following string%mymacro arg1 arg2
$$Terminate command sequence, if the preceding command was actually run@n:isAdminUser
You are an admin $$
You are not an admin
$$$Terminate command sequence and any calling macro, if the preceding command was actually run@n:isAdminUser
You are an admin $$$
&&Start a new command, if the preceding command was actually run$E,50;H,-20 &&
You feel great!

Comments

Posts Quoted:
Reply
Clear All Quotes