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

chapo

чопа сребдс // @moujeek
Модератор
8,860
11,544
как подключить скрипт к сайту, брать от туда изображения и рендерить их в имгуи


спс, но у меня в скрипте дохуища чаилдов, врятли это будет работать как мне надо)
так сделай для этих чайлдов другой цвет
 

ioSeoGio

Известный
30
33
Есть функция sampev.onCreate3DText, позволяющая получить инфу о созданном 3dtext, есть ли такая же функция для поиска 3dtext'ов в окружении игрока?

Есть функция sampev.onCreate3DText, позволяющая получить инфу о созданном 3dtext, есть ли такая же функция для поиска 3dtext'ов в окружении игрока?
Нашел, https://www.blast.hk/threads/13380/post-119168
 

Gorskin

♥ Love Lua ♥
Проверенный
1,331
1,161
Почему в консоль выводятся какие-то каракули?
Lua:
if id == 36 then
        id = raknetBitStreamReadInt16(bs)
        color = raknetBitStreamReadInt32(bs)
        position = {x = raknetBitStreamReadFloat(bs), y = raknetBitStreamReadFloat(bs), z = raknetBitStreamReadFloat(bs)}
        distance = raknetBitStreamReadFloat(bs)
        testLOS = raknetBitStreamReadBool(bs)
        pid = raknetBitStreamReadInt16(bs)
        vid = raknetBitStreamReadInt16(bs)
        text = raknetBitStreamDecodeString(bs, 4096)
        print(text)
    end
 

YarikVL

Известный
Проверенный
4,767
1,820
как можно получить кординаты игрока и вывести их в renderfontdrawtext?
Этим узнаешь координаты:
local X, Y, Z = getCharCoordinates(PLAYER_PED)
А этим выводишь: https://wiki.blast.hk/moonloader/lua/renderFontDrawText
Если тебе не свои координаты нужно то вот пример по ид: https://www.blast.hk/threads/67124/
 
  • Нравится
Реакции: shibaTaidjy

Gorskin

♥ Love Lua ♥
Проверенный
1,331
1,161
Почему в консоль выводятся какие-то каракули?
Lua:
if id == 36 then
        id = raknetBitStreamReadInt16(bs)
        color = raknetBitStreamReadInt32(bs)
        position = {x = raknetBitStreamReadFloat(bs), y = raknetBitStreamReadFloat(bs), z = raknetBitStreamReadFloat(bs)}
        distance = raknetBitStreamReadFloat(bs)
        testLOS = raknetBitStreamReadBool(bs)
        pid = raknetBitStreamReadInt16(bs)
        vid = raknetBitStreamReadInt16(bs)
        text = raknetBitStreamDecodeString(bs, 4096)
        print(text)
    end
А как можно поменять для себя дистанцию 3д текста без samp.lua Знаю что через samp.lua очень просто, достаточно подменить ретурн. А как быть без него? Эмулировать получение битстрима? (Хотя по моему глупо получать битстрим, и тут же его эмулировать дабы изменить что-то)
 

imring

Ride the Lightning
Всефорумный модератор
2,362
2,545
А как можно поменять для себя дистанцию 3д текста без samp.lua Знаю что через samp.lua очень просто, достаточно подменить ретурн. А как быть без него? Эмулировать получение битстрима? (Хотя по моему глупо получать битстрим, и тут же его эмулировать дабы изменить что-то)
перемещаешься к тому значению (через raknetBitStreamSetWriteOffset) и перезаписываешь (raknetBitStreamWriteFloat)
 
  • Нравится
  • Влюблен
Реакции: YarikVL и Gorskin

deveeh

Новичок
25
6
Хочу сделать смс рассылку на родине. Можете пожалуйста подсказать, как задетектить цифры набора номера, желательно конечно их и сравнить))
1661241556778.png
 

KOLBASKA@

Участник
35
0
кароче ребят хотел написать свой первый скрипт на луа флуд alt enter и через 100 мили сек ескейп
вот посмотрите что тут не так.
Lua:
require 'lib.moonloader'

local enable = false

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

    sampAddChatMessage("{E5336B}[Alt + Enter]: {FFFFFF}. Enable.")

    sampRegisterChatCommand("ae", function()
        if enable == false then
            enable = true
            sampAddChatMessage("[Alt + Enter]: {8B00FF} Alt Enter WORK. PRESS  {E5336B} M {8B00FF}, STOP-WORK!", 0xE5336B)
        end
    end)
    while true do
        wait(0)
        if enable == true and not sampIsChatInputActive() and not sampIsDialogActive() then
            setVirtualKeyDown(18, true)
            wait(100)
            setVirtualKeyDown(18, false)
            wait(100)
            setVirtualKeyDown(13, true)
            wait(100)
            setVirtualKeyDown(13, false)
        wait(500)
        setVirtualKeyDown(VK_ESCAPE, true)
            if isKeyJustPressed(VK_M) then
                sampAddChatMessage("[Alt + Enter]:{8B00FF}STOP HUINYA!", 0xE5336B)
                enable = false
       end
        end
    end
end
 
Последнее редактирование:

PanSeek

t.me/dailypanseek
Всефорумный модератор
908
1,774
кароче ребят хотел написать свой первый скрипт на луа флуд alt enter и через 100 мили сек ескейп
вот посмотрите что тут не так.
Lua:
require 'lib.moonloader'

local enable = false

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

    sampAddChatMessage("{E5336B}[Alt + Enter]: {FFFFFF}. Enable.")

    sampRegisterChatCommand("ae", function()
        if enable == false then
            enable = true
            sampAddChatMessage("[Alt + Enter]: {8B00FF} Alt Enter WORK. PRESS  {E5336B} M {8B00FF}, STOP-WORK!", 0xE5336B)
        end
    end)
    while true do
        wait(0)
        if enable == true and not sampIsChatInputActive() and not sampIsDialogActive() then
            setVirtualKeyDown(18, true)
            wait(100)
            setVirtualKeyDown(18, false)
            wait(100)
            setVirtualKeyDown(13, true)
            wait(100)
            setVirtualKeyDown(13, false)
        wait(500)
        setVirtualKeyDown(VK_ESCAPE, true)
            if isKeyJustPressed(VK_M) then
                sampAddChatMessage("[Alt + Enter]:{8B00FF}STOP HUINYA!", 0xE5336B)
                enable = false
       end
        end
    end
end
типа такого?
Lua:
script_properties("work-in-pause")
local enable = false

local function msg(text)
    sampAddChatMessage("[Alt + Enter]: {FFFFFF}" .. text, 0xE5336B)
end

local function VirtKey(key)
    setVirtualKeyDown(key, true)
    wait(15)
    setVirtualKeyDown(key, false)
end

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

    msg("Loaded")

    sampRegisterChatCommand("ae", function()
        if not enable then
            enable = true
            msg("{8B00FF} Alt Enter WORK. PRESS  {E5336B} M {8B00FF}, STOP-WORK!")
        end
    end)

    while true do wait(0)
        if enable and not sampIsChatInputActive() and not sampIsDialogActive() then
            VirtKey(18)
            VirtKey(13)
            wait(100)
            VirtKey(0x1B)
            if isKeyJustPressed(0x4D) then
                msg("{8B00FF}STOP HUINYA!")
                enable = false
            end
        end
    end
end
 
  • Нравится
Реакции: KOLBASKA@

rynt

Новичок
1
0
Вопрос по регулярке Lua

Мне нужно выловить номер стоящей машины, в чат это высвечивается так:

Номер: О644ТЕ
Буквы русские

Пробую так: "Номер: %(%D(%d+)%(%D+)%)", не получается

Я пока совсем зеленый, что я делаю не так.
 

TheUnity

Известный
113
39
Есть такой скрипт, добавляет запятые в строки с деньгами
split the money:
require 'lib.moonloader'
local sampevcheck, sampev = pcall(require, "lib.samp.events")

function comma_value(n)
    local left,num,right = string.match(n,'^([^%d]*%d)(%d*)(.-)$')
    return left..(num:reverse():gsub('(%d%d%d)','%1,'):reverse())..right
end

function separator(text)
    if text:find("$") then
        for S in string.gmatch(text, "%$%d+") do
            local replace = comma_value(S)
            text = string.gsub(text, S, replace)
        end
        for S in string.gmatch(text, "%d+%$") do
            S = string.sub(S, 0, #S-1)
            local replace = comma_value(S)
            text = string.gsub(text, S, replace)
        end
    end
    return text
end

function sampev.onShowDialog(dialogId, style, title, button1, button2, text)
    text = separator(text)
    title = separator(title)
    return {dialogId, style, title, button1, button2, text}
end

function sampev.onServerMessage(color, text)
    text = separator(text)
    return {color, text}
end

function sampev.onCreate3DText(id, color, position, distance, testLOS, attachedPlayerId, attachedVehicleId, text)
    text = separator(text)
    return {id, color, position, distance, testLOS, attachedPlayerId, attachedVehicleId, text}
end

function sampev.onTextDrawSetString(id, text)
    text = separator(text)
    return {id, text}
end
смотрел, вроде все верно, в replace правильный текст, но вот string.gsub как то криво заменяет подстроку.
Посмотреть вложение 163179
а должно быть 70,000,000
12,500,000

Проверял в онлайн компиляторе - все ок.
UP
 

Hero_0_

Участник
37
4
Помогите. Если менять значение в инпут тексте то всё норм, сохраняется, но при перезагрузке скрипта третий четвёртый и пятый слот возвращают значение второго, не понимаю что не так


ХЕЛП МИ:
script_author('HeroIAm') -- не меняй или гей лох чмо урод

require "lib.moonloader"
local vkeys = require 'vkeys'
local sampev = require 'lib.samp.events'
local inicfg = require 'inicfg'
local vkeys = require 'vkeys'
local sw, sh = getScreenResolution()
local imgui = require 'imgui'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8
local cfg = inicfg.load({
    Settings = {
        call1 = "f",
        call2 = "f",
        call3 = "f",
        call4 = "f",
        call5 = "f"
    }
}, 'auto_callsign')
local main_window = imgui.ImBool(false)

combo = imgui.ImInt(0)
arr = {"first", "second", "third"}
ch_m = imgui.ImInt(1)
call1 = imgui.ImBuffer(146)
call2 = imgui.ImBuffer(146)
call3 = imgui.ImBuffer(146)
call4 = imgui.ImBuffer(146)
call5 = imgui.ImBuffer(146)

call1.v = cfg.Settings.call1
call2.v = cfg.Settings.call2
call3.v = cfg.Settings.call2
call4.v = cfg.Settings.call2
call5.v = cfg.Settings.call2

function showmenu()
    main_window.v = not main_window.v
    imgui.Process = main_window.v
end
function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(100) end
    if not doesFileExist(getWorkingDirectory()..'/config/auto_callsign.ini') then
        inicfg.save(cfg, 'auto_callsign.ini')
    end
    sampAddChatMessage('{0099ff}[Auto Callsign] {ffffff}Скрипт загружен [BETA]. Автор: HeroIAm.', 0x0099ff)
    theme()
    sampRegisterChatCommand('setc', setc)
    sampRegisterChatCommand('ac', showmenu)
end

function imgui.OnDrawFrame()
    if main_window.v then
        imgui.SetNextWindowPos(imgui.ImVec2(sw / 2, sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        imgui.SetNextWindowSize(imgui.ImVec2(400, 280), imgui.Cond.FirstUseEver)
        imgui.Begin("Auto Callsign by Hero", main_window, imgui.WindowFlags.NoResize)
        imgui.SetCursorPosX(125)
        imgui.Text(u8"Режимы")
        imgui.RadioButton(u8"Авто",ch_m, 1)
        imgui.SameLine()
        imgui.SetCursorPosX(250)
        imgui.RadioButton(u8"Ручной",ch_m, 2)
        if ch_m.v == 2 then
            imgui.Text(u8"В ручном режиме используйте /setc для установки callsign")
        
        else
            imgui.Text("")
        end
        imgui.Combo(u8"Слоты", combo, u8"Первый\0Второй\0Третий\0Четвёртый\0Пятый\0\0", 146)
        if combo.v == 0 then
            imgui.InputText('##1', call1)
        end
        if combo.v == 1 then
            imgui.InputText('##2', call2)
        end
        if combo.v == 2 then
            imgui.InputText('##3', call3)
        end
        if combo.v == 3 then
            imgui.InputText('##4', call4)
        end
        if combo.v == 4 then
            imgui.InputText('##5', call5)
        end
        if imgui.Button(u8"Сохранить") then
            cfg.Settings.call1 = call1.v
            cfg.Settings.call2 = call2.v
            cfg.Settings.call3 = call3.v
            cfg.Settings.call4 = call4.v
            cfg.Settings.call5 = call5.v
            inicfg.save(cfg, 'auto_callsign.ini')
            imgui.SameLine()
            imgui.Text(u8"Настройки успешно сохранены.")
            
        else
            imgui.SameLine()
            imgui.Text("")
        end
        imgui.Text("Combo: "..combo.v)
        imgui.End()
    end
end

local sampev = require 'lib.samp.events'

function sampev.onSendEnterVehicle(vehId, pass)
    lua_thread.create(function()
        if ch_m.v == 1 then
            if not pass then
                lua_thread.create(function()
                    while not isCharInAnyCar(PLAYER_PED) do wait(0) end
                    setc()
                end)
            end
        end
    end)
end
function setc()
    lua_thread.create(function()
        if combo.v == 0 then
            sampSendChat('/callsign')
            wait(30)
            sampSendDialogResponse(32700, 1, nil, u8:decode(" " ..call1.v))
        end
        if combo.v == 1 then
            sampSendChat('/callsign')
            wait(30)
            sampSendDialogResponse(32700, 1, nil, u8:decode(" " ..call2.v))
        end
        if combo.v == 2 then
            sampSendChat('/callsign')
            wait(30)
            sampSendDialogResponse(32700, 1, nil, u8:decode(" " ..call3.v))
        end
        if combo.v == 3 then
            sampSendChat('/callsign')
            wait(30)
            sampSendDialogResponse(32700, 1, nil, u8:decode(" " ..call4.v))
        end
        if combo.v == 4 then
            sampSendChat('/callsign')
            wait(30)
            sampSendDialogResponse(32700, 1, nil, u8:decode(" " ..call5.v))
        end
    end)
end

function theme()
    imgui.SwitchContext()
    local style  = imgui.GetStyle()
    local colors = style.Colors
    local clr    = imgui.Col
    local ImVec4 = imgui.ImVec4
    local ImVec2 = imgui.ImVec2

    style.WindowPadding       = ImVec2(10, 10)
    style.WindowRounding      = 16
    style.ChildWindowRounding = 2
    style.FramePadding        = ImVec2(5, 4)
    style.FrameRounding       = 2
    style.ItemSpacing         = ImVec2(4, 4)
    style.TouchExtraPadding   = ImVec2(0, 0)
    style.IndentSpacing       = 21
    style.ScrollbarSize       = 15
    style.ScrollbarRounding   = 0
    style.GrabMinSize         = 10
    style.GrabRounding        = 1
    style.WindowTitleAlign    = ImVec2(0.5, 0.5)
    style.ButtonTextAlign     = ImVec2(0.5, 0.5)

    colors[clr.Text]                 = ImVec4(1.00, 1.00, 1.00, 1.00)
    colors[clr.TextDisabled]         = ImVec4(0.73, 0.75, 0.74, 1.00)
    colors[clr.WindowBg]             = ImVec4(0.00, 0.00, 0.00, 0.80)
    colors[clr.ChildWindowBg]        = ImVec4(0.00, 0.00, 0.00, 0.00)
    colors[clr.PopupBg]              = ImVec4(0.08, 0.08, 0.08, 0.94)
    colors[clr.Border]               = ImVec4(0.00, 0.60, 1.00, 0.00)
    colors[clr.BorderShadow]         = ImVec4(0.00, 0.00, 0.00, 0.00)
    colors[clr.FrameBg]              = ImVec4(0.00, 0.17, 0.28, 1.00)
    colors[clr.FrameBgHovered]       = ImVec4(0.00, 0.60, 1.00, 0.5)
    colors[clr.FrameBgActive]        = ImVec4(0.00, 0.60, 1.00, 0.7)
    colors[clr.TitleBg]              = ImVec4(0.00, 0.60, 1.00, 0.33)
    colors[clr.TitleBgActive]        = ImVec4(0.00, 0.60, 1.00, 0.33)
    colors[clr.TitleBgCollapsed]     = ImVec4(0.00, 0.60, 1.00, 0.33)
    colors[clr.MenuBarBg]            = ImVec4(0.34, 0.16, 0.16, 1.00)
    colors[clr.ScrollbarBg]          = ImVec4(0.02, 0.02, 0.02, 0.53)
    colors[clr.ScrollbarGrab]        = ImVec4(0.31, 0.31, 0.31, 1.00)
    colors[clr.ScrollbarGrabHovered] = ImVec4(0.41, 0.41, 0.41, 1.00)
    colors[clr.ScrollbarGrabActive]  = ImVec4(0.51, 0.51, 0.51, 1.00)
    colors[clr.ComboBg]              = ImVec4(0.20, 0.20, 0.20, 0.99)
    colors[clr.CheckMark]            = ImVec4(1.00, 1.00, 1.00, 1.00)
    colors[clr.SliderGrab]           = ImVec4(0.00, 0.60, 1.00, 1.00)
    colors[clr.SliderGrabActive]     = ImVec4(0.84, 0.66, 0.66, 1.00)
    colors[clr.Button]               = ImVec4(0.00, 0.60, 1.00, 0.33)
    colors[clr.ButtonHovered]        = ImVec4(0.71, 0.39, 0.39, 0.65)
    colors[clr.ButtonActive]         = ImVec4(0.20, 0.20, 0.20, 0.50)
    colors[clr.Header]               = ImVec4(0.71, 0.39, 0.39, 0.54)
    colors[clr.HeaderHovered]        = ImVec4(0.84, 0.66, 0.66, 0.65)
    colors[clr.HeaderActive]         = ImVec4(0.84, 0.66, 0.66, 0.00)
    colors[clr.Separator]            = ImVec4(0.43, 0.43, 0.50, 0.50)
    colors[clr.SeparatorHovered]     = ImVec4(0.71, 0.39, 0.39, 0.54)
    colors[clr.SeparatorActive]      = ImVec4(0.71, 0.39, 0.39, 0.54)
    colors[clr.ResizeGrip]           = ImVec4(0.71, 0.39, 0.39, 0.54)
    colors[clr.ResizeGripHovered]    = ImVec4(0.84, 0.66, 0.66, 0.66)
    colors[clr.ResizeGripActive]     = ImVec4(0.84, 0.66, 0.66, 0.66)
    colors[clr.CloseButton]          = ImVec4(0.41, 0.41, 0.41, 1.00)
    colors[clr.CloseButtonHovered]   = ImVec4(0.98, 0.39, 0.36, 1.00)
    colors[clr.CloseButtonActive]    = ImVec4(0.98, 0.39, 0.36, 1.00)
    colors[clr.PlotLines]            = ImVec4(0.61, 0.61, 0.61, 1.00)
    colors[clr.PlotLinesHovered]     = ImVec4(1.00, 0.43, 0.35, 1.00)
    colors[clr.PlotHistogram]        = ImVec4(0.90, 0.70, 0.00, 1.00)
    colors[clr.PlotHistogramHovered] = ImVec4(1.00, 0.60, 0.00, 1.00)
    colors[clr.TextSelectedBg]       = ImVec4(0.26, 0.59, 0.98, 0.35)
    colors[clr.ModalWindowDarkening] = ImVec4(0.80, 0.80, 0.80, 0.35)
end