📄 embedded.html
字号:
<h3>Table of contents</h3> <UL><LI><a href="#chap0">Embedded Language Support</a><LI><a href="#chap1">Running code</a><LI><a href="#chap2">Scope of variables</a><LI><a href="#chap3">Directory structure</a><LI><a href="#chap4">Programming in Embedded Perl</a><LI><a href="#chap5">Variables set by mcl</a><LI><a href="#chap6">Callouts</a><LI><a href="#chap7">Custom commands</a><LI><a href="#chap8">Custom configuration</a><LI><a href="#chap9">Processing multiple lines of input</a><LI><a href="#chap10">Functions called by mcl</a><LI><a href="#chap11">Color codes</a></UL><PRE></PRE><h3><a name="chap0">Embedded Language Support</a></h3><PRE>Since version 0.50.00, mcl supports Perl scripting. All scripts executedby mcl reside in the ~/.mcl directory and end with .pl. This section assumesthat you have some knowledge of Perl.Since version 0.52.00 mcl also supports embedded Python scripts. Thosescripts end with .py. Pretty much everything below applies to Python: justreplace .pl with .py.To choose between Perl or Python, simply supply plugins=perl or plugins=pythonin the configuration file. If you specify multiple interpreters, they arestacked. That is, the first interpreter gets the first shot at all triggersand then the second one gets called with whatever the result of the firstpass was. Pattern matching, substitution and variable extraction is onlycalled in the first interpreter however.When mcl starts up, it will execute the init script - i.e.~/.mcl/sys/init.pl. You don't want to modify that file - it may be changedwith new versions of mcl. Instead modify the "localinit.pl" file. Generally,files in sys/* are some that will be modified with new versions of mcl.The init script can contain anything - assignments to variables, definitionof functions you want available globally, etc.Also, in the second part of the initialization, mcl will load *all* thescripts that are loaded in ~/.mcl/auto/*.The first time you connect to a MUD, mcl will load the script with its name(e.g. ~/.mcl/ar.pl if you connect to 'ar'). This works as the init script.Before exiting, Perl will run the sys/done.pl script. This can be useful forsaving custom configuration options. Again, this is a system script andyou should use various hooks to have things run at exit time.If ~/.mcl/sys/init.pl is </PRE><h3><a name="chap1">Running code</a></h3><PRE>You can run perl code from mcl by several means. The #run command takesa function name and an argument. mcl tries to find a function with that nameamongs the function loaded by the init and mud-specific scripts first. Then,if that fails, it will load the file named the same as the function (e.g.if you run the function checkConnection, mcl will try to load the file~/.mcl/checkConnection.pl). You can use slashes here, so #run extra/testwill load ~/.mcl/extra/test.pl.The argument to the function is passed in the default variable, $_ (as isthe case with just about all embeded functions). This function runssynchronously - mcl will not continue until you have returned from thefunction, so don't use e.g. sleep() or blocking calls unless you know whatyou are doing.The other way to run Perl code is using #eval. #eval takes raw perl code,evaluates it and prints out the result on the screen. E.g. #eval 5**5 willcalculate 5 to the 5th power and print out the result on the screen. Thefull power of perl is available to you here - you could e.g. do#eval `cat /etc/group`. Personally, I have % aliased to #run (i.e. Alias %#run %0 in mclrc) so I can just type %`cat /etc/passwd`.The third way is to type any command for which there also is a cmd_namefunction (e.g. you type foobar, and have defined cmd_foobar, so cmd_foobarruns. See <a href="#chap7">"Custom commands"</a> for more info).You can also create a mcl command by creating a mclcmd_foo function. Thatwould make mcl react to the #foo command (# being the current commandcharacter).Finally, you can use the #load command to load up a file. This works justlike the initial loading of init.pl, but you specify the filename yourself.If you specify an absolute path, Perl will load that file. Otherwise,~/.mcl/ will be prepended.</PRE><h3><a name="chap2">Scope of variables</a></h3><PRE>mcl will parse all the perl code you run as one very long Perl script.Since Perl employs garbage collection and reference counting, this isfairly memory-efficient - things that are not used disappear.Keep in mind however, that all variables are global unless declared local(i.e. via my inside a function, as you should always declare suchvariables - but that is basic Perl that I will not cover here).You might want to put functions and variables that you do not wantpolluting the global namespace inside a package - see the mudftp.pl scriptfor an example.</PRE><h3><a name="chap3">Directory structure</a></h3><PRE>The sample/ directory contains the standard mcl Perl script distribution.You should copy the contents of this directory to your ~/.mcl directory.The sys/ subdirectory contains system scripts (like sys/init.pl) that youusually don't want to modify. These scripts will be update with new versionsof mcl.The auto/ directory is initially empty. Files that end with *.pl thereare automatically loaded on startup. In addition, each directory has thefile named the same as itself loaded (e.g. if you have a directory calledauto/highlight, the file auto/highlight/highlight.pl is loaded).The contrib/ directory contains scripts that are not per default part ofmcl. Usually you want to move those scripts to the auto/ directory. Scriptsthat consist of several parts have a directory for themselves. All thescripts are described in the sample/contrib/README file.Finally, the ~/.mcl directory itself can contain your own functions (or youcan put them in subdirectories).</PRE><h3><a name="chap4">Programming in Embedded Perl</a></h3><PRE>Some things to remember:Don't use require. It will exit mcl if it fails. Use include "file.pl" - itwill just print an error message.If you want to print something to the screen, just print it. What happensis that standard output is connected to a pipe which mcl reads from anddisplays on the screen.If you want to run a command, use the run function (e.g. run ("#open ar")).This will NOT execute the command right away - it will be put on a queueof commands to be run and that queue will be executed when your scriptreturns. There are a number of shortcut functions defined which makesthis easier - basically, for each mcl #function there is a mcl_function.E.g. you can use mcl_open("ar") instead of run("#open ar").If you make an endless loop in your program, you're screwed.Alt-T is handy for restarting mcl after changing some configuration orscript files.</PRE><h3><a name="chap5">Variables set by mcl</a></h3><PRE>mcl will set a number of variables that are available to scripts. These are:$now Current time in seconds ($^T is when mcl started)$mud Name of MUD currently connected to$VERSION mcl version%MUD Information about all MUDs: hostname,port,commands%Options All options (e.g. $Options{mudbeep} is value of mudbeep)%Aliases All aliases (trigger => commands)%Substitutions All substitutions%Macros All macrosAll these variables are read-only (or rather, changing any of their valueswill not have any effect on mcl).(Note that all the %hashes are not yet implemented).</PRE><h3><a name="chap6">Callouts</a></h3><PRE>Using the callout function, you can setup some of your functions to be calledoccasionally. This is programmed almost entirely in Perl - mcl will calla function called "idle" every second, and that function goes through thelist of callout functions and calls them if their time has come.To add a function:callout_add(\&function, period);the period is in seconds.To remove a function:callout_remove(\&function).NOTE that the function will continue to be called until you remove ityourself. You can add a one-shot callout by using:callout_once(\&function, period);If you want to pass parameters to your functions, use a closure:{ my $var = $_[0]; callout_once( sub { my_function($var); }, period);}</PRE><h3><a name="chap7">Custom commands</a></h3><PRE>Let us say that you have implemented a module that highlights certain strings,and you want to be able to add to those strings at runtime, rather thanhaving to edit the .pl file and restart mcl.To do that you probably want to get a command hook. This is easily done thisway:command_add ("highlight", highlight_function);After that, whenever the user types "highlight", your highlight_functionwill be called with whatever comes after highlight in $_.This works like aliases, so it's recursive (i.e. if you have an alias thatcalls highlight it will work). NOTE: You must end the fuction byreturning '1' if you want to "stop" the command from being executed.Otherwise, the command interpreter in mcl will continue with the command.Commands can be similarily removed using command_remove().There is also another, much easier way. You can just define a functioncalled cmd_cmdname. E.g. if you want to catch all "highlight" commands,you can just declare a sub cmd_highlight. Unlike with hooks, mcl willnever continue to execute after your subroutine has been called.The first way to add commands will let you remove them while they arepermanent in the second case.</PRE><h3><a name="chap8">Custom configuration</a></h3><PRE>Custom configuration is stored in the ~/.mcl/config file. A module of yoursthat wishes to save custom configuration should add a load and save hook:load_add ("highlight", \&highlight_loader);save_add (\&highlight_saver);Note that you most of the time can get away with using the same functionfor loading as you do for command-line adding. While the configurationis loaded, the variable $Loading is set to 1 - you don't want to reportthings too verbosely in that case.In your save function, you should output a number of lines, all startingwith a keyword followed by space. What you put on the rest of the line isup to you. Note that the filehandle is passed by the standard symbolictypeglobbing method.You can also optionally start with a comment line before writing outyour functions.See the sys/highlight.pl file for example of both this and command adding.Remember to put your configuration keys in in lower case! The configurationloader will look for a lower case version.</PRE><h3><a name="chap9">Processing multiple lines of input</a></h3><PRE>Instead of using a simple input trigger, you can also hook directly to thestream of input from the MUD. This is done using:input_add("function");input_remove("function");Once you get the input, you can do whatever you want with it. If you set$_ to "" there, the line will not be shown at all.</PRE><h3><a name="chap10">Functions called by mcl</a></h3><PRE>There is a number of functions that mcl will call in your perl scriptsautomatically. mcl will give up after one time of calling this function andnot finding it - if you want to e.g. remove the idle function to laterreturn it, you will have to call enableFunction("idle") to allow mclto search for it again.You probably DON'T want to register any of those functions yourself!Use instead functions provided to ad a hook to list of functions that getrun. When nothing else is specified, the functions that add/remove a hookare called X_add/X_remove (e.g. postinput_add). Remember to pass the functionas reference - that is either:input_add(\&function);orinput_add("function");Note that all these functions are searched for in the sys/ directory, unlessthey are defined already. Following functions are called:idle Called every second. See section about callouts longer up.command Ran after input has been received from the user - at the same level as aliased, so can be (and is) used to add custom commands.userinput Called after the user has typed something on the keyboard and pressed enter. You can modify $_ to modify the text typed.send Called when about to write something to the MUD. You can change the text written. Note that userinput and send are not the same - for example "nnnn" will call userinput with $_ set to "nnnn" but then will call send 4 times, with 4_ set to "n" each time.output Triggered on any output from the mud. Can modify it. Ran after triggers and substitutions.loselink Triggered on link loss. Typicall you would add a e.g. 5 second calllout and try to reconnect - *unless* quit has been used recently. The reconnect.pl file does exactly that.prompt Triggered when a new prompt arrives. By changing the prompt there, you can change what gets displayed in the status line.postoutput This is a function that is called after all output the MUD has been received.init This is called when mcl starts up. If you have somethin you need loaded then, put it in the auto/ directory or in the localinit.pl file - there are no hooks for this callback.done Called when mcl exits (including via alt-t). If you have started any processes, you must kill them here! (see e.g. the spellcheck module).keypress Called at every keypress done while on the input line. $_ holds the input line (you can modify this). $Key holds the value of the key pressed - you can modify that as well.connect Run when the user attempts to connect to a MUD </PRE><h3><a name="chap11">Color codes</a></h3><PRE>mcl will define a number of color codes for you that you can use in yourscripts. The full list is in sys/color.pl. You can use them in e.g. print:print "I am ${Red}Red${Off}.\n";Note that we use ${Red} here rather than $Red to avoid confusion where thevariable name starts and ends. $Off just resets to White on Black.In addition to normal colors, B makes a color bold. E.g. $BRed.To make a background color you need to use the setColor sub with theforeground as the first argument and the background as the second - e.g.print "You have been", &setColor($Black, $White), "KILLED!${Off}\n"Finally, you can use the two procedures str_to_color and color_to_str toconvert colors into saveable strings. str_to color will accept a string like"red", "bold_red", "red_blue" (red on blue background) and output the rightcolor code, while color_to_str will do exactly the reverse.</PRE>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -