Project

General

Profile

Scripting » History » Revision 163

Revision 162 (Per Amundsen, 08/14/2012 12:13 PM) → Revision 163/246 (Per Amundsen, 08/14/2012 12:15 PM)

h1. Notice: this is info for 1.8.10 and higher. 

 h1. 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 

 h1. 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* 
 <pre> 
 /hello /msg $channel hello everybody 
 </pre> 

 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* 
 <pre> 
 Ctrl&r /msg $channel hello everybody i pressed 'ctrl' and 'r' 
 </pre> 

 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. 

 h1. 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 

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

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

 OnBefore OnCommand { /EXECUTE } 
 OnCommand /mode { /EXECUTE } 
 </pre> 

 *Available events:* 
 <pre> 
 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 
 </pre> 

 *if/else if/else blocks:* 

 You can use any combination of if, else if, else and while 
 <pre> 
 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} 
 } 
 </pre> 

 *while blocks:* 
 <pre> 
 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) 
	 } 
 } 
 </pre> 

 *goto/label:* 

 <pre> 
 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 
 } 
 </pre> 

 *client variables:* 
 All client variables starts with $ 

 <pre> 
 $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" 
 </pre> 

 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: 
 <pre> 
 /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 
 </pre> 

 *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. 

 <pre> 
 $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 
 </pre> 

 *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. 

 <pre> 
 == / 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 
 </pre> 

 *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. 

 h1. Example scripts 

 Simple kickcounter script: 

 <pre> 
 OnBefore OnCommand {  
	 if ($0 != /kick)    return 
		
	 if (%kickcount == null) %kickcount = 0 

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

 Kickban example 
 <pre> 
 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 
 } 
 </pre> 

 Simple calculator script: 
 <pre> 
 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-) 
	 } 
 } 
 </pre> 

 Colored version 
 <pre> 
 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-) 
	 } 
 }*/ 
 </pre> 

 CTCP flood detection example 

 <pre> 
 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 
 } 
 </pre> 

 Mass mode example 

 <pre> 
 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 
	 } 
 } 
 </pre> 

 Shows info about servers, channels and users 
 <pre> 
 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 
 } 
 </pre> 

 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. 
 <pre> 
 OnCommand /mycalc { 
	 return $calc($0+$1); 
 } 
 </pre> 

 Then you can call this function with eiter /mycalc <number> <number> the normal way or $mycalc(<number, <number>) 
 Typing /testcalc will show the result. 
 <pre> 
 OnCommand /testcalc { 
	 /echo $0 + $1 is $mycalc($0, $1); 
	 /echo 5 + 4 is $mycalc(5, 4); 
 } 
 </pre> 

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

 <pre> 
 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 
 } 
 </pre> 

 Test if input contains a link 
 <pre> 
 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) 
 } 

 </pre> 

 Retrives plot summary from captured imbd links 
 <pre> 
 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 
 } 
 </pre> 

 An example showing the difference between dates 
 <pre> 
 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 
 } 
 </pre> 

 Announce song changes in a channel or to a user 
 <pre> 
 On OnSongChanged {  
	 /nmsg <network> <channel/Nick> $0- 
 } 
 </pre> 

 Announce to several channels with: 
 <pre> 
 On OnSongChanged {  
	 /nmsg <network> <channel1/Nick>,<channel2/Nick> $0- 
	 /nmsg <network2> <channel3/Nick> $0-  
 } 
 </pre>