You are doing a mass mode change for the selected nicks. Therefore, you can use $snicks to get a comma-delimited list of nicks to operate on. Here's one strategy:
- Check to ensure that:
a. $active is a channel
b. you are opped in the active channel
c. $1 is either a + or a -
d. $2 is either o, v or h
e. you have nicks selected to operate on.
f. the length of $snicks is less than 900, to prevent /set: line too long error messages.
Complain if there is a problem with an appropriate error message and halt the script. - Save $snicks in a local variable and replace the commas with spaces so you can modify its contents with $deltok(%snicks, 1-4, 32) as you work through the list, creating your list of $modespl nicks.
- Create a local variable to use to build the MODE commands you'll be sending.
- Create a local variable to hold the range 1-$modespl ... $+(1-,$modespl) ... to use as the second parameter of a $gettok() on %snicks (and the subsequent $deltok() to remove the first 1-$modespl nicks from %snicks).
- Create a local variable to hold the +|-mode string so you don't have to keep evaluating identifiers to use the identical string repetitively. Use $modespl to return the number of MODES Per Line allowed on that network, for use in the $str() .. $str($2, $modespl) ... then combine that with $1 (the + or -) with $+() ... $+($1, $str($2, $modespl)) ... to create your +oooo.
- Now all you have to do is loop through %snicks to create each of the MODE commands. You do not need a loop index because you will simply be using moding the first 1-$modespl nicks, then removing them from the list and repeating until the list is fully processed (deleted). That means you can use ($gettok(%snicks, %range, 44)) as your loop condition and then $replace the commas in $ifmatch with spaces.
One way to dramatically speed up the alias and possibly even prevent flooding off is to build the mode strings and add them all together until their length exceeds 400 (approaches 500). Then send the mode string and start rebuilding it. In order to do that, you will need to save the results of $ifmatch so you don't lose them when you check to see if %ModeString already exists, and thus needs the $crlf separator between the commands. When you finally exit the loop, you check to see if there are any left over mode strings that need to be sent (that weren't sent because the length of the mode strings didn't exceed 400) and send the remaining string.
Since I have described the algorithm fairly clearly, I have only labelled the major sections below to match the above description.
alias modes {
; 1. Input error checking
;
if $active !ischan {
echo $color(ctcp) -ait * /MODES CHANNEL ERROR: $&
You are not in a channel window.
halt
}
elseif $me !isop $active {
echo $color(ctcp) -ait * /MODES OP ERROR: $&
You are not opped in $active $+ .
halt
}
elseif !$istok(-:+,$1,58) {
echo $color(ctcp) -ait * /MODES USAGE ERROR: $&
The first parameter must be either + or - only. No other characters are allowed.
halt
}
elseif !$istok(o:h:v,$2,58) {
echo $color(ctcp) -ait * /MODES USAGE ERROR: $&
The second parameter must be a channel mode to apply to all of these nicks and must be one of: o, h or v.
halt
}
elseif !$snicks {
echo $color(ctcp) -ait * /MODES NICK SELECTION ERROR: $&
You have not selected any nicks in $active $+ .
halt
}
elseif $len($snicks) > 900 {
echo $color(ctcp) -ait * /MODES NICK SELECTION ERROR: $&
You have selected too many nicks in $active $+ .
halt
}
; 2-5. Variable declarations
;
var %SNicks = $replace($snicks, $chr(44), $chr(32))
var %ModeString
var %Range = $+(1-,$modespl)
var %ModeList = MODE $chan $+($1,$str($2, $modespl))
; 6. Loop through the selected nicks
;
while ($gettok(%SNicks, %Range, 32)) {
var %IfMatch = $ifmatch
if (!%ModeString) %ModeString = %ModeList %IfMatch
else %ModeString = $+(%ModeString, $crlf, %ModeList %IfMatch)
if $len(%ModeString) > 400 {
.raw %ModeString
%ModeString = $null
}
%SNicks = $deltok(%SNicks, %Range, 32)
}
if (%ModeString) .raw %ModeString
}
One final note: a nice touch might be to deselect all the selected nicks with /sline -r $active. If you put this in, put it in immediately following the final IF statement before the closing }. Like this:
if (%ModeString) .raw %ModeString
sline -r $active
}