- Код: Выделить всё
######################################################
# Windrop © Vladislav
# Автор: Stream mod Vladislav
# Версия: 1.4
# Описание: Скрипт канальных цитат.
# Команды: !addquote <цитата> - добавить цитату в базу;
# !delquote <номер> - удалить цитату с указанным номером;
# !quote - вывод произвольной цитаты;
# !quote <номер> - вывод цитаты с указанным номером
# !quote <строка> - вывод цитаты, в которой есть указанная "строка"
#####################################################################################
namespace eval quote {}
setudef flag noquote
setudef flag auto-quote
#################################################
bind pub - $::gprefix(1)quote ::quote::pub_quote
bind pub - $::gprefix(1)цитата ::quote::pub_quote
bind pub - $::gprefix(1)q ::quote::pub_quote
bind pub - $::gprefix(1)ц ::quote::pub_quote
bind pub - $::gprefix(1)addquote ::quote::pub_addquote
bind pub - $::gprefix(1)+цитата ::quote::pub_addquote
bind pub - $::gprefix(1)aq ::quote::pub_addquote
bind pub - $::gprefix(1)+ц ::quote::pub_addquote
bind pub o|o $::gprefix(1)delquote ::quote::pub_delquote
bind pub o|o $::gprefix(1)-цитата ::quote::pub_delquote
bind pub o|o $::gprefix(1)dq ::quote::pub_delquote
bind pub o|o $::gprefix(1)-ц ::quote::pub_delquote
#################################################
foreach p [array names quote *] {catch {unset quote($p)}}
#################################################
set quote(announcetime) 45
set quote(datafile) "data/quote.data"
set quote(data) ""
#################################################
proc ::quote::readdata {} {
global quote
set quote(data) ""
if {![catch {set fid [open $quote(datafile) "r"]}]} {
while {![eof $fid]} {
set data [split [string trim [gets $fid]] "|"]
if {[llength $data] == 4} {lappend quote(data) $data}
}
close $fid
}
}
proc ::quote::writedata {} {
global quote
set fid [open "$quote(datafile)" "w+"]
foreach data $quote(data) {
set sdata [join $data "|"]
puts $fid "$sdata "
}
close $fid
}
proc ::quote::init {} {
global quote
foreach tmr [timers] {if {[lindex $tmr 1] == "::quote::announce"} {killtimer [lindex $tmr 2]}}
::quote::readdata
timer $quote(announcetime) ::quote::announce
}
proc ::quote::tolower {text} {
return [string map {А а Б б В в Г г Д д Е е Ё ё Ж ж З з И и Й й К к Л л М м Н н О о П п Р р С с Т т У у Ф ф Х х Ц ц Ч ч Ш ш Щ щ Ъ ъ Ы ы Ь ь Э э Ю ю Я я} [string tolower $text]]
}
proc ::quote::out {nick chan text} {
global botnick
if {$nick != $botnick} {
if {[validchan $chan]} {putserv "PRIVMSG $chan :$text"
} else {putserv "NOTICE $nick :$text"}
} else {putserv "PRIVMSG $chan :$text"}
}
#################################################
proc ::quote::pub_quote {nick uhost hand chan args} {
if {![validchan $chan]} {return}
if {[channel get $chan noquote]} { return }
regsub -all -- {\\} [join $args] "" args
::quote::quote $nick $uhost $hand $chan $chan [string trim $args]
}
proc ::quote::pub_addquote {nick uhost hand chan args} {
if {![validchan $chan]} {return}
if {[channel get $chan noquote]} { return }
regsub -all -- {\\} [join $args] "" args
::quote::addquote $nick $uhost $hand $chan [string trim $args]
}
proc ::quote::pub_delquote {nick uhost hand chan args} {
if {![validchan $chan]} {return}
if {[channel get $chan noquote]} { return }
regsub -all -- {\\} [join $args] "" args
::quote::delquote $nick $uhost $hand $chan [string trim $args]
}
#################################################
proc ::quote::total {chan} {
global quote
set total 0
foreach q $quote(data) {if {![validchan $chan] || [string equal [lindex $q 0] $chan]} {incr total}}
return $total
}
proc ::quote::addquote {nick uhost hand chan args} {
global quote
set args [join $args]
if {[string length $args] < 1} {::quote::out $nick $nick "Формат: $::gprefix(1)+цитата <цитата>"; return}
set largs [::quote::tolower $args]
set num 0
foreach q $quote(data) {
if {![string equal [lindex $q 0] $chan]} {continue}
incr num
if {[string equal [::quote::tolower [lindex $q 2]] $largs]} {
::quote::out $nick $nick "Такая цитата уже добавлена (номер $num)."
return
}
}
lappend quote(data) [list $chan $nick $args [unixtime]]
incr num
::quote::out $nick $nick "Цитата добавлена (номер $num)."
::quote::writedata
}
proc ::quote::delquote {nick uhost hand chan args} {
global quote
set args [join $args]
if {[string length $args] < 1} {::quote::out $nick $nick "Формат: $::gprefix(1)-цитата <номер>"; return}
if {[::quote::total $chan] == 0} {::quote::out $nick $nick "В базе нет ни одной цитаты..."; return}
if {![regexp -nocase -- {^([0-9]{1,5})$} $args]} {::quote::out $nick $nick "Некорректный номер цитаты."; return}
set num 0
set res ""
foreach q $quote(data) {
if {![string equal [lindex $q 0] $chan]} {lappend res $q; continue}
incr num
if {$num != $args} {lappend res $q} else {::quote::out $nick $nick "Удалена цитата номер $num."}
}
if {[llength $res] < [llength $quote(data)]} {
set quote(data) $res
::quote::writedata
} else {::quote::out $nick $nick "Цитата под номером $args не найдена."}
}
proc ::quote::randomquote {nick chan dchan} {
global quote botnick
set total [::quote::total $chan]
if {$total == 0} {return}
set rnum [rand $total]
set num 0
set res ""
foreach q $quote(data) {
if {[validchan $chan] && ![string equal [lindex $q 0] $chan]} {continue}
if {$num == $rnum} {set res $q}
incr num
}
if {$res != ""} {
if {[validchan $chan]} {::quote::out $botnick $dchan "$::gcolor(14)\[$::gcolor(6)[expr {$rnum + 1}]$::gcolor(14)/$num\]\003 [lindex $res 2]\017 $::gcolor(14)\[$::gcolor(5)[lindex $res 1]$::gcolor(14) [clock format [lindex $res 3] -format {%d-%m-%Y %H:%M:%S}]\]"
} else {::quote::out $nick $dchan "$::gcolor(14)\[$::gcolor(6)[expr {$rnum + 1}]$::gcolor(14)/$num\]\003 [lindex $res 2]\017 $::gcolor(14)\[$::gcolor(5)[lindex $res 1]$::gcolor(14) [clock format [lindex $res 3] -format {%d-%m-%Y %H:%M:%S}]\]"}
}
}
proc ::quote::quotebynum {nick chan dchan args} {
global quote botnick
set args [join $args]
set num 0
set res ""
foreach q $quote(data) {
if {[validchan $chan] && ![string equal [lindex $q 0] $chan]} {continue}
incr num
if {$num == $args} {set res $q}
}
if {$res != ""} {
if {[validchan $chan]} {::quote::out $botnick $dchan "$::gcolor(14)\[$::gcolor(6)$args$::gcolor(14)/$num\]\003 [lindex $res 2]\017 $::gcolor(14)\[$::gcolor(5)[lindex $res 1]$::gcolor(14) [clock format [lindex $res 3] -format {%d-%m-%Y %H:%M:%S}]\]"
} else {::quote::out $nick $dchan "$::gcolor(14)\[$::gcolor(6)$args$::gcolor(14)/$num\]\003 [lindex $res 2]\017 $::gcolor(14)\[$::gcolor(5)[lindex $res 1]$::gcolor(14) [clock format [lindex $res 3] -format {%d-%m-%Y %H:%M:%S}]\]"}
} else {::quote::out $nick $nick "Цитата под номером $args не найдена."}
}
proc ::quote::quotebycontent {nick chan dchan args} {
global quote botnick
set args [join $args]
set num 0
set res ""
set rnum 0
foreach q $quote(data) {
if {[validchan $chan] && ![string equal [lindex $q 0] $chan]} {continue}
incr num
if {$res == ""} {
if {[string match "*$args*" "[lindex $q 2] \[[lindex $q 1]\]"]} {
set res $q
set rnum $num
}
}
}
if {$res != ""} {
if {[validchan $chan]} {::quote::out $botnick $dchan "$::gcolor(14)\[$::gcolor(6)$rnum$::gcolor(14)/$num\]\003 [lindex $res 2]\017 $::gcolor(14)\[$::gcolor(5)[lindex $res 1]$::gcolor(14) [clock format [lindex $res 3] -format {%d-%m-%Y %H:%M:%S}]\]"
} else {::quote::out $nick $dchan "$::gcolor(14)\[$::gcolor(6)$rnum$::gcolor(14)/$num\]\003 [lindex $res 2]\017 $::gcolor(14)\[$::gcolor(5)[lindex $res 1]$::gcolor(14) [clock format [lindex $res 3] -format {%d-%m-%Y %H:%M:%S}]\]"}
} else {::quote::out $nick $nick "Цитата не найдена."}
}
proc ::quote::quote {nick uhost hand chan dchan args} {
global quote
if {[::quote::total $chan] == 0} {::quote::out $nick $nick "В базе нет ни одной цитаты..."; return}
set args [join $args]
if {[string length $args] == 0} {::quote::randomquote $nick $chan $dchan
} elseif {[regexp -nocase -- {^([0-9]{1,5})$} $args]} {::quote::quotebynum $nick $chan $dchan $args
} else {::quote::quotebycontent $nick $chan $dchan $args}
}
proc ::quote::announce {} {
global quote botnick
if {[llength $quote(data)] == 0} {return}
foreach chan [channels] {
if {[channel get $chan auto-quote]} {::quote::randomquote $botnick $chan $chan}
}
timer $quote(announcetime) ::quote::announce
}
::quote::init
Скрипт работает замечательно, но есть одно НО.
Команда !цитата <строка_для поиска> - ищет цитату в базе цитат, в которой есть строка <строка_для поиска>. Но проблема в том, что этот скрипт ищет первую в списке цитату с вхождением <строка_для поиска>. Если в базе есть несколько цитат со строкой <строка_для поиска>, то команда всё равно всегда ищет и показывает первую в списке цитату в базе.
Приведу пример.
Пример базы quote.data:
- Код: Выделить всё
#channel|MyNick|<Vegas> Цитата номер один|1371710485
#channel|MyNick|<Vegas> Цитата номер два|1371710485
#channel|MyNick|<Vegas> Цитата номер три|1371710485
#channel|MyNick|<Vegas> Цитата номер четыре|1371710485
Если я напишу в ирке команду "!цитата Vegas", то он мне будет всегда показывать "<Vegas> Цитата номер один", сколько бы я раз не повторял команду "!цитата Vegas".
Так вот задача вроде бы простая, как мне поправить скрипт, чтобы он мне выдавал поиском цитаты не первое совпадение по базе, а случайное (рандомную цитату с указанным вхождением/совпадением)?
Иначе говоря, чтобы когда я писал команду "!цитата Vegas", он мне выдавал случайную цитату из 4 совпадений, указанных выше в базе, а не всегда первую в списке по базе от автора Vegas.
P.S. В TCL пока достаточно плохо разбираюсь, поэтому буду очень благодарен за помощь в исправлении скрипта. Спасибо.