ViRCScript Documentation (for Visual IRC '96 0.82a and above) - Revision 16a ============================================================================ Introduction ============ What is ViRCScript? ViRCScript (from now on abbreviated to VS) is the scripting language supported by ViRC '96. VS is similar to BASIC, C, VPL, and ircII's scripting language. You use VS to write code for events and aliases. In 0.82, the ViRCScript interpreter is around 97% complete. Newer versions will add more functionality, however, I will endeavour to ensure that these new changes don't break your old code. VS is 100% written by myself. I've used no code from anywhere else or custom controls in my parser, numerical evaluator, or anything else. This means that if you have any problems, you have no-one to blame them on but me. >:-> (That said, no-one has reported any real problems in ViRCScript. It seems to be the most stable portion of V96 I've written so far). What's new in this release of ViRCScript? ----------------------------------------- Note that this list also includes the stuff new in 0.80 and 0.82. The ^^ (raise to a power) operator now works properly. Deleting array variables with a variable as the index (e.g. -@ $array.$x) now works properly (finally!! ;). Added C-style += and -= operators. Added date/time formatting capabilities to the TIME function. Corrected some documentation inaccuracies (e.g. the built-in variables, and in the sample code for the IDLETIME function). New built-in event. New BEEP command. New OPENDIALOG and SAVEDIALOG functions to encapsulate the common dialogs. Fixed bugs where pseudovariables could be lost after TextOut and Yield statements. New built-in DCC events (, , ). Minor performance improvements. HALT statement now breaks out of all loops correctly (previous versions had problems with breaking out of nested code blocks). MIN, MAX, RESTORE, CLOSE, SETFOCUS window-handling functions. New file I/O stuff (READLINE, GETLINESINFILE commands). Directory I/O stuff (MKDIR, CHDIR, RMDIR commands, GETCURRENTDIR function). UNALIAS and UNEVENT commands added. ObjectViRCScript extensions added (see OBJECTVS.TXT). New MESSAGEDLG function added. New in 0.82: SIMULATESERVERDATA command. New OPTIMIZED keyword for FOR and WHILE statements. New set-handling functions (ADDTOSET, REMOVEFROMSET and ISINSET). New GETUSER function. Documented event templates (they were implemented in 0.80, but were documented only in 0.82). Severely-broken BREAK command fixed. CONTINUE command added. Conditional execution parameters added to BREAK and HALT commands (and CONTINUE too). Corrected documentation inaccuracies (e.g. the code sample given in the local variables section (the LOCALTEST and LOCALLOOP aliases) did not work at all ;). New OPSTRIP and SELECTEDNICK functions. New in 0.82a: Buggy string comparisons with == fixed. WILDMATCH function improved to handle a*c-style wildcards. New === (exactly equals) operator added. Syntax ------ Place one VS instruction on each line. Lines beginning with # or // are assumed to be comments, and are ignored. Otherwise the line is parsed and executed. Statements and functions are case-insensitive, except for variables, which are case-sensitive, i.e. $x is not the same as $X. Numerical parameters to functions can be supplied in decimal, or in hex by prefixing with a $. For example, to get a random number between 0 and 254, you could use: $rand(255) Or: $rand($FF) Variables --------- Variables are allocated and assigned with the @ operator, and deallocated with the -@ operator. Examples: @ $x = Hello everybody!! -@ $x Wildcards are supported when using -@, and this is very useful with arrays. Say, for example, you defined the following array: @ $greeting.0 = Hello @ $greeting.1 = Hi @ $greeting.2 = Yo @ $greeting.3 = Greetings @ $greeting.4 = Howdy You could delete the whole thing in one go with the single statement: -@ $greeting.* Or, as the array element numbers are only 1 figure long: -@ $greeting.? You should always deallocate used variables at the end of your scripts, as "dangling" variables will make script parsing slower and take up memory. In addition, ViRC '96 0.34 and above support stored variables. These are like regular variables, except their values are stored in the registry, and hence are retained if V96 is closed down and then restarted. Define a stored variable exactly like a regular variable, except use @s instead of @. Undefine a stored variable by using -@s instead of -@. For example: @s $script_ver = YTooLZ for ViRC '96 version 4.91 The value of $script_ver will not be lost when V96 is closed down. The third type of variable (new in V96 0.80) is the local variable. This type of variable is the recommended type to use inside your aliases and events. Local variables are only accessible from the scope that they were created in. In addition, you can have more than one local variable with the same name, provided they are in different scope blocks. ViRC '96's garbage collector automatically deallocates local variables when they fall out of scope - you cannot deallocate them yourself. Local variables are created with @l instead of @. Note that local array variables currently aren't supported, as I've found this to result in a large performance hit. Example: @l $x = hello Here's a good example of where global (@) variables will not work, and you have to use locals. Just type /localtest, and observe the (correct, expected) output: Alias LOCALTEST for (@l $i = 0; $i < 10; $i++) TextOut > . clBlue Variable $$i in LOCALTEST: $i LocalLoop endfor EndAlias Alias LOCALLOOP for (@l $i = 0; $i < 10; $i++) TextOut > . clBlue Variable $$i in LOCALLOOP: $i endfor EndAlias This code will work correctly, despite the fact that two local variables called $i are used at the same time, as they are defined as local (@l) variables. If the @l was changed to @ to make them global variables, typing /localtest would produce incorrect output as the $i defined in LOCALTEST would be accessible in LOCALLOOP. You can evaluate a numeric expression by enclosing it in $( and ). For example: @ $x = $(1+1) As opposed to @ $x = 1+1, which will assign the string "1+1" to the variable $x, and so _WILL_NOT_WORK_. You can evaluate expressions as complex as you want, including variables and functions, for example: @ $x = $((((16/2)*$strpos(xt $3-))+(18/$dfactor))-1) $() is not required in if/while/for statements, as the conditions are evaluated numerically anyway. In addition, V96 0.60 and above support the C-style ++ and -- operators. What's more, they're not just a pretty face - they execute a LOT, LOT faster than the equivalent code @ $i = $($i + 1), and are ideal for loops and things. For example, to increment $x by one, you could use: $x++ Please note that, unlike variable assignments, you DO NOT prefix this with an @. V96 0.80 and above support the C-style += and -= operators (BUT NOT *= and /= etc. yet), e.g. $x += 4 $y -= 16 Again, these are much faster than the equivalent @ $x = $($x + 4) etc. ViRCScript doesn't care about spacing when using any of these operators. Pseudovariables (Pvars) are also supported in aliases and events. A typical Pvar looks like $0, or $7-, and represents a parameter supplied to the alias or event. $n means the n'th parameter. With events, the first word of the line of text received from the server is $0, the second word $1, and so on. With aliases, the alias command is $0, the first parameter supplied is $1, the second parameter supplied is $2, and so on. In addition, an expression like $2- means "the second parameter and all subsequent parameters". So, $2- is equal to $2 $3 $4 $5 $6 $7 $8 .... $n. More about this later. V96 also maintains a number of built-in variables. These are as follows: $ver The current version of V96, e.g. 0.60 $build The current version V96 in integer form, e.g. 60 $N Your nickname $U Your username $H Your hostname $ip Your IP address $server The server you're connected to $C The channel the user types the alias in. If the alias is typed in a server window, $C is set to . (a period). If the alias is typed in a query window, $C contains the nick of the person you are querying. $null Equals nothing. Use to set variables to nothing, e.g. @ $x = $null A number of constants are also maintained: \b Bold \u Underline \i Italic \A ASCII character 1 -  (used for CTCPs) Note that V96 supports a number of simultaneous server connections, even if you're on the same channel on both servers!! And you can have a different nickname on each server. So what nickname does $N correspond to? The answer is, the active context's nickname. If you use $N from an event, $N is the nickname on the server which caused the event. $N in an alias refers to the nickname of the current server connection relating to the window you typed the alias in. For example, $N in a channel window would be your nick on the server that you're on that channel on. Sounds confusing? Just use $N and it should work as you expect it to every time. =] What about $+ you may ask. As most of you know, in mIRC, PIRCH etc. you need $+ to trim spaces ... in other words, you'd need something like this: *** $nick ( $+ $user $+ @ $+ $host $+ ) has joined channel $3 To display this: *** MeGALiTH (megalith@jimc.demon.co.uk) has joined channel #quake In V96, spaces are not required before variables and functions, because of its intelligent parser. So you could do something like this, which looks much neater: *** $nick ($user@$host) has joined channel $3 The above would totally foul up mIRC and PIRCH. In fact, V96 doesn't care what you have before or after a variable. This would work: alkjdsjkadjka$nickjhdakajsdakjdhkjadhk So, the skeptic asks, in this case, how does V96 know whether you want the variable $nick, $nickj, $nickjhdak, or what? The answer is, it reads your mind. Well, no, it doesn't - it actually sorts the variables alphabetically and parses them in reverse order (you what?!??!). This ends up with the right result. If a variable $nickjhd exists, then it'll parse the line as containing $nickjhd, otherwise it'll do $nickjh, and if that doesn't exist, $nickj ... and so on, all the way down to $n. So, again, as with the multiple-$N-on-multiple- servers thing I described above, V96 is intelligent enough to work out what you're trying to do, and do it correctly. ViRCScript Statements ===================== TEXTOUT statement ----------------- Usage: TextOut [> window] Displays some text in a window. If the window name is left out, TextOut will output the text to all channel windows, unless there are none open, in which case the text will be displayed in the server window. Specifying a channel name will display the text in that channel (or the server window if the channel doesn't exist). Specifying . will output the text to the server notices window. Specifying anything else will create a query window with that name (if it doesn't already exist) and output the text there. You can use a query window created "on-the-fly" like this as a simple text output window for your scripts. Colour may be specified in four ways. (1) Specifying a colour constant. The following colour constants are supported (this will be familiar to Delphi 2.0 users): clBlack Black clMaroon Maroon clGreen Green clOlive Olive green clNavy Navy blue clPurple Purple clTeal Teal clGray Gray clSilver Silver clRed Red clLime Lime green clBlue Blue clFuchsia Fuchsia clAqua Aqua clWhite White clBackground Current color of your Windows background clActiveCaption Current color of the title bar of the active window clInactiveCaption Current color of the title bar of inactive windows clMenu Current background color of menus clWindow Current background color of windows clWindowFrame Current color of window frames clMenuText Current color of text on menus clWindowText Current color of text in windows clCaptionText Current color of the text on the title bar of the active window clActiveBorder Current border color of the active window clInactiveBorder Current border color of inactive windows clAppWorkSpace Current color of the application workspace clHighlight Current background color of selected text clHightlightText Current color of selected text clBtnFace Current color of a button face clBtnShadow Current color of a shadow cast by a button clGrayText Current color of text that is dimmed clBtnText Current color of text on a button clInactiveCaptionText Current color of the text on the title bar of an inactive window clBtnHighlight Current color of the highlighting on a button cl3DDkShadow Windows 95 only: Dark shadow for three-dimensional display elements cl3DLight Windows 95 only: Light color for three-dimensional display elements (for edges facing the light source) clInfoText Windows 95 only: Text color for tooltip controls clInfoBk Windows 95 only: Background color for tooltip controls The second half of the colors listed here are Windows system colors. The color that appears depends on the color scheme users are using for Windows. Users can change these colors using the Control Panel in Program Manager. The actual color that appears will vary from system to system. For example, the color fuchsia may appear more blue on one system than another. For example, to output some blue text in the server window: TextOut > . clBlue blah blah blah ... (2) Specifying an event colour constant. Event colour constants correspond to the colour of the corresponding event type the user has selected in Client setup/Colours and fonts. This allows scripts that you write to automatically adjust to the colours the user wants. The following event colour constants are available. ecJOIN Join colour ecPART Part colour ecQUIT Quit colour ecTOPIC Topic change colour ecMODE Mode change colour ecKICK Kick colour ecPRIVMSG Private message colour ecNOTICE Notice colour ecCTCP CTCP colour ecACTION Action colour ecNICK Nick change colour ecMyChanText Colour of channel text the user has entered himself ecChanText Colour of channel text other users have entered ecMyQueryText Colour of query text the user has entered himself ecQueryText Colour of query text other users have entered ecServText Colour of server text ecError Colour of error text ecScript or ecXDCC Colour of script (e.g. XDCC) status messages For example: TextOut ecKICK This text will appear in the same colour as channel kicks do. (3) Specifying a hex RGB value, in the form $bbggrr. For example: TextOut $0000FF This text is red. TextOut $00FF00 This text is green. TextOut $FF0000 This text is blue. TextOut $00FFFF This text is yellow. TextOut $FFFFFF This text is white. TextOut $000000 This text is black. (4) Specifying a decimal RGB value. This is rather useless, unless you're specifying the text colour as a random number, e.g. TextOut $rand($FFFFFF) This text appears in a random colour. New in 0.80, with ObjectViRCScript, you can also specify the handle of a TRichEdit object you have created (see OBJECTVS.TXT) to output text to that TRichEdit control. However, in order for TextOut to recognize the handle as an ObjectViRCScript object handle, it must be preceded with %. Example to create a form with a TRichEdit on it and write some text to it (BTW, the @p $edit.Align = 5 line simply makes the TRichEdit automatically fill the form, so there's no need to specify a size initally by setting the Left, Top etc. properties. Align = 5 corresponds to Delphi's Align = alClient. You'll be able to specify the properties by textual name shortly, but for now you'll just have to fiddle with the numbers until you get the effect you want!!): @ $form = $new(TForm) @p $form.Left = 20 @p $form.Top = 20 @p $form.Width = 300 @p $form.Height = 300 @p $form.Visible = 1 @ $edit = $new(TRichEdit ownedby $form) @p $edit.Align = 5 @p $edit.Visible = 1 TextOut > %$edit clBlue This text will appear in \bblue\b!! TextOut > %$edit clRed This text will appear in \bred\b!! IF/ELSE/ENDIF statements ------------------------ Usage: if (condition) ... [else] [...] endif Executes a block of code only if a given condition is true. Multiple conditions can be specified, and are separated with && (boolean AND) or || (boolean OR) operators. If the condition is false and an ELSE block exists, this code is executed. The following operators are supported: Op | Meaning ------+-------------------------- == | Equal to === | Strong (exact) comparison (same as == only case-sensitive when comparing strings) != | Not equal to > | Greater than < | Less than >= | Greater than or equal to <= | Less than or equal to + | Plus - | Minus * | Multiply / | Divide ^^ | Power && | Boolean AND || | Boolean OR ! | Boolean NOT If you're used to C, you'll have no problems. Expressions can be as simple or as complex as you like - you can nest many levels of brackets if you need to. IF can be used to compare numeric expressions or string expressions. All string expressions must be enclosed in []'s, just as in ircII. Numeric expression example: if (2+3 == 5) TextOut clBlue Of course it does!! endif String expression example: if ([hello] == [goodbye]) TextOut clBlue Not unless the laws of physics have changed. endif Boolean operators may also be used. && = and, || = or, ! = not. if (2+3 == 5) && (4*2 == 8) TextOut clBlue Naturally. endif In fact, you'll rarely have to use the ! operator. You'll see that the following two statements are equivalent: if ([$x] != [$y]) if !([$x] == [$y]) Note that spaces are not required (they are ignored by the parser), but may be included for clarity. For example: if (2+3==5)&&(10*17==170)&&((5>=2)||(9=16)) That's perfectly correct, but impossible to read ;). Adding spaces makes the statement far clearer: if (2+3 == 5) && (10*17 == 170) && ((5 >= 2) || (9 == 16)) You must enclose string expressions in []'s. This prevents V96 from trying to numerically evaluate the text between the [ and the ]. For example: if ([$nick] == [hello]) TextOut clBlue Blah!! endif An ELSE construction is supported too. @ $x = $?="What does IRC stand for?" if ([$x] == [Internet Relay Chat]) TextOut clGreen Well done!! else TextOut clRed Wrong!! endif WHILE/ENDWHILE statements ------------------------- Usage: while [optimized] (condition) ... endwhile Executes a block of code while condition is true. If condition is false initially, the while block will be skipped. See the IF/ELSE/ENDIF statement for details on how to specify conditions. Beware, as a condition that's always true will produce an infinite loop and will lock V96 up!! For example: while (1) endwhile In fact, now ViRCScript has a C-like for statement, while is largely superflous. In fact: while (condition) ... endwhile Is functionally-identical to: for (;condition;) ... endfor The for statement is used only with a condition, with no initial statement and no increment statement. In V96 0.82 and above, the new OPTIMIZED keyword is supported. You can use it like this: while optimized ($i <= 10000) $i++ endwhile OPTIMIZED enables specific optimizations which cause tight loops (containing only one instruction, in this case $j++) to execute around 20% faster. V96 will check that the loop contains only one instruction if you specify OPTIMIZED, and if it does not, the keyword will be ignored. You can use all regular commands and functions in an OPTIMIZED while loop except for HALT, BREAK, CONTINUE, FALLTHROUGH, YIELD, and TEXTOUT. Usage of these commands in an OPTIMIZED loop may cause undefined (and possibly erratic) problems. FOR/ENDFOR statements --------------------- Usage: for [optimized] (initial statement;condition;increment statement) ... endfor V96's for statement behaves exactly like the for statement in C/C++, so you should have no problems. For example, the following C code: for (int i = 0; i < 10; i++) printf("%d", i); Is equivalent to the following ViRCScript code: for (@ $i = 0; $i < 10; $i++) TextOut clBlue $i endfor (Note the use of the new ++ operator here!!) Note that variables created by the for statement (e.g. the $i above) are not deallocated at the end, so the following statement should really be added to the end of the above code fragment: -@ $i The for and while statements are often interchangable. In fact: for (x;y;z) ... endfor Is equivalent to: x while (y) ... z endwhile However, usage of for is much neater in many cases than while. Note that, just like C, misuse of for can lock the system up!! Compare the following C fragment: for (;;) ... And the following ViRCScript: for (;;) ... endfor Both will lock the system up in an infinite loop (unless, of course, a BREAK or HALT statement is used somewhere in the loop). So be careful!! In V96 0.82 and above, the new OPTIMIZED keyword is supported. You can use it like this: for optimized (@ $i = 1; $i <= 10000; $i++) $j++ endfor OPTIMIZED enables specific optimizations which cause tight loops (containing only one instruction, in this case $j++) to execute around 20% faster. V96 will check that the loop contains only one instruction if you specify OPTIMIZED, and if it does not, the keyword will be ignored. You can use all regular commands and functions in an OPTIMIZED for loop except for HALT, BREAK, FALLTHROUGH, YIELD, and TEXTOUT. Usage of these commands in an OPTIMIZED loop may cause undefined (and possibly erratic) problems. ALIAS/ENDALIAS statements ------------------------- Usage: alias [hotkey] ... endalias Defines an alias (similar to a procedure or function in other languages). The parameters of the alias are passed in as $1, $2, $3 and so on, and the actual alias command itself is passed in as $0. The channel window the alias is typed in is passed in as $C. $C is set to . if the alias is run from the server notices window. Optionally, hotkey may be specifed (e.g. F3, or Ctrl+Shift+Z). When hotkey is pressed, the alias will be executed as if it were typed in the current window. Aliases can be very useful, for example, consider this: Alias GO Connect Join #quake Msg Bot !op Mode #quake +ooo User1 User2 User3 Part #quake Quit EndAlias When the user types /go, V96 will connect to the server, join #quake, /msg Bot for ops, op User1, User2 and User3, leave #quake, and quit IRC. Aliases can also be used as functions. Simply assign a value to $fresult as the value of the function. For example, consider this, a function to pick and return a random boolean value, either True or False: Alias RANDBOOL @ $x = $rand(2) if ($x == 1) @ $fresult = True else @ $fresult = False endif EndAlias Now: TextOut clBlue Random boolean expression: $randbool() Another use for aliases is executing frequently-used single commands. For example, say you're on #quake, and are frequently asked what the current version of Quake is. You could make an alias like this: Alias QUAKEVER Say $C $1: The current version of Quake is 1.01. EndAlias Then, for example, if Dnormlguy asked what the latest version of Quake was, in the #quake channel window, you could just type /quakever Dnormlguy. V96 would expand $C to #quake, and $1 to the first parameter, Dnormlguy. So, the text "Dnormlguy: The current version of Quake is 0.92" to the channel. UNALIAS command --------------- Usage: UnAlias alias [alias ...] Removes one or more aliases. For example, this removes the 3 aliases OP, DEOP and J. UnAlias OP DEOP J EVENT/ENDEVENT statements (read!! This is changed!!) ---------------------------------------------------- Usage: event "" ... endevent Defines an event. Events are the most powerful feature of VS, although also the hardest to grasp (although this has largely been alleviated now that event priorities have been removed). The best way to get a feel for events is to look through V96's built-in events and see how they work. Name is just an arbitrary name to assign to the event. You can call events anything you like. Mask is the text that must be received from the server to trigger the event, and can include wildcards. Parameters are passed into the event with the first word received from the server as $0, the second word as $1, etc. In addition, the sender of the message's nick is stored in $nick, the username in $user, and the hostname in $host. If the message originates from the server, $nick is the server, and $user and $host are empty. Example: :greygoon!bhess@wilma.widomaker.com NOTICE MeGALiTH :You're not opped!! This is what the server sends when greygoon sends the notice "You're not opped!!" to MeGALiTH. So, the parameter breakdown would be as follows: $0 :greygoon!bhess@wilma.widomaker.com $1 NOTICE $2 MeGALiTH $3 :You're $4 not $5 opped!! $nick greygoon $user bhess $host wilma.widomaker.com Thus the activation mask for a NOTICE is "* NOTICE *". This basically means: $0 can be anything, $1 must be NOTICE, and $2 can be anything. Any parameters that are not supplied can be anything - in fact, the * at the end of the mask is not really necessary, but is included for clarity. More specific masks are executed in preference to less specific masks. For example, the following event statements are used for private and channel messages. Private messages: Event PrivateMessage "* PRIVMSG *" Channel messages: Event ChannelMessage "* PRIVMSG #*" A typical private message received from the server may look like this: :nick!user@host PRIVMSG YourNick :hello!! A typical channel message might look like this: :nick!user@host PRIVMSG #quake :hello all!! Therefore, if V96 gets a channel message, the PrivateMessage event is NOT executed, even though the mask matches, because there's a more specific event mask that matches, namely ChannelMessage. Note that the event (mask *), which is fired for every line of server text that is received, is only executed if NO OTHER EVENTS have a mask which matches the line of server text. In 0.80 and above, event templates are supported. This means that you can use masks from other events as templates for your own masks, which makes the events clearer. You use another event mask as a template by putting the name of the event in ()'s at the beginning of your own mask. For example, the CTCP event mask is as follows: * PRIVMSG * :\A* Therefore, if you wanted to make an event that responded to CTCP HELLO, you could do: Event CTCPHello "(CTCP)HELLO" V96 would expand the mask (CTCP)HELLO to ... * PRIVMSG * :\A*HELLO ... which is the correct mask to do what you want. In addition, if you wish to redefine an event without changing the mask, you could always use the event mask itself as a mask template, for example: Event PrivateMessage "(PrivateMessage)" ... code for new PrivateMessage event ... EndEvent Events that begin with < (with the exception of ) are NEVER fired by events from the server, even if the masks match. You can thus create your own events which you can fire manually from code with the FIREEVENT command. Built-in events --------------- V96 has a number of built-in events. They are: - fired when connected to a server $0 = server name - fired when disconnected from a server $0 = server name - fired when a user in the notify list joins IRC $0 = nick of user who joined - fired when a user in the notify list leaves IRC $0 = nick of user who left - fired when next is added to an inactive window $0 = 1 if first new line, 0 for subsequent lines $1 = window type (SERVER, CHANNEL, QUERY, or DCC) $2 = window name (e.g. #quake, MeGALiTH, etc). - fired when a DCC Chat session connects $0 = nick of user who chat connection is with - fired when a DCC Chat session disconnects $0 = nick of user who chat connection is with - fired when a DCC Send session connects $0 = nick of user you're sending the file to $1 = filename of file you're sending - fired when a DCC Send session disconnects $0 = nick of user you're sending the file to $1 = filename of file you're sending $2 = 1 if transfer complete, 0 if transfer aborted - fired when a DCC Send session connects $0 = nick of user you're getting the file from $1 = filename of file you're receiving - fired when a DCC Send session disconnects $0 = nick of user you're getting the file from $1 = filename of file you're receiving $2 = 1 if transfer complete, 0 if transfer aborted - fired when ViRC '96 starts up - fired when ViRC '96 closes down IMPORTANT NOTE: In 0.82 and later versions of V96, you can define multiple, individual events for each of the above. This is done by calling the events . For example, if you wanted several events, you could define them as , etc., and they would each be called correctly. If you are defining these events in a script, it is STRONGLY RECOMMENDED that you give these events a unique name, so that it doesn't interfere with the operation of any other scripts, for example, you could call an event or if you're writing a script called XYZScript. UNEVENT command --------------- Usage: UnEvent event [event ...] Removes one or more events. For example, this removes the 2 events JOIN and PART: UnEvent JOIN PART PARSE/ENDPARSE statements ------------------------- Usage: parse text ... endparse Parses text into the pseudovariables $0 to $9 for the duration of the parse block. Without doubt one of the most powerful commands in ViRCScript. Its use is best illustrated by an example: @ $x = This is a test. Parse $x TextOut clBlue $0 $1 $2 $3 TextOut clBlue $3 $2 $1 $0 EndParse The following will appear on the screen: This is a test. test. a is This The values of the pseudovariables are restored to their previous state at the end of the parse block. So, they are only valid between Parse and EndParse. You must assign them to other variables if you want to use them outside the parse block. You may nest as many parse blocks within each other as you like. What in reality could this be used for? One idea is a #chaos-type question game, You have a file called QUESTION.TXT which contains questions and answers in the form: answer question ... answer question ... answer question ... And so on. You want some code to pick a random question from the file, putting the question in $question and the answer in $answer. The following code would do the trick: @ $x = $randomread(question.txt) Parse $x @ $answer = $0 @ $question = $1- EndParse MENUTREE/ENDMENUTREE command ---------------------------- Usage: menutree menutype [item1] [item2] ... endmenutree Defines the menu tree for menutype. This command is used to define the structure of a menu or popup, before code is assigned to each item. The following values for menutype are currently recognized: MT_MAINMENU - define the tree for the main menu MT_SERVERPOPUP - define the tree for the server window popup MT_CHANNELTEXT - define the tree for the channel window text pane popup MT_CHANNELNICKS - define the tree for the channel window names pane popup Each item defined between MenuTree and EndMenuTree takes the following format: ItemName HotKey State Depth Text ItemName is an arbitrary name to give to the menu item. The name will be used again later to define the code when you click on the menu item. HotKey defines what hotkey to activate the menu item on. HotKey can be something like F12 or Ctrl+Shift+A, or if you don't require a hotkey. Note that HotKey is ignored for menus other than MT_MAINMENU. State determines the menu item's state. For menu types MT_MAINMENU and MT_SERVERPOPUP, State can take the following values: 0 - Menu item is enabled 1 - Menu item is enabled when you're connected to the server, and disabled otherwise 2 - Menu item is disabled when you're connected to the server, and enabled otherwise 3 - Menu item is disabled For menu types MT_CHANNELTEXT and MT_CHANNELNICKS, State can take the following values: 0 - Menu item is enabled 1 - Menu item is enabled when you're opped on this channel, and disabled otherwise 2 - Menu item is disabled when you're opped on this channel, and enabled otherwise 3 - Menu item is disabled Depth defines the "depth" of the menu item. For MT_MAINMENU, a depth of 0 represents an entry on the top menu bar. A depth of 1 is a subitem of the closest item above which has a depth of 0. A depth of 2 is a subitem of the closest item above that has a depth of 1. Text is the actual text to display on the menu. If an & is present in Text, you can pull the menu down quickly by pressing Alt and the letter after the &. Here are some example menu tree items, taken from DEFAULT.LIB: M_FILE 0 0 &File M_NEWCONNECT Ctrl+K 0 1 &New connection ... M_SETUP 0 1 Client s&etup ... M_FSEP1 0 1 - M_EXIT Alt+X 0 1 E&xit M_TOOLS 0 0 &Tools M_FINGER Ctrl+F 0 1 UNIX &finger ... Hopefully by comparing this with what you actually see in the program will enable you to understand the significance of each field. MENUITEM/ENDMENUITEM command ---------------------------- Usage: menuitem ItemName on MenuType Defines the ViRCScript code to trigger when the user clicks on the menu item Name on the menu type MenuType. MenuType can take the same values here as with the MenuTree command detailed above. In the above example, one of the item lines between MenuTree and EndMenuTree is: M_NEWCONNECT Ctrl+K 0 1 &New connection ... To define the ViRCScript code to actually make this open a new server window, you would use: MenuItem M_NEWCONNECT on MT_MAINMENU NewServerWindow EndMenuItem For a good example of how this works, see DEFAULT.LIB. Menu items on a MenuType of MT_CHANNELNICKSPOPUP are supplied with the nickname selected in the names pane of the currently-active channel window as the parameter $1. For example: MenuItem M_HELLO on MT_CHANNELNICKSPOPUP Say $C Hello, $1!! EndMenuItem If the user clicks on abc123's nick in a channel window, and then right-clicks and selects M_HELLO from the popup menu, the text "Hello, abc123!!" will be said to the channel. UPDATEMENUS command ------------------- Usage: updatemenus Recreates all menus and popups from the in-memory menu trees and writes the trees to the registry. After you have changed menu(s) with MenuTree and MenuItem statements, you must use this command for your changes to take effect properly. Failure to execute this command when you've finished altering the menus can cause unwanted side-effects, as the in-memory menu trees and the actual menus and popups become desynchronized from each other. NAME statement -------------- Usage: name text Names your script text. This isn't really a statement at all. It's used by the script loader to display your script's name in the loading progress dialog box. It's recommended you use NAME to give your script a sensible name at the top of the file, so people know what they're loading. MESSAGEBOX command ------------------ Usage: MessageBox text Displays a message box on the screen with an OK button, with text as its contents. Use this in scripts to inform the user of something. CREATEFILE command ------------------ Usage: CreateFile filename Creates filename, or truncates it to 0 bytes if it already exists. APPENDTEXT command ------------------ Usage: AppendText filename text Appends text to the end of filename. In V96 0.80 and above, filename will be created if it doesn't already exist. MKDIR command ------------- Usage: MkDir dir Makes a directory called dir. CHDIR command ------------- Usage: ChDir dir Changes to the dir directory. RMDIR command ------------- Usage: RmDir dir Removes the dir directory. SETINPUTLINE command -------------------- Usage: SetInputLine channel text Sets the command entry box's contents of channel to text. If you wish to set the contents of the server window's entry box, specify . as channel (a period). EVAL command ------------ Usage: Eval command Normally, commands are evaluated before executing them. Placing EVAL before a command line causes the line to be evaluated twice before executing. You'd probably never have to use this in your scripts, except when evaluating expressions that are stored somewhere else, for example, a line in a file. To get a random line from a file, evaluate that line, and store in $x, you'd use: Eval @ $x = $randomread(filename.txt) BREAK command ------------- Usage: Break [if condition] Quits from the currently-executing code block. A code block is something like the code between if/endif, while/endwhile, parse/endparse etc. If this statement is executed outside a code block, execution of your script routine will stop (see the HALT command). If a BREAK statement is encountered inside a FOR or WHILE loop, control will immediately be transferred out of the loop. If a condition is specified, the break will only occur if the condition is met, for example, the following code will print 0, 1, 2, 3 and 4 in the server window: for (@l $i = 0; $i <= 10; $i++) Break if ($i == 5) TextOut > . clBlue $i endfor CONTINUE command ---------------- Usage: Continue [if condition] Only used within FOR and WHILE blocks, CONTINUE causes the next iteration of the loop to begin immediately, without finishing the current iteration. If a condition is specified, the continue will only occur if the condition is met, for example, the following code will print 0, 1, 2, 3, 4, 6, 7 and 8 in the server window: for (@l $i = 0; $i <= 10; $i++) Continue if ($i == 5) TextOut > . clBlue $i endfor HALT command ------------ Usage: Halt [if condition] Similar to the BREAK command, only exits from ALL code blocks and terminates execution of your script. As with BREAK, an optional condition can be specified, and the HALT will only occur if the condition is met. FALLTHROUGH command ------------------- Usage: FallThrough This powerful command makes event programming much easier. If you've defined a special event, but you only want it to execute sometimes, and the rest of the time you want the system to behave as if the event was never defined, you can use the FallThrough statement to pass the event down to a handler of lower priority. A good example is if you're writing, for example, a channel statistics script, which catches WHO replies (* 352 *) and processes them, without displaying them in the server notices window. However, if the user has not typed /chanst, then the regular event should be executed to display the WHO on the screen in the normal way. The event would be defined like this: Event ChanStatWHOReply 5 "* 352 *" if ($doingchanst) ... else FallThrough endif YIELD command ------------- Usage: Yield Polls the Windows message queue and processes waiting messages. If you're writing a script that uses a while loop that takes a long time to execute, it may be a good idea to use YIELD to prevent the system from locking up while your script is executing. For example, the following will lock V96 up: while (1) endwhile However, the following will not lock V96 up, although it'll slow it down a little because it is actually executing the while loop over and over again, ad infinitum: while (1) Yield endwhile The YIELD command is very useful when implementing background processing. Adding a YIELD statement to a time-consuming for loop will allow other tasks to continue running in the background while the for loop executes. IMPORTANT NOTE!! Things can happen while Yield is executing. Even other VS code can execute (e.g. if an event occurs during the Yield statement). Therefore, you CANNOT assume that variables like $C will retain their value after executing Yield, as another VS code section may have changed them. Therefore, always save things like $C to your own variables (e.g. $chan) before executing Yield if you wish to ensure that the variables don't change from underneath your feet. BEEP command ------------ Usage: Beep The name says it all. ;) Produces a standard Windows beep. SETFOCUS command ---------------- Usage: SetFocus window Sets focus to window. window can be . to set the focus to the server notices window, a channel name, or a nick (query window). MIN command ----------- Usage: Min window Minimizes window. window can be . to set the focus to the server notices window, a channel name, or a nick (query window). MAX command ----------- Usage: Max window Maximizes window. window can be . to set the focus to the server notices window, a channel name, or a nick (query window). RESTORE command --------------- Usage: Restore window Restores window. window can be . to set the focus to the server notices window, a channel name, or a nick (query window). CLOSE command ------------- Usage: Close window Closes window. window can be . to set the focus to the server notices window, a channel name, or a nick (query window). DDE command ----------- Usage: DDE service topic "item" text Suntactically identical to mIRC's command of the same name. Connects to a DDE server using the details supplied and sends text by DDE. This command can also be used as a function, i.e. $dde(service topic "item" text), and will return any data received from the DDE server as a result of the DDE command. SAY command ----------- Usage: Say channel text Sends the message text to channel. Use in scripts to send text to a channel. I believe this has been undocumented since around 0.30. =] REHASHREGISTRY command ---------------------- Usage: RehashRegistry Makes V96 reload all its settings from the registry. If you're writing a program which modifies any of the in-registry settings while V96 is running, the program should send a RehashRegistry command to V96 via DDE (see VIRCDDE.TXT) to make V96 reload everything from the registry. SIMULATESERVERDATA command -------------------------- Usage: SimulateServerData text Puts text directly into ViRC '96's received data buffer, making V96 behave as if text was received from the server. This is very useful as it allows you to test new events you've written offline, and, possibly more usefully, to simply make DCC connections to a certain IP address and port from a script. In clients like mIRC which don't have this function, you have to send a CTCP to yourself, but this isn't a good idea as you have to wait for the request to come back, which is subject to server lag, and won't work if you're not connected to an IRC server. This command can get around that. For example: SimulateServerData :test!virc@megalith.co.uk PRIVMSG blah :This is a test!! This would make it appear exactly as if you received a private message from a user whose nick is test and whose email address is virc@megalith.co.uk. There is no way to differentiate between real and simulated server events in your scripts. FIREEVENT command ----------------- Usage: FireEvent event parameters Fires event with parameters. This can either be used to pretend that an event was fired by ViRC '96, for example: FireEvent Or, you can define your own custom events, for example , which you could then fire manually, say, in your MODE event: FireEvent $C $nick If no parameters are specified, the event is fired unconditionally. If parameters are specified, the event is only fired if the event's mask matches the parameters specified. You may fire a range of events by including a wildcard, for example: FireEvent \b$1\b<*]\t$2- ^*Msg $1- EndAlias ViRCScript Functions ==================== The current implementation of ViRCScript is almost complete, except for the file I/O functions which will be added later. Getting input from the user --------------------------- $? pseudofunction ----------------- Usage: $?="prompt" Prompts the user to enter some text, displaying prompt in the text entry dialog box. This is similar to mIRC's $? "function". STRTRIM function ---------------- Usage: $strtrim(text) Removes control characters and the preceding colon, if present, from text. This is very useful, as many lines received from the IRC server contain parameters prefixed by a colon. Example: Consider this line of server text. :nick!user@host PRIVMSG #channel :well, what's up everybody!! To extract the actual message sent to the channel correctly, you would use $strtrim($3-). DECODEPINGINTERVAL function --------------------------- Usage: $decodepinginterval(integer) Converts the ping-encoded integer specified to a human-readable time interval. This function is only useful to decode received pings. To decode normal time intervals, use the DECODEINTERVAL function. DECODEINTERVAL function ----------------------- Usage: $decodeinterval(integer) Converts the integer supplied as the parameter to a human-readable time interval. For example: $decodeinterval(38) = 38 seconds $decodeinterval(60) = 1 minute $decodeinterval(61) = 1 minute 1 second $decodeinterval(3728) = 1 hour 2 minutes 8 seconds UPPER function -------------- Usage: $upper(text) Converts the given text to upper case. For example: $upper(blah) = BLAH LOWER function -------------- Usage: $lower(text) Converts the given text to lower case. For example: $lower(BLAH) = blah STRPOS function --------------- Usage: $strpos(needle haystack) Finds needle within haystack, and returns the character position of needle. 0 is returned if needle is not found in haystack. For example: $strpos(cd abcdefg) = 3 $strpos(blah hahahahha) = 0 RAND function ------------- Usage: $rand(n) Returns a random integer in the range 0 to n - 1. For example, $rand(1000) may return 0, 273, or 879, but never -112 or 1000. RANDOMREAD function ------------------- Usage: $randomread(file) Returns a randomly-selected line from file. This is useful for quote or slap scripts. ISON function ------------- Usage: $ison(nick channel) Returns true (1) if nick is on channel, otherwise returns false (0). Example: if $ison(MeGALiTH #quake) Msg MeGALiTH Hi there!! endif ISOP function ------------- Usage: $isop(nick channel) Returns true (1) if nick is an op on channel. If nick is a non-op on channel, or if nick is not on channel, returns false (0). WILDMATCH function ------------------ Usage: $wildmatch(text mask) Matches text against mask, which can contain wildcards. Examples: $wildmatch(blah *lah) = 1 $wildmatch(blah bla*) = 1 $wildmatch(blah *la*) = 1 $wildmatch(blah *) = 1 $wildmatch(blah *hah) = 0 Mask comparisons are case-insensitive. text may contain spaces. mask, however, may not. MASKMATCH function ------------------ Usage: $maskmatch(text mask) Matches text against mask. Use MASKMATCH, and _not_ WILDMATCH, if you're trying to match a nick!user@host-style mask. Example: $maskmatch(MeGALiTH!~megalith@jimc.demon.co.uk *!*megalith@*demon.co.uk) = 1 Mask comparisons are case-insensitive. NICKCOUNT function ------------------ Usage: $nickcount(channel) Returns the number of users on channel. If channel doesn't exist, the function will return 0. OPCOUNT function ---------------- Usage: $opcount(channel) Returns the number of ops on channel. If channel doesn't exist, or if there are no ops, the function will return 0. PEONCOUNT function ------------------ Usage: $peoncount(channel) Returns the number of peons (non-ops) on channel. If channel doesn't exist, or if there are no peons, the function will return 0. NICKS function -------------- Usage: $nicks(channel num) Returns the num'th user on channel. For example, $nicks(#quake 45) will return the nick of the 45th user on channel #quake (the list is sorted alphabetically, with ops at the top, followed by peons). If channel doesn't exist, or there is no user at num (i.e. if num is less than 1 or greater than $nickcount), the function will return nothing. OPS function ------------ Usage: $ops(channel num) Returns the num'th op on channel. For example, $ops(#quake 3) will return the nick of the 3rd op on channel #quake (the list is sorted alphabetically). If channel doesn't exist, or there is no op at num (i.e. if num is less than 1 or greater than $opcount), the function will return nothing. PEONS function -------------- Usage: $peons(channel num) Returns the num'th peon (non-op) on channel. For example, $peons(#quake 19) will return the nick of the 19th peon on channel #quake (the list is sorted alphabetically). If channel doesn't exist, or there is no peon at num (i.e. if num is less than 1 or greater than $peoncount), the function will return nothing. FILEEXISTS function ------------------- Usage: $fileexists(filename) Returns true (1) if filename exists, otherwise returns false (0). SUBSTR function --------------- Usage: $substr(text start num) Returns num characters at start from text. Exactly equivalent to Delphi's Copy(text, start, num) function or VB's Mid$(text, start, num) function. Example: $substr(abcdef 2 3) = bcd GETINPUTLINE function --------------------- Usage: $getinputline(channel) Gets the current contents of the command entry box in channel. To do this for the server notices window, specify . as channel (a period). LENGTH function --------------- Usage: $length(text) Returns the length of text in characters. Example: $length(hello) = 5 CHANNELCOUNT function --------------------- Usage: $channelcount() Returns the number of open channels. CHANNELS function ----------------- Usage: $channels(num) Returns the name of open channel number num. For example, if you have one channel open, #quake, $channels(1) will return #quake. If the channel number num specified does not exist, the function will return nothing. GETSETTING function ------------------- Usage: $getsetting(section value) This is a very powerful function which allows a script to obtain any ViRC '96 user setting that it's stored in the registry. For example, the default event library that comes with V96, DEFAULT.LIB, uses this function to determine whether to output text in a query window or not, depending on whether the user has chosen to use a query window or not in the Options tab of the Client Setup dialog. The best way to find the values for section and value is to load up REGEDIT (it comes with Windows 95 and NT) and to look in HKEY_CURRENT_USER/Software/MeGALiTH Software/Visual IRC '96. All available sections are visible there. Examples: $getsetting(Options QueryEnabled) $getsetting(Options AutoRejoin) $getsetting(SOCKS setup Enabled) $getsetting(IDENTD setup Port) GETUSERLEVEL function --------------------- Usage: $getuserlevel(mask) Returns the userlevel of mask in your userlist. For example, if *!*blah@*hah.com is in your userlist with level 3, $getuserlevel(user!nablah@spahah.com) would return 3. If the user cannot be found in the userlist, the function will return 0. GETBANLEVEL function --------------------- Usage: $getbanlevel(mask) Returns the banlevel of mask in your banlist. If the user cannot be found in the banlist, the function will return 0. GETPROTLEVEL function --------------------- Usage: $getprotlevel(mask) Returns the protlevel of mask in your protlist. If the user cannot be found in the protlist, the function will return 0. TIME function ------------- Usage: $time(format) Returns the current system time in a human-readable format (hh:mm:ss xx). For example, $time() may return 11:52:48 AM. If you wish, you may specify an optional format string to format the date/time in any way you wish. For example: $time(dd/mm/yy hh:mm:ss) - might return 12/07/96 19:21:18 $time(ss) - might return 18 DATE function ------------- Usage: $date() Returns the current system date in default system format. This format is determined by your Windows locale (internationalization) settings, and may be something like 17th June 1996. CTIME function -------------- Usage: $ctime() Used to calculate time intervals, measured in seconds. The actual value returned is the number of seconds that Windows has been running, although this may change in the future and cannot be relied upon. The number returned by $ctime() increases by 1 every second. For example: @ $x = $ctime() for (@ $i = 0; $i < 1000; @ $i = $($i + 1)) Yield endfor TextOut clBlue *** An empty 1000-iteration for loop takes $($ctime() - $x) seconds to complete. Notice how $ctime() is used here to calculate a time interval - the actual meaning of the value returned by $ctime() is insignificant. The $ctime() function can also be used as a timer. For example, to wait for 20 seconds before quitting V96, you could use the following code: @ $x = $ctime() while ($ctime() - $x) < 20 Yield endwhile Exit MTIME function -------------- Usage: $mtime() Used to calculate time intervals, measured in milliseconds. Use for measuring time intervals. The number returned by $mtime() increases by 1 every millisecond. IDLETIME function ----------------- Usage: $idletime() Returns the amount of time the user has been idle for in seconds. Can be used to implement auto-away scripts. For example, the following code will wait until the user has been idle for 2 minutes (120 seconds) and will then set him away: while ($idletime() < 120) Yield endwhile Away Automatically set away after 2 minutes IDLEMTIME function ------------------ Usage: $idlemtime() Returns the amount of time the user has been idle for in milliseconds. The same as $idletime(), only returns a value in milliseconds rather than seconds. CURRENTCHANNEL function ----------------------- Usage: $currentchannel() Returns the name of the channel window that currently has the focus. If a channel window does not have the focus, this function will return . (a period). Note that, in an alias, $C and $currentchannel() are equivalent, however, in an event, $currentchannel() returns the correct value, whereas $C is undefined. Useful if you want to write some text to the channel window the user currently has the focus set to (so he/she won't miss the text!!). ISQUERYING function ------------------- Usage: $isquerying(nick) Returns 1 if a query window is currently open for nick, and 0 otherwise. ASC function ------------ Usage: $asc(char) Returns the ASCII value for char. For example, $asc(A) = 65, as the ASCII code for the character A is 65. CHAR function ------------- Usage: $char(value) Returns the character for value. For example, $asc(65) = A, as the character A corresponds to the ASCII code 65. TIMECONNECTED function ---------------------- Usage: $timeconnected() Returns the number of seconds that you've been connected to the server for. If you're not currently connected to the server, this will return 0. Usefully, the value of this function is not reset to 0 until after has been fired. Therefore, your script can report the total time connected to the server when the user disconnects by adding a line of code to the event. OPENDIALOG function ------------------- Usage: $opendialog(title|filespecdescription|filespec ...) Displays a COMDLG32.DLL standard file open dialog, which has the title title, and displays files of type filespecdescription and filespec. If filespecdescription and filespec are omitted, all files (*.*) are displayed. Use of this function is best illustrated with a few examples: // Prompts the user for a script and /loads it Load $opendialog(Select a ViRCScript script to load|ViRCScript files (*.vsc)|*.vsc) // Prompts the user to select any file, and assigns its name to $x @ $x = $opendialog(Select any file) // Prompts the user for a .TXT or a .DOC file, and DCC SENDs it to the nick abc123 DCC Send abc123 $opendialog(Select a text file|Text files|*.txt|Word documents|*.doc) If the user presses the Cancel button on the dialog, an empty string is returned, for example: @ $x = $opendialog(blah blah blah) if ([$x] == []) MessageBox You must select a filename!! Halt endif SAVEDIALOG function ------------------- Usage: $opendialog(title|filespecdescription|filespec ...) Very similar to the OPENDIALOG function documented above, except the dialog has a Save button instead of an Open button. In addition, if the file the user selects already exists, they will be prompted whether they wish to overwrite it. If no file is selected, the function returns an empty string. For examples, see the OPENDIALOG function documented above. READLINE function ----------------- Usage: $readline(linenum filename) Returns line number linenum from filename. For example, $readline(1 blah.txt) will return the 1st line from the file blah.txt. If you specify an invalid line number, the function returns an empty string. GETLINESINFILE function ----------------------- Usage: $getlinesinfile(filename) Returns the number of lines in filename. If filename doesn't exist, the function will return -1. GETPATH function ---------------- Usage: $getpath(id) Returns one of the stock ViRC '96 paths (see Client setup/Paths). id can be one of the following: virc - returns the base ViRC '96 directory upload - returns the V96 upload directory download - returns the V96 download directory script - returns the V96 script directory sound - returns the V96 sound directory GETCURRENTDIR function ---------------------- Usage: $getcurrentdir() Returns the current directory on the current drive. The directory name returned by this function ALWAYS ends in a bashslash (\). GETADDRESS function ------------------- Usage: $getaddress(nick) Gets the email (user@host) address of nick. If the address cannot be retrieved for some reason, the function will return unknown@unknown. CURRENTSERVER_ACTIVEWINDOW function ----------------------------------- Usage: $currentserver_activewindow() This horribly-named function is exactly the same as $activewindow(), except for the fact that, if the active window does NOT belong to the current server connection (e.g. if the active window is a channel from a different server to the one that the alias/event was executed in), the function will return . as if the active window was the server notices window for the current server. If you don't understand this, you won't have to use this function. :) ISDCCCHATTING function ---------------------- Usage: $isdccchatting(nick) Returns 1 if a DCC Chat connection is currently open with nick, and 0 if no DCC Chat connection is currently open with nick. ENCODEIP function ----------------- Usage: $encodeip(IP) Encodes IP to unsigned long format. This lets you connect to an IP address and send stuff via a DCC Chat connection, for example, just like telnet. For example, my mail server is 194.217.242.145, so, in a script, you could use the following line to start an SMTP connection with my mail server: CTCP $N DCC CHAT chat $encodeip(194.217.242.145) 25 By faking an incoming DCC Chat connection, this neat little trick lets you do all sorts of things, like, for example, making raw connections to IRC servers etc. without the use of the ObjectViRCScript TSockets class. GETLAG function --------------- Usage: $getlag() Gets the current lag-ness of the active server connection. The lag is returned in tenths of seconds (e.g. 10 means 1 second of lag). If the lag is unknown, this function will return -1. MESSAGEDLG function ------------------- Usage: $messagedlg(type text) Displays a message box on the screen, of type type, which contains text, and returns which button the user pressed. type is calculated by selecting either none or one item from each of the 3 groups, and adding the numbers together. Group 1: 0 Display OK button only. 1 Display OK and Cancel buttons. 2 Display Abort, Retry, and Ignore buttons. 3 Display Yes, No, and Cancel buttons. 4 Display Yes and No buttons. 5 Display Retry and Cancel buttons. Group 2: 16 Display a STOP icon. 32 Display a question mark icon. 48 Display an exclamation mark icon. 64 Display an "i" icon. Group 3: 0 First button is default. 256 Second button is default. 512 Third button is default. For example, if you wanted a message dialog that had Yes and No buttons, displayed a question mark icon, and whose second button (No) was default, you would specify type as 292 (which is 4+32+256). The value returned by this function depends on the button the user pressed: 1 OK button selected. 2 Cancel button selected. 3 Abort button selected. 4 Retry button selected. 5 Ignore button selected. 6 Yes button selected. 7 No button selected. ALIASEXISTS function -------------------- Usage: $aliasexists(name) Returns 1 if the alias name exists, and 0 if it does not. EVENTEXISTS function -------------------- Usage: $eventexists(name) Returns 1 if the event name exists, and 0 if it does not. GETUSER function ---------------- Usage: $getuser() If the -user parameter was specified on V96's command line, this function returns the name of the user. If -user was not specified, this function returns an empty string. OPSTRIP function ---------------- Usage: $opstrip(nick) Strips any trailing @ or + from nick. If, for example, you are using the SELECTEDNICK function to get the currently-selected nick in a channel nicks list, you must use the OPSTRIP function on the nick before performing any operations to make sure that the op (@) and/or voice (+) prefixes are removed. SELECTEDNICK function --------------------- Usage: $selectednick(channel) Returns the nick selected in channel's nicks list. If channel is not a valid channel window, or if no nick is selected in channel's nicks list, this function will return an empty string. The nick returned may be prefixed with op (@) and/or voice (+) flags, which should be stripped off with the OPSTRIP function before the nick can be used with other IRC commands (e.g. MODE, KICK etc.). Set-handling commands and functions =================================== V96 0.82 and above support sets, a very powerful feature similar to Delphi's set capability. ObjectVS set properties are supported (see OBJECTVS.TXT), but sets work well in regular VS without objects too. Basically, a set can contain one or more elements, each which is one word. It's as simple as that. For example, consider this data: Patricia - Female, long dark hair, brown eyes, married Mark - Male, short dark hair, blue eyes, not married Sarah - Female, short red hair, black eyes, not married You could represent this data in VS easily by use of sets: @ $Patricia = [sexFemale,hairLong,hairDark,eyesBrown,msMarried] @ $Mark = [sexMale,hairShort,hairDark,eyesBlue] @ $Sarah = [sexFemale,hairShort,hairRed,eyesBlack] Note that all sets are surrounded by []'s and each set element is separated from the next by a comma. Once $Patricia and $Mark are defined, you can use, for example, the ISINSET function as follows: $IsInSet([sexMale] $Mark) == 1 $IsInSet([sexFemale,eyesBrown] $Patricia) == 1 $IsInSet([sexFemale,hairDark] $Sarah) == 0 If Sarah dyes her hair black and grows it long, the ADDTOSET and REMOVEFROMSET functions can be used: @ $Sarah = $RemoveFromSet($Sarah [hairShort,hairRed]) @ $Sarah = $AddToSet($Sarah [hairLong,hairBlack]) On IRC, of course, you'd hardly ever represent personal information using sets. :) What sets are very useful for is storing user flags, for example: @s $userflags.$nick = [AutoOp,Protected,OnUserlist] Then when a user joins a channel you could use something like this to auto-op them: if ($IsInSet([AutoOp] $userflags.$nick)) Mode +o $nick endif Or a set could be used to hold a list of nicknames for some purpose - the possibilities are practically endless. Anyway. Now I'll document these set functions individually. ISINSET function ---------------- Usage: $IsInSet(set1 set2) Returns 1 if every element in set1 is also in set2, and 0 otherwise. ADDTOSET function ----------------- Usage: $AddToSet(set1 set2) Additionally combines set1 and set2, and returns a new set containing all the elements in both set1 and set2. Note that ADDTOSET also cleans up the set, removing any spaces and duplicate items. Hence it's sometimes useful to use ADDTOSET with set1 or set2 as an empty set [] to clean it up, for example: @ $x = [ blue, BLACK, blAck, green ] @ $y = $AddToSet([] $x) $y will now contain [blue,BLACK,green]. Spaces and duplicate items (BLACK and blAck, set operations are case-insensitive) have been removed. REMOVEFROMSET function ---------------------- Usage: $RemoveFromSet(set1 set2) Returns a new set containing all the items in set1 that are not also in set2. Note that REMOVETOSET also cleans up the set. For more information on cleaning sets, see the note at the bottom of the ADDTOSET function above.