wilkowe skrypty dla Eggdropa

Wszystko co chcielibyście wiedzieć o kanale, poznać historię jego powstawania, dowiedzieć się kto nim administruje i jaki jest regulamin, zobaczyć osiągnięcia naszych najlepszych graczy oraz sprawdzić globalny ranking Q-punktów, bądź poczytać kompendium wiedzy o quizach IRC-owych.

Polecenia: IRC, quizbot, statbot, funbot

wilkowe skrypty dla Eggdropa

Postprzez wilk » 10 lutego 2016, 18:40

Może komuś się przydadzą niektóre moje skrypty dla Eggdropa, które napisałem m.in. dla naszego #.

Do pobrania: skrypty dla Eggdropa, inne: skrypty dla irssi, skrypty dla mIRCa.

topicresync.tcl (v1.14) - ustawia ponownie topic po 15 minutach po splicie (bo serwery nie synchronizują topiców i jeśli split był spowodowany np. wyłączeniem serwera, to osoby, które wejdą później z niego na kanał nie będą w ogóle widziały topica). Dodatkowo skrypt zapamiętuje zmiany topica dokonane przez operatorów i w razie gdyby był pusty. to przywraca ostatni zapamiętany stan. Należy ustawić na kanałach, na których ma działać flagę "topicresync" (.chanset #kanal +topicresync). Skrypt dodaje polecenie ".topicresync" dostępne przez partyline.

Kod: Zaznacz cały
# Name      Topic Resync & Recovery after a netsplit
# Author   wilk wilkowy
# Version   1.14 (2015..2018-01-29)
# License   GNU GPL v2 or any later version

# Resync delay, in minutes (0 - instant).
set topres_delay 15

# Protect against floods, in seconds (0 - off).
set topres_antiflood 15

# Resync topic everywhere?
# 1: unless set by @ before timer runs out
# 0: only on channels where someone netsplitted
set topres_everywhere 1

# Default channel topics.
#set topres_default(#channel) "Hello!"

# On/off .chanset flag.
setudef flag topicresync

bind rejn - * topres:check
bind topc o|o * topres:change
bind dcc n|n topicresync topres:dcc

proc topres:dcc {hand idx text} {
   if {$text eq "now"} {
      topres:resync
      return 1
   } elseif {$text eq "info"} {
      topres:info $idx
   } else {
      putdcc $idx "Usage: .topicresync <info/now>"
   }
   return
}

proc topres:cleantxt {text} {
   return [string map {"\002" "B" "\003" "C" "\017" "P" "\026" "R" "\037" "U" "\035" "I"} $text]
}

proc topres:check {nick uhost hand chan} {
   global topres_timer topres_delay topres_flood topres_antiflood topres_resync
   set topres_resync($chan) 1
   set now [unixtime]
   if {[info exists topres_flood] && ($now - $topres_flood) < $topres_antiflood} { return }
   set topres_flood $now
   if {[info exists topres_timer] && [lsearch -glob [timers] "*$topres_timer"] != -1} {
      killtimer $topres_timer
   }
   if {$topres_delay > 0} {
      set topres_timer [timer $topres_delay topres:resync]
   } else {
      topres:resync
   }
   return
}

proc topres:change {nick uhost hand chan topic} {
   global topres_topic topres_resync
   set topres_topic($chan) $topic
   set topres_resync($chan) 0
   return
}

proc topres:resync {} {
   global topres_topic topres_default topres_resync topres_everywhere topres_timer
   if {[info exists topres_timer]} {
      unset topres_timer
   }
   foreach chan [channels] {
      if {![channel get $chan topicresync] || ![botisop $chan]} { continue }
      if {[info exists topres_resync($chan)]} {
         set resync $topres_resync($chan)
      } else {
         set resync $topres_everywhere
      }
      set topres_resync($chan) $topres_everywhere
      if {!$resync} { continue }
      set topic [topic $chan]
      if {$topic ne ""} {
         set ctopic [topres:cleantxt $topic]
         set length [format "%03d" [string length $ctopic]]
         putlog "Topic resync ($chan) \[$length]: $ctopic"
         putserv "TOPIC $chan :$topic"
         set topres_topic($chan) $topic
      } elseif {[info exists topres_topic($chan)] && $topres_topic($chan) ne ""} {
         set ctopic [topres:cleantxt $topres_topic($chan)]
         set length [format "%03d" [string length $ctopic]]
         putlog "Topic recovery ($chan) \[$length]: $ctopic"
         putserv "TOPIC $chan :$topres_topic($chan)"
      } elseif {[info exists topres_default($chan)] && $topres_default($chan) ne ""} {
         set ctopic [topres:cleantxt $topres_default($chan)]
         set length [format "%03d" [string length $ctopic]]
         putlog "Topic default ($chan) \[$length]: $ctopic"
         putserv "TOPIC $chan :$topres_default($chan)"
         set topres_topic($chan) $topres_default($chan)
      }
   }
}

proc topres:info {idx} {
   global topres_topic topres_default
   foreach chan [channels] {
      if {![channel get $chan topicresync]} {
         putdcc $idx "* Channel $chan: (resync disabled)"
      } elseif {[channel get $chan inactive]} {
         putdcc $idx "* Channel $chan: (inactive)"
      } elseif {![botonchan $chan]} {
         putdcc $idx "* Channel $chan: (not on channel)"
      } else {
         set info "* Channel $chan:"
         if {![botisop $chan]} {
            append info " (need ops)"
         }
         putdcc $idx $info
         set topic [topres:cleantxt [topic $chan]]
         set length [format "%03d" [string length $topic]]
         putdcc $idx "| Topic (current) \[$length] : $topic"
         if {[info exists topres_topic($chan)]} {
            set topic [topres:cleantxt $topres_topic($chan)]
            set length [format "%03d" [string length $topic]]
            putdcc $idx "| Topic (backup) \[$length]  : $topic"
         }
         if {[info exists topres_default($chan)]} {
            set topic [topres:cleantxt $topres_default($chan)]
            set length [format "%03d" [string length $topic]]
            putdcc $idx "| Topic (default) \[$length] : $topic"
         }
      }
   }
}

putlog "Topic Resync v1.14 by wilk"

topicupdate.tcl (v1.15) - ten skrypt jest bardziej dla nas tylko — automatyzuje aktualizowanie w topicu informacji o nadchodzącym quizie (czasem o tym zapominaliśmy). Zmienia (zielony) ciąg "\0033Nastepny quiz: nazwa_dnia (dzień.miesiąc)" na: w przeddzień quizu: (czerwony) "\0034Nastepny quiz: jutro", a potem: "jutro" na "dzis". Zmiana następuje o północy. Należy ustawić na kanałach, na których ma on działać flagę "topicupdate" (.chanset #kanal +topicupdate). Skrypt dodaje polecenie ".topicupdate" dostępne przez partyline.

Kod: Zaznacz cały
# Name      Topic Update: date->tomorrow->today
# Author   wilk wilkowy
# Version   1.15 (2015..2018-01-29)
# License   GNU GPL v2 or any later version

# On/off .chanset flag.
setudef flag topicupdate

bind time - "00 00 *" topupd:update
bind dcc n|n topicupdate topupd:dcc

proc topupd:dcc {hand idx text} {
   if {$text eq "now"} {
      topupd:update 0 0 0 0 0
      return 1
   } elseif {$text eq "info"} {
      topupd:info $idx
   } else {
      putdcc $idx "Usage: .topicupdate <info/now>"
   }
   return
}

proc topupd:cleantxt {text} {
   return [string map {"\002" "B" "\003" "C" "\017" "P" "\026" "R" "\037" "U" "\035" "I"} $text]
}

proc topupd:update {minute hour day month year} {
   set now_day [strftime %-d]
   set now_month [strftime %-m]
   foreach chan [channels] {
      if {![channel get $chan topicupdate] || ![botisop $chan]} { continue }
      set topic [topic $chan]
      if {$topic eq ""} { continue }
      set oldtopic $topic
      set update 0
      if {[string match -nocase "*jutro*" $topic]} {
         set topic [string map -nocase {"JUTRO" "DZIS"} $topic]
         regsub -all -nocase -- "\0030?3((?:Nast|Next|Quiz)\[^:\]*?: DZIS )" $topic "\0034\\1" topic
         incr update
      }
      set matches [regexp -all -inline -nocase -- {(?:(?:\mwe? )?(?:poniedzialek|po?n\.|wtorek|wto?\.|srod[ae]|sro?\.|czwartek|czw\.|piatek|piat?\.|pt\.|sobot[ae]|sob\.|niedziel[ae]|nie\.|niedz\.) )?\(([0-3]?[0-9])[./]([01]?[0-9])\)} $topic]
      foreach {match event_day event_month} $matches {
         set event_day [scan $event_day %d]
         set event_month [scan $event_month %d]
         set prev_day [expr {$event_day - 1}]
         set prev_month $event_month
         set prev_year [strftime %Y]
         if {$prev_day == 0} {
            incr prev_month -1
            if {$prev_month == 0} {
               set prev_month 12
               incr prev_year -1
            }
            if {$prev_month == 2} {
               set prev_day 28
               if {($prev_year % 4 == 0 && $prev_year % 100 != 0) || $prev_year % 400 == 0} {
                  incr prev_day 1
               }
            } elseif {$prev_month in [list 1 3 5 7 8 10 12]} {
               set prev_day 31
            } else {
               set prev_day 30
            }
         }
         set soon ""
         if {$now_day == $prev_day && $now_month == $prev_month} {
            set soon "JUTRO"
         } elseif {$now_day == $event_day && $now_month == $event_month} {
            set soon "DZIS"
         }
         if {$soon ne ""} {
            set topic [string map -nocase [list $match $soon] $topic]
            regsub -nocase -- "\0030?3((?:Nast|Next|Quiz)\[^:\]*?: )" $topic "\0034\\1" topic
            incr update
         }
      }
      if {$update} {
         putlog "Topic update ($chan) from: $oldtopic"
         putlog "Topic update ($chan) to  : $topic"
         putserv "TOPIC $chan :$topic"
      }
   }
   return
}

proc topupd:info {idx} {
   foreach chan [channels] {
      if {![channel get $chan topicupdate]} {
         putdcc $idx "* Channel $chan: (update disabled)"
      } elseif {[channel get $chan inactive]} {
         putdcc $idx "* Channel $chan: (inactive)"
      } elseif {![botonchan $chan]} {
         putdcc $idx "* Channel $chan: (not on channel)"
      } else {
         set info "* Channel $chan:"
         if {![botisop $chan]} {
            append info " (need ops)"
         }
         putdcc $idx $info
         set topic [topupd:cleantxt [topic $chan]]
         set length [format "%03d" [string length $topic]]
         putdcc $idx "| Topic \[$length] : $topic"
      }
   }
}

putlog "Topic Update v1.15 by wilk"

autolimit.tcl (v1.12) - automatycznie pilnuje limitu kanałowego (ochrona przed mass-joinem). Sposób działania skryptu bazuje na rozwiązaniu zaimplementowanym w bocie IRC-owym Psotnic (przy którego powstawaniu nota bene też miałem swój wkład). W przeciwieństwie do klasycznych skryptów, które aktualizują na sztywno limit co kilka minut — tutaj wyzwalaczem timerów jest wejście/zniknięcie z kanału. Dodatkowo są osobne timery dla zwiększania limitu i zmniejszania (obniża szybciej) oraz osobny dla zmian wprowadzonych przez ownera kanału. Na których ma działać należy ustawić flagę "autolimit" (.chanset #kanal +autolimit). Ponadto dostępna jest funkcja włączana flagą kanałową "lockdown", która ustawia na kanale flagę "i" w chwili wejścia maksymalnej liczby osób dopuszczonej bieżącym limitem - pozwala ona ochronić kanał przed atakami klonów robiącymi wielokrotne join/part. Skrypt dodaje też polecenie ".autolimit" dostępne z poziomu partyline.

Kod: Zaznacz cały
# Name      Auto-Limit (based on Psotnic limiter)
# Author   wilk wilkowy
# Version   1.12 (2016..2018-01-29)
# License   GNU GPL v2 or any later version

# Limit update latency in seconds - new user (0 - instant, min:max notation allowed).
set alimit_delay_up 120

# Limit update latency in seconds - gone user (0 - instant, min:max notation allowed).
set alimit_delay_down 30

# Limit update latency in seconds - bot got opped (0 - instant, -1 - ignore, min:max notation allowed).
set alimit_delay_gotop 5

# Limit update latency in seconds - server mode change (netsplit) (0 - instant, -1 - ignore, min:max notation allowed).
set alimit_delay_server 5

# Limit update latency in seconds - owner mode change (0 - instant, -1 - ignore, min:max notation allowed).
set alimit_delay_owner -1

# Limit update latency in seconds - bot mode change (0 - instant, -1 - ignore, min:max notation allowed).
set alimit_delay_bot 120

# Limit update latency in seconds - @ mode change (0 - instant, -1 - ignore, min:max notation allowed).
set alimit_delay_op 0

# Limit update latency in seconds - someone else mode change (0 - instant, -1 - ignore, min:max notation allowed).
set alimit_delay_unknown 0

# Keep this amount of free limit space for users.
set alimit_offset 5

# Limit tolerance to reduce amount of unnecessary updates (<0 - percent of offset, >0 - static, 0 - off).
set alimit_tolerance -50

# Protect against event floods, in seconds (0 - off).
set alimit_antiflood 15

# Lockdown duration in seconds (0 - off). Lockdown closes the channel (+i) to prevent join/part floods with clones.
set alimit_lockdown_time 15

# On/off .chanset flags.
setudef flag autolimit
setudef flag lockdown

bind join - * alimit:join
#bind rejn - * alimit:netjoin
bind part - * alimit:part
bind sign - * alimit:quit
bind kick - * alimit:kick
bind mode - *+l* alimit:mode
bind mode - *-l* alimit:mode
bind mode - *+o* alimit:mode
bind dcc n|n autolimit alimit:dcc

proc alimit:dcc {hand idx text} {
   if {$text eq "info"} {
      alimit:info $idx
   } elseif {$text eq "now"} {
      foreach chan [channels] {
         alimit:update $chan
      }
      return 1
   } elseif {$text eq "now!"} {
      foreach chan [channels] {
         alimit:update $chan 1
      }
      return 1
   } elseif {[validchan $text]} {
      alimit:update $text 1
      return 1
   } else {
      putdcc $idx "Usage: .autolimit <info/now/now!/#>"
   }
   return
}

proc alimit:getdelay {value} {
   set time [split $value ":"]
   if {[llength $time] > 1} {
      set min [lindex $time 0]
      set max [lindex $time 1]
      if {$min > $max} {
         foreach {min max} [list $max $min] {break}
      }
      return [expr {[rand [expr {$max + 1 - $min}]] + $min}]
   } else {
      return $value
   }
}

proc alimit:getlimit {chan} {
   set modes [split [getchanmode $chan]]
   if {[string match *l* [lindex $modes 0]]} {
      return [lindex $modes end]
   } else {
      return ""
   }
}

proc alimit:islocked {chan} {
   return [string match *i* [lindex [split [getchanmode $chan]] 0]]
}

proc alimit:join {nick uhost hand chan} {
   global alimit_delay_up alimit_lockdown_time alimit_lockdown
   set users [llength [chanlist $chan]]
   set limit [alimit:getlimit $chan]
   if {$limit ne "" && $users >= $limit} {
      if {$alimit_lockdown_time > 0 && [channel get $chan lockdown] && [botisop $chan] && ![alimit:islocked $chan] && (![info exists alimit_lockdown($chan)] || $alimit_lockdown($chan) == 0)} {
         set alimit_lockdown($chan) 1
         pushmode $chan +i
         flushmode $chan
         putlog "Channel is full ($chan/$users:$limit) - lockdown!"
         utimer $alimit_lockdown_time [list alimit:unlock $chan]
      } else {
         putlog "Channel is full ($chan/$users:$limit)!"
      }
   }
   alimit:change $chan $alimit_delay_up
   return
}

proc alimit:unlock {chan} {
   global alimit_lockdown
   set alimit_lockdown($chan) 0
   pushmode $chan -i
   set users [llength [chanlist $chan]]
   set limit [alimit:getlimit $chan]
   putlog "Lockdown lifted ($chan/$users:$limit)"
}

proc alimit:part {nick uhost hand chan {msg ""}} {
   global alimit_delay_down
   alimit:change $chan $alimit_delay_down
   return
}

proc alimit:quit {nick uhost hand chan why} {
   global alimit_delay_down
   alimit:change $chan $alimit_delay_down
   return
}

proc alimit:kick {nick uhost hand chan whom why} {
   global alimit_delay_down
   alimit:change $chan $alimit_delay_down
   return
}

proc alimit:mode {nick uhost hand chan mode whom} {
   global alimit_delay_server alimit_delay_gotop alimit_delay_owner alimit_delay_bot alimit_delay_op alimit_delay_unknown
   if {[isbotnick $nick] || ![botisop $chan]} { return }
   if {$mode eq "+o" && [isbotnick $whom]} {
      if {$alimit_delay_gotop < 0} { return }
      alimit:change $chan $alimit_delay_gotop 1
   } elseif {($mode eq "-l" || $mode eq "+l")} {
      set enforce 0
      if {$nick eq "" && $hand eq "*"} {
         if {$alimit_delay_server < 0} { return }
         set delay $alimit_delay_server
         if {$mode eq "-l"} { set enforce 1 }
      } elseif {$hand ne "" && $hand ne "*" && [matchattr $hand b|- $chan]} {
         if {$alimit_delay_bot < 0} { return }
         set delay $alimit_delay_bot
      } elseif {$hand ne "" && $hand ne "*" && [matchattr $hand n|n $chan]} {
         if {$alimit_delay_owner < 0} { return }
         set delay $alimit_delay_owner
      } elseif {$hand ne "" && $hand ne "*" && [matchattr $hand o|o $chan]} {
         if {$alimit_delay_op < 0} { return }
         set delay $alimit_delay_op
         if {$mode eq "-l"} { set enforce 1 }
      } else {
         if {$alimit_delay_unknown < 0} { return }
         set delay $alimit_delay_unknown
         if {$mode eq "-l"} { set enforce 1 }
      }
      alimit:change $chan $delay 1 $enforce
   }
   return
}

proc alimit:change {chan delay {nocheck 0} {enforce 0}} {
   global alimit_timer alimit_flood alimit_antiflood
   set now [unixtime]
   if {!$nocheck && [info exists alimit_flood($chan)] && ($now - $alimit_flood($chan)) < $alimit_antiflood} { return }
   set alimit_flood($chan) $now
   if {[info exists alimit_timer($chan)] && [lsearch -glob [utimers] "*$alimit_timer($chan)"] != -1} {
      killutimer $alimit_timer($chan)
   }
   set delay [alimit:getdelay $delay]
   if {$delay > 0} {
      set alimit_timer($chan) [utimer $delay [list alimit:update $chan $enforce]]
   } else {
      alimit:update $chan $enforce
   }
}

proc alimit:update {chan {enforce 0}} {
   global alimit_offset alimit_tolerance alimit_limit alimit_timer
   if {[info exists alimit_timer($chan)]} {
      unset alimit_timer($chan)
   }
   if {![channel get $chan autolimit] || ![botisop $chan]} { return }
   set users [llength [chanlist $chan]]
   set limit [alimit:getlimit $chan]
   set new_limit [expr {$users + $alimit_offset}]
   if {$limit ne "" && $new_limit == $limit && !$enforce} { return }
   if {$alimit_tolerance >= 0} {
      set tolerance $alimit_tolerance
   } else {
      set tolerance [expr {int($alimit_offset * $alimit_tolerance / -100.0)}]
   }
   if {$enforce || $limit eq "" || $limit < $users + $alimit_offset - $tolerance || $limit > $users + $alimit_offset + $tolerance} {
      if {$limit eq ""} {
         set limit "none"
      }
      putlog "Limit change ($chan/$users): $limit -> $new_limit"
      pushmode $chan +l $new_limit
      set alimit_limit($chan) $new_limit
      #flushmode $chan
   }
}

proc alimit:info {idx} {
   global alimit_tolerance alimit_offset alimit_timer
   foreach chan [channels] {
      if {![channel get $chan autolimit]} {
         putdcc $idx "* Channel $chan: (autolimit disabled)"
      } elseif {[channel get $chan inactive]} {
         putdcc $idx "* Channel $chan: (inactive)"
      } elseif {![botonchan $chan]} {
         putdcc $idx "* Channel $chan: (not on channel)"
      } else {
         set info "* Channel $chan:"
         if {![botisop $chan]} {
            append info " (need ops)"
         }
         putdcc $idx $info
         if {$alimit_tolerance >= 0} {
            set tolerance $alimit_tolerance
         } else {
            set tolerance [expr {int($alimit_offset * $alimit_tolerance / -100.0)}]
         }
         set limit [alimit:getlimit $chan]
         set users [llength [chanlist $chan]]
         set range "NOONE"
         if {$limit eq ""} {
            set range "ANYONE"
         } elseif {$limit > 0} {
            set min [expr {$limit - $alimit_offset - $tolerance}]
            set max [expr {$limit - $alimit_offset + $tolerance}]
            set range "$min..$max"
         }
         putdcc $idx "| Users : $users \[current limit allows: $range]"
         set exp [expr {$users + $alimit_offset}]
         set min [expr {$exp - $tolerance}]
         set max [expr {$exp + $tolerance}]
         set status "ok"
         if {$limit eq "" || $limit < $min || $limit > $max} { set status "update required" }
         if {[info exists alimit_timer($chan)]} {
            set timers [utimers]
            set timer [lsearch -glob $timers "*$alimit_timer($chan)"]
            if {$timer != -1} {
               append status ", update in [lindex $timers $timer 0]s"
               if {[lindex $timers $timer 1 2] == 1} { append status ", forced" }
            }
         }
         if {$limit eq ""} {
            set limit "none"
         }
         putdcc $idx "| Limit : $limit \[expected: $exp, tolerance: $min..$max] ($status)"
      }
   }
}

putlog "Auto Limit v1.12 by wilk"

pcc.tcl (v1.8) - zestaw poleceń kanałowych do obsługi bota czy pozwalających wybranym użytkownikom np. na dawanie plusików, bez posiadania opa. Na kanałach, na których ma działać należy ustawić flagę "chancmds" (.chanset #kanal +chancmds).

Kod: Zaznacz cały
# Name      Public Channel Commands
# Author   wilk wilkowy
# Version   1.8 (2007..2017-01-09)
# License   GNU GPL v2 or any later version

set pcc_char "!"

setudef flag chancmds

bind pub m|m ${pcc_char}o pcc:op
bind pub m|m ${pcc_char}op pcc:op
bind pub m|m ${pcc_char}do pcc:deop
bind pub m|m ${pcc_char}deop pcc:deop

bind pub v|v ${pcc_char}v pcc:voice
bind pub v|v ${pcc_char}voice pcc:voice
bind pub v|v ${pcc_char}dv pcc:devoice
bind pub v|v ${pcc_char}devoice pcc:devoice

bind pub o|o ${pcc_char}k pcc:kick
bind pub o|o ${pcc_char}kick pcc:kick
bind pub m|m ${pcc_char}b pcc:ban
bind pub m|m ${pcc_char}ban pcc:ban
bind pub m|m ${pcc_char}kb pcc:kban
bind pub m|m ${pcc_char}kickban pcc:kban
bind pub m|m ${pcc_char}ub pcc:unban
bind pub m|m ${pcc_char}unban pcc:unban

bind pub o|o ${pcc_char}t pcc:topic
bind pub o|o ${pcc_char}topic pcc:topic
bind pub n|n ${pcc_char}m pcc:mode
bind pub n|n ${pcc_char}mode pcc:mode
bind pub m|m ${pcc_char}s pcc:shutup
bind pub m|m ${pcc_char}silence pcc:shutup
bind pub m|m ${pcc_char}shutup pcc:shutup
bind pub m|m ${pcc_char}l pcc:ulimit
bind pub m|m ${pcc_char}limit pcc:ulimit
bind pub m|m ${pcc_char}ulimit pcc:ulimit
bind pub m|m ${pcc_char}unlimit pcc:ulimit
bind pub n|n ${pcc_char}lock pcc:lock
bind pub n|n ${pcc_char}unlock pcc:unlock

bind pub n|- ${pcc_char}au pcc:adduser
bind pub n|- ${pcc_char}+user pcc:adduser
bind pub n|- ${pcc_char}adduser pcc:adduser
bind pub n|- ${pcc_char}du pcc:deluser
bind pub n|- ${pcc_char}-user pcc:deluser
bind pub n|- ${pcc_char}deluser pcc:deluser
bind pub n|- ${pcc_char}ah pcc:addhost
bind pub n|- ${pcc_char}+host pcc:addhost
bind pub n|- ${pcc_char}addhost pcc:addhost

bind pub n|- ${pcc_char}rehash pcc:rehash
bind pub n|- ${pcc_char}restart pcc:restart
bind pub n|- ${pcc_char}reload pcc:reload
bind pub n|- ${pcc_char}save pcc:save
bind pub n|- ${pcc_char}backup pcc:backup
bind pub n|- ${pcc_char}die pcc:die

bind pub n|n ${pcc_char}jump pcc:jump

proc pcc:adduser {nick host hand chan text} {
   if {![pcc:ok_usr $nick $chan 0]} { return 0 }
   set _who [pcc:getarg $text]
   if {![validuser $_who]} {
      putcmdlog "<<$nick>> !$hand! adduser $_who"
      adduser $_who
   }
}

proc pcc:deluser {nick host hand chan text} {
   if {![pcc:ok_usr $nick $chan 0]} { return 0 }
   set _who [pcc:getarg $text]
   if {[validuser $_who]} {
      putcmdlog "<<$nick>> !$hand! deluser $_who"
      deluser $_who
   }
}

proc pcc:addhost {nick host hand chan text} {
   if {![pcc:ok_usr $nick $chan 0]} { return 0 }
   set _who [pcc:getarg $text]
   if {[validuser $_who]} {
      set _host [pcc:getarg $text 1]
      putcmdlog "<<$nick>> !$hand! addhost $_who $_host"
      setuser $_who HOSTS $_host
   }
}

proc pcc:op {nick host hand chan text} {
   if {![pcc:ok_bot $chan]} { return 0 }
   if {[llength $text] < 1 && ![isop $nick $chan]} {
      putcmdlog "<<$nick>> !$hand! op $chan $nick"
      pushmode $chan +o $nick
      #flushmode $chan
   } else {
      set _who ""
      foreach _nick [split [pcc:strcln $text]] {
         if {[onchan $_nick $chan] && ![isop $_nick $chan]} {
            append _who "$_nick "
            pushmode $chan +o $_nick
         }
      }
      #if {$_who ne ""} {
         putcmdlog "<<$nick>> !$hand! op $chan [string trimright $_who] ($text)"
         #flushmode $chan
      #}
   }
}

proc pcc:deop {nick host hand chan text} {
   if {![pcc:ok_bot $chan]} { return 0 }
   if {[llength $text] < 1 && [isop $nick $chan]} {
      putcmdlog "<<$nick>> !$hand! deop $chan $nick"
      pushmode $chan -o $nick
      #flushmode $chan
   } else {
      set _who ""
      set _lvl [pcc:getlvl $hand $chan]
      foreach _nick [split [pcc:strcln $text]] {
         if {[onchan $_nick $chan] && ![isbotnick $_nick] && [isop $_nick $chan]} {
            if {$_lvl >= [pcc:getlvl [nick2hand $_nick] $chan]} {
               append _who "$_nick "
               pushmode $chan -o $_nick
            }
         }
      }
      #if {$_who ne ""} {
         putcmdlog "<<$nick>> !$hand! deop $chan [string trimright $_who] ($text)"
         #flushmode $chan
      #}
   }
}

proc pcc:voice {nick host hand chan text} {
   if {![pcc:ok_bot $chan]} { return 0 }
   if {[llength $text] < 1 && ![isop $nick $chan] && ![isvoice $nick $chan]} {
      putcmdlog "<<$nick>> !$hand! voice $chan $nick"
      pushmode $chan +v $nick
      #flushmode $chan
   } else {
      set _who ""
      foreach _nick [split [pcc:strcln $text]] {
         if {[onchan $_nick $chan] && ![isop $_nick $chan] && ![isvoice $_nick $chan]} {
            append _who "$_nick "
            pushmode $chan +v $_nick
         }
      }
      #if {$_who ne ""} {
         putcmdlog "<<$nick>> !$hand! voice $chan [string trimright $_who] ($text)"
         #flushmode $chan
      #}
   }
}

proc pcc:devoice {nick host hand chan text} {
   if {![pcc:ok_bot $chan]} { return 0 }
   if {[llength $text] < 1 && [isvoice $nick $chan]} {
      putcmdlog "<<$nick>> !$hand! devoice $chan $nick"
      pushmode $chan -v $nick
      #flushmode $chan
   } else {
      set _who ""
      foreach _nick [split [pcc:strcln $text]] {
         if {[onchan $_nick $chan] && [isvoice $_nick $chan]} {
            append _who "$_nick "
            pushmode $chan -v $_nick
         }
      }
      #if {$_who ne ""} {
         putcmdlog "<<$nick>> !$hand! devoice $chan [string trimright $_who] ($text)"
         #flushmode $chan
      #}
   }
}

proc pcc:kick {nick host hand chan text} {
   if {![pcc:ok_bot $chan] || [llength $text] < 1} { return 0 }
   set _text [split [string trim $text]]
   set _who [lindex $_text 0]
   if {[onchan $_who $chan] && ![isbotnick $_who]} {
      if {[llength $_text] > 1} {
         set _reason "[join [lrange $_text 1 end]] - "
      }
      append _reason "requested by: $nick"
      if {[pcc:getlvl $hand $chan] >= [pcc:getlvl [nick2hand $_who] $chan]} {
         putcmdlog "<<$nick>> !$hand! kick $chan $_who $_reason"
         putkick $chan $_who $_reason
      }
   }
}

proc pcc:topic {nick host hand chan text} {
   if {![pcc:ok_bot $chan] || [llength $text] < 1} { return 0 }
   putcmdlog "<<$nick>> !$hand! topic $chan $text"
   putserv "TOPIC $chan :$text"
}

proc pcc:mode {nick host hand chan text} {
   if {![pcc:ok_bot $chan] || [llength $text] < 1} { return 0 }
   set _mode [lrange [split [pcc:strcln $text]] 0 6]
   putcmdlog "<<$nick>> !$hand! mode $chan $_mode"
   putserv "MODE $chan :$_mode"
}

proc pcc:shutup {nick host hand chan text} {
   if {![pcc:ok_bot $chan] || [llength $text] < 1} { return 0 }
   set _who [pcc:getarg $text]
   if {$_who ne "" && [onchan $_who $chan] && ![isbotnick $_who] && $_who != $nick} {
      if {![isvoice $nick $chan] && ![isop $nick $chan]} {
         pushmode $chan +v $nick
      }
      if {[isvoice $_who $chan]} {
         pushmode $chan -v $_who
      }
      if {[isop $_who $chan]} {
         pushmode $chan -o $_who
      }
      pushmode $chan +m
      putcmdlog "<<$nick>> !$hand! shutup $chan $_who"
   }
}

proc pcc:lock {nick host hand chan text} {
   if {![pcc:ok_bot $chan]} { return 0 }
   putcmdlog "<<$nick>> !$hand! mode $chan +im"
   pushmode $chan +im
}

proc pcc:unlock {nick host hand chan text} {
   if {![pcc:ok_bot $chan]} { return 0 }
   putcmdlog "<<$nick>> !$hand! mode $chan -im"
   pushmode $chan -im
}

proc pcc:ban {nick host hand chan text} {
   if {![pcc:ok_bot $chan] || [llength $text] < 1} { return 0 }
   set _text [split [string trim $text]]
   set _who [lindex $_text 0]
   if {[isbotnick $_who]} { return 0 }
   if {[onchan $_who $chan]} {
      if {[pcc:getlvl $hand $chan] >= [pcc:getlvl [nick2hand $_who] $chan]} {
         set _mask [maskhost [getchanhost $_who $chan]]
         #set _mask "*!*[lindex [split $_mask "!"] 1]"
      }
   } else {
      set _mask $_who
   }
   if {[llength $_text] > 1} {
      set _reason "[join [lrange $_text 1 end]] - "
   }
   append _reason "requested by: $nick"
   putcmdlog "<<$nick>> !$hand! ban $text"
   newchanban $chan $_mask $nick $_reason
}

proc pcc:kban {nick host hand chan text} {
   if {![pcc:ok_bot $chan] || [llength $text] < 1} { return 0 }
   set _text [split [string trim $text]]
   set _who [lindex $_text 0]
   if {[isbotnick $_who]} { return 0 }
   if {[onchan $_who $chan]} {
      if {[pcc:getlvl $hand $chan] >= [pcc:getlvl [nick2hand $_who] $chan]} {
         set _mask [maskhost [getchanhost $_who $chan]]
         #set _mask "*!*[lindex [split $_mask "!"] 1]"
         if {[llength $_text] > 1} {
            set _reason "[join [lrange $_text 1 end]] - "
         }
         append _reason "requested by: $nick"
         putcmdlog "<<$nick>> !$hand! kickban $text"
         newchanban $chan $_mask $nick $_reason
         putkick $chan $_who $_reason
      }
   }
}

proc pcc:unban {nick host hand chan text} {
   if {![pcc:ok_bot $chan] || [llength $text] < 1} { return 0 }
   set _mask [pcc:getarg $text]
   if {![ischanban $_mask $chan]} { return 0 }
   putcmdlog "<<$nick>> !$hand! unban $chan $_mask"
   killchanban $chan $_mask
   #pushmode $chan -b $_mask
}

proc pcc:rehash {nick host hand chan text} {
   if {![pcc:ok_usr $nick $chan]} { return 0 }
   putcmdlog "<<$nick>> !$hand! rehash"
   rehash
}

proc pcc:restart {nick host hand chan text} {
   if {![pcc:ok_usr $nick $chan]} { return 0 }
   putcmdlog "<<$nick>> !$hand! restart"
   restart
}

proc pcc:backup {nick host hand chan text} {
   if {![pcc:ok_usr $nick $chan]} { return 0 }
   putcmdlog "<<$nick>> !$hand! backup"
   backup
}

proc pcc:save {nick host hand chan text} {
   if {![pcc:ok_usr $nick $chan]} { return 0 }
   putcmdlog "<<$nick>> !$hand! save"
   save
}

proc pcc:reload {nick host hand chan text} {
   if {![pcc:ok_usr $nick $chan]} { return 0 }
   putcmdlog "<<$nick>> !$hand! reload"
   reload
}

proc pcc:die {nick host hand chan text} {
   if {![pcc:ok_usr $nick $chan]} { return 0 }
   if {[llength $text] < 1} { set text "requested by: $nick" }
   putcmdlog "<<$nick>> !$hand! die $text"
   die $text
}

proc pcc:jump {nick host hand chan text} {
   if {![pcc:ok_usr $nick $chan]} { return 0 }
   set _srv [pcc:getarg $text]
   putcmdlog "<<$nick>> !$hand! jump $_srv"
   jump $_srv
}

proc pcc:ulimit {nick host hand chan text} {
   if {![pcc:ok_bot $chan]} { return 0 }
   putcmdlog "<<$nick>> !$hand! limit $chan -l"
   pushmode $chan -l
}

proc pcc:getlvl {hand chan} {
   set _lvl 0
   if {$hand ne "*" && $hand ne ""} {
      if {[matchattr $hand v|v $chan]} { set _lvl [expr {$_lvl | 0x01}] }
      if {[matchattr $hand o|o $chan]} { set _lvl [expr {$_lvl | 0x02}] }
      if {[matchattr $hand -|m $chan]} { set _lvl [expr {$_lvl | 0x04}] }
      if {[matchattr $hand m|- $chan]} { set _lvl [expr {$_lvl | 0x08}] }
      if {[matchattr $hand -|n $chan]} { set _lvl [expr {$_lvl | 0x10}] }
      if {[matchattr $hand n|- $chan]} { set _lvl [expr {$_lvl | 0x20}] }
      if {[matchattr $hand f|f $chan]} { set _lvl [expr {$_lvl | 0x40}] }
   }
   return $_lvl
}

proc pcc:ok_bot {chan {needop 1}} {
   if {[channel get $chan chancmds] != 1} { return 0 }
   if {$needop && ![botisop $chan]} { return 0 }
   return 1
}

proc pcc:ok_usr {nick chan {needop 1}} {
   if {[channel get $chan chancmds] != 1} { return 0 }
   if {$needop && ![isop $nick $chan]} { return 0 }
   return 1
}

proc pcc:strcln {text} {
   return [string trim [regsub -all -- " +" $text " "]]
}

proc pcc:getarg {text {idx 0}} {
   return [lindex [split [pcc:strcln $text]] $idx]
}

putlog "Public Channel Commands v1.8 by wilk"

urltitle.tcl (v1.5) - po wklejeniu na kanał odnośnika skrypt pobiera i wyświetla na kanale tytuł podlinkowanej strony. Na kanałach, na których ma działać należy ustawić flagę "urltitle" (.chanset #kanal +urltitle).

Kod: Zaznacz cały
# Name      Display URL Title
# Author   wilk wilkowy
# Version   1.5 (2018..2018-02-22)
# License   GNU GPL v2 or any later version

# Users having this flags are ignored.
set urltitle_ignored "I|I"

# Users having this flags can trigger script.
set urltitle_allowed "-|-"

# Limit title length (0 - off).
set urltitle_max_length 0

# Protect against floods, in seconds (0 - off).
set urltitle_antiflood 10

# This is how script introduces itself to servers, chosen randomly.
set urltitle_agent [list "Mozilla/5.0 (X11; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0"]

# Website fetching timeout, in miliseconds.
set urltitle_timeout 5000

# Max depth for 301/302 redirections.
set urltitle_max_depth 5

# On/off .chanset flag.
setudef flag urltitle

bind pubm $urltitle_allowed {*://*} urltitle:fetch
bind pubm $urltitle_allowed {*www.*} urltitle:fetch

package require http
if {![catch {set urltitle_tlsver [package require tls]}]} {
   set urltitle_tls 1
   if {[package vcompare $urltitle_tlsver 1.6.4] < 0} {
      putlog "URL Title: tls package version <1.6.4 = no SNI support, some HTTPS links will not work properly"
   }
} else {
   set urltitle_tls 0
   putlog "URL Title: no tls package = no SSL/TLS support (HTTPS protocol)"
}
if {![catch {package require htmlparse}]} {
   set urltitle_htmlparse 1
} else {
   set urltitle_htmlparse 0
   putlog "URL Title: no htmlparse package = no escape sequences substitution"
}

proc urltitle:tlssocket {args} {
   global urltitle_tlsver
   set opts [lrange $args 0 end-2]
   set host [lindex $args end-1]
   set port [lindex $args end]
   if {[package vcompare $urltitle_tlsver 1.7.11] >= 0} {
      ::tls::socket -tls1 1 -tls1.1 1 -tls1.2 1 -ssl3 0 -ssl2 0 -autoservername 1 {*}$opts $host $port
   } elseif {[package vcompare $urltitle_tlsver 1.6.4] >= 0} {
      ::tls::socket -tls1 1 -tls1.1 1 -tls1.2 1 -ssl3 0 -ssl2 0 -servername $host {*}$opts $host $port
   } else {
      ::tls::socket -tls1 1 -ssl3 0 -ssl2 0 {*}$opts $host $port
   }
}

proc urltitle:gethtml {query depth {referer ""} {cookies ""}} {
   global urltitle_tls urltitle_agent urltitle_timeout urltitle_state
   if {[string length $query] == 0 || $depth < 0} { return "" }
   if {[string match -nocase "www.*" $query]} {
      set query "http://$query"
   }
   if {$urltitle_tls && [string match -nocase "https://*" $query]} {
      ::http::register https 443 urltitle:tlssocket
   }
   #-accept "text/html"
   ::http::config -useragent [lindex $urltitle_agent [rand [llength $urltitle_agent]]]
   if {[llength $cookies] > 0} {
      catch { set http [::http::geturl $query -timeout $urltitle_timeout -headers [list "Referer" $referer "Cookie" [string trim [join $cookies ";"] ";"]]] } httperror
   } else {
      catch { set http [::http::geturl $query -timeout $urltitle_timeout] } httperror
   }
   if {![info exists http]} {
      putlog "URL Title: connection error for $query ($httperror)"
      return ""
   }
   set status [::http::status $http]
   set code [::http::ncode $http]
   set html ""
   if {$status eq "ok"} {
      upvar #0 $http state
      array set urltitle_state [array get state]
      if {$code in [list 301 302 303 307]} {
         set redir ""
         set cook [list]
         foreach {name value} $state(meta) {
            if {[string equal -nocase "Location" $name]} {
               set redir $value
            } elseif {[string equal -nocase "Set-Cookie" $name]} {
               lappend cook [lindex [split $value ";"] 0]
            }
         }
         if {[llength $cook] == 0} {
            set cook $cookies
         }
         if {$redir ne ""} {
            ::http::cleanup $http
            if {$urltitle_tls} {
               #::http::unregister https
            }
            set addr ""
            if {[regexp -nocase {^https?://[^/&?]+?} $query addr] && ![regexp -nocase {^https?://} $redir]} {
               #array set parts [uri::split $query]
               #set redir "$parts(scheme)://$parts(host)$redir"
               set redir "$addr$redir"
            }
            #tailcall?
            return [urltitle:gethtml $redir [expr {$depth - 1}] $addr $cook]
         }
      }
      if {[string match -nocase "text/html*" $state(type)]} {
         set html [::http::data $http]
      } else {
         putlog "URL Title: invalid content-type for $query ($state(type))"
      }
   } else {
      putlog "URL Title: connection failed for $query ($status)"
   }
   ::http::cleanup $http
   if {$urltitle_tls} {
      #::http::unregister https
   }
   return $html
}

proc urltitle:recode {title} {
   global urltitle_state
   set charset_m [set charset_b [set charset ""]]
   if {[regexp -nocase {<meta[^>]+?charset="?([^"]+?)"} $urltitle_state(body) match charset]} { ;#"
      set charset_m [::http::CharsetToEncoding $urltitle_state(charset)]
      set charset_b [::http::CharsetToEncoding $charset]
   }
   if {![string equal -nocase $charset_m $charset_b] && $charset_b ne "" && $charset_b ne "binary"} {
      set title [encoding convertfrom $charset_b $title]
   }
   return $title
}

proc urltitle:gettitle {query} {
   global urltitle_htmlparse urltitle_max_depth
   set html [string map {"\r" "" "\n" ""} [urltitle:gethtml $query $urltitle_max_depth]]
   set title ""
   if {![regexp -nocase {<title[^>]*?>([^<>]*?)</title>} $html match title]} { return "" }
   if {[string match -nocase "*youtube.com/*" $query] || [string match -nocase "*youtu.be/*" $query]} {
      set yttitle ""
      if {[regexp -nocase {document\.title\s*?=\s*?"([^"]*?)"\s*?;} $html match yttitle]} { ;#"
         append title " :: $yttitle"
      } elseif {[regexp -nocase {"title":"([^"]*?)"} $html match yttitle]} { ;#"
         append title " :: $yttitle"
      }
   }
   if {$urltitle_htmlparse} {
      set title [::htmlparse::mapEscapes $title]
   }
   return [urltitle:recode $title]
}

proc urltitle:fetch {nick host hand chan text} {
   global urltitle_ignored urltitle_flood urltitle_antiflood urltitle_max_length
   if {![channel get $chan urltitle] || [matchattr $hand $urltitle_ignored $chan]} { return }
   set now [unixtime]
   if {[info exists urltitle_flood] && ($now - $urltitle_flood) < $urltitle_antiflood} { return }
   set urltitle_flood $now
   foreach token [split $text] {
      if {![regexp -nocase {^(?:https?://|www\.)} $token] || [regexp -nocase {^https?://\[} $token] || [regexp -nocase {^(?:https?://|www\.)[^/:]+?:} $token] } { continue }
      set title [string trim [regsub -all {\s+} [urltitle:gettitle $token] " "]]
      if {$urltitle_max_length > 0 && [string length $title] > $urltitle_max_length} {
         set ctitle [string range $title 0 $urltitle_max_length]
         if {[string length $title] != [string length $ctitle]} {
            append ctitle " (...)"
         }
         set title $ctitle
      }
      if {[string length $title] > 0} {
         putlog "URL Title ($nick/$chan): $token - $title"
         puthelp "PRIVMSG $chan :\[URL] $title"
      }
      break
   }
   return 1
}

putlog "URL Title v1.5 by wilk"

websearch.tcl (v1.2) - udostępnia szereg poleceń do wyszukiwania za pomocą Google, Bing, DuckDuckGo, Yandex i YouTube. Na kanałach, na których ma działać należy ustawić flagę "websearch" (.chanset #kanal +websearch).

Kod: Zaznacz cały
# Name      WebSearch
# Author   wilk wilkowy
# Version   1.2 (2018..2018-02-20)
# License   GNU GPL v2 or any later version

# Users having this flags are ignored.
set websearch_ignored "I|I"

# Users having this flags can trigger script.
set websearch_allowed "v|v"

# Command prefix.
set websearch_prefix "!"

# Protect against floods, in seconds (0 - off).
set websearch_antiflood 5

# Protect against web floods, in seconds per engine (0 - off).
set websearch_webantiflood 30

# This is how script introduces itself to servers, chosen randomly.
set websearch_agent [list "Mozilla/5.0 (X11; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0"]

# Website fetching timeout, in miliseconds.
set websearch_timeout 5000

# Max depth for 301/302 redirections.
set websearch_max_depth 5

# On/off .chanset flag.
setudef flag websearch

bind pub $websearch_allowed ${websearch_prefix}google websearch:search_google
bind pub $websearch_allowed ${websearch_prefix}goog websearch:search_google
bind pub $websearch_allowed ${websearch_prefix}goo websearch:search_google
bind pub $websearch_allowed ${websearch_prefix}g websearch:search_google
bind pub $websearch_allowed ${websearch_prefix}duckduckgo websearch:search_ddg
bind pub $websearch_allowed ${websearch_prefix}duck websearch:search_ddg
bind pub $websearch_allowed ${websearch_prefix}ddg websearch:search_ddg
bind pub $websearch_allowed ${websearch_prefix}d websearch:search_ddg
bind pub $websearch_allowed ${websearch_prefix}bing websearch:search_bing
bind pub $websearch_allowed ${websearch_prefix}b websearch:search_bing
bind pub $websearch_allowed ${websearch_prefix}yandex websearch:search_yandex
bind pub $websearch_allowed ${websearch_prefix}yan websearch:search_yandex
bind pub $websearch_allowed ${websearch_prefix}y websearch:search_yandex
bind pub $websearch_allowed ${websearch_prefix}youtube websearch:search_youtube
bind pub $websearch_allowed ${websearch_prefix}yt websearch:search_youtube

package require http
if {![catch {set websearch_tlsver [package require tls]}]} {
   set websearch_tls 1
   if {[package vcompare $websearch_tlsver 1.6.4] < 0} {
      putlog "Web Search: tls package version <1.6.4 = no SNI support, HTTPS links might not work properly"
   }
} else {
   set websearch_tls 0
   putlog "Web Search: no tls package = no SSL/TLS support (HTTPS protocol), script will not work properly"
}
if {![catch {package require htmlparse}]} {
   set websearch_htmlparse 1
} else {
   set websearch_htmlparse 0
   putlog "Web Search: no htmlparse package = no escape sequences substitution"
}

proc websearch:tlssocket {args} {
   global websearch_tlsver
   set opts [lrange $args 0 end-2]
   set host [lindex $args end-1]
   set port [lindex $args end]
   if {[package vcompare $websearch_tlsver 1.7.11] >= 0} {
      ::tls::socket -tls1 1 -tls1.1 1 -tls1.2 1 -ssl3 0 -ssl2 0 -autoservername 1 {*}$opts $host $port
   } elseif {[package vcompare $websearch_tlsver 1.6.4] >= 0} {
      ::tls::socket -tls1 1 -tls1.1 1 -tls1.2 1 -ssl3 0 -ssl2 0 -servername $host {*}$opts $host $port
   } else {
      ::tls::socket -tls1 1 -ssl3 0 -ssl2 0 {*}$opts $host $port
   }
}

proc websearch:gethtml {query depth {referer ""} {cookies ""}} {
   global websearch_tls websearch_agent websearch_timeout websearch_state
   if {[string length $query] == 0 || $depth < 0} { return "" }
   if {$websearch_tls && [string match -nocase "https://*" $query]} {
      ::http::register https 443 websearch:tlssocket
   }
   ::http::config -useragent [lindex $websearch_agent [rand [llength $websearch_agent]]]
   if {[llength $cookies] > 0} {
      catch { set http [::http::geturl $query -timeout $websearch_timeout -headers [list "Referer" $referer "Cookie" [string trim [join $cookies ";"] ";"]]] } httperror
   } else {
      catch { set http [::http::geturl $query -timeout $websearch_timeout] } httperror
   }
   if {![info exists http]} {
      putlog "Web Search: connection error for $query ($httperror)"
      return ""
   }
   set status [::http::status $http]
   set code [::http::ncode $http]
   set html ""
   if {$status eq "ok"} {
      upvar #0 $http state
      array set websearch_state [array get state]
      if {$code in [list 301 302 303 307]} {
         set redir ""
         set cook [list]
         foreach {name value} $state(meta) {
            if {[string equal -nocase "Location" $name]} {
               set redir $value
            } elseif {[string equal -nocase "Set-Cookie" $name]} {
               lappend cook [lindex [split $value ";"] 0]
            }
         }
         if {[llength $cook] == 0 && [llength $cookies] != 0} {
            set cook $cookies
         }
         if {$redir ne ""} {
            ::http::cleanup $http
            if {$websearch_tls} {
               #::http::unregister https
            }
            set addr ""
            if {[regexp -nocase {^https?://[^/&?]+?} $query addr] && ![regexp -nocase {^https?://} $redir]} {
               set redir "$addr$redir"
            }
            return [websearch:gethtml $redir [expr {$depth - 1}] $addr $cook]
         }
      }
      if {[string match -nocase "text/html*" $state(type)]} {
         set html [::http::data $http]
      } else {
         putlog "Web Search: invalid content-type for $query ($state(type))"
      }
   } else {
      putlog "Web Search: connection failed for $query ($status)"
   }
   ::http::cleanup $http
   if {$websearch_tls} {
      #::http::unregister https
   }
   return $html
}

proc websearch:_search {chan nick engine query link} {
   global websearch_max_depth websearch_htmlparse
   set query [string trim $query]
   if {$query eq ""} { return }
   set words [list]
   foreach word [split $query] {
      lappend words [::http::formatQuery $word]
   }
   set equery [join $words "+"]
   set url "$link$equery"
   array set ename [list 1 "Google" 2 "DuckDuckGo" 3 "Bing" 4 "Yandex" 5 "YouTube"]
   set html [string map -nocase {"\r" "" "\n" "" "<b>" "" "</b>" "" "<strong>" "" "</strong>" "" "<b class=\"needsclick\">" ""} [websearch:gethtml $url $websearch_max_depth]]
   set link [set desc ""]
   switch $engine {
      1   {
            regexp -nocase {<h3[^>]+?class="r"[^>]*?>\s*?<a[^>]+?href="([^"]+?)"[^>]*?">([^<>]+?)</a>\s*?</h3>} $html match link desc
         }
      2   {
            regexp -nocase {<h2[^>]+?class="result__title"[^>]*?>\s*?<a[^>]+?href="([^"]+?)"[^>]*?>([^<>]+?)</a>\s*?</h2>} $html match link desc ;#"
         }
      3   {
            regexp -nocase {<h2>\s*?<a[^>]+?href="([^"]+?)"[^>]*?>([^<>]+?)</a>\s*?</h2>} $html match link desc ;#"
         }
      4   {
            regexp -nocase {<h2[^>]+?class="organic__title[^/]+?/div>\s*?<a[^>]+?class="link[^>]+?href="([^"]+?)"[^>]*?>[^/]+?/div></div>([^<>]+?)</a>\s*?</h2>} $html match link desc ;#"
         }
      5   {
            if {[regexp -nocase {"videoRenderer":\{"videoId":"([^"]+?)".+?"title":.+?"simpleText":"([^"]+?)"} $html match link desc]} {
               set link "https://www.youtube.com/watch?v=$link"
            }
         }
   }
   if {[string length $link] > 0} {
      set desc [string trim [regsub -all {\s+} $desc " "]]
      if {$websearch_htmlparse} {
         set desc [::htmlparse::mapEscapes $desc]
      }
      putlog "Web Search ($nick/$chan): $url - $link - $desc"
      puthelp "PRIVMSG $chan :\[$ename($engine)] $link <=> $desc"
   } elseif {[string length $html] > 0} {
      putlog "Web Search: something went wrong for query $url"
   }
}

proc websearch:search {chan nick hand engine query link} {
   global websearch_ignored websearch_flood websearch_antiflood websearch_webflood websearch_webantiflood
   if {![channel get $chan websearch] || [matchattr $hand $websearch_ignored $chan]} { return }
   set now [unixtime]
   if {[info exists websearch_flood] && ($now - $websearch_flood) < $websearch_antiflood} { return }
   set websearch_flood $now
   if {[info exists websearch_webflood($engine)] && ($now - $websearch_webflood($engine)) < $websearch_webantiflood} {
      array set ename [list 1 "Google" 2 "DuckDuckGo" 3 "Bing" 4 "Yandex" 5 "YouTube"]
      puthelp "PRIVMSG $chan :\[$ename($engine)] Zbyt czeste zapytania (co ${websearch_webantiflood}s, zostalo [expr {$websearch_webantiflood - ($now - $websearch_webflood($engine))}]s)."
      return
   }
   set websearch_webflood($engine) $now
   websearch:_search $chan $nick $engine $query $link
}

proc websearch:search_all {nick host hand chan text} {
   websearch:_search $chan $nick 1 $text "https://www.google.pl/search?q="
   websearch:_search $chan $nick 2 $text "https://duckduckgo.com/html/?q="
   websearch:_search $chan $nick 3 $text "https://www.bing.com/search?q="
   websearch:_search $chan $nick 4 $text "https://www.yandex.com/search/?text="
   websearch:_search $chan $nick 5 $text "https://www.youtube.com/results?search_query="
   return 1
}

proc websearch:search_google {nick host hand chan text} {
   websearch:search $chan $nick $hand 1 $text "https://www.google.pl/search?q="
   return 1
}

proc websearch:search_ddg {nick host hand chan text} {
   websearch:search $chan $nick $hand 2 $text "https://duckduckgo.com/html/?q="
   return 1
}

proc websearch:search_bing {nick host hand chan text} {
   websearch:search $chan $nick $hand 3 $text "https://www.bing.com/search?q="
   return 1
}

proc websearch:search_yandex {nick host hand chan text} {
   websearch:search $chan $nick $hand 4 $text "https://www.yandex.com/search/?text="
   return 1
}

proc websearch:search_youtube {nick host hand chan text} {
   websearch:search $chan $nick $hand 5 $text "https://www.youtube.com/results?search_query="
   return 1
}

putlog "Web Search v1.2 by wilk"
Ostatnio edytowano 28 lutego 2018, 22:18 przez wilk, łącznie edytowano 23 razy
Powód: aktualizacja skryptów
Avatar użytkownika
wilk (autor wątku)
Operator
Operator
Ascendant
Ascendant
 
Posty: 1720
Dołączył(a): 30 lipca 2005, 16:32
Lokalizacja: #QuizPL @ IRCnet
Płeć: Mężczyzna
Pytań w bazie: 12543
Lubię quizy: klasyczne (np. Dizzy)

Powrót do O #QuizPL

Kto przegląda forum

Użytkownicy przeglądający ten dział: Common i 0 gości