# # modeparse.irc # version 1.0 # by blue-elf (belf@null.net) # 21 June 2005 # ############################## About ################################################ # # This addon adds certain events for the general scripter. # jIRCii has only one ON MODE event. Therefore, when a mode change happens in a channel, # scripters have to "parse" or break down the modes set, who set them. # For example, if you see this: # # *** dude sets mode -o+b somenick *!*@*.banned.hostmask.com # # There will be ON DEOP and ON BAN that will be triggered. # # This addon also shows how you can use fireEvent() in your scripts. # ############################## Events and scalar variables ########################## # # For op, deop, voice, devoice, help, dehelp, ban, and unban, the scalar variables are as follows: # # $nick = the nick who did the opping # $opnick = the person who got opped # $chan = the channel where it happened # $fulladdress = the full address of $nick # $address = the user@host address of $nick # $wildsite = the *!*user@host address of $nick # $event = returns the name of the event 'op' # # For ban and unban events, there are additional scalars: # # $banmask = the address that got banned # $bnick = the part of the full nick!user@host format. # this means that if the banmask is *!*@*.aol.com, $bnick will have a value of '*' # if the banmask is *bleah*!*@*, $bnick will have a value of *bleah* # # There are two "weird" mode events: # multi_ban # multi_op/multi_deop # # For multi_ban event, there is NO $banmask, but you will get @banmasks that contains # all the banned addresses. (Note that there is NO multi_unban event) # # For multi_op/multi_deop, there is NO $opnick, but there is a @opnicks that contains # all the nicks who got opped or deopped. # # EXTREMELY IMPORTANT!!! # # For the following events: # on multi_op { } # on multi_deop { } # on multi_ban { } # # They are only triggered when the modes set match the following: # +oo # +bb # -oo # # There can be more o's or b's set, but the minimum is 2, and there are NO OTHER MODES in that line. # If someone sets a +oo-b, you will have to use the separate op/ban/unban events. # # on multi_op { # this will not trigger if the actual mode set was +oov # this will not trigger if the actual mode set was +oo-oo # } # # on voice { # this will trigger if the mode set was +bvo # } # # on op { # this will also trigger if the mode was +bvo # } # # on multi_ban { # this will trigger if the mode was set to +bbb # but will NOT trigger if the mode was set to +bbb-b # } # # on ban { # this will also trigger if the mode was set to +bbb # } # ########################## SAMPLE EVENTS ############################################ # # on multi_ban # { # $lf = chr(10); # $myaddress = "$me $+ !" . getAddress($me); # foreach $var (@banmasks) # { # if ($var iswm $myaddress) # { # echo($chan, "*** It seems that $nick has banned your address!"); # sendRaw("MODE $chan -ob+b $nick $var $wildsite $+ $lf $+ KICK $chan $nick :Don't ban me!"); # } # } # } # # on op # { # foreach $var (keys(%localData)) { echo("$[16]var = " . %localData[$var]); } # } # on ban # { # echo($chan, ">>> $nick has banned $banmask in $chan"); # } # on deop # { # echo($chan, ">>> $nick has deopped $opnick in $chan"); # } # on unban # { # echo($chan, ">>> $nick has unbanned $banmask in $chan"); # } # on voice # { # echo($chan, ">>> $nick has voiced $opnick in $chan"); # } # on devoice # { # echo($chan, ">>> $nick has devoiced $banmask in $chan"); # } # on multi_op # { # foreach $var (keys(%localData)) { echo("$[16]var = " . %localData[$var]); } # } # on multi_deop # { # foreach $var (keys(%localData)) { echo("$[16]var = " . %localData[$var]); } # } # on multi_ban # { # foreach $var (keys(%localData)) { echo("$[16]var = " . %localData[$var]); } # } # ########################################################################################## # Damn, the "documentation" is longer than the actual code.. on mode { if ($me ison $target) { modeparse($target, $parms, $source); } } # modeparse("#channel", "+-bovklstpnm targets", "source") # $source = the op who set the mode sub modeparse { local('$tmp_addr $tmp_event'); $tmp_addr = "$3 $+ !" . getAddress($3); # Multi-modes. local('$mmode @tmp @mtarg'); @tmp = split(' ', $2); @mtarg = subarray(@tmp, 1, size(@tmp)); $mmode = @tmp[0]; if ($mmode ismatch '^\+(b{2,})$') { fireEvent('multi_ban', hash($nick => $3, $chan => $1, $event => 'multi_ban', @banmasks => @mtarg, $fulladdress => $tmp_addr, $address => getAddress($3), $wildsite => mask($tmp_addr, 2))); } if ($mmode ismatch '^(\+|\-)(o{2,})$') { $tmp_event = 'multi_' . iff(matched()[0] eq '+', 'op', 'deop'); fireEvent($tmp_event, hash($nick => $3, $event => $tmp_event, $chan => $1, @opnicks => @mtarg, $fulladdress => $tmp_addr, $address => getAddress($3), $wildsite => mask($tmp_addr, 2))); } # Single-modes local('$i $_modes $_pre $_targets $_string $_pos $_tmp $modesWithTargets $tmpvar %tmp_hash'); $_pos = 0; $_string = tokenize($2," "); $_modes = getToken($_string, 0); $_targets = getTokenFrom($_string, 1); local('$umodes $cmodes'); $umodes = getSupportHints()["PREFIX"]; $cmodes = getSupportHints()["CHANMODES"]; if ($umodes eq '') { $umodes = 'ovh'; } else { $umodes = matches($umodes, '^\((\S+)\).*$')[0]; } if ($cmodes eq '') { $cmodes = 'bkl'; } else { $cmodes = replace(getTokenRange(tokenize($cmodes, ','), 0, 3), '\,', ''); } $modesWithTargets = $umodes . $cmodes; for ($i = 0; $i < strlen($_modes); $i++) { $_chr = charAt($_modes, $i); if ($_chr isin "\+\-") { $_pre = $_chr; } else if ($_chr isin $modesWithTargets) { $_tmp = $_pre . $_chr; $tmpvar = getToken(tokenize($_targets), $_pos); %tmp_hash = hash($chan => $1, $event => match_mode_event($_tmp); $nick => $3, $opnick => $tmpvar, $fulladdress => $tmp_addr, $wildsite => mask($tmp_addr, 2), $address => getAddress($3)); if ($_chr eq 'o') { if ('.' isin $3 && $_tmp eq '+o') { fireEvent('serverop', hash($event => 'serverop', $chan => $1, $nick => $3, $opnick => $tmpvar)); } else { fireEvent(iff($_pre eq '+', 'op', 'deop'), %tmp_hash); } } if ($_chr eq 'v') { fireEvent(iff($_pre eq '+', 'voice', 'devoice'), %tmp_hash); } if ($_chr eq 'h') { fireEvent(iff($_pre eq '+', 'help', 'dehelp'), %tmp_hash); } if ($_chr eq 'b') { $tmp_event = iff($_pre eq '+', 'ban', 'unban'); fireEvent($tmp_event, hash($chan => $1, $event => $tmp_event, $nick => $3, $banmask => $tmpvar, $bnick => split('!', $tmpvar)[0], $fulladress => $tmp_addr, $wildsite => mask($tmp_addr, 2), $address => getAddress($3))); } $_pos++; } } return; } sub match_mode_event { local('$e'); if ('o' isin $1) { $e = 'op'; } if ('v' isin $1) { $e = 'voice'; } if ('h' isin $1) { $e = 'help'; } return iff('-*' iswm $1, "de $+ $e", $e); } # EOF