Scripts


Here we come to the powerful TurboIRC Scripting Language . This file explains the syntax and all the things you would like to know about scripts

TurboIRC Interpreter processes your script line by line . That means that commands are line-separated .

TurboIRC scripts funcion only to the relative server window . While there are some commands that allow you to handle other server windows , your script basically deals with the relative server window .

To see some ready for you scripts , see Script Examples .

The lines are processed with some ways , depending on what line it is . See the execution method below to see how TurboIRC interprets lines . Each line can start with :

TurboIRC uses "Default Variables" to short some things . See Default Variables below .

When a TurboIRC script is fired with an alias while in a DCC Chat Session , only the "Direct Output" style commands are executed .

 

Directives

A directive is a command to the interpreter . This command has no output , but it changes the way that the interpreter handles the script . Currently , the following directives are supported :

#debug . When you use #debug , all script lines will be shown to the relative server window . This helps you find why a script is not functional .

#nodebug : Removes #debug

#lock : This has effect only in scripts fired by Events . It causes the event to be locked . See Events for more about locking events .

#unlock : Removes #lock

#defaultlock : Returns the default locking value as used by the Event Editor .

#define : This is almost the same with the /define default alias , but all definitions made by #define are destroyed once the script terminates .

#yield : This is the default . After a script line is processed , TurboIRC looks for window and IRC messages waiting to be processed before the next line . This ensures that your script will not "stuck" TurboIRC . The maximum number of messages to be checked is set by More Options . Setting e.g. a value of 5 , orders TurboIRC to process 5 messages before continuing with the script . If the message queue has more than 5 messages , only the first 5 are processed . If the queue has less than 5, TurboIRC will not wait for another message to be placed in the queue ; it will continue with script execution .

The yield value is better to be set from 1 to 3 , not greater .

#noyield : This disables the yielding mechanism set by #yield . If you disable yelding , TurboIRC will do nothing else during the script execution . Watch out !! This might halt TurboIRC !

There is a possibility that you want to use #noyield . With the yielding mechanism , one script might be started before another one is finished . You can use #noyield to ensure that the script will terminate first . For example , if you create a script for the WHOIS reply , it is safe to set #noyield , because the server will send all 31? replies immediately one after the other .

#watch <variable> : This will print in the screen the variable you requested and its current value .

#sleep <#msecs> : This allows you to suspend script execution for # milliseconds . For example , #sleep 2000 will execute next line after 2000 msecs = 2 seconds . This command is useful if you don't want to flood the server with script execution .

WARNING : #sleep allows you to work with TurboIRC while the script is executed in the background . You have the ability to fire other scripts while the first script waits . For example , consumer the following TEMPBAN alias

  1. if (strncmp("$2","*",1) == 0)
  2. goto BanRelease
  3. endif
  4.  
  5. string ID = ""
  6. string Dom = ""
  7. string Msk = ""
  8.  
  9. if (FindStringPos("$2","!")==-1)
  10. // this is a user
  11. ID = GetUserIdent("$2")
  12. Dom = GetUserDomain("$2")
  13. Msk = sprintf("%s!%s@%s","$2",ID,Dom)
  14. else
  15. ID = "--found--"
  16. Msk = "$2"
  17. endif
  18.  
  19. if (ID=="")
  20. /mode $1 +b $2!*@*
  21. /kick $1 $2 $3*
  22. /firescript ATEMPBAN 60000 $0 $1 *$2 $3
  23. else
  24. /mode $1 +b %DefaultBanFromMask("%Msk%")%
  25. /kick $1 %NickFromMask("%Msk%")% $3*
  26. /firescript ATEMPBAN 60000 $0 $1 *%Msk% $3
  27. endif
  28.  
  29. return
  30.  
  31. :BanRelease
  32.  
  33. // release the ban
  34. string SB = "$2" + 1
  35. if (FindStringPos("$2","!")==-1)
  36. /mode $1 -b %SB%
  37. else
  38. /mode $1 -b %DefaultBanFromMask("%SB%")%
  39. endif

This alias enables you to set manually a timer with /firescript to remove a temporary ban . The syntax is /tempban <channel> <nicktoban> . With #sleep , the following is possible

  1. /mode $1 +b $2!*@*
  2. /kick $1 $2 $3*
  3. #sleep 20000
  4. /mode $1 -b $2!*@*

This script won't halt your other things ; You can even fire another scripts . After 20 seconds the script will be continued without affecting your other possible running scripts .

WARNING : There is a limited number of "nested scripts" you may fire with this #sleep . Please do not fire more than 2 - 3 scripts , otherwise you will get memory errors , even crashes .

TurboIRC has an internal variable checking , that stops execution of a script if the stack is overflown . Therefore , if you e.g. create a ONJOIN event and you receive too many joins from the server , if you have a big yielding value ( e.g. 3 ) , the onjoin script may not be fired fom all the nicks joined , to prevent a crash . If you have #noyield the script , the script will have no problem in firing , but it will stuck TurboIRC until it is finished .

Generally you should use /timer or /firescript to run timer-based commands .

 

 

Aliases in Scripts

You can direct fire any of your available aliases , or even default aliases . When the line starts with "/" , it will be handled as you had passed the line in the server input window .

 

Comments

Any line that has "//" in the start is ignored . You can place comments with "//" to help others find out what your script does .

 

Labels

Lines that start with : , are ignored . When you issue a goto command , TurboIRC continues script execution from the label mentioned by the goto command .

 

Direct Output

This type of line is intended to be used only in alias scripts . It causes the rest of the line ( without the "\" prefix ) to be passed to the window you used the alias . For example , firing an alias with that script :

\Hello There

will pass the "Hello There" in the window that you fired the script . This type of line is the only one that will be executed from a DCC Chat Window .

Note that strings containing control characters like \r or \x are not expanded within direct output .

Direct output also happens when the line does not contain any function/variable name and it is not beginning with / .

Variable Creation

TurboIRC enables you to create variables . Variables are places that you can store data , to play with later . TurboIRC recognizes 2 types of variables :

In addtion , TurboIRC has 2 variable-power definitions :

Each Variable name must be up to 15 characters in length , containing only letters , numbers and underscores . If you not follow these rules , a script error occurs ( see Errors below )

Variable names are case-sensitive !

To create a dynamic integer , use this syntax :

int <NameOfInteger>

for example : int MyInt

You may initialize the integer at creation time : int MyInt = 4 , or with a function ( see functions below )

The same apply to strings : string <NameOfString> . For example : string MyStr = "hello there"

To Use the variable in a line starting with / or \ , you must put in in %'s . For example

  1. string MyStr = "Hello there !"
  2. /display #MyChannel %MyStr%

This will diplay Hello there ! in #MyChannel

If your variable is not in a line starting with / or \ , you need not to place it in %'s

 

Let's see this example :

  1. string Active = GetCurrentWindowName()
  2. /display %Active% HEYYYY

The function GetCurrentWindowName() is discussed in functions . It returns a string of the currently window active . The /display command then displays some text to that window . When the script finishes , the Active variable is removed from the memory . Let's see the example with a static variable

  1. staticstring Active = GetCurrentWindowName()
  2. /display %Active% HEYYYY

Now assume that this is an alias script you fire from a channel "#hello" . The first time you fire the script , Active will be "#hello" , and the /display will act on the channel #hello .

Assume now that you want to fire the script from another channel "#ripper" . When you fire this script again , the message will be displayed in #hello , and not in #ripper . What is the problem ? The static variable Active has already been initialized once , and it has the old value "#hello" . You forgot to destroy the static variable . Place another line so the script looks like that :

  1. staticstring Active = GetCurrentWindowName()
  2. /display %Active% HEYYYY
  3. /destroystaticvariable Active

To change the value of a variable , you do an assigment , as follows :

variablename = newvalue , or %variablename% = newvalue

For example .. to edit the Active variable we created , we use :

Active = "new string"

If it is an integer variable , you can use calculations .

MyInt = 3*5

Assuming you want e.g. to add 5 to the current value . You would use :

MyInt = MyInt + 5

You can easier do : MyInt += 5 , as C++ support .

TurboIRC supports the following operations in integers :

  1. +
  2. -
  3. *
  4. /
  5. & ( logical AND )
  6. | ( logical OR )
  7. ^ ( logical XOR )
  8. ~ ( logical NOT )
  9. % ( MOD - division remain )

You may directly use shortcurs ... for example MyInt /= 4 .

Divisions that return floating numbers are converted to integers .

Default Variables

Default variables are existing reserved variables that have their values preassigned once the script starts : These are :

 

 

Execution Method

This is how TurboIRC works on each script line

Calling Functions

Functions are used to provide information , and optionally to store it into variables . Function may accept parameters , and may return also parameters . For example . the GetCurrentWindowName() we used takes no parameters and returns a string . When you do not have to provide a parameter , you must still use the () empty parentheses . When you need to pass a parameter , you may pass a direct value , like 1 or "test" , a variable , or even another function that returns a variable . For example , the function FindStringPos searches in a string for another string and returns an integer , as the position that the string was found . If it is not found , it returns -1 . Lets check a simple call

  1. int Z = FindStringPos("hey there","lol")

This assigns -1 to Z because "hey there" does not contain "lol"

  1. string V = GetCurrentWindowName()
  2. int Z = FindStringPos(V,"lol")

This time FindStringPos checks for a "lol" in the current window name . You may use this also :

  1. int Z = FindStringPos(GetCurrentWindowName(),"lol")

Any functions that return strings , they return them in "" 's . If you want to use a function in a line that starts with / or \ , be sure first to call the function inside %'s , for example

And second ,remember that the function will return the string without "" 's , if used in a line starting with / or \ .

A complete list of functions supported is here. All function names are case-sensitive !

String Expressions

As we saw , there are string and integer expressions . You may however modify these exressions as follows :

For example , You may give a direct string , like "hi there"

This string may be contained in a variable , e.g. MyString

You may want to get not all the string , but only a part of it . For example , to get only the "there" from "hi there" , you would use MyString + 3 . This returns MyString from the 4th character and after

For example , to create a string that contains only one character of the "Hi there" , you need to do :

string NewString = strcat(MyString,1) . This will create NewString to hold "H" . If you wanted , for example , to copy the second characted , you 'd use strcat(MyString + 1,1) .

You can even use a variable , instead of an 1 , or a direct integer .

Format characters in strings :

You use the C++ escape character \ , to include special characters in your strings

To insert a character that you don't know the excactly HEX value , use the KEY.EXE , included with the TurboIRC package

WARNING : Be sure to remember to use \\ if you want to use a single \ character , otherwise you will get errors !

WARNING : Format characters are not expanded with commands starting with / or \ . When you use e.g. /target #chan +Mf\x41 , you will get Mf\x41 and not MfA .

The strings are expanded when they are printed in screen , only the \xXX . So the /addtext ! \x41L will print AL , but \rL will print \rL

 

 

Integer Expressions

Integer expressions can be direct integer values , like 1 , variables that hold integers , and also calculations . Go to the "Variable Creation" above to check the available calculations . You can , for example , use this expression

int I = 5 + 4 - 3 . This makes I = 6

Please DO NOT USE parentheses . TurboIRC will execute the calculations with the form you were used . For example , the previous example takes 5 , adds 4 and subtracts 3 . This expression :

5 * 100 / 4 +33 , will take 5 , multiply * 100 , then divide / 4 , and then add 33 .

 

TurboIRC Commands

Commands especially for scripts are :

IF allows you to check two variables and proceed or not depending of the result . The syntax of IF is :

Expression1 and 2 must be both integers , or both strings . These may be direct values , variables , or functions that return a variable . ? can be == , != , >= , <= , > or < .

TurboIRC allows you to only test once . It is not supporting extensions of if that are supported in C++ , for example if (something == someelse && here == there) . Only ONE test .

For example

  1. if (Var=="test")
  2. if (FindStringPos(GetCurrentWindowName(),"#")==-1)
  3. if (MyInt>=YourInt)

after a successfull IF command , if the tested expression is true , the execution continues until an ELSE is found , then all other commands are ignored until and ENDIF found . By contrast , if the tested condition is false , all commands until ELSE are ignored and after the ELSE , all commands are executed . Be sure to include the ENDIF to terminate the IF session

TurboIRC will NOT allow you to use nested if commands ... you should terminate an IF session with ENDIF and then attempt to use another IF command .

Example : The following script checks if the current channel is global or local ( global channels are prefixed with # , local with & )

  1. string V = GetCurrentWindowName()
  2. if (FindStringPos(V,"#")!=-1)
  3. /display %V% This is a global channel
  4. else
  5. /display %V% This is a local channel
  6. endif

The following script does the same , but accepts the first parameter as the channel to be checked

  1. if (FindStringPos("$1","#")!=-1)
  2. /display %V% This is a global channel
  3. else
  4. /display %V% This is a local channel
  5. endif

As you can see , I used "$1" and not $1 , because $n variables are always replaced as they are .

The goto coninues execution from another line , marked as label . Look an example :

  1. if (FindStringPos(GetClientMode(),"x")==-1)
  2. goto NotIRCX
  3. else
  4. goto IRCX
  5. endif
  6. :NotIRCX
  7. /addtext $server ***You are NOT in IRCX mode
  8. return
  9. :IRCX
  10. /addtext $server ***You are in IRCX mode !
  11. return

First line checks if our client mode ( check functions for GetClientMode() ) contains "x" . If not , goto transfer us to NotIRCX . If yes , we go to IRCX . Then the /addtext adds some text to the server window , indicating our mode . In line 8 I used the return command , to cause the script to be terminated . If I didn't , after the first /addtext , the script would resume to lines 9 , 10 ,and 11 .

Goto instruction releases all if or for sessions , so , don't go to a label that has else , endif , endfor etc after that !!

 

FOR Loops

For command , enables you to start loops . That is , instead of writing the same script for more than one e.g. variables , you can easily create a for loop

Syntax : for ( initial expression ; test expression ; loop expression )

Initial Expression is a single command to be executed only once , when the for command is processed for the first time

Test Expression is an expression to be tested every time the program goes to the for loop , except from the first time

Loop Expression is a command to be executed each time the FOR loop reloads .

As with IF , TurboIRC will not allow you to nest FOR commands , however , youcan use an IF command inside a FOR loop .

 

For example . Assume you want to send a message to all nicks in your channel . Without the for loop , you should get the number of nicks using GetNickCount() , then issue e.g. a /msg command for each one like this script

  1. int Z = GetNickCount("#Chat")
  2. int P = 0
  3. string N = ""
  4.  
  5. :ReLoad
  6.  
  7. if (P == Z)
  8. return
  9. endif
  10.  
  11. N = GetNick("#Chat",P)
  12. /display #Chat Hello there %N% !!
  13. P += 1
  14. goto ReLoad

The same script with FOR looks like that :

  1. string Sph = ""
  2.  
  3. for (int Z = 0 ; Z < GetNickCount("#Chat") ; Z += 1)
  4.  
  5. Sph = GetNick("#Chat",Z)
  6. /display #Chat Welcome %Sph% !
  7.  
  8. endfor
  9.  
  10. return

The first time TurboIRC sees FOR command , it executes only the int Z = 0 statement , to create the variable . The it proceeds with the two other commands . When the endfor is reached , TurboIRC returns to the for line , increases the Z += 1 , and checks if Z < GetNickCount("#Chat") . If Z is less than GetNickCount , the execution continues , otherwise the execution continues from the line next to endfor ( i.e. the loop terminates )

for command ,enables you to leave an entry blank , even all of them . For example , the above script can be used also as follows

  1. string Sph = ""
  2. int Z = 0
  3. for ( ; Z < GetNickCount("#Chat") ; )
  4.  
  5. Sph = GetNick("#Chat",Z)
  6. /display #Chat Welcome %Sph% !
  7. Z += 1
  8.  
  9. endfor
  10.  
  11. return

This manually increases the Z in line 7 , and also the Z variable is created before for loop begins . The result is the same .

You can use the break statement to exit immediately from a loop , no matter if the tested condition in the for statement is true or false

You can use the continue statement to bypass some commands in special situations . For example , the above script will send a message to all nicks in the channel , including yours . To avoid that , use this :

  1. string Sph = ""
  2.  
  3. for (int Z = 0 ; Z < GetNickCount("#Chat") ; Z += 1)
  4.  
  5. Sph = GetNick("#Chat",Z)
  6.  
  7. if (Sph == $mynick)
  8. continue;
  9. endif
  10.  
  11. /display #Chat Welcome %Sph% !
  12.  
  13. endfor
  14.  
  15. return

This time , when the if in line 6 matches the Sph with our nick , the /display is not executed ; The continue statement forces the loop to continue from endfor , and then re-continue from the for statement . If you used break instead of continue here , when TurboIRC finds your nick in the list , it will exit from the loop and it won't send the /display for any other nick your nick list might have .

You can use also goto to go outside of the loop , but remember that goto resets all if and for sessions . Don't use it to go to a label that is inside in the for loop .

Remember that variable creation is global to a script . Therefore , you should NOT create variables within a loop , because the next time the line is processed you will get an error of "Attempt to create an existing variable" . The same applies to goto command .

 

Timer Scripts

Some times you may need to fire some script from another . You can use then the /firescript or /timer Default alias. If you use it with timer = 0 , the script will be fired immediately and all of your dynamic variables will be destroyed , and the static variables may alter their values or destroyed as well . Be sure what the new script does . If you use the /firescript with a timer , ensure that you will give the script time to be executed AFTER the current script has terminated . If the new script strarts executing while the other script is still active , weird things may occur .

Using the static variables , you can force a script to act with different ways . Check that alias script:

  1. staticint V = 0
  2. V += 1
  3. /addtext $server ***You have used this script for %V% times !
  4. if (V==100)
  5. /destroystaticvariable V
  6. endif
  7. return

This script increases the variable V each time . When the V reaches 100 , it is destroyed .

 

Script Errors

  1. "Variable Name must have only letters ,numbers or underscores"
  2. "Variable Name length must be up to 15 characters"
  3. "Invalid Redirection"
  4. "Variable Name is already defined"
  5. "Cannot create more than 50 variables of that type"
  6. "Integer Required"
  7. "String Required"
  8. "Unindentified Function"
  9. "Incorrect IF/FOR syntax"
  10. "Incorrect Expression"
  11. "Type Mismatch"
  12. "No nested IF's allowed"
  13. "Misplaced ELSE"
  14. "Misplaced ENDIF"
  15. "Variable Not Found !"
  16. "Assignment operation cannot be used in strings"
  17. "Invalid # directive"
  18. "Too much dynamic definitions"
  19. "Misplaced ENDFOR/BREAK/CONTINUE"

1 -> Please create a variable with only letters/digits and the underscore ( _ )

2-> Please create variables up to 15 characters in name length

3-> Invalid redirection is an invalid syntax with " , or % inside a line , in a variable assignment .

4-> You attempted to recreate an already-existing variable

5-> You can create up to 50 integers and up to 50 strings .

6-> You placed a string and the function requires an integer

7-> You placed an int and the function requires a string

8-> You call a not-existant function . If you get this error when you attempt to send direct output to the screen , place a \ before the line .

9-> Check the syntax of your IF / FOR statements , usually a single = instead of the correct ==

10 -> Invalid expression .

11 -> Your expression returns a string when an integer is expected , or vice versa

12 -> You tried to use an IF before an older ENDIF

13 -> Misplaced ELSE

14-> Misplaced ENDIF

15-> You referenced a variable that is not existing

16-> Do not use += or -= shortcurs in string variables

17 -> Use only correct #directives

18-> You have exceeded the range of dynamic definitions with #define

19-> Misplaced ENDFOR,BREAK,CONTINUE