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

_Nelit_

Потрачен
109
39
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Допустим у меня в скрипте используется inicfg, могу ли я изменить расширение файлов с .ini на своё и что бы он работал как inicfg? Например file.sa и в нём структура ini файла. Просто видел скрипты, где расширение файлов было .medhelper и так далее
Актуально
 

Nicolas

Активный
114
66
Lua:
function on_off_lights()
    lua_thread.create(function()
        print('нажал кнопку')
        setGameKeyState(3,1)
        wait(500)
        print('отпустил кнопку')
        setGameKeyState(3,0)
    end)
end
Почему принты идут, а клавиша не нажимаются?
 

meowprd

Тот самый Котовский
Проверенный
1,280
714
Lua:
function on_off_lights()
    lua_thread.create(function()
        print('нажал кнопку')
        setGameKeyState(3,1)
        wait(500)
        print('отпустил кнопку')
        setGameKeyState(3,0)
    end)
end
Почему принты идут, а клавиша не нажимаются?
Читай вики функции

1 - не нажмет клавишу
 
Последнее редактирование:

Nicolas

Активный
114
66
Читай вики функции

0 - не отпустит клавишу
Почему? как работает true false в числовом виде?

прости я затупил я думал она создает файл а она просто записывает в уже создатый

как в одну строчку сделать ?
filelipini = getGameDirectory().."\\moonloader\\resource\\lip\\lip.ini"
if not doesFileExist(filelipini) then

типо так но так не хочет
if not doesFileExist(getGameDirectory().."\\moonloader\\resource\\lip\\lip.ini") then
Lua:
if not doesFileExist(getWorkingDirectory()..'\\resource\\lip\\lip.ini') then
    print('Nema faila lip.ini')
end
 

meowprd

Тот самый Котовский
Проверенный
1,280
714
Почему? как работает true false в числовом виде?
У тебя клавиша TURRETUP_TURRETDOWN, ничего не напоминает из ссылки на вики выше?
Если нет, цитирую
Статусы отрицательного значения (-32768, -256, -128 и т.п.) предназначены только для тех клавиш, которые имеют два действия: GOLEFT_GORIGHT, GOFORWARD_GOBACK, ANSWERPHONE_FIREWEAPONALT, LOOKBEHIND_LOOKRIGHT и подобных.
 
  • Ха-ха
Реакции: Nicolas

linmsqn

Участник
337
9
где можно найти инфу о работе с рендером? допустим мне нужно чтобы на машине или игроке рисовалась точка только тогда, когда я нажму на определенную кнопку. к этой точке должно быть пару функций. где можно найти инфу об этом?
 

m1racles

Активный
199
32
можно ли перезагрузить другой скрипт, не тот с которого выполняется функция?
 

_Nelit_

Потрачен
109
39
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Хотел сделать файл со своим расширением .sa но со структурой ini файла, сказали что так работать будет. Скрипт создаёт файл config.sa.ini. Вот код
Lua:
local settings = 'State-Assistant\\config.sa'
local mainIni = inicfg.load(nil, settings)

function iniReset()
    inicfg.save({
        config = {
            name = '',
            fracname = 0,
            rang = '',
            gender = 0,
            autoupdate = false,
            testmode = false,
            theme = 0,
            notfupdate = true,
            subdivision = 0,
        }
    }, settings)
    print('[ Создание конфигурационных файлов... ]')
end

function iniLoad()
    print('[ Проверка конфигурационных файлов... ]')
    mainIni = inicfg.load(nil, settings)
    if mainIni == nil then
        iniReset()
    else
        name.v = mainIni.config.name
        fracname.v = mainIni.config.fracname
        gender.v = mainIni.config.gender
        rang.v = mainIni.config.rang
        autoupdate.v = mainIni.config.autoupdate
        testmode.v = mainIni.config.testmode
        themechange.v = mainIni.config.theme
        notfupdate.v = mainIni.config.notfupdate
        subdivision.v = mainIni.config.subdivision
        print('[ Загрузка конфигурационных файлов... ]')
    end
    if not doesFileExist(list_file) then
        jsonSave(list_file, {})
    end
    list = jsonRead(list_file)
    if list[selected] then
        input.v = list[selected]
    end
end

function iniSave()
    inicfg.save({
        config = {
            name = name.v,
            fracname = fracname.v,
            gender = gender.v,
            rang = rang.v,
            autoupdate = autoupdate.v,
            testmode = testmode.v,
            theme = themechange.v,
            notfupdate = notfupdate.v,
            subdivision = subdivision.v,
        }
    }, settings)
end

function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(100) end

    iniLoad()

    while true do
        wait(0)
        
    end   
end

В чём проблема?
 

meowprd

Тот самый Котовский
Проверенный
1,280
714
где можно найти инфу о работе с рендером? допустим мне нужно чтобы на машине или игроке рисовалась точка только тогда, когда я нажму на определенную кнопку. к этой точке должно быть пару функций. где можно найти инфу об этом?

можно ли перезагрузить другой скрипт, не тот с которого выполняется функция?
Смотри исходник AutoReboot.lua, перезагрузить можно.

Хотел сделать файл со своим расширением .sa но со структурой ini файла, сказали что так работать будет. Скрипт создаёт файл config.sa.ini. Вот код
Lua:
local settings = 'State-Assistant\\config.sa'
local mainIni = inicfg.load(nil, settings)

function iniReset()
    inicfg.save({
        config = {
            name = '',
            fracname = 0,
            rang = '',
            gender = 0,
            autoupdate = false,
            testmode = false,
            theme = 0,
            notfupdate = true,
            subdivision = 0,
        }
    }, settings)
    print('[ Создание конфигурационных файлов... ]')
end

function iniLoad()
    print('[ Проверка конфигурационных файлов... ]')
    mainIni = inicfg.load(nil, settings)
    if mainIni == nil then
        iniReset()
    else
        name.v = mainIni.config.name
        fracname.v = mainIni.config.fracname
        gender.v = mainIni.config.gender
        rang.v = mainIni.config.rang
        autoupdate.v = mainIni.config.autoupdate
        testmode.v = mainIni.config.testmode
        themechange.v = mainIni.config.theme
        notfupdate.v = mainIni.config.notfupdate
        subdivision.v = mainIni.config.subdivision
        print('[ Загрузка конфигурационных файлов... ]')
    end
    if not doesFileExist(list_file) then
        jsonSave(list_file, {})
    end
    list = jsonRead(list_file)
    if list[selected] then
        input.v = list[selected]
    end
end

function iniSave()
    inicfg.save({
        config = {
            name = name.v,
            fracname = fracname.v,
            gender = gender.v,
            rang = rang.v,
            autoupdate = autoupdate.v,
            testmode = testmode.v,
            theme = themechange.v,
            notfupdate = notfupdate.v,
            subdivision = subdivision.v,
        }
    }, settings)
end

function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(100) end

    iniLoad()

    while true do
        wait(0)
     
    end
end

В чём проблема?
Lua:
local inicfg = require 'inicfg'
local inidir = getGameDirectory().."\\moonloader\\inifile" -- where inifile = ur file name
local ini = {
    Settings = {
        var1 = "foo",
        var2 = "bar"
    }
}
local config = inicfg.load(nil, inidir)
if not config then
    local f = io.open(inidir, "w")
        f:close()
    if inicfg.save(ini, ini_dir) then
        config = inicfg.load(nil, ini_dir)
    else
        print("Error create default ini")
        return
    end
    print("Created default ini")
end

function main()
    -- other code
    print(config.Settings.var1, config.Settings.var2)
    -- output in console: foo  bar
    wait(-1)
end

1637490371882.png


upd:
если этот способ тебе не поможет, раньше я сталкивался с таким же, что файл создается - но он пустой, то проще переехать на jsonDecode / jsonEncode
ну или пойти колхозным способом сохранения по типу:
Lua:
function save()
    local f = io.open(inidir, "w")
    local str = "[Settings]\n"
    local str = str .. "var1=" .. config.Settings.var1 .. "\n"
    local str = str .. "var2=" .. config.Settings.var2 .. "\n"
    -- и т.д.
    -- но лучше перестраховаться и использовать не конкатенацию строк, а string.format()
    -- А еще лучше не пользоваться этим способом и реально использовать json
end
 
Последнее редактирование:
  • Нравится
Реакции: _Nelit_

meowprd

Тот самый Котовский
Проверенный
1,280
714
я там не понимаю ничего
Lua:
function main()
    -- other code
    local path = getGameDirectory().."\\moonloader\\test.lua"
    local src = find_script_by_path(path)
    if src then
        src:reload()
    end
    
    wait(-1)
end

function find_script_by_path(path) -- by FYP
    for _, s in ipairs(script.list()) do
      if s.path == path then
       return s
     end
   end
   return nil
end
 
  • Нравится
Реакции: m1racles

meowprd

Тот самый Котовский
Проверенный
1,280
714
можешь пожалуйста конкретным примером? я буду его в телеграм себе выводить

вырезал это, но чет не работает
Lua:
function getIp()
    ip = openUrl('https://api.ipify.org/?format=json')

    return ip:match('{\"ip\":\"(.*)\"}')
end
что за openUrl() и почему ты издеваешься над форматом json