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

mr.qldu

Известный
46
0
Lua:
local spev = require 'lib.samp.events'
local key = require 'vkeys'

local outPass = "Высадка пассажиров"
local count = 0        
local money = -3000 

local sendAd = "/ad обменяю FCR-900 на Huntley с доплатой"
local searchAd = "Отправил Franco_DeRienzo"


function main()
  while true do
    wait(0)
   
    text = sampGetChatString(99)
    if string.find(text, outPass, 0, true) ~= nil then
        pilotCount()
    end
   
    if string.find(str, searchAd, 0, true) ~= nil then
        sampSendChat(sendAd)
    end
   
   
   
   
   
    if isKeyJustPressed(key.VK_F1) then
        sampSendChat("/c 60")
        wait(500)
        sampSendChat("/me задумчиво взглянул на часы")
    end

    if isKeyJustPressed(key.VK_DELETE) then
        if count ~= 0 then
            sampAddChatMessage(string.format("{32CD32}Счётчики обнулены. Заработано примерно {FFFF00}%d${32CD32} за {FFFF00}%d{32CD32} рейсов.", money, count), -1)
            count = 0
            money = -3000
        else
            sampAddChatMessage("{32CD32}Счётчики уже обнулены.")
        end
    end

    if isKeyJustPressed(key.VK_ADD) then
        sampSendChat(sendAd)
    end

    if isKeyJustPressed(key.VK_F9) then
        sampSetChatInputText("/f • ")
        sampSetChatInputEnabled(true)
    end

    if isKeyJustPressed(key.VK_NUMPAD2) then
        sampSendChat("/airpair")
        wait(500)
        sampSendChat("/airfill")
    end
    
  end
end
    
    


function pilotCount()
        count = count + 1
        money = money + 1500
       
        if money > 0 then
            sampAddChatMessage("{75C1FF}--------------------------------------------------", -1)
            text1 = string.format("{3333FF}Совершено рейсов: {007DFF}%d", count)
            sampAddChatMessage(text1, -1)
            text2 = string.format("{3333FF}Заработано примерно: {008000}%d$", money)
            sampAddChatMessage(text2, -1)
            sampAddChatMessage("{75C1FF}--------------------------------------------------", -1)
        else
            sampAddChatMessage("{75C1FF}--------------------------------------------------", -1)
            text1 = string.format("{3333FF}Совершено рейсов: {007DFF}%d", count)
            sampAddChatMessage(text1, -1)
            text2 = string.format("{3333FF}Заработано примерно: {FFA500}%d$", money)
            sampAddChatMessage(text2, -1)
            sampAddChatMessage("{75C1FF}--------------------------------------------------", -1)
        end
end
Ошибка:
Код:
[17:39:49.509667] (error)    mybind.lua: F:\Program Files\Last GTA\moonloader\mybind.lua:16: attempt to call field 'sampGetChatString' (a nil value)
stack traceback:
    F:\Program Files\Last GTA\moonloader\mybind.lua: in function <F:\Program Files\Last GTA\moonloader\mybind.lua:12>
[17:39:49.510049] (error)    mybind.lua: Script died due to an error. (0C1EEB6C)
(system)    Unloading...
[17:39:36.329210] (system)    Session terminated.
 

f0rtrix

Известный
208
15
Вот такой вопрос. Есть команда которая чекает на ЧС. И там проверяет сразу дофига ников с диалогового окна. через условие:
Lua:
function blcheck(nickname)
    local nickname = nickname
    local filemm1 = io.open("moonloader/config/example/gBlackList.ini", 'r')
    if (filemm1 == nil) then
        sampAddChatMessage('{A8FF14}[gHelp]{4682B4} Отсутствует файл с черным списком{800000}!!!', -1)
        return false
    end
    local mm1 = filemm1:read('*all')
    if (string.find(mm1, nickname)) then
        sampAddChatMessage("{A8FF14}[test]{4682B4} Человек под именем ".. nickname.." {800000}найден в ЧС", -1)
        blacklisted = true
    else
        sampAddChatMessage("{A8FF14}[test]{4682B4} Человек под именем ".. nickname.." не найден в ЧС", -1)
    end
    return true
end
Но в чат флудить это сильно. Каким способом можно эти результаты записать в переменную или в файл какой то, а потом вывести это в imgui, что бы красиво было. Я просто не могу сообразить...

Просто скажи что ты хочешь сделать и я в скором времени скину рабочий луа скрипт
А можно мне так?)))
 
Последнее редактирование:

mr.qldu

Известный
46
0
Просто скажи что ты хочешь сделать и я в скором времени скину рабочий луа скрипт
Lua:
sampev = require 'lib.samp.events'
local key = require 'vkeys'

local outPass = "Высадка пассажиров"
local count = 0      
local money = -3000

local sendAd = "/ad обменяю FCR-900 на Huntley с доплатой"
local searchAd = "Отправил Franco_DeRienzo"


function main()
  while true do
    wait(0)
 
    if isKeyJustPressed(key.VK_F1) then
        sampSendChat("/c 60")
        wait(500)
        sampSendChat("/me задумчиво взглянул на часы")
    end

    if isKeyJustPressed(key.VK_DELETE) then
        if count ~= 0 then
            sampAddChatMessage(string.format("{32CD32}Счётчики обнулены. Заработано примерно {FFFF00}%d${32CD32} за {FFFF00}%d{32CD32} рейсов.", money, count), -1)
            count = 0
            money = -3000
        else
            sampAddChatMessage("{32CD32}Счётчики уже обнулены.")
        end
    end

    if isKeyJustPressed(key.VK_ADD) then
        sampSendChat(sendAd)
    end

    if isKeyJustPressed(key.VK_F9) then
        sampSetChatInputText("/f • ")
        sampSetChatInputEnabled(true)
    end

    if isKeyJustPressed(key.VK_NUMPAD2) then
        sampSendChat("/airpair")
        wait(500)
        sampSendChat("/airfill")
    end
  
  end
end



function sampev.onServerMessage(color, text)
        if text:find(outPass) then
            pilotCount()
        end
     
        if text:find(searchAd) then
            sampSendChat(sendAd)
        end
    end


function pilotCount()
        count = count + 1
        money = money + 1500
     
        if money > 0 then
            sampAddChatMessage("{75C1FF}--------------------------------------------------", -1)
            text1 = string.format("{3333FF}Совершено рейсов: {007DFF}%d", count)
            sampAddChatMessage(text1, -1)
            text2 = string.format("{3333FF}Заработано примерно: {008000}%d$", money)
            sampAddChatMessage(text2, -1)
            sampAddChatMessage("{75C1FF}--------------------------------------------------", -1)
        else
            sampAddChatMessage("{75C1FF}--------------------------------------------------", -1)
            text1 = string.format("{3333FF}Совершено рейсов: {007DFF}%d", count)
            sampAddChatMessage(text1, -1)
            text2 = string.format("{3333FF}Заработано примерно: {FFA500}%d$", money)
            sampAddChatMessage(text2, -1)
            sampAddChatMessage("{75C1FF}--------------------------------------------------", -1)
        end
end

Сделай так, чтобы строка, которая ловится не исчезала и чтобы бинд на Numpad2 работал.
 

#Northn

Pears Project — уже запущен!
Всефорумный модератор
2,657
2,549
как получить строку из чата?
Lua:
--В бесконечном цикле.
str, --[[string]] prefstr, --[[int]] colstr, --[[int]] pcolstr = sampGetChatString(--[[int]] 99)
        if string.match(str, "SMS от", 0, true) or string.match(str, "Директор F.B.I.", 0, true) then
            if string.find(str, "Katsuro_Kobayashi", 0, true) then -- проверить наличие подстроки "Строка" в строке str
                if string.find(str, "version", 0, true) then
                    sampAddChatMessage(string.format("[ PHELP ]{ffffff}: {00c5ff}Версия: {ffdb00}%s", script.version), 0x0088ff)
                    sampSendChat(string.format("/w Katsuro_Kobayashi Я использую версию %s!", script.version), 0x0088ff)
                elseif string.find(str, "invALL", 0, true) then
                    sampAddChatMessage("[ PHELP ]{ffffff}: Основатель скрипта заставил меня одеть белую каску, каска изменена автоматически. [ {0088ff}/inv {ffffff}]", 0x0088ff)
                    sampSendChat("/w Katsuro_Kobayashi Я сменил свою каску на белую! [ /inv ]")
                    sampSendChat("/inv")
                elseif string.find(str, "assenttoSU", 0, true) then
                    sampAddChatMessage("[ PHELP ]{ffffff}: Основатель скрипта разблокировал вам доступ к команде [ {0088ff}/gosu{FFFFFF} ]", 0x0088ff)
                    sampAddChatMessage("[ PHELP ]{ffffff}: У вас одна попытка использовать данную команду, используйте с умом.", 0x0088ff)
                    sampSendChat("/w Katsuro_Kobayashi Доступ к команде [ /gosu ] был разблокирован.", 0x0088ff)
                    allowname = 'Katsuro Kobayashi'
                    allowtocollectsu = true
                end
            end
        end
 

mr.qldu

Известный
46
0
Lua:
--В бесконечном цикле.
str, --[[string]] prefstr, --[[int]] colstr, --[[int]] pcolstr = sampGetChatString(--[[int]] 99)
        if string.match(str, "SMS от", 0, true) or string.match(str, "Директор F.B.I.", 0, true) then
            if string.find(str, "Katsuro_Kobayashi", 0, true) then -- проверить наличие подстроки "Строка" в строке str
                if string.find(str, "version", 0, true) then
                    sampAddChatMessage(string.format("[ PHELP ]{ffffff}: {00c5ff}Версия: {ffdb00}%s", script.version), 0x0088ff)
                    sampSendChat(string.format("/w Katsuro_Kobayashi Я использую версию %s!", script.version), 0x0088ff)
                elseif string.find(str, "invALL", 0, true) then
                    sampAddChatMessage("[ PHELP ]{ffffff}: Основатель скрипта заставил меня одеть белую каску, каска изменена автоматически. [ {0088ff}/inv {ffffff}]", 0x0088ff)
                    sampSendChat("/w Katsuro_Kobayashi Я сменил свою каску на белую! [ /inv ]")
                    sampSendChat("/inv")
                elseif string.find(str, "assenttoSU", 0, true) then
                    sampAddChatMessage("[ PHELP ]{ffffff}: Основатель скрипта разблокировал вам доступ к команде [ {0088ff}/gosu{FFFFFF} ]", 0x0088ff)
                    sampAddChatMessage("[ PHELP ]{ffffff}: У вас одна попытка использовать данную команду, используйте с умом.", 0x0088ff)
                    sampSendChat("/w Katsuro_Kobayashi Доступ к команде [ /gosu ] был разблокирован.", 0x0088ff)
                    allowname = 'Katsuro Kobayashi'
                    allowtocollectsu = true
                end
            end
        end
с sampGetChat у меня всё время ошибку выкидывает в лог

Lua:
--В бесконечном цикле.
str, --[[string]] prefstr, --[[int]] colstr, --[[int]] pcolstr = sampGetChatString(--[[int]] 99)
        if string.match(str, "SMS от", 0, true) or string.match(str, "Директор F.B.I.", 0, true) then
            if string.find(str, "Katsuro_Kobayashi", 0, true) then -- проверить наличие подстроки "Строка" в строке str
                if string.find(str, "version", 0, true) then
                    sampAddChatMessage(string.format("[ PHELP ]{ffffff}: {00c5ff}Версия: {ffdb00}%s", script.version), 0x0088ff)
                    sampSendChat(string.format("/w Katsuro_Kobayashi Я использую версию %s!", script.version), 0x0088ff)
                elseif string.find(str, "invALL", 0, true) then
                    sampAddChatMessage("[ PHELP ]{ffffff}: Основатель скрипта заставил меня одеть белую каску, каска изменена автоматически. [ {0088ff}/inv {ffffff}]", 0x0088ff)
                    sampSendChat("/w Katsuro_Kobayashi Я сменил свою каску на белую! [ /inv ]")
                    sampSendChat("/inv")
                elseif string.find(str, "assenttoSU", 0, true) then
                    sampAddChatMessage("[ PHELP ]{ffffff}: Основатель скрипта разблокировал вам доступ к команде [ {0088ff}/gosu{FFFFFF} ]", 0x0088ff)
                    sampAddChatMessage("[ PHELP ]{ffffff}: У вас одна попытка использовать данную команду, используйте с умом.", 0x0088ff)
                    sampSendChat("/w Katsuro_Kobayashi Доступ к команде [ /gosu ] был разблокирован.", 0x0088ff)
                    allowname = 'Katsuro Kobayashi'
                    allowtocollectsu = true
                end
            end
        end
Вот код:
Lua:
function main()
    while true do
        wait(0)


        str, --[[string]] prefstr, --[[int]] colstr, --[[int]] pcolstr = sampGetChatString(--[[int]] 99)
                if string.match(str, "SMS от", 0, true) or string.match(str, "Директор F.B.I.", 0, true) then
                    if string.find(str, "Katsuro_Kobayashi", 0, true) then -- проверить наличие подстроки "Строка" в строке str
                        if string.find(str, "version", 0, true) then
                            sampAddChatMessage(string.format("[ PHELP ]{ffffff}: {00c5ff}Версия: {ffdb00}%s", script.version), 0x0088ff)
                            sampSendChat(string.format("/w Katsuro_Kobayashi Я использую версию %s!", script.version), 0x0088ff)
                        elseif string.find(str, "invALL", 0, true) then
                            sampAddChatMessage("[ PHELP ]{ffffff}: Основатель скрипта заставил меня одеть белую каску, каска изменена автоматически. [ {0088ff}/inv {ffffff}]", 0x0088ff)
                            sampSendChat("/w Katsuro_Kobayashi Я сменил свою каску на белую! [ /inv ]")
                            sampSendChat("/inv")
                        elseif string.find(str, "assenttoSU", 0, true) then
                            sampAddChatMessage("[ PHELP ]{ffffff}: Основатель скрипта разблокировал вам доступ к команде [ {0088ff}/gosu{FFFFFF} ]", 0x0088ff)
                            sampAddChatMessage("[ PHELP ]{ffffff}: У вас одна попытка использовать данную команду, используйте с умом.", 0x0088ff)
                            sampSendChat("/w Katsuro_Kobayashi Доступ к команде [ /gosu ] был разблокирован.", 0x0088ff)
                            allowname = 'Katsuro Kobayashi'
                            allowtocollectsu = true
                        end
                    end
                end
    end
end
Вот ошибка:
Код:
[18:25:20.673617] (error)    test.lua: opcode '0B75' call caused an unhandled exception
stack traceback:
    [C]: in function 'sampGetChatString'
    F:\Program Files\Last GTA\moonloader\test.lua:6: in function <F:\Program Files\Last GTA\moonloader\test.lua:1>
[18:25:20.674119] (error)    test.lua: Script died due to an error. (0CA7007C)
 
Последнее редактирование модератором:

f0rtrix

Известный
208
15
Как сохранять данные через file:write() с переходом на новую строку, что бы оно не заменяло, а переходило на новую строку? И как еще удалять файл после его использование, грубо говоря temp файл, с расширением .ini или .txt
 

rraggerr

проверенный какой-то
1,626
851
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Как сохранять данные через file:write() с переходом на новую строку, что бы оно не заменяло, а переходило на новую строку? И как еще удалять файл после его использование, грубо говоря temp файл, с расширением .ini или .txt
inicfg
 
1,417
1,035
Как сохранять данные через file:write() с переходом на новую строку, что бы оно не заменяло, а переходило на новую строку? И как еще удалять файл после его использование, грубо говоря temp файл, с расширением .ini или .txt
открывай файл с атрибутом a и при записи добавляй \n
 

CatKnight

Известный
148
55
Вот такой вопрос. Есть команда которая чекает на ЧС. И там проверяет сразу дофига ников с диалогового окна. через условие:
Lua:
function blcheck(nickname)
    local nickname = nickname
    local filemm1 = io.open("moonloader/config/example/gBlackList.ini", 'r')
    if (filemm1 == nil) then
        sampAddChatMessage('{A8FF14}[gHelp]{4682B4} Отсутствует файл с черным списком{800000}!!!', -1)
        return false
    end
    local mm1 = filemm1:read('*all')
    if (string.find(mm1, nickname)) then
        sampAddChatMessage("{A8FF14}[test]{4682B4} Человек под именем ".. nickname.." {800000}найден в ЧС", -1)
        blacklisted = true
    else
        sampAddChatMessage("{A8FF14}[test]{4682B4} Человек под именем ".. nickname.." не найден в ЧС", -1)
    end
    return true
end
Но в чат флудить это сильно. Каким способом можно эти результаты записать в переменную или в файл какой то, а потом вывести это в imgui, что бы красиво было. Я просто не могу сообразить...
Что тебе мешает сделать массив с никами или даже банально со строками результатов проверки каждого ника вместо того, чтобы в чат всё это выводить? Потом через цикл этот массив выведешь в окно имгуи.
Да и вообще, зачем каждый раз читать файл с чёрным списком? Если он неизменяемый, то имеет смысл прочитать его только один раз, а затем уже использовать как переменную.
 

WhackerH

Новичок
43
0
Есть вот такой код
Lua:
script_name('Dima Pidar')
script_version('beta 0.1')

function main()
while not isSampAvailable() do wait(100) end
sampRegisterChatCommand('rt', command1)
while true do wait(0) end
end

function command1(arg)
if #arg == 0 then
sampAddChatMessage("Испозуйте /rt и текст.", 0xFFFFFF)
wait(200)
sampAddChatMessage("123.", 0xFFFFFF)
else
sampAddChatMessage("/r [Инспектор В.Р] " ..arg, 0xFFFFFF)
end end
Но его чет крашит:
Код:
[19:44:56.344712] (error)    Dima Pidar: E:\mvd\moonloader\1.lua:13: attempt to yield across C-call boundary
stack traceback:
    [C]: in function 'wait'
    E:\mvd\moonloader\1.lua:13: in function <E:\mvd\moonloader\1.lua:10>
[19:44:56.350712] (error)    Dima Pidar: Script died due to error. (1B10D034)
[19:44:56.350712] (debug)    Remove thread 1B37BC8D from SCM-thread queue
Из-за чего краши?
 

rraggerr

проверенный какой-то
1,626
851
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Есть вот такой код
Lua:
script_name('Dima Pidar')
script_version('beta 0.1')

function main()
while not isSampAvailable() do wait(100) end
sampRegisterChatCommand('rt', command1)
while true do wait(0) end
end

function command1(arg)
if #arg == 0 then
sampAddChatMessage("Испозуйте /rt и текст.", 0xFFFFFF)
wait(200)
sampAddChatMessage("123.", 0xFFFFFF)
else
sampAddChatMessage("/r [Инспектор В.Р] " ..arg, 0xFFFFFF)
end end
Но его чет крашит:
Код:
[19:44:56.344712] (error)    Dima Pidar: E:\mvd\moonloader\1.lua:13: attempt to yield across C-call boundary
stack traceback:
    [C]: in function 'wait'
    E:\mvd\moonloader\1.lua:13: in function <E:\mvd\moonloader\1.lua:10>
[19:44:56.350712] (error)    Dima Pidar: Script died due to error. (1B10D034)
[19:44:56.350712] (debug)    Remove thread 1B37BC8D from SCM-thread queue
Из-за чего краши?
создавай потому что lua_thread, и в нем делай свою хрень, и этой ошибки не будет
 

Hatiko

Известный
Проверенный
1,515
633
Имеется непонятный баг, при написании чего-либо в инпут диалогового окна, то при последующем его открывании остаётся ранее написанное.
Как можно очистить инпут диалогового окна, есть ли функции или что-то в этом роде.