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

h0los

Активный
267
45
перемести
local enabled = new.bool(ini.main.enabled)
ниже кода с конфигом,он его не видит,поэтому крашит
<3

плз хелп (что то напартачил)
суть не работает отображение жму галочку не жму отображается все равно
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 inicfg = require "inicfg"
local directIni = "ktime.ini"
local ini = inicfg.load(inicfg.load({
    main = {
        enabled = false
    },
}, directIni))
local encoding = require 'encoding'
encoding.default = 'CP1251'
local u8 = encoding.UTF8

local font = renderCreateFont("Arial", 20, 15)

local enabled = new.bool(ini.main.enabled)

imgui.OnFrame(function() return window[0] end, function(player)
    imgui.Begin("ktime", window, flags.NoResize + flags.AlwaysAutoResize + flags.NoCollapse)
    if imgui.Checkbox(u8"Включить время на экране", enabled) then
        ini.main.enabled = enabled[0]
        inicfg.save(ini, "ktime.ini")
        time = not time
    end
    imgui.End()
end)

function main()
    sampRegisterChatCommand("kt", function() window[0] = not window[0] end)
    while true do wait(0)
        local time = renderFontDrawText(font, "" .. getTimeOfDay(), 1100, 50, -1)
    end
end
 
Последнее редактирование:
D

deleted-user-139653

Гость
<3

плз хелп (что то напартачил)
суть не работает отображение жму галочку не жму отображается все равно
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 inicfg = require "inicfg"
local directIni = "ktime.ini"
local ini = inicfg.load(inicfg.load({
    main = {
        enabled = false
    },
}, directIni))
local encoding = require 'encoding'
encoding.default = 'CP1251'
local u8 = encoding.UTF8

local font = renderCreateFont("Arial", 20, 15)

local enabled = new.bool(ini.main.enabled)

imgui.OnFrame(function() return window[0] end, function(player)
    imgui.Begin("ktime", window, flags.NoResize + flags.AlwaysAutoResize + flags.NoCollapse)
    if imgui.Checkbox(u8"Включить время на экране", enabled) then
        ini.main.enabled = enabled[0]
        inicfg.save(ini, "ktime.ini")
        time = not time
    end
    imgui.End()
end)

function main()
    sampRegisterChatCommand("kt", function() window[0] = not window[0] end)
    while true do wait(0)
        local time = renderFontDrawText(font, "" .. getTimeOfDay(), 1100, 50, -1)
    end
end
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 inicfg = require "inicfg"
local directIni = "ktime.ini"
local ini = inicfg.load(inicfg.load({
    main = {
        enabled = false
    },
}, directIni))
local encoding = require 'encoding'
encoding.default = 'CP1251'
local u8 = encoding.UTF8

local font = renderCreateFont("Arial", 20, 15)

local enabled = new.bool(ini.main.enabled)

imgui.OnFrame(function() return window[0] end, function(player)
    imgui.Begin("ktime", window, flags.NoResize + flags.AlwaysAutoResize + flags.NoCollapse)
    if imgui.Checkbox(u8"Включить время на экране", enabled) then
        ini.main.enabled = not ini.main.enabled
        inicfg.save(ini, "ktime.ini")
    end
    imgui.End()
end)

function main()
    sampRegisterChatCommand("kt", function() window[0] = not window[0] end)
    while true do wait(0)
        if ini.main.enabled then
            local time = renderFontDrawText(font, "" .. getTimeOfDay(), 1100, 50, -1)
        end
    end
end
 

Corrygan228

Участник
132
9
почему могут не появляться инпуты "команда" и "клавиша"? что бы я не выбирал в комбо, рядом пусто
Lua:
                                if imgui.Button(u8'Добавить') 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 == 1 then            
                                        imgui.InputText(u8'Команда', whatSave.command)  
                                    elseif whatSave.activation == 0 then
                                        imgui.InputText(u8'Клавиша', whatSave.hotkey)
                                    end
                                    imgui.SetCursorPosX(35)
                                    if imgui.Button(u8'Принять', imgui.ImVec2(120, 30)) then
                                        imgui.CloseCurrentPopup()
                                    end
                                    imgui.SameLine()
                                    if imgui.Button(u8'Отмена', imgui.ImVec2(120, 30)) then
                                        imgui.CloseCurrentPopup()
                                    end
 
Последнее редактирование:

painw

Известный
120
66
почему могут не появляться инпуты "команда" и "клавиша"? что бы я не выбирал в комбо, рядом пусто
Lua:
                                if imgui.Button(u8'Добавить') 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 == 1 then          
                                        imgui.InputText(u8'Команда', whatSave.command)
                                    elseif whatSave.activation == 0 then
                                        imgui.InputText(u8'Клавиша', whatSave.hotkey)
                                    end
                                    imgui.SetCursorPosX(35)
                                    if imgui.Button(u8'Принять', imgui.ImVec2(120, 30)) then
                                        imgui.CloseCurrentPopup()
                                    end
                                    imgui.SameLine()
                                    if imgui.Button(u8'Отмена', imgui.ImVec2(120, 30)) then
                                        imgui.CloseCurrentPopup()
                                    end
Lua:
if whatSave.activation.v == 1 then                                                       
   imgui.InputText(u8'Команда',whatSave.command)                               
elseif whatSave.activation.v == 0 then                                       
   imgui.InputText(u8'Клавиша',whatSave.hotkey)
end
 

legnd

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

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

dmitry.karle

Известный
367
103
Посмотреть вложение 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

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

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

Известный
701
520
почему не получается обратиться к значению 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()
 
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