Code: Select all
if {[string match "#channel" [string tolower $arg]]} {return 0}
How could I make bot do nothing if someone says "Hello....#channel", "#channel is ok"
Thanks for ideas.
Code: Select all
if {[string match "#channel" [string tolower $arg]]} {return 0}
Code: Select all
if {([string match -nocase "*$chan * $arg]) || ([string match -nocase "*$chan" $arg)} { return 0 }
Heya #channel - Why no come to #xxx and for xxx pics
You probably would rather be using something like:Nexus6 wrote:I'm using one script which bans people if they say *www.* *#* on public, it works ok but I don't wanna bot do anything if somone says #channel on #channel, I tried this:I thought that it will work, but it doesn't and "*#channel*" doesn't fix prob because if people spammed #channel2 they wouldn't get banned.Code: Select all
if {[string match "#channel" [string tolower $arg]]} {return 0}
How could I make bot do nothing if someone says "Hello....#channel", "#channel is ok"
Thanks for ideas.
Code: Select all
if {[lsearch -exact [split [string tolower $arg]] [string tolower "#channel"]] != -1} { return 0 }
Nexus, ppslim has a good point that a user could come in and do "Heya #channel - Why no come to #xxx and for xxx pics".Nexus6 wrote:I'm using one script which bans people if they say *www.* *#* on public, it works ok but I don't wanna bot do anything if somone says #channel on #channel, I tried this:I thought that it will work, but it doesn't and "*#channel*" doesn't fix prob because if people spammed #channel2 they wouldn't get banned.Code: Select all
if {[string match "#channel" [string tolower $arg]]} {return 0}
How could I make bot do nothing if someone says "Hello....#channel", "#channel is ok"
Thanks for ideas.
Code: Select all
#---------------------------------------------------------------------
# proc stringisbad checks a string for channel names (# chans only!)
# returns 1 if string contains undesired channelnames
# returns 0 if string does not contain undesired channelnames
#---------------------------------------------------------------------
proc stringisbad { string } {
# allowed channel
set channel #egghead
# iteration counter (limit number of iterations)
set count 0
# regexp rule
set rule {^[^#]*(#[^ ]*)(.*)}
# iterate on the string, breaking at every "#channame"
while {[regexp $rule $string match channame string] == 1} {
# limit the number of iterations.
# more than 5: consider it a bad string.
incr count
if { $count > 5 } { return 1 }
# compare the channame with the allowed channelname
if { [string compare $channel $channame] != 0 } { return 1 }
}
return 0
}
Code: Select all
#---------------------------------------------------------------------
# test
#---------------------------------------------------------------------
lappend strings "join egghead"
lappend strings "join #egghead"
lappend strings "join #egghead for fun"
lappend strings "#egghead"
lappend strings "#egghead2"
lappend strings "#egghead2 for fun"
lappend strings "join #egghead2"
lappend strings "join #egghead2 for xxx"
lappend strings "hi #egghead join #xxx "
lappend strings "join #xxx for xxx"
lappend strings "#xxx for xxx"
lappend strings "#xxx"
lappend strings "####xxx"
lappend strings "#egghead #egghead #egghead #xxxx"
lappend strings "#egghead #xxxx #egghead"
lappend strings "#"
lappend strings "xxx#"
lappend strings "##egghead"
proc mput { keyword string } {
set line [format "%-8s %s" $keyword $string]
puts $line
}
foreach line $strings {
if {[stringisbad $line]} {
mput BAD $line
} else {
mput GOOD $line
}
}
Code: Select all
GOOD join egghead
GOOD join #egghead
GOOD join #egghead for fun
GOOD #egghead
BAD #egghead2
BAD #egghead2 for fun
BAD join #egghead2
BAD join #egghead2 for xxx
BAD hi #egghead join #xxx
BAD join #xxx for xxx
BAD #xxx for xxx
BAD #xxx
BAD ####xxx
BAD #egghead #egghead #egghead #xxxx
BAD #egghead #xxxx #egghead
BAD #
BAD xxx#
BAD ##egghead
Or..egghead wrote:Nexus, ppslim has a good point that a user could come in and do "Heya #channel - Why no come to #xxx and for xxx pics".Nexus6 wrote:I'm using one script which bans people if they say *www.* *#* on public, it works ok but I don't wanna bot do anything if somone says #channel on #channel, I tried this:I thought that it will work, but it doesn't and "*#channel*" doesn't fix prob because if people spammed #channel2 they wouldn't get banned.Code: Select all
if {[string match "#channel" [string tolower $arg]]} {return 0}
How could I make bot do nothing if someone says "Hello....#channel", "#channel is ok"
Thanks for ideas.
After messing around for a while with lists, scans and regexp here is an attempt:
comments, suggestions welcome.Code: Select all
#--------------------------------------------------------------------- # proc stringisbad checks a string for channel names (# chans only!) # returns 1 if string contains undesired channelnames # returns 0 if string does not contain undesired channelnames #--------------------------------------------------------------------- proc stringisbad { string } { # allowed channel set channel #egghead # iteration counter (limit number of iterations) set count 0 # regexp rule set rule {^[^#]*(#[^ ]*)(.*)} # iterate on the string, breaking at every "#channame" while {[regexp $rule $string match channame string] == 1} { # limit the number of iterations. # more than 5: consider it a bad string. incr count if { $count > 5 } { return 1 } # compare the channame with the allowed channelname if { [string compare $channel $channame] != 0 } { return 1 } } return 0 }
Code: Select all
set bad 0
foreach word [split $arg] {
if {[string match "#*" $word] && [string tolower $word] != [string tolower $chan]} {
set bad 1
}
}
if {!$bad} { return }
Code: Select all
set bad 0
set mylist [lsort [split [string tolower $arg]]]
set aloc [lsearch $mylist #*]
if {$aloc == -1} { return }
set mylist [lrange $mylist $aloc end]
foreach word $mylist {
if {![string match "#*" $word]} { break }
if {$word != [string tolower $chan]} { set bad 1 }
}
if {!$bad} { return }
Aside from having a "break" right when the "set bad 1" has been reached, there is another issue:strikelight wrote:
[snip]
Or..
Code: Select all
set bad 0 foreach word [split $arg] { if {[string match "#*" $word] && [string tolower $word] != [string tolower $chan]} { set bad 1 } } if {!$bad} { return }
Hello #egghead, join#xxx for xxx, join#xxx!!!
I thought I had read him say something that he didn't..egghead wrote:Aside from having a "break" right when the "set bad 1" has been reached, there is another issue:strikelight wrote:
[snip]
Or..
Code: Select all
set bad 0 foreach word [split $arg] { if {[string match "#*" $word] && [string tolower $word] != [string tolower $chan]} { set bad 1 } } if {!$bad} { return }
Hello #egghead, join#xxx for xxx, join#xxx!!!
Actually, Tcl8.4 has an [lsearch -all -inline] option which in principle should be able to produce immediately a list of matches. Unfortunately I'm still on Tcl8.3, so I couldn't test that ideastrikelight wrote:
or to cut down on iterations while still actually verifying each channel name..
Code: Select all
set bad 0 set mylist [lsort [split [string tolower $arg]]] set aloc [lsearch $mylist #*] if {$aloc == -1} { return } set mylist [lrange $mylist $aloc end] foreach word $mylist { if {![string match "#*" $word]} { break } if {$word != [string tolower $chan]} { set bad 1 } } if {!$bad} { return }
Already addressed this in my modification on my post containing the example, with the lsort, lrange, etc...egghead wrote:
Another drawback of doing a word by word check, is that it's not cheap on the average say 5 to 10 word sentences not containing any "#" char. Maybe doing a check for the presence of a # char in the string before going to a word by word check can solve this.
Same here...egghead wrote:
Actually, Tcl8.4 has an [lsearch -all -inline] option which in principle should be able to produce immediately a list of matches. Unfortunately
I'm still on Tcl8.3, so I couldn't test that idea
Code: Select all
proc stringisbad { string } {
# omit sentences without # in it
if {[set index [string first "#" $string]] == -1 } { return 0 }
# remove first part of the string
set string [string range $string $index end]
# allowed channel
set channel #egghead
# split the line into a list of words
set list [split $string]
# iterate on the words
foreach word $list {
# if word does not contain a "#" then continue ...
if { [set index [string first "#" $word]] == -1 } { continue }
# ... else retrieve channel name
set channame [string range $word $index end]
# if found name is not allowed name then string is bad
if { $channame != $channel } { return 1 }
}
# iterated on all words, but nothing bad found :)
return 0
}