TCL скрипты для eggdrop и windrop (часть 1)

Написал Danila Vershinin Четверг, 26 Июль 2007

Бот — это такая программа, одна часть которой работает как IRC клиент, а другая выполняет некоторые действия в IRC сети.

Если объяснять ещё более доступным языком, то это опять же программа, которая выглядит на канале в IRC как обыкновенный пользователь, но действиями которой управляет другая программа, называемая скриптом.

Вот теперь, по-моему, уже понятней. Ботом может быть как обычный IRC клиент, такой как mIRC или BitchX, так и специализированная программа, самой известной из которых является eggdrop.

А теперь я говорю абсолютно конкретно - вот о нём дальше речь и пойдёт. Если вы никогда раньше не пользовались eggdrop (дальше для краткости «егг»), то дальше опять же нет смысла читать: я не буду рассказывать, как его устанавливать и настраивать. Все скрипты для егга пишутся на языке шелл программирования для *nix — TCL, дополненном специфическими командами, облегчающими жизнь нам, простым скриптописателям для егга. Синтаксис языка очень простой, и по ходу чтения статьи вы с ним полностью разберётесь и научитесь писать простенькие скрипты. В следующих статьях я напишу о более сложных вещах.

А теперь начнём рассмотрение базовых основ скриптинга для егга. Основное применяемое мной сокращение будет комментарий, который будет ограничиваться символами #! и !# (это не общепринятый комментарий в скриптах, такое отделение даже не будет восприниматься как комментарий ботом).

Всегда, когда вы хотите чтобы ваш бот как-то реагировал на происходящее на канале, например на слово !bot, стоящее в начале строки, скрипт должен содержать строку:

bind pub -|- !bot pub:bot

Объясняю, команда bind означает привязку к определённому происшествию, в данном случае к сказанному на канале (pub) слову !bot, и боту не должно быть важно, кто это сказал (-|-), но зато он выполняет процедуру pub:bot (это просто имя процедуры, и вы можете выбирать его сами).

Следуя негласному кодексу скриптописателей для егга, все привязки обычно идут в самом начале скрипта. Привязать можно очень ко многим действиям, и в добавок некоторые действия имеют два разных слова для привязки, например pub и pubm, основное отличие между ними состоит в том, что привязка типа pub не распознаёт масок (* ?) и соответственно выглядит как написанный выше пример, но если вы хотите, чтобы бот реагировал на любую строку, где например встречается сочетание букв "фыв" (очень часто это применяется для скрипта наказания за нецензурные выражения на канале), то выглядеть это должно так:

pind pubm -|- "*фыв*" pubm:bot

После такой привязки надо написать процедуру, которую бот будет выполнять.

 
proc pub:bot {nick host hand chan text}
{
  if {[matchattr $hand o $chan]} {
    putserv "PRIVMSG $chan :Ты мой оператор."
  } else {
    putserv "PRIVMSG $chan :Ты не являешься моим оператором."
  }
  return
}

Этот скрипт производит следующие действия:

proc pub:bot {nick host hand chan text}
— Это мы описали процедуру, называется она pub:bot и принимает в качестве аргументов ник пользователя, который сказал "!bot" (nick), хост этого пользователя (host), его хэндлер (hand), канал, на котором это всё происходило (chan), а так же текст (text), следующий за словом !bot (которое обязательно должно стоять в начале строки, при такой организации привязки)

if {[matchattr $hand o $chan]} { — строка проверяет, соответствует ли этому хэндлеру флаг "о" и если это так, то бот напишет на канал такую строку «Ты мой оператор». Если вызов команды происходит где-нибудь в середине строки, или в ее конце, то команда заключается в квадратные скобки: []

putserv "PRIVMSG $chan :Ты мой оператор." — вывод осуществляется при п омощи команды putserv, эта команда отправляет серверу строку, которая идёт дальше в кавычках. А в кавычках написано следующее: «Отправить сообщение на канал $chan (который был передан процедуре как параметр)». Так этой командой можно отправлять нотисы: NOTICE $nick (или $chan), сообщения в приват (PRIVMSG $nick) и другие действия, про которые будет написано чуть дальше.

} else { — Ну, тут я думаю всё понятно. И одно важное замечание, каждая процедура должна содержать команду return (это даже не обязательно, но быстродействие бота немного повышается в больших процедурах). Этой командой можно вернуть какое-нибудь значение, которое будет присвоено переменной, например: set param [mycommand $string] — здесь переменная $string - это любая переменная, которая должна быть объявлена раньше и в результате param присваивается значение, которое вернула процедура mycommand после определённых манипуляций с переменной string.

Все процедуры обязательно вызывать со строго заданным количеством переменных, т.е. процедура mycommand была описана всего с одной переменной, следовательно, две переменных передавать нельзя, иначе это вызовет ошибку и бот «умрет». Передавать множество переменных в процедуру можно так: mycommand $string1 $strin2 $string3. Но процедура может вернуть всего одну переменную.

К слову о переменных, все переменные в TCL являются строковыми, даже когда переменной присваивается число командой: set param 1 (здесь мы присвоили переменной param значение равное 1), эта единица присваивается в виде строки. А точнее одного слова. Если вы точно уверенны, что эта переменная содержит число, то можно производить с ним математические операции с помощью команды expr, например: set new [expr $param+10].

Команда putserv

Как было сказано выше, эта команда отправляет на сервер строку, помещая её в буфер со средним приоритетом (т.е. приоритет этой строке отдаваться не будет, иногда это вызывает иллюзию подтормаживания бота, но это только иллюзия, и я рекомендую пользоваться в основном этой командой). Строка может быть любой, однако любую строку сервер может не понять, поэтому основные используемые виды такие:

  • putserv "PRIVMSG $chan :Целое длинное предложение" — в результате ваш бот скажет целое длинное предложение на канале $chan
  • putserv "NOTICE $chan :А вот это вы обязательно прочитаете" — отправит нотис на канал
  • putserv "PRIVMSG $nick :Привет!" — отправит сообщение в приват $nick
  • putserv "NOTICE $nick :Текст нотиса" — пошлет нотис в приват
  • putserv "mode $chan +o $nick" — в результате ваш бот сделает $nick оператором канала $chan (установит мод +o)
  • putserv "mode $chan -o $nick" — снимет статус оператора с nick

Думаю, уже стало понятно, что этой командой можно делать всё, что угодно на канале. Синтаксис строк, отправляемых командой putserv, описан в статьях посвящённых общим вопросам IRC.

Так же эта команда имеет двух своих «братьев» puthelp и putquick, отличаются они тем, что первая команда отправляет строку с пониженным приоритетом, т.е. эта строка выведется только после того, как выведутся все строки с более высоким приоритетом, а команда putquick отправляет строку с повышенным приоритетом. Обратите внимание, что скрипт работает намного быстрее, чем человек может печатать, и в результате, если вы будете часто пользоваться командой putquick, ваш бот может насильно выйти из IRC сети по причине флуда на сервер. Так что с этой командой надобно быть поосторожнее.

Команда set

В принципе, эта команда очень простая: она присваивает переменной какое-то значение, будь оно постоянной строкой или результатом выполнения другой команды. Если до выполнения этой команды переменная не была объявлена, set её объявит, на самом деле это единственная команда, которая объявляет переменные.

Команда if

Эта команда имеет следующий синтаксис

 
if {TRUE} {
  #! ваш скрипт, если выражение в скобках верное !#
} else {
  #! соответсвенно если не верно !#
}

Выражения могут быть следующими:

  • $var1 == $var2 равно
  • $var1 != $var2 не равно
  • $var1 < $var2 меньше
  • $var1 > $var2 больше
  • $var1 >= $var2 больше или равно
  • $var1 <= $var2 меньше или равно

Так же в этой команде поддерживаются логические операции || (или) && (и).

В языке TCL очень сильно развиты операции со строками: Вот два основных примера:

set slovo [lindex $string $var] — эта строка присваивает переменной $slovo значение, которое идёт под номером $var в строке $string (обратите внимание, нумерация начинается с нуля), если слов в строке больше, чем указывает $var, то присвоится пустая строка.

set sl [lrange $string $slovo1 $slovo2] — В результате переменной $sl присвоится значение промежутка строки $string со слова $slovo1 (число, т.е. порядковый номер с какого слова) по $slovo2 (аналогично), если вам надо до конца строки, то это выглядит таким образом: set sl [lrange $string $slovo1 end]

Для начала вашей скриптописательской карьеры этого материала будет достаточно, но на этом я свой рассказ не закончил.

Последнее обновление ( Понедельник, 24 Сентябрь 2007 )
< Пред.   След. >