ViRCScript Documentation for Visual IRC
ViRCScript Documentation for Visual IRC
Introduction
============
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).
Note that this list also includes the stuff new in 0.80, 0.82 and 0.82a.
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 <OnNewInactiveText> 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 (<OnDCCChatConnect>, <OnDCCChatText>,
<OnDCCChatDisconnect>). 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 [Link]).
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 ALIASEXISTS and EVENTEXISTS functions. 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.92: Rewritten script loading code - large scripts now load in 5
seconds, rather than 5 minutes. Added new STRPOSFROM function. New
EVALUATEWINDOW command for debugging. New STRTOKL and STRTOKR functions. RMFILE
(added ages ago) finally documented. New RSTRPOS, RSTRTOKL and RSTRTOKR
functions. New NOATTRIBS command. EVAL command can now be called as a function.
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:
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
@. V96 0.91 and above support local array variables, too. Simple 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.
Bear in mind speed considerations when using the different types of variables.
Local variables (e.g. @l $x = 0) are the fastest. Global variables (e.g.
@ $x = 0) are almost, but not quite, as fast as local variables. Local array
variables (e.g. @l $x.0 = 0) and global array variables (e.g. @ $x.0 = 0) are
much slower, so don't use them heavily in tight loops! (that said, they're not
_that_ slow ... even a slow PC should have no problem executing several
thousand complex array operations every second).
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)
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.
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:
To display this:
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:
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, almost ... the new parser takes care of it in a different, and rather
more complex way, than the old one ... but it should work properly every time.
In V96 0.91 and later, VS supports variables within variables. This is achieved
with the new $'$var' syntax. It's best demonstrated as follows:
@ $blah = hello
@ $foo = blah
This will print hello on the screen. $'$foo' basically means "the value of the
variable whose name is the value of $foo". So $'$foo' means the value of
the variable whose name is $blah, which is hello.
ViRCScript Statements
=====================
TEXTOUT statement
-----------------
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.
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
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:
TextOut ecKICK This text will appear in the same colour as channel
kicks do.
For example:
New in 0.80, with ObjectViRCScript, you can also specify the handle of a
TRichEdit object you have created (see [Link]) 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 $[Link] = 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 $[Link] = 20
@p $[Link] = 20
@p $[Link] = 300
@p $[Link] = 300
@p $[Link] = 1
IF/ELSE/ENDIF statements
------------------------
Usage: if (condition)
...
[else]
[...]
endif
Op | Meaning
------+--------------------------
== | Equal to (case-insensitive)
=== | Equal to (same as == only case-sensitive when comparing strings)
!= | Not equal to (case-insensitive)
!== | Not equal to (case-sensitive)
> | Greater than
< | Less than
>= | Greater than or equal to
<= | Less than or equal to
&& | Boolean AND
|| | Boolean OR
! | Boolean NOT
+ | Plus
- | Minus
* | Multiply
/ | Divide
% | Modulus (remainder after division)
^^ | Power
& | Bitwise AND
| | Bitwise OR
^ | Bitwise XOR
if (2+3 == 5)
TextOut clBlue Of course it does!!
endif
if ([hello] == [goodbye])
TextOut clBlue Not unless the laws of physics have changed.
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:
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
WHILE/ENDWHILE statements
-------------------------
while (1)
endwhile
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:
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
---------------------
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:
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
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 (;;)
...
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:
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
-------------------------
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:
<no value>
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
---------------
Removes one or more aliases. For example, this removes the 3 aliases OP, DEOP
and J.
UnAlias OP DEOP J
SETALIAS command
----------------
This is a very powerful command which you will use very seldomly, if at all.
It creates an alias with the ViRCScript code set to text. You can separate
multiple lines of code in text with $char(13). Examples:
Together with the GETALIAS function, SETALIAS can be used to append ViRCScript
code to existing aliases. For an example of this usage, see the GETALIAS
function.
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:
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@[Link]
$1 NOTICE
$2 MeGALiTH
$3 :You're
$4 not
$5 opped!!
$nick greygoon
$user bhess
$host [Link]
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:
Channel messages:
A typical private message received from the server may look like this:
Note that the <default> 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:
* 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:
Events that begin with < (with the exception of <default>) are NEVER fired by
events from the server, even if the masks match. You can thus create your own
<On_xxx> events which you can fire manually from code with the FIREEVENT
command.
Built-in events
---------------
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
<OnXXXX_text>. For example, if you wanted several <OnStart> events, you could
define them as <OnStart_1>, <OnStart_2> 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 <OnStart_XYZScript> or <OnDCCGetConnect_XYZScript> if you're writing
a script called XYZScript.
Event names in <>'s (e.g. <OnXYZ>) will never be fired by text received from
the server, even if the masks match. If they're not built-in events, like
<OnStart>, you will have to call them manually with the FIREEVENT command.
UNEVENT command
---------------
Removes one or more events. For example, this removes the 2 events JOIN and
PART:
DISABLEEVENT command
--------------------
ENABLEEVENT command
-------------------
PARSE/ENDPARSE statements
-------------------------
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
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 [Link] which contains questions and answers
in the form:
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([Link])
Parse $x
@ $answer = $0
@ $question = $1-
EndParse
In addition, 0.91 and above support the new EXTENDED keyword. If this keyword
is specified, multiple words surrounded by quotes will be parsed as one
parameter. Example:
0: "one
1: two"
2: "three
3: four"
0: "one two"
1: "three four"
2:
3:
The EXTENDED keyword is very useful when you're parsing strings that might
contain multiple filenames, each enclosed in quotes (the filenames may contain
spaces on Win32 systems, remember). For example, the following code snippet
will display each filename in XDCC pack #1 on a separate line:
MENUTREE/ENDMENUTREE command
----------------------------
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:
Each item defined between MenuTree and EndMenuTree takes the following format:
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 <none> 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:
For menu types MT_CHANNELTEXT and MT_CHANNELNICKS, State can take the following
values:
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 [Link]:
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
----------------------------
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:
To define the ViRCScript code to actually make this open a new server window,
you would use:
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
--------------
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
------------------
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
------------------
APPENDTEXT command
------------------
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
-------------
CHDIR command
-------------
RMDIR command
-------------
SETINPUTLINE command
--------------------
Sets the the contents of window's command entry box to text. window can be .
(a period) for the server notices window, a channel name for a channel window,
a nick for a query window, or =nick for a DCC Chat window.
EVAL command/function
---------------------
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 can also be called as a function, in which case text is evaluated, and
the evaluated text is returned, rather than being executed, as with the EVAL
command. Hence, the above line could be rewritten as:
@ $x = $eval($randomread([Link]))
BREAK command
-------------
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.
CONTINUE command
----------------
Only used within FOR and WHILE blocks, CONTINUE causes the next iteration of
the loop to begin immediately, without finishing the current iteration.
HALT command
------------
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 <default> event should be executed to
display the WHO on the screen in the normal way. The event would be defined
like this:
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
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
SETFOCUS command
----------------
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
-----------
Minimizes window. window can be . to set the focus to the server notices
window, a channel name, or a nick (query window).
MAX command
-----------
Maximizes window. window can be . to set the focus to the server notices
window, a channel name, or a nick (query window).
RESTORE command
---------------
Restores window. window can be . to set the focus to the server notices window,
a channel name, or a nick (query window).
CLOSE command
-------------
Closes window. window can be . to set the focus to the server notices window,
a channel name, or a nick (query window).
DDE command
-----------
SAY command
-----------
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
[Link]) to make V96 reload everything from the registry.
SIMULATESERVERDATA command
--------------------------
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:
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@[Link]. There
is no way to differentiate between real and simulated server events in your
scripts.
FIREEVENT command
-----------------
Fires event with parameters. This can either be used to pretend that an event
was fired by ViRC '96, for example:
FireEvent <OnConnect>
Or, you can define your own custom events, for example <OnOpNick>, which you
could then fire manually, say, in your MODE event:
FireEvent <OnConnect*
This would fire all events whose names begin with the string <OnConnect.
WRITEREGISTRY command
---------------------
Assigns value to key in the registry under the section "section", located under
the ViRC '96 key (e.g. having a section of "YyzScript" would write to
HKEY_CURRENT_USER\Software\MeGALiTH Software\Visual IRC 96\YyzScript. If key
doesn't exist, it will be created. If key already contains a value, it will
be overwritten by the new value you're setting. You cannot write outside the
ViRC '96 key in the registry. This is a conscious design decision to ensure
maximum security (a buggy or malicious script could go around trashing
system-required registry entries otherwise).
EVALUATEWINDOW command
----------------------
Usage: EvaluateWindow
ASAY command
------------
AME command
-----------
RMFILE command
--------------
Erases file.
NOATTRIBS command
-----------------
Executes command as normal, but surpresses attribute (\b, \u, \i and \t)
parsing. For example, the following statement will not work as desired (try
it):
This is because V96's parser will pick up the \u and \t in your "filename" and
will translate them to the underline and tab formatting codes. The solution is
to prefix the command with NoAttribs, which surpresses parsing of formatting
codes:
This will work as desired (try this too if you don't understand this fully).
IRC commands
------------
Regular IRC commands may be used in VS (of course ;), only the slash prefix is
optional and should be left out, and the code looks neater without it. In
addition, the command can be prefixed with ^, * or ^*.
A prefix of ^ surpresses the output of any text that the command directly
causes. For example, V96 contains code in its built-in MSG command to display
the message you're sending on the screen. ^MSG will send the message, but
surpress the text output.
The following code will change the text displayed when the user uses the /msg
command to something a little more fancy, demonstrating how to override a
built-in command:
Alias MSG
TextOut ecPRIVMSG [*>\b$1\b<*]\t$2-
^*Msg $1-
EndAlias
ViRCScript Functions
====================
$? 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".
In 0.91 and above, you may specify some text that appears in the input section
of the box by placing |text in prompt. For example, the following line of code
will prompt you for a channel name with #virc already in the input field of the
box:
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.
To extract the actual message sent to the channel correctly, you would use
$strtrim($3-). This function will also remove the \A character from the
beginning of CTCPs.
DECODEPINGINTERVAL function
---------------------------
Usage: $decodepinginterval(integer)
DECODEINTERVAL function
-----------------------
Usage: $decodeinterval(integer)
$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)
$upper(blah) = BLAH
LOWER function
--------------
Usage: $lower(text)
$lower(BLAH) = blah
STRPOS function
---------------
Finds the first occurrence of 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)
RANDOMREAD function
-------------------
Usage: $randomread(file)
Returns a randomly-selected line from file. This is useful for quote or slap
scripts.
ISON function
-------------
Returns true (1) if nick is on channel, otherwise returns false (0). Example:
if $ison(MeGALiTH #quake)
Msg MeGALiTH Hi there!!
endif
ISOP function
-------------
WILDMATCH function
------------------
$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
------------------
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@[Link] *!*megalith@*[Link]) =
1
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)
NICKS function
--------------
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
------------
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
--------------
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)
$substr(abcdef 2 3) = bcd
GETINPUTLINE function
---------------------
Usage: $getinputline(window)
Gets the current contents of the command entry box in window. window can be .
(a period) for the server notices window, a channel name for a channel window,
a nick for a query window, or =nick for a DCC Chat window.
LENGTH function
---------------
Usage: $length(text)
$length(hello) = 5
CHANNELCOUNT function
---------------------
Usage: $channelcount()
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
-------------------
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, [Link], 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)
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)
Note that if A/P or AM/PM are specified, the time is given in 12-hour format,
otherwise, it is given in 24-hour format.
For example:
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()
@ $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()
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:
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)
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 <OnDisconnect> 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 <OnDisconnect>
event.
OPENDIALOG function
-------------------
Displays a [Link] 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 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:
SAVEDIALOG function
-------------------
READLINE function
-----------------
Returns line number linenum from filename. For example, $readline(1 [Link])
will return the 1st line from the file [Link]. If you specify an invalid
line number, the function returns an empty string.
GETLINESINFILE function
-----------------------
Usage: $getlinesinfile(filename)
GETPATH function
----------------
Usage: $getpath(id)
Returns one of the stock ViRC '96 paths (see Client setup/Paths). id can be one
of the following:
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)
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 [Link], so, in a script, you could use the
following line to start an SMTP connection with my mail server:
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
-------------------
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:
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:
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)
EVENTEXISTS function
--------------------
Usage: $eventexists(name)
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.).
WORDCOUNT function
------------------
Usage: $wordcount(text)
$wordcount() = 0
$wordcount(abc) = 1
$wordcount(a b c) = 3
This is very useful if you wish to find out the number of parameters passed to
an alias, for example. You would use something like:
@l $paramcount = $wordcount($1-)
GETALIAS function
-----------------
Usage: $getalias(alias)
Returns the ViRCScript code of alias. Together with the SETALIAS command, the
GETALIAS function can be used to append lines of code to existing aliases.
Example:
This will add the command BEEP (preceded by a $char(13) - the new line
character) to the end of the DEOP alias.
ISWATCHDOGACTIVE function
-------------------------
Usage: $iswatchdogactive()
Returns 1 if the watchdog is currently enabled (and hence the main V96 window
is hidden), and 0 if the watchdog is currently disabled (the normal state -
the main V96 window is visible).
READREGISTRY function
---------------------
Returns the value of key from the registry section "section", located under
the ViRC '96 key (e.g. having a section of "YyzScript" would write to
HKEY_CURRENT_USER\Software\MeGALiTH Software\Visual IRC 96\YyzScript. If you
wish, you may also specify a default value which is returned if the registry
value you're trying to read doesn't exist. You cannot read outside the ViRC '96
key in the registry. This is a conscious design decision to ensure maximum
security (a malicious script cannot read private parts of your registry and
send them over IRC).
GETXDCCPACKCOUNT function
-------------------------
Usage: $getxdccpackcount()
Returns the number of XDCC packs defined in Client setup/XDCC. If no packs are
defined, this function will return 0.
GETXDCCPACKSIZE function
------------------------
Usage: $getxdccpacksize(pack)
Returns the total size of all the files defined in XDCC pack number pack. pack
ranges from 1 to the value returned by the GETXDCCPACKCOUNT function. If you
specify an invalid pack number, this function will return 0.
GETXDCCPACKGETS function
------------------------
Usage: $getxdccpackgets(pack)
Returns the number of times XDCC pack number pack has been downloaded. pack
ranges from 1 to the value returned by the GETXDCCPACKCOUNT function. If you
specify an invalid pack number, this function will return 0.
GETXDCCPACKDESC function
------------------------
Usage: $getxdccpackdesc(pack)
Returns the pack description for XDCC pack number pack. pack ranges from 1 to
the value returned by the GETXDCCPACKCOUNT function. If you specify an invalid
pack number, this function will return an empty string.
GETXDCCPACKFILES function
-------------------------
Usage: $getxdccpackfiles(pack)
Returns a list of files in XDCC pack number pack. Quotes (") are placed around
each filename, and the filenames (which include a full path) are separated by
spaces. pack ranges from 1 to the value returned by the GETXDCCPACKCOUNT
function. If you specify an invalid pack number, this function will return an
empty string. The PARSE EXTENDED statement can then be used to separate the
file names.
GETXDCCPACKFILECOUNT function
-----------------------------
Usage: $getxdccpackfilecount(pack)
Returns the number of files in XDCC pack number pack. pack ranges from 1 to the
value returned by the GETXDCCPACKCOUNT function. If you specify an invalid pack
number, this function will return 0.
GETWINDOWID function
--------------------
Usage: $getwindowid(window)
Returns a window ID for window. The window ID is the number in []'s in the
window's title bar. For example, $getwindowid(.) would return 2 if the
current server connection's server window was "[2] Server notices".
UNIXTIME function
-----------------
Usage: $unixtime(unixtime)
$unixtime(unixtime format)
DECODEIP function
-----------------
Usage: $decodeip(encodedip)
Converts encodedip (an unsigned long) into an IP address in a.b.c.d format. You
can use this function to convert encoded IP addresses (for example, in DCC
requests received from users) to user-readable format. Example:
$decodeip(2660773201) = [Link]
GETFILESIZE function
--------------------
Usage: $getfilesize(filename)
GETFILEDATETIME function
------------------------
Usage: $getfiledatetime(filename)
$getfiledatetime(filename format)
Returns filename's date and/or time. If format is not specified, the filename's
date and time will be returned in the same format as the TIME function returns
system times. You may also specify format to format the date and time
information in any way you wish. See the TIME function for information on
format strings.
PATHEXISTS function
-------------------
Usage: $pathexists(path)
ISEVENTENABLED function
-----------------------
Usage: $iseventenabled(event)
STRPOSFROM function
-------------------
Starting from the character at position (where 1 is the first character in the
string) and onwards, finds needle within haystack, and returns the character
position of needle. 0 is returned if needle is not found in haystack. For
example:
$strposfrom(5 cd abcdefcdg) = 7
$strposfrom(4 blah hahahahha) = 0
STRTOKL function
----------------
Searches for token within text, and returns everything to the left of the first
occurrence of token. If token can't be found, returns text unchanged.
STRTOKR function
----------------
Searches for token within text, and returns everything to the right of the
first occurrence of token. If token can't be found, returns an empty string.
RSTRPOS function
----------------
The reverse of STRPOS. Finds the last occurrence of needle within haystack, and
returns the character position of needle. 0 is returned if needle is not found
in haystack. For example:
$rstrpos(x abxcdxba) = 6
$rstrpos(dx abxcdxba) = 5
$rstrpos(blah hahahahha) = 0
RSTRTOKL function
-----------------
The reverse of STRTOKL. Searches for token within text, and returns everything
to the left of the last occurrence of token. If token can't be found, returns
text unchanged.
RSTRTOKR function
-----------------
The reverse of STRTOKR. Searches for token within text, and returns everything
to the right of the last occurrence of token. If token can't be found, returns
an empty string.
$rstrtokr(. [Link]) = uk
$rstrtokr(q abc123xyz) =
DNS function
------------
Usage: $dns(hostname)
$dns([Link]) = [Link]
V96 0.82 and above support sets, a very powerful feature similar to Delphi's
set capability. ObjectVS set properties are supported (see [Link]), 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 = [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:
On IRC, of course, you'd hardly ever represent personal information using sets.
:) What sets are very useful for is for 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.
ISINSET function
----------------
ADDTOSET function
-----------------
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:
$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.