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

imring

Ride the Lightning
Всефорумный модератор
2,362
2,545
Здравствуйте, проблемка у меня. Нужно написать чекер ЧС.

Есть следующий код:
Lua:
downloadUrlToFile(url, file) -- обе переменные указаны
wait(3000) -- 3 секундочки для загрузки
local tobl = getWorkingDirectory() .. "/blacklist.txt" -- получаем путь к документу с ЧС
local checkerfiler = io.open(tobl,"r+") -- открываем его
if checkerfiler == nil then -- проверяем существует документ или нет
sampAddChatMessage("[AutoMVD] Не удалось обновить Черный Список.", 0xFF0000) -- сообщение
else -- если существует, то
blacklist = io.input(tobl); -- открываем документ
blacklist = io.read(); -- читаем его
blacklisttext = sampGetPlayerNickname(blacklisttext) -- ID в Nickname
if string.find(blacklist:read() ,blacklisttext) then -- если есть упоминание
sampAddChatMessage("[AutoMVD] "..blacklisttext.." НАХОДИТСЯ в Черном Списке!", 0xFF0000)
else
sampSendChat("/history "..blacklisttext) -- открываем историю смены ников
dial = sampGetDialogText() -- получаем текст истории
if blacklist:read():find(dial) then -- проверяем историю
sampAddChatMessage("[AutoMVD] "..blacklisttext.." НАХОДИТСЯ в Черном Списке!", 0xFF0000)
else
blacklisttext = blacklisttext:gsub("_", " "); -- превращаем в РП имя
if string.find(blacklist:read(), blacklisttext) then -- тоже проверяем
sampAddChatMessage("[AutoMVD] "..blacklisttext.." НАХОДИТСЯ в Черном Списке!", 0xFF0000)
else
sampAddChatMessage("[AutoMVD] "..blacklisttext.." не состоит в Черном Списке.", 0x4682B4)
end
end
end
end

В итоге не один человек из документа в ЧС не состоит. Что не так?
Скинь всю функцию.

Здравствуйте, проблемка у меня. Нужно написать чекер ЧС.

Есть следующий код:
Lua:
downloadUrlToFile(url, file) -- обе переменные указаны
wait(3000) -- 3 секундочки для загрузки
local tobl = getWorkingDirectory() .. "/blacklist.txt" -- получаем путь к документу с ЧС
local checkerfiler = io.open(tobl,"r+") -- открываем его
if checkerfiler == nil then -- проверяем существует документ или нет
sampAddChatMessage("[AutoMVD] Не удалось обновить Черный Список.", 0xFF0000) -- сообщение
else -- если существует, то
blacklist = io.input(tobl); -- открываем документ
blacklist = io.read(); -- читаем его
blacklisttext = sampGetPlayerNickname(blacklisttext) -- ID в Nickname
if string.find(blacklist:read() ,blacklisttext) then -- если есть упоминание
sampAddChatMessage("[AutoMVD] "..blacklisttext.." НАХОДИТСЯ в Черном Списке!", 0xFF0000)
else
sampSendChat("/history "..blacklisttext) -- открываем историю смены ников
dial = sampGetDialogText() -- получаем текст истории
if blacklist:read():find(dial) then -- проверяем историю
sampAddChatMessage("[AutoMVD] "..blacklisttext.." НАХОДИТСЯ в Черном Списке!", 0xFF0000)
else
blacklisttext = blacklisttext:gsub("_", " "); -- превращаем в РП имя
if string.find(blacklist:read(), blacklisttext) then -- тоже проверяем
sampAddChatMessage("[AutoMVD] "..blacklisttext.." НАХОДИТСЯ в Черном Списке!", 0xFF0000)
else
sampAddChatMessage("[AutoMVD] "..blacklisttext.." не состоит в Черном Списке.", 0x4682B4)
end
end
end
end

В итоге не один человек из документа в ЧС не состоит. Что не так?
Проверка всех игроков
Lua:
function checkBlackList()
    downloadUrlToFile(url, file) -- Скачиваем файл.
    wait(3000) -- Ждём 3 секунды.
    local tobl = getWorkingDirectory() .. '/blacklist.txt' -- Местонахождение файла blacklist.txt.
    local checkerfiler = io.open(tobl, 'r') -- Открываем файл в режиме чтения.
    if checkerfiler == nil then sampAddChatMessage('[AutoMVD] Не удалось обновить Черный Список.', 0xFF0000) -- Если файл не открылся, то выводит в чат сообщение.
    else -- Если файл открылся
        for lines in checkerfiler:lines() do -- Проверяем каждую строку файла
            for id = 0, 1000 do -- Перебираем всех игроков.
                if sampIsPlayerConnected(id) then -- Если игрок подключён.
                    local nick = sampGetPlayerNickname(id) -- Выводим игрока ник.
                    if lines == nick then -- Если строка с ником будет похож на ник, то выводит в чат сообщение.
                        sampAddChatMessage('[AutoMVD] '..nick..' НАХОДИТСЯ в Черном Списке!', 0xFF0000)
                    else -- Если строка с ником НЕ будет похож на ник, то проверяем по истории ника.
                        sampSendChat('/history '..nick) -- Пишет в чат команду /history
                        local dial = sampGetDialogText() -- Получаем текст диалога.
                        if string.find(dial, lines) or string.find(dial, string.gsub(lines, '_', ' ')) then -- Если в тексте диалога есть ник со строки lines, то выводит в чат.
                            sampAddChatMessage('[AutoMVD] '..nick..' НАХОДИТСЯ в Черном Списке!', 0xFF0000)
                        end
                    end
                end
            end
        end
    end
end
Проверка одного игрока [ по ID игрока ]
Lua:
function checkBlackList(id)
    downloadUrlToFile(url, file) -- Скачиваем файл.
    wait(3000) -- Ждём 3 секунды.
    local tobl = getWorkingDirectory() .. '/blacklist.txt' -- Местонахождение файла blacklist.txt.
    local checkerfiler = io.open(tobl, 'r') -- Открываем файл в режиме чтения.
    if checkerfiler == nil then sampAddChatMessage('[AutoMVD] Не удалось обновить Черный Список.', 0xFF0000) -- Если файл не открылся, то выводит в чат сообщение.
    else -- Если файл открылся
        for lines in checkerfiler:lines() do -- Проверяем каждую строку файла
            if sampIsPlayerConnected(id) then -- Если игрок подключён.
                local nick = sampGetPlayerNickname(id) -- Выводим игрока ник.
                if lines == nick then -- Если строка с ником будет похож на ник, то выводит в чат сообщение.
                    sampAddChatMessage('[AutoMVD] '..nick..' НАХОДИТСЯ в Черном Списке!', 0xFF0000)
                else -- Если строка с ником НЕ будет похож на ник, то проверяем по истории ника.
                    sampSendChat('/history '..nick) -- Пишет в чат команду /history
                    local dial = sampGetDialogText() -- Получаем текст диалога.
                    if string.find(dial, lines) or string.find(dial, string.gsub(lines, '_', ' ')) then -- Если в тексте диалога есть ник со строки lines, то выводит в чат.
                        sampAddChatMessage('[AutoMVD] '..nick..' НАХОДИТСЯ в Черном Списке!', 0xFF0000)
                    end
                end
            end
        end
    end
end
 
Последнее редактирование модератором:

Widness

Новичок
25
4
По идее вот этот код должен работать, но это не точно, я не проверял.
Lua:
function main()
if not isSampfuncsLoaded() or not isSampLoaded() then return end
while not isSampAvailable() do wait(420) end
while true do
wait(0)
local TextDrawString1 = sampTextdrawGetString(2120)
local TextDrawString2 = sampTextdrawGetString(2119)
local TextDrawString4 = sampTextdrawGetString(2117)
local TextDrawString3 = sampTextdrawGetString(2118)
local TextDrawString5 = sampTextdrawGetString(2116)
if string.lower(TextDrawString2) == string.lower(TextDrawString1) then
wait(255)
sampSendClickTextdraw(2119)
end
if string.lower(TextDrawString3) == string.lower(TextDrawString1) then
wait(255)
sampSendClickTextdraw(2118)
end
if string.lower(TextDrawString4) == string.lower(TextDrawString1) then
wait(255)
sampSendClickTextdraw(2117)
end
if string.lower(TextDrawString5) == string.lower(TextDrawString1) then
wait(255)
sampSendClickTextdraw(2116)
end
end
end
Мог бы ты объяснить, откуда ID текстдрайвов?
У меня везде ID 0
screen:
WKLIQqd.png
 
Последнее редактирование:

imring

Ride the Lightning
Всефорумный модератор
2,362
2,545
Мог бы ты объяснить, откуда ID текстдрайвов?
Если надо
Команда: /rtd
Lua:
script_name('textdraw')

scron = false

function main()
    font = renderCreateFont('Verdana', 8, 13)
    sampRegisterChatCommand('rtd', rendTextDraw)
    while true do
        wait(0)
        for textdrawid = 0, 3000 do
            if sampTextdrawIsExists(textdrawid) then
                local X, Y = sampTextdrawGetPos(textdrawid)
                posX, posY = convertGameScreenCoordsToWindowScreenCoords(X, Y)
                if scron then renderFontDrawText(font, textdrawid, posX, posY, 0xFFFF0000) end
            end
        end
    end
end

function rendTextDraw()
    scron = not scron
end
 

Widness

Новичок
25
4
Как проверить видим ли текстрадрайв или нет? Мне нужно чтобы скрипт срабатывал именно тогда, когда открывалась этот текстдрайв
PTQFjID.png
 

imring

Ride the Lightning
Всефорумный модератор
2,362
2,545
Что мне нужно чтобы написать такой скрипт -
.
Что я должен хукать и какой ид пакета/RPc?
Lua:
function main()
    while not isSampAvailable() do wait(0) end
    while true do wait(0)
        if sampTextdrawIsExists(2125) then
            for id = 0, 4 do
                if string.lower(sampTextdrawGetString(2116+id)) == string.lower(sampTextdrawGetString(2125)) then
                    wait(255)
                    sampSendClickTextdraw(2116+id)
                end
            end
        end
    end
end
 

Widness

Новичок
25
4
Как узнать сколько в переменной символов? К примеру есть переменная a, в ней есть какое то значение и я хочу чтобы скрипт срабатывал тогда, когда в ней есть 3 значения

Lua:
function main()
    while not isSampAvailable() do wait(0) end
    while true do wait(0)
        if sampTextdrawIsExists(2125) then
            for id = 0, 4 do
                if string.lower(sampTextdrawGetString(2116+id)) == string.lower(sampTextdrawGetString(2125)) then
                    wait(255)
                    sampSendClickTextdraw(2116+id)
                end
            end
        end
    end
end
Данный текстдрав может иметь следующий ID : 2125, 2124, 2121. И они определяются рандомно
9eDf8qQ.png
 
Последнее редактирование модератором:

imring

Ride the Lightning
Всефорумный модератор
2,362
2,545
Как узнать сколько в переменной символов? К примеру есть переменная a, в ней есть какое то значение и я хочу чтобы скрипт срабатывал тогда, когда в ней есть 3 значения
Lua:
local text = 'text'
print(#text)
-- 4
-- Аналогичный вариант: string.len(text)
Данный текстдрав может иметь следующий ID : 2125, 2124, 2121. И они определяются рандомно
Lua:
function main()
    while not isSampAvailable() do wait(0) end
    while true do wait(0)
        if sampTextdrawIsExists(2125) then
            for id = 0, 4 do
                if string.lower(sampTextdrawGetString(2116+id)) == string.lower(sampTextdrawGetString(2121)) or string.lower(sampTextdrawGetString(2124)) or string.lower(sampTextdrawGetString(2125)) then
                    wait(255)
                    sampSendClickTextdraw(2116+id)
                end
            end
        end
    end
end
 

Dark_Knight

Me, me and me.
Друг
4,078
2,095
Текстдравов всего лишь 2048. После них идут 256 пользовательских.
 

Widness

Новичок
25
4
В чем ошибка? Все равно пишет "сорвалась рыба"
Lua:
function main()
  while not isSampAvailable() do wait(0) end
  while true do wait(0)
  if sampTextdrawIsExists(2125) then
  for id = 0, 4 do
  if string.lower(sampTextdrawGetString(2116+id)) == string.lower(sampTextdrawGetString(2121)) or string.lower(sampTextdrawGetString(2124)) or string.lower(sampTextdrawGetString(2125)) then
  wait(255)
  sampSendClickTextdraw(2116+id)
  end
  end
  end
     if sampTextdrawIsExists(2124) then
  for id = 0, 4 do
  if string.lower(sampTextdrawGetString(2116+id)) == string.lower(sampTextdrawGetString(2121)) or string.lower(sampTextdrawGetString(2124)) or string.lower(sampTextdrawGetString(2125)) then
  wait(255)
  sampSendClickTextdraw(2116+id)
  end
  end
  end
     if sampTextdrawIsExists(2121) then
  for id = 0, 4 do
  if string.lower(sampTextdrawGetString(2116+id)) == string.lower(sampTextdrawGetString(2121)) or string.lower(sampTextdrawGetString(2124)) or string.lower(sampTextdrawGetString(2125)) then
  wait(255)
  sampSendClickTextdraw(2116+id)
  end
  end
  end
  end
end
 

imring

Ride the Lightning
Всефорумный модератор
2,362
2,545
В чем ошибка? Все равно пишет "сорвалась рыба"
Lua:
function main()
  while not isSampAvailable() do wait(0) end
  while true do wait(0)
  if sampTextdrawIsExists(2125) then
  for id = 0, 4 do
  if string.lower(sampTextdrawGetString(2116+id)) == string.lower(sampTextdrawGetString(2121)) or string.lower(sampTextdrawGetString(2124)) or string.lower(sampTextdrawGetString(2125)) then
  wait(255)
  sampSendClickTextdraw(2116+id)
  end
  end
  end
     if sampTextdrawIsExists(2124) then
  for id = 0, 4 do
  if string.lower(sampTextdrawGetString(2116+id)) == string.lower(sampTextdrawGetString(2121)) or string.lower(sampTextdrawGetString(2124)) or string.lower(sampTextdrawGetString(2125)) then
  wait(255)
  sampSendClickTextdraw(2116+id)
  end
  end
  end
     if sampTextdrawIsExists(2121) then
  for id = 0, 4 do
  if string.lower(sampTextdrawGetString(2116+id)) == string.lower(sampTextdrawGetString(2121)) or string.lower(sampTextdrawGetString(2124)) or string.lower(sampTextdrawGetString(2125)) then
  wait(255)
  sampSendClickTextdraw(2116+id)
  end
  end
  end
  end
end
Попробуй поставить побольше задержку.
 

Widness

Новичок
25
4
Попробуй поставить побольше задержку.
Все равно не работает, еще и продолжает работать после закрытие текстдрава
Lua:
function main()
  while not isSampAvailable() do wait(0) end
  while true do wait(0)
  if sampTextdrawIsExists(2125) then
  for id = 0, 4 do
  if string.lower(sampTextdrawGetString(2116+id)) == string.lower(sampTextdrawGetString(2121)) or string.lower(sampTextdrawGetString(2124)) or string.lower(sampTextdrawGetString(2125)) then
   
  wait(755)
  sampSendClickTextdraw(2116+id)
  end
  end
  end
     if sampTextdrawIsExists(2124) then
  for id = 0, 4 do
  if string.lower(sampTextdrawGetString(2116+id)) == string.lower(sampTextdrawGetString(2121)) or string.lower(sampTextdrawGetString(2124)) or string.lower(sampTextdrawGetString(2125)) then
         
  wait(755)
  sampSendClickTextdraw(2116+id)
  end
  end
  end
     if sampTextdrawIsExists(2121) then
  for id = 0, 4 do
  if string.lower(sampTextdrawGetString(2116+id)) == string.lower(sampTextdrawGetString(2121)) or string.lower(sampTextdrawGetString(2124)) or string.lower(sampTextdrawGetString(2125)) then
           
  wait(755)
  sampSendClickTextdraw(2116+id)
  end
  end
  end
  end
end
 

ImPasha

Software Developer & System Administrator
Друг
1,789
2,141
Скинь всю функцию.


Проверка всех игроков
Lua:
function checkBlackList()
    downloadUrlToFile(url, file) -- Скачиваем файл.
    wait(3000) -- Ждём 3 секунды.
    local tobl = getWorkingDirectory() .. '/blacklist.txt' -- Местонахождение файла blacklist.txt.
    local checkerfiler = io.open(tobl, 'r') -- Открываем файл в режиме чтения.
    if checkerfiler == nil then sampAddChatMessage('[AutoMVD] Не удалось обновить Черный Список.', 0xFF0000) -- Если файл не открылся, то выводит в чат сообщение.
    else -- Если файл открылся
        for lines in checkerfiler:lines() do -- Проверяем каждую строку файла
            for id = 0, 1000 do -- Перебираем всех игроков.
                if sampIsPlayerConnected(id) then -- Если игрок подключён.
                    local nick = sampGetPlayerNickname(id) -- Выводим игрока ник.
                    if lines == nick then -- Если строка с ником будет похож на ник, то выводит в чат сообщение.
                        sampAddChatMessage('[AutoMVD] '..nick..' НАХОДИТСЯ в Черном Списке!', 0xFF0000)
                    else -- Если строка с ником НЕ будет похож на ник, то проверяем по истории ника.
                        sampSendChat('/history '..nick) -- Пишет в чат команду /history
                        local dial = sampGetDialogText() -- Получаем текст диалога.
                        if string.find(dial, lines) or string.find(dial, string.gsub(lines, '_', ' ')) then -- Если в тексте диалога есть ник со строки lines, то выводит в чат.
                            sampAddChatMessage('[AutoMVD] '..nick..' НАХОДИТСЯ в Черном Списке!', 0xFF0000)
                        end
                    end
                end
            end
        end
    end
end
Проверка одного игрока [ по ID игрока ]
Lua:
function checkBlackList(id)
    downloadUrlToFile(url, file) -- Скачиваем файл.
    wait(3000) -- Ждём 3 секунды.
    local tobl = getWorkingDirectory() .. '/blacklist.txt' -- Местонахождение файла blacklist.txt.
    local checkerfiler = io.open(tobl, 'r') -- Открываем файл в режиме чтения.
    if checkerfiler == nil then sampAddChatMessage('[AutoMVD] Не удалось обновить Черный Список.', 0xFF0000) -- Если файл не открылся, то выводит в чат сообщение.
    else -- Если файл открылся
        for lines in checkerfiler:lines() do -- Проверяем каждую строку файла
            if sampIsPlayerConnected(id) then -- Если игрок подключён.
                local nick = sampGetPlayerNickname(id) -- Выводим игрока ник.
                if lines == nick then -- Если строка с ником будет похож на ник, то выводит в чат сообщение.
                    sampAddChatMessage('[AutoMVD] '..nick..' НАХОДИТСЯ в Черном Списке!', 0xFF0000)
                else -- Если строка с ником НЕ будет похож на ник, то проверяем по истории ника.
                    sampSendChat('/history '..nick) -- Пишет в чат команду /history
                    local dial = sampGetDialogText() -- Получаем текст диалога.
                    if string.find(dial, lines) or string.find(dial, string.gsub(lines, '_', ' ')) then -- Если в тексте диалога есть ник со строки lines, то выводит в чат.
                        sampAddChatMessage('[AutoMVD] '..nick..' НАХОДИТСЯ в Черном Списке!', 0xFF0000)
                    end
                end
            end
        end
    end
end
"Не флудите" и вылет.
 

Widness

Новичок
25
4
Все равно пишет рыба сорвалась
Lua:
function main()
  while not isSampAvailable() do wait(0) end
  while true do wait(0)
  if sampTextdrawIsExists(2123) then
  for id = 0, 3 do
  if string.lower(sampTextdrawGetString(2117+id)) == string.lower(sampTextdrawGetString(2121)) or string.lower(sampTextdrawGetString(2124)) or string.lower(sampTextdrawGetString(2125)) then
   
  wait(755)
  sampSendClickTextdraw(2117+id)
  end
  end
  end
  end
end
 

Widness

Новичок
25
4
Он почему то не попадает по стрелкам
Скрины: Imgur: The magic of the Internet(https://imgur.com/a/nkxd4)
Lua:
function main()
  while not isSampAvailable() do wait(0) end
  while true do wait(0)
  if sampTextdrawIsExists(2123) then
  for id = 0, 3 do
  if string.lower(sampTextdrawGetString(2117+id)) == string.lower(sampTextdrawGetString(2121)) or string.lower(sampTextdrawGetString(2124)) or string.lower(sampTextdrawGetString(2125)) then
           sampAddChatMessage(2117+id, 0x40FF40)
           wait(500)
           sampSendClickTextdraw(2117+id)
  end
  end
  end
  end
end