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

Nebekh1

Новичок
1
0
Здравствуйте! Не горите на меня, ломаю голову, не могу понять как сделать.
+сохранение положения
И кстати, что будет легче собрать:
1
/sms [id] [Текст]
ДействиеИдТекст
Кнопка "Отправить"Ид ввожу самТекст который необходимо отправить
Кнопка "Отправить"Ид ввожу самТекст который необходимо отправить
[TBODY] [/TBODY]
2
ДействиеТекст
Кнопка "Копировать"Сам текст который необходимо копировать.
Кнопка "Копировать"Сам текст который необходимо копировать.
[TBODY] [/TBODY]
 
Последнее редактирование:

AnWu

https://t.me/anwublog
Всефорумный модератор
4,771
5,377
В фотошопе, например. Либо в любой палитре в инете. юинт записывается как 0xYYYYYY - где за место YYYYYY цвет. 0xFA1954 например. но это не точно.
uint означает что это числовой тип с расшириным диапазоном... то что ты написал это 16тиричное число. но можно вписать и обычное.
0хFF = 255
 

Caicyo

Новичок
21
0
всё в туторе же понятно

Lua:
if not doesFileExist("moonloader\\config\\simple.ini") then
    local cfg =
    {
        main =
        {
            bEnable = nil,
            iValue = nil
        },
    };
    inicfg.save(cfg, 'simple.ini')
end

чтобы сохранить что-то:

local cfg = inicfg.load(nil, 'moonloader\\config\\simple.ini')
cfg.main.bEnable = 1
inicfg.save(cfg, 'simple.ini')

Да в том то и дело что как загружать, изменять и сохранять ini файл скрипта в директорию moonloader я прекрасно знаю.
Мне нужно загружать ini файл стороннего скрипта с совершенно иной директории, редачить его и сохранять!

Окей обьясню еще раз.
Мне нужно через lua скрипт открыть ini файл лежащий вот тут:
1.png

После чего заменить в нем вот эти два значения:
1.png

После чего сохранить этот же файл по этой же директории с этими измененными значениями. Говоря простым языком, перезаписать значения в файле посредством скрипта, так как будто это сделано через тот же notepad++ руками пользователя.

У меня прекрасно получилось сделать это опкодами клео, но moonloader вместо этих опкодов юзает этот inicfg который по моим попыткам, как в него путь до файла не втыкай, ищет его в moonloader/config/+ весь указанный путь.
А сохранить после изменения пытается туда же но еще и при этом изменяя ini файлу имя на имя скрипта.
Так вот как заставить эту заразу делать то что должно?

На сайте вики moonloader написанно что опкод 0AF1 через который я и проворачиваю эту перезапись на клео из moonloader выпилили с еще парой опкодов того же типа, заменив их на этот inicfg. Но я так понимаю самого функционала этих опкодов в inicfg не завезли?

- Заменены встроенным модулем inicfg (v.018-alpha):
0AF00AF0=4,%4d% = get_int_from_ini_file %1s% section %2s% key %3s%
0AF10AF1=4,write_int %1d% to_ini_file %2s% section %3s% key %4s%
0AF20AF2=4,%4d% = get_float_from_ini_file %1s% section %2s% key %3s%
0AF30AF3=4,write_float %1d% to_ini_file %2s% section %3s% key %4s%
0AF40AF4=4,%4d% = read_string_from_ini_file %1s% section %2s% key %3s%
0AF50AF5=4,write_string %1s% to_ini_file %2s% section %3s% key %4s%
[TBODY] [/TBODY]

В Cleo Просчет пути до ini файла идет начиная с корневой папки (Местоположение gta_sa.exe)
В IniCfg Просчет пути до ini файла, как я понял идет начиная с moonloader/config/

Вообщем я так понимаю закатать губу и продолжать юзать клео?
 
Последнее редактирование:

Musaigen

abobusnik
Проверенный
1,607
1,365
Да в том то и дело что как загружать, изменять и сохранять ini файл скрипта в директорию moonloader я прекрасно знаю.
Мне нужно загружать ini файл стороннего скрипта с совершенно иной директории, редачить его и сохранять!

Окей обьясню еще раз.
Мне нужно через lua скрипт открыть ini файл лежащий вот тут:
1.png

После чего заменить в нем вот эти два значения:
1.png

После чего сохранить этот же файл по этой же директории с этими измененными значениями. Говоря простым языком, перезаписать значения в файле посредством скрипта, так как будто это сделано через тот же notepad++ руками пользователя.

У меня прекрасно получилось сделать это опкодами клео, но moonloader вместо этих опкодов юзает этот inicfg который по моим попыткам, как в него путь до файла не втыкай, ищет его в moonloader/config/+ весь указанный путь.
А сохранить после изменения пытается туда же но еще и при этом изменяя ini файлу имя на имя скрипта.
Так вот как заставить эту заразу делать то что должно?

На сайте вики moonloader написанно что опкод 0AF1 через который я и проворачиваю эту перезапись на клео из moonloader выпилили с еще парой опкодов того же типа, заменив их на этот inicfg. Но я так понимаю самого функционала этих опкодов в inicfg не завезли?
В каком смысле функционал не завезли?
inicfg сам по себе выполняет эти опкоды. Он спокойно может считать туже строку.

Lua:
-- load
local cfg = inicfg.load(nil, getGameDirectory() .. '\\GTAVHud_by_DK22Pac\\mp\\V_HUD_by_DK22Pac.ini')



-- save
local data =
{
    CUSTOM_ABILITY =
    {
        bEnable = 1,
        tValue = 0
    }
}
inicfg.save(data, getGameDirectory() .. '\\GTAVHud_by_DK22Pac\\mp\\V_HUD_by_DK22Pac.ini')
 
  • Нравится
Реакции: Caicyo

Caicyo

Новичок
21
0
В каком смысле функционал не завезли?
inicfg сам по себе выполняет эти опкоды. Он спокойно может считать туже строку.

Lua:
-- load
local cfg = inicfg.load(nil, getGameDirectory() .. '\\GTAVHud_by_DK22Pac\\mp\\V_HUD_by_DK22Pac.ini')



-- save
local data =
{
    CUSTOM_ABILITY =
    {
        bEnable = 1,
        tValue = 0
    }
}
inicfg.save(data, getGameDirectory() .. '\\GTAVHud_by_DK22Pac\\mp\\V_HUD_by_DK22Pac.ini')

getGameDirectory() - Вот то что я и хотел увидеть, ибо не увидел это в гайде. Огромное тебе спасибо.
Моей главной проблемой и было то что я не знал как именно заставить inicfg читать из вне moonloader/config
...
Да все работает, немного не так как я ожидал, но тут уже проблема совсем к данному вопросу не относящаяся.

Еще один маленький вопросик насчет этого долбанного inicfg.

Вот скрипт с кодом из ответа на предыдущий мой вопрос:
Lua:
require "lib.moonloader"

local inicfg = require 'inicfg'
local font = renderCreateFont("Arial", 8, 5)
local cfg = inicfg.load(nil, getGameDirectory() .. '\\modloader\\SAMP_GTAV_Hud\\GTAVHud_by_DK22Pac\\mp\\V_HUD_by_DK22Pac.ini')

function main()
    while true do
        wait(0)
        x, y = getScreenResolution()
        renderFontDrawText(font, '' .. os.date("%X"), 112, y-200, 0xFFBEBEBE)
        if isCharInAnyCar(playerPed) then
            car = storeCarCharIsInNoSave(playerPed)
            carhp = getCarHealth(car)
            renderFontDrawText(font, string.format("Car health: %d", carhp), x-300, y-20, 0xFFBEBEBE)
            local data =
            {
                CUSTOM_ABILITY =
                {
                    bEnable = 1,
                    iValue = carhp
                }
            }
            inicfg.save(data, getGameDirectory() .. '\\modloader\\SAMP_GTAV_Hud\\GTAVHud_by_DK22Pac\\mp\\V_HUD_by_DK22Pac.ini')
        else
            local data =
            {
                CUSTOM_ABILITY =
                {
                    bEnable = 0,
                    iValue = 0
                }
            }
            inicfg.save(data, getGameDirectory() .. '\\modloader\\SAMP_GTAV_Hud\\GTAVHud_by_DK22Pac\\mp\\V_HUD_by_DK22Pac.ini')
        end
    end
end

Он прекрасно работает, но вот только он полностью вытирает из ini файла все кроме этих двух значений.
Как нибудь можно сделать так что бы он так не поступал?
Я конечно понимаю что можно описать весь остальной конфиг в local data но извините меня в этом конфиге 424 параметра, скрипт в рулон превратится при таком костыле.
 

biscuitt

Известный
186
14
Как записать какую то переменную в ини, чтобы потом она была в sampsendchat.
Пример:
В ини поставил слово "лох".
Затем при введении команды привет в чат будет выводиться "Привет, я лох".
 

[SA ARZ]

Известный
392
8
задержка 10 секунд не помогает на даймонде, сразу проверяет, как исправить? подскажите

Lua:
function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(1000) end
    math.randomseed(os.time())
    sampAddChatMessage("{FFFFFF}• {FF4F00}[NewsEditor]: {FFFFFF}Версия: "..thisScript().version.." {FF4F00}» /nhelp - список команд.", 0xFFFFFF)
    sampAddChatMessage("{FFFFFF}• {FF4F00}[NewsEditor]: {FFFFFF}Авторы данного скрипта {FF4F00}Family Galliardi", 0xFFFFFF)
    while not sampIsLocalPlayerSpawned() do wait(100) end
    _, myid = sampGetPlayerIdByCharHandle(PLAYER_PED)
    nick = sampGetPlayerNickname(myid)
    color = string.format("%06X", ARGBtoRGB(sampGetPlayerColor(myid)))
    wait(10000)
    if color == 'FF4F00' then
          sampSendChat('/stats')
          RegDialogID = 1
    elseif nick == "Isabella_Galliardi" then
        RangPlayer = "Директор"
        OrgPlayer = "Радоицентр СФ"
        SubOrgPlayer = "Новостная сеть"
        SexPlayersRP = "Женский"
        TagF = "Lite FM |"
        NumRangPlayer = 10
        NumPhoneNumber = 6336
        sampAddChatMessage("{FFFFFF}• {FF4F00}[NewsEditor]: {FFFFFF}Здравствуйте - {FF4F00}Isabella Galliardi{FFFFFF}, как у Вас дела?", 0xFFFFFF)
    else
        sampAddChatMessage("{FFFFFF}• {FF4F00}[NewsEditor]: {FFFFFF}Данный скрипт работает только для: {FF4F00}MassMedia", 0xFFFFFF)
        thisScript():unload()
    end
    lua_thread.create(function()
        sec, min, hour = 0, 0, 0
        while true do wait(0)
            wait(1000)
            sec = sec + 1
            if sec == 60 then
                sec = 0
                min = min + 1
            end
            if min == 60 then
                min = 0
                hour = hour + 1
            end
        end
    end)
    sampRegisterChatCommand('nhelp', tthelp)
    sampRegisterChatCommand('r', RadioR)
      sampRegisterChatCommand('rn', RadioRNonRP)
      sampRegisterChatCommand('f', RadioF)
      sampRegisterChatCommand('fn', RadioFNonRP)
      sampRegisterChatCommand('whois', WhoisPlayer)
    menuupdate()
    if updateScript == true then
        update()
        while update ~= false do wait(100) end
    end
    while true do wait(0)
        imgui.Process = Main_News.v or StatsPlayers.v or CommandsDostup.v or SetttingsMenu.v
        if menutrigger ~= nil then menu() menutrigger = nil end
        if not sampIsChatInputActive() and not sampIsDialogActive() and not sampIsScoreboardOpen() and not isSampfuncsConsoleActive() then
            if wasKeyPressed(123) then Main_News.v = not Main_News.v end
        end
    end
end
 

Aniki

🐰
Администратор
1,228
1,558
задержка 10 секунд не помогает на даймонде, сразу проверяет, как исправить? подскажите

Lua:
function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(1000) end
    math.randomseed(os.time())
    sampAddChatMessage("{FFFFFF}• {FF4F00}[NewsEditor]: {FFFFFF}Версия: "..thisScript().version.." {FF4F00}» /nhelp - список команд.", 0xFFFFFF)
    sampAddChatMessage("{FFFFFF}• {FF4F00}[NewsEditor]: {FFFFFF}Авторы данного скрипта {FF4F00}Family Galliardi", 0xFFFFFF)
    while not sampIsLocalPlayerSpawned() do wait(100) end
    _, myid = sampGetPlayerIdByCharHandle(PLAYER_PED)
    nick = sampGetPlayerNickname(myid)
    color = string.format("%06X", ARGBtoRGB(sampGetPlayerColor(myid)))
    wait(10000)
    if color == 'FF4F00' then
          sampSendChat('/stats')
          RegDialogID = 1
    elseif nick == "Isabella_Galliardi" then
        RangPlayer = "Директор"
        OrgPlayer = "Радоицентр СФ"
        SubOrgPlayer = "Новостная сеть"
        SexPlayersRP = "Женский"
        TagF = "Lite FM |"
        NumRangPlayer = 10
        NumPhoneNumber = 6336
        sampAddChatMessage("{FFFFFF}• {FF4F00}[NewsEditor]: {FFFFFF}Здравствуйте - {FF4F00}Isabella Galliardi{FFFFFF}, как у Вас дела?", 0xFFFFFF)
    else
        sampAddChatMessage("{FFFFFF}• {FF4F00}[NewsEditor]: {FFFFFF}Данный скрипт работает только для: {FF4F00}MassMedia", 0xFFFFFF)
        thisScript():unload()
    end
    lua_thread.create(function()
        sec, min, hour = 0, 0, 0
        while true do wait(0)
            wait(1000)
            sec = sec + 1
            if sec == 60 then
                sec = 0
                min = min + 1
            end
            if min == 60 then
                min = 0
                hour = hour + 1
            end
        end
    end)
    sampRegisterChatCommand('nhelp', tthelp)
    sampRegisterChatCommand('r', RadioR)
      sampRegisterChatCommand('rn', RadioRNonRP)
      sampRegisterChatCommand('f', RadioF)
      sampRegisterChatCommand('fn', RadioFNonRP)
      sampRegisterChatCommand('whois', WhoisPlayer)
    menuupdate()
    if updateScript == true then
        update()
        while update ~= false do wait(100) end
    end
    while true do wait(0)
        imgui.Process = Main_News.v or StatsPlayers.v or CommandsDostup.v or SetttingsMenu.v
        if menutrigger ~= nil then menu() menutrigger = nil end
        if not sampIsChatInputActive() and not sampIsDialogActive() and not sampIsScoreboardOpen() and not isSampfuncsConsoleActive() then
            if wasKeyPressed(123) then Main_News.v = not Main_News.v end
        end
    end
end
Наверное вместо ожидания в 10 сек стоит сделать проверку на sampIsLocalPlayerSpawned() ?
Как записать какую то переменную в ини, чтобы потом она была в sampsendchat.
Пример:
В ини поставил слово "лох".
Затем при введении команды привет в чат будет выводиться "Привет, я лох".
Lua:
local inicfg = require 'inicfg'

local ini = inicfg.load(nil, path) -- где path путь к твоему ини

-- обычный мейн
sampRegisterChatCommand('lox', lox)

-- закрываешь мейн

function lox()
  sampSendChat(ini.main.xd) -- ini выглядит как
--[main]
--xd=lox
end
 
  • Нравится
Реакции: biscuitt

[SA ARZ]

Известный
392
8

k0lenval

Известный
133
111
Всем привет! Может кто решил подобную проблему. Есть такая функция setVirtualKeyDown
Возможно ли с помощью нее отправить нажатие клавиши исключительно в то игровое окно, из которого она была вызвана? А то нажатие распространяется на всю винду, если использовать оконный режим игры и антипаузу.
 

Aniki

🐰
Администратор
1,228
1,558
Всем привет! Может кто решил подобную проблему. Есть такая функция setVirtualKeyDown
Возможно ли с помощью нее отправить нажатие клавиши исключительно в то игровое окно, из которого она была вызвана? А то нажатие распространяется на всю винду, если использовать оконный режим игры и антипаузу.
По возможности лучше заменить эту функу на setGameKeyState или setCharKeyDown, тогда будет работать в том окне, что и скрипт