Всем привет, возможно у Вас появлялись мысли о том, как можно запускать Lua скрипты не используя SA:MP и в частности Moonloader.
Так вот, эта статья именно для Вас.
Все ниже перечисленное я тестировал на Windows 10, поэтому я не гарантирую, что все ниже написанное будет работать на других ОС.
Первое, что нам нужно сделать, так это скачать LuaJIT компилятор.
Скачиваем архив, после чего достаем папку из архива и перекидываем в удобное место.
Теперь мы можем запускать файлы с помощью файла «путь-до-папки-которую-скачали\luajit-compiler\luajit.luajit.exe».
Теперь напишем небольшой скрипт, который будет например выводить сообщения в консоль.
print("I'm gay (I write in LUA). Don't hit, a joke, like haha, rzhaka.")
Для того, чтобы запустить это чудо, нам необходимо открыть командную строку (WIN+R->cmd) и ввести в нее следующую команду:
путь-до-нашей-папки-с-LuaJIT\luajit\luajit.exe путь-до-нашего-скрипта\скрипт.lua"
(например: D:\DEV\lua\luajit-compiler\luajit\luajit.exe "D:\DEV\lua\scripts\script.lua")
Все хорошо, но что, если мы допустим захотим подключить какую-либо библиотеку? Для этого нам надо разобраться, откуда функция require() берет путь до файла, указанного в качестве параметра (то, что мы пишем в скобках функции).
Берет она его из таблиц package.path (если библиотека .lua) и package.cpath (если библиотека .dll), встроенных в LuaJIT.
По стандарту package.path равна
;.\?.lua;\luajit-compiler\luajit\lua\?.lua;\luajit-compiler\luajit\lua\?\init.lua;;C:\Program Files (x86)\Lua\5.1\lua\?.luac
Т.е. все .lua файлы (или папки с файлами) мы должны кидать в \luajit-compiler\luajit\lua
А вот package.сpath равна
.\?.dll;D:\luajit-compiler\luajit\?.dll;\luajit-compiler\luajit\loadall.dll
Это значит то, что она не ищет все в папке \luajit-compiler\luajit
Для того, чтобы добавить или изменить этот путь, нам необходимо перед подключением библиотек добавить вот такую строчку
package.cpath = ("%s;D:/DEV/lua/luajit-compiler/luajit/lua/?.dll"):format(package.cpath) -- если хотим добавить к остальным путям еще один
package.cpath = "/DEV/lua/luajit-compiler/luajit/lua/?.dll" -- если хотим полностью переписать все пути на один единственный
Проверяем и создаем скрипт, который будет отправлять сообщение в телеграм при запуске скрипта:
--========================================================LIBS========================================================
package.cpath = ("%s;D:/DEV/lua/luajit-compiler/luajit/lua/?.dll"):format(package.cpath)
local effil = require("effil")
local encoding = require("encoding")
--========================================================VARIABLES========================================================
encoding.default = "CP1251"
local u8 = encoding.UTF8
local telegram = {
token = "хер вам, а не мой токен"
chatId = "хер вам, а не мой chatID"
}
--========================================================TELEGRAM========================================================
function threadHandle(runner, url, args, resolve, reject)
local t = runner(url, args)
local r = t:get(0)
while not r do
r = t:get(0)
end
local status = t:status()
if status == "completed" then
local ok, result = r[1], r[2]
if ok then resolve(result) else reject(result) end
elseif err then
reject(err)
elseif status == "canceled" then
reject(status)
end
t:cancel(0)
end
function requestRunner()
return effil.thread(function(u, a)
local https = require "ssl.https"
local ok, result = pcall(https.request, u, a)
return {ok, result}
end)
end
function async_http_request(url, args, resolve, reject)
local runner = requestRunner()
if not reject then reject = function() end end
threadHandle(runner, url, args, resolve, reject)
end
function encodeUrl(str)
str = str:gsub(" ", "%+")
str = str:gsub("\n", "%%0A")
return u8:encode(str, "CP1251")
end
--================================================================================================================
function telegram:sendMessage(msg)
msg = tostring(msg)
msg = msg:gsub("{......}", "")
msg = encodeUrl(msg)
async_http_request(("https://api.telegram.org/bot%s/sendMessage?chat_id=%s&text=%s"):format(telegram.token, telegram.chatId, msg), "", function(result) end)
end
telegram:sendMessage("Скрипт успешно запустился!")
print("send!")
Для тех, кто еще не понял, запуская код вне SA:MP, мы не можем использовать функционал Moonloader и SAMPFUNCS и других библиотек и плагинов для SAMP. К этому списку также относятся такие штуки, как потоки и функция задержки wait(time)
Окей, мы разобрались, как можно запускать скрипты без Moonloader’а,
но что делать, если нам лень писать каждый раз команду в cmd, чтобы запустить код и мы счастливые (или нет) пользователи Visual Studio Code?
Для этого существует специальное расширение «Code Runner», который может за нас вписывать нужную команду.
Для его установки открываем Visual Studio Code, далее нажимаем комбинацию клавиш CTRL+SHIFT+X или же на панельке (по умолчанию слева) выбираем пункт «Расширения». В поиске находим расширение «Code Runner».
Теперь устанавливаем его и в списке расширений находим его и нажимаем на значок шестриренки. В появившемся окошке выбираем пункт «Параметры расширения».
Далее ставим галочки у «Clear Previous», «Run In Terminal», «Save File Before Run». Как мы видим, в верхней панельке, рядом с открытыми файлами появился значок запуска скрипта (скрипт можно также запустить комбинацией клавиш CTRL+ALT+N).
Думаю на этом можно заканчить…
Установка интерпретатора Lua
Для работы с языком Lua требуется установка интерпретатора. На
официальном сайте Lua (https://www.lua.org) всегда доступна актуальная
версия для загрузки. Интерпретатор Lua можно установить на большинстве
операционных систем, включая Windows, macOS и Linux.
Windows
-
Перейдите на официальный сайт Lua и скачайте архив с бинарными
файлами для Windows. Обычно это архив с именем вида
lua-<версия>-win64.zip
. -
Распакуйте архив в удобное место, например, в
C:\Lua
. -
Добавьте путь к папке с бинарными файлами в переменную окружения
PATH
:- Откройте Панель управления → Система → Дополнительные параметры
системы → Переменные среды. - В разделе “Системные переменные” найдите переменную
PATH
и нажмите “Изменить”. - Добавьте путь к папке Lua, например:
C:\Lua
.
- Откройте Панель управления → Система → Дополнительные параметры
-
Проверьте установку, запустив команду в командной строке:
lua -v
Вы должны увидеть версию Lua.
macOS
На macOS проще всего установить Lua с помощью менеджера пакетов
Homebrew:
brew install lua
Проверьте корректность установки командой:
lua -v
Linux
На большинстве дистрибутивов Linux Lua можно установить через
стандартные менеджеры пакетов: — Ubuntu/Debian:
sudo apt update sudo apt install lua5.4
— Fedora:
sudo dnf install lua
— Arch Linux:
sudo pacman -S lua
Сборка из исходников
Если вам требуется специфическая версия Lua или вы хотите собрать
интерпретатор вручную, скачайте исходники с официального сайта.
Распакуйте архив и выполните команды:
tar -xvf lua-<версия>.tar.gz
cd lua-<версия>
make linux test
Чтобы установить интерпретатор глобально:
sudo make install
Настройка окружения
После установки Lua важно настроить окружение разработки.
Рекомендуется использовать текстовые редакторы или IDE с поддержкой Lua,
такие как: — Visual Studio Code (с расширением Lua) — IntelliJ IDEA
(плагин EmmyLua) — Sublime Text (с плагином Lua)
Менеджеры версий Lua
Для работы с разными версиями Lua удобно использовать менеджеры
версий, например, luaver
:
git clone https://github.com/dhavlik/luaver.git
cd luaver
./install.sh
После установки можно управлять версиями Lua командой:
luaver install 5.4.4
luaver use 5.4.4
Запуск скриптов
Чтобы запустить Lua-скрипт, используйте команду:
lua script.lua
Проверка кода в
интерактивном режиме
Интерпретатор Lua позволяет выполнять команды в интерактивном
режиме:
lua
> print("Hello, world!")
Для выхода из интерактивного режима используйте сочетание клавиш
Ctrl + D
(Linux и macOS) или Ctrl + Z
(Windows).
Настройка путей модулей
Lua позволяет подключать модули через функцию require
.
Для корректной работы следует настроить переменную
LUA_PATH
, указав пути к модулям:
export LUA_PATH="./?.lua;/usr/local/share/lua/5.4/?.lua;"
Проверьте текущий путь командой:
print(package.path)
Настройка окружения завершена. Теперь вы готовы к написанию и
выполнению Lua-скриптов.
Provide feedback
Saved searches
Use saved searches to filter your results more quickly
Sign up
Appearance settings
By Samir Tine, published on May 2023
rtc is an open source command line tool available with Luart that generates standalone executables from your Lua scripts.
Once compiled, an executable can be run on other Windows computers without the need to install Lua, facilitating the deployment of your applications.
In this tutorial, we will see how easy it is to make executables from Lua scripts, embed content, and deploy your applications on any Windows computer.
Your first executable
Create a simple hello.lua
file containing this script :
print("Hello World !")
Now, open a command line prompt, go to the folder where you just saved the file, and type the following command to invoke rtc
:
rtc hello.lua
Voila! You have just compiled your Lua script to a Windows executable hello.exe
. You can run it like any other Windows program.
In fact, by default, your compiled executable is not really standalone, it needs the Lua runtime library lua54.dll
, that can be found in the Luart bin\
folder.
If you suppress the PATH environment variable, your program hello.exe
won’t execute as it won’t be able to find the Lua runtime library anymore.
The hello.exe
depends on the Lua dynamic library lua54.dll
. This is called dynamic compilation.
Dynamic compilation is the standard way to run Lua, as it permits to load binary modules during runtime.
Let’s go static
If you want to get ride of the lua54.dll
dependency, you can use static compilation, by using the -s
option :
rtc -s hello.lua
You can see that the new hello.exe
has a bigger size. You guess it, that’s because it contains the Lua runtime library. It can now be executed without the need of the lua54.dll
library.
Since Luart 2.0.0, static compilation supports binary Lua modules loading.
You will need a binary module compiled with the lua54-static.lib
library, and its name must be suffixed by "-static"
Open a Window
By default, rtc
decide to compile executables for console or desktop depending on the file extension :
- Lua source file with a
.lua
extension are compiled for console - Lua source file with a
.wlua
extension are compiled for desktop
Let’s go further and compile our first desktop application, by saving the following file to hello.lua
:
local ui = require "ui"
ui.info("Hello world !")
Now compile it :
rtc hello.lua
If you run hello.exe
, by double clicking on it in the Windows explorer, a console window will show with an error message complaining that the ui
module is not found…
This happens because we have named our Lua source file with the .lua
extension, and rtc
compiled our file as a console application (remember that the ui
module is only available using desktop interpreter).
We have two possibilities to correct this: either rename our source file with the .wlua
extension or force rtc
to generate a desktop application. Let’s use this last method with the -w
option:
rtc -w hello.lua
Running hello.exe
will show only the message box, without the console window. You just compiled your first Lua desktop application !
You are iconic
rtc
provides default applications icons for your compiled executables, depending on console/desktop applications.
You can override this default behaviour and provide your own applications icons with the -i
option. Let’s use a specific icon for our previous hello.lua
desktop application :
rtc.exe -i path/to/your/icon.ico -w hello.lua
Just replace the path/to/your/icon.ico
with the path of the .ico
file to use. Rather simple !
I got this baggage with me
Now imagine that your application is made up of several Lua files in the same directory and even in subdirectories. How to package everything in the executable ?
Once again rtc
makes it easy. We just need to indicate, in addition to the main Lua source file, the directory to embed entirely in the executable. Yes, you read correctly. rtc
is able to include in the compiled executable the entire contents of a directory with all these files and subdirectories.
Let’s try to compile our desktop application with its entire directory content. To do this, open a command line prompt, got to the folder where our main Lua file hello.lua
is and type the following command :
rtc.exe -w hello.lua .
The dot .
means we ask rtc
to embed the current directory with all its content inside the executable.
The embed module
But wait a minute, how to access our files once they are embedded in our executable ?
The embed
module comes to the rescue. This module is only available to compiled scripts if embedded content is found inside the executable. This module contains :
- A File object to interact with all the embedded files.
- A Zip object instance to access the compressed embedded content.
If you want to use a Lua file or a Lua binary module in the embedded content, just use the global require()
function seamlessly, without the need to extract files before.
rtc
creates inside the executable a virtual file system that contains the directory content provided by the command line.
This allows access to embedded content transparently from your Lua scripts, both for accessing files and for loading Lua modules, whether binary or not.