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

MrCold

Активный
364
118
Помогите плз. Вот смотрите, например:
Сервер ограничил дальность прорисовки объектов(некоторых). Как сделать так, чтобы увеличить эту дальность?
Есть кто сможет мне помочь, можете объяснить функции? Большое спасибо заранее
 

imring

Ride the Lightning
Всефорумный модератор
2,365
2,552
Большое спасибо, может знаешь решение проблемы
Lua:
elseif gNumLicExam == 30 then -- Делаем скриншотик..
             if not sampIsDialogActive() then
                    wait(3000)
                     sampSendChat("/time")
                     wait(2222)
                     memory.setuint8( sampGetBase() + 0x119CBC, 1 );
                     gNumLicExam = 0
             end

Перед тем, как переменная приравняется 30, появляется диалог, пу сути дела, код под условием
Lua:
if not sampIsDialogActive() then
должен сработать тогда, когда я закрою диалог, но по каким - то неведомым причинам условие игнорируется и код срабатывает даже если диалог открыт.
Без понятия, что делать. Не хочу задержку делать.
Lua:
elseif gNumLicExam == 30 then -- Делаем скриншотик..
    while not sampIsDialogActive() do sampSendChat("/time") end
    memory.setuint8( sampGetBase() + 0x119CBC, 1 );
    gNumLicExam = 0
попробуй
 

GORYCH

Известный
63
77
После неудачных попыток разобраться самому, все же решил обратиться в данную тему.
Проблема такова: не знаю как создать мультизадачность или как это назвать. В общем, чтобы скрипт выполнял и основной код с ботом, и при этом выполнял код с коллизией игроков. Предлагать создать отдельный скрипт не надо.
Lua:
function main()
-- тут код с ботом
end
function colls()
-- тут код с коллизией
end
как сделать чтобы функции работали одновременно. help
 

Bogach

Активный
558
27
Lua:
elseif gNumLicExam == 30 then -- Делаем скриншотик..
    while not sampIsDialogActive() do sampSendChat("/time") end
    memory.setuint8( sampGetBase() + 0x119CBC, 1 );
    gNumLicExam = 0
попробуй
Хм. Я вроде так пробовал, ну ладно, попробую ещё раз.

После неудачных попыток разобраться самому, все же решил обратиться в данную тему.
Проблема такова: не знаю как создать мультизадачность или как это назвать. В общем, чтобы скрипт выполнял и основной код с ботом, и при этом выполнял код с коллизией игроков. Предлагать создать отдельный скрипт не надо.
Lua:
function main()
-- тут код с ботом
end
function colls()
-- тут код с коллизией
end
как сделать чтобы функции работали одновременно. help
Создай просто новый поток и все
Lua:
lua_thread.create(colls)
 
Последнее редактирование модератором:

Bogach

Активный
558
27
Lua:
elseif gNumLicExam == 30 then -- Делаем скриншотик..
    while not sampIsDialogActive() do sampSendChat("/time") end
    memory.setuint8( sampGetBase() + 0x119CBC, 1 );
    gNumLicExam = 0
попробуй
Так он делает скриншот без /time, даже если я не закрываю диалог
вот так:
Lua:
while not sampIsDialogActive() do sampSendChat("/time")
                     wait(2000)
                      memory.setuint8( sampGetBase() + 0x119CBC, 1 );
                      gNumLicExam = 0
                end
Он не делает скриншот пока не закроется диалог, но после закрытия диалога он начинает флудить time'om с скриншотом
вот так:
Lua:
while not sampIsDialogActive() do sampSendChat("/time")
                     wait(2000)
                      memory.setuint8( sampGetBase() + 0x119CBC, 1 );
                end
                gNumLicExam = 0
Вот так вообще ничего не делает. Я хз уже что делать.

Lua:
elseif gNumLicExam == 30 then -- Делаем скриншотик..
    while not sampIsDialogActive() do sampSendChat("/time") end
    memory.setuint8( sampGetBase() + 0x119CBC, 1 );
    gNumLicExam = 0
попробуй
Бро, ещё идеи есть?
 
Последнее редактирование модератором:

Bogach

Активный
558
27
ну так закрой диалог.
Ну так все это происходит быстро, диалог не успеть закрыть. Я хотел сделать, чтобы скрипт не делал скриншот с /time пока я не закрою диалог, я и не думал, что все так сложно
последний вариант твой тоже не работает, похуй, будет с задержкой
 

MrCold

Активный
364
118
Помогите плз. Вот смотрите, например:
Сервер ограничил дальность прорисовки объектов(некоторых). Как сделать так, чтобы увеличить эту дальность?
Есть кто сможет мне помочь, можете объяснить функции? Большое спасибо заранее
 

Hatiko

Известный
Проверенный
1,512
628
Чилдами ограничивается, не думаю что прям весь код нужен.
Lua:
imgui.Text(u8"Характеристика игрока:"); imgui.SameLine(); ShowHelpMarker(u8"Раз два")
Ошибка вылетает.

И ещё, что делать с KeyRepeatDelay в imgui. Описание к функции IsKeyPressed шло, что при использовании режима двойного нажатия использовать io.KeyRepeatDelay. Хочу сделать активацию чего-то по двойному нажатию клавиши . По желанию ещё показать второй вариант активации чего-либо по двойного нажатию на клавишу без библиотеки imgui, а на стандартном lua.
Вопрос ещё актуален.
 

MrCold

Активный
364
118
В чем проблема кода? Я с CLEO попробовал переписать на Lua. Вот код Lua:
Lua:
require 'lib.moonloader'

function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(100) end
    while true do
        wait(0)
        if anti then
            car = storeCarCharIsInNoSave(playerPed)
            result = isCharInCar(playerPed, car)
            if result then
                setCharCanBeKnockedOffBike(playerPed, 1)
            end
        end
    end
end
 

FYP

Известный
Автор темы
Администратор
1,764
5,924
Приветствую, BH. Пишу многофункциональный скрипт, среди функций которого хотелось бы увидеть автоввод кода безопасности Google Authenticator при появлении соответствующего диалога. Мною на гитхабе была найдена замечательная либа под это дело и был написан код:
Lua:
                elseif did == 389 then
                    if asecret ~= nil then
                        code = gauth.gencode(asecret, math.floor(os.time() / 30))
                                sampAddChatMessage("{3C519A}[GRPAdmin] {FFFFFF}Секретка: "..asecret, 0xC1C1C1)
                                sampAddChatMessage("{3C519A}[GRPAdmin] {FFFFFF}Код: "..code, 0xC1C1C1)
                                sampAddChatMessage("{3C519A}[GRPAdmin] {FFFFFF}Время: "..os.time(), 0xC1C1C1)
                                sampSendDialogResponse(389, 1, 0, code)
                                sampCloseCurrentDialogWithButton(1)
                    end
                end
Суть проблемы в том, что коды генерируются некорректно. Результат выполнения в игре:

TX6Nr_B4Zyc.jpg


Библиотеку я естественно подключил и секретный ключ указываю правильно. Вопрос - в чем тогда дело? Сразу же подумал на время, но оно выводится верно. Также были подозрения в кодировке, однако ее смена также результатов не дала.

Сама библиотека

Lua:
gauth = require "gauth"
seckey = "TESTtestTESTtest"
gauth.gencode(seckey, math.floor(os.time() / 30))
if gauth.check(seckey, io.read()) then
  print "Pass"
else
  print "Bad code"
end
если это и должно вообще работать, то проблему надо искать в библиотеке. только я не понимаю, какой тогда вообще смысл в двухфакторной авторизации, при наличии способов её обхода?
функция gencode в этой либе принимает только один аргумент, так что дело точно не во времени, ну или по крайней мере не во втором аргументе
Ну так все это происходит быстро, диалог не успеть закрыть. Я хотел сделать, чтобы скрипт не делал скриншот с /time пока я не закрою диалог, я и не думал, что все так сложно
последний вариант твой тоже не работает, похуй, будет с задержкой
Lua:
while sampIsDialogActive() do wait(0) end
sampSendChat('/time')
memory.setuint8(sampGetBase() + 0x119CBC, 1)
Помогите плз. Вот смотрите, например:
Сервер ограничил дальность прорисовки объектов(некоторых). Как сделать так, чтобы увеличить эту дальность?
Есть кто сможет мне помочь, можете объяснить функции? Большое спасибо заранее
это контролируется на стороне сервера. максимум, что можно сделать - это запретить удаление объектов.
Описание к функции IsKeyPressed шло, что при использовании режима двойного нажатия использовать io.KeyRepeatDelay. Хочу сделать активацию чего-то по двойному нажатию клавиши .
для проверки двойного нажатия кнопки мыши в имгуи есть функция IsMouseDoubleClicked, для остального нужно делать свою реализацию с сохранением времени между нажатиями клавиши и соответствующей реакцией на это.
 
Последнее редактирование:
  • Нравится
Реакции: Bogach

Nishikinov

Известный
148
34
если это и должно вообще работать, то проблему надо искать в библиотеке. только я не понимаю, какой тогда вообще смысл в двухфакторной авторизации, при наличии способов её обхода?
функция gencode в этой либе принимает только один аргумент, так что дело точно не во времени, ну или по крайней мере не во втором аргументе
Смысл в том, чтобы автоматизировать действия со стороны клиента, внешняя защита остается в любом случае. Однако спасибо огромное за ответ, я пошарился в либе, обратил внимание на передаваемые аргументы и все-таки смог начать генерацию корректных кодов прямо в игре.