Расширение возможностей клиента с помощью скриптов

Создание надстроек в виде DLL оказалось для многих пользователей недоступным, поэтому сделана попытка подружить клиент с простым, но очень мощным скриптовым языком LUA (Подробнее: www.lua.org, lua.ru)

Планируется, что c помощью скриптов будут реализоватся самые изысканые запросы (например, замысловатые условия авто-банов, управление скоростями закачек).

На данный момент реализован необходимый минимум для создания "разговорного" бота, но система комманд будет расширяться.
Общие положения

- LUA-интерпретатор lua32.dll при старте клиента должен находится в подкаталоге lua основного каталога клиента (скачать)
- Пользовательские расширения LUA-интерпретатора должны быть оформлены в виде dll и находиться в одном каталоге с lua32.dll
- Все скрипты должны находиться в подкаталоге Scripts основного каталога клиента
- При загрузке клиента происходит автозапуск файла startup.lua, если он существует
- Выполнить произвольную lua-команду можно, введя /lua lua-выражение в окне приватного или общего чата
- Выполнить lua-скрипт из файла можно, введя /luafile script.lua в окне приватного или общего чата

Подробное руковоство находится в процессе написания, ниже будут даны лишь краткие комментарии к функциям скрипта. Представление о приёмах программирования в LUA можно получить, изучив скрипты к хаб-ботам (Robocop, HUBBA-BOT)
Вызов системных функций клиента

Функция DC() вернёт таблицу, в которой зарегистрированы сервисные функции клиента greylink. Пока доступны следующие функции:

- SendPrivateMessage(uid, message)
- SendPublicMessage(huburl, message)
- SimPrivateMessage(uid, message)
- SimPublicMessage(huburl, message)
- GetUsers(huburl)
- GetUserInfo(uid)
- GetList(uid, mode)
  -- числовой параметр mode аналогичен BotInit::DlFileListFlags
- SetExtraSlot(uid, s)
  -- дать слот на s секунд. При s=0 убирается экстра-слот, но соединение не разрывается
- RunTimer(enabled)
  -- 1 - включение таймера, 0 - выключение
- PrintDebug(message)
- GetSetting(key)
-- параметр key совпадает с названием ноды в ветке Settings файла настроек DCPlusPlus.xml
- SetSetting(key, value)
- GetHubSetting(huburl, key)
-- если хаб не внесён в Избранные, функция возвращает nil
- SetHubSetting(huburl, key, value)
-- если хаб не внесён в Избранные, выбрасывается исключение
- ToUtf8(str)
- FromUtf8(str)
- GetAppPath()
- MessageBox(text, title, "yesno", "question")
- Beep(frequency, duration)

Примеры вызова из строки ввода чата:

    /lua DC():PrintDebug("this goes to client system log")
    /lua DC():MessageBox(DC():GetSetting("LanguageFile"), DC():GetAppPath(), "ok", "warning")

    При выполнении команд /lua и /luafile в глобальных переменных
    dc_huburl и dc_uid будут записаны параметры хаба и пользователя,
    из чата которых выполняется команда. Чтобы отличить запуск скрипта из чата хаба
    от запуска из приватного чата, можно использовать такое условие:
    if (DC():GetUserInfo(dc_uid).ME == "1") then hub

    Передача скрипту сообщений о событиях
    Скрипт должен создать таблицу с именем dcpp
    и в ней определить функции:

    OnHubConnected(huburl)

    Хаб подключен
    OnHubDisconnected(huburl)

    Хаб отключен
    OnUserUpdated(uid)

    Юзер передал $MyInfo (BINF) - пришёл на хаб или обновил параметры
    OnUserDisconnected(uid)

    Юзер ушёл с хаба
    OnPublicMessage(uid, msg)

    приём сообщения от юзера в общий чат. хаб может быть выбран из uid юзера фунцией GetUserInfo
    OnStatusMessage(huburl, msg)

    приём системного сообщения хаба
    OnPrivateMessage(uid, msg)

    приём личного сообщения от юзера
    OnDownloadFinished(path, uid)

    завершена скачка файла path. uid - источник файла или источник последнего сегмента, в случае мультискачки
    PreviewPublicMessage(huburl, msg) / PreviewPrivateMessage(uid, msg)

    Проверка сообщения перед отправкой в общий/приватный чат

    Функция возвращает 0 (nil), если не вмешивается в передачу сообщения,

    возвращает 1, чтобы отменить посылку сообщения (возможно, с последующей посылкой

    исправленного сообщения функциями SendPublicMessage / SendPrivateMessage),

    или возвращает 2, чтобы отменить посылку сообщения без очистки строки ввода сообщения
    OnTimer()

    Вызывается раз в секунду после DC():RunTimer(1)

    Примеры

    sample1.lua

    Бот - повторялка (только в личке)

    Запустить можно командой /luafile sample1.lua

    sample2.lua

    Бот - перекидывает все обращения из лички в общий чат

    sample3.lua

    Считывает файл Favorites.xml и выводит случайно выбранную строку в чат хаба 127.0.0.1

    sample4.lua

    Замена "graylink" на "greylink" во всех отправляемых сообщениях. Запрет отправки строки "fly"

    sample5.lua

    Выбор случайного ника из файла nicklist.txt при каждом переподключении к хабу

    spam.lua

    Бот - пишет с заданным периодом спам в общий чат заданного хаба

    Для загрузки бота используется команда /luafile spam.lua