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

Morse

Потрачен
436
70
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Есть может у кого исходник админ чекера который пробивает через /admins, заносит в таблицу и выводит рендером?
 

Sanchez.

Известный
704
190
Есть может у кого исходник админ чекера который пробивает через /admins, заносит в таблицу и выводит рендером?
А что сложного самому написать? Сделать авто-написание /admins, написать return false, хукнуть регулярки, занести все в массив и вывести все через рендер. Все
 
  • Нравится
Реакции: Morse

СоМиК

Известный
456
320
Смотри, мне нужно, чтобы Посмотреть вложение 108953скрипт искал текст "Купить валюту ЕВРО" по этому диалоговому окну, и кликал по этому элементу диалог окна с помощью sampSendDialogResponse(). Потому что элементы этого диалог окна могут как увеличиваться, так и убавляться (Строка "Купить валюту ЕВРО" скачет с 8 по 12 строку, и скрипт должен сам определять какая это строка по названию элемента)
up
 

Sanchez.

Известный
704
190
Есть может у кого исходник админ чекера который пробивает через /admins, заносит в таблицу и выводит рендером?
Если что, вот исходник чекера лидеров. Можешь переделать его под чекер админов

Lua:
local leaderscheck = true
local font_flag = require('moonloader').font_flag
local font = renderCreateFont("Arial", 9, 11)

local leaders = {}

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

    lua_thread.create(leaderschecker)
    leaderschecker = false

    while true do
        wait(0)

        if leaderscheck then
            if leaders ~= {} then
                for k,v in pairs(leaders) do
                    renderFontDrawText(font, v.lead_name .. "[" .. v.lead_id .. "] - " .. v.lead_org, 960, 540 + k * 30 --[[измени это значение, чтобы поменять расстояние между лидерами]], 0xFFFFFFFF)
                end
            end
        end
    end
end

function leaderschecker()
    while true do
        wait(500)
        if sampGetGamestate() == 3 and not isGamePaused() then
            sampSendChat("/leaders")
        end
    end
end

function sampev.onServerMessage(color, text)
    if leaderscheck then
        if text:find("Лидеры онлайн:") then
            leaders = {}
            return false
        end
 
        if text:find("(.*)%[(%d+)%] %- (.*) %| Номер%: (%d+)") then
            lead_name, lead_id, lead_org, lead_number = text:match("(.*)%[(%d+)%] %- (.*) %| Номер%: (%d+)")
            table.insert(leaders,{
                lead_name = lead_name,
                lead_id = lead_id,
                lead_org = lead_org
            })
            return false
        end
        if text:find("Используйте /phone %- menu, чтобы найти членов организаций.") then
            return false
        end
    end
end

(код от @JustMini )




Ребята, как сделать так, чтобы если в массиве содержались одинаковые строки, то повторяющаяся строка удалялась?
 
Последнее редактирование:

paulohardy

Известный
Всефорумный модератор
1,997
1,339
Ребята, как сделать так, чтобы если в массиве содержались одинаковые строки, то повторяющаяся строка удалялась?
Цикл в цикле, в обоих прогонять массив и во втором сравнивать значение из первого со вторым
 
  • Нравится
Реакции: Sanchez.

Sanchez.

Известный
704
190
Lua:
[ML] (error) GiveAway.lua: D:\GTA San Andreas\moonloader\GiveAway.lua:61: attempt to compare string with number
stack traceback:
    D:\GTA San Andreas\moonloader\GiveAway.lua:61: in function 'OnDrawFrame'
    D:\GTA San Andreas\moonloader\lib\imgui.lua:1378: in function <D:\GTA San Andreas\moonloader\lib\imgui.lua:1367>

Lua:
if #member > members.v then sampAddChatMessage('Достигнут лимит участников! Начинаю розыгрыш', -1) hook = true end

Почему вылазит эта ошибка? Я не сравниваю строку с числом, я добавил возле member #
 

chapo

tg/inst: @moujeek
Всефорумный модератор
9,238
12,671
Lua:
[ML] (error) GiveAway.lua: D:\GTA San Andreas\moonloader\GiveAway.lua:61: attempt to compare string with number
stack traceback:
    D:\GTA San Andreas\moonloader\GiveAway.lua:61: in function 'OnDrawFrame'
    D:\GTA San Andreas\moonloader\lib\imgui.lua:1378: in function <D:\GTA San Andreas\moonloader\lib\imgui.lua:1367>

Lua:
if #member > members.v then sampAddChatMessage('Достигнут лимит участников! Начинаю розыгрыш', -1) hook = true end

Почему вылазит эта ошибка? Я не сравниваю строку с числом, я добавил возле member #
#member возвращает число.
если member - массив, то # возвращает кол-во элементов в массиве
если member - строка, то # возвращает кол-во символов в строке
 
  • Нравится
Реакции: Sanchez.

Sanchez.

Известный
704
190
Lua:
local imgui = require 'imgui'
local encoding = require 'encoding'
local sampev = require 'lib.samp.events'
encoding.default = 'CP1251'
u8 = encoding.UTF8

local window = imgui.ImBool(false)

local nickname, id, msg = nil,nil,nil

local sw, sh = getScreenResolution()

local members = imgui.ImBuffer(256)

--ocal members1 = 0

local prize = imgui.ImBuffer(256)

local mesta = imgui.ImBuffer(256)

local giveaway = false

local hook = false

local member = {}

function imgui.CenterButton(text)
    local width = imgui.GetWindowWidth()
    local calc = imgui.CalcTextSize(text)
    imgui.SetCursorPosX( width / 2 - calc.x / 2 )
    imgui.Button(text)
end

function main()
    while not isSampAvailable() do wait(200) end

    sampRegisterChatCommand('giveaway', function()
        window.v = not window.v
    end)

    while true do
        wait(0)
        imgui.Process = window.v
    end
end

function imgui.OnDrawFrame()
    if window.v then
        imgui.SetNextWindowSize(imgui.ImVec2(250, 225), imgui.Cond.FirstUseEver)

        imgui.SetNextWindowPos(imgui.ImVec2((sw / 2), sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        imgui.Begin('GiveAway || BETA', window)
        --imgui.SameLine(60)
        if imgui.Button(giveaway and u8'Остановить розыгрыш' or u8'Запустить розыгрыш', imgui.ImVec2(-1, 35)) then
            if members.v == "" or mesta.v == "" or prize.v == "" then
                sampAddChatMessage('Недостаточно аргументов', -1)
            else
                giveaway = not giveaway
                proverka()
                hook = not hook
            end
        end
        --if #member > members.v then sampAddChatMessage('Достигнут лимит участников! Начинаю розыгрыш', -1) hook = true end
        --if members.v > #member then podchet = true en
        if #member > members.v then sampAddChatMessage('Достигнут лимит участников. Начинаю розыгрыш!', -1) hook = true end

        imgui.Separator()
        imgui.PushItemWidth(50)
        imgui.InputText(u8' || Кол-во участников', members)
        imgui.PopItemWidth()
        imgui.PushItemWidth(50)
        imgui.InputText(u8' || Сколько призовых мест', mesta)
        imgui.PopItemWidth()
        imgui.PushItemWidth(50)
        imgui.InputText(u8' || Приз на каждого', prize)
        imgui.PopItemWidth()
        imgui.Separator()
        --imgui.NewLine()
        --imgui.NewLine()
        --imgui.SameLine(63)
        imgui.BeginChild('##memberrss', imgui.ImVec2(-1, -1), true)
        imgui.Text(u8'Список участников:')
        imgui.SameLine()
        if imgui.Button(u8'Очистить', imgui.ImVec2(-1, 18)) then member = {} end
        for i=1, #member do
            imgui.Text(member[i])
        end
        --if members.v ~= "" and giveaway then
        --end
        imgui.NewLine()
        imgui.EndChild()
        imgui.End()
    end
end

function sampev.onServerMessage(color, text)
    if giveaway and hook then
        if text:find('{......}(%S+)%[(%d+)%] говорит:{B7AFAF}  %+') and #member ~= nickname then
            nickname, id, msg = text:match('{......}(%S+)%[(%d+)%] говорит:{B7AFAF}  %+')
            table.insert(member, string.format('%s[%d]', nickname, id))
            --members = members + 1
        end
    end
end
Помогите пожалуйста подправить код, в консоле вот такая ошибка [ML] (error) GiveAway.lua: D:\GTA San Andreas\moonloader\GiveAway.lua:67: attempt to compare string with number stack traceback: Кто может помогите прошу, я ебусь с этой хуетой пол дня. В пустой мозг ничего не приходит
 

paulohardy

Известный
Всефорумный модератор
1,997
1,339
Помогите пожалуйста исправить код, в консоле вот такая ошибка [ML] (error) GiveAway.lua: D:\GTA San Andreas\moonloader\GiveAway.lua:67: attempt to compare string with number stack traceback: Кто может помогите прошу, я ебусь с этой хуетой пол дня
тебе же ответили уже
ты пытаешься сравнить число и строку, так делать нельзя
1628367278938.png
 
  • Нравится
Реакции: Sanchez.

kizn

q(≧▽≦q)
Всефорумный модератор
2,411
2,139
Lua:
local imgui = require 'imgui'
local encoding = require 'encoding'
local sampev = require 'lib.samp.events'
encoding.default = 'CP1251'
u8 = encoding.UTF8

local window = imgui.ImBool(false)

local nickname, id, msg = nil,nil,nil

local sw, sh = getScreenResolution()

local members = imgui.ImBuffer(256)

--ocal members1 = 0

local prize = imgui.ImBuffer(256)

local mesta = imgui.ImBuffer(256)

local giveaway = false

local hook = false

local member = {}

function imgui.CenterButton(text)
    local width = imgui.GetWindowWidth()
    local calc = imgui.CalcTextSize(text)
    imgui.SetCursorPosX( width / 2 - calc.x / 2 )
    imgui.Button(text)
end

function main()
    while not isSampAvailable() do wait(200) end

    sampRegisterChatCommand('giveaway', function()
        window.v = not window.v
    end)

    while true do
        wait(0)
        imgui.Process = window.v
    end
end

function imgui.OnDrawFrame()
    if window.v then
        imgui.SetNextWindowSize(imgui.ImVec2(250, 225), imgui.Cond.FirstUseEver)

        imgui.SetNextWindowPos(imgui.ImVec2((sw / 2), sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        imgui.Begin('GiveAway || BETA', window)
        --imgui.SameLine(60)
        if imgui.Button(giveaway and u8'Остановить розыгрыш' or u8'Запустить розыгрыш', imgui.ImVec2(-1, 35)) then
            if members.v == "" or mesta.v == "" or prize.v == "" then
                sampAddChatMessage('Недостаточно аргументов', -1)
            else
                giveaway = not giveaway
                proverka()
                hook = not hook
            end
        end
        --if #member > members.v then sampAddChatMessage('Достигнут лимит участников! Начинаю розыгрыш', -1) hook = true end
        --if members.v > #member then podchet = true en
        if #member > members.v then sampAddChatMessage('Достигнут лимит участников. Начинаю розыгрыш!', -1) hook = true end

        imgui.Separator()
        imgui.PushItemWidth(50)
        imgui.InputText(u8' || Кол-во участников', members)
        imgui.PopItemWidth()
        imgui.PushItemWidth(50)
        imgui.InputText(u8' || Сколько призовых мест', mesta)
        imgui.PopItemWidth()
        imgui.PushItemWidth(50)
        imgui.InputText(u8' || Приз на каждого', prize)
        imgui.PopItemWidth()
        imgui.Separator()
        --imgui.NewLine()
        --imgui.NewLine()
        --imgui.SameLine(63)
        imgui.BeginChild('##memberrss', imgui.ImVec2(-1, -1), true)
        imgui.Text(u8'Список участников:')
        imgui.SameLine()
        if imgui.Button(u8'Очистить', imgui.ImVec2(-1, 18)) then member = {} end
        for i=1, #member do
            imgui.Text(member[i])
        end
        --if members.v ~= "" and giveaway then
        --end
        imgui.NewLine()
        imgui.EndChild()
        imgui.End()
    end
end

function sampev.onServerMessage(color, text)
    if giveaway and hook then
        if text:find('{......}(%S+)%[(%d+)%] говорит:{B7AFAF}  %+') and #member ~= nickname then
            nickname, id, msg = text:match('{......}(%S+)%[(%d+)%] говорит:{B7AFAF}  %+')
            table.insert(member, string.format('%s[%d]', nickname, id))
            --members = members + 1
        end
    end
end
Помогите пожалуйста подправить код, в консоле вот такая ошибка [ML] (error) GiveAway.lua: D:\GTA San Andreas\moonloader\GiveAway.lua:67: attempt to compare string with number stack traceback: Кто может помогите прошу, я ебусь с этой хуетой пол дня. В пустой мозг ничего не приходит
#member > #members.v
 
  • Нравится
Реакции: Sanchez.

bab0n

Известный
95
10
Попытка сделать так
Lua:
picks = getAllPickups()
Приводит к такому:
attempt to call global 'getAllPickups' (a nil value)
stack traceback:
E:\sa_mp\moonloader\fullghettohelper.lua: in function <E:\sa_mp\moonloader\fullghettohelper.lua:200>
[ML] (error) fullghettohelper.lua: Script died due to an error. (07D15F04)

Возможно баг @FYP
Если есть альтернатива, подскажите пожалуйста
 

Dmitriy Makarov

25.05.2021
Проверенный
2,512
1,139
Попытка сделать так
Lua:
picks = getAllPickups()
Приводит к такому:
attempt to call global 'getAllPickups' (a nil value)
stack traceback:
E:\sa_mp\moonloader\fullghettohelper.lua: in function <E:\sa_mp\moonloader\fullghettohelper.lua:200>
[ML] (error) fullghettohelper.lua: Script died due to an error. (07D15F04)
На MoonLoader 0.27 работает эта функция вроде.
 
  • Нравится
Реакции: bab0n
D

deleted-user-216129

Гость
Можно ли сохранять объёмные таблицы(больше 300к строк) в ini конфигах? Стоит ли для этого использовать json и есть ли для него библиотека(что-бы самому не писать функции сохранения/чтения и т. п.)
 

AnWu

Известный
Всефорумный модератор
4,788
5,432
Можно ли сохранять объёмные таблицы(больше 300к строк) в ini конфигах? Стоит ли для этого использовать json и есть ли для него библиотека(что-бы самому не писать функции сохранения/чтения и т. п.)
сомневаюсь, разумно использовать json. либы точно есть, на гитхабе поищи. однако лучше самому написать 4 строки, ладно 8 на две функции
 
  • Нравится
Реакции: deleted-user-216129

JustFedot

legends never die 🕊️
357
379
Утро доброе ребята.
Давно меня не было, уже всё позабывал, вот пытаюсь восстановиться.
Подскажите мне пожалуйста, как можно узнать что меня отключило от сервера?
Знаю способ через беск. цикл с sampGetGamestate(), но может можно что-то использовать без беск. цикла....
сомневаюсь, разумно использовать json. либы точно есть, на гитхабе поищи. однако лучше самому написать 4 строки, ладно 8 на две функции
Какраз вопрос по этому поводу.
В чём разница между json и ini если шо то шо то используется в скрипте по сути как текстовый файл? Я всё ещё нуб, объясните пожалуйста.
 
Последнее редактирование: