Lua скрипт: Гайд по использованию Lua-скриптов в Redis
Гайд по использованию Lua-скриптов в Redis
Что такое язык Lua?
Язык программирования Lua появился в 1993 году. По своей структуре он является компактным языком программирования, который можно встраивать практически в любое приложение — от World of Warcraft до веб-сервера Nginx. Ну и конечно же, в Redis, о котором далее и пойдёт речь.
Благодаря Lua в Redis возможно встраивать собственные скриптовые расширения для базы данных. Вызов скриптов выглядит следующим образом:
> EVAL 'local val="Hello Compose" return val' 0
"Hello Compose"
Далее сам Lua-скрипт:
local val="Hello Compose"
return val
Что более важно, вы можете запускать скрипты в качестве «умных транзакций». Это позволяет обрабатывать ошибки в рантайме, не останавливая приложение. Безусловно, то, насколько «умными» будут эти транзакции, зависит целиком и полностью от вас.
Ключи и аргументы
Для обращения к скрипту неплохо бы было передать ему ключи и аргументы. Например, как в нижеприведённом коде:
> EVAL 'local val="Hello Compose" return val' 0
В конце EVAL
мы видим ноль — это количество ключей, переданных скрипту. Но если вместо ноля написать 2 foo bar fizz buzzthen
, первые два элемента foo
и bar
будут переданы в качестве ключей, а fizz
и buzz
— в качестве аргументов.
Ключи доступны Lua-скрипту в таблице KEYS
. Таблица в Lua — это ассоциативный массив, который также используется в качестве массива из одного элемента. Если помимо ключей используются аргументы, они будут доступны в таблице ARGV
, например:
return ARGV[1]..' '..KEYS[1]
В Lua ..
используется в качестве оператора объединения, так что здесь в качестве возвращаемого значения мы получаем аргумент, привязанный к пробелу, и название ключа, которое было передано в качестве аргумента:
> EVAL "return ARGV[1]. .' '..KEYS[1]" 1 name:first "Hello"
"Hello name:first"
Никакой магии в KEYS, это просто строка, так что нам по-прежнему нужно получить их значение.
Что касается вызова Redis из Lua, можно использовать функцию redis.call()
. Например:
> EVAL 'return ARGV[1].." "..redis.call("get",KEYS[1])' 1 name:first "Hello"
"Hello Brian"
Прим. автора Если в процессе объединения вы получаете ошибку «attempt to concatenate a boolean value» (попытка объединения значений булевого типа), скорее всего name:first
не было присвоено какое-либо значение.
Таким образом, скрипт взял параметр, нашёл значение ключа и вернул в качестве вывода созданную строку.
Однако помимо EVAL
есть и другой способ передать скрипт на сервер. Например, используя аргументы команды redis-cli
. Попробуем написать чуть более сложный скрипт:
lua
local name=redis.call("get", KEYS[1])
local greet=ARGV[1]
local result=greet. ." "..name
return result
Сохраним его как longhello.lua
и выполним в командной строке:
$ redis-cli -h aws-us-east-1-portal.15.dblayer.com -p 11260 -a secret --eval longhello.lua name:first , Hello
"Hello Brian"
Итак, мы запускаем redis-cli
, добавляем параметры -h
, -p
и -a
для связи с базой данных. Затем идёт --eval
, позволяющий указать имя файла, в виде которого скрипт отправится на сервер. Также нашему скрипту понадобятся ключи и аргументы. В данном случае ключами являются указанные до первой запятой параметры команды.
Сложные скрипты
Следующий случай наглядно демонстрирует, как Lua решает одну небольшую проблему. Допустим, разные пользователи или разработчики увеличивают счётчики в большой структуре данных. Например, region:one
увеличивает count:emea
, count:usa
, count:atlantic
, в то время как region:two
затрагивает лишь count:usa
. Эти счётчики могут быть добавлены позже, но вдруг вам важно убедиться, что добавятся они все разом? Самое время вспомнить про «умные транзакции».
Добавим все наши регионы в список:
> rpush region:one count:emea count:usa count:atlantic
(integer) 3
> rpush region:two "count:usa"
(integer) 1
Создадим локальную переменную:
local count=0
Начнём с переменной-счётчика — он будет считать все операции по увеличению наших округов.
local broadcast=redis.call("lrange", KEYS[1], 0,-1)
Теперь запросим у Redis все значения списка, относящиеся к первому ключу.
for _,key in ipairs(broadcast) do
Здесь мы запустили цикл, в котором функция ipairs()
просмотрит каждую задействованную Lua-таблицу и передаст из неё ключ.
redis.call("INCR",key)
count=count+1
end
return count
С каждым вызовом мы увеличиваем указанный ключ, а заодно и наш счётчик.
После окончания цикла мы получаем конечное число итераций. Сохраним итоговый скрипт и запустим его на сервере:
$ redis-cli -h aws-us-east-1-portal.15.dblayer.com -p 11260 -a secret --eval broadcast.lua region:one
(integer) 3
В таблице будут содержаться следующие значения:
> mget count:usa count:atlantic count:emea
1) "1"
2) "1"
3) "1"
Значения для region.two
:
$ redis-cli -h aws-us-east-1-portal.15.dblayer.com -p 11260 -a secret --eval broadcast.lua region:two
(integer) 1
> mget count:usa count:atlantic count:emea
1) "2"
2) "1"
3) "1"
Но что, если бы во время выполнения скрипта произошла ошибка? Он просто продолжил бы выполняться, игнорируя её. Для вывода деталей ошибки следует использовать redis.pcall()
.
Кэширование скриптов
Для того чтобы не загружать скрипт каждый раз перед выполнением, можно использовать команду SCRIPT LOAD
для загрузки скрипта в кэш. Рассмотрим пример использования из командной строки:
$ redis-cli -h aws-us-east-1-portal.15.dblayer.com -p 11260 -a secret SCRIPT LOAD "$(cat broadcast.lua)"
"84ffc8b6e4b45af697cfc5cd83894417b7946cc1"
Здесь $(cat broadcast.lua)
превращает наш скрипт в аргумент. А шестнадцатеричное число ниже — SHA1-подпись нашего скрипта. Её можно использовать для его последующего вызова командой EVALSHA
:
> EVALSHA 84ffc8b6e4b45af697cfc5cd83894417b7946cc1 1 region:one
(integer) 3
Также есть команды для проверки наличия скрипта на сервере и его удаления — SCRIPT EXISTS
и SCRIPT FLUSH
соответственно.
Не всё так просто
После довольно небольшого промежутка времени (по умолчанию — 5 секунд) Lua-скрипты начнут выдавать ошибки в ответ на запросы — в таком случае возможно только «убить» скрипт командой KILL SCRIPT
либо выключить сервер командой SHUTDOWN NOSAVE
. С другой стороны, 5 секунд — очень щедрое ограничение, ведь ваши скрипты должны выполняться буквально в течение миллисекунд. И на это есть очень веская причина: во время выполнения ваших скриптов все остальные процессы приостанавливаются.
Заключение
Итак, в этой статье мы рассмотрели примеры написания простых и сложных Lua-скриптов, их вызов из Redis, а также запись и хранение на сервере.
Перевод статьи «A Speed Guide To Redis Lua Scripting»
Гайд — Написание Lua скриптов для MoonLoader | BLASTHACK
Данная тема посвящена нюансам и особенностям разработки Lua скриптов для MoonLoader.
Список вопросов:
Начало разработки.
Взаимодействие с игроками.
Работа с переменными.
Работа с командами.
Начало разработки.
Каждый Lua скрипт при запуске создает поток «main» который и является основным местом работы со скриптом.
Сразу обговорим — скрипт «жив» пока «жив» поток main(), поэтому если мы хотим продолжать работать со скриптом после запуска — будем держать поток активным:
function main() -- Объявляем поток main()
wait(-1) -- Устанавливаем бесконечное ожидание
end -- закрываем функцию
Запускаем скрипт — работает!
Что ж, поставим себе цель — при запуске выводить сообщение «Привет мир» в чат.
Что нам для этого нужно?
Заходим на WIKI (Раздел «Функции» moonloader`a) и ищем функции чата — Поиск -> «Chat». Видим функцию sampAddChatMessage(message, color) — то что надо.
Вставляем:
function main()
sampAddChatMessage("Привет мир!", 0xFFFFFFFF) -- Выводим сообщение в чат
wait(-1) -- Устанавливаем бесконечное ожидание
end
Запускаем скрипт — ошибка?
(error) test.lua: opcode '0AF8' call caused an unhandled exception
Бежим на WIKI (Опять раздел «Функции» moonloader`a) и в поиск вводим наш опкод «0AF8».
Находим нашу функцию sampAddChatMessage()
Что это значит? Дело в том что нельзя вызывать функции для работы с SA:MP пока сам SA:MP не готов. Что делать? Добавим перед выводом сообщения такой код:
if not isSampfuncsLoaded() or not isSampLoaded() then -- Если SF или SA:MP не загружены
return -- Завершаем работу скрипта
end
while not isSampAvailable() do -- Ждём пока функция isSampAvailable() вернет true
wait(0) -- Устанавливаем минимальное ожидание, что бы наша игра не зависла
-- значение 0 говорит что мы ждём следующий кадр (Frame)
end
Теперь наш скрипт будет ждать пока самп полностью не загрузится и продолжит выполнение кода.
Что такое wait() и с чем его едят?
Wait позволяет ставить поток в режим ожидания на указанное количество мили-секунд (ms)
Wait нельзя в CallBack-функциях, это приведет к ошибке, а в последствии и смерти, скрипта.
Почему мы ставим 0? Потому-что это минимальная задержка.
Подведем краткий итог кода:
function main()
if not isSampfuncsLoaded() or not isSampLoaded() then
return
end
while not isSampAvailable() do
wait(0)
end
sampAddChatMessage("Привет мир!", 0xFFFFFFFF)
wait(-1)
end
Теперь при входе в игру / перезапуске скрипта в чат будет выводиться сообщение «Привет мир».
К списку вопросов
Взаимодействие с игроками
Перейдем к примерам посложнее — попробуем получить ник, ид и счет игрока в которого мы прицелились.
Цель поставили, какие нам нужны средства?
Опять бежим к WIKI, всё в тот же раздел функций и ищем функции связанные с целями, Поиск -> Target.
Смотрим в списке есть getCharPlayerIsTargeting(ped).
Она возвращает 2 значения — result, ped.
Первое значение — возвращает результат проверки на целится ли указанный Ped в кого-либо.
Второе — если указанный Ped целится — возвращает саму цель.
Как нам это использовать? Всё просто, уберем бесконечное ожидание и будем проверять значение result.
function main()
if not isSampfuncsLoaded() or not isSampLoaded() then
return
end
while not isSampAvailable() do
wait(0)
end
sampAddChatMessage("Привет мир!", 0xFFFFFFFF)
while true do -- Создаем бесконечный цикл, вместо бесконечного ожидания
wait(0) -- Опять таки чтобы наша игра не зависла, ждем след кадр
local result, ped = getCharPlayerIsTargeting(PLAYER_HANDLE) -- Каждый кадр получаем данные функции, PLAYER_HANDLE - возвращает ваш Handle
if result then -- Если result вернет true
print("True!") -- Выведем сообщение в лог / консоль
end
end
end
Что мы можем с этим делать? Теперь если мы целимся в кого-либо, мы увидим сообщения в moonloader. log об этом. Мы получили Ped игрока в которого мы целимся. Давайте используем эту информацию.
function main()
if not isSampfuncsLoaded() or not isSampLoaded() then
return
end
while not isSampAvailable() do
wait(0)
end
sampAddChatMessage("Привет мир!", 0xFFFFFFFF)
while true do
wait(0)
local result, ped = getCharPlayerIsTargeting(playerPed)
if result then
local result2, id = sampGetPlayerIdByCharHandle(ped) -- Попробуем получить ID игрока по его Ped
if result2 then -- Если получилось
local nickname = sampGetPlayerNickname(id) -- Запишем его ник
local score = sampGetPlayerScore(id) -- и счет
sampAddChatMessage(string.format("%s[%d] имеет счет %d", nickname, id, score), -1) -- И выведем это в чат
end
end
end
end
К списку вопросов
Работа с переменными
Что у нас получилось? Мы будем получать кучу сообщений в чат о игрока по пока целимся в кого-либо, но как убрать этот флуд?
Давайте создадим переменную перед main(), например targeting, и присвоим ей значение false.
И задействуем её в коде
local targeting = false -- Создаем булевую переменную
function main()
if not isSampfuncsLoaded() or not isSampLoaded() then
return
end
while not isSampAvailable() do
wait(0)
end
sampAddChatMessage("Привет мир!", 0xFFFFFFFF)
while true do
wait(0)
local result, ped = getCharPlayerIsTargeting(playerPed)
if result and not targeting then -- Если мы целимся, но ранее ни в кого не целились
local result2, id = sampGetPlayerIdByCharHandle(ped)
if result2 then
local nickname = sampGetPlayerNickname(id)
local score = sampGetPlayerScore(id)
sampAddChatMessage(string.format("%s[%d] имеет счет %d", nickname, id, score), -1)
targeting = true -- запишем что мы целимся в кого либо и наше условие выше станет ложным
end
elseif not result and targeting then -- Если условие обратное - скажем скрипту что мы не целимся
targeting = false
end
end
end
Отлично, теперь если мы целимся в игрока — получаем одно сообщение, меняем цель или заново целимся в того же игрока — снова получим о нём информацию.
К списку вопросов
Работа с командами.
Уже лучше, давайте теперь работаем с командами.
Уберем лишний код и оставим следующее:
function main()
if not isSampfuncsLoaded() or not isSampLoaded() then
return
end
while not isSampAvailable() do
wait(0)
end
while true do
wait(0)
end
end
Как добавить команду? Давайте опять порыщем на WIKI, Поиск -> Command
Нашли sampRegisterChatCommand(command, callback)? Отлично, можно уже приступать.
Зарегистрируем нашу команду, например «toster»:
function main()
if not isSampfuncsLoaded() or not isSampLoaded() then
return
end
while not isSampAvailable() do
wait(0)
end
sampRegisterChatCommand("toster", tosterCallBack) -- Регистрируем ДО бесконечного цикла.
-- Первый параметр - команда, без слэша.
-- Второй - функция-callback которая будет вызваться если будет введена команда.
wait(-1) -- Уберем бесконечный цикл, он тут вовсе не нужен, но нам же нужно чтобы скрипт работал
end
function tosterCallBack(params)
sampAddChatMessage("Дзынь!", -1)
end
Теперь при вводе команды «/toster» мы увидим в чате сообщение. Успех? Но как например вывести свой текст в чат? Легко!
sampAddChatMessage(params, -1)
Теперь мы выводим весь текст после команды «/toster» в чат. Например: /toster Привет жалкий мирок!
Помните я говорил что нельзя использовать wait() внутри callback-функций, это всё еще так, но есть тут одна хитрость!
function tosterCallBack()
sampAddChatMessage("Дзынь!", -1)
lua_thread. create(function() -- Создаем новый поток
wait(5000) -- Ждём 5 секунд
sampAddChatMessage("Тоже дзынь, но на 5 секунд позже!", -1) -- Выводим текст в чат
end) -- Тут наш поток умирает :(
end
К списку вопросов
На сегодня всё, теперь вы чертовы волшебники, поняв как всё работает, можно приступать к изучению примеров Lua скриптов!
Тема будет дополняться по мере изучения популярных вопросов по Lua скриптингу.
Спойлер: Хейтерам
Я понимаю что вы невъебенные мастера луа скриптинга, но это тема не для вас
DC — Скрипты Lua
Double Commander может выполнять скрипты Lua с помощью команды cm_ExecuteScript.
Эта возможность добавлена в версии 0.8.
Также на языке Lua возможно писать контентные (или информационные) плагины (WDX-плагины).
Более подробную информацию о языке программирования Lua можно найти на официальном веб-сайте Lua.
(наверх)
Чтобы использовать скрипты Lua, нам требуется интерпретатор Lua версии 5.1 или выше, DLL-файл должен лежать рядом с исполняемым файлом Double Commander или в системной папке.
По умолчанию DC ищет файл с именем lua5.1.dll
(Windows), liblua5.1.so.0
(Unix или GNU/Linux) или liblua5.1.dylib
(Mac OS). Мы можем вручную изменить имя файла в параметре <PathToLibrary>.
Мы можем использовать DLL-файл проекта LuaJIT.
LuaJIT сочетает в себе высокоскоростной интерпретатор, написанный на ассемблере, и JIT-компилятор. Также мы получаем библиотеку FFI: с её помощью в скриптах можно будет вызывать внешние функции C и использовать структуры данных C.
DLL для Windows: 32-битная или 64-битная.
Если мы используем 64-битную версию DC, то DLL-файл также должен быть 64-битным.
Дистрибутивы DC для Windows включают в себя DLL-файл Lua (в DC 0. 9.7 и новее из проекта LuaJIT), в иных случаях мы можем найти и установить его с помощью менеджера пакетов или скомпилировать.
(наверх)
Double Commander предлагает несколько библиотек функций для скриптов Lua, список представлен ниже.
(наверх)
Эта библиотека содержит особые функции Double Commander, все функции представлены в таблице DC
.
Библиотека DC | |
---|---|
Функция | Описание |
DC.LogWrite | DC.LogWrite(Message, MsgType, bForce, bLogFile) Пишет сообщение в окно протокола. Описание:
|
DC.CurrentPanel | iPanel = DC.CurrentPanel() Получить активную панель: возвращает 0, если активна левая панель, или 1, если правая. DC.CurrentPanel(iPanel) Сделать активной: левую панель, если iPanel равно 0, или правую, если равно 1. |
DC.ExecuteCommand | DC.ExecuteCommand(Command, Param1, Param2,…,ParamX) Вызывает внутреннюю команду Double Commander Command с параметрами Param1..ParamX. Мы можем подставить столько Param…, сколько поддерживает команда Command. |
(наверх)
В этом примере мы написали простой скрипт, который сделает следующее:
- перенесёт фокус на правую панель
- закроет все открытые вкладки
- перейдёт в указанную папку
- перенесёт фокус на левую панель
- закроет все открытые вкладки
- перейдёт в указанный каталог
- откроет новую вкладку
- перейдёт в указанный каталог
-- 1. Перенести фокус на правую панель. DC.ExecuteCommand("cm_FocusSwap", "side=right") -- 2. Закрыть все вкладки. DC.ExecuteCommand("cm_CloseAllTabs") -- 3. Перейти в указанный каталог. DC.ExecuteCommand("cm_ChangeDir", "e:\\FakeKey\\Documents\\Music") -- 4. Перенести фокус на левую панель. DC.ExecuteCommand("cm_FocusSwap", "side=left") -- 5. Закрыть все вкладки. DC.ExecuteCommand("cm_CloseAllTabs") -- 6. Перейти в указанный каталог. DC.ExecuteCommand("cm_ChangeDir", "C:\\Users\\Public\\Music") -- 7. Открыть новую вкладку. DC.ExecuteCommand("cm_NewTab") -- 8. Перейти в указанный каталог. DC.ExecuteCommand("cm_ChangeDir", "e:\\VirtualMachines\\ShareFolder")
Для выполнения нашего скрипта мы можем создать кнопку на панели инструментов с внутренней командой cm_ExecuteScript.
Предположим, наш скрипт e:\scripts\lua\music.lua
, мы могли бы настроить эту кнопку следующим образом:
Кроме того, для редактирования наших скриптов мы можем использовать внутренний редактор Double Commander.
Если файл имеет расширение .lua
, то он будет распознан внутренним редактором и открыт с подсветкой синтаксиса, специфичного для языка Lua:
(наверх)
Эта библиотека содержит различные системные функции, все они представлены в таблице SysUtils
.
Библиотека System | |
---|---|
Функция | Описание |
SysUtils.Sleep | SysUtils.Sleep(Milliseconds) Приостанавливает выполнение скрипта на указанное количество миллисекунд (Milliseconds), выполнение сценария будет продолжено после истечения указанного времени. |
SysUtils.GetTickCount | SysUtils.GetTickCount() Возвращает количество интервалов времени (тиков) с момента старта системы. Это полезно для измерения времени, но не следует делать каких-либо предположений относительно количества времени в интервале между тиками. |
SysUtils.FileExists | bFlagExists = SysUtils.FileExists(FileName) Проверяет, существует ли в файловой системе определённый файл. FileExists возвращает |
SysUtils.DirectoryExists | bFlagExists = SysUtils.DirectoryExists(Directory) Проверяет существование Directory в файловой системе и что это действительно каталог. Если это так, то функция возвращает |
SysUtils.FileGetAttr | Attr = SysUtils.FileGetAttr(FileName) Возвращает в Attr атрибуты файла FileName. Подробное описание возвращаемого значения смотрите здесь. |
SysUtils.FindFirst | Handle, FindData = SysUtils.FindFirst(Path) Ищет файлы, совпадающие с Path (можно использовать маски). Если файл не найден, Handle будет равно nil. В случае успеха функция вернёт дескриптор поиска Handle для последующих вызовов Таблица FindData содержит информацию о найденном файле или каталоге. Поля таблицы FindData:
|
SysUtils.FindNext | Result, FindData = SysUtils.FindNext(Handle) Находит следующее вхождение поиска, инициированного FindFirst, Handle — дескриптор поиска, возвращённый функцией FindFirst. В случае успеха функция вернёт Result не равный nil и таблицу FindData, содержащую информацию о найденном файле или каталоге. Замечание: За последним вызовом |
SysUtils.FindClose | SysUtils.FindClose(Handle) Завершает серию вызовов Вызов этой функции абсолютно необходим, иначе могут возникнуть большие утечки памяти. |
SysUtils.CreateHardLink | bResult = SysUtils.CreateHardLink(Path, LinkName) Создаёт жёсткую ссылку LinkName на файл Path. Возвращет |
SysUtils.CreateSymbolicLink | bResult = SysUtils.CreateSymbolicLink(Path, LinkName) Создаёт символьную ссылку LinkName на файл Path. Возвращет |
SysUtils.ReadSymbolicLink | sTarget = SysUtils.ReadSymbolicLink(LinkName, Recursive) Читает имя файла, на который указывает символьная ссылка LinkName. Если Recursive равно Возвращает путь, на который указывает символьная ссылка LinkName или пустую строку, если ссылка недействительна или файл, на который она указывает, не существует и значение Recursive равно |
SysUtils.PathDelim | SysUtils.PathDelim Позволяет получить от DC разделитель пути в системе. В системах Unix/Linux это будет » / » и » \ » в Windows. |
SysUtils.ExtractFileName | sName = SysUtils.ExtractFileName(FileName) Возвращает имя файла из полного (имя+путь) имени файла. Имя файла содержит все символы после последнего символа разделителя каталогов («/» или «\») или буквы диска. |
SysUtils.ExtractFilePath | sPath = SysUtils.ExtractFilePath(FileName) Возвращает путь из полного имени файла (включая букву диска). Путь содержит все символы до последнего символа разделителя каталогов («/» или «\»), включая сам разделитель каталогов. |
SysUtils.ExtractFileDir | sDir = SysUtils.ExtractFileDir(FileName) Возвращает только каталог из FileName, включая букву диска. Результат НЕ содержит разделитель каталогов в конце, в отличие от |
SysUtils.ExtractFileDrive | sDrive = SysUtils.ExtractFileDrive(FileName) Возвращает диск из полного имени файла. Обратите внимание, некоторые операционные системы не поддерживают буквы дисков. |
SysUtils.ExtractFileExt | sExt = SysUtils.ExtractFileExt(FileName) Возвращает расширение файла (все символы после последней точки, включая сам символ «.»). |
SysUtils.CreateDirectory | bResult = SysUtils.CreateDirectory(Directory) Создаёт цепочку каталогов, Directory — полный путь каталога. Возвращает |
(наверх)
FileGetAttr возвращает атрибуты FileName в виде ИЛИ-совокупности следующих констант:
Константы, используемые в возвращаемом значении SysUtils. FileGetAttr | |
---|---|
Значение | Описание |
0x00000001 | Файл только для чтения. |
0x00000002 | Скрытый файл. В Unix/Linux это значит, что имя файла начинается с точки. |
0x00000004 | Системный файл. В Unix/Linux это может быть символьное или блочное физическое устройство, именованный канал (FIFO). |
0x00000008 | Метка тома (означает, что файл содержит идентификатор (ID) тома). Только для DOS/Windows 9x на обычной файловой системе FAT (не VFAT или FAT32). |
0x00000010 | Каталог. |
0x00000020 | Архивный. Не используется в Unix/Linux. |
0x00000400 | Символьная ссылка. |
Примечание: В случае ошибки функция возвращает -1. |
Смотрите пример в следующей секции.
(наверх)
Пример скрипта ниже использует SysUtils.FileGetAttr.
Если параметр окажется каталогом, то скрипт откроет его в новой вкладке активной панели и переключится на неё.
local params = {...} local myfileattr if #params == 1 then -- Мы получили один параметр? myfileattr = SysUtils.FileGetAttr(params[1]) if myfileattr > 0 then -- Получили значение атрибута? if math.floor(myfileattr / 0x00000010) % 2 ~= 0 then -- 0x00000010 присутствует? Тогда это каталог. DC.ExecuteCommand("cm_NewTab") DC.ExecuteCommand("cm_ChangeDir", params[1]) end end end
В приведённом выше примере param[1] является первым параметром, переданным скрипту.
При использовании внутренней команды cm_ExecuteScript это будет первый параметр, переданный после имени файла скрипта.
Итак, в нашем примере мы можем создать на панели инструментов кнопку, как показано ниже:
В этом примере скрипту будет передан параметр %»0%p: имя выделенного в активной панели файла или папки, без кавычек.
(наверх)
В следующем примере мы просканируем содержимое каталога, переданного первым параметром, и сохраним полученные данные в текстовый файл с именем, переданным вторым параметром.
Это даст нам хорошее представление об использовании FindFirst, FindNext и FindClose.
local params = {...} if #params == 2 then -- У нас есть два параметра? local Result = nil local OutputFile = nil OutputFile = io.output(params[2]) local Handle,FindData = SysUtils.FindFirst(params[1] .. "\\*") if Handle ~= nil then repeat io. write(FindData.Name .. "\r") io.write(FindData.Size .. "\r") io.write("---------------\r") Result,FindData = SysUtils.FindNext(Handle) until Result == nil SysUtils.FindClose(Handle) io.close(OutputFile) end end
В приведённом выше примере нам нужно передать скрипту два параметра:
- param[1] — каталог, содержимое которого мы хотим получить
- param[2] — имя файла для сохранения результата работы скрипта
Настраиваем кнопку на панели инструментов с внутренней командой cm_ExecuteScript и передаём параметрами всё необходимое:
В этом примере скрипту в качестве первого параметра будет передано %»0%Ds: имя каталога активной панели, без кавычек.
(наверх)
Double Commander предоставляет скриптам Lua библиотеку функций для работы с буфером обмена.
Библиотека Clipboard | |
---|---|
Функция | Описание |
Clipbrd. Clear | Clipbrd.Clear() Очищает содержимое буфера обмена. |
Clipbrd.GetAsText | StringVar = Clipbrd.GetAsText() Получает содержимое буфера обмена как строку StringVar. |
Clipbrd.SetAsText | Clipbrd.SetAsText(StringVar) Помещает в буфер обмена строку текста StringVar. |
Clipbrd.SetAsHtml | Clipbrd.SetAsHtml(Html) Добавляет в буфер обмена текст Html в формате HTML (формат буфера обмена Содержимое может быть вставлено в приложения, поддерживающие этот формат буфера обмена, такие как MS Word, LO Writer и другие. Правильным будет сохранять данные с помощью и Например, у нас может быть следующее:
Если мы запустим Блокнот и попытаемся вставить текст из буфера обмена, то будет вставлен текст, скопированный с помощью |
(наверх)
В следующем примере используются три функции, связанные с буфером обмена: Clear
, GetAsText
и SetAsText
.
Это относительно большой скрипт, но было бы неплохо собрать вместе несколько функций, с которыми мы познакомились ранее.
Предполагается, что в нашей активной панели открыт каталог с большим количеством текстовых файлов.
Также предполагается, что в настоящее время в буфере обмена одно слово и что скрипт в качестве единственного параметра получит текущий каталог активной панели.
Скрипт будет сканировать папку, читать содержимое файлов, один за другим, и искать слово из буфера обмена.
Затем имена файлов, которые содержат это словом, будут скопированы в буфер обмена.
Далее скрипт вызовет внутреннюю команду cm_LoadSelectionFromClip и все эти файлы будут выделены.
Кроме того, в конце вернём обратно в буфер обмена слово, которое мы искали.
local params = {...} local Result = nil local myfileattr local bFound = false local sCompleteFilename = "" local InputFile = nil local line = "" local iPosS local iPosE local sFileToSelect = "" local sSearchString = "" if #params == 1 then -- Мы получили наш параметр? sSearchString = Clipbrd. GetAsText() -- Получаем выражение для поиска. Clipbrd.Clear() -- Очищаем буфер обмена. DC.ExecuteCommand("cm_MarkUnmarkAll") -- Убедимся, что ничего не выделено. -- Начинаем сканировать все файлы нашего каталога один за другим. local Handle,FindData = SysUtils.FindFirst(params[1] .. "\\*") if Handle ~= nil then repeat sCompleteFilename = params[1] .. "\\" .. FindData.Name myfileattr = SysUtils.FileGetAttr(sCompleteFilename) if myfileattr > 0 then -- Получили значение атрибута? -- Нам нужен файл, не каталог! if math.floor(myfileattr / 0x00000010) % 2 == 0 then -- Начинаем читать файл построчно, до конца файла ИЛИ до совпадения. InputFile = io.open(sCompleteFilename, "r") bFound = false while bFound == false do line = InputFile:read() if line == nil then break end iPosS, iPosE = string.find(line, sSearchString) if iPosS ~= nil then bFound = true end end if bFound == true then sFileToSelect = sFileToSelect . . FindData.Name .. "\n" end io.close(InputFile) end end Result,FindData = SysUtils.FindNext(Handle) until Result == nil SysUtils.FindClose(Handle) end -- Если что-то нашли, то выделяем! if sFileToSelect ~= "" then Clipbrd.SetAsText(sFileToSelect) DC.ExecuteCommand("cm_LoadSelectionFromClip") end Clipbrd.SetAsText(sSearchString) -- Восстанавливаем содержимое буфера обмена. end
(наверх)
Эта библиотека позволяет нашим скриптам взаимодействовать с пользователем, показывая сообщения, выдавая запросы и т.д.
Библиотека Dialogs | |
---|---|
Функция | Описание |
Dialogs.MessageBox | ButPressed = Dialogs.MessageBox(Message, Title, ButFlags) Показывает окно сообщения, функция вернёт нажатую пользователем кнопку. Описание:
|
Dialogs.InputQuery | bAck, sAnswer = Dialogs.InputQuery(Title, Msg, bMask, sDefault) Показывает диалоговое окно с полем ввода текста. Описание:
|
Dialogs.InputListBox | sAnswer = Dialogs.InputListBox(Title, Msg, Items, sDefault) Показывает диалоговое окно с возможностью выбора из списка элементов. Описание:
|
(наверх)
Кнопки, отображаемые в окне Dialogs. MessageBox
, задаются одним из следующих значений:
(наверх)
Стиль окна Dialogs.MessageBox
задаётся одним из следующих значений:
Константы, задающие значок и стиль окна Dialogs.MessageBox | |
---|---|
Значение константы | Стиль окна |
0x0040 | Информационное окно |
0x0030 | Окно предупреждения |
0x0020 | Окно подтверждения |
0x0010 | Окно ошибки |
(наверх)
Кнопка по умолчанию (активная) в Dialogs.MessageBox
задаётся одним из следующих значений:
Константы, задающие кнопку по умолчанию в Dialogs. MessageBox | |
---|---|
Значение константы | Кнопка по умолчанию |
0x0000 | Первая кнопка слева |
0x0100 | Вторая кнопка слева |
0x0200 | Третья кнопка слева |
(наверх)
Число, возвращаемое функцией Dialogs.MessageBox
, указывает на кнопку, которую нажал пользователь, и может быть одним из следующих:
Возвращаемое значение Dialogs.MessageBox | |
---|---|
Значение константы | Нажатая кнопка |
0x0000 | Кнопка не нажата |
0x0001 | |
0x0002 | |
0x0003 | |
0x0004 | |
0x0005 | |
0x0006 | |
0x0007 |
Примечание: Если закрыть окно, нажав крестик «x» в углу окна или клавишу Esc, то функция вернёт 0x0002
, как нажатие кнопки Отмена.
(наверх)
Маленький скрипт, использующий Dialogs.MessageBox
:
-- Отображаемые кнопки MB_OK = 0x0000 MB_OKCANCEL = 0x0001 MB_ABORTRETRYIGNORE = 0x0002 MB_YESNOCANCEL = 0x0003 MB_YESNO = 0x0004 MB_RETRYCANCEL = 0x0005 -- Стиль окна MB_ICONINFORMATION = 0x0040 MB_ICONWARNING = 0x0030 MB_ICONQUESTION = 0x0020 MB_ICONERROR = 0x0010 -- Кнопка по умолчанию MB_DEFBUTTON1 = 0x0000 MB_DEFBUTTON2 = 0x0100 MB_DEFBUTTON3 = 0x0200 -- Возвращаемое значение mrNone = 0x0000 mrOK = 0x0001 mrCancel = 0x0002 mrAbort = 0x0003 mrRetry = 0x0004 mrIgnore = 0x0005 mrYes = 0x0006 mrNo = 0x0007 ButFlags = MB_YESNO + MB_ICONQUESTION + MB_DEFBUTTON2 ButPressed = Dialogs.MessageBox("Хотите завершить?", "Вопрос", ButFlags) if ButPressed == mrYes then DC.ExecuteCommand("cm_Exit") end
(наверх)
Маленький скрипт, использующий Dialogs.InputQuery
:
bAck, sAnswer = Dialogs. InputQuery("Идентификация", "Введите ваше имя:", false, "Иван") if bAck == true then Dialogs.MessageBox("Привет, " .. sAnswer .. "!", "Добро пожаловать!", 0x0040) end
(наверх)
Эта библиотека обеспечивает базовую поддержку кодировки UTF-8.
Все функции представлены в таблице LazUtf8
.
Библиотека UTF-8 | |
---|---|
Функция | Описание |
LazUtf8.Pos | Result = LazUtf8.Pos(SearchText, SourceText, Offset) Поиск подстроки в строке, начиная с определённой позиции. Поиск чувствителен к регистру. Возвращает позицию первого вхождения подстроки SearchText в строке SourceText, поиск начинается с позиции Offset (по умолчанию 1). Если в SourceText не найдено совпадение с SearchText после заданного Offset, то функция возвращает ноль. |
LazUtf8.Copy | Result = LazUtf8.Copy(Source, Index, Count) Копирует (извлекает) часть строки. Функция возвращает Count символов из строки Source, начиная с позиции Index. Если Count больше длины строки Source, то результат усекается. Если Index больше длины строки Source, то возвращается пустая строка. |
LazUtf8.Length | Result = LazUtf8.Length(String) Возвращает количество символов в строке с учётом кодировки UTF-8. |
LazUtf8.UpperCase | Result = LazUtf8.UpperCase(String) Возвращает строку, в которой все буквы в нижнем регистре (строчные) заменены на буквы в верхнем регистре (прописные или заглавные). |
LazUtf8.LowerCase | Result = LazUtf8.LowerCase(String) Возвращает строку, в которой все буквы в верхнем регистре (прописные или заглавные) заменены на буквы в нижнем регистре (строчные). |
LazUtf8.ConvertEncoding | Result = LazUtf8.ConvertEncoding(String, FromEnc, ToEnc) Конвертирует кодировку String из FromEnc в ToEnc. Список поддерживаемых значений кодировок:
Специальные значения кодировок (примеры). В Windows с русской локалью:
В Linux с русской локалью:
|
(наверх)
Эта библиотека содержит функции, связанные с операционной системой, в которой запущен Double Commander.
Список доступных функций:
Библиотека OS | |
---|---|
Функция | Описание |
os. execute | resultcode = os.execute(command) Выполнить command, аналогично введённой в командной строке, будет возвращён код завершения. command может быть:
|
os.tmpname | tempfilename = os.tmpname() Возвращает строку с именем файла, который может быть использован в качестве временного файла. |
os.remove | bresult, errorstr, errorno = os.remove(filename) Удалить файл с именем filename. Если удалось, функция вернёт true. Если не удалось, функция вернёт:
|
os.rename | bresult, errorstr, errorno = os.rename(nameS, nameD) Переименовать файл nameS в nameD. Если удалось, функция вернёт true. Если не удалось, функция вернёт:
|
os.getenv | value = os.getenv(variablename) Получить в value значение переменной окружения variablename. |
(наверх)
Lua-скрипты: примеры, как установить и запустить
Lua не является интерпретированным языком и генерирует байт-код из другой программы, например, Java. Эта программа работает на виртуальной машине Lua VM. Большинство таких устройств называются стеками, но Lua отличается тем, что она основана на регистрах и является одной из первых широко используемых VM в игровой сфере.
Преимущество регисторной архитектуры заключается в том, что она позволяет избежать большого количества копированных данных и уменьшает объем инструкций для функции. Lua VM обладает автоматическим управлением памяти и сбросом ненужной информации, что обеспечивает идеальную конфигурацию для создания сценариев быстрого прототипирования.
Коротко про Луа
Lua — это простой в освоении и быстрый скриптовый язык с синтаксисом типа pascal. Это позволяет начинающим программистам писать свои собственные программы. Он используется во многих играх и приложениях для расширения существующей функциональности и программирования пользовательских последовательностей. В интернете есть много обучающих программ, которые помогают работать на этом языке, в том числе много информации можно найти на домашней странице Lua.
Этот язык программирования был создан в Бразилии в 1993 году программистами Роберто Иерусальшимом, Луисом Энрике де Фигеиредо и Вальдемаром Целесом в университете Рио-де-Жанейро, где по-прежнему находится офис «LabLua». Название происходит от португальского, что в переводе значит — луна. Одним из предшественников был язык SOL (Simple Object Language). Поскольку имя Lua является существительным, а не аббревиатурой, оно не должно писаться, как LUA, а именно как Lua.
Это гибкий язык, он используется на нескольких направлениях:
Функционал этой программы можно использовать в LÖVE, Defold и, конечно же, в Pico-8.
Основы синтаксиса
Lua использует очень упрощенный синтаксис. Пользователю не нужно применять точки с запятыми или большие пробелы, потому что эти знаки сами интерпретируются программой. Все переменные в скриптах Lua для quik по умолчанию глобальны. Поэтому всегда нужно указывать, когда локальные значения нужны для текущей области и предварительно объявлять их. Фактически на практике существует очень мало случаев, когда в действительности нужны глобальные значения.
Можно определить локальную переменную с ключевым словом local. При этом значение ее объявлять не нужно. Глобальные переменные означают контекст текущего сценария и поэтому не являются такими для каждого отдельного скрипта в игре, которые каждый работают самостоятельно и автономно.
Переменные могут содержать любую последовательность цифр, букв и подчеркиваний, но они не должны начинаться с числа. Null представляет ключевое слово, когда переменные не определены. Необъявленные неотличимы от объявленных переменных, которые не имеют значения. Примеры скриптов Lua:
Блоки кода и операторы if
Блоки определяются определенными ключевыми словами, после чего следует «end». Условия в if операторах должны сопровождаться ключевиками «then». If заявления используют «elseif», а не «else if». Можно создать новую пустую область с «do…end» блоком.
Lua использует особый тип данных, называемый таблицей, предназначенный для целей создания массивов, словарей, хеш-карт, объектов других языков. Таблицы — это просто список пар «ключ-значение», которыми может быть любой тип данных, даже другие таблицы. Можно использовать логическое значение в качестве ключа. Поскольку Lua динамически типизируется, можно иметь любую смесь типов данных в обоих ключах и значениях по выбору пользователя, с которые нужно определиться перед тем, как устанавливать Lua скрипты.
Значения таблиц могут быть определены как внутри, так и отдельно. Обычно есть два способа получить и установить их значения, синтаксис «точка», например, «myTable.a», и синтаксис скобки, например, «myTable[«a»]». При использовании строковых ключей можно использовать только синтаксис точек и нельзя применять его, если строка начинается с числа.
Каждое значение в таблице учитывается, nil — если оно не установлено. Это означает, что невозможно определить, объявлено ли значение в таблице или это просто нуль, если оно никогда не было определено раньше. Это означает, что если ключи в таблице указаны и установлены на нуль, это не будет иметь никакого эффекта, вернее, оно будет таким, каким было бы в случае, если бы их и не определяли вовсе. В Lua таблицы с числовыми ключами начинаются с индекса 1, а не 0. Это то, что вызывает большую головную боль для программистов. Можно разделить встроенные элементы таблицы запятой или точкой с запятой.
Сложный тип данных
Таблицы считаются сложным типом данных в Lua — это означает, что переменные в них просто ссылаются на один и тот же объект в памяти, поэтому нельзя напрямую сравнивать два значения и ожидать, что они проведут что-либо. Тем не менее строки, числа, буквы и другие примитивные типы данных можно сравнивать напрямую.
Цифры в Lua используют только в одном виде — своего собственного числа. Нет таких типов, как int, float, long, double и других, как в прочих языках и это надо учитывать перед тем, как устанавливать Lua-скрипты. Технически все значения в Lua представляют собой числа с плавающей запятой.
Lua имеет только «=» оператор для определения и увеличения. В нем нет «+=», «-=», «++» или чего-нибудь еще. Оператором конкатенации является «…». Можно применять эту операцию на строках и номерах без проблем. Однако нельзя объединять другие типы данных — логические или табличные. Можно получить длину таблицы или строки с «#» оператором и это работает только для массивов с числовыми индексами. Например, код не будет работать с таблицами, которые имеют строковые индексы.
Циклические типы Loops
Существует четыре типа циклов Loop, что в переводе означает петля или виток.
While (промежуточный) — это самый простой вид цикла и функций, как и следовало ожидать на других языках, и означает, что проверка проводится перед запуском внутреннего блока.
Numeric for loop (цифровой). Цикл применяет переменную local для своей области и увеличивает или уменьшает ее. Пользователь объявляет и определяет переменную, которую нужно использовать и за которой следует значение цели.
Generic for loop (генерируемый) — использует функцию итератора. Она вызывается повторением каждого цикла и возвращает значения, которые будут применены в ней.
Pairs (пары) является функцией итератора в глобальном масштабе. Она принимает таблицу в качестве аргумента, возвращает индекс и значение каждой переменной в таблице. Код будет перебирать даже ненулевые индексы. У нее есть «брат» — «ipairs», который делает точно то же самое, за исключением того, что работает только с числовыми индексами и останавливается, когда достигается значения nil.
Repeat loop (повторение) похож на while, за исключением того, что проверка условий проводится в конце блока, а не в начале. Перед тем как открыть lua скрипт нужно учитывать, что код внутри будет запускаться не менее одного раза. Цикл повторения обычно избегают в разработке этого языка, поскольку его прецедент ограничен и трудно читаем из-за того, что не использует стандартный do..end синтаксис.
Метод функций
Функции — это еще один сложный тип данных, можно передавать как переменные, и также можно вызвать их, чтобы выполнить код внутри. Они похожи на методы на других языках.
Существует два способа определения функции в Lua. Первое объявление является глобальным, так как не существует локального ключевого слова. Как правило, глобальные функции считаются приемлемыми. Тем не менее пользователь все равно может сделать их локальными, если нужно, поставив «local» фронт. Можно также объявить переменные до того, как определить функции, которые все равно похожи на любой другой тип данных. Можно передать их, назначить переменными или принять столько аргументов, сколько нужно, с помощью синтаксиса «…». Фактическим объектом «…» является «tuple» (кортеж), поэтому нужно окружить его фигурными скобками, чтобы превратить данные в таблицу.
Кортеж — это просто список имен, таких как параметры в функциях, которые могут возвращать несколько значений, а им, в свою очередь, можно присвоить переменные. Если поместить функцию в таблицу, то ее можно вызвать двумя разными способами. Стандартный синтаксис точек или двоеточия отправит массив в качестве первого аргумента.
Глобальное пространство имен
«Луа» предоставляет несколько таблиц в глобальном пространстве имен, которые содержат вспомогательные функции, такие как «string», «table» и «math». Таким образом, пользователь никогда не должен указывать какую-либо переменную из названных, поскольку они будут перераспределять массивы, содержащие полезные функции.
Существуют две таблицы, которые совместно используются всеми сценариями на сервере или клиенте (но не для обоих) — это «_G» и «shared». Первая — поистине глобальная, реализуемая через отдельные скрипты, поэтому, если нужно получить или установить значения из нее, используют «_G.something».
«Strings» (Струны) — этой функцией Lua может несколькими способами определить строковый литерал и многострочные данные, используя двойные квадратные скобки. И также можно поместить любое количество знаков равенства (=) между квадратными скобками ([===[ … ]===]). Они сбалансированы, могут включать в себя последовательности внутри, как ]]. Lua также имеет собственный набор встроенных функций манипуляции строками и собственную, вытесненную версию регулярных выражений, называемых строковыми шаблонами.
Игровой лунный сценарий
Это очень простые первые шаги по написанию программы, но они являются хорошими отправными точками для взлома скриптов Garry Mod 10 Lua. Первый шаг — создают фактический файл сценария Lua. Открывают текст или редактор — блокнот будет отлично работать для этой цели. Далее сохраняют этот файл, прописывая, как на рисунке.
Где:
- <Steamname> — имя пользователя паролей.
- <Garry’s Mod Install location> — каталог Steam для Garry’s Mod.
Место установки по умолчанию для Lua-скриптов для garry s mod обычно «C:Program FilesSteamsteamapps\garrysmod», но может отличаться на компьютере — «autorunclient». Любые файлы сценариев, помещенные в этот каталог, будут запускаться при запуске Lua на клиенте, например, когда начнется новая игра или пользователь присоединяется к серверу. Далее создают файл типа Hello World, добавляя к нему сценарий lua mod скриптов. Это самый простой вариант.
Это может казаться немного запутанным сразу. Скрипт выдает содержимое таблицы (какие массивы или списки вызываются) и перехватывает данные до команды консоли, чтобы подтвердить, что требуется определить функцию, которая которая не принимает никаких параметров и не возвращает значения, но обязательно устанавливает «конец» в конце своих команд.
Функции — это модульные фрагменты кода, которые можно использовать несколько раз. В этом примере показано, как запустить скрипт Lua. Здесь создан список строк, но пользователь также может вставлять и другие объекты. Таблицы являются ассоциативными или хешированными. Это означает, что каждый элемент в списке может ссылаться на ключ.
Эти команды распечатывают все элементы в таблице, а структура называется циклом. Обращают внимание на команду пары «myTable», которая запускается один раз для каждого элемента и возвращает пары ключ/значение для значений в списке.
Значение — это элемент в таблице, а ключ — это просто способ ссылки на него. Этот пример показывает, как выводить текстовые и значения переменных с той же командой печати. Переменные «ключ» и «значение» устанавливаются в цикле выше. Обращают внимание на «…» между строками и переменными. Символ «…» — оператор конкатенации Lua. Это говорит языку, что нужно склеить два элемента вместе и рассматривать их как одну текстовую строку «.concommand.Add»:
- my_test_function;
- myTestFunction.
Запись создает консольную команду, которая запускает только что инициированную функцию. Первым ее параметром является имя команды управления, в этом случае: «my_test_function». Это то, что пользователь вводит в консоль мод Garry для запуска скрипта.
Второй параметр — это функция для запуска, в этом случае: myTestFunction. Этот файл впоследствии потребуется сохранить. Далее тестируют скрипт, запускают Garry’s Mod и новую игру. После этого открывают консоль, используя тильду (~). Если она не появляется, тогда нужно ее включить, вводя «my_test_function» в строку в нижней части панели. После запуска начнется автоматическое заполнение экрана с именем команды, нажимают Enter, чтобы ее запустить.
Возможности Lua-Quick-Try-Out
Эта консоль предназначена для прямого ввода кода Lua (например, команда команды Lua (8 + 9) сразу выводит результат 17).
Ее функции:
Точки консоли останова могут быть установлены щелчком рядом с номером строки. Если режим отладки включен, вид переменной будет виден в правой части главного окна. Ее размер можно изменить, перетаскивая левую границу. Различные параметры режима отладки «вкл.» или «выкл.» сохраняются и восстанавливаются, когда он включен или отключен. Можно применять колесико мыши для изменения видимого размера диаграмм и графики. Правую кнопку мыши можно использовать, чтобы открыть контекстное меню для диаграмм с функциями их масштабирования.
SAMP Lua-скрипты — это библиотека lua для MoonLoader, которая добавляет некоторые команды, чтобы упростить модификацию SA: MP,SAMP. Events дает возможность обрабатывать SA: MP входящие и исходящие низкоуровневые сетевые пакеты очень простым способом. Можно переписать данные, установив все аргументы в таблице в правильном порядке или можно прервать обработку любых пакетов, вернув false, которая предотвращает изменение пользователем позиции игрока.Перед тем как установить Lua-скрипт samp, можно добавить собственный обработчик пакетов.
Дистрибутив Lua-WoW
Так называется дистрибутив исходного кода Lua, модифицированный для соответствия среде аддонов World of Warcraft.
Его данные:
Эта версия языка настроена на соответствие среде Lua World of Warcraft. Все параметры совместимости 5.0-5.1 отключены, кроме openlib. Библиотека битлиба работает. Некоторые wow Lua скрипты — специфичные, Lua-библиотечные функции реализованы.
Программой предоставляются глобальные псевдонимы для функций «Lua.string.format», они могут использовать выбор аргументов из Lua 4.0. Двоичные файлы Windows, включенные в эту загрузку, статически связаны для производительности. Они могут работать не так, как ожидалось пользователем, при использовании с некоторыми сторонними пакетами.
История версий:
Игровой движок Pico-8
Pico-8 — это фантастическая программа, которая эмулирует полную игровую консоль с ограниченными 8-битными спецификациями. Она имеет все необходимые инструменты для программирования на языке Lua. Причина, по которой пользователи выбирают Pico-8, заключается в том, что ее можно использовать прямо из коробки, без необходимости настройки или внешних редакторов, все инструменты включены в пакет Lua-скриптов для самп, а обучение довольно простое.
Порядок работы:
Pico-8 предназначена только для отображения символов верхнего регистра, поэтому можно просто набирать шрифт, нет необходимости использовать Shift или Caps-lock. Редактор также имеет синтаксическую раскраску для кода. Если посмотреть в верхнем правом углу редактора, можно увидеть несколько значков. Это встроенные инструменты для создания спрайтов, карт, звуков и музыки. Этот пример довольно простой, но дает представление о редакторе и языке.
Чтобы исследовать более интересные примеры, можно перейти в каталог DEMOS. Для этого вводят: INSTALL_DEMOS. После открывается каталог DEMOS с несколькими примерами программ для изучения. Одним из главных преимуществ Lua является его простота. Некоторые компании используют этот язык исключительно из-за этого, поскольку думают, что их сотрудники смогут работать лучше.
Некоторые очень простые языки, такие как Bash или Batch, не будут достаточно сильными, чтобы выполнять требуемые задачи, но Lua является одновременно мощной и простой программой. Другим важным преимуществом Lua скриптов для css v34 является их способность внедряться, что признается одной из важнейших характеристик этого продукта на протяжении всего этапа его развития. Такие игры, как World of Warcraft или ROBLOX, имеют возможность встраивать Lua в свое приложение.
Подключение к КВИКу | jato
Подключение Jatotrader© к КВИКу через луа-скрипт.
Пошаговая инструкция.
ВНИМАНИЕ! С настоящего момента Jatotrader можно подключать к терминалу КВИК версии 8 и выше. Поддержка подключения к КВИКу ниже версии 8 осуществляться не будет.
Новый луа-скрипт, называется QuikLuaJatoConnector. lua. Со старым скриптом QuikLuaJATOFastest.lua программа больше не работает!
Установка коннектора JatoTrader-КВИК
В главном меню программы JatoTrader© нажмите кнопку «Настройки соединения».
(1) В окне настроек задайте путь к КВИКу через который вы будете совершать торговые операции. Обратите внимание, что последним символом в имени пути должен быть обратный слэш «\» . Например: C:\Open_Broker_QUIK\.
(3) В полях «AccountT+» и «Client code T+» введите соответствующие значения номера счета и кода клиента, которые можно определить через окно ручного ввода заявки в КВИКе, выбрав в качестве инструмента на ММВБ, например, обыкновенные акции Сбербанка (если вы не собираетесь торговать акциями, то эти поля можно оставить пустыми):
(2) Ту же процедуру повторите для счета и кода клиента на FORTS («Account FUT» и «Client code FUT»), выбрав в качестве инструмента, например, фьючерсный контракт на индекс РТС.
Если в поле «Торговый счет» терминала КВИК нет никакого значения, то убедитесь, что торговые счета были выбраны в основном меню КВИКа: «Система»—>»Настройки»—>»Основные настройки»—>»Настройка счетов».
(4) В нижней части окна «Настроек соединения» в разделе «Подключение по умолчанию» выберите «КВИК» и нажмите кнопку «Сохранить» . Если вы все сделали правильно появится сообщение:
Примечание: Если вы желаете установить коннектор вручную, то просто скопируйте содержимое папки \Jatotrader\QUIK8 (а не саму папку!) в папку КВИКа.
Настройка КВИКа для подключения к JatoTrader©
Запустите КВИК и установите соединение с сервером брокера. Платформа JatoTrader© использует для каждого инструмента тиковые данные и данные биржевого стакана. В КВИКе нужно открыть: «Таблицу обезличенных
сделок», а также биржевые стаканы, которые нужно передавать в JatoTrader©.
Чтобы открыть «Таблицу всех сделок» в главном меню КВИКа выберите пункты «Создать окно»—>«Таблица обезличенных сделок». В появившемся окне нажмите кнопку «Да». В таблицу добавьте нужные вам инструменты для анализа и торговли (правая кнопка мыши на таблице, пункт «Редактировать таблицу»). Таблица обезличенных сделок(тиковые данные) в КВИКе выглядит примерно так:
Если после описанных выше действий «Таблица всех сделок» оказалась пуста, вам следует связаться с вашим брокером и попросить включить трансляцию тиковых данных.
Если вы не используете в своей работе биржевые стаканы, то для увеличения быстродействия их можно не открывать. Для трансляции биржевых стаканов в JatoTrader© просто откройте в КВИКе нужные «стаканы»
через главное меню «Создать окно»—>»Котировки…»
Загрузите в КВИК луа-скрипт. В главном меню КВИКа выберите пункт «Сервисы»—>«Луа скрипты». В появившемся окне «Доступные скрипты» нажмите кнопку «Добавить». Выберите скрипт QuikLuaJatoConnector. lua (после установки коннектора он будет в папке КВИКа, если его там нет, поищите его в папке \Jatotrader\QUIK8, он идет в комплекте поставки).
Запустите луа-скрипт и дождитесь загрузки данных в Jatotrader. Теперь все готово к успешной работе.
Возможные проблемы при подключении к КВИКу
1. При запуске луа скрипта QuikLuaJatoConnector.lua в КВИКе появляется сообщение об ошибке:
Причина: в папке КВИКа отсутствуют необходимые библиотеки.
Скопируйте содержимое папки \Jatotrader\QUIK8 (а не саму папку!) в папку КВИКа и запустите луа-скрипт снова.
2. При запуске луа скрипта QuikLuaJatoConnector.lua в КВИКе появляется сообщение об ошибке:
Причина: КВИК старой версии (ниже 8-й). Обновите КВИК до версии 8.5.2 или выше.
4. При запуске луа-скрипта в КВИКе (окно «Доступные скрипты») соединение с JatoTrader© не устанавливается, КВИК выдает ошибку:
Причина: не запущен JatoTrader©. Запустите JatoTrader© и повторите попытку.
Lua-скрипт с таймером для тренировок — RCPilots
Друзья, хочу поделиться с вами своим Lua-скриптом для OpenTX, который помогает мне тренироваться перед гонками в условиях, максимально приближенных к боевым.
Как известно, многие гонки дронов проводятся по системе MultiGP: за отведённое время пилотам нужно пролететь как можно больше кругов по трассе. Данный скрипт воспроизводит стартовый и финишный сигналы и предупреждение о скором окончании вылета.
Как это работает:
- Пилот, полностью готовый к вылету, щёлкает тумблером.
- Через случайный промежуток времени от 2 до 5 секунд раздаётся стартовый сигнал.
- За 10 секунд до окончания вылета звучит предупредительный сигнал.
- По истечении двух минут скрипт сигнализирует о завершении вылета.
Все интервалы настраиваются в широких пределах. Переключатель тоже можно выбрать любой. Удобнее всего назначить отсчёт времени на тумблер без фиксации.
Как установить:
- Скачать архив из гитхаба: https://github.com/alexeystn/droneracing-timer-lua-script/archive/master.zip
- Поместить содержимое папки /TELEMETRY/ из архива в папку /SCRIPTS/TELEMETRY/ на SD-карте в вашем Таранисе: файл ‘race.lua’ и папку с четырьмя звуками.
- Назначить на один из экранов телеметрии скрипт ‘race’. Можно сделать как с аппы, так и через Companion.
- Теперь скрипт можно запустить с главного экрана долгим нажатием кнопки ‘Page’.
Скрипт тестировался на Таранисе Q X7 с OpenTX 2.2.2, но также должен работать и на X9 и X-Lite. Если у вас возникнут проблемы на данных передатчиках, не стесняйтесь сообщить мне об этом.
Приятных полётов и продуктивных тренировок!
Автор — Алексей Станкевич. https://t.me/AlexeyStn
Garry’s Mod: LUA скрипты
Старая, но прекрасно выполняющая свои функции разработка неизвестного мне автора.
Данная статья предполагает, что вы играете на сервере, где разрешены кастомные скрипты.
VAC-бан исключён, если на сервере разрешены кастомные скрипты, и вы смогли загрузить его командой, не используя обход.
noclip.lua нужно положить в папку, с расположением: ..Steam/steamApps/common/Garry’s mod/garrysmod/lua
Команда загрузки скрипта: lua_openscript_cl noclip.lua
Активация меню — Insert.
Функции:
[spoiler]
MAIN-CONFIG — Главная отличительная черта данного скрипта — возможность сохранить все изменения в отдельный файл для каждого сервера, в названии файла название сервера. Файлов можно сохранить неограниченное количество, но при списке больше 50 файлов — иногда происходит баг при загрузке, и меню не закрывается, от чего игра становится невозможно — не создавайте слишком много сейвов. В меню можно перезагрузить сам скрипт, можно выключить его (panic key — кнопка disable справа вверху в окне чита.
Aimbot — гибкий в настройке автоприцел, способный стрелять по частям тела, наводиться лишь по тем кто находится в поле зрения — и наоборот, по тем кто находится за стенами. Присутствует FOV и эффект смягчения наведения для тех, кто предпочитает «сильно не палиться».
ESP — Гибкий в настройке ESP (Впрочем, тут почти во всём гибкая настройка)
Возможность включить фильтр отрисовки; Друзья, Враги, Команда(те, у кого такой же скин), NPC, Наблюдатели.
Возможность выбрать элементы для отображения: Ник, здоровье, оружие, дистанция, здоровье(шкала), команда(цвет), коробка(квадрат/3D прямоугольник).
Возможность включить отрисовку entity, список которых составляется вручную, так же поддерживается коробка
Misc — Возможность выбрать для отображения в небольшом окне слева вверху админов и наблюдателей.
Манипулятор временем позволяет ускорить игровое время, но это не дает спидхака, и не ускоряет получение зарплаты/возрождение, поскольку работает лишь у хоста сервера.
Не до конца понятно, зачем эта функция была добавлена.
ENTS[/color — Управление списком интересных вам entity сервера с функцией обновления спика, очищения списка, сохранения набора entity в отдельный файл (не путать с config — это отдельное меню и отдельные файлы, которые не видны из других менеджеров сохранения)
FRIENDS — Список друзей составленный по SteamId с отображением ников. После составления его можно переключить в список врагов. Внимание — если нажать Friends is enemy до составления списка — вы не сможете переместить человека ни в список друзей, ни в список врагов — почему-то свитчер перестает работать в этом случае. Составляйте заранее.
CAMS — Функция, в честь которой назван сам скрипт. Позволяет открепить камеру от пользователя, имитируя вид от третьего лица (консольный thirdperson), либо вовсе открепить от игрока и летать ей по карте. Она проходит стены и дает весьма не слабый потенциал для вора на Dark RP, трейтора в TTT или убийцы в Murder. Регулятор скорости полёта камеры прилагается.
Почти бесполезные функции, но всё же присутствующие и требующие описания.
bhop, который не дает бонуса скорости почти нигде. Тем не менее, присутствуют функции движения боком для более успешной распрыжки, автоматических стрейфов, движения со скоростью прыжка, автоматического прыжка и движения по углам поворота — «W only». Данная функция поворачивает ваш скин под углами, позволяющая прыгать назад, смотря вперед, при этом чтобы вас все видели, будто вы прыгаете нормально — смотря туда, куда прыгая. Удобно при побеге.
Spam — функция спама сообщениями. С настраиваемой задержкой и обходом защиты от однотипных сообщений. Просто и со вкусом.
Test 10 и 11 — тестовые функции, которые пока не реализованы. Пустые окна.
[/spoiler]
Искренне надеюсь что тут работают коды и я не зря их писал.
Lua — мощный, эффективный, легкий встраиваемый язык сценариев. Lua сочетает простой процедурный синтаксис с Lua Lua разработан, внедрен и поддерживается «Луа» Есть несколько Ты можешь Присоединяйтесь к нам на Вы можете помочь Вы также можете помочь распространить информацию о Lua, купив продукты Lua. | Lua — проверенный и надежный язык. Lua использовался в Lua быстрый Lua имеет заслуженную репутацию за производительность. Если вам нужно еще больше скорости, попробуйте Lua переносной Lua распространяется в небольшом пакете и По определенным причинам, по которым Lua является хорошим выбором также для устройств с ограничениями, Lua встраиваемый Lua — это быстрый языковой движок с небольшими размерами, который Lua мощный (но простой) Фундаментальная концепция дизайна Lua — это: Lua маленький Добавление Lua в приложение его не раздувает. Lua бесплатно Lua — бесплатное программное обеспечение с открытым исходным кодом, |
Сценарии Lua — Rainmeter
Rainmeter может загружать и выполнять сценарии на Lua , функциональном языке программирования. Rainmeter включает стандартные библиотеки Lua 5.1, которые включают в себя множество мощных функций.
Сценарий относится к набору функций Lua, связанных с мерой сценария.Эти функции могут выполняться при загрузке скина, при обновлении или по команде.
На этой странице подробно описаны модификации Rainmeter и новые функции, которые были добавлены во встроенную среду Lua Rainmeter. Дополнительная документация для самого Lua доступна по адресу:
Остальная часть этой страницы предполагает базовые знания языка Lua.
Мера сценария
Показатель сценария используется для загрузки сценария Lua из файла и взаимодействия со сценарием.Файл сценария должен быть текстовым и обычно имеет расширение .lua
.
Как и меры плагина, каждая мера скрипта создает отдельный экземпляр своего скрипта. Это означает, что скин может иметь любое количество загружаемых одновременно сценариев — даже из одного файла сценария. (Порядок выполнения скриптов определяется порядком измерений.) «Глобальные» переменные не используются совместно между экземплярами.
[MeasureName] |
Опции
В дополнение к общим параметрам измерения и ScriptFile сценарии также допускают параметры, определяемые пользователем. Эти параметры могут иметь любое имя и значение и могут быть изменены с помощью! SetOption. Сценарий может читать и использовать собственные значения параметров с помощью объектных функций SELF. Это позволяет использовать один и тот же файл сценария с разными параметрами в зависимости от контекста.
[MeasureName] |
Динамические переменные
Обычно динамические переменные не требуются для показателей скрипта. Это связано с тем, что в Lua предусмотрены функции для получения текущих значений переменных, показателей и параметров. Если эти функции используются в функции обновления, они будут возвращать текущие значения во время вызова функции.
! CommandMeasure
Команда! CommandMeasure bang может использоваться для выполнения кода Lua в контексте конкретного экземпляра скрипта:
! CommandMeasure «MyScriptMeasure» «MyFunction ()»
Несколько операторов можно разделять точкой с запятой (;
).Все заявления глобальны.
! CommandMeasure "MyScriptMeasure" "a = b; print (SKIN: ParseFormula ('(2 + 2)'))"
Все операторы должны передаваться как один параметр в bang. Поскольку одинарные кавычки ( '
) и двойные кавычки ( "
) являются допустимыми контейнерами строк в Lua, в то время как в Rainmeter распознаются только двойные кавычки, при передаче строк с помощью! CommandMeasure.
рекомендуется использовать одинарные кавычки.
Инициализировать
Если функция Initialize определена в каком-либо скрипте, функция вызывается один раз (без параметров) при активации или обновлении темы оформления.Это происходит, даже если мера скрипта отключена. Если файл сценария изменяется с помощью команды! SetOption, также вызывается функция Initialize нового сценария.
function Initialize () |
Действия, необходимые для «настройки» сценария, такие как объявление глобальных переменных, должны выполняться в функции Initialize.
Использование dofile
Функцию dofile можно использовать для включения библиотек или других фрагментов кода Lua.Вы должны указать полный путь к dofile, используя синтаксис dofile ('C: \ PathToDoFile \ SomeLua.lua')
. Используйте функцию GetVariable, если вы хотите использовать ярлык переменной # @ # для папки @Resources для текущей конфигурации, или MakePathAbsolute, если вы хотите, чтобы файл .lua располагался относительно текущей папки скинов.
функция Initialize () |
Примечание: Хотя файл, который вы вызываете, может находиться в любом месте вашей системы, имейте в виду, что если вы не поместите этот файл.lua где-нибудь на пути к текущей конфигурации, вы не сможете распространять его вместе со своим скином как пакет .rmskin. Пакет .rmskin может распространять только содержимое одной корневой папки конфигурации.
Обновление
Если функция Update определена в любом скрипте, функция вызывается (без параметров) всякий раз, когда обновляется мера скрипта. Мера скрипта обычно реагирует на параметр Disabled, параметр UpdateDivider и все удары измерения.
Обновление функции () |
Возвращаемое значение функции обновления определяет, какие значения предоставляются мерой сценария.Строки и числа в Lua аналогичны строковым значениям и числовым значениям в мерах Rainmeter. Примеры:
return
Предоставляет 0 как числовое значение и » (пробел) как строковое значение. То же самое верно, если не указаноreturn
.return 99
return '99'
В любом случае предоставляет 99 как числовое значение и ’99’ как строковое значение.return 'Девяносто девять'
Предоставляет 0 как числовое значение (поскольку строка не может быть преобразована в число) и ‘Девяносто девять’ как строковое значение.
Значения, предоставленные мерой сценария, можно использовать так же, как и другие значения меры. (Примечание : значения обновляются только при обновлении самой меры. Вызов Update ()
в Lua не обновляет значения меры.)
Журнал
ошибок Lua регистрируется в окне «О программе».Функцию печати также можно использовать для записи строк в журнал. Это может обеспечить полезную обратную связь при написании или устранении неполадок скрипта.
print ('Текущее значение MyVariable:' .. MyVariable)
Функции
Функции Lua предназначены для идентификации измерителя, меры или текущей оболочки как объекта Lua . Предоставляются дополнительные функции для управления каждым типом объекта определенным образом.
СКИН объект
Объект SKIN
создается автоматически.
-
GetMeasure
Параметр:MeasureName
Создает дескриптор для именованной меры. Возвращает
nil
, если мера не найдена.Пример:
MyMeasure = SKIN: GetMeasure ('MeasureName')
-
GetMeter
Параметр:MeterName
Создает объект ручки для названного счетчика.Возвращает
nil
, если счетчик не найден.Пример:
MyMeter = SKIN: GetMeter ('MeterName')
-
GetVariable
Параметр:Имя переменной , по умолчанию
Возвращает текущее значение названной переменной в виде строки. Если переменная не существует, возвращает заданное значение по умолчанию или
nil
, если значение по умолчанию не задано.Пример:
MyVariable = SKIN: GetVariable ('VariableName', 'n / a')
-
GetX
Возвращает текущую позицию X окна скина в виде числа.
Пример:
MyX = SKIN: GetX ()
-
GetY
Возвращает текущую позицию Y окна скина в виде числа.
Пример:
MyY = SKIN: GetY ()
-
GetW
Возвращает текущий размер окна скина в виде числа.
Пример:
MyW = SKIN: GetW ()
-
GetH
Возвращает текущий размер H окна скина в виде числа.
Пример:
MyH = SKIN: GetH ()
-
MoveWindow
Параметры:X , Y
Перемещает окно скина в положение экрана, определяемое целочисленными параметрами
X
иY
.Пример:
SKIN: MoveWindow (200,100)
-
FadeWindow
Параметры:от , до
Уменьшает непрозрачность окна обложки от начального целочисленного значения до конечного целочисленного значения.Допустимые значения от 255 (непрозрачный) до 0 (прозрачный). Обратите внимание, что мышь не будет обнаружена с непрозрачностью 0 в окне скина.
Скорость затухания контролируется настройкой FadeDuration для кожи.
Пример:
СКИН: FadeWindow (255,100)
-
Bang
Параметры:BangName , BangArg1, BangArg2, BangArgN
Выполняет удар. Удар будет выполнен Rainmeter, когда управление будет возвращено из скрипта.
Каждый параметр взрыва — это отдельный параметр в функции.
Пример:
someVar = 12
SKIN: Bang ('! SetOption', 'MeterName', 'Text', 'Hello, world!')
SKIN: Bang ('! SetOption', 'MeterName', 'FontSize', someVar)
SKIN: Bang ('! UpdateMeter', 'MeterName')
SKIN: Bang ('! Redraw')
Примечание: ! Delay bang в Rainmeter не поддерживается в Lua.
-
MakePathAbsolute
Параметр:Файл / папка
Преобразует относительный путь к файлу в полный путь к файлу.Путь будет относиться к папке со скинами.
Пример:
MyPath = SKIN: MakePathAbsolute ('MyImage.png')
-
ReplaceVariables
Параметр:Строка
Возвращает заданную строку с должным образом замененными всеми допустимыми значениями переменных. Переменные раздела действительны.
Пример:
MyString = SKIN: ReplaceVariables ('Значение MyVariable - # MyVariable #.')
-
ParseFormula
Параметр:FormulaString
Если заданная строка является допустимой формулой, вычисляет формулу и возвращает результат в виде числа. В противном случае возвращает
ноль
. Это может использовать математические функции в Rainmeter, которые не могут быть встроены в Lua. Помните, что формулы в Rainmeter должны быть полностью заключены в (круглые скобки).numToRound = 239.78
roundedNum = SKIN: ParseFormula ('(Round (' .. numToRound .. '))')
Измерение объекта
Объект Measure
создается с помощью GetMeasure. Он создает дескриптор определенной меры в скине, которую затем можно использовать со следующими функциями для воздействия на меру.
Пример: MyMeasure = SKIN: GetMeasure ('MeasureName')
-
GetValue
Возвращает текущее числовое значение меры.
Пример:
MyMeasureValue = MyMeasure: GetValue ()
-
GetStringValue
Возвращает текущее строковое значение меры.
Пример:
MyMeasureValue = MyMeasure: GetStringValue ()
-
GetOption
Параметры:Имя опции , по умолчанию
Возвращает текущее значение указанной опции в виде строки.Если параметр не существует, возвращает заданное значение по умолчанию или
''
, если значение по умолчанию не задано.Пример:
MyGroup = MyMeasure: GetOption ('Группа', 'Нет')
-
GetNumberOption
Параметры:OptionName , по умолчанию
Возвращает текущее значение названной опции в виде числа. Если параметр не существует или не является допустимым числом или формулой, возвращает заданное значение по умолчанию или
0
, если значение по умолчанию не задано.Пример:
MyUpdateDivider = MyMeasure: GetNumberOption ('UpdateDivider', 1)
-
GetName
Возвращает имя меры в виде строки.
Пример:
MyMeasureName = MyMeasure: GetName ()
-
GetMinValue
Возвращает текущее минимальное значение меры в виде числа.
Пример:
MyMeasureMin = MyMeasure: GetMinValue ()
-
GetMaxValue
Возвращает текущее максимальное значение меры в виде числа.
Пример:
MyMeasureMax = MyMeasure: GetMaxValue ()
-
GetRelativeValue
Возвращает текущее числовое процентное значение меры в виде числа с масштабированием от
0,0
до1,0
. Результат будет основан на текущих определенных или производных MinValue и MaxValue меры.Пример:
MyMeasureValue = MyMeasure: GetRelativeValue ()
-
GetValueRange
Возвращает текущий диапазон значений меры в виде числа.Результат будет основан на текущих определенных или производных MinValue и MaxValue меры, и будет разницей между ними.
Пример:
MyMeasureRange = MyMeasure: GetValueRange ()
-
Отключить
Отключает меру.
Пример:
MyMeasure: Disable ()
-
Включить
Включает измерение.
Пример:
MyMeasure: Enable ()
SELF объект
Объект SELF
создается автоматически. SELF
— это объект меры, связанный с текущей мерой скрипта. Все функции объекта измерения действительны для SELF
.
MyScriptMeasureName = SELF: GetName ()
Метр объекта
Объект Meter
создается с помощью GetMeter. Он создает ручку для конкретного измерителя в коже, которую затем можно использовать со следующими функциями для воздействия на измеритель.
Пример: MyMeter = SKIN: GetMeter ('MeterName')
-
GetOption
Параметры:Имя опции , по умолчанию
Возвращает текущее значение указанной опции в виде строки.Если параметр не существует, возвращает заданное значение по умолчанию или
''
, если значение по умолчанию не задано.Пример:
MySolidColor = MyMeter: GetOption ('SolidColor', '000000')
-
GetName
Возвращает имя счетчика в виде строки.
Пример:
MyMeterName = MyMeter: GetName ()
-
GetX
Параметры:Абсолютный
Возвращает текущую позицию X измерителя в виде числа.Если необязательный параметр Absolute равен
true
, возвращает абсолютное (или «реальное») положение X, которое может отличаться от заданного параметра на измерителе.Пример:
MyX = MyMeter: GetX ()
-
GetY
Параметры:Абсолютный
Возвращает текущую позицию Y измерителя в виде числа. Если необязательный параметр Absolute равен
true
, возвращает абсолютное (или «реальное») положение Y, которое может отличаться от заданного параметра на измерителе.Пример:
MyY = MyMeter: GetY ()
-
GetW
Возвращает текущую «реальную» ширину счетчика в виде числа.
Пример:
MyW = MyMeter: GetW ()
-
GetH
Возвращает текущую «реальную» высоту измерителя в виде числа.
Пример:
MyH = MyMeter: GetH ()
-
Набор X
Устанавливает положение X измерителя.
Пример:
MyMeter: SetX ()
-
КОМПЛЕКТ
Устанавливает положение Y измерителя.
Пример:
MyMeter: SetY ()
-
НАБОР
Устанавливает ширину измерителя.
Пример:
MyMeter: SetW ()
-
НАБОР
Устанавливает высоту измерителя.
Пример:
MyMeter: SetH ()
-
Скрыть
Скрывает счетчик.
Пример:
MyMeter: Hide ()
-
Показать
Показывает счетчик.
Пример:
MyMeter: Show ()
Ограничения
Следующие функции Lua в настоящее время недоступны в Rainmeter:
- Внешние скомпилированные библиотеки, такие как LuaCURL.
-
требует
,os.exit
,os.setlocale
,io.popen
иcollectgarbage функции
.
Устаревшие функции
Следующие специфичные для Rainmeter функции устарели и не должны использоваться. Они все еще поддерживаются, но могут быть удалены в будущих версиях.
PROPERTIES = {...}
Эта таблица ранее использовалась для чтения параметров в мере скрипта. Вместо этого используйте:
SELF: GetOption ('MyOption')
илиSELF: GetNumberOption ('MyOption')
MyMeter: SetText ('... ')
Эта функция использовалась для изменения текста счетчика строк. Вместо этого используйте:
SKIN: Bang ('! SetOption', 'MeterName', 'Text', '...')
функция GetStringValue ()
Эта функция использовалась для установки значения меры скрипта. Вместо этого используйте:
function Update () ... return ... end
Создание веб-скриптов с помощью Lua
Введение
CGILua использует Lua как серверный скрипт.
язык для создания динамических веб-страниц.Оба чистые
Скрипты Lua и
Страницы Lua (LP) поддерживаются CGILua.
Сценарий Lua — это, по сути, программа Lua, которая создает все содержимое
веб-страницу и возвращает ее клиенту. Страница Lua — это обычная
текст разметки (HTML, XML и т. д.), который встраивает код Lua с помощью специальных
теги. Эти теги обрабатываются CGILua, и результирующая страница возвращается в
клиент.
Lua Scripts и Lua Pages одинаково просты в использовании, и выбор одного из них
в основном зависит от характеристик результирующей страницы.Хотя Lua
Страницы более удобны для разделения логики и формата, скрипты Lua
больше подходят для создания более простых по структуре страниц,
но требуют более значительной внутренней обработки.
Позволяя смешивать эти два метода, CGILua предоставляет веб-приложения
разработчики с большой гибкостью, когда присутствуют оба требования. Для
подробное описание обоих методов написания сценариев и несколько примеров
их использование см. Скрипты Lua и
Страницы Lua.
Архитектура
Архитектура CGILua разделена на два уровня. Нижний уровень представлен
серверным API (SAPI), а на более высоком уровне
представлен самим API CGILua. SAPI — это интерфейс между веб-сервером
и CGILua API, поэтому его необходимо реализовать для каждого веб-сервера и запустить
используемый метод.
Лаунчер отвечает за взаимодействие CGILua и веб-сервера,
реализация SAPI, например, с использованием ISAPI в IIS или mod_lua в Apache.Эталонная реализация пусковых установок CGILua:
Кеплер.
CGILua API реализован с использованием только SAPI и полностью переносим.
над различными программами запуска и поддерживающими их веб-серверами. Таким образом, любой скрипт Lua
или Lua Page может использоваться любым лаунчером.
Жизненный цикл запроса
CGILua обрабатывает запросы, используя метафору CGI (даже если лаунчер не основан на
на CGI), а у запросов есть жизненный цикл, который может настраивать программист.
Жизненный цикл запроса CGILua состоит из следующей последовательности шагов для каждого
запрос:
- Добавьте обработчики по умолчанию, такие как LuaScripts и Lua Pages, а также форматы файлов commom.
- Выполните файл
config.lua
, позволяющий настроить следующие шаги. - Создайте таблицы
cgilua.POST
иcgilua.QUERY
(обработка данных POST и QUERY). - Перейти в каталог пользовательских сценариев.
- Выполняет зарегистрированные функции открытия .
- Выполнить запрошенный сценарий в правильной среде.
- Выполняет зарегистрированные функции закрыть .
- Вернуться в исходный каталог
Редактируя файл config.lua
, можно настроить поведение CGILua.
Типичное использование — регистрация функций открыть и закрыть .
чтобы изменить поведение обработки запроса.
С помощью этой настройки можно реализовать новые функции, такие как
управление сеансами и каталоги частных библиотек, как показано в разделе
Конфигурация или даже внедрение нового
абстракции для всего образа жизни CGILua, такие как MVC-frameworks, такие как Orbit.
Установка
CGILua следует за
модель упаковки
для Lua 5.1, поэтому он должен быть «установлен» в вашем package.path
.
Вы также можете установить CGILua, используя LuaRocks:
luarocks установить cgilua
Конфигурация
Дистрибутив Kepler для CGILua 5.1 предлагает один файл конфигурации с именем config.lua
.
Этот файл можно использовать для изменения поведения CGILua по умолчанию, и он находится в каталоге конфигурации Kepler.
Некоторые из вариантов использования настройки config.lua
:
- Обработчики скриптов
- Обработчик отвечает за ответ на запрос.
Вы можете добавить новые обработчики CGILua, используя
cgilua.addscripthandler
(см. такжеcgilua.buildplainhandler
иcgilua.buildprocesshandler
для функций, которые создают простые обработчики). - Размеры данных POST
- Вы можете изменить ограничения размера данных POST, используя
cgilua.setmaxinput
и
cgilua.setmaxfilesize
. - Функции открытия и закрытия
- Вы можете добавить свои функции в жизненный цикл CGILua, используя
cgilua.addopenfunction
и
cgilua.addclosefunction
.
Эти функции выполняются непосредственно до и сразу после выполнения скрипта,
даже при возникновении ошибки в обработке скрипта.
В частности, функции открытия и закрытия полезны для разных вещей.Далее показаны некоторые примеры использования таких функций в файле config.lua
.
Предыдущие версии CGILua загружали файл env.lua
из
каталог скрипта перед его обработкой. Чтобы эмулировать это с помощью CGILua 5.1, вы можете
используйте что-то вроде:
cgilua.addopenfunction (функция () cgilua.doif ("env.lua") конец)
Если каждому сценарию необходимо загрузить модуль (например, библиотеку сеансов), вы можете сделать:
требуется ("cgilua.session") cgilua.session.setsessiondir (CGILUA_TMP) cgilua.addopenfunction (cgilua.session.open) cgilua.addclosefunction (cgilua.session.close)
Обратите внимание на , что функция cgilua.addopenfunction
необходимо использовать для вызова cgilua.session.open
, потому что эта функция
необходимо изменить таблицу cgi
(см. раздел
Получение параметров
для получения дополнительной информации об этой специальной таблице)
который еще не доступен во время выполнения config.lua
файл (см. Жизненный цикл запроса).
Когда одни скрипты могут использовать библиотеку, а другие нет,
вы можете определить «разрешающую» функцию (которая должна вызываться в
самое начало каждого скрипта, который должен использовать сеансы):
требуется ("cgilua.session") cgilua.session.setsessiondir (CGILUA_TMP) cgilua.enablesession = функция () cgilua.session.open () cgilua.addclosefunction (cgilua.session.close) конец
Иногда вам нужно настроить каталог частных библиотек для каждого приложения.
размещен на сервере.Эта конфигурация позволяет функции требовать
найти пакеты, установленные в личном каталоге и в системном каталоге
но не в личном каталоге другого приложения. Чтобы реализовать это, вы можете сделать:
local app_lib_dir = { ["/ виртуальный / путь /"] = "/ абсолютный / путь / библиотека /", } локальный пакет = пакет cgilua.addopenfunction (функция () локальное приложение = app_lib_dir [cgilua.script_vdir] если приложение то package.path = app .. '/ ?. lua' .. ';' .. package.path конец конец)
Скрипты Lua
Сценарии Lua — это текстовые файлы, содержащие действительный код Lua.Этот стиль использования
принимает более «сырую» форму веб-программирования, когда программа отвечает за
на всю генерацию получившейся страницы. Скрипты Lua имеют значение по умолчанию
.lua
расширение.
Для создания действительного веб-документа (HTML, XML, WML, CSS и т. Д.) Lua Script
должен следовать ожидаемому порядку HTTP, чтобы произвести свой вывод, сначала отправив
правильные заголовки, а затем отправка
фактическое содержание документа.
CGILua предлагает некоторые функции для облегчения этих задач, например
cgilua.htmlheader
в
создать заголовок для HTML-документа и
cgilua.put
для отправки документа
содержимое (или его часть).
Например, документ HTML, в котором отображается предложение «Hello World!» мочь
может быть сгенерирован с помощью следующего Lua Script:
cgilua.htmlheader () cgilua.put ([[Привет, мир Привет, мир! ]])
Следует отметить, что в приведенном выше примере создается «фиксированная» страница: даже
хотя страница создается во время выполнения, «переменной» нет
Информация.Это означает, что тот же самый документ может быть создан напрямую
с помощью простого статического файла HTML. Однако скрипты Lua становятся особенно полезными
когда документ содержит заранее неизвестную информацию или изменяется
согласно переданным параметрам, и необходимо сформировать «динамическую» страницу.
Можно показать еще один простой пример, на этот раз с использованием структуры управления Lua,
переменные и оператор конкатенации:
cgilua.htmlheader () если cgilua.QUERY.language == 'english', тогда приветствие = 'Hello World!' elseif cgilua.QUERY.language == 'португальский', затем приветствие = 'Olá Mundo!' еще приветствие = '[неизвестный язык]' конец cgilua.put ('') cgilua.put ('<заголовок>') cgilua.put ('' ..greeting .. ' ') cgilua.put ('') cgilua.put ('<тело>') cgilua.put ('' ..приветствие .. '') cgilua.put ('