Вопросы по 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
 
Последнее редактирование:

legnd

Известный
1,534
655
Скриншот 16-12-2023 011606.jpg

русский язык не воспринимается
 

Дядя Энрик.

Активный
319
75
Посмотреть вложение 224811
русский язык не воспринимается
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(), но ничего не происходит. Нажать надо на "выбор"
1702697952084.png
1702697966550.png
 

DarkDTM

Участник
52
3
Как сделать так, что бы если скрипт не находил файл - он создавал его
 

Corrygan228

Участник
132
9
почему не получается обратиться к значению activation?
[11:54:27.185195] (error) Prison Helper.lua: ...HER\resources\projects\crmp\moonloader\Prison Helper.lua:597: attempt to index field 'activation' (a number value)
stack traceback:
...HER\resources\projects\crmp\moonloader\Prison Helper.lua:597: in function 'OnDrawFrame'
...AUNCHER\resources\projects\crmp\moonloader\lib\imgui.lua:1378: in function <...AUNCHER\resources\projects\crmp\moonloader\lib\imgui.lua:1367>
[11:54:27.185195] (error) Prison Helper.lua: Script died due to an error. (303E9454)
Lua:
                                for k, v in ipairs(testJSON) do
                                    if k == switch then
                                        if v.activation.v == 0 then -- здесь ошибка
                                            imgui.Text(u8'Активация: ' .. v.hotkey.v)
                                        else
                                            imgui.Text(u8'Активaция: ' .. v.command.v)
                                        end
                                        if imgui.InputTextMultiline('##multiline', v.multiline, imgui.ImVec2(300, 200)) then
                                            testJSON[k].multiline = v.multiline.v
                                            save()
                                        end
                                        if imgui.Button(u8'Удалить', imgui.ImVec2(120, 30)) then
                                            table.remove(testJSON, k)
                                            save()
                                        end
                                    end
                                end
1702716985795.png
 

Andrinall

Известный
679
532
почему не получается обратиться к значению activation?

Lua:
                                for k, v in ipairs(testJSON) do
                                    if k == switch then
                                        if v.activation.v == 0 then -- здесь ошибка
                                            imgui.Text(u8'Активация: ' .. v.hotkey.v)
                                        else
                                            imgui.Text(u8'Активaция: ' .. v.command.v)
                                        end
                                        if imgui.InputTextMultiline('##multiline', v.multiline, imgui.ImVec2(300, 200)) then
                                            testJSON[k].multiline = v.multiline.v
                                            save()
                                        end
                                        if imgui.Button(u8'Удалить', imgui.ImVec2(120, 30)) then
                                            table.remove(testJSON, k)
                                            save()
                                        end
                                    end
                                end
Посмотреть вложение 224823
Потому что ты пытаешься обратиться по индексу к числу, а не таблице или userdata. Оберни в ImBool значение из json'а, если тебе так хочется через v.activation.v, либо просто убери это .v в конце
 

Corrygan228

Участник
132
9
Потому что ты пытаешься обратиться по индексу к числу, а не таблице или userdata. Оберни в ImBool значение из json'а, если тебе так хочется через v.activation.v, либо просто убери это .v в конце
Немного не понял? Как мне обернуть это в ImBool, если оно изначально является ImInt?
Скинул чуть больше кода, мб понятнее будет
Lua:
                                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()
                                                    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()
                                                    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.BeginChild("##2", imgui.ImVec2(342, 240), false)
                                        
                                for k, v in ipairs(testJSON) do
                                    if k == switch then
                                        if v.activation.v == 0 then -- вот оно
                                            imgui.Text(u8'Активация: ' .. v.hotkey.v)
                                        else
                                            imgui.Text(u8'Активaция: ' .. v.command.v)
                                        end
                                        if imgui.InputTextMultiline('##multiline', v.multiline, imgui.ImVec2(300, 200)) then
                                            testJSON[k].multiline = v.multiline.v
                                            save()
                                        end
                                        if imgui.Button(u8'Удалить', imgui.ImVec2(120, 30)) then
                                            table.remove(testJSON, k)
                                            save()
                                        end
                                    end
                                end

                            imgui.EndChild()
 

percheklii

Известный
725
266
как же я люблю регулярки...
не находит ник если в них есть ( ) [ ]
хелпаните

Код:
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
Проверенный
742
500
как же я люблю регулярки...
не находит ник если в них есть ( ) [ ]
хелпаните

Код:
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
 
Последнее редактирование:

percheklii

Известный
725
266
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
Проверенный
742
500
почему сообщения отправляются без задержки? типо биндер
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