Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to "verify" your details, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.
 Entire forum ➜ MUSHclient ➜ General ➜ How MUSHclient processes commands you type

How MUSHclient processes commands you type

This subject is now closed.     Refresh page


Posted by Nick Gammon   Australia  (23,072 posts)  Bio   Forum Administrator
Date Sat 20 May 2006 11:20 PM (UTC)

Amended on Mon 10 Nov 2008 04:20 AM (UTC) by Nick Gammon

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



  1. 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).


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

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

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



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

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

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

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

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

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



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

  2. If the line is totally empty a blank line is sent to the world.

  3. Otherwise, if the speedwalk prefix applies to this line, then the speedwalk is evaluated and sent to the world.

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

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

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

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

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

Posted by Nick Gammon   Australia  (23,072 posts)  Bio   Forum Administrator
Date Reply #1 on Tue 30 May 2006 06:06 AM (UTC)
Message
Macros

These are the single-keystroke commands (like F4) you can define in the "Macros" configuration window.


  1. If the macro is empty, nothing is done.

  2. The state of the Auto-say flag is saved, and then Auto-say is turned off. We presume that if you have a macro to "eat food" bound to F4 and you hit F4 then you really want to "eat food" not "say eat food".

  3. Processing now proceeds depending on the "send action" type for the macro:



    • If the macro type is "Replace" then the contents of the command window are replaced by the macro text.

    • If the macro type is "Insert" then the contents of the selection in the command window is replaced by the macro text. If there is no selection the text is inserted at the cursor position.

    • If the macro type is "Send Now" then the command processor described above is called as if you had typed the command in the command window. Thus macros are added to the command history.



  4. Auto-say is restored to how it was before.



- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,072 posts)  Bio   Forum Administrator
Date Reply #2 on Tue 30 May 2006 06:11 AM (UTC)
Message
Accelerators

Commands added with the Accelerator script function basically are processed the same as a Macro of type "send now". That is, empty accelerators are discarded, auto-say is turned off, and the command is processed by the input command processor.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,072 posts)  Bio   Forum Administrator
Date Reply #3 on Tue 30 May 2006 06:12 AM (UTC)
Message
It follows from these descriptions that both Accelerator commands, and Macros, can use things like speedwalking prefixes, and the scripting prefix. Thus you can use a Macro to do a script, a speedwalk (or call an alias).

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,072 posts)  Bio   Forum Administrator
Date Reply #4 on Wed 04 Jun 2008 04:57 AM (UTC)

Amended on Wed 04 Jun 2008 06:35 AM (UTC) by Nick Gammon

Message
Sending text to the MUD

Often text will need to be sent to the MUD. This may be a result of simply typing something, or an alias or trigger doing "send to world". Also, a script can do a world.Send to do a scripted send.


  1. If the world is not connected, nothing is done.

  2. Any trailing carriage-return/newline character sequence is removed (it is added back shortly).

  3. If the flag "Translate German characters" is checked, then various accented German characters are translated into 2-character replacements.

  4. The text to be sent is broken into individual lines at the carriage-return/linefeed characters (for the case where you did a world.Send with multiple lines, or had multiple lines in a trigger or alias "Send" box).

  5. If there are now no lines (because we were just sending a single newline, which was deleted in the earlier step) an empty line is added to the line list.

  6. For each line in the list, the following takes place:


    1. If the line needs to be queued (perhaps, a speedwalk with a speedwalk delay), then it is added to the outstanding "lines to be sent list", and processing stops for this line.

    2. Otherwise, we proceed as follows. First a carriage-return/newline (0x0D/0x0A) is appended to the line.

    3. Next, the "spam prevention" code, if enabled, checks whether this line is identical to the previous one sent, and if so, and it has reached the "spam count limit", the "spam prevention" text is sent by doing a recursive call to this section (sending text to the MUD). (For example, if you typed "north" 20 times, it automatically sends something different, like "look", so the MUD doesn't disconnect you).

    4. Each plugin is scanned for the OnPluginSend function, which gets a chance to inspect the line, and if any plugin returns false then that particular line is not sent. It is possible for OnPluginSend to reject the line, but substitute a different one (by calling world.Send). However a flag is set to prevent this happening recursively. That is, if the new line is also rejected a third version cannot be substituted. If the line is rejected then processing stops for this line. Once one plugin rejects the line, other plugins are not given a chance to look at it. The order in which the plugins are called is not defined.

    5. If no plugin has rejected the line, each plugin is scanned for the OnPluginSent function, which gets a chance to log or otherwise remember which lines were actually sent. This two-phase sequence is necessary because if you try to remember in OnPluginSend function what is being sent (eg. "north") you won't know if a subsequently-called plugin decides to reject it, or replace it by something else. This facility could be used by a user-written mapper or something similar (such as checking whether you have eaten a herb, either by typing the command directly, or because a script somewhere did it).

    6. The line is echoed on the Output window (if that was wanted)

    7. The line is logged to the log file as a "sent command" (if that was wanted)

    8. If the auto mapper is active, it notes that the line was sent in its mapping sequence. Specifically, the auto mapper checks for one of "north, south, east, west, up, down, ne, nw, se, sw, f, n , s, e, w, u, d". If one of those is found, it is added to the map sequence. An exception to this is if you "reverse" out of a place. For example, if you go north and then south, rather than "north,south" being added to the automap sequence, the "south" entry causes the "north" entry to be removed.

    9. Any IAC characters in the line (hex 0xFF) are now doubled so they become IAC/IAC (0xFF 0xFF) so the MUD server does not treat them as telnet negotiation sequences. This is done last so that the doubled IAC does not end up on the output window, in log files, etc. This doubling of the IAC can be prevented by setting the world option "do_not_translate_iac_to_iac_iac" by using the world.SetOption script function.

    10. The resulting line is sent to the MUD.



- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


21,193 views.

This subject is now closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.