Web Вход

 

TCL скриптинг для eggdrop'ов [статья #2] - Автор: Sat

В прошлой статье я рассмотрел основу построения скрипта для егга. В этой я собираюсь рассмотреть различные типы привязки, а точнее типы событий, и привязку к ним. Заодно познакомлю ещё с парочкой функций.
Основным событием, к которому привязывают процедуры является публичное выражение, наверное вы не раз видели как кто-то пишет на канале "!opme" и бот его делает оператором канала, то что это бот можете не сомневаться. Так вот данная привязка делается при помощи слов "pub", или "pubm", основное различие я рассмотрел в прошлой статье.
А допустим вам захотелось написать скрипт, который делал бы вас опом, на сообщение боту в приват, тут уже словами "pub" "pubm" ну никак не обойдёшься. Для того чтобы привязать определённый скрипт к приватному сообщению надо применять такой тип привязки:
bind msg !opme o|o msg:op #! или !#
bind msgm "!op*" o|o msgm:op
Отличия между "msg" и "msgm" такие-же как и между "pub" и "pubm"(читай предыдущую статью.)
Но вот описание процедуры, которая привязана к приватному сообщению, немного отличается от процедуры, привязанной к публичному сообщению. Так сообщение прозвучало не на канале, бот не может определить, с какого канала, из тех, где он вас видит, пришло сообщение, поэтому описание выглядит следующим образом:
proc msg:op {nick host hand text} { #! тут аналогично с процедурой pub:bot (читай предыдущую статью) передаются следующие параметры: ник пользователя(nick), хост(host), его хэндлер(hand) и собственно слова идущие после слова, вызвавшего данную процедуру(text), к примеру строка выглядела так - "!op me on channel #main", в переменной $text будет содержаться строка - "me on channel #main". !#
Соответственно каждая процедура должна закрываться фигурной скобкой.
Вот теперь можно построить весь скрипт, который опает вас на указанном канале. Соответственно, если вы не являетесь оператором бота, на этом канале, он вам об этом сообщит.
bind msg !op -|- msg:op #! привязали к личному сообщению боту процедуру msg:op, сообщение должно выглядеть таким образом: "!op #main", тогда бот сделает вас оператором на канале #main, если вы являетесь оператором бота на этом канале.!#

proc msg:op {nick host hand text} { #! Описали процедуру msg:op !#
set chan [lindex $text 0] #! Из строки пришедшей в качестве параметра выбрали первое слово, напомню, что нумерация слов в строке начинается с нуля, эта строка написана для того, чтобы бот не попытался проверить, являетесь ли вы оператором на канале например "#main please" :) !#
if {[matchattr $hand o $chan]} { #! теперь проверяем, является ли человек написавший боту его оператором на канале $chan, т.е. его хэндлеру должен соответствовать флаг "о" !#
putserv "mode $chan +o $nick" #! если он оператром, "говорим" серверу, что надо сделать этого человека оператором канала $chan, естесственно имеет смысл если бот сам является оператором на канале $chan !#
return #! Заканчиваем процедуру !#
} else { #! А если всё таки этот человек не оператор бота, ведь бот не должен слушаться всех подряд, то... !#
putserv "NOTICE $nick :Извините, но вы не являетесь моим оператором на канале $chan" #! Сообщаем ему что он зря старается !#
return #! и завершаем процедуру !#
}
}

Вот так выглядит скрипт, чуть более серьёзный, чем в рассмотренной ранее статье. А вот допустим бот не является оператором канала $chan, спросите вы. Ну что-ж, тогда бот зря старается сделать вас оператором, но если вы хотите, что бы бот вам говорил что он не оператор, то следует поставить условие:
if {![botisop $chan]} { #! Если бот не оператор на канале $chan, чтоб было понятней, объясняю, многие функции возвращают либо 0 либо 1, а восклицательный знак перед скобками выполняет логическую операци "не", если вы изучали раньше программирование, то вам должно быть ивестно, что любое условие то-же своего рода процедура, которая возвращает 1 если условие верно и 0 в противном случае.
putserv "NOTICE $nick :Извините, но я не оператор на канале $chan." #! Дальше думаю пояснений уже не требуется !#
return
}
Этот кусок скрипта надо вставить сразу за строкой:
set chan [lindex $text 0]

Соответственно по образу и подобию вы можете сделать скрипт, который заставлял бы бота банить бы кого-нибудь на канале, или наоборот разбанивать, и делать ещё много других полезных действий. Для написания скрипта на бота выполняющего стандартные команды типа: !opme !deopme !ban !unban - этих знаний уже достаточно. Но вдруг кому-то не понравилось что ваш бот делает что-то по вашему указанию, и он решил лишить вашего бота статуса оператора канала... По моему это самый простой способ лишить бота "подвижности", но ваш бот имеет статус AOP на канале (читай статьи посвящённые общим вопросам IRC). Тогда следует написать скрипт, который защищал бы вашего бота от подобных действий, если логично прикинуть, то противостоять этому нельзя, но можно вернуть оператора канала, при помощи ChanServ-a(Зто для сетеи WeNET, для других сетей я ботов пока не делал.). Выглядит это таким образом:

bind mode - * mode:bot #! К любому изменению мода канала привязываем скрипт mode:bot !#

proc mode:bot {nick host hand chan mc {victim ""}} { #! описываем процедуру mode:bot, которой передаются переменные, о которых говорилось раньше, и две новые - mc(конкретное какое изменение произошло) и victim(жертва этого изменения)
global botnick #! Плучаем ник бота, он устанавливается в кофигурации бота, которая то же выполняется как самый обыкновенный скрипт !#
if {$mc == "-o"} { #! Если изменением послужило лишение кого-либо статуса оператора канала, то идём дальше !#
if {$victim == $botnick || $victim == [getchanhost $botnick $chan]} { #! А если жертвой послужил бот, то выполняем следующие действия: !#
putserv "PRIVMSG chanserv :op $chan $botnick" #! Сообщаем чансерву, что надобно бы вернуть статус оператора. !#
return #! и прекращаем выполнение процедуры !#
}
}
return #! А тут прекращаем выполнение процедуры, в случае если жертвой был не бот, или если изменение мода было другим.
}

Тут встретилась неизвестная функция "getchanhost". Эта функция возвращает хост, с которого зашёл в мирк $nick, а переменная $chan в этой функции говорит что хост надо смотреть на канале $chan, если эта переменная опущена, то бот будет искать этот $nick на всех каналах, а когда найдёт "посмотрит" его хост. Эту переменную лучше указывать, потому, что если вдруг этот скрипт будет ещё и наказывать, т.е. допустим банить обидчика, и нечаянно в случае какой-либо ошибки скрипт получит неправильный ник, то может пострадать невиновный человек. Которого на этом канале и нет вообще.
Таким образом можно и перехватывать баны, присвоение статуса оператора нежелательным лицам, и все остальные.
Ключевое слово "gobal" получает значения глобальных перемнных, установленных вне какой-либо процедуры, в данном случае ник бота. Можно указывать несколько глобальных переменных, например: global arg1 arg2 arg3 arg4 - получит значения четырёх глобальных переменных.
Ну естественно, что вы не постоянно следите за ботом, за его действиями на всех канал, где он находится, поэтому иногда очень полезно почитать лог бота, а вот все действия, производимые ботом можно записывать так: putlog "$nick получил оператора на $chan" - что соответственно значит, что $nick получил статус оператора канала $chan. Это просто бывает полезным, когда вашего бота обвиняют в каких-либо действиях, которые противоречат правилам канала, ведь на каждом канале свои правила.
Вот теперь вы можете задуматься над попыткой написать набор простейших, но полезных комманд для вашего бота, которые будут упрощать управление ботом с канала, или как-то автоматизируют поведение бота.
В следующей статье буду рассмотрены основные строковые операции, и управление пользователями и каналами.

 

Copyright (с) 2004-2005 by Vozotron