Author Topic: Tutorial 1: The Basics  (Read 19147 times)

DarkStar

  • Full Member
  • ***
  • Posts: 135
  • Scripts for Praise
    • CorpseCorp
Tutorial 1: The Basics
« on: March 25, 2008, 03:41:10 AM »
This is the first of a series of tutorials I am going to write in order to help people new to Icechat get a hang of the VBS (or "IceChat 5") scripting engine. I will only cover the VBS engine, as it is my preferred engine.

Icechat Editor
To open the IceChat Editor, press Ctrl + S. We will be doing most of our work in the Scripts tab, so click that. If the text field is not empty, go to File -> New.

Quick Guide to Saving
These scripts use the Icechat 5 scripting engine and must be saved with a ".ice" extension. The default is ".ics" so when we save the script, be sure to click the "Save as type" drop down box and select "Icechat 5 Script".

In this first tutorial I will cover some basic concepts used in many scripts, including:
  • Comments
  • Procedures
  • Control flow
  • Local variables
  • Global variables
  • SendCommand
  • WriteIniFile
  • GetIniFile
  • GetIdentifier

Now I could just write a bunch of examples showing each, but that's boring for both me and you. So we're going to write a script that will allow us to store notes on a person for a particular server. The script should have procedures for adding notes and removing notes. It should also display the note about the person whenever the person joins a channel. (This should be displayed inside that channel so that if the same person joins multiple channels you are in, it doesn't show it repeatedly in the same window.)      



So first we need to write a procedure to add a note. The procedure should check to see if there is an old note, and if there is, display it. It should then store the note in a file by network name and the person's nickname. Finally it should display a confirmation that the note was added.

Code: [Select]
'1) Declare procedure, give it a name, and assign names to the variables we expect.
Sub AddNote(nickname,note)
  '2) retrieve old note, default it to "" if not found.
  oldnote = getinifile("notes.ini",Network,Nickname,"")
  '3) If there was an old note, show it.
  if len(oldnote) > 0 then SendCommand "/print [NOTES:" & nickname & "] Old note: " & oldnote
  '4) Store the new note
  WriteIniFile "notes.ini",Network,Nickname,note
  SendCommand "/print [NOTES:" & nickname & "] Note added." ' Display that the note was added.
'6) End the procedure.
End Sub

1. Here we define our first procedure. The syntax is "Sub sub_name(Variable1,Variable2...)". The procedure name is alpha-numeric with the exception that it can have a underscore ( _ ) in it, but it must start with a letter. Procedure names (along with variable names) are case-insensitive. Next we declare our Variable names, note that they are comma separated (so if we had two it would be (foo,bar)). Variables are also optional, so if we were to have a procedure which did not have a variable, it would be "Sub MySub()".
NOTE: There are two kind of procedures in VBS. First, procedures proper, which are sandwiched in Sub/End Sub blocks, and functions, which use Function/End Function. The big difference between both is that functions return a value, while subs don't. The syntax is also different.
Example:
Code: [Select]
Sub MySub()
   'Functions are used like variables. You can do anything with them except changing their value, since the value's determined by the function itself. They also NEED to have parentheses around the paramenters.
   If MyFunc(SomeVar,SomeOtherVar) = 3 then
      SomeOtherSub SomeVar, SomeOtherVar 'Meanwhile, procedures need to NOT have parentheses when being used. A good example of the workings of procedures and functions is the WriteIniFile/GetIniFile pair, covered below.
   elseif
      SomeOtherSub "Blah", "BlahBlah"
   End If
End Sub

Function MyFunc(SomeVar,SomeOtherVar) 'Functions work pretty much the same as procedures, except for...
   (Stuff here.)
   MyFunc = SomeVar + 2 ' This. Once the end is reached, it'll check the value of a variable with the same name as the function, and use it to return a value.
End Function

Sub SomeOtherSub(SomeVar,SomeOtherVar)
   (Stuff happens here.) ' Meanwhile, procedures just do stuff.
End Sub

Also note that anything after a single-quote (as long as the single quote is not inside of double-quotes) is considered a comment and not treated as code. Comments run to the end of the line, and can be on the same line as code (after the code) or on a line by itself.

2. Here we call a function and assign its value to a variable ("oldnote"). The GetINIFile function requires four values, as follows: GetINIFile("filename","SectionName","OptionName","Default Value").

Also note that we use a variable that we haven't defined here. "Network" is just one of many pre-defined variables, in this case it contains the name of the currently selected network.

3. If Statements
Conditions are sometimes dificult to explain in words (for me anyways) so I will just show a few examples. Basically it comes down to a true / false test.
  • "4 > 5" = False
  • "5 > 4" = True
  • "not (4 > 5)" = True. "not" makes it the opposite. "not True" = False.
These are known as "conditions".

if condition1 OR condition2 then returns True if condition1 or condition2 evaluates to True, False otherwise.
if condition1 AND condition2 then returns True if both condition1 and condition2 are True, False otherwise.
When you start combining conditions, it's best to group them using parentheses in order to force IceChat to evaluate the conditions in the order you want them to.
NOTE: When testing text strings, it's usually good to wrap the variable with an LCase(), a function that'll turn everything into lowercase. That way, you can check for variations like "foo", "Foo", "FOO", "foO", and even "FoO".
Example: If lcase(Message) = "foo" Then Some_Sub


Code: [Select]
if condition then
  some code
elseif some_other_condition then ' runs if the If fails
  some other code
elseif some_other_condition then ' runs if the If and the first elseif fails
  even_other_code
else ' runs if the if and both elseifs fail
  code
end if ' ends block of statements

A note on end if If you have only one line of code inside of a If-End If block, you can remove the end if and write all of the condition in one line. However, you cannot use elseif or else with this syntax. Example: if condition then some_code()

SendCommand
Syntax: SendCommand "command" or SendCommand "command", ServerNumber
Here we execute a command just like if we had typed it in ourselves. The optional "ServerNumber" attribute can send it to a specific server.

4. Here we write data to a INI file. Syntax: WriteIniFile "filename","Section name","Key name","Value"

5. End Sub - This ends the procedure declaration. For every Sub there must be a End Sub.

Three ways to call procedures
  • Enter "/! sub_name Variable1 | Variable2" in the main text box. Example: "/! AddNote DarkStar | Your tutor"
  • In the script; "AddNote "DarkStar","Your tutor""
  • In the script; "Call AddNote("DarkStar","Your Tutor")"


Now we need to add a procedure to delete notes. It should check if the note exists, if it does, display it one last time and then delete it, if not, say it wasn't found.

Code: [Select]
Sub DeleteNote(Nickname)
  check = getinifile("notes.ini",Network,Nickname,"")
  if len(check)>0 then
    SendCommand "/print -a [NOTES:" & Nickname & "] Note deleted. Content was: " & check
    writeinifile "notes.ini",Network,Nickname,"" '1 Delete note
  else
    SendCommand "/print -a [NOTES:" & nickname & "] Not Found."
  end if
End Sub

1. Only new concept here - when you use writeinifile with an empty value the entry is erased.



Now we need to add an event handler for when someone joins a channel. It should check if they have a note stored, if they do it should print the note into that channel.

Code: [Select]
Sub ONJOIN(Nickname,Host,Channel,ServerNumber)' This is a predefined event handler which Icechat will call when the event happens. More can be found in Script Events -> IceChat 5 Style.
note = getinifile("notes.ini",Getidentifier("$network",servernumber),Nickname,"") '1
if len(note) > 0 then SendCommand "/print " & channel & " [NOTES:" & nickname & "] " & note, ServerNumber '2
End Sub

1. In this line we use a new function, "GetIdentifier". Syntax: GetIdentifier("$identifier",ServerNumber). The second variable, "ServerNumber" is optional, and should not be passed when retriving global identifiers (although it can be). If you are retrieving information about a certain server (as we are in this case) you should pass along the servernumber. If you don't, it will assume you mean the CurrentServerNumber, which changes based on what window your looking at.

2. Here we use the SendCommand, and because we want the message to go to a certain place, we include the ServerNumber.


Here is the complete script. Don't forget to save it with a .ice extension.

Code: [Select]
Sub AddNote(nickname,note) '1 Declare procedure, give it a name, and assign names to the variables we expect.
  oldnote = getinifile("notes.ini",Network,Nickname,"") '2 retrieve old note, default it to "" if not found.
  if len(oldnote) > 0 then SendCommand "/print [NOTES:" & nickname & "] Old note: " & oldnote '3 If there was an old note, show it.
  WriteIniFile "notes.ini",Network,Nickname,note '4 Store the new note
  SendCommand "/print [NOTES:" & nickname & "] Note added." ' Display that the note was added.
End Sub '5 End the procedure.

Sub DeleteNote(Nickname)
  check = getinifile("notes.ini",Network,Nickname,"")
  if len(check)>0 then
    SendCommand "/print -a [NOTES:" & Nickname & "] Note deleted. Content was: " & check
    writeinifile "notes.ini",Network,Nickname,"" '1 Delete note
  else
    SendCommand "/print -a [NOTES:" & nickname & "] Not Found."
  end if
End Sub

Sub ONJOIN(Nickname,Host,Channel,ServerNumber)' This is a predefined event handler which Icechat will call when the event happens.
note = getinifile("notes.ini",Getidentifier("$network",servernumber),Nickname,"") '1
if len(note) > 0 then SendCommand "/print " & channel & " [NOTES:" & nickname & "] " & note, ServerNumber '2
End Sub

Now we have a complete script, test it to your hearts content. But Adding and Deleteing entries is too dificult, in my opinion. I would much rather type "/addnote DarkStar Your Tutor" over "/! AddNote DarkStar | Your tutor", so why not?

What we are going to do is add two aliases. /addnote and /delnote. We want to retrieve the first word after the command, and call it the nickname, then the rest of the words will be the note. So we get the first word by using $1. The rest by using $2-. So, Click the "Alias" tab. Aliases are in the form of: /alias /command

Code: [Select]
/addnote /! AddNote $1 | $2-
/delnote /! DeleteNote $1

There, all finished. You've made your first script.



Thats it for this tutorial. If you find something that's missing, a mistake, or something that needs better clarification please post it so I can improve on this tutorial.

Grammer fixed by Kyte
« Last Edit: March 25, 2008, 04:45:27 PM by DarkStar »
This message brought to you by the Wonderful Wizard of Oz.