Вопросы по Lua скриптингу

Общая тема для вопросов по разработке скриптов на языке программирования Lua, в частности под MoonLoader.
  • Задавая вопрос, убедитесь, что его нет в списке частых вопросов и что на него ещё не отвечали (воспользуйтесь поиском).
  • Поищите ответ в теме посвященной разработке Lua скриптов в MoonLoader
  • Отвечая, убедитесь, что ваш ответ корректен.
  • Старайтесь как можно точнее выразить мысль, а если проблема связана с кодом, то обязательно прикрепите его к сообщению, используя блок [code=lua]здесь мог бы быть ваш код[/code].
  • Если вопрос связан с MoonLoader-ом первым делом желательно поискать решение на wiki.

Частые вопросы

Как научиться писать скрипты? С чего начать?
Информация - Гайд - Всё о Lua скриптинге для MoonLoader(https://blast.hk/threads/22707/)
Как вывести текст на русском? Вместо русского текста у меня какие-то каракули.
Изменить кодировку файла скрипта на Windows-1251. В Atom: комбинация клавиш Ctrl+Shift+U, в Notepad++: меню Кодировки -> Кодировки -> Кириллица -> Windows-1251.
Как получить транспорт, в котором сидит игрок?
Lua:
local veh = storeCarCharIsInNoSave(PLAYER_PED)
Как получить свой id или id другого игрока?
Lua:
local _, id = sampGetPlayerIdByCharHandle(PLAYER_PED) -- получить свой ид
local _, id = sampGetPlayerIdByCharHandle(ped) -- получить ид другого игрока. ped - это хендл персонажа
Как проверить, что строка содержит какой-то текст?
Lua:
if string.find(str, 'текст', 1, true) then
-- строка str содержит "текст"
end
Как эмулировать нажатие игровой клавиши?
Lua:
local game_keys = require 'game.keys' -- где-нибудь в начале скрипта вне функции main

setGameKeyState(game_keys.player.FIREWEAPON, -1) -- будет сэмулировано нажатие клавиши атаки
Все иды клавиш находятся в файле moonloader/lib/game/keys.lua.
Подробнее о функции setGameKeyState здесь: lua - setgamekeystate | BlastHack — DEV_WIKI(https://www.blast.hk/wiki/lua:setgamekeystate)
Как получить id другого игрока, в которого целюсь я?
Lua:
local valid, ped = getCharPlayerIsTargeting(PLAYER_HANDLE) -- получить хендл персонажа, в которого целится игрок
if valid and doesCharExist(ped) then -- если цель есть и персонаж существует
  local result, id = sampGetPlayerIdByCharHandle(ped) -- получить samp-ид игрока по хендлу персонажа
  if result then -- проверить, прошло ли получение ида успешно
    -- здесь любые действия с полученным идом игрока
  end
end
Как зарегистрировать команду чата SAMP?
Lua:
-- До бесконечного цикла/задержки
sampRegisterChatCommand("mycommand", function (param)
     -- param будет содержать весь текст введенный после команды, чтобы разделить его на аргументы используйте string.match()
    sampAddChatMessage("MyCMD", -1)
end)
Крашит игру при вызове sampSendChat. Как это исправить?
Это происходит из-за бага в SAMPFUNCS, когда производится попытка отправки пакета определенными функциями изнутри события исходящих RPC и пакетов. Исправления для этого бага нет, но есть способ не провоцировать его. Вызов sampSendChat изнутри обработчика исходящих RPC/пакетов нужно обернуть в скриптовый поток с нулевой задержкой:
Lua:
function onSendRpc(id)
  -- крашит:
  -- sampSendChat('Send RPC: ' .. id)

  -- норм:
  lua_thread.create(function()
    wait(0)
    sampSendChat('Send RPC: ' .. id)
  end)
end
 
Последнее редактирование:
D

deleted-user-139653

Гость
как же я люблю регулярки...
не находит ник если в них есть ( ) [ ]
хелпаните

Код:
2023-12-16 11:11:13 (test) (ID: 2) подключился к серверу (IP: 141.105.222.22).
2023-12-16 11:11:13 [test] (ID: 2) подключился к серверу (IP: 141.105.222.22).

Lua:
function findNickByIP(ip, logContent)
    local result = {}
    for _, line in ipairs(logContent) do
        local nick = string.match(line, "%- (%S+) %(%a+: %d+%) подключился к серверу %(")
        local lineIP = extractIP(line)
        if nick and lineIP and lineIP == ip then
            table.insert(result, nick)
        end
    end
    return result
end
 

Akionka

akionka.lua
Проверенный
740
501
как же я люблю регулярки...
не находит ник если в них есть ( ) [ ]
хелпаните

Код:
2023-12-16 11:11:13 (test) (ID: 2) подключился к серверу (IP: 141.105.222.22).
2023-12-16 11:11:13 [test] (ID: 2) подключился к серверу (IP: 141.105.222.22).

Lua:
function findNickByIP(ip, logContent)
    local result = {}
    for _, line in ipairs(logContent) do
        local nick = string.match(line, "%- (%S+) %(%a+: %d+%) подключился к серверу %(")
        local lineIP = extractIP(line)
        if nick and lineIP and lineIP == ip then
            table.insert(result, nick)
        end
    end
    return result
end
Lua:
local texts = {
    '2023-12-16 11:11:13 (test) (ID: 2) подключился к серверу (IP: 141.105.222.22).',
    '2023-12-16 11:11:13 [test] (ID: 2) подключился к серверу (IP: 141.105.222.22).',
    '2023-12-16 11:11:13 ivan_govnov (ID: 2) подключился к серверу (IP: 141.105.222.22).'
 }

local pattern = '(%d+)%-(%d+)%-(%d+)% (%d+):(%d+):(%d+) (.-) %(ID: (%d+)%) .+ %(IP: (.-)%)'

for i, v in ipairs(texts) do
    local year, month, day, hour, min, sec, nick, id, ip = v:match(pattern)
    print(year, month, day, hour, min, sec, nick, id, ip)
end
 

Corrygan228

Участник
132
9
почему сообщения отправляются без задержки? типо биндер
Lua:
    for k, v in ipairs(buffer) do
        if v.activation == 1 then
            sampRegisterChatCommand(u8:decode(v.command), function()
                for text in v.multiline.v:gmatch("[^\r\n]+") do
                    lua_thread.create(function()
                        sampSendChat(text)
                        wait(1500)
                    end)
                end   
            end)
        end
    end
пробовал ставить задержку перед сообщением - не помогло
1702723053804.png
1702723065716.png
 
Последнее редактирование:
D

deleted-user-139653

Гость
Lua:
local texts = {
    '2023-12-16 11:11:13 (test) (ID: 2) подключился к серверу (IP: 141.105.222.22).',
    '2023-12-16 11:11:13 [test] (ID: 2) подключился к серверу (IP: 141.105.222.22).',
    '2023-12-16 11:11:13 ivan_govnov (ID: 2) подключился к серверу (IP: 141.105.222.22).'
 }

local pattern = '(%d+)%-(%d+)%-(%d+)% (%d+):(%d+):(%d+) (.-) %(ID: (%d+)%) .+ %(IP: (.-)%)'

for i, v in ipairs(texts) do
    local year, month, day, hour, min, sec, nick, id, ip = v:match(pattern)
    print(year, month, day, hour, min, sec, nick, id, ip)
end
спасибо, но я клоун пиздец, у меня после даты и времени не стояло -
потому и регулярка не хотела вытаскивать ник....
 

Akionka

akionka.lua
Проверенный
740
501
почему сообщения отправляются без задержки? типо биндер
Lua:
    for k, v in ipairs(buffer) do
        if v.activation == 1 then
            sampRegisterChatCommand(u8:decode(v.command), function()
                for text in v.multiline.v:gmatch("[^\r\n]+") do
                    lua_thread.create(function()
                        sampSendChat(text)
                        wait(1500)
                    end)
                end    
            end)
        end
    end
потому что ты создаешь тред в котором выполняешь действие и ждешь, а треды выполняются конкурентно

Lua:
    for k, v in ipairs(buffer) do
        if v.activation == 1 then
            sampRegisterChatCommand(u8:decode(v.command), function()
                lua_thread.create(function()
                    for text in v.multiline.v:gmatch("[^\r\n]+") do
                        sampSendChat(text)
                        wait(1500)
                    end
                end)
            end)
        end
    end
 
  • Нравится
Реакции: Corrygan228

Leon_Trotsky

Участник
39
2
Как в имгуи сделать возможность копирования информации по клику на саму информацию?
 

Dmitriy Makarov

25.05.2021
Проверенный
2,505
1,134
Как в имгуи сделать возможность копирования информации по клику на саму информацию?
 

newerlock

Новичок
5
0
помогите мне чтобы бот автоматически регистрировался на этом сервере 46.174.48.235:7777
 

Вложения

  • moon bot krp.lua
    41.7 KB · Просмотры: 1

kuboni

Потрачен
154
2
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Pls
 

Вложения

  • decompile_c.luac
    1.5 KB · Просмотры: 1
  • decompile_c.luac
    1.5 KB · Просмотры: 1

Corrygan228

Участник
132
9
почему я ввожу текст и с ним все нормально, но если перезапустить скрипт, то в инпуте он отображается вопросительными знаками, хотя в json все нормально и в чат он тоже нормально отправляется
Lua:
function json(filePath)
    local filePath = getWorkingDirectory()..'\\config\\'..(filePath:find('(.+).json') and filePath or filePath..'.json')
    local class = {}
    if not doesDirectoryExist(getWorkingDirectory()..'\\config') then
        createDirectory(getWorkingDirectory()..'\\config')
    end
    function class:Save(tbl)
        if tbl then
            local F = io.open(filePath, 'w')
            F:write(encodeJson(tbl) or {})
            F:close()
            return true, 'ok'
        end
        return false, 'table = nil'
    end
    function class:Load(defaultTable)
        if not doesFileExist(filePath) then
            class:Save(defaultTable or {})
        end
        local F = io.open(filePath, 'r+')
        local TABLE = decodeJson(F:read() or {})
        F:close()
        for def_k, def_v in next, defaultTable do
            if TABLE[def_k] == nil then
                TABLE[def_k] = def_v
            end
        end
        return TABLE
    end
    return class
end
local testJSON = json('Prison Helper Binder.json'):Load({})
function save()
    json('Prison Helper Binder.json'):Save(testJSON)
end

switch = 0

local whatSave = {
    name = imgui.ImBuffer(256),
    multiline = imgui.ImBuffer(256),
    command = imgui.ImBuffer(256),
    hotkey = imgui.ImBuffer(256),
    activation = imgui.ImInt(0),
}

local buffer = {}

for k, v in ipairs(testJSON) do
    table.insert(buffer, {
        name = u8:decode(v.name),
        multiline = imgui.ImBuffer(tostring(v.multiline), 1024),
        command = u8:decode(v.command),
        hotkey = u8:decode(v.hotkey),
        activation = v.activation
    })
end

--main()
    for k, v in ipairs(buffer) do
        if v.activation == 1 then
            sampRegisterChatCommand(u8:decode(v.command), function()
                lua_thread.create(function()
                    for text in v.multiline.v:gmatch("[^\r\n]+") do
                        sampSendChat(text)
                        wait(2000)
                    end
                end)
            end)
        end
    end

                        --OnDrawFrame()
                        imgui.Columns(2, '##binder_main_and_secondary_parts', true)
                        imgui.SetColumnWidth(-1, 200)

                            imgui.BeginChild("##1", imgui.ImVec2(184, 250), false)

                                for k, v in ipairs(testJSON) do
                                    if imgui.Button(u8(v.name), imgui.ImVec2(180, 28)) then
                                        switch = k
                                    end
                                end
                                imgui.SetCursorPosX((184-80)/2)
                                if imgui.Button(u8'Добавить', imgui.ImVec2(80, 26)) then
                                    imgui.OpenPopup('##add_bind')
                                end
                                if imgui.BeginPopupModal('##add_bind', _, imgui.WindowFlags.NoResize + imgui.WindowFlags.NoMove) then
                                    imgui.SetNextWindowSize(imgui.ImVec2(350, 250))
                                    imgui.SetNextWindowPos(imgui.ImVec2(sw / 2, sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
                                    imgui.CenterText(u8'Настройка нового бинда')
                                    imgui.Separator()
                                    imgui.NewLine()
                                    imgui.PushItemWidth(130)
                                    imgui.InputText(u8'Название', whatSave.name)
                                    imgui.PopItemWidth()
                                    imgui.PushItemWidth(130)
                                    imgui.Combo(u8'##Активация', whatSave.activation, {u8"На кнопку", u8"На команду"})
                                    imgui.PopItemWidth()
                                    imgui.SameLine()
                                    if whatSave.activation.v == 1 then  
                                        imgui.PushItemWidth(130)        
                                        imgui.InputText(u8'##Команда без /', whatSave.command)
                                        imgui.PopItemWidth()
                                    elseif whatSave.activation.v == 0 then
                                        imgui.PushItemWidth(130)
                                        imgui.InputText(u8'##Клавиша', whatSave.hotkey)
                                        imgui.PopItemWidth()
                                    end
                                    imgui.NewLine()
                                    imgui.Separator()
                                    imgui.SetCursorPosX(18)
                                    if imgui.Button(u8'Принять', imgui.ImVec2(120, 30)) then
                                        if whatSave.name.v ~= '' then
                                            if whatSave.activation.v == 1 then
                                                if whatSave.command.v ~= '' then
                                                    table.insert(testJSON, {
                                                        name = u8:decode(whatSave.name.v),
                                                        multiline = u8:decode(whatSave.multiline.v),
                                                        command = u8:decode(whatSave.command.v),
                                                        hotkey = u8:decode(whatSave.hotkey.v),
                                                        activation = whatSave.activation.v,
                                                    }) save()
                                                    table.insert(buffer, {
                                                        name = u8:decode(tostring(whatSave.name.v)),
                                                        multiline = imgui.ImBuffer(tostring(whatSave.multiline.v), 1024),
                                                        command = u8:decode(whatSave.command.v),
                                                        hotkey = u8:decode(whatSave.hotkey.v),
                                                        activation = whatSave.activation.v,
                                                    })
                                                    whatSave = {
                                                        name = imgui.ImBuffer(256),
                                                        multiline = imgui.ImBuffer(256),
                                                        command = imgui.ImBuffer(256),
                                                        hotkey = imgui.ImBuffer(256),
                                                        activation =  imgui.ImInt(0),
                                                    }
                                                    imgui.CloseCurrentPopup()
                                                else
                                                    sampAddChatMessage('{0099FF}[Prison Helper]:' .. white_color .. ' Введите команду для активации бинда!', -1)
                                                    imgui.CloseCurrentPopup()
                                                end
                                            else
                                                if whatSave.hotkey.v ~= '' then
                                                    table.insert(testJSON, {
                                                        name = u8:decode(whatSave.name.v),
                                                        multiline = u8:decode(whatSave.multiline.v),
                                                        command = u8:decode(whatSave.command.v),
                                                        hotkey = u8:decode(whatSave.hotkey.v),
                                                        activation = whatSave.activation.v,
                                                    }) save()
                                                    table.insert(buffer, {
                                                        name = u8:decode(tostring(whatSave.name.v)),
                                                        multiline = imgui.ImBuffer(tostring(whatSave.multiline.v), 1024),
                                                        command = u8:decode(whatSave.command.v),
                                                        hotkey = u8:decode(whatSave.hotkey.v),
                                                        activation = whatSave.activation.v,
                                                    })
                                                    whatSave = {
                                                        name = imgui.ImBuffer(256),
                                                        multiline = imgui.ImBuffer(256),
                                                        command = imgui.ImBuffer(256),
                                                        hotkey = imgui.ImBuffer(256),
                                                        activation =  imgui.ImInt(0),
                                                    }
                                                    imgui.CloseCurrentPopup()
                                                else
                                                    sampAddChatMessage('{0099FF}[Prison Helper]:' .. white_color .. ' Укажите клавишу для активации бинда!', -1)
                                                    imgui.CloseCurrentPopup()
                                                end
                                            end
                                        else
                                            sampAddChatMessage('{0099FF}[Prison Helper]:' .. white_color .. ' Укажите название бинда!', -1)
                                            imgui.CloseCurrentPopup()
                                        end
                                    end
                                    imgui.SameLine()
                                    imgui.SetCursorPosX(178)
                                    if imgui.Button(u8'Отмена', imgui.ImVec2(120, 30)) then
                                        imgui.CloseCurrentPopup()
                                    end
                                    imgui.EndPopup()
                                end

                            imgui.EndChild()

                        imgui.NextColumn()

                            imgui.BeginChild("##2", imgui.ImVec2(342, 240), false)
                                       
                                for k, v in ipairs(buffer) do
                                    if k == switch then
                                        if v.activation == 0 then
                                            imgui.Text(u8'Активация: ' .. v.hotkey)
                                        else
                                            imgui.Text(u8'Активaция: /' .. v.command)
                                        end
                                        if imgui.InputTextMultiline('##multiline', v.multiline, imgui.ImVec2(342, 178)) then
                                            testJSON[k].multiline = u8:decode(v.multiline.v)
                                            save()
                                        end

                                        imgui.SetCursorPosX(342-120)
                                        if imgui.Button(u8'Удалить', imgui.ImVec2(120, 30)) then
                                            table.remove(testJSON, k)
                                            table.remove(buffer, k)
                                            save()
                                        end
                                    end
                                end

                            imgui.EndChild()

                        imgui.Columns(1)
1702731438175.png

1702731449874.png
 

Дядя Энрик.

Активный
338
81
u8'Text'

Lua:
for k, v in ipairs(panel2) do
        imgui.SetCursorPosX(10)
        if imgui.Selectable(u8(v[1]), selectable == v[1], imgui.SelectableFlags.AllowDoubleClick) then
            imgui.Text(u8(v[1]))
            selectable = v[1]
            sampAddChatMessage('Выбран: '..v[1], -1)
        end
    end
выбираю строчку из диалога, после выбора строчки мне надо отправить sampSendDialogResponse(), но ничего не происходит. Нажать надо на "выбор"
всё ещё актуально
 

h0los

Активный
260
45
хелп опять что то напартачил с кодом :)
[ML] (error) langlua.lua: ...rizona Games Launcher\bin\arizona\moonloader\langlua.lua:36: ')' expected near 'mimgui'
[ML] (error) langlua.lua: Script died due to an error. (1DB75F84)
Lua:
require("lib.moonloader")
local imgui = require("mimgui")
local new = imgui.new
local flags = imgui.WindowFlags
local window = new.bool()
local ffi = require("ffi")
local str = ffi.string
local encoding = require 'encoding'
encoding.default = 'CP1251'
local u8 = encoding.UTF8

imgui.OnFrame(function() return window[0] end, function(player)
    imgui.Begin("Lang-Lua", window, flags.NoResize + flags.AlwaysAutoResize + flags.NoCollapse)
    if imgui.CollapsingHeader(u8"Что такое lua?") then
        imgui.Text(u8"Lua - Это язык программирования который используется в играх для дополнений фиксов и т.д")
    end
    if imgui.CollapsingHeader(u8"А как на нем написать легкий скрипт?") then
        imgui.Text(u8"Что бы написать легкий скрипт нужно")
        imgui.Text(u8"Используем функцию скрипта")
        imgui.Separator()
        imgui.TextDisabled("function main()")
        imgui.TextDisabled("    wait(-1)")
        imgui.TextDisabled("end")
        imgui.Separator()
        imgui.Text(u8"Мы только что сделали функию, Ура!")
        imgui.Text(u8"Главное в функции нужно прописать") imgui.SameLine() imgui.TextDisabled("wait(-1)")
        imgui.Text(u8"Теперь заходим на сайт") imgui.SameLine() imgui.TextDisabled("https://wiki.blast.hk/")
        imgui.SameLine() imgui.Text(u8"После этого заходим в поиск и пишем что мы хотим сделать в скрипте")
        imgui.Text(u8"Когда нашли вставляем в код только перед wait(-1)")
        imgui.Text(u8"Когда вставили сохраняем код и захожим в игру проверять!")
    end
    if imgui.CollapsingHeader(u8"Что такое мимгуи и как на нем писать скрипты?") then
        imgui.Text(u8"Мимгуи - это библиотека для красивых окон, очень легкая в освоении")
        imgui.Text(u8"А вот и первый пример")
        imgui.Separator()
        imgui.TextDisabled("local imgui = require("mimgui")")
        imgui.TextDisabled("local new = imgui.new")
        imgui.TextDisabled("local window = new.bool()")
        imgui.TextDisabled("imgui.OnFrame(function() return window[0] end, function(player)")
        imgui.TextDisabled("    imgui.Begin("Window"), window")
        imgui.TextDisabled("    imgui.End()")
        imgui.TextDisabled("end)")
        imgui.Separator()
        imgui.Text("Поздравляю мы теперь сделали mimgui окно!")
    end
    imgui.End()
end)

function main()
    sampRegisterChatCommand("ll", function() window[0] = not window[0] end)
    wait(-1)
end