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

владикс

Потрачен
533
182
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Почему при нажатии на imgui.Button - не работает прожатие АЛЬТ, а при хуке текста из чата всё работает.


аа?:
-- работает
if text:find('test') then
    lua_thread.create(function()
        setVirtualKeyDown(18, true)
        wait(300)
        setVirtualKeyDown(18, false)
    end)
end

a&:
-- не работает
if imgui.Button("tes", imgui.ImVec2(20, 20))  then
    lua_thread.create(function()
        setVirtualKeyDown(18, true)
        wait(300)
        setVirtualKeyDown(18, false)
    end)
end
 
D

deleted-user-418783

Гость
Почему код не работает?
text:
local cfg = ini.load({
    opengate = {
        lock = false
    }

}, "Config.ini")
local opengate = cfg.opengate.lock

function main()
sampRegisterChatCommand("opengateinfo", function()
        cfg.opengate.lock = not cfg.opengate.lock
    if ini.save(cfg, "Config.ini") then
        sampAddChatMessage("{58c9b1}[Config]: {FFFFFF}OpenGate: " .. (cfg.opengate.lock and "{FFAAAA}Выключён" or "{AAFFAA}Включен"), 0xEEEEEE)
        end
    end)
    
            while true do wait(0)
            if opengate then
            if isKeyJustPressed(VK_H) then
            sampSendChat("/opengate")
              end
        end
end

Код работает в обоих состояниях, в true и false. Как пофиксить?
 

qdIbp

Автор темы
Проверенный
1,450
1,197
Почему код не работает?
text:
local cfg = ini.load({
    opengate = {
        lock = false
    }

}, "Config.ini")
local opengate = cfg.opengate.lock

function main()
sampRegisterChatCommand("opengateinfo", function()
        cfg.opengate.lock = not cfg.opengate.lock
    if ini.save(cfg, "Config.ini") then
        sampAddChatMessage("{58c9b1}[Config]: {FFFFFF}OpenGate: " .. (cfg.opengate.lock and "{FFAAAA}Выключён" or "{AAFFAA}Включен"), 0xEEEEEE)
        end
    end)
 
            while true do wait(0)
            if opengate then
            if isKeyJustPressed(VK_H) then
            sampSendChat("/opengate")
              end
        end
end

Код работает в обоих состояниях, в true и false. Как пофиксить?
Попробуй так
Lua:
require('moonloader')
local ini = require('inicfg')
local nCfg = "Config.ini"

local cfg = ini.load({
    opengate = {
        lock = false
    }

}, nCfg)

function main()
    sampRegisterChatCommand("opengateinfo", function()
        cfg.opengate.lock = not cfg.opengate.lock
        if ini.save(cfg, nCfg) then
           sampAddChatMessage("[Config]: {FFFFFF}OpenGate: " .. (cfg.opengate.lock and "{FFAAAA}Выключён" or "{AAFFAA}Включен"), 0x58c9b1)
        end
    end)
  
    while true do wait(0)
       if cfg.opengate.lock then
           if isKeyJustPressed(VK_H) then
               sampSendChat("/opengate")
           end
        end
    end
end
 

xColorized

Известный
1,113
489
Попробуй так
Lua:
local ini = require('inicfg')
local nCfg = "Config.ini"

local cfg = ini.load({
    opengate = {
        lock = false
    }

}, nCfg)

function main()
    sampRegisterChatCommand("opengateinfo", function()
        cfg.opengate.lock = not cfg.opengate.lock
        if ini.save(cfg, nCfg) then
           sampAddChatMessage("[Config]: {FFFFFF}OpenGate: " .. (cfg.opengate.lock and "{FFAAAA}Выключён" or "{AAFFAA}Включен"), 0x58c9b1)
        end
    end)
  
    while true do wait(0)
       if cfg.opengate.lock then
           if isKeyJustPressed(VK_H) then
               sampSendChat("/opengate")
           end
        end
    end
end
Ты забыл require 'moonloader'
 
  • Нравится
Реакции: qdIbp
D

deleted-user-418783

Гость
Попробуй так
Lua:
require('moonloader')
local ini = require('inicfg')
local nCfg = "Config.ini"

local cfg = ini.load({
    opengate = {
        lock = false
    }

}, nCfg)

function main()
    sampRegisterChatCommand("opengateinfo", function()
        cfg.opengate.lock = not cfg.opengate.lock
        if ini.save(cfg, nCfg) then
           sampAddChatMessage("[Config]: {FFFFFF}OpenGate: " .. (cfg.opengate.lock and "{FFAAAA}Выключён" or "{AAFFAA}Включен"), 0x58c9b1)
        end
    end)
 
    while true do wait(0)
       if cfg.opengate.lock then
           if isKeyJustPressed(VK_H) then
               sampSendChat("/opengate")
           end
        end
    end
end
не понял, как ты это сделал, объясни пожалуйста, потому что у меня всё заработало.
 
  • Злость
Реакции: qdIbp

qdIbp

Автор темы
Проверенный
1,450
1,197
не понял, как ты это сделал, объясни пожалуйста, потому что у меня всё заработало.
Ты создал переменную которая сохранила изначальную переменную из массива и она по ходу скрипта ни как не меняло свое значение, тогда я удалил opengate и заменил в беск.цикле на cfg.opengate.lock
 
  • Нравится
Реакции: deleted-user-418783

tsunamiqq

Участник
433
17
Не находит текст
Lua:
local statbizWeek = 0

    if id == 0 then
        for line in text:gmatch("[^\r\n]+") do
            if line:find("Вторник    {.-}%$(%d+){.-}") then
                bankbizWeek = line:match("Вторник    {.-}%$(%d+){.-}")
                statbizWeek = statbizWeek + bankbizWeek
            end
        end
    end
Вторник [96E54C]$1201700[FFFFFF]
 
Последнее редактирование:

0x18d036

Известный
783
221
Как сделать проверку на то что именно в руках у меня сейчас НЕ то оружие по айди, к примеру: У меня в руках сейчас НЕ дигл вернет = true, а если в руках сейчас он взят = false
 

MLycoris

На вид оружие массового семяизвержения
Проверенный
1,974
2,209
Как сделать проверку на то что именно в руках у меня сейчас НЕ то оружие по айди, к примеру: У меня в руках сейчас НЕ дигл вернет = true, а если в руках сейчас он взят = false
Lua:
if getCurrentCharWeapon(1) ~= 24 then -- ~= означает не равенство
    -- если оружие не равно 24 ид, то выполняется условие
end
 
  • Нравится
Реакции: 0x18d036

MLycoris

На вид оружие массового семяизвержения
Проверенный
1,974
2,209
Аргумент 1 что значит? Там же вроде должен быть хендл персонажа?
int weapon = getCurrentCharWeapon(Ped ped)
хендл твоего перса всегда равен 1, так что нет разницы поставишь ты PLAYER_PED или цифру 1
 
  • Нравится
Реакции: 0x18d036

Julimba

Участник
108
10
Тема такая, что если бегать с этим скриптом около 5 минут и крутить камерой, то фпс сильно падает.
Если перезагрузить скрипт или удалить его, то фпс на время возвращается. Проверяли это на нескольких компах, везде такая проблема.
Буду рад если поможете решить данную проблему.

Lua:
require "lib.moonloader"

    --==[БИБЛИОТЕКИ]==--
local keys         = require "vkeys"
local imgui     = require 'mimgui'
local encoding    = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8
local new = imgui.new

    --==[ЛОКАЛЬНЫЕ ТЕГИ]==--
local tag = '{6cbdab}[Chat Manager] {ffffff}'
local sizeX, sizeY     = getScreenResolution()
local renderWindow = new.bool()

function main()
    while not isSampAvailable() do wait(100) end
    sampAddChatMessage(tag .. 'Script loaded', 0x6cbdab)
    while true do wait(0)
        if wasKeyPressed(88) and not sampIsCursorActive() then
            renderWindow[0] = not renderWindow[0]
        end
        addEventHandler("onWindowMessage", function (msg, wparam, lparam)
            if wparam == keys.VK_ESCAPE or wparam == keys.VK_TAB then
                if renderWindow[0] then renderWindow[0] = false consumeWindowMessage(true, true) end
            end
        end)
    end
end

    --==[OnFrame]==--
imgui.OnFrame(function() return renderWindow[0] end,
    function(player)
        imgui.SetNextWindowPos(imgui.ImVec2(sizeX / 2, sizeY / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        imgui.SetNextWindowSize(imgui.ImVec2(400, 400))
        imgui.Begin("Chat Manager", renderWindow, imgui.WindowFlags.NoResize + imgui.WindowFlags.NoCollapse)
        imgui.End()
    end
)
 

вайега52

Налуашил состояние
Модератор
2,976
3,094
Тема такая, что если бегать с этим скриптом около 5 минут и крутить камерой, то фпс сильно падает.
Если перезагрузить скрипт или удалить его, то фпс на время возвращается. Проверяли это на нескольких компах, везде такая проблема.
Буду рад если поможете решить данную проблему.

Lua:
require "lib.moonloader"

    --==[БИБЛИОТЕКИ]==--
local keys         = require "vkeys"
local imgui     = require 'mimgui'
local encoding    = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8
local new = imgui.new

    --==[ЛОКАЛЬНЫЕ ТЕГИ]==--
local tag = '{6cbdab}[Chat Manager] {ffffff}'
local sizeX, sizeY     = getScreenResolution()
local renderWindow = new.bool()

function main()
    while not isSampAvailable() do wait(100) end
    sampAddChatMessage(tag .. 'Script loaded', 0x6cbdab)
    while true do wait(0)
        if wasKeyPressed(88) and not sampIsCursorActive() then
            renderWindow[0] = not renderWindow[0]
        end
        addEventHandler("onWindowMessage", function (msg, wparam, lparam)
            if wparam == keys.VK_ESCAPE or wparam == keys.VK_TAB then
                if renderWindow[0] then renderWindow[0] = false consumeWindowMessage(true, true) end
            end
        end)
    end
end

    --==[OnFrame]==--
imgui.OnFrame(function() return renderWindow[0] end,
    function(player)
        imgui.SetNextWindowPos(imgui.ImVec2(sizeX / 2, sizeY / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        imgui.SetNextWindowSize(imgui.ImVec2(400, 400))
        imgui.Begin("Chat Manager", renderWindow, imgui.WindowFlags.NoResize + imgui.WindowFlags.NoCollapse)
        imgui.End()
    end
)
У тебя функция addEventHandler сидит в бесконечном цикле, хз, есть ли в мунлоадере защита от такой утечки памяти, но в любом случае её желательно перенести в глобальное пространство
 
  • Нравится
Реакции: Julimba

Corrygan228

Участник
132
9
пытаюсь сделать биндер, но почему-то не появляется imgui.InputText в цикле(комментарий оставил), а если я нажимаю на +, чтобы добавить другой инпут, то игру крашит, в чём ошибка? такая же тема и с добавлянием именно бинда. когда в первой колонке нажимаю кнопку "добавить", игру крашит
Lua:
local binds_arr = {
    {name=u8'Приветствие', activation_arr={u8'На кнопку:', u8'По команде:'}, activation_select=imgui.ImInt(0), activation_command=imgui.ImBuffer(256), binds={stroke = imgui.ImBuffer(256)}}
}

local bind_name = imgui.ImBuffer(256)
 
   
                         --фрейм
                        imgui.Columns(2, '##main_part_4_select_binder')
                        imgui.SetColumnWidth(-1, 200)

                            imgui.BeginChild('##binds_first_column', imgui.ImVec2(186, 250), false)

                                for i, k in ipairs(binds_arr) do
                                    imgui.Button(binds_arr[i].name, imgui.ImVec2(170, 24))
                                end

                                imgui.SetCursorPosX(48)
                                if imgui.Button(u8'Добавить', imgui.ImVec2(74, 24)) then
                                    imgui.OpenPopup('##add_new_bind')
                                end

                                if imgui.BeginPopupModal('##add_new_bind', true, imgui.WindowFlags.NoTitleBar + imgui.WindowFlags.NoResize) then
                                    imgui.SetWindowSize(imgui.ImVec2(300, 120))
                                    imgui.PushItemWidth(140)
                                    imgui.InputText(u8'Название бинда', bind_name)
                                    imgui.NewLine()
                                    imgui.SetCursorPosX(53.3)
                                    if imgui.Button(u8'Добавить', imgui.ImVec2(90, 30)) then
                                        table.insert(binds_arr, {name = u8(bind_name.v), activation_arr={u8'На кнопку:', u8'По команде'}, activation_select=imgui.ImInt(0), binds={stroke = imgui.ImBuffer(256)}})
                                        imgui.CloseCurrentPopup()
                                    end
                                    imgui.SameLine()
                                    imgui.SetCursorPosX(166.7)
                                    if imgui.Button(u8'Отмена', imgui.ImVec2(90, 30)) then
                                        imgui.CloseCurrentPopup()
                                    end
                                    imgui.EndPopup()
                                end


                            imgui.EndChild()

                        imgui.NextColumn()

                            imgui.BeginChild('##binds_second_column', imgui.ImVec2(348, 250), false)

                                for i = 1, #binds_arr do
                                    if binds_arr[i] then
                                        imgui.CenterText(u8'Настройки бинда: ' .. binds_arr[i].name)
                                        imgui.Combo(u8'Активация', binds_arr[i].activation_select, binds_arr[i].activation_arr, #binds_arr[i].activation_arr)
                                        if binds_arr[i].activation_select == 0 then
                                            imgui.SameLine()
                                            imgui.Text(u8'Кнопка')
                                        else
                                            imgui.SameLine()
                                            imgui.InputText(u8'Команда для активации', binds_arr[i].activation_command)
                                        end
                                        imgui.Separator()
                                        for k, v in ipairs(binds_arr[i].binds) do -- где-то здесь козяк
                                            imgui.InputText(u8'Строка №' .. #binds_arr[i].binds + 1, binds_arr[i].binds[k])
                                        end
                                        imgui.SameLine()
                                        if imgui.Button('+') then -- и здесь косяк
                                            table.insert(binds_arr[i].binds, {stroke = imgui.ImBuffer(256)})
                                        end
                                        imgui.SameLine()
                                        if imgui.Button('-') then -- и здесь косяк
                                            table.remove(binds_arr[i].binds)
                                        end
                                    end
                                end
                           
                            imgui.EndChild()

                        imgui.Columns(1)
 

Dmitriy Makarov

25.05.2021
Проверенный
2,516
1,142
Не находит текст
Lua:
local statbizWeek = 0

    if id == 0 then
        for line in text:gmatch("[^\r\n]+") do
            if line:find("Вторник    {.-}%$(%d+){.-}") then
                bankbizWeek = line:match("Вторник    {.-}%$(%d+){.-}")
                statbizWeek = statbizWeek + bankbizWeek
            end
        end
    end
Вторник [96E54C]$1201700[FFFFFF]
Тебе именно в таком виде лог дал текст?
Вторник [96E54C]$1201700[FFFFFF]
Просто немного смущают квадратные скобки у HEX кодов. Они должны быть такими: {} > {FFFFFF}.
Если всё-таки квадратные скобки, то попробуй, не знаю, как-то так:
"Вторник %[.-%]%$(%d+)%[.-%]"
 
  • Нравится
Реакции: MLycoris