Figured I'd butt my head in here...
There is indeed issues with mixing list- and string-types in this script:
Starting from the initial script:
Code: Select all
set users [list]
set reason [join [lrange [split $text "."] 1 end] "."]
set text [lindex [split $text "."] 0]
users is an (empty) list
reason is a (sub)string of everything past the first "." on the "commandline"
text is a (sub)string of everything before the first "." on the "commandline"
Moving on...
We want to build a list of users;
text is a string presumably with an enumeration of nicks separated with space. Thus, we use
split to get a list of strings (nicknames).
This is just wrong;
foreach iterates through each list-member - which in this instance is a string. Don't try to
join it here, or you'll try to parse {} as list delimiters (and they'll disappear, or the code breaks due to a malformed list).
Next...
Code: Select all
if {![onchan $user $chan]} {
putserv "NOTICE $nick $user is not on channel $chan"
} else {
lappend users $user
}
Unless you are using some arcane IRC-server that I havn't kept up to date with, the text-argument for a NOTICE-command needs to be prefixed with : if it contains spaces
Code: Select all
putserv "NOTICE $nick :$user is not on channel $chan"
lappend appends the (string)
user to the list
users. That is legit.
Finally...
Code: Select all
stackKicks $chan [join $users] $reason 4
Here we take our list of nicks to be kicked, and squash it into a string; which is not so good given that stackKicks actually expects a list of nicknames, not a string...
Drop the
join.
Now, for stackKicks:
Code: Select all
proc stackKicks {chan kicklist reason {max 4}} {
set count [llength $kicklist]
while {$count > 0} {
So we expect kicklist to be a list of nicks, and we iterate over it using a while-loop.
Code: Select all
if {$count > $max} {
set users [join [lrange $kicklist 0 [expr {$max - 1}]] ","]
set kicklist [lrange $kicklist $max end]
incr count -$max
If there's more than
max entities remaining in the list, grab the first
max items, and squash then down to a string with "," as separator.
Then trim the first
max entities off the kicklist.
Edit: disregard this part, as it's not really valid:
You could probably gain some readability and performance by using lreplace instead of set ... [lrange ...], but it's still fully functional.
Finally decrement
count so we don't get stuck in an infinite loop. Good!
Code: Select all
} else {
set users [join $kicklist ","]
set count 0
}
Otherwise, we just grab the whole (remaining) list, and squash it.
Code: Select all
putnow "KICK $chan $users $reason"
Finally, we send a KICK-command to the server; once again, if the last argument contains spaces, it should be prefixed with :
Sorry if I got a bit lengthy...