Posted by
| Nick Gammon
Australia (23,072 posts) Bio
Forum Administrator |
Message
| This post describes what happens when you type a command, and the sequence in which various tests are applied (auto-say, scripting prefix, command stacking and so on).
The rules also apply to using the world.Execute script command, however world.Execute bypasses some of the initial tests, see below.
Processing for commands typed in the command window
- First, plugins are scanned for the plugin callback function: OnPluginCommandEntered. If found, the command is sent to that function. The function can then modify it if desired (eg. to convert speedwalks in a custom way, to handle command stacking in a custom way, and so on). The order in which the plugins are called is not defined.
The results from OnPluginCommandEntered are used for subsequent processing, even if empty (thus a blank line can still be processed). However if OnPluginCommandEntered returns the single character <tab> (hex 0x09) then the command is discarded and no further processing takes place.
(Version 3.75 onwards).
- Next, if auto-say is active, then some initial checks are made to see if auto-say applies. If it passes those checks (see auto-say configuration screen) then the command is broken up into lines (at the newline character), the auto-say prefix is prepended to each line, they are sent to the MUD, and command processing terminates.
- If auto-say is not active, or does not apply to this particular case, then the world.Execute function is called, with the command passed to it. If backslash sequences are supposed to be translated (see command configuration window) this is done now.
- Once the execution phase is complete the following things are then done (in other words, they are not done if you call world.Execute from a script, trigger, alias or timer):
- The command is added to the command history
- If "repeat last command" is enabled, the command is replaced in the command window
- If "unpause on send" is set the output window is unpaused.
world.Execute processing
- The "command execution depth" is incremented by one. If it exceeds the limit (currently 20) the execution terminates with an error status (which can be detected in a script). This is designed to stop infinite recursion, where someone might use world.Execute to re-call the same alias, and thus send MUSHclient into a loop.
- The start of the command is checked for the "scripting prefix" - default is the "/" character (this is only done if scripting is active). If it is detected the rest of the line(s) are passed to the script engine for execution. (Thus, command-stacking is ignored if you use a scripting prefix). Then the "command execution depth" is decremented again, and processing is complete.
- If the line commences with the command-stack character, and command-stacking is active, then command stacking is disabled for this command. For example:
Command: ;south ; east
Replacement: south ; east
In this case, two command-stack characters in a row, are still retained as two command-stack characters.
- Otherwise the command is now broken into individual lines at the command-stack character, excepting that two command stack characters in a row are replaced with a single command stack character. For example, if the command stack character is ";" and assuming \n represents a new line, this might happen:
Command: south ; east ; say I go;; I eat; drink \n sigh
Replacement: south \n east \n say I go; I eat\n drink \n sigh
Note that you can put multiple lines into a command by simply using the newline character (eg. typing Ctrl+Enter). Using the command stack character is simply another way of achieving the same result.
- The resulting command (with command-stack characters replaced by newlines) is then broken into individual lines.
Note that there is always considered to be at least one line, so entering a blank command will result in one newline being sent to the MUD. Each line is then processed as described in the next section below.
Note also that you cannot put the scripting prefix on subsequent lines - either the whole command is a script command - or not - there are no partial script commands. See the next point for more clarification.
- The "command execution depth" is decremented again, and processing is complete.
You can see from this description that it is possible to have speedwalks mixed with non-speedwalks, but not scripts mixed with non-scripts. For instance, assuming "#" is the speedwalk prefix:
eat food; # 3w 2s; enter shop <--- OK
eat food; /world.note "hello" <--- NOT OK
Processing for each individual command line
- Each plugin (if any) is given a chance to evaluate the command line ("OnPluginCommand" script subroutine). If it chooses to reject that line, then processing for that line terminates.
- If the line is totally empty a blank line is sent to the world.
- Otherwise, if the speedwalk prefix applies to this line, then the speedwalk is evaluated and sent to the world.
- If no speedwalk prefix was detected the line is scanned for global aliases. If one matches the action specified is done (ie. the "send" text is sent to the "send to" location). If "keep evaluating" was set for that alias then further aliases will be scanned (for the same text, not the output from the previous alias). The order in which the plugins are called is not defined.
- This process is repeated for the aliases in all plugins. Each plugin is scanned for aliases regardless of whether the main world file had a matching alias, and regardless of whether some other plugin had a matching alias. In other words, each plugin can attempt to match what was typed, regardless of what other plugins do.
However, see below about what happens if an alias tries to send to the MUD and the connection is not open.
- If no alias was found at all, then the text is sent to the world "as is" - note this is the normal case where something you type is just an ordinary command for the MUD. For the processing that is done for lines which are to be sent to the MUD, see further down.
- If one or more aliases were found, the alias scripts are now executed. Note that the scripts are executed after the alias "send" text has been sent. If the script sends text to the MUD (with world.Send) then see further down for how this is done.
- If any aliases were marked as "one-shot" they are now deleted from the alias list.
Just before text is sent to the MUD, a check is done to see if the connection is open. In other words, typing something that matches an alias that does not send to the world (or simply typing a script command) does not care whether or not you are connected.
If an alias tries to send text to the MUD, and fails because the connection is not open, processing of further aliases is discontinued (in the main world or plugins). Thus, if the connection is not open, it is possible for an alias which doesn't care if the world is connected (because it simply executes script commands or does something similar) to not be executed, if an earlier, matching, alias tries to send to the MUD. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|