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

#Northn

Pears Project — уже запущен!
Всефорумный модератор
2,643
2,493
Почему то не изменяет значение в самом файле конфига
Lua:
local fbitools =
{
  key1 =
  {
    tazerkey = 0x58,
    fastmenukey = 0x71,
    posX = 1748,
    posY = 1005,
    widehud = 290,
    male = true,
    tar = nil
  }
}
cfg = inicfg.load(nil, 'fbitools/config.ini')

function fstate()
  if cfg.key1.male == true then
    lua_thread.create(function()
      cfg.key1.male = false
      wait(100)
      inicfg.save(cfg, 'fbitools/config.ini')
      sampAddChatMessage('{9966CC}FBI Tools {ffffff}| Пол персонажа успешно изменен.', -1)
      sampAddChatMessage('{9966cc}FBI Tools {ffffff}| Скрипт автоматически перезагрузится.', -1)
      wait(500)
      thisScript():reload()
    end)
  else
    lua_thread.create(function()
      cfg.key1.male = true
      wait(100)
      inicfg.save(cfg, 'fbitools/config.ini')
      sampAddChatMessage('{9966CC}FBI Tools {ffffff}| Пол персонажа успешно изменен.', -1)
      sampAddChatMessage('{9966cc}FBI Tools {ffffff}| Скрипт автоматически перезагрузится.', -1)
      wait(500)
      thisScript():reload()
    end)
  end
end
 
  • Нравится
Реакции: tlwsn

f0rtrix

Известный
208
15
Почему не ловит ev.onServerMessage следующую строку:

[R] Сотрудник службы безопасности Lucio_Salieri[58]: Докладывает Lucio Salieri: Какой-то текст
я делаю так:
Lua:
   if color == 869033727 and msg:find("[R] Сотрудник службы безопасности(%s+)(.+)[(%d+)]:(%s)Докладывает(%s)(.+):(%s+)") then
       local test = msg:match('Докладывает(.*):(%s+)')
       dostup = test:match('(.+):')
       sampAddChatMessage(dostup, -1)
   end
Нужно получать текст, то есть имя, после "Докладывает(.+): "
Но оно не реагирует.
p.s если можно киньте подсказку для регулярок, путаюсь в них сильно
 

Aniki

🐰
Администратор
1,226
1,516
Почему не ловит ev.onServerMessage следующую строку:

[R] Сотрудник службы безопасности Lucio_Salieri[58]: Докладывает Lucio Salieri: Какой-то текст
я делаю так:
Lua:
   if color == 869033727 and msg:find("[R] Сотрудник службы безопасности(%s+)(.+)[(%d+)]:(%s)Докладывает(%s)(.+):(%s+)") then
       local test = msg:match('Докладывает(.*):(%s+)')
       dostup = test:match('(.+):')
       sampAddChatMessage(dostup, -1)
   end
Нужно получать текст, то есть имя, после "Докладывает(.+): "
Но оно не реагирует.
p.s если можно киньте подсказку для регулярок, путаюсь в них сильно
Заэкранируй квадратные скобки %[ и %]
 

#Northn

Pears Project — уже запущен!
Всефорумный модератор
2,643
2,493
Почему не ловит ev.onServerMessage следующую строку:

[R] Сотрудник службы безопасности Lucio_Salieri[58]: Докладывает Lucio Salieri: Какой-то текст
я делаю так:
Lua:
   if color == 869033727 and msg:find("[R] Сотрудник службы безопасности(%s+)(.+)[(%d+)]:(%s)Докладывает(%s)(.+):(%s+)") then
       local test = msg:match('Докладывает(.*):(%s+)')
       dostup = test:match('(.+):')
       sampAddChatMessage(dostup, -1)
   end
Нужно получать текст, то есть имя, после "Докладывает(.+): "
Но оно не реагирует.
p.s если можно киньте подсказку для регулярок, путаюсь в них сильно
Lua:
local sampev = require 'lib.samp.events'

function main()
    while not isSampAvailable() do wait(50) end
    wait(-1)
end

function sampev.onServerMessage(color, text)
    if text:find('%[R%] .+ %a+_%a+%[%d+%]: Докладывает .+') then
        local test = text:match('%[R%] .+ %a+_%a+%[%d+%]: Докладывает (.+): .+')
        sampAddChatMessage(test, -1)
    end
end
 

Parabellum

Новичок
5
0
Подскажите что сделал не так, в идеале должна получиться схема
Проверка на машину ==> Включение сирены ==> Проверка на сирену + стробоскоп
В итоге сирена включается, но выключить её не представляется возможным. Подскажите что нужно исправить :)

Lua:
local memory = require "memory"
local vehptr = nil
local key = require "vkeys"


function main()
  if not isSampfuncsLoaded() or not isSampLoaded() then return end
  while not isSampAvailable() do wait(100) end
  while true do
    wait(0)
    local car = storeCarCharIsInNoSave(PLAYER_PED)
    if isCharInAnyCar(PLAYER_PED) then
      if isKeyJustPressed(key.VK_F12) then
        local state = isCarSirenOn(car)
        if state == true then
          switchCarSiren(car, false)
        else
          switchCarSiren(car, true)
        end
      end
      if doesVehicleExist(car) then
        vehptr = getCarPointer(storeCarCharIsInNoSave(PLAYER_PED)) + 1440
        while isCarSirenOn(car) and isCharInAnyCar(PLAYER_PED) do
          callMethod(7086336, vehptr, 2, 0, 0, 0)
          callMethod(7086336, vehptr, 2, 0, 1, 1)
          wait(250)
          callMethod(7086336, vehptr, 2, 0, 0, 1)
          callMethod(7086336, vehptr, 2, 0, 1, 0)
          wait(250)
        end
        callMethod(7086336, vehptr, 2, 0, 0, 0)
        callMethod(7086336, vehptr, 2, 0, 1, 0)
      end
    end
  end
end
local memory = require "memory"
local vehptr = nil
local key = require "vkeys"


function main()
  if not isSampfuncsLoaded() or not isSampLoaded() then return end
  while not isSampAvailable() do wait(100) end
  while true do
    wait(0)
    local car = storeCarCharIsInNoSave(PLAYER_PED)
    if isCharInAnyCar(PLAYER_PED) then
      if isKeyJustPressed(key.VK_F12) then
        local state = isCarSirenOn(car)
        if state == true then
          switchCarSiren(car, false)
        else
          switchCarSiren(car, true)
        end
      end
      if doesVehicleExist(car) then
        vehptr = getCarPointer(storeCarCharIsInNoSave(PLAYER_PED)) + 1440
        while isCarSirenOn(car) and isCharInAnyCar(PLAYER_PED) do
          callMethod(7086336, vehptr, 2, 0, 0, 0)
          callMethod(7086336, vehptr, 2, 0, 1, 1)
          wait(250)
          callMethod(7086336, vehptr, 2, 0, 0, 1)
          callMethod(7086336, vehptr, 2, 0, 1, 0)
          wait(250)
        end
        callMethod(7086336, vehptr, 2, 0, 0, 0)
        callMethod(7086336, vehptr, 2, 0, 1, 0)
      end
    end
  end
end
 

#Northn

Pears Project — уже запущен!
Всефорумный модератор
2,643
2,493
Подскажите что сделал не так, в идеале должна получиться схема
Проверка на машину ==> Включение сирены ==> Проверка на сирену + стробоскоп
В итоге сирена включается, но выключить её не представляется возможным. Подскажите что нужно исправить :)

Lua:
local memory = require "memory"
local vehptr = nil
local key = require "vkeys"


function main()
  if not isSampfuncsLoaded() or not isSampLoaded() then return end
  while not isSampAvailable() do wait(100) end
  while true do
    wait(0)
    local car = storeCarCharIsInNoSave(PLAYER_PED)
    if isCharInAnyCar(PLAYER_PED) then
      if isKeyJustPressed(key.VK_F12) then
        local state = isCarSirenOn(car)
        if state == true then
          switchCarSiren(car, false)
        else
          switchCarSiren(car, true)
        end
      end
      if doesVehicleExist(car) then
        vehptr = getCarPointer(storeCarCharIsInNoSave(PLAYER_PED)) + 1440
        while isCarSirenOn(car) and isCharInAnyCar(PLAYER_PED) do
          callMethod(7086336, vehptr, 2, 0, 0, 0)
          callMethod(7086336, vehptr, 2, 0, 1, 1)
          wait(250)
          callMethod(7086336, vehptr, 2, 0, 0, 1)
          callMethod(7086336, vehptr, 2, 0, 1, 0)
          wait(250)
        end
        callMethod(7086336, vehptr, 2, 0, 0, 0)
        callMethod(7086336, vehptr, 2, 0, 1, 0)
      end
    end
  end
end
local memory = require "memory"
local vehptr = nil
local key = require "vkeys"


function main()
  if not isSampfuncsLoaded() or not isSampLoaded() then return end
  while not isSampAvailable() do wait(100) end
  while true do
    wait(0)
    local car = storeCarCharIsInNoSave(PLAYER_PED)
    if isCharInAnyCar(PLAYER_PED) then
      if isKeyJustPressed(key.VK_F12) then
        local state = isCarSirenOn(car)
        if state == true then
          switchCarSiren(car, false)
        else
          switchCarSiren(car, true)
        end
      end
      if doesVehicleExist(car) then
        vehptr = getCarPointer(storeCarCharIsInNoSave(PLAYER_PED)) + 1440
        while isCarSirenOn(car) and isCharInAnyCar(PLAYER_PED) do
          callMethod(7086336, vehptr, 2, 0, 0, 0)
          callMethod(7086336, vehptr, 2, 0, 1, 1)
          wait(250)
          callMethod(7086336, vehptr, 2, 0, 0, 1)
          callMethod(7086336, vehptr, 2, 0, 1, 0)
          wait(250)
        end
        callMethod(7086336, vehptr, 2, 0, 0, 0)
        callMethod(7086336, vehptr, 2, 0, 1, 0)
      end
    end
  end
end
В стробоскопе AppleThe всё подробно расписано, можешь прочитать.
Stroboscopes(http://athe.ml/scripts/g/stroboscopes)
 
  • Нравится
Реакции: hiplice и applethecandy

Frapsy

Известный
Проверенный
393
226
Кто подскажет, что с этим куском не так и почему он не говорит, что видит совпадения с файлом, когда они есть?
Есть файлик blacklist.txt, в нем в есть 4 ника, 2 с "_", и 2 таких же, но без "_".
Вставив print - понял, что цикл видит эти 4 строки, но они не проходят через проверку, как и text:find аналогично.

Lua:
if (dialogId == 436 and checking) then -- работа с диалогом истории ников для чекера               
        --title = title:match("Прошлые имена (.*)")
        text = text:gsub('{.-}', '')
        text = text:gsub('До %d+.%d+.%d+', '')
           
        for nicknames in text:gmatch('\t(.*)\n') do
            nicknames = nicknames:gsub("\t", "")
            nicknames = nicknames:gsub("\n", " ")

            local lolnick = nicknames:gsub("_"," ")
            for checkB in io.lines(getGameDirectory() .. "\\moonloader\\blacklist.txt") do
                if checkB == nicknames or checkB == lolnick then
                    sampAddChatMessage(string.format("[BLACK][%s]{DC143C} Найдена запись: %s", title, checkB), 0x9D6525)
                end
            end

            if (button2 ~= '') then
                sampSendDialogResponse(436, 1, -1, '')
                return false
            else
                checking = false
                sampSendDialogResponse(436, 1, -1, '')
                return false
            end
            checking = false
        end
 

Rental

Участник
60
1
Как в isKeyJustPressed(int key) "поставить" Escape? И как добавлять другие необычные клавиши, точнее как добовлять клавиши по VK кодам.

Как узнать находится ли локальный игрок за рулем автомобиля?
Ped ped = getDriverOfCar(Vehicle car) и сравнивай со своим PED

dxutAddStatic(dx, 3, "{87084a}Обращение с оружием. \n Если все так расказывать то тот не там и.", 00, 0, 600, 100) - Все нормально.
Если изменить цвет после заголовка "\n {000000} Если" то все плывет.
gta_sa%202018-06-19%2022-57-01-640.jpg
gta_sa%202018-06-19%2022-57-40-852.jpg

+ как назваются эти \n, \t?
 
Последнее редактирование модератором:

штейн

Известный
Проверенный
1,000
686
Lua:
    if text:find('хуй') then
        local posX, posY, posZ = GetCoordinates()
        local mfind, mposX, mposY, mposZ = SearchMarker(posX, posY, posZ, 150000.000000, false)
        if mfind then
            if autofinddd or find2 then
            --stadion ls - x = 2695.62 y = -1704.69 z = 10.74
                sampAddChatMessage(string.format('[ {800000}HitMan {ffffff}]: Позиция маркера: X = {800000}%.2f {ffffff}Y = {800000}%.2f {ffffff}Z = {800000}%.2f{ffffff}.', mposX, mposY, mposZ), -1)
                placeWaypoint(mposX, mposY, mposZ)
            end
        else
            sampAddChatMessage("[ {800000}HitMan {ffffff}]: Маркер не найден. Если Вы считаете, что это ошибка - сообщите создателю скрипта - [ {800000}/hvk {ffffff}].", -1)
        end
    end
есть у меня код который ищет маркеры и вроде всё норм, но иногда он находит маркер стадиона что мне вообще не нужно, у меня есть координаты этого стадиона, но когда я пытался сделать что-то типа if mposX ~= 2695.62 то он всё равно показывал мне стадион
 

checkdasound

Известный
Проверенный
963
407
Не подскажете адрес памяти, при помощи которого можно узнать значение своего ФПС? Где-то в этом разделе видел, но уже не помню где точно.

UPD уже нашел
Lua:
fFps = memory.getfloat([[ FPS ]]0xB7CB50, true)
 
Последнее редактирование:

#Northn

Pears Project — уже запущен!
Всефорумный модератор
2,643
2,493
Есть у меня код:

Lua:
local sampev = require 'lib.samp.events'
local imgui = require 'imgui'
local encoding = require 'encoding'
local wantedlist = imgui.ImBool(false)
encoding.default = 'CP1251'
u8 = encoding.UTF8

function main()
    while not isSampAvailable() do wait(50) end
    while not data do wait(0) end
    sust = {}
    lua_thread.create(function() while true do wait(0) takewd = true sampSendChat('/wanted') wait(120000) end end)
    while true do wait(0)
        for _, h in pairs(getAllChars()) do
            _ , id = sampGetPlayerIdByCharHandle(h)
            _ , m = sampGetPlayerIdByCharHandle(PLAYER_PED)
            if id ~= -1 and id ~= m and doesCharExist(h) and sampIsPlayerConnected(id) then
                local x, y, z = getCharCoordinates(h)
                local mx, my, mz = getCharCoordinates(PLAYER_PED)
                local dist = getDistanceBetweenCoords3d(mx, my, mz, x, y, z)
                local color = string.format("%06X", ARGBtoRGB(sampGetPlayerColor(id)))
                for _, l in pairs(sust) do
                    local nicksu, idsu = l:match('.+%{FFFFFF%} (%a+_%a+)%[(%d+)%].+')
                    local sulvl = l:match('.+Ур. Розыска:{ff0000} (%d+)')
                    if id == idsu then
                        print('k')
                    end
                end
            end
        end
    end
end

function sampev.onServerMessage(color, text)
    if text:find('%{0088ff%}Привет, %{FFFFFF%}.+Сегодня %{ffcc66%}%S+ г.') then data = true end
end

function sampev.onShowDialog(dialogId, style, title, button1, button2, text)
    if takewd ~= true and dialogId == 11436 then
        sust = {}
        for w in string.gmatch(text, "[^\r\n]+") do
            table.insert(sust, w)
        end
    elseif takewd and dialogId == 11436 then
        sust = {}
        for w in string.gmatch(text, "[^\r\n]+") do
            table.insert(sust, w)
        end
        takewd = false
        return false
    end
end

function ARGBtoRGB(color)
    local a = bit.band(bit.rshift(color, 24), 0xFF)
    local r = bit.band(bit.rshift(color, 16), 0xFF)
    local g = bit.band(bit.rshift(color, 8), 0xFF)
    local b = bit.band(color, 0xFF)
    local rgb = b
    rgb = bit.bor(rgb, bit.lshift(g, 8))
    rgb = bit.bor(rgb, bit.lshift(r, 16))
    return rgb
end

function sampev.onPlaySound()
    if takewd then return false end
end

Он должен проверять, есть ли игрок из цикла под определённым ID в зоне стрима, если да - print('k'), но он никогда не срабатывает, что бы я не делал.
Ники и ID он берёт из диалогового окна, скриншот ниже, я проверил, он из этого диалога всё правильно получает, не nil

Oul57ax.jpg


UPD: if id == idsu then заменил на if tonumber(id) == tonumber(idsu) then
 
Последнее редактирование:

CyberSuslik

Участник
88
12
Добрый вечер. Как с помощью функции function sampev.onServerMessage(color, text) взять нужный текст если он есть в чате и записать в переменную ? Спасибо