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

ШPEK

Известный
1,476
524
Код:
require "lib.moonloader"
local imgui = require 'imgui'
local notf = import 'imgui_notf.lua'
local ev = require("samp.events")
function main()
  if not isSampfuncsLoaded() or not isSampLoaded() then return end
  while not isSampAvailable() do wait(100) end
  while true do
    wait(0)
    if not sampIsChatInputActive() then
      if not sampIsDialogActive() then
        if isKeyJustPressed(VK_R) then
          sampSendChat("/healme")
          notf.addNotification("Уведомление\n\nВы использовали аптечку", 5)
        end
      end
    end
  end
end
function ev.onServerMessage(_, msg)
  if msg:gsub("{......}", ""):find("Вы взяли маску (/mask)") then
    sampSendChat("/mask")
    notf.addNotification("Уведомление\n\nВы надели маску", 5)
  end
end


Код:
require "lib.moonloader"
local imgui = require 'imgui'
local notf = import 'imgui_notf.lua'
local ev = require("samp.events")
function main()
  if not isSampfuncsLoaded() or not isSampLoaded() then return end
  while not isSampAvailable() do wait(100) end
  while true do
    wait(0)
    if not sampIsChatInputActive() then
      if not sampIsDialogActive() then
        if isKeyJustPressed(VK_R) then
          sampSendChat("/healme")
          notf.addNotification("Уведомление\n\nВы использовали аптечку", 5)
        end
      end
    end
  end
end
function ev.onServerMessage(_, msg)
  if msg:gsub("{......}", ""):find("Вы взяли маску (/mask)") then
    sampSendChat("/mask")
    notf.addNotification("Уведомление\n\nВы надели маску", 5)
  end
end
[code]
if msg:gsub("{......}", ""):find("Вы взяли маску %(/mask%)") then
 

SanyaVersus

Участник
65
1
Хелп, как сделать, чтобы в диалоге, выбирался определённый пункт
Кому не сложно сделайте пример
 

SanyaVersus

Участник
65
1
sampSendDialogResponse(id, 1, 0)
Нажимает 1 строку в диалоге
Это нажимает на 1 строку в открытом диалоге? Если нет, то как сделать в открытом.
Так-же вопрос, если после нажатия на 1 строку, открываеться новый. Как в нём выбрать строку?
 

MrCold

Активный
364
118
Помогите пожалуйста, как сделать флудерку клавиши по команде? Сам пытался, них*я не вышло.
 

ШPEK

Известный
1,476
524
Это нажимает на 1 строку в открытом диалоге? Если нет, то как сделать в открытом.
Так-же вопрос, если после нажатия на 1 строку, открываеться новый. Как в нём выбрать строку?
1. Это отправляет rpc
2.
Тут уже можно и логикой обойтись. Если у тебя нету логики, то программирование не твоё.

Помогите пожалуйста, как сделать флудерку клавиши по команде? Сам пытался, них*я не вышло.
Lua:
sampRegisterChatCommand("flood", function() lua_thread.create(function()
while true do 
  wait(0)
  setGameKeyState(клавиша, статус)
end
end)
end)
 

vituchaky

Новичок
7
0
Ребята, пытаюсь хоть что-то понять :) Код понимаю, а сам написать нифига немогу. В том же Hello World'e выдаёт ошибку, скиньте пожалуйста код Hello World'a :D
 

MrCold

Активный
364
118
В чём беда?
Lua:
local dob = false

function main()
    repeat wait(0) until isSampAvailable()
    sampRegisterChatCommand("dob", dob)
    while true do
        wait(0)
    end
end

function dob()
    if dob then
        dob = false
        sampAddChatMessage("Выключен", -1)
    else
        dob = true
        sampAddChatMessage("Включён", -1)
    end
end

function pizdec()
    local result, target = sampGetPlayerIdByCharHandle(playerHandle)
    if dob and result then
        local result, playerid = sampGetPlayerNickname(target)
        sampAddChatMessage("Ваш никнейм: "..playerid.."["..target.."]", -1)
    end
end

Ребята, пытаюсь хоть что-то понять :) Код понимаю, а сам написать нифига немогу. В том же Hello World'e выдаёт ошибку, скиньте пожалуйста код Hello World'a :D
По команде /hello пишет в чате "Hello World!"
Lua:
function main()
    repeat wait(0) until isSampAvailable()
    sampRegisterChatCommand("hello", hello)
    while true do
        wait(0)
    end
end

function hello()
    if hello then
        sampAddChatMessage("Hello World!", -1)
    end
end
 
  • Нравится
Реакции: vituchaky

vituchaky

Новичок
7
0
В чём беда?
Lua:
local dob = false

function main()
    repeat wait(0) until isSampAvailable()
    sampRegisterChatCommand("dob", dob)
    while true do
        wait(0)
    end
end

function dob()
    if dob then
        dob = false
        sampAddChatMessage("Выключен", -1)
    else
        dob = true
        sampAddChatMessage("Включён", -1)
    end
end

function pizdec()
    local result, target = sampGetPlayerIdByCharHandle(playerHandle)
    if dob and result then
        local result, playerid = sampGetPlayerNickname(target)
        sampAddChatMessage("Ваш никнейм: "..playerid.."["..target.."]", -1)
    end
end


По команде /hello пишет в чате "Hello World!"
Lua:
function main()
    repeat wait(0) until isSampAvailable()
    sampRegisterChatCommand("hello", hello)
    while true do
        wait(0)
    end
end

function hello()
    if hello then
        sampAddChatMessage("Hello World!", -1)
    end
end
Cпасибо :)
 

Lord

Новичок
236
42
Вывод информации вместо диалога нужно в чат. Сам пытался, но всё тщетно и выходит криво. Переделайте пожалуйста, немного. Был бы благодарен.

Lua:
script_name("IP Checker")
script_author("drags (blast.hk)")
script_version("Poxuy na Versiyu")
local cjson = require "cjson"
require 'lib.utf8data'
require 'lib.utf8'
local lanes = require('lanes').configure() -- в начало скрипта, конечно же
function async_http_request(method, url, args, resolve, reject)
    local request_lane = lanes.gen('*', {package = {path = package.path, cpath = package.cpath}}, function()
        local requests = require 'requests'
        local ok, result = pcall(requests.request, method, url, args)
        if ok then
            result.json, result.xml = nil, nil -- cannot be passed through a lane
            return true, result
        else
            return false, result -- return error
        end
    end)
    if not reject then reject = function() end end
    lua_thread.create(function()
        local lh = request_lane()
        while true do
            local status = lh.status
            if status == 'done' then
                local ok, result = lh[1], lh[2]
                if ok then resolve(result) else reject(result) end
                return
            elseif status == 'error' then
                return reject(lh[1])
            elseif status == 'killed' or status == 'cancelled' then
                return reject(status)
            end
            wait(0)
        end
    end)
end

function distance_cord(lat1, lon1, lat2, lon2)
    if lat1 == nil or lon1 == nil or lat2 == nil or lon2 == nil or lat1 == "" or lon1 == "" or lat2 == "" or lon2 == "" then
        return 0
    end
    local dlat = math.rad(lat2 - lat1)
    local dlon = math.rad(lon2 - lon1)
    local sin_dlat = math.sin(dlat / 2)
    local sin_dlon = math.sin(dlon / 2)
    local a = sin_dlat * sin_dlat + math.cos(math.rad(lat1)) * math.cos(math.rad(lat2)) * sin_dlon * sin_dlon
    local c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
    local d = 6378 * c
    return d
end

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(100) end
    sampRegisterChatCommand("chip", chip)
    wait(-1)
end
function chip(cl)
    ips = {}
    for word in string.gmatch(cl, "(%d+%p%d+%p%d+%p%d+)") do
        table.insert(ips, word)
    end
    if #ips > 0 then
    data_json = cjson.encode(ips)
    async_http_request('GET', string.format("http://mezerus.me/ip.php?ip=%s", data_json), nil,
        function(response)
            local rdata = cjson.decode(Utf8ToAnsi(response.text))
            local text2 = ""
            for i = 1, #rdata do
                if rdata[i]["lat"] ~= "" then
                local distances = distance_cord(rdata[1]["lat"], rdata[1]["lon"], rdata[i]["lat"], rdata[i]["lon"])
                text2 = text2 .. string.format("\n{FFF500}IP - {FF0400}%s\n{FFF500}Страна -{FF0400} %s\n{FFF500}Город -{FF0400} %s\n{FFF500}Провайдер -{FF0400} %s\n{FFF500}Растояние -{FF0400} %d  \n\n", rdata[i]["query"], rdata[i]["country"], rdata[i]["city"], rdata[i]["isp"], distances )
            end
        end
            showdialog("Информация о IP", text2)
    end)
end
end

function showdialog(name, rdata )
    sampShowDialog(math.random(1000), "{FF4444}"..name, rdata, "Закрыть", false, 0)
end
 

Petr_Sergeevich

Известный
Проверенный
707
296
В чём беда?
Lua:
local dob = false

function main()
    repeat wait(0) until isSampAvailable()
    sampRegisterChatCommand("dob", dob)
    while true do
        wait(0)
    end
end

function dob()
    if dob then
        dob = false
        sampAddChatMessage("Выключен", -1)
    else
        dob = true
        sampAddChatMessage("Включён", -1)
    end
end

function pizdec()
    local result, target = sampGetPlayerIdByCharHandle(playerHandle)
    if dob and result then
        local result, playerid = sampGetPlayerNickname(target)
        sampAddChatMessage("Ваш никнейм: "..playerid.."["..target.."]", -1)
    end
end

По команде /hello пишет в чате "Hello World!"
Lua:
function main()
    repeat wait(0) until isSampAvailable()
    sampRegisterChatCommand("hello", hello)
    while true do
        wait(0)
    end
end

function hello()
    if hello then
        sampAddChatMessage("Hello World!", -1)
    end
end

Вот ответ на твой вопрос:

Lua:
local dob = false
function main()
    repeat wait(0) until isSampAvailable()
    sampRegisterChatCommand("dob", function()
        dob = not dob
        sampAddChatMessage(dob and "Включен" or "Выключен", -1)
    end)
    while true do
        wait(0)
        local result, handle = getCharPlayerIsTargeting(PLAYER_HANDLE)
        if result and dob then
            sampAddChatMessage("Ваш никнейм: "..sampGetPlayerNickname(select(2, sampGetPlayerIdByCharHandle(handle))), -1)
        end
    end
end

Не нужно делать 0-ую задержку в беск. цикле, если ты его не используешь, лучше так.
Lua:
function main()
    while not isSampAvailable() do wait(0) end
    sampRegisterChatCommand("cmd", function() sampAddChatMessage("Hi") end)
    wait(-1)
end
 
Последнее редактирование:

MrCold

Активный
364
118
Вот ответ на твой вопрос:

Lua:
local dob = false
function main()
    repeat wait(0) until isSampAvailable()
    sampRegisterChatCommand("dob", function()
        dob = not dob
        sampAddChatMessage(dob and "Включен" or "Выключен", -1)
    end)
    while true do
        wait(0)
        local result, playerID = sampGetPlayerIdByCharHandle(PLAYER_HANDLE)
        if result and dob then
            sampAddChatMessage("Ваш никнейм: "..select(2, sampGetPlayerNickname(playerID)), -1)
        end
    end
end

Не нужно делать 0-ую задержку в беск. цикле, если ты его не используешь, лучше так.
Lua:
function main()
    while not isSampAvailable() do wait(0) end
    sampRegisterChatCommand("cmd", function() sampAddChatMessage("Hi") end)
    wait(-1)
end
А что это такое ты написал? Можешь расшифровать??)) Я новичкок
Lua:
("Ваш никнейм: "..select(2, sampGetPlayerNickname(playerID)), -1)

1. Это отправляет rpc
2.
Тут уже можно и логикой обойтись. Если у тебя нету логики, то программирование не твоё.


Lua:
sampRegisterChatCommand("flood", function() lua_thread.create(function()
while true do
  wait(0)
  setGameKeyState(клавиша, статус)
end
end)
end)
Не робит. Нужно чтоб при активации оно флудило кнопкой "Огонь", но чот нихуя.
Lua:
local flood = false
function main()
    repeat wait(0) until isSampAvailable()
    sampRegisterChatCommand("flood", function()
        flood = not flood
        sampAddChatMessage(flood and "Включен" or "Выключен", -1)
    end)
    while true do
        wait(0)
              setGameKeyState(4, 255)
            end
        end
 

Fomikus

Известный
Проверенный
472
341
Lua:
function getserial()
   local ffi = require("ffi")
   ffi.cdef[[
   int __stdcall GetVolumeInformationA(
   const char* lpRootPathName,
   char* lpVolumeNameBuffer,
   uint32_t nVolumeNameSize,
   uint32_t* lpVolumeSerialNumber,
   uint32_t* lpMaximumComponentLength,
   uint32_t* lpFileSystemFlags,
   char* lpFileSystemNameBuffer,
   uint32_t nFileSystemNameSize
   );
   ]]
   local serial = ffi.new("unsigned long[1]", 0)
   ffi.C.GetVolumeInformationA(nil, nil, 0, serial, nil, nil, nil, 0)
   return serial[0]
end
Как достать серийник и задать переменную? (Вывести в чат/Лог)
 

trefa

Известный
Всефорумный модератор
2,097
1,231
Lua:
function getserial()
   local ffi = require("ffi")
   ffi.cdef[[
   int __stdcall GetVolumeInformationA(
   const char* lpRootPathName,
   char* lpVolumeNameBuffer,
   uint32_t nVolumeNameSize,
   uint32_t* lpVolumeSerialNumber,
   uint32_t* lpMaximumComponentLength,
   uint32_t* lpFileSystemFlags,
   char* lpFileSystemNameBuffer,
   uint32_t nFileSystemNameSize
   );
   ]]
   local serial = ffi.new("unsigned long[1]", 0)
   ffi.C.GetVolumeInformationA(nil, nil, 0, serial, nil, nil, nil, 0)
   return serial[0]
end
Как достать серийник и задать переменную? (Вывести в чат/Лог)
Lua:
print(getserial())