## vseen.tcl - seen by Vertigo ## modified 23-02-2011 - rewrited to use sqlite3 database ## modified 22-02-2012 - added channel flags, rewritted output messages ## ————————————————————————————————————— ## Channel flags: ## +vseen - enable script for specified channel ## +quietvseen - show messages as NOTICE nick, instead PRIVMSG chan nick ## +novseendata - disable collecting any statistics and public triggering # minimal works version sqlite - 3.3.0 package require sqlite3 3.3.0 namespace eval ::vseen { # ôàéë áàçû äàííûõ variable base "vseen.db" # ôàéë áàçû ïîñëåäíèõ ôðàç variable pubmbase "vseen_pubm.dat" # ïîë áîòà (äëÿ ñîîáùåíèé) [m/w] variable botgender "m" #if {![file exists $base]} {set f [open $base w+]; close $f} variable expire "1825"; #days variable debug 0 variable maxmatches 500 bind join - * ::vseen::vjoin bind part - * ::vseen::vpart bind sign - * ::vseen::vsign bind kick - * ::vseen::vkick bind nick - * ::vseen::vnick ## bind splt - * ::vseen::vsplt bind rejn - * ::vseen::vrejn bind chjn - * ::vseen::vchjn bind chpt - * ::vseen::vchpt ## bind pubm - * ::vseen::pubm bind pub - !seen "::vseen::pub 0" bind pub m|n !!seen "::vseen::pub 2" bind pub - !seennick "::vseen::pub 1" bind pub - !seenstats ::vseen::pub_stats #bind time - "01 00 * * *" ::vseen::clear ;# <- clearing now not needed #bind pub n !optimizeseens "::vseen::optimize 0";# <- optimizing too ;) variable version "4.2.1" variable bchan {} variable bnick {} variable bnum 1 variable b_cache "" variable cl_cache "" setudef flag vseen setudef flag quietvseen setudef flag novseendata proc out {nick chan msg} { if {[validchan $chan] && [channel get $chan quietvseen]} { putserv "NOTICE $nick :$msg" } else { putserv "PRIVMSG $chan :$nick, $msg" } } proc pubm {nick uhost hand chan text} { if {[channel get $chan novseendata]} {return} variable pubmbase set text [string map {\017 ""} [stripcodes bcurag $text]] if {[string is space $text]} {return} if {![file exists $pubmbase]} { set f [open $pubmbase w+] if {[encoding system] ne "cp1251"} {fconfigure $f -encoding cp1251} close $f return } set f [open $pubmbase r] if {[encoding system] ne "cp1251"} {fconfigure $f -encoding cp1251} set data [lrange [split [read $f] \n] 0 end-1] close $f if {[lsearch -exact -index 0 $data "$nick|$chan"] == "-1"} { lappend data [list "$nick|$chan" $text] unset -nocomplain text } elseif {[set idx [lsearch -exact -index 0 $data "$nick|$chan"]] != "-1"} { #putlog "nick $nick found in datatabase. adding/replacing text..." set data [lreplace $data $idx $idx [list "$nick|$chan" $text]] unset -nocomplain line text idx } else { #putlog "fuckinshit" unset -nocomplain data return } set f [open $pubmbase w] if {[encoding system] ne "cp1251"} {fconfigure $f -encoding cp1251} puts $f [join $data \n] close $f } proc issecret {chan} { if {![validchan $chan]} { return " $chan" } elseif {[channel get $chan secret]} { return " \[êàíàë ñêðûò\]" } else { return " $chan" } } proc pubmtext {nick chan} { variable pubmbase if {![file exists $pubmbase]} { set f [open $pubmbase w+] if {[encoding system] ne "cp1251"} {fconfigure $f -encoding cp1251} close $f return 0 } set f [open $pubmbase r] if {[encoding system] ne "cp1251"} {fconfigure $f -encoding cp1251} set data [lrange [split [read $f] \n] 0 end-1] close $f if {[set idx [lsearch -exact -index 0 $data "$nick|$chan"]] != "-1"} { return [join [lrange [lindex $data $idx] 1 end]] } else { return 0 } } # opening database file if {[string is space [info command vseen]]} {sqlite3 vseen $base} # creating table data if it's missing if {[catch {vseen eval "SELECT * FROM seendata ORDER by time LIMIT 1"} err]} { vseen eval "CREATE TABLE seendata (nick STRING UNIQUE NOT NULL, fullmask STRING UNIQUE NOT NULL, channel STRING NOT NULL, time INTEGER NOT NULL, action STRING, info STRING, kickreason STRING)" } proc pub_stats {nick uhost hand chan text} { if {[channel get $chan novseendata]} {return} if {[validuser $hand] && [matchattr $hand X]} { putserv "NOTICE $nick :Access denied." return } if {![channel get $chan vseen] && ![matchattr $hand n]} {return} variable base set total [vseen eval "SELECT COUNT(*) FROM seendata"] if {$total == "0"} {putserv "PRIVMSG $chan :$nick, áàçà ïóñòà."; return 0} out $nick $chan "çàïèñåé âñåãî: $total, ðàçìåð áàçû [fsize [file size $base]]." } proc optimize {mode nick uhost hand chan text} { variable base variable cl_cache out $nick $chan "Feature disabled." return } proc clear {min hour day month year} { variable base variable expire variable debug putlog "\[vseen\] clearing temporarily disabled" return } if {[string is space [info command vr::fsize]]} {proc fsize {args} {return $args}} {proc fsize {size} {::vr::fsize $size}} proc putdb {nick fullmask channel time action info kickreason} { if {[validchan $channel] && [channel get $channel novseendata]} {return} if {[catch { vseen eval "INSERT OR REPLACE INTO seendata VALUES('$nick','$fullmask','[string trim $channel \x7B\x7D]','$time','$action','[string map {{'} {}} [string trim $info \x7B\x7D]]','[string map {{'} {}} [string trim $kickreason \x7B\x7D]]')" } err]} { putlog "\[vseen\] putdb SQL ERROR: $err" return } } proc vjoin {nick uhost hand chan} { putdb $nick $nick!$uhost $chan [expr [clock seconds] +1] join {} {} } proc vchjn {bot user arg0 flag arg1 host} { putdb $user $user!$host partyline [clock seconds] chjn $bot {} } proc vchon {bot user arg0 flag arg1 host} { putdb $user $user!$host partyline [clock seconds] chon $bot {} } proc vchof {bot user arg0 flag arg1 host} { putdb $user $user!$host partyline [clock seconds] chof $bot {} } proc vchpt {bot user arg0 arg1} { putdb $user $user partyline [clock seconds] chpt $bot {} } proc vsplt {nick uhost hand chan} { putdb $nick $nick!$uhost $chan [clock seconds] splt {} {} } proc vrejn {nick uhost hand chan} { putdb $nick $nick!$uhost $chan [clock seconds] rejn {} {} } proc vkick {nick uhost hand chan victim text} { putdb $victim $victim![getchanhost $victim] $chan [expr [clock seconds] -1] kick $nick $text } proc vnick {nick uhost hand chan newnick} { putdb $nick $nick!$uhost $chan [clock seconds] nick $newnick {} } proc vpart {nick uhost hand chan text} { putdb $nick $nick!$uhost $chan [clock seconds] part $text {} } proc vsign {nick uhost hand chan text} { putdb $nick $nick!$uhost $chan [clock seconds] sign $text {} } ################## ## SEARCH ################## proc search {text {exact 0} {channel ""}} { set text [string map [list {'} {} {*} {%} {?} {_}] $text] variable maxmatches if {![string is space $channel] && [validchan $channel]} {set chan_search "channel LIKE '$channel' AND "} {set chan_search ""} if {$exact} { if {[catch { set res [vseen eval "SELECT * FROM seendata WHERE ${chan_search}nick = '$text' ORDER BY time DESC LIMIT [expr $maxmatches + 1]"] } err]} { putlog "\[vseen\] search SQL ERROR: $err" return } } else { if {[catch { set res [vseen eval "SELECT * FROM seendata WHERE ${chan_search}nick LIKE '$text' OR ${chan_search}fullmask LIKE '$text' ORDER BY time DESC LIMIT [expr $maxmatches + 1]"] } err]} { putlog "\[vseen\] search SQL ERROR: $err" return } } if {[string is space $res]} { return "notf" } elseif {[expr [llength $res] / 7] > $maxmatches} { unset -nocomplain res return "max" } else { return $res } } proc pub {exact nick uhost hand chan text} { if {![channel get $chan vseen] && $exact ne 2} {return 1} if {[channel get $chan novseendata]} {return} if {[validuser $hand] && [matchattr $hand X]} { putserv "NOTICE $nick :Access denied." return } set text [string map {\017 ""} [stripcodes bcurag $text]] if {[string is space $text]} {out $nick $chan " èñïîëüçóé $::lastbind \[-force \[-÷èñëî\]|-bot \|-nobotnet\] \ \[channel\]. Îïöèè: -force - èñêàòü ñðàçó â áîòíåòå, -bot - îòîñëàòü çàïðîñ óêàçàííîìó áîòó, -nobotnet - èñïîëüçîâàòü òîëüêî ëîêàëüíóþ áàçó ïðè ïîèñêå. Åñëè óêàçàí 'channel' - ïîèñê áóäåò âåñòèñü òîëüêî â äàííîì êàíàëå."; return 0} if {[string tolower $text] eq [string tolower $nick]} {out $nick $chan "ïîòåðÿëñÿ?\)"; return 0} if {[string tolower $text] eq [string tolower $::botnick]} {out $nick $chan "òû íàøåë ìåíÿ!"; return 0} if {[onchan $text $chan] && ![onchansplit $text]} {out $nick $chan "ðàçóé ãëàçà!"; return 0} variable bnum; variable tmpnum set num 0; set bnum 0; set tmpnum 0 if {[regexp -- {^-force\s-?(\d)?} $text -> num]} { regsub -- {^-force\s-?(\d)?} $text "" text set text [string trim $text] #if {[encoding system] ne "cp1251"} {set text [encoding convertfrom [encoding system] [encoding convertto cp1251 $text]]} putlog "\[vseen\] forcebly trying botnet seen for request '$text' from $nick ($uhost) $chan ..."; variable bchan; variable bnick; if {$num > 0 && $num <= 9} {set bnum $num} {set bnum 0} set bchan $chan; set bnick $nick; set tmpnum 0 putallbots "gseen_req $text $nick $uhost $chan" return 0 } if {[regexp -- {^-bot\s(.*?)\s} $text -> bot]} { regsub -- {^-bot\s.*?\s} $text "" text if {$bot ni [bots]} {out $nick $chan "òàêîãî áîòà '$bot' ÿ íå âèæó â áîòíåòå..."; return} putlog "\[vseen\] forcebly trying botnet seen (bot $bot) for request '$text' from $nick ($uhost) $chan ..."; variable bchan; variable bnick set bchan $chan; set bnick $nick putbot $bot "gseen_req $text $nick $uhost $chan" return 0 } set nobotnet 0 if {[regexp -- {^-nobotnet\s} $text]} { regsub -- {^-nobotnet\s} $text "" text set nobotnet 1 } set channel "" if {[regexp -- {\s(\#.+?)$} $text -> channel]} { regsub -- {\s\#.+?$} $text "" text } if {$channel != "" && ![validchan $channel]} { out $nick $chan "Óêàçàííûé êàíàë íå ïîääåðæèâàåòñÿ." return 0 } foreach _ [channels] { if {[onchan $text $_] && ![onchansplit $text]} { if {[getchanidle $text $_] > 0} { out $nick $chan "$text â äàííûé ìîìåíò ñèäèò íà êàíàëå[issecret $_]. Ìîë÷èò [duration [expr [getchanidle $text $_] * 60]]." } else { out $nick $chan "$text â äàííûé ìîìåíò ñèäèò íà êàíàëå[issecret $_]." } return 1 } } set ::vseen::start_time [clock clicks -milliseconds] set i 0 set results [list] set founds [list] set tmp [list] #set text [split $text] variable maxmatches putlog "::vseen:: before search: [format %.2f [expr ([clock clicks -milliseconds] - $::vseen::start_time)]] ms." set data [search $text $exact $channel] putlog "::vseen:: after search: [format %.2f [expr ([clock clicks -milliseconds] - $::vseen::start_time)]] ms." #putfast "PRIVMSG #vb :vseen:pub \<1\> data=$data" set total [expr [llength $data] /7] if {$data eq "notf"} { if {![string is space [set line [useronpartyline $text check]]]} { if {![string is space [lindex $line end]]} {set away ", íî â away ([lindex $line end]\017)."} {set away "."} if {[string is digit [set idle [lindex $line 4]]]} { if {$idle > 0} {set idle " Ìîë÷èò [duration [expr $idle * 60]]."} else {set idle ""} } out $nick $chan "$text ([lindex $line 2]) ñåé÷àñ â ïàòèëàéíå íà [lindex $line 1]$away$idle" return } if {[llength [bots]] > 1} { if {$text in [bots]} { out $nick $chan "$text (áîò) ñåé÷àñ íàõîäèòñÿ â áîòíåòå." return } } if {[validuser $text] && ![string is space [set laston [getuser $text LASTON]]]} { lassign $laston time where set lmsg "." if {[validchan $where] && [set tmppubm [pubmtext $text $where]] ne 0} { if {[string length $tmppubm] >= 100} {set tmppubm "[string range $tmppubm 0 99]..."} set lmsg ". Ïîñëåäíÿÿ ôðàçà: $tmppubm" } if {[string index $where 0] eq "#" && [validchan $where]} { out $nick $chan "$text ïîñëåäíèé ðàç áûë çàìå÷åí â êàíàëå[issecret $where] [duration [expr [clock seconds] - $time]] íàçàä ([rustime $time])$lmsg" return 0 } elseif {[string index $where 0] in {@ * % +}} { out $nick $chan "$text ïîñëåäíèé ðàç áûë çàìå÷åí â ïàòèëàéíå ó [string range $where 1 end] [duration [expr [clock seconds] - $time]] íàçàä ([rustime $time])." return 0 } } #if {[encoding system] ne "cp1251"} {set text [encoding convertfrom [encoding system] [encoding convertto cp1251 $text]]} out $nick $chan "íè÷åãî íå íàéäåíî. \([format %.2f [expr ([clock clicks -milliseconds] - $::vseen::start_time)/1000.0]] sec.\)"; #if {![string match "*\\**" $text]} { if {$nobotnet eq "0"} { putlog "\[vseen\] trying botnet seen for request '$text' from $nick ($uhost) $chan ..."; variable bchan; variable bnick set bchan $chan; set bnick $nick putallbots "gseen_req $text $nick $uhost $chan" } #} return 0 } if {$data eq "max"} { out $nick $chan "óêàæèòå áîëåå æåñòêèå óñëîâèÿ ïîèñêà - ñëèøêîì ìíîãî ñîâïàäåíèé ñ '$text' - áîëåå $maxmatches. \([format %.2f [expr ([clock clicks -milliseconds] - $::vseen::start_time)/1000.0]] sec.\)"; return } set tdata [list] foreach {vnick vhost vchan vtime vtype varg1 varg2} $data { set vhost [lindex [split $vhost "!"] end] if {$vnick in $tmp || $vhost in $tmp} {continue} lappend tmp $vnick lappend tmp $vhost lappend tdata [list $vnick $vhost $vchan $vtime $vtype $varg1 $varg2] } set rdata [lrange $tdata 0 4] set ftotal [llength $tdata] foreach _ $rdata { if {[string is space $_]} {continue} lassign $_ vnick vhost vchan vtime vtype varg1 varg2 set vhost [lindex [split $vhost "!"] end] lappend founds $vnick #putfast "PRIVMSG #vb :\00304vseen:search \<2\>\003 _=$_" set msg " ." if {[validchan $vchan] && [onchan $varg1 $vchan] && ![onchansplit $varg1] && $vtype ne "kick"} {set msg ". $varg1 âñå åùå òàì."} if {[validchan $vchan] && [onchan $vnick $vchan] && ![onchansplit $vnick] && $vtype ne "kick"} {set msg ". $vnick âñå åùå òàì."} if {[set tmppubm [pubmtext $vnick $vchan]] ne 0} { if {[string length $tmppubm] >= 100} {set tmppubm "[string range $tmppubm 0 99]..."} append msg " Ïîñëåäíÿÿ ôðàçà â êàíàëå: \<$tmppubm\>." unset -nocomplain tmppubm } switch -- $vtype { nick {lappend results "$vnick ($vhost) ïîñëåäíèé ðàç ìåíÿë íèê íà $varg1 â êàíàëå[issecret $vchan] [duration [expr [clock seconds] - $vtime]] íàçàä ([rustime $vtime])$msg"} kick {lappend results "$vnick ($vhost) áûë âûêèíóò èç êàíàëà[issecret $vchan] ïîëüçîâàòåëåì $varg1 ïî ïðè÷èíå \<$varg2\017\> [duration [expr [clock seconds] - $vtime]] íàçàä ([rustime $vtime])$msg"} join {lappend results "$vnick ($vhost) çàõîäèë íà êàíàë[issecret $vchan] [duration [expr [clock seconds] - $vtime]] íàçàä ([rustime $vtime])$msg"} splt {lappend results "$vnick ($vhost) âûõîäèë èç ñåòè èç-çà ñïëèòà ñ êàíàëà[issecret $vchan] [duration [expr [clock seconds] - $vtime]] íàçàä ([rustime $vtime])$msg"} rejn {lappend results "$vnick ($vhost) ïåðåçàõîäèë íà êàíàë[issecret $vchan] èç ñïëèòà [duration [expr [clock seconds] - $vtime]] íàçàä ([rustime $vtime])$msg"} part {if {![string is space $varg1]} {set ptext " ñ ñîîáùåíèåì \<$varg1\017\>"} else {set ptext ""}; lappend results "$vnick ($vhost) ïîêèäàë êàíàë[issecret $vchan] [duration [expr [clock seconds] - $vtime]] íàçàä ([rustime $vtime])$ptext$msg"} sign {if {![string is space $varg1]} {set ptext " ñ ñîîáùåíèåì \<$varg1\017\>"} else {set ptext ""}; lappend results "$vnick ($vhost) âûõîäèë èç ñåòè ñ[issecret $vchan] [duration [expr [clock seconds] - $vtime]] íàçàä ([rustime $vtime])$ptext$msg"} chjn {lappend results "$vnick ($vhost) çàõîäèë â ïàòèëàéí íà $varg1 [duration [expr [clock seconds] - $vtime]] íàçàä ([rustime $vtime])[useronpartyline $vnick]"} chpt {lappend results "$vnick âûõîäèë èç ïàòèëàéí íà $varg1 [duration [expr [clock seconds] - $vtime]] íàçàä ([rustime $vtime])."} default {} } } putlog "::vseen:: after foreach: [format %.2f [expr ([clock clicks -milliseconds] - $::vseen::start_time)]] ms." unset -nocomplain data if {$ftotal eq 1} {set fnd "1 çàïèñü"; set len ":"} elseif {$ftotal >=2 && $ftotal <=4} {set fnd "$ftotal çàïèñè"; set len ":"} else {set fnd "$ftotal óíèêàëüíûõ çàïèñåé (âñåãî $total)"; set len ". Ïîñëåäíèå 5:"} variable botgender if {$botgender eq "m"} { set fmsg "ÿ íàøåë" } elseif {$botgender eq "w"} { set fmsg "ÿ íàøëà" } else { set fmsg "ÿ íàøëî" } if {![string match "*\\**" $text] && ![string match "*.*" "*$text*"] && ![string match "*\\?*" $text]} { if {![string is space [info command ::vr::out]]} { ::vr::out "$nick, [lindex $results 0] \([format %.2f [expr ([clock clicks -milliseconds] - $::vseen::start_time)/1000.0]] sec.\)" $chan 380 } else { out $nick $chan "[lindex $results 0] \([format %.2f [expr ([clock clicks -milliseconds] - $::vseen::start_time)/1000.0]] sec.\)]" } } else { if {![string is space [info command ::vr::out]]} { ::vr::out "$nick, $fmsg $fnd ïî âàøåìó çàïðîñó$len [join [lrange $founds 0 4] ", "]. [lindex $results 0] \([format %.2f [expr ([clock clicks -milliseconds] - $::vseen::start_time)/1000.0]] sec.\)" $chan 380 } else { out $nick $chan "$fmsg $fnd ïî âàøåìó çàïðîñó$len [join [lrange $founds 0 4] ", "]. [lindex $results 0] \([format %.2f [expr ([clock clicks -milliseconds] - $::vseen::start_time)/1000.0]] sec.\)"} } } proc useronpartyline {user {mode ""}} { if {[llength [bots]] < 2} {return ""} set line "" foreach _ [whom 0] { if {[string equal -nocase $user [lindex $_ 0]]} { set line $_ break } } if {$line eq ""} {return ""} if {[encoding system] ne "cp1251"} {set line [encoding convertfrom cp1251 $line]} if {![string is space [lindex $line end]]} { if {$mode eq ""} {return ". $user âñå åùå òàì, íî â away ([lindex $line end]\017)"} else {return $line} } else { if {$mode eq ""} {return ". $user âñå åùå òàì."} else {return $line} } } proc duration {seconds} { set years [expr {$seconds / 31449600}] set seconds [expr {$seconds % 31449600}] set weeks [expr {$seconds / 604800}] set seconds [expr {$seconds % 604800}] set days [expr {$seconds / 86400}] set seconds [expr {$seconds % 86400}] set hours [expr {$seconds / 3600}] set seconds [expr {$seconds % 3600}] set minutes [expr {$seconds / 60}] set seconds [expr {$seconds % 60}] set res "" if {$years != 0} {lappend res [numstr_spec $years "ëåò" "ãîä" "ãîäà"]} if {$weeks != 0} {lappend res [numstr_spec $weeks "íåäåëü" "íåäåëþ" "íåäåëè"]} if {$days != 0} {lappend res [numstr_spec $days "äíåé" "äåíü" "äíÿ"]} if {$hours != 0} {lappend res [numstr_spec $hours "÷àñîâ" "÷àñ" "÷àñà"]} if {$minutes != 0} {lappend res [numstr_spec $minutes "ìèíóò" "ìèíóòó" "ìèíóòû"]} if {$seconds != 0} {lappend res [numstr_spec $seconds "ñåêóíä" "ñåêóíäó" "ñåêóíäû"]} return [join $res ", "] } proc numstr_spec {val str1 str2 str3} { set d1 [expr $val % 10] set d2 [expr $val % 100] if {$d2 < 10 || $d2 > 19} { if {$d1 == 1} {return "$val $str2"} if {$d1 >= 2 && $d1 <= 4} {return "$val $str3"} } return "$val $str1" } bind bot - gseen_req ::vseen::botreq proc botreq {bot key str} { variable base variable debug set str [split $str] if {[encoding system] ne "cp1251"} {set str [encoding convertfrom cp1251 $str]} #putlog "[lindex $str 0] :: [lindex $str 1] :: [lindex $str 3]" # ZveRs gseen_req ÀëÈñÈê Alex55 ~Alex@irccorp.ru #bot_is74 set text [lindex $str 0] set nick [lindex $str 1] set where [lindex $str 3] #if {($text eq "!enctest!" || [string equal -nocase $text "ÿ߸¨÷×"] || $text eq "!êîäòåñò!") && $bot in {dxb localbot}} {putbot $bot "gseen_rep $nick $where without encoding: òåñò ÿ߸¨÷× :: with 1 encoding: [encoding convertfrom cp1251 "òåñò ÿ߸¨÷×"] :: with 2 encoding: [encoding convertfrom utf-8 [encoding convertto cp1251 "òåñò ÿ߸¨÷×"]]";return} foreach _ [channels] { if {[onchan $text $_] && ![onchansplit $text]} { if {[getchanidle $text $_] > 0} { putbot $bot "gseen_rep $nick $where $text â äàííûé ìîìåíò ñèäèò íà êàíàëå[issecret $_] ([lindex $::network 0]). Ìîë÷èò [duration [expr [getchanidle $text $_] * 60]]." } else { putbot $bot "gseen_rep $nick $where $text â äàííûé ìîìåíò ñèäèò íà êàíàëå[issecret $_] ([lindex $::network 0])." } return 0 } } if {![string is space [set line [useronpartyline $text check]]]} { if {![string is space [lindex $line end]]} {set away ", íî â away ([lindex $line end]\017)."} {set away "."} if {[string is digit [set idle [lindex $line 4]]]} { if {$idle > 0} {set idle " Ìîë÷èò [duration [expr $idle * 60]]."} else {set idle ""} } putbot $bot "gseen_rep $nick $where $text ([lindex $line 2]) ñåé÷àñ â ïàòèëàéíå íà [lindex $line 1]$away$idle" return } variable b_cache if {$b_cache ne "" && [string match "*$text*" "*$b_cache*"]} { putlog "\[vseen\] cached request: $b_cache :: sending to: $bot" putbot $bot "gseen_rep $nick $where $b_cache" return } if {$b_cache ne "" && $b_cache eq "+BUSY+"} { putlog "\[vseen\] cached request: $text, but no results - aborting..." return } set data [search [split $text] 0 ""] set total [expr [llength $data] / 7] if {$data eq "notf"} { if {[validuser [split $text]] && ![string is space [set laston [getuser [split $text] LASTON]]]} { lassign $laston time where_ set lmsg "." if {[validchan $where_] && [set tmppubm [pubmtext $text $where_]] ne 0} { if {[string length $tmppubm] >= 100} {set tmppubm "[string range $tmppubm 0 99]..."} set lmsg ". Ïîñëåäíÿÿ ôðàçà: $tmppubm" } if {[string index $where_ 0] eq "#" && [validchan $where_]} { putbot $bot "gseen_rep $nick $where $nick, $text ïîñëåäíèé ðàç áûë çàìå÷åí â êàíàëå[issecret $where_] [duration [expr [clock seconds] - $time]] íàçàä ([rustime $time])$lmsg" return 0 } elseif {[string index $where_ 0] in {@ * % +}} { putbot $bot "gseen_rep $nick $where $nick, $text ïîñëåäíèé ðàç áûë çàìå÷åí â ïàòèëàéíå ó [string range $where_ 1 end] [duration [expr [clock seconds] - $time]] íàçàä ([rustime $time])." return 0 } } putlog "\[vseen\] botreq: nothing found.; bot: $bot; request: $text îò $nick ([lindex $str 2]) $where" set b_cache "+BUSY+" after 10000 {set ::vseen::b_cache "" putlog "\[vseen\] cache variable cleared..."} return 0 } if {$data eq "max"} { set text_ "óêàæèòå áîëåå æåñòêèå óñëîâèÿ ïîèñêà - ñëèøêîì ìíîãî ñîâïàäåíèé ñ '$text'." putbot $bot "gseen_rep $nick $where $nick, $text_"; return } set i 0 set results [list] set founds [list] set tmp [list] variable maxmatches set tdata [list] foreach {vnick vhost vchan vtime vtype varg1 varg2} $data { set vhost [lindex [split $vhost "!"] end] if {$vnick in $tmp || $vhost in $tmp} {continue} lappend tmp $vnick lappend tmp $vhost lappend tdata [list $vnick $vhost $vchan $vtime $vtype $varg1 $varg2] } set rdata [lrange $tdata 0 4] set ftotal [llength $tdata] foreach _ $rdata { if {[string is space $_]} {continue} lassign $_ vnick vhost vchan vtime vtype varg1 varg2 set vhost [lindex [split $vhost "!"] end] lappend founds $vnick set msg " ." if {[validchan $vchan] && [onchan $varg1 $vchan] && ![onchansplit $varg1] && $text eq $varg1} {set msg ". $varg1 âñå åùå òàì."} if {[validchan $vchan] && [onchan $vnick $vchan] && ![onchansplit $vnick]} {set msg ". $vnick âñå åùå òàì."} if {[set tmppubm [pubmtext $vnick $vchan]] ne 0} { if {[string length $tmppubm] >= 100} {set tmppubm "[string range $tmppubm 0 99]..."} append msg ". Ïîñëåäíÿÿ ôðàçà â êàíàëå: \<$tmppubm\>." unset -nocomplain tmppubm } switch -- $vtype { nick {lappend results "$vnick ($vhost) ïîñëåäíèé ðàç ìåíÿë íèê íà $varg1 â êàíàëå[issecret $vchan] [duration [expr [clock seconds] - $vtime]] íàçàä ([rustime $vtime])$msg"} kick {lappend results "$vnick ($vhost) áûë âûêèíóò èç êàíàëà[issecret $vchan] ïîëüçîâàòåëåì $varg1 ïî ïðè÷èíå \<$varg2\017\> [duration [expr [clock seconds] - $vtime]] íàçàä ([rustime $vtime])$msg"} join {lappend results "$vnick ($vhost) çàõîäèë íà êàíàë[issecret $vchan] [duration [expr [clock seconds] - $vtime]] íàçàä ([rustime $vtime])$msg"} splt {lappend results "$vnick ($vhost) âûõîäèë èç ñåòè èç-çà ñïëèòà ñ êàíàëà[issecret $vchan] [duration [expr [clock seconds] - $vtime]] íàçàä ([rustime $vtime])$msg"} rejn {lappend results "$vnick ($vhost) ïåðåçàõîäèë íà êàíàë[issecret $vchan] èç ñïëèòà [duration [expr [clock seconds] - $vtime]] íàçàä ([rustime $vtime])$msg"} part {if {![string is space $varg1]} {set ptext " ñ ñîîáùåíèåì \<$varg1\017\>"} else {set ptext ""}; lappend results "$vnick ($vhost) ïîêèäàë êàíàë[issecret $vchan] [duration [expr [clock seconds] - $vtime]] íàçàä ([rustime $vtime])$ptext$msg"} sign {if {![string is space $varg1]} {set ptext " ñ ñîîáùåíèåì \<$varg1\017\>"} else {set ptext ""}; lappend results "$vnick ($vhost) âûõîäèë èç ñåòè ñ[issecret $vchan] [duration [expr [clock seconds] - $vtime]] íàçàä ([rustime $vtime])$ptext$msg"} chjn {lappend results "$vnick ($vhost) çàõîäèë â ïàòèëàéí íà $varg1 [duration [expr [clock seconds] - $vtime]] íàçàä ([rustime $vtime])[useronpartyline $vnick]"} chpt {lappend results "$vnick âûõîäèë èç ïàòèëàéí íà $varg1 [duration [expr [clock seconds] - $vtime]] íàçàä ([rustime $vtime])."} default {} } } unset -nocomplain data if {$debug} {putlog "\[vseen\] botreq: sending result to $bot... :: request: $text îò $nick ([lindex $str 2]) $where"} if {$ftotal eq 1} {set fnd "1 çàïèñü"; set len ":"} elseif {$ftotal >=2 && $ftotal <=4} {set fnd "$ftotal çàïèñè"; set len ":"} else {set fnd "$ftotal óíèêàëüíûõ çàïèñåé (âñåãî $total)"; set len ". Ïîñëåäíèå 5:"} variable botgender if {$botgender eq "m"} { set fmsg "ß íàøåë" } elseif {$botgender eq "w"} { set fmsg "ß íàøëà" } else { set fmsg "ß íàøëî" } set outmsg "\[\002[lindex $::network 0]\002\] :: $fmsg $fnd ïî âàøåìó çàïðîñó$len [join [lrange $founds 0 4] ", "]. [lindex $results 0]" putbot $bot "gseen_rep $nick $where $outmsg" set b_cache "\[\002[lindex $::network 0]\002\] :: $fmsg $fnd ïî âàøåìó çàïðîñó$len [join [lrange $founds 0 4] ", "]. [lindex $results 0]" after 30000 {set ::vseen::b_cache ""; putlog "\[vseen\] b_cache variable cleared..."} } bind bot - gseen_rep ::vseen::botrep variable tmpnum 0 proc botrep {bot key text} { variable bchan; variable bnick; variable bnum; variable tmpnum if {[validchan $bchan] && [channel get $bchan novseendata]} {return} #putlog "::vseen::debug:botrep: $bchan :: $bnick :: $bnum :: $tmpnum" if {$bchan eq {} || $bnick eq {}} {return} if {[encoding system] ne "cp1251"} {set text [encoding convertfrom cp1251 $text]} if {[string match -nocase "*íèê*äëèííûé*" $text] || [string match -nocase "*äëèí*à*ëèìèòèðîâàíà*" $text] || [string match -nocase "*ÏÞÅÎØ*ÄÌÉÎÎÙÊ*" $text] || [string match -nocase "*ÄÌÉÎ*Á*ÌÉÍÉÔÉÒÏ×ÁÎÁ*" $text] || [string match -nocase "*length*of*nicks*" $text] || [string match -nocase "*this*nick*is*a*bit*long*" $text] || [string match -nocase "*nolang*" $text]} {return} if {$bnum > 1} { if {[validchan $bchan] && [channel get $bchan quietvseen]} { putserv "NOTICE $bnick :[incr tmpnum]. $bot ñêàçàë: [stripcodes cu [join [lrange [split $text] 2 end]]]" } else { putserv "PRIVMSG $bchan :[incr tmpnum]. $bnick, $bot ñêàçàë: [stripcodes cu [join [lrange [split $text] 2 end]]]" } if {$tmpnum >= $bnum} { set bchan {}; set bnick {}; set tmpnum 0 return } } else { out $bnick $bchan "$bot ñêàçàë: [stripcodes cu [join [lrange [split $text] 2 end]]]" set bchan {}; set bnick {}; set tmpnum 0 } } proc rustime {seconds} { if {$seconds ne ""} { return [clock format $seconds -format "%d.%m.%Y %H:%M:%S"] } } return "\002vseen.tcl\002 v.$version by Vertigo@RusNet loaded." }