Project

General

Profile

Scripting » History » Revision 156

Revision 155 (Per Amundsen, 08/14/2012 11:51 AM) → Revision 156/246 (Per Amundsen, 08/14/2012 11:52 AM)

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. 
 <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> 
 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:* 
 <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) 
 </pre> 
 *user set variables:* 
 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> 

 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 now possible to use scripts custom commands as functions. 
 These functions custom commands/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> 
 </pre>