Project

General

Profile

Actions

Scripting » History » Revision 163

« Previous | Revision 163/246 (diff) | Next »
Per Amundsen, 08/14/2012 12:15 PM


Notice: this is info for 1.8.10 and higher.

Scripting

Scripting BETA Click here to see scripting in the latest beta versions.

You can write full scripts in Commands -> Edit Scripts or you can create one liners in Commands -> Edit Commands

Custom Commands:

Custom Commands are created in Commands -> Edit Commands

Custom commands consists of differents ways to execute a script either by making your own command, or use a hotkey, you can also enter a full script as a one liner (for legacy reasons)

Alias

/hello /msg $channel hello everybody

This creates a alias named "/hello", everytime you type "/hello" the script "/msg $channel hello everybody" will be executed, you can use any script features here.

Hot keys

Ctrl&r /msg $channel hello everybody i pressed 'ctrl' and 'r'

Every time you press ctrl + r, the script "/msg $channel hello everybody i pressed 'ctrl' and 'r'" will be executed, you can use any script features her.

You can comment out a command by putting a # in front of it.

It is also possible to use a full script, but it has to be on one line, and the script editor is preferred.

Scripts:

Events:
There are different ways to listen to the irc client/server events for legacy reasons.
On/OnEvent will be executed after the event
OnBefore/OnBeforeEvent will be executed before the event

OnEvent if ($event == PRIVMSG) { /EXECUTE }
OnBeforeEvent if ($event == PRIVMSG) { /EXECUTE }

On PRIVMSG { /EXECUTE }
OnBefore PRIVMSG { /EXECUTE }

OnBefore OnCommand { /EXECUTE }
OnCommand /mode { /EXECUTE }

Available events:

SockOpen / Called when a script opens a socket
SockRead / Called when a socket have data to read
SockOpen / Called when a script socket is closed

OnLoad / Called when the script is loaded
OnUnload / Called when the script is unloaded
OnReload / Called when the script is reloaded
OnConnecting / Called when a server is connecting
OnLookingUp / Called when a server is looking up the hostname
OnConnected / Called when a server is connected
OnDisconnect / Called when a server gets disconnected
OnCommand / Called whenever a user types a /slash command in the client ($0- will hold the full command, $0 will be the first word, $1 the second and so on)

OnCTCPRequest / Called when a user recives a CTCP request
OnCTCPReply / Called when a user recives a CTCP reply
OnDCCRequest / Called when a user recived a DCC request

OnNickChanged / Called when a user's nick changes, will only trigger on the user unlike NICK who triggers for everyone
OnSongChanged / Called when a song is changed in the selected media player

OnDeVoice / Called when a user gets devoiced
OnVoice / Called when a user gets voiced
OnDeHop / Called when a user gets dehalfoppeed
OnHop / Called when a user gets halfopped
OnOp / Called when a user gets opped
OnDeOp / Called when a user gets deopped
OnDeOwner/ Called when a user gets owner deopped
OnOwner/ Called when a user gets owner opped
OnDeSop / Called when a user gets special deopped
OnSop / Called when a user gets special opped

MODE / Called whenever a channel or user mode is changed
JOIN / Called whenever a user joins a channel
PART / Called when a user parts a channel 
NICK / Called when a user changes their nick
TOPIC / Called when a topic is set/changed
KICK / Called when any user gets kicked
NOTICE / Called when any notice is recived
QUIT / Called when a user quits irc
PRIVMSG / Called when any message is recived
WHOIS / Called when any whois reply is recived
LIST / Called when a user gets a /list
KILL / Called when a user gets killed
ACTION / Called when a user recives a ACTION (/me) message

<irc numeric> / Called when a raw irc line with <irc numeric> is recived
<irc textual> / Called when a raw irc line with <irc textual> is recived

if/else if/else blocks:

You can use any combination of if, else if, else and while

OnEvent if ($event == PRIVMSG) { 
    if (%test == null) { 
        /echo Hello world
        if (%test == null) { 
            /echo Hello world
        }
        else /echo Hello World
    } else if (%test == null) { 
        /echo Hello world
    } else (%test == null) { 
        /echo Hello world 
    } 

    if (%test == null) { 
        /echo Hello world
        while (%test == null) {
            /echo Hello world
        }
    }

    if(%test == null)/echo Hello World
    else if(%test == null)/echo Hello World
    else/echo Hello world

    if(%test == null){/echo Hello World
    }else if(%test == null){/echo Hello World
    }else{/echo Hello World
    }

    if(%test == null){/echo Hello World}else if(%test == null){/echo Hello World}else{/echo Hello World}
}

while blocks:

On JOIN {
    var %t = 0
    /echo There are ($user($chan, 0)) users in ($chan)

    while (%t < $user($chan, 0)) {
        %t++
        var %nick = $user($chan, %t)
        /echo User (%t) is (%nick) and is $iif(%nick isop $chan, opped, not opped)
    }
}

goto/label:

OnCommand /goto {
    var %loop = 0 
    if ($1 == 1) {
        goto 1
    } else if ($1 == 2) {
        goto 2
    } else if ($1 == loop) {
        :3
        /echo you typed loop
        %loop++
        if (%loop < 5) {
            goto 3
        }
        return
    } else {
        goto 4
    }

    :1
    /echo You typed 1
    return
    :2
    /echo You typed 2
    return
    :4
    /echo The end
    return
}

client variables:
All client variables starts with $

$event / current event, e.g PRIVMSG 001 MODE and so forth
$channel / the channel the event occurred on, if any
$msg / the message to the channel/user or the message in a raw irc line e.g whois [kr0n] is a registered nick
$nick / the nick the event was sent from, can be a irc.server.com, a nick or null
$me / my current nick
$network / the network the event occured on e.g Quakenet
$ident / the from user ident if any
$host / the from user hostname if any
$myident / my ident
$myhost / my host
$server / host from the server e.g irc.server.com
$now / returns unixtime/ctime from current time.
$active / returns the current window Status/#channel/Nick.
$activeserver / returns an id for current server
$status / returns current server status
$crlf / returns newline \r\n
$0-$9 / will return parts of the $msg, $<number>- will combine parts of the $msg from 0 to <number>. $0- will return everything
$! / returns how many $0 $1 etc variables are filled (not sure if final name of it)
$raw0-$raw9 / will return parts of the raw message, $raw<number>- will combine parts of the raw message from 0 to <number>. $raw0- will return everything
$r! / returns how many $raw0 $raw1 etc variables are filled (not sure if final name of it)
$+ / use to combine variables output e.g "$now $+ $server" 

All sysinfo/mediaplayer variables are available as well.

user set variables:
All user set variables starts with %

var %variable = 4242, %variable2 = 4343; will create local variables that gets deleted when the script is done.
using += instead of = will append to the variable, if both variable and new value is numbers it will combine them to a new number %variable += 4242.

If a variable is created without var, the variable will be available to all scripts, saved to a file and restored when AdiIRC is started.

Commands for manipulating variables:

/set {-u seconds/-d] [%var] [value] / create or update a variable with value -u seconds, will delete the variable after X seconds, -d will decrease its value by 1 every second, then remove it

/unset [var] / deletes a variable

/inc {-u seconds/-d] [%var] [value] / increases a variable with value (only if value and var is ints) -u seconds, will delete the variable after X seconds, -d will decrease its value by 1 every second, then remove it

/dec {-u seconds/-d] [%var] [value] / decreases a variable with value (only if value and var is ints) -u seconds, will delete the variable after X seconds, -d will decrease its value by 1 every second, then remove it

/vars shows a list of all variables and their values

functions:
Several functions are exsists, they are all recursive and you can use any %variable or $variable as parameters:
They are also usable inside if () else if () while () statements.
All variable numbers are floats and all functions supports floats for precise calculations.

$replace(text, text2, text3) / replace all occurrences of text2 in text with text3
$upper(text) / return text uppercase
$lower(text) return text lowercase
$mid(text, startpos, endpos) / return part of text from startpos to endpos
$substr(text, startpos, endpos) / return part of text from startpos to endpos
$left(text, pos) / return pos characters starting from left of the text
$right(text, pos) / return pos characters starting from right of the text
$remove(text, text2) / replace all occurrences of text2 from text
$len(text) / return length of text
$count(text, text2) / counts all occurrences of text2 in text
$pos(text, text2) / returns first occurrences position of text2 in text
$lastpos(text, text2) / returns last occurrences position of text2 in text
$strip(text) / removes all color and font tags
$repeat(text, times) / repeats text X times
$insert(text, text2, pos) / inserts text2 into pos of text
$chr(num) / returns ascii character from the number num
$char(num) / returns ascii character from the number num

$calc(formula) / calculate any variation of +-*/
$formatdate(date, text) / formats a unix timestamp into date using date variables %d %m %y etc
$fdate(date, text) / formats a unix timestamp into date using date variables %d %m %y etc
$ctime(datestamp) / converts most variations of a date stamp to unix/ctime
$datediff(ctime1, ctime2) / diffs two unix/ctime and fills the $datematch array with values
$datematch(num) / returns part of a $datediff, 0 = milliseconds, 1 = seconds, 2 = minutes, 3 = hours, 4 = days
$host(nick) / returns the hostmask of nick
$ident(nick) / returns the ident of nick
$(number) / dynamically gets a $0 $1 $2 variable e.g $(1) is same as $1 (not sure if final function name)
$cond(cond, execute1, execute2) / checks if cond is true then executes execute1, else executes execute2, will return string if not at the begining of the line
$iif(cond, execute1, execute2) / checks if cond is true then executes execute1, else executes execute2, will return string if not at the begining of the line
$round(num, decimals) / rounds down a float to X decimals
$regex(text, pattern) / does a regular expression test if text matches pattern, then returns the matched part
$regmatch(num) / returns the captured group at pos num from a $regex. 0 returns group count
$regreplace(text, pattern, text2) / replace any occurence in text of patterh with text2 where pattern is a regular expression

$file(path) / reads file to end and returns the entire output without newlines
$fileloop(path) / reads through a file one line at the time, line increases +1 every time the same file is called
$floop(path) / reads through a file one line at the time, line increases +1 every time the same file is called
$filerandom(path) / returns a random line from a file
$frand(path) / returns a random line from a file
$fread(name) / reads a line from current pos in file named name
$fileread(name) / reads a line from current pos in file named name
$freadc(name) / reads a char/byte from current pos in file named name
$freadchar(name) / reads a char/byte from current pos in file named name
$fsize(file) / returns size off file in bytes
$filesize(file) / returns size off file in bytes
$fpos(name) / returns current position/byte in file named name
$filepos(name) / returns current position/byte in file named name
$flines(file) / returns amount of lines in file
$filelines(file) / returns amount of lines in file
$fileexists(file) / returns if file exists or not
$isfile(file) / returns if file exists or not

$chan(num) / if num is 0 returns how many channels you are joined on this server else returns channel name in position num
$user(#chan, num) / if num is 0 returns how many users are on this #chan else returns nick in position num
$nick(#chan, num) / if num is 0 returns how many users are on this #chan else returns nick in position num
$server(num) / if num is 0 returns how many servers you are connected to else returns server id in position num

$sread(name) / reads available bytes from socket named name (on sockread)
$sockread(name) / reads available bytes from socket named name (on sockread)
$sbytes(name) / returns amount of available bytes to be read from socket named name
$sockbytes(name) / returns amount of available bytes to be read from socket named name

operators:

All operators can use ! to reverse the logic e.g !ison.
If no operators are added it will test if remaining text is not null if (%test), if ($channel) or if (!$channel) etc.

== / Will check if left and right string or int is the same
> / Will try and cast left and right variable to int and try "int1 greater than int2" 
< / Will try and cast left and right variable to int and try "int1 lower than int2" 
>= / Will try and cast left and right variable to int and try "int1 greater than or equal to int2" 
<= / Will try and cast left and right variable to int and try "int1 lower than or equal to int2" 
isbetween / Will try and cast left variable to int and right variable have to be int-int, e.g "40 isbetween 30-50" 
ison / check if ($nick ison $channel) nick is the channel
isop / check if ($nick isop $channel) is operator on the channel
ishop / check if ($nick ishop $channel) is half operator on the channel
issop / check if ($nick issop $channel) is special operator on the channel
isowner / check if ($nick isowner $channel) is channel owner
hasvoice / check if ($nick hasvoice $channel) have voice on the channel
inchan / check if i am in chan (#channel inchan) (#channel !inchan)
isnum / check something is a number (5 isnum) (5 !isnum)
ismatch / will check if left contains right value or right contains left value
isin / same as ismatch except only checking if left value is in right value, ismatch checks both

tips:
/ is not needed to execute a command in scripts e.g /echo and echo is the same.
use null to check for nothing "if ($nick == null)"
Comment out a line with # or several lines with /* code */
All paths needs to be escaped e.g c:\\users\\kr0n\\file.txt if only a filename is entered, the script directory will be used.
All characters that needs to be escaped before used as strings are \ { } ;
In some cases you might have to escape ( ) | , # $ %
; as a newline "/echo 1; /echo 2" is the same as
/echo 1
/echo 2

"halt" will halt the script immediately, telling the client to eat the event and ignoring the rest of the script.
"return" will halt immediately, ignoring rest of the script, but not eat anything.

Example scripts

Simple kickcounter script:

OnBefore OnCommand { 
    if ($0 != /kick)  return

    if (%kickcount == null) %kickcount = 0

    %kickcount++

    if ($2 == null) { 
        /kick $channel $1 Kick number %kickcount
        halt
    } 
}

Kickban example

OnCommand /kb {
    if (!$1) {
        /echo /kb - Nick missing
        return
    }

    var %msg = $iif($channel, $2-, $3-)
    var %chan = $iif($channel, $channel, $2)

    # Set this for default ban reason, or remove for no default reason
    # Can be shortened to %msg = $iif(%msg, %msg, GTFO)
    if (%msg == null) %msg = GTFO

    if ($me isop %chan) {
        /raw MODE %chan +b *!$ident($1)@$host($1)
        /raw KICK %chan $1 %msg
    } 
    else /echo You are not oper on %chan
}

Simple calculator script:

OnCommand /calc {
    if (!$1) {
        /echo /calc - Parameters missing
        return
    }

    # typing /calc -p <expression> sends output to channel
    if ($1 == -p) {
        /msg $channel Calculating : $2-
        /msg $channel Result is : $calc($2-)
    } else {
        /echo Calculating : $1-
        /echo Result is : $calc($1-)
    }
}

Colored version

OnCommand /calc {
    if (!$1) {
        /echo /calc - Parameters missing
        return
    }

    # typing /calc -p <expression> sends output to channel
    if ($1 == -p) {
        /msg $channel $chr(3)4Calculating : $2-
        /msg $channel $chr(3)4Result is : $calc($2-)
    } else {
        /echo $chr(3)4Calculating : 4$1-
        /echo $chr(3)4Result is : $calc($1-)
    }
}*/

CTCP flood detection example

On OnCTCPRequest {
    if (%count == null) /set -u 10 %count 1
    else /inc -u 10 %count 1

    if (%count > 4) /ignore  -u 30 -t $nick!$ident@$host
}

Mass mode example

OnCommand /mass {
    if (!$2) {
        /echo /mass - Parameters missing [+/-<mode> <nick> <nick> <nick>]
        return
    }

    %len = 2

    # equal to while (%len <= $count(%0-, $chr(32)))
    while (%len <= $!) {
        if ($(%len) ison $channel) /mode $channel $1 $(%len)
        /inc %len
    }
}

Shows info about servers, channels and users

On JOIN {
    var %s = $server(0), %c = 0, %u = 0, %t = 0, %c2 = 0;

    while (%t < %s) {
        %t++
        /setserver $server(%t);
        %c += $chan(0)

        %c2 = 0
        while (%c2 < $chan(0)) {
            %c2++
            %u += $user($chan(%c2), 0)
        }
    }

    /echo You are on (%s) servers, (%c) channels with (%u) users
}

It is possible to use scripts as functions.
These functions are fully nested like the client functions.

Lets say you make a /mycalc like this.

OnCommand /mycalc {
    return $calc($0+$1);
}

Then you can call this function with eiter /mycalc <number> <number> the normal way or $mycalc(<number, <number>)
Typing /testcalc will show the result.

OnCommand /testcalc {
    /echo $0 + $1 is $mycalc($0, $1);
    /echo 5 + 4 is $mycalc(5, 4);
}

Simple convert temperature C to F or F to C
/temp C 20 will print 68 F

OnCommand /temp {
    if ($1 == C) /echo $calc(($2 * 9/5) + 32) F
    else if ($1 == F) /echo $round($calc(($2 - 32) * 5/9), 1) C
    else /echo Temp missing
}

Test if input contains a link

OnCommand /testlink {
    if (!$1) {
        /echo Link missing
        return
    }

    /echo $iif($regex($1, (?i)\\b((?:[a-z][\\w-]+:(?:/\{1\,3\}|[a-z0-9%])|www\\d\{0\,3\}[.]|[a-z0-9.\\-]+[.][a-z]\{2\,4\}/)(?:[^\\s()<>]+|\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\))+(?:\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\)|[^\\s`!()\\[\\]\\\{\\\}\\\;:'".\,<>?«»“â€â€˜â€™]))), yes, no)
}

Retrives plot summary from captured imbd links

On PRIVMSG {
    var %reg = $regex($0-, http://www\\.imdb\\.com(/title/[a-z0-9]+/))
    if (!%reg) { return }

    /sockclose imdb
    %text = null
    %imdb = $regmatch(1)plotsummary
    %imdbchan = $channel
    /sockopen imdb www.imdb.com 80
}

On SockOpen {
    if ($1 != imdb) { return }

    /sockwrite -n imdb GET %imdb HTTP/1.1
    /sockwrite -n imdb Host: www.imdb.com
    /sockwrite -n imdb User-Agent: Mozilla/5.0 (Windows NT 6.1\; WOW64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.24 Safari/536.5
    /sockwrite -n imdb Referer: http://www.imdb.com
    /sockwrite -n imdb Accept: text/xml,application/xml,application/xhtml+xml,text/html\;q=0.9,text/plain\;q=0.8,video/x-mng,image/png,image/jpeg,image/gif\;q=0.2,text/css,*\/*\;q=0.1
    /sockwrite -n imdb Accept-Language: en-us, en\;q=0.50
    /sockwrite -n imdb Connection: Close$crlf
}

On SockRead {
    if ($1 != imdb) { return }

    %text += $sockread(imdb)
}

On SockClose {
    if ($1 != imdb) { return }

    if ($regex(%text, <p class="plotpar">([\\s\\S]*?)<i>)) {
        /msg %imdbchan $regmatch(1)
    }

    %text = null
}

An example showing the difference between dates

OnCommand /test {
    $datediff($ctime(1/1 2042), $now)

    var %text = Difference is
    %text += $chr(32)$datematch(4) $iif($datematch(4) == 1, day, days)
    %text += $chr(32)$datematch(3) $iif($datematch(3) == 1, hour, hours) 
    %text += $chr(32)$datematch(2) $iif($datematch(3) == 1, minut, minutes) 

    /echo %text
}

Announce song changes in a channel or to a user

On OnSongChanged { 
    /nmsg <network> <channel/Nick> $0-
}

Announce to several channels with:

On OnSongChanged { 
    /nmsg <network> <channel1/Nick>,<channel2/Nick> $0-
    /nmsg <network2> <channel3/Nick> $0- 
}

Updated by Per Amundsen over 12 years ago · 163 revisions

Also available in: PDF HTML TXT