Регистрация | Вход
[ Главная · Новые сообщения ]
Страница 1 из 11
Форум » Основной раздел » Мастерская » Примеры простых скриптов
Примеры простых скриптов
Vladislav 22.09.10 10:28 #1
Скрипты


1. Скрипт выводит текст:

Код
bind pub - !ком com

proc com {nick uhost hand chan text} {
putserv "PRIVMSG $chan :текст"
}


2. Скрипт выводит случайный текст:

Код
bind pub - !ком2 com2

proc com2 {nick uhost hand chan text} {
set list {"текст1" "текст2" "текст3"}
set text [lindex $list [rand [llength $list]]]
putserv "PRIVMSG $chan :$text"
}


3. Скрипт выводит случайный ник:

Код
bind pub - !ком3 com3

proc com3 {nick uhost hand chan text} {
set nicks [chanlist $chan]
set dnick [lindex $nicks [rand [llength $nicks]]]
while {[string equal -noc $::botnick $dnick]} {set dnick [lindex $nicks [rand [llength $nicks]]]}
putserv "PRIVMSG $chan :$dnick"
}


4. Скрипт выводит случайную строку из файла каждые 5 минут автоматически:

Код
bind cron - "*/5 * * * *" com4

proc com4 {min hour day month weekday} {
set chan #windrop
set file baza.txt
if {![file exists $file]} {putlog "Бызы нет."; return}
set f [open $file r]
set list [split [read $f] \n]
close $f
if {[llength $list] == 0} {putlog "База пуста."; return}
putserv "PRIVMSG $chan :[lindex $list [rand [llength $list]]]"
}


5. Cкрипт выводит текст на определённое слово в сообщении:

Код
bind pubm - "*привет*" com5

proc com5 {nick uhost hand chan text} {
putserv "PRIVMSG $chan :$nick здорова!"
}


Или:

Код
bind pubm - * com5

proc com5 {nick uhost hand chan text} {
set text [string tolower [string trim [string map { {}} [stripcodes bcur $text]]]]
if {[string match "*привет*" $text]} {putserv "PRIVMSG $chan :$nick здорова!"; return}
if {[string match "*пока*" $text] || [string match "*прощай*" $text]} {putserv "PRIVMSG $chan :$nick пока!"; return}
}


6. Скрипт добавляет строку в файл:

Код
bind pub - !строка com6

proc com6 {nick uhost hand chan text} {
set file baza.txt
if {[string is space $text]} {putserv "NOTICE $nick :Формат: !строка <текст>"; return}
set f [open $file a+]
puts $f $text
close $f
putserv "NOTICE $nick :Строка была успешно сохранена. Спасибо!"
}


7. Скрипт выводит некую информацию с сайта:

Код
bind pub - !ком7 com7

proc com7 {nick uhost hand chan text} {

::http::config -useragent "Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; PPC; 240x320)"   
set url http://windrop.clan.su
if {[catch {set token [::http::geturl $url -timeout 10000]} error]} {putserv "NOTICE $nick :Ошибка: $error"; return
} elseif {[::http::ncode $token] == "404"} {putserv "NOTICE $nick :Ошибка: [::http::code $token]"
} elseif {[::http::status $token] == "ok"} {set data [regsub -all -- {\n|\r|\t|\v} [::http::data $token] ""]
} elseif {[::http::status $token] == "timeout"} {putserv "NOTICE $nick :Ошибка: Таймаут соединения."
} elseif {[::http::status $token] == "error"} {putserv "NOTICE $nick :Ошибка: [::http::error $token]"}
if {[info exists data]} {::http::cleanup $token; set data [regsub -all -- {\s+} $data " "]} else {::http::cleanup $token; return}
if {[regexp -nocase -- {Бот обновлён.*?>(.*?)</a>.*?<a href="/Windrop.exe" target="_blank" title="Актуальная.*?">(.*?)</a>} $data -> dat ver]} {
putserv "PRIVMSG $chan :$ver - $dat"
}
}


8. Задержка по времени. В данном случае при входе на канал даётся войс, а затем снимается:

Код
bind join - * com8

proc com8 {nick uhost hand chan} {
if {![isbotnick $nick] && ([botisop $chan] || [botishalfop $chan])} {
putserv "MODE $chan +v $nick"
after 120000 [list com8d $chan $nick]
}
}

proc com8d {chan nick} {
if {([botisop $chan] || [botishalfop $chan]) && [onchan $nick $chan] && [isvoice $nick $chan]} {
putserv "MODE $chan -v $nick"
}
}


9. По команде определённому нику отправляет текст.

Код
bind pub - !ком9 com9

proc com9 {nick uhost hand chan text} {
if {[string is space $text]} {putserv "NOTICE $nick :Формат: !ком9 <ник>"; return}
set dnick [lindex [split $text] 0]
if {[onchan $dnick $chan]} {
putserv "NOTICE $dnick :Текст сообщения."
} else {
putserv "NOTICE $nick :$dnick отсутствует на канале $chan."
}
}


10. Скрипт выводит всё что есть в файле:

Код
bind pub - !ком10 com10

proc com10 {nick uhost hand chan text} {
set file text/motd
if {![file exists $file]} {putlog "Бызы нет."; return}
set f [open $file r]
set data [split [read $f] \n]
close $f
foreach line $data {
putserv "PRIVMSG $chan :$line"
}
}


11. Скрипт сохраняет количество использования данной команды на каждый ник отдельно:

Код
bind pub - !ком11 com11

proc com11 {nick uhost hand chan text} {
# Путь к базе:
set baza baza.txt
# Проверка наличие базы, если нет то создадим пустой файл (директория должна существовать):
if {![file exists $baza]} {set f [open $baza w+]; close $f}
# Открываем файл, читаем его и закрываем:
set f [open $baza r]; set data [lrange [split [read $f] \n] 0 end-1]; close $f
# Проверяем каждую строку на совпадения ника, формируем базу без этого ника:
set inick ""; set list {}; foreach line $data {
if {[string equal -nocase [lindex $line 0] $nick]} {set inick [lindex $line 1]; continue} {lappend list $line}
}
# Если ник не найден, то записываем новую строку с ником в этот файл:
if {$inick == ""} {
set f [open $baza a+]; puts $f [list $nick 1]; close $f
} {
# Если ник найден то переписываем базу без ника:
set f [open $baza w+]
foreach line $list { puts $f $line }
# Затем добавляем этот ник с изменением числа:
puts $f [list $nick [expr $inick+1]]; close $f
}
# Выводим результат:
if {$inick == ""} {putserv "PRIVMSG $chan :1"} {putserv "PRIVMSG $chan :[expr $inick+1]"}
}


12. Скрипт каждую минуту будет менять топик на указанном канале из списка по порядку:

Код
bind time - "* * * * *" com12

proc com12 {min hour day month year} {
global topicend
set chan #windrop
set file baza.txt
if {![file exists $file]} {putlog "Бызы нет."; return}
if {![info exists topicend]} {set topicend 1}
set f [open $file r]
set data [split [read $f] \n]
close $f
set topicstart 0; foreach line $data {
if {$line eq ""} {continue}
incr topicstart
if {$topicstart eq $topicend} {putserv "TOPIC $chan :$line"}
}
if {$topicstart eq $topicend} {set topicend 1} {set topicend [expr $topicend+1]}
}


13. Скрипт запоминает последнее сообщение которое содержит в начале ip на том канале где включён флаг "ipsave" и выводит его по команде !ip:

Код
namespace eval ipsave {

setudef flag [namespace tail [namespace current]]

variable ipvrem ""
variable iptext ""

bind pub - !ip [namespace current]::pub
bind pubm - *  [namespace current]::parser

proc parser {nick uhost hand chan text} {
variable ipvrem; variable iptext
if {[channel get $chan [namespace tail [namespace current]]]} {
set text [string trim [string map { {}} [stripcodes cubr $text]]]
if {[regexp -nocase -- {^[0-9\.]{7,20}$} [lindex [split $text] 0]] && [string match "*\.*" [lindex [split $text] 0]]} {
set ipvrem [strftime %X]
set iptext [list [lindex [split $text] 0] [join [lrange [split $text] 1 end]]]
}
}
}

proc pub {nick uhost hand chan text} {
variable ipvrem; variable iptext
if {$ipvrem ne "" && $iptext ne ""} {
putserv "PRIVMSG $chan :\002$nick\002, последний ip был записан в \002$ipvrem\002 -> \037[lindex $iptext 0]\037 [lindex $iptext 1]"
} {
putserv "PRIVMSG $chan :\002$nick\002, данных пока нет :("
}
}

}


14. Скрипт добавляет топик для каждого канала отдельно и меняет его на случайный каждые 30 минут:

Код
bind cron - "*/30 * * * *" autotopic
bind pub  n !топик+        topicplus

proc autotopic {min hour day month weekday} {
set file data/baza.txt
if {![file exists $file]} {putlog "Бызы нет."; return}
set filep [open $file r]; set list [lrange [split [read $filep] \n] 0 end-1]; close $filep
if {[llength $list] == 0} {putlog "База пуста."; return}
foreach chan  [channels]{
if {![botisop $chan] && ![botishalfop $chan]} {continue}
set topic {}; foreach line $list { if {[string equal -nocase [lindex $line 0] $chan]} {lappend topic [lindex $line 1]} }
if {[llength $topic] != 0} {putserv "TOPIC $chan :[lindex $topic [rand [llength $topic]]]"}
}
}

proc topicplus {nick uhost hand chan text} {
set file data/baza.txt
if {[string is space $text]} {putserv "NOTICE $nick :Формат: !топик+ <текст>"; return}
if {[string length $text] > 300} {putserv "NOTICE $nick :Лимит для топика = 300 символов! У вас [string length $text]."; return}
set filep [open $file a+]; puts $filep [list $chan $text]; close $filep
putserv "NOTICE $nick :Топик успешно добавлен. Спасибо!"
}


15. Удаляем строку из файла по номеру или по тексту или все строки разом.

Код
bind pub - !-строка com15

proc com15 {nick uhost hand chan text} {
set file baza.txt
# если команда без параметров то напоминаем их
if {[string is space $text]} {putserv "NOTICE $nick :Формат: !-строка <номер/текст/все>"; return}
# создаём файл если его нет
if {![file exists $file]} {set f [open $file w+]; close $f}
# читаем файл
set filep [open $file r]; set list [lrange [split [read $filep] \n] 0 end-1]; close $filep
# если файл пустой то сообщаем об этом
if {[llength $list] == 0} {putserv "NOTICE $nick :База пуста."; return}
# если указаны цифры то удаляем строку по номеру
if {[string is digit $text]} {
# проверяем есть ли такой номер
if {$text <= [llength $list]} {
# формируем новый список без этой строки
set list [lreplace $list [expr $text-1] [expr $text-1]]
# переписываем файл
set filep [open $file w+]; foreach line $list { puts $filep $line }; close $filep
# сообщаем что всё хорошо
putserv "NOTICE $nick :Строка под номером $text удалена."; return
} {
# сообщаем что такой строки нет
putserv "NOTICE $nick :Строки под номером $text не существует. Всего строк: [llength $list]."; return}
} {
# если указано слово "все" то чистим файл
if {[string equal -nocase "все" $text]} {set f [open $file w+]; close $f; putserv "NOTICE $nick :Все строки удалены."; return}
# в другом случае сравниваем строки, проверяем есть ли такая строка, если есть то получаем сразу её номер
if {[set num [lsearch -exact -nocase $list $text]] != "-1"} {
# формируем новый список без этой строки
set list [lreplace $list $num $num]
# переписываем файл
set filep [open $file w+]; foreach line $list { puts $filep $line }; close $filep
# сообщаем что всё хорошо
putserv "NOTICE $nick :Строка \"$text\" удалена."; return
} {
# сообщаем что такой строки нет
putserv "NOTICE $nick :Строки \"$text\" не существует."; return
}
}
}


16. Как отловить ошибки в TCL скриптах для eggdrop с выводом на канал.

Код
set ::erchan "#bots"

set ::errtm 0; proc ::wrerr {args} {
if {[incr ::errtm] >= 1 && ![string is space $::errorInfo]} {
if {[string match -nocase "*state(sock)*" $::errorInfo] || [string match -nocase "*named \"sock*" $::errorInfo]} {set ::errtm 0; set ::errorInfo ""; return}
putchan $::erchan "\00304 .---Error---"
set i 0; foreach _ [split $::errorInfo \n] { if {[incr i] > 20} {break} else {putchan $::erchan "\00304| \017$_"} }
putchan $::erchan "\00304`----End----"  
set ::errtm 0; set ::errorInfo ""
}
}

trace add variable errorInfo write ::wrerr
Vladislav 07.05.12 11:20 #2
Синтаксис процедур


Цитата
bind <тип> <флаги> <ключевое слово|маска> <имя процедуры>
proc <имя процедуры> {аргументы} {
код
}


тип - один из возможных типов процедур, сейчас их 47.

флаги - флаг, необходимый для вызова процедуры, например если указать "n" то процедура сработает только для овнера, а если "-" то для всех.

ключевое слово|маска - ключевое слово, при котором будет вызвана процедура. Маска может содержать символ "?", обозначающий 1 любой символ, или символ "*", обозначающий любое количество символов (от 0)

имя процедуры - процедура, которая будет вызвана для обработки события. Имя процедуры не должно повторяться в боте, проверить можно командой !tcl имя_процедуры. Если напишет "неизвестная команда" значит такой процедуры нет, если "неверное количество аргументов" значит такая процедура уже существует и нужно придумать другое имя.

аргументы - передаваемые при вызове процедуры значения (зависит от типа bind).

код - код самого действия.

Процедура для команды на канале (PUB)


Код
bind pub - !команда name          
proc name {nick uhost hand chan text} {          
putlog ok                    
}


Первое слово рассматривается как команда, а все последующие как текстовой аргумент. Передаёт 5 значений: "ник идент@хост хэндл канал текст". Если вместо аргумента "text" поставить "args" то передаст не текст, а список из одного элемента.

Процедура для команды в привате (MSG)


Код
bind msg - !команда name          
proc name {nick uhost hand text} {          
putlog ok                    
}


Первое слово является командой и все последующие - текстовой аргумент. Передаёт 4 значения: "ник идент@хост хэндл текст". Если вместо аргумента "text" поставить "args" то передаст не текст, а список из одного элемента.

Процедура для маски на канале (PUBM)


Код
bind pubm - "*текст*" name          
proc name {nick uhost hand chan text} {          
putlog ok                    
}


Поиск совпадений в тексте с указанной маской. Полезно для привязки Tcl-процедур к словам или фразам, встречающимся в тексте. Если указать "*" то будет срабатывать на все сообщения. Передаёт 5 значений: "ник идент@хост хэндл канал текст". Если вместо аргумента "text" поставить "args" то передаст не текст, а список из одного элемента.

Процедура для маски в привате (MSGM)


Код
bind msgm - * name          
proc name {nick uhost hand text} {          
putlog ok                    
}


Поиск совпадений в тексте с указанной маской. Полезно для привязки Tcl-процедур к словам или фразам, встречающимся в тексте. Если указать "*" то будет срабатывать на все сообщения. Передаёт 4 значения: "ник идент@хост хэндл текст". Если вместо аргумента "text" поставить "args" то передаст не текст, а список из одного элемента.

Процедура реагирует на чей-либо вход на канал (JOIN)


Код
bind join - * name          
proc name {nick uhost hand chan} {          
putlog ok                    
}


Передаёт 4 значения: "ник идент@хост хэндл канал". Содержит маску "#канал ник!идент@хост", если "*" то для всех.

Процедура реагирует когда кто-либо покидает канал (PART)


Код
bind part - * name          
proc name {nick uhost hand chan {msg ""}} {          
putlog ok                    
}


Передаёт 5 значений: "ник идент@хост хэндл канал прощальное_сообщение". Содержит маску "#канал ник!идент@хост", если "*" то для всех.

Процедура по расписанию (TIME)


Содержит 5 разделенных пробелами целых значений формы "минуты часы дни месяцы годы".
Минуты, часы, дни, месяцы содержат значение из двух цифр (нулей), год в любом случае имеет длину в четыре символа.

Код
bind time - "* * * * *" timeproc
proc timeproc {min hour day month year} {
putlog ok
}


Раз в минуту:

Код
bind time - "?? * * * *" timeproc


Раз в 5 минут:

Код
bind time - "?5 * * * *" timeproc
bind time - "?0 * * * *" timeproc


Каждые 10 минут:

Код
bind time - "?0 * * * *" timeproc


Каждые полчаса:

Код
bind time - "00 * * * *" timeproc
bind time - "30 * * * *" timeproc


Каждый час:

Код
bind time - "00 * * * *" timeproc


Процедура по расписанию (CRON)


Похоже на bind time, но маска времени таже, что и в cron "16/2 */2 5-15 7,8,9 4".
Содержит 5 разделенных пробелами целых значений формы "минуты часы дни месяцы дни_недели".

Любое из пять полей может содержать символ * (звездочка) в качестве значения.
Это означает полный диапазон возможных значений, например, каждая минута, каждый час и тд

Любое из полей может содержать список значений, разделенных запятыми (например, 1,3,7) или интервал (поддиапазон) значений, обозначаемый дефисом (например, 1-5).

После звездочки (*) или интервала можно с помощью символа / указать шаг значений. Например, 0-23/2 может использоваться в поле "Часы" для указания того, что действие должно происходить каждые два часа (альтернатива из старого варианта - 0,2,4,6,8,10,12,14,16,18,20,22), значение */4 в поле "Минуты" означает, что действие, должно происходить каждые четыре минуты, 1-30/3 - это то же, что и 1,4,7,10,13,16,19,22,25,28.

* * * * *
| | | | |
| | | | |
| | | | +----- Дни недели (диапазон: 1-7)
| | | +------- Месяцы (диапазон: 1-12)
| | +--------- Дни месяца (диапазон: 1-31)
| +----------- Часы (диапазон: 0-23)
+------------- Минуты (диапазон: 0-59)

Код
bind cron - "* * * * *" timeproc
proc timeproc {min hour day month weekday} {
putlog ok
}


Раз в минуту:

Код
bind cron - "* * * * *" timeproc


Раз в 5 минут:

Код
bind cron - "*/5 * * * *" timeproc


Каждые 10 минут:

Код
bind cron - "*/10 * * * *" timeproc


Каждые полчаса:

Код
bind cron - "*/30 * * * *" timeproc


Каждый час:

Код
bind cron - "* */1 * * *" timeproc
Vladislav 11.05.12 14:21 #3
Способы вывода текста

Первый способ - короткий аналог второго, третий осуществляет перенос текста если он не влезет в одну строку.
Подразумевается что в proc аргументы выглядят как chan и nick, вместо них так же можно указать имя канала или ник.
Если в тексте вам нужно поместить скобки [] или {} то их надо экранировать, например: \[текст\] \{текст\} или только открывающую \[текст] \{текст}. А также экранируются кавычки, например \"текст\" и бэкслеш \, например \\.

На канал:

Код
putchan $chan "текст"
putserv "PRIVMSG $chan :текст"
::ccs::put_msgdest $chan "текст"


В приват:

Код
putmsg $nick "текст"
putserv "PRIVMSG $nick :текст"
::ccs::put_msgdest $nick "текст"


Нотисом:

Код
putnotc $nick "текст"
putserv "NOTICE $nick :текст"
::ccs::put_msgdest -type notice $nick "текст"


Действие:

Код
putact $chan "текст"
putserv "PRIVMSG $chan :\001ACTION текст\001"
Форум » Основной раздел » Мастерская » Примеры простых скриптов
Страница 1 из 11
Поиск: