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

DeMoN3D

Известный
366
77
Lua:
local imgui = require 'imgui'
local key = require 'vkeys'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8

local main_window_state = imgui.ImBool(false)
function imgui.OnDrawFrame()
  if main_window_state.v then
    imgui.SetNextWindowSize(imgui.ImVec2(300, 200), imgui.Cond.FirstUseEver)
    imgui.SetNextWindowPos(imgui.ImVec2(5, 300), imgui.Cond.FirstUseEver)
    imgui.Begin('Ether by H.e.a.v.e.n.l.y', main_window_state)
    imgui.Text('Ether')
    if imgui.Button(u8'Начало') then
      sampSendChat("/n протянув руку к специальному креплению, снял(а) с него наушники и одел их на голову")
      wait(3000)
      sampSendChat(string.format("/w Наушники на голове у %s.", sampGetPlayerNickname(sampGetPlayerIdByCharHandle(playerPed))))
      wait(3000)
      sampSendChat("/n включив оборудование, начал(а) настраивать оборудование к ведению эфира")
      wait(3000)
      sampSendChat("/n подрегулировал(а) громкость воспроизведения заставки и голосов в эфире")
      wait(3000)
      sampSendChat("/w Громкость урегулирована и находится в нормальном состоянии.")
      wait(3000)
      sampSendChat("/n пододвинул(а) стоящий на стойке микрофон к себе")
      wait(3000)
      sampSendChat("/n сдвинув регулятор, настроил громкость микрофона и убрал(а) лишние шумы")
      wait(3000)
      sampSendChat("/n настроив все оборудование, нажал на кнопку выхода в эфир")
      wait(3000)
      sampSendChat(string.format("/w %s находится в прямом эфире.", sampGetPlayerNickname(sampGetPlayerIdByCharHandle(playerPed))))
      wait(3000)
      end
    imgui.End()
  end
end

function main()
  while true do
    wait(0)
    if wasKeyPressed(key.VK_F2) then
        main_window_state.v = not main_window_state.v
    end
    imgui.Process = main_window_state.v
  end
end
как тут правильно использовать ?
Lua:
local imgui = require 'imgui'
local key = require 'vkeys'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8

local main_window_state = imgui.ImBool(false)
function imgui.OnDrawFrame()
  if main_window_state.v then
    imgui.SetNextWindowSize(imgui.ImVec2(300, 200), imgui.Cond.FirstUseEver)
    imgui.SetNextWindowPos(imgui.ImVec2(5, 300), imgui.Cond.FirstUseEver)
    imgui.Begin('Ether by H.e.a.v.e.n.l.y', main_window_state)
    imgui.Text('Ether')
    if imgui.Button(u8'Начало') then
      lua_thread.create(function()
      sampSendChat("/n протянув руку к специальному креплению, снял(а) с него наушники и надел их на голову")
      wait(3000)
      sampSendChat(string.format("/w Наушники на голове у %s.", sampGetPlayerNickname(sampGetPlayerIdByCharHandle(playerPed))))
      wait(3000)
      sampSendChat("/n включив оборудование, начал(а) настраивать оборудование к ведению эфира")
      wait(3000)
      sampSendChat("/n подрегулировал(а) громкость воспроизведения заставки и голосов в эфире")
      wait(3000)
      sampSendChat("/w Громкость урегулирована и находится в нормальном состоянии.")
      wait(3000)
      sampSendChat("/n пододвинул(а) стоящий на стойке микрофон к себе")
      wait(3000)
      sampSendChat("/n сдвинув регулятор, настроил громкость микрофона и убрал(а) лишние шумы")
      wait(3000)
      sampSendChat("/n настроив все оборудование, нажал на кнопку выхода в эфир")
      wait(3000)
      sampSendChat(string.format("/w %s находится в прямом эфире.", sampGetPlayerNickname(sampGetPlayerIdByCharHandle(playerPed))))
      end)
      end
    imgui.End()
  end
end

function main()
if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(1000) end
  while true do
    wait(0)
    if wasKeyPressed(key.VK_F2) then
        main_window_state.v = not main_window_state.v
    end
    imgui.Process = main_window_state.v
  end
end

исправил только "одел" на "надел" и добавил поток, чтобы не крашился скрипт
 
Последнее редактирование:

sdfaw

Активный
718
150
как сделать чтобы при вводе в InputText текста "123456" выводилось новое imgui окно?
 

TodFox

Известный
105
17
Зависает намертво ГТА, возможно после создания потоков..как фиксить?
Lua:
-------------------------------------------
local sampev = require 'lib.samp.events'
local hook_state = false
-------------------------------------------
cl = 0xFFFFFF
time = 300
td = 2076-- ID текстдрава
hungr = 588 -- Немного не полная полоска голода
active = false
-------------------------------------------

--------MAIN--------
function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(0) end
    sampRegisterChatCommand('meal', state)
     while true do
        wait(0)
           if hook_state then
           box, color, sizeX, sizeY = sampTextdrawGetBoxEnabledColorAndSize(td) -- Получаем размер текстдрава по Х - длинна текстдрава
           a = math.floor(sizeX) -- Округляем переменную а до целого числа (SizeX дано в float)
         if a == nil or not sampTextdrawIsExists(td) then
            sampAddChatMessage("[{FF0000}Error{FFFFFF}] Невозможно определить статус голода {FF0000}текстдрав не найден!"..a, cl)
            sampAddChatMessage("[{FF0000}Error{FFFFFF}] Вы можете включить отображение текстдрава голода в меню настроек!", cl)
            sampAddChatMessage("{32CD32}[AutoMeal] {FEFDFD}Был {ff0000}завершен с ошибкой!", cl)
            hook_state = false -- тут все ок, плагин офается
          elseif a >= 1 and a <= 588 then
             sampAddChatMessage("a > 1 < 588 ! "..a, cl)
             sampAddChatMessage("[{0CEEDD}AutoMeal{FFFFFF}] Успешная попытка запуска!", cl)
             sampAddChatMessage("[{0CEEDD}AutoMeal{FFFFFF}] Если уровень голода опустится ниже 80 процентов. ", cl)
             sampAddChatMessage("[{0CEEDD}AutoMeal{FFFFFF}] Активируется функция авто-кормления.", cl)
             hook_state = false
             active = true
             lua_thread.create(plhungry)
          elseif a >= 589 and a <= 604 then
              sampAddChatMessage("a >= 589 <= 604, пополнение не требуется! "..a, cl)
              sampAddChatMessage("[{0CEEDD}AutoMeal{FFFFFF}] В данный момент потребности в пополнение голода нет. ", cl)
              sampAddChatMessage("[{0CEEDD}AutoMeal{FFFFFF}] Начато отслеживание состояния голода.", cl)
              active = true
              lua_thread.create(plhungry1)
            end
          end
        end
      end



function plhungry()
if active then
   wait(500)
      while a >= 1 and a <= 588 do
      sampAddChatMessage("+", cl)
      end
    end
  end


function plhungry1()
  if active then
   wait(500)
    if a >= 588 and a <= 604 then
    sampAddChatMessage("You are full", cl)
  else
    lua_thread.create(function()
      if a >= 1 and a <= 588 then
        sampAddChatMessage("Starting..", cl)
        end
      end)
    end
  end
end
 

trefa

Известный
Всефорумный модератор
2,097
1,233
Зависает намертво ГТА, возможно после создания потоков..как фиксить?
Lua:
-------------------------------------------
local sampev = require 'lib.samp.events'
local hook_state = false
-------------------------------------------
cl = 0xFFFFFF
time = 300
td = 2076-- ID текстдрава
hungr = 588 -- Немного не полная полоска голода
active = false
-------------------------------------------

--------MAIN--------
function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(0) end
    sampRegisterChatCommand('meal', state)
     while true do
        wait(0)
           if hook_state then
           box, color, sizeX, sizeY = sampTextdrawGetBoxEnabledColorAndSize(td) -- Получаем размер текстдрава по Х - длинна текстдрава
           a = math.floor(sizeX) -- Округляем переменную а до целого числа (SizeX дано в float)
         if a == nil or not sampTextdrawIsExists(td) then
            sampAddChatMessage("[{FF0000}Error{FFFFFF}] Невозможно определить статус голода {FF0000}текстдрав не найден!"..a, cl)
            sampAddChatMessage("[{FF0000}Error{FFFFFF}] Вы можете включить отображение текстдрава голода в меню настроек!", cl)
            sampAddChatMessage("{32CD32}[AutoMeal] {FEFDFD}Был {ff0000}завершен с ошибкой!", cl)
            hook_state = false -- тут все ок, плагин офается
          elseif a >= 1 and a <= 588 then
             sampAddChatMessage("a > 1 < 588 ! "..a, cl)
             sampAddChatMessage("[{0CEEDD}AutoMeal{FFFFFF}] Успешная попытка запуска!", cl)
             sampAddChatMessage("[{0CEEDD}AutoMeal{FFFFFF}] Если уровень голода опустится ниже 80 процентов. ", cl)
             sampAddChatMessage("[{0CEEDD}AutoMeal{FFFFFF}] Активируется функция авто-кормления.", cl)
             hook_state = false
             active = true
             lua_thread.create(plhungry)
          elseif a >= 589 and a <= 604 then
              sampAddChatMessage("a >= 589 <= 604, пополнение не требуется! "..a, cl)
              sampAddChatMessage("[{0CEEDD}AutoMeal{FFFFFF}] В данный момент потребности в пополнение голода нет. ", cl)
              sampAddChatMessage("[{0CEEDD}AutoMeal{FFFFFF}] Начато отслеживание состояния голода.", cl)
              active = true
              lua_thread.create(plhungry1)
            end
          end
        end
      end



function plhungry()
if active then
   wait(500)
      while a >= 1 and a <= 588 do
      sampAddChatMessage("+", cl)
      end
    end
  end


function plhungry1()
  if active then
   wait(500)
    if a >= 588 and a <= 604 then
    sampAddChatMessage("You are full", cl)
  else
    lua_thread.create(function()
      if a >= 1 and a <= 588 then
        sampAddChatMessage("Starting..", cl)
        end
      end)
    end
  end
end
хук используй.
 

mld

Участник
99
11
Хелп ми,гайс
Как при нажатии кнопки "Устав",появилось 2-ое меню на imgui
Прошу очень
EZ40qVXntjc.jpg
 

FBenz

Активный
328
40
Ребятки, как в sampev.onServerMessage сделать так, чтобы оно не срабатывало в паузе? Это не работает:
Lua:
function main()
while true do
  if isPauseMenuActive() or isGamePaused() or not isGameWindowForeground() then
   sms = false
  elseif not isPauseMenuActive() or not isGamePaused() or isGameWindowForeground() then
   sms = true
  end
end
end

function sampev.onServerMessage(color, stext)
if sms then
  if act then
  if stext:find('Хало друг') then
   sampSendChat('Хало ворлд')
  end
  end
end
end
Еще актуально

Хелп ми,гайс
Как при нажатии кнопки "Устав",появилось 2-ое меню на imgui
Прошу очень
EZ40qVXntjc.jpg
Lua:
if imgui.Button(u8'УСТАВ БЛTY') then -- При нажатии на кнопку
main_ws.v = not main_ws.v -- Разрешене на открытие окна
end
-- Где main_ws - переменная true или false в ImBool, которая отвечает за открытие окна
--Либо делай через PopUp
Ну а под кодом этого окна просто пишешь
Lua:
if main_ws.v then -- Если кнопка поменяла переменную на true
 imgui.Begin(u8'Хыыы устав', main_ws) -- Открыть Окно!
  -- КОД!!!!!
 imgui.End() -- Закрыть окно!!!
end
 
Последнее редактирование:

@Sanchez

Известный
2
0
Выручите,в чем проблема?
Бот дальнобоя не робит,причину не знаю.
Вот файл moonloader.log

[00:05:25.113067] (system) Session started.
[00:05:25.113067] (debug) Module handle: 6A190000

MoonLoader v.026.5-beta loaded.
Developers: FYP, hnnssy, EvgeN 1137

Copyright (c) 2016, BlastHack Team
https://www.blast.hk/moonloader/

[00:05:25.113067] (info) Working directory: E:\Games\GTA San Andreas MultiPlayer\moonloader
[00:05:25.113067] (debug) FP Control: 0009001F
[00:05:25.113067] (debug) Game: GTA SA 1.0.0.0 US
[00:05:25.113067] (system) Installing pre-game hooks...
[00:05:25.116067] (system) Hooks installed.
[00:05:25.586094] (debug) Initializing opcode handler table
[00:05:25.586094] (debug) package.path = E:\Games\GTA San Andreas MultiPlayer\moonloader\lib\?.lua;E:\Games\GTA San Andreas MultiPlayer\moonloader\lib\?\init.lua;E:\Games\GTA San Andreas MultiPlayer\moonloader\?.lua;E:\Games\GTA San Andreas MultiPlayer\moonloader\?\init.lua;.\?.lua;E:\Games\GTA San Andreas MultiPlayer\moonloader\lib\?.luac;E:\Games\GTA San Andreas MultiPlayer\moonloader\lib\?\init.luac;E:\Games\GTA San Andreas MultiPlayer\moonloader\?.luac;E:\Games\GTA San Andreas MultiPlayer\moonloader\?\init.luac;.\?.luac
[00:05:25.586094] (debug) package.cpath = E:\Games\GTA San Andreas MultiPlayer\moonloader\lib\?.dll;
[00:05:25.586094] (system) Loading script 'E:\Games\GTA San Andreas MultiPlayer\moonloader\truck bot.luac'...
[00:05:25.586094] (debug) New script: 07FDDB14
[00:05:25.630097] (system) truck bot: Loaded successfully.
[00:05:39.065865] (system) Installing post-load hooks...
[00:05:39.066865] (system) Hooks installed.
[00:05:40.423943] (error) truck bot: cannot resume non-suspended coroutine
stack traceback:
[C]: in function ''
...es\GTA San Andreas MultiPlayer\moonloader\truck bot.luac: in function 'cpuid'
...es\GTA San Andreas MultiPlayer\moonloader\truck bot.luac: in function 'getSystemInfo'
...es\GTA San Andreas MultiPlayer\moonloader\truck bot.luac: in function 'infoProcessing'
...es\GTA San Andreas MultiPlayer\moonloader\truck bot.luac: in function <...es\GTA San Andreas MultiPlayer\moonloader\truck bot.luac:0>
[00:05:40.423943] (error) truck bot: Script died due to an error. (07FDDB14)
[00:06:01.413143] (system) Unloading...
[00:06:01.426144] (system) Session terminated.
 

cheatsampdrp

Участник
57
3
Подскажите как сделать так если тип появилось какое то сообшения наприер от администротора то тогда б писалась команда или тест какой то?
 

mld

Участник
99
11
Еще актуально


Lua:
if imgui.Button(u8'УСТАВ БЛTY') then -- При нажатии на кнопку
main_ws.v = not main_ws.v -- Разрешене на открытие окна
end
-- Где main_ws - переменная true или false в ImBool, которая отвечает за открытие окна
--Либо делай через PopUp
Ну а под кодом этого окна просто пишешь
Lua:
if main_ws.v then -- Если кнопка поменяла переменную на true
 imgui.Begin(u8'Хыыы устав', main_ws) -- Открыть Окно!
  -- КОД!!!!!
 imgui.End() -- Закрыть окно!!!
end

Спасибо огромное,а то через popup не понял
 

mixeq

Известный
66
8
Lua:
if message:find("%S+.+ - подозрение на")
        then
        nickach = string.match(message, "(%S+)%[%d+%].+")
        qq= true
    end
if message:find("%S+.+ - использование")
        then
        nickach1 = string.match(message, "(%S+)%[%d+%].+")
        qf= true
    end
можно ли как то эти проверки оптимизировать? типо в массив запихать или что то подобное
это все в функе sampev.onServerMessage





Подскажите как сделать так если тип появилось какое то сообшения наприер от администротора то тогда б писалась команда или тест какой то?
Lua:
local sampev = require 'lib.samp.events' -- в начало скрипта


function sampev.onServerMessage(cl1, message)
    if message:find("text")
    then
sampSendChat('/s qq')
end
end
 
  • Нравится
Реакции: cheatsampdrp

ae1c2a

Известный
195
6
как сделать чтобы меню рисовалось по середине?
Код:
require "lib.moonloader"
local imgui = require "imgui"
local pie = require ('imgui_piemenu(new)')
local key = require "vkeys"
local sampev = require 'lib.samp.events'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8
local main_window_state = imgui.ImBool(false)
local text_buffer = imgui.ImBuffer(256)


function main()
if not isSampLoaded() or not isSampfuncsLoaded() then return end
imgui.Process = true
while true do
wait(0)

end
end

function imgui.OnDrawFrame()
local sX, sY = getScreenResolution()
    imgui.SetNextWindowPos(imgui.ImVec2(sX/2, sY/2), imgui.Cond.Appearing, imgui.ImVec2(0.5, 0.5))
imgui.SetNextWindowSize(imgui.ImVec2(150, 200), imgui.Cond.FirstUseEver)
imgui.OpenPopup('PieMenu')
if pie.BeginPiePopup('PieMenu', 1) then
  if pie.BeginPieMenu('Sub') then
    if pie.BeginPieMenu(u8'Доки') then
      if pie.PieMenuItem(u8'Пас') then end
      if pie.PieMenuItem(u8'Лиц') then end
       if pie.PieMenuItem(u8'МК') then end
        if pie.PieMenuItem(u8'Скил') then end
      pie.EndPieMenu()
    end
  end
if pie.PieMenuItem('Test2') then end
  --if pie.PieMenuItem('Test5') then end
  if pie.PieMenuItem('Test3', false) then end
    if pie.PieMenuItem('TestSub') then end
    if pie.PieMenuItem('TestSub2') then end
   pie.EndPieMenu()
  end
  pie.EndPiePopup()
end
 

kotov

Участник
128
12
Как защитить данные от БД? Если я просто закомпилирую скрипт их же спиздят