| View previous topic :: View next topic |
| Author |
Message |
simo Owner
Joined: 22 Mar 2015 Posts: 941
|
Posted: Thu Jul 30, 2020 11:31 am Post subject: same issue with massvoice and nicks with {} |
|
|
simmilarly as the previous one i checked what it could be and i couldnt find any thing why it wouldnt set voice on nicks with {} in them like {somenick}
| Code: |
bind pub n .mv voice_all
set excnick {
"chanserv"
"somenick"
}
proc voice_all {nick host handle chan text} {
global excnick
if {![botisop $chan]} {
puthelp "NOTICE $nick :I'm not oped on $chan."
return
}
# grab the channel members list and exclude the bot from it
set userList [chanlist $chan]
set pos [lsearch -nocase $userList $::botnick]
set userList [lreplace $userList $pos $pos]
# build the op list with only people that aren't op or any other channel access level
foreach user [split $userList] {
if {![isvoice $user $chan] && ![isop $user $chan] && ![ishalfop $user $chan] && ![matchattr [nick2hand $user] o|o $chan] && [lsearch -nocase $excnick $user] == -1} { lappend voiceList $user }
}
# define the max amount of modes per line
set max 15
# op all the members in the above built voice list
if {[info exists voiceList]} {
set len [llength $voiceList]
while {$len > 0} {
if {$len > $max} {
set mode [string repeat "v" $max]
set users [join [lrange $voiceList 0 [expr {$max - 1}]]]
set voiceList [lrange $voiceList $max end]
incr len -$max
} else {
set mode [string repeat "v" $len]
set users [join $voiceList]
set len 0
}
putnow "MODE $chan +$mode $users"
}
puthelp "NOTICE $nick :Voiced all users on $chan."
} else {
puthelp "NOTICE $nick :Nobody needed to be Voiced on $chan."
}
}
|
it adds {} to the nicks for example
a nick like {ykbeucwvi} would be seen as {{ykbeucwvi}} |
|
| Back to top |
|
 |
nml375 Revered One
Joined: 04 Aug 2006 Posts: 2857
|
Posted: Thu Jul 30, 2020 11:55 am Post subject: |
|
|
Hi Simo,
Going to try and not make a complete teardown of the script this time...
But...
Lets start here:
| Code: | set userList [chanlist $chan]
set pos [lsearch -nocase $userList $::botnick
set userList [lreplace $userList $pos $pos] |
Here, we treat userList as an actual list (which it is); so far so good.
But then, we get here:
| Code: | | foreach user [split $userList] { |
split is really only intended to be used on strings, not lists. Remove it, as userList already is a list.
Next;
| Code: | | if {... && [lsearch -nocase $excnick $user] ... |
Here, we treat excnick as a list, but to be honest it's merely a list-like string;
| Code: | set excnick {
"chanserv"
"somenick"
} |
You'll get away with it for as long as your exclusion-nicks does not contain list-formatting characters such as {}... Consider creating a proper list using the list command instead.
In the end, you've got some code iterating through a list of nicks, trying to build optimal MODE commands (stack multiple mode changes in one command, not unlike the KICK-stacking in your previous thread). Technically nothing obviously wrong with the code; I just wanted to point out that this functionality is already implemented in eggdrop itself using the pushmode command (which will queue all mode changes until the binding returns, and then stack them properly). _________________ NML_375, idling at #eggdrop@IrcNET |
|
| Back to top |
|
 |
simo Owner
Joined: 22 Mar 2015 Posts: 941
|
Posted: Thu Jul 30, 2020 12:12 pm Post subject: |
|
|
excellent tnx for the explanation nml375
about the list i tried searching for it in the docs couldnt find it would you have any example i can use as a template cause we might want to add nicks wich may contain list formatting chars as u mentioned we want to have it optional anyway
tnx once again nml375 much apreciated |
|
| Back to top |
|
 |
nml375 Revered One
Joined: 04 Aug 2006 Posts: 2857
|
Posted: Thu Jul 30, 2020 12:49 pm Post subject: |
|
|
Certainly; though the man-page for list do have a few good examples: https://www.tcl.tk/man/tcl8.6/TclCmd/list.htm
| Code: | #sampe 1
set excnick [list chanserv somenick]
#sample 2
set excnick [list \
chanserv \
somenick \
]
#sample 3, adding the value of the global variable ::botnick to the list.
set excnick [list "chanserv" \
somenick $::botnick] |
Be cautious though, as you still go through variable- and command-substitutions, as well as syntax checks in the tcl-interpreter:
| Code: | #this will not work well;
set uxcnick [list badnick{ \
badnick2 \
}badnick3 ]
#this one might surprise you
set excnick [list "chanserv" \
{somenick} \
]
#result is "chanserv somenick"
#What you probably wanted:
set excnick [list "chanserv" \
"{somenick}" \
"{othernick" \
]
#result is "chanserv {{somenick}} \{othernick"
#"lindex $excnick 0" => "chanserv"
#"lindex $excnick 1" => "{somenick}"
#"lindex $excnick 2" => "{othernick"
#Another one:
set excnick [list "chanserv" \
{$botnick} \
]
#result is "chanserv {$botnick}"
#"lindex $excnick 1" => "$botnick"
#note that there is no variable substitution done due to the use of braces |
Somewhat simplified, an atomic item on the command line may be a single word (no quotes or braces), a substitutable string (enclosed in quotes), or a plain string (enclosed in braces, or {}). That's why list "chanserv" {somenick} produced a list with the strings "chanserv" and "somenick", and list "chanserv" {$botnick} created a list containing the strings "chanserv" and "$botnick".
Finally, the backspaces are needed to escape the newline character into a whitespace character, as newline otherwize would terminate the commandline early (and there's alot of more trickery that can be done with escaping).
You'll also find a decent readup on the various substitutions done by the tcl interpreter here: https://www.tcl.tk/man/tcl8.6/TclCmd/Tcl.htm _________________ NML_375, idling at #eggdrop@IrcNET |
|
| Back to top |
|
 |
simo Owner
Joined: 22 Mar 2015 Posts: 941
|
Posted: Thu Jul 30, 2020 1:06 pm Post subject: |
|
|
| excellent thank you nml375 for the explanation and the provided examples much apreciated |
|
| Back to top |
|
 |
nml375 Revered One
Joined: 04 Aug 2006 Posts: 2857
|
Posted: Thu Jul 30, 2020 1:11 pm Post subject: |
|
|
You're welcome,
I tried to cover the most common mistakes I've seen over the years, though there certainly are other pitfalls. Understanding when and how substitutions and escaping occurs is really the name of the game here.
The list command does guarantee a valid list (will not break on foreach, lindex, etc), but you still need to make sure the input isn't mangled by the tcl interpreter before list gets it hands on it. _________________ NML_375, idling at #eggdrop@IrcNET |
|
| Back to top |
|
 |
CrazyCat Revered One

Joined: 13 Jan 2002 Posts: 1032 Location: France
|
Posted: Thu Jul 30, 2020 6:00 pm Post subject: |
|
|
I'll made a short critic about the script...
You set a "max" variable ("define the max amount of modes per line") and after various calculation and manipulation you use:
| Code: | | putnow "MODE $chan +$mode $users" |
I think that if you use the good tcl commands (pushmode & flushmode), you can really simplify your procedure:
| Code: | proc voice_all {nick host handle chan text} {
global excnick
if {![botisop $chan]} {
puthelp "NOTICE $nick :I'm not oped on $chan."
return 0
}
# build the op list with only people that aren't op or any other channel access level
set voiced 0
foreach user [chanlist $chan] {
if {($user ne $::botnick) && ![isvoice $user $chan] && ![isop $user $chan] && ![ishalfop $user $chan] && ![matchattr [nick2hand $user] o|o $chan] && [lsearch -nocase $excnick $user] == -1} {
incr voiced
pushmode $chan +v $user
}
}
flushmode $chan
if { $voiced == 0} {
puthelp "NOTICE $nick :Nobody needed to be Voiced on $chan."
} else {
puthelp "NOTICE $nick :Voiced all users on $chan."
}
} |
_________________ https://www.eggdrop.fr - French IRC network
Offer me a coffee - Do not ask me help in PM, we are a community. |
|
| Back to top |
|
 |
simo Owner
Joined: 22 Mar 2015 Posts: 941
|
Posted: Thu Jul 30, 2020 8:44 pm Post subject: |
|
|
| thats even better thanx CrazyCat |
|
| Back to top |
|
 |
|