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

de_clain

Активный
231
63
Как в json сохранять по ключам, а не по номерам? например, создать список значений, к которым я хочу обращаться как table['a1'], а не tabe[1] и т.д.
При использовании номеров возникают ошибки, если нужно какие-то элементы полностью стереть или что-то подобное
Не понял, разве tbl = { name = "Алумбек", age = "228" } не сохраняет по ключам
 

chapo

чопа сребдс // @moujeek
Модератор
8,935
11,704
Кто может рассказать, почему никто не использует loadstring() для чтение таблиц из файлов? Это связано только с безопасностью? Будет ли рационально так делать, если обычный json не передаёт всю информацию, которая мне нужна? Или всё таки делать функцию-парсер?
скорее всего потому что надо ебаться с записью таблицы в файл
 

_Dino_

Активный
122
49
Как увеличивать шрифт fAwesome6?
Пример из скрипта fAwesome5

LUA:
imgui.OnInitialize(function()
    local config = imgui.ImFontConfig()
    config.MergeMode = true
    local glyph_ranges = imgui.GetIO().Fonts:GetGlyphRangesCyrillic()
    local iconRanges = imgui.new.ImWchar[3](fa.min_range, fa.max_range, 0)
    imgui.GetIO().Fonts:AddFontFromFileTTF('trebucbd.ttf', 14.0, nil, glyph_ranges)
    for Size = 10, 25 do
        FaFont[Size] = imgui.GetIO().Fonts:AddFontFromFileTTF('moonloader/resource/fonts/fa-solid-900.ttf', Size, config, iconRanges)
    end
    icon = imgui.GetIO().Fonts:AddFontFromFileTTF('moonloader/resource/fonts/fa-solid-900.ttf', 14, config, iconRanges)
end)
 

lorgon

Известный
656
271
через table.insert, там по команде мне надо значение сохранять
я плох с json, можно как то по-другому?
Я тоже немного не понял, вроде encodeJson должен сохранять таблицу и с ключами, такими как a1 и т. п.
Можешь вот так попробывать, если тебе надо добавлять в конец таблицы,

Lua:
local tab = {}
tab[tostring(#tab + 1)] = {} -- вместо '{}', вставляй то, что тебе надо
 

goodflex

Активный
280
57
при нажатии на чекбокс то что нужно начинает работать, но при убратии галочки с чекбокса скрипт дальше работает, как сиправить?
Код:
function main()
-- код
    while true do
-- код
        if Checkbox11.v then
        afk = not afk
        end

        if afk then
            memory.setuint8(7634870, 1, false)
            memory.setuint8(7635034, 1, false)
            memory.fill(7623723, 144, 8, false)
            memory.fill(5499528, 144, 6, false)
        else
            memory.setuint8(7634870, 0, false)
            memory.setuint8(7635034, 0, false)
            memory.hex2bin('0F 84 7B 01 00 00', 7623723, 8)
            memory.hex2bin('50 51 FF 15 00 83 85 00', 5499528, 6)
        end
    end
end
 

DZONE

Известный
188
200
при нажатии на чекбокс то что нужно начинает работать, но при убратии галочки с чекбокса скрипт дальше работает, как сиправить?
Код:
function main()
-- код
    while true do
-- код
        if Checkbox11.v then
        afk = not afk
        end

        if afk then
            memory.setuint8(7634870, 1, false)
            memory.setuint8(7635034, 1, false)
            memory.fill(7623723, 144, 8, false)
            memory.fill(5499528, 144, 6, false)
        else
            memory.setuint8(7634870, 0, false)
            memory.setuint8(7635034, 0, false)
            memory.hex2bin('0F 84 7B 01 00 00', 7623723, 8)
            memory.hex2bin('50 51 FF 15 00 83 85 00', 5499528, 6)
        end
    end
end
Lua:
function main()
-- код
    while true do
-- код
        if Checkbox11.v then
            memory.setuint8(7634870, 1, false)
            memory.setuint8(7635034, 1, false)
            memory.fill(7623723, 144, 8, false)
            memory.fill(5499528, 144, 6, false)
        else
            memory.setuint8(7634870, 0, false)
            memory.setuint8(7635034, 0, false)
            memory.hex2bin('0F 84 7B 01 00 00', 7623723, 8)
            memory.hex2bin('50 51 FF 15 00 83 85 00', 5499528, 6)
        end
    end
end
 
  • Нравится
Реакции: goodflex

MLycoris

На вид оружие массового семяизвержения
Проверенный
1,992
2,187
Подскажите сниппет для определния нажатой клавиши/клавиш. Нужно для создания бинда. Встречал такие в биндерах и мвд хелпере
Lua:
-- в начале
local vkeys = require 'vkeys'
local wm = require 'windows.message'

-- в какой нибудь функции
addEventHandler('onWindowMessage', function(msg, wparam, lparam)
    if msg == wm.WM_KEYDOWN then
        sampAddChatMessage('Ид клавиши: '..wparam..' Название клавиши: '..vkeys.id_to_name(wparam),-1)
    end
end)
 
  • Нравится
Реакции: histor

Tango

Новичок
28
4
123:
function imgui.OnDrawFrame()
  if window.v then
    local sw, sh = getScreenResolution()
        imgui.SetNextWindowPos(imgui.ImVec2(sw / 2, sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    imgui.SetNextWindowSize(imgui.ImVec2(sw / 1.6, sh / 1.5), imgui.Cond.FirstUseEver)
    imgui.Begin(u8(__name__..' by '..__author__), window, imgui.WindowFlags.NoResize + imgui.WindowFlags.NoCollapse + imgui.WindowFlags.ShowBorders)
                if bufferSearch[1].v then
                  for i, f in ipairs(choiceBuyArray) do
                    local pat1 = string.rlower(f)
                    local pat2 = string.rlower(u8:decode(bufferSearch[1].v))
                    if pat1:find(pat2, 0, true) then
                      if imgui.Button(tostring('%s - %s'):format(i,u8(f)), imgui.ImVec2(sw / 4.3 , sh / 40)) then
                        if choiceBuyArray_myBuyArray(i) ~= false then
                          table.insert(myBuyArray, {f, 1, 10})
                          jsonSave(json_file_mybuyarray,myBuyArray)
                        end
                      end
                    end
                  end
                end
                imgui.End()
  end
end
вообщемто решил сделать поиск среди кнопок в массиве, но при открытии имгуи окна и вообще раздела, где видны эти кнопки фпс понижается до 30-40, хотя до этого 100-200Посмотреть вложение 197546Посмотреть вложение 197547
up help me pls
 

Revavi

Участник
101
24
Я тоже немного не понял, вроде encodeJson должен сохранять таблицу и с ключами, такими как a1 и т. п.
Можешь вот так попробывать, если тебе надо добавлять в конец таблицы,

Lua:
local tab = {}
tab[tostring(#tab + 1)] = {} -- вместо '{}', вставляй то, что тебе надо
код:
local json = {
    save = function(data, path)
        if type(data) ~= 'table' then return end
        local f = io.open(path, 'w+')
        f:write(encodeJson(data))
        f:close()
    end,
    load = function(path)
        if doesFileExist(path) then
            local f = io.open(path, 'a+')
            local data = decodeJson(f:read('*a'))
            f:close()
            return data
        end
    end
}

function create(name)
    if #name == 0 then name = 'Точка #'..#buf.value+1 end
    local x, y, z = getCharCoordinates(PLAYER_PED)
    buf.value['point'..#buf.value+1] = {name=u8(name), coord={x=x, y=y, z=z}}
    json.save(buf.value, buf.path)
end
до этого вместо " buf.value['point'..#buf.value+1] = {name=u8(name), coord={x=x, y=y, z=z}} " стояло "table.insert(buf.value, {name=u8(name), coord={x=x, y=y, z=z}})", тогда оно работало, но были некоторые баги дальше.
Щас вообще не работает, ну в смысле оно не идёт дальше счёт, создаёт только wp1 и заменяет его постоянно
 
  • Грустно
  • Нравится
Реакции: Tango и lorgon

Tango

Новичок
28
4
У тебя OnDrawFrame каждую секунду пытается рисовать кадр, а ты туда ещё и цикл засунул for i, f in ipairs(choiceBuyArray) do.
Неа, если я просто уберу поиск, а просто будет через цикл выводится значения массива, то лагать не будет, хотя цикл тоже присутствует. Помогите пожалуйста буду благодарен
 

lorgon

Известный
656
271
Неа, если я просто уберу поиск, а просто будет через цикл выводится значения массива, то лагать не будет, хотя цикл тоже присутствует. Помогите пожалуйста буду благодарен
У тебя в цикле этом каждый раз файл сохраняет
jsonSave(json_file_mybuyarray,myBuyArray).
Попробуй постепенно убирать каждый шаг и смотреть на фпс. Рано или поздно доберёшься до лагучего момента.

код:
local json = {
    save = function(data, path)
        if type(data) ~= 'table' then return end
        local f = io.open(path, 'w+')
        f:write(encodeJson(data))
        f:close()
    end,
    load = function(path)
        if doesFileExist(path) then
            local f = io.open(path, 'a+')
            local data = decodeJson(f:read('*a'))
            f:close()
            return data
        end
    end
}

function create(name)
    if #name == 0 then name = 'Точка #'..#buf.value+1 end
    local x, y, z = getCharCoordinates(PLAYER_PED)
    buf.value['point'..#buf.value+1] = {name=u8(name), coord={x=x, y=y, z=z}}
    json.save(buf.value, buf.path)
end
до этого вместо " buf.value['point'..#buf.value+1] = {name=u8(name), coord={x=x, y=y, z=z}} " стояло "table.insert(buf.value, {name=u8(name), coord={x=x, y=y, z=z}})", тогда оно работало, но были некоторые баги дальше.
Щас вообще не работает, ну в смысле оно не идёт дальше счёт, создаёт только wp1 и заменяет его постоянно
Оххх, я покапался немного и понял, что ошибся ранее. Оказывается в lua длина массива очень странно считается. Вот мой говно код, но это должно сохранять точки в json, в виде ["1"] = ...

Lua:
if buf.value[#buf.value] == nil then
   buf.value['1'] = {}
   buf.value['1'].name = (name)
   buf.value['1'].coord = {x=x, y=y, z=z}
else
   local i = tostring(tonumber(buf.value[#buf.value]) + 1)
   buf.value[i] = {}
   buf.value[i].name = (name)
   buf.value[i].coord = {x=x, y=y, z=z}
end
 
Последнее редактирование:
  • Нравится
Реакции: Tango

Tango

Новичок
28
4
У тебя в цикле этом каждый раз файл сохраняет
jsonSave(json_file_mybuyarray,myBuyArray).
Попробуй постепенно убирать каждый шаг и смотреть на фпс. Рано или поздно доберёшься до лагучего момента.


Оххх, я покапался немного и понял, что ошибся ранее. Оказывается в lua длина массива очень странно считается. Вот мой говно код, но это должно сохранять точки в json, в виде ["1"] = ...

Lua:
if buf.value[#buf.value] == nil then
   buf.value['1'] = {}
   buf.value['1'].name = (name)
   buf.value['1'].coord = {x=x, y=y, z=z}
else
   local i = tostring(tonumber(buf.value[#buf.value]) + 1)
   buf.value[i] = {}
   buf.value[i].name = (name)
   buf.value[i].coord = {x=x, y=y, z=z}
end
Дело не в конфиге, оно сжирает фпс как только цикл фор чтото засовываю
 

Sadow

Известный
1,428
593
Как мне сделать мод, который постоянно делает это:
- говорить/игнорировать в чате; затем появляется диалоговое окно (с сервера)
- нажать на выбор «Add player...»; диалоговое окно ввода отображается в (с сервера)
- набирает в диалоге "victor1" и нажимает ENTER.
- набрать /игнорировать в чате
- нажмите на второй вариант
-- повторить
пожалуйста, кто-нибудь, помогите мне, это срочно, я новичок в lua
Тебе сюда - https://www.blast.hk/forums/16/

И не мод. а в данном случае скрипт
 
  • Нравится
Реакции: Tango и lorgon