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

MyRaXa229229

Участник
90
0
malformed number near '5.254.104.135'
if ip == 5.254.104.135 and port == 7777 then
sampSetCurrentDialogEditboxText("Здарова админы блу")
end
HELP
 

Firus20016

Участник
148
15
Привет всем. Посдскажите плез как определить самый максимальный ид текстдрава, который показан на экране?
 

|DEVIL|

Известный
359
273
Не могу понять что не так в функции
Код:
local font_flag = require('moonloader').font_flag
local my_font = renderCreateFont('Verdana', 100, font_flag.BOLD)

function main()
fast = 0
doremi = 0
while true do
                wait(0)
                local result, button, list, input = sampHasDialogRespond(11219) --вместо id - айди диалога
        if result then
                    print("Хоб")
                    inicfg.load(mainIni)
            if input:match(mainIni.kapcha.customcaptcha) then
                            mainIni.kapcha.nt = os.clock()
                            kpch = mainIni.kapcha.nt - mainIni.kapcha.tt
                            sampAddChatMessage(tag.."{19ff19}Вы ввели капчу за "..("%.2f"):format(kpch).." секунд!", -1)
                            doremi = 0
                            if fast == 1 then dialog() end
                        else
                             sampAddChatMessage(tag.."Вы неправильно ввели капчу!", 0xFF0000)
                             if fast == 1 then dialog() end
                    end
                end
                if doremi == 1 then
                     renderDrawBoxWithBorder(700, 300, 500, 140, 0xFF76A4AB, 7, 0xFF121624)
                     renderFontDrawText(my_font, mainIni.kapcha.customcaptcha, 715, 285, 0xFF121624)
                end
                
                function dialog()
            inicfg.load(mainIni)
            mainIni.kapcha.tt = os.clock()
            mainIni.kapcha.customcaptcha = math.random(10000,99999)
            inicfg.save(mainIni)
            doremi = 1
            sampShowDialog(76755, "{F0F000}Тренировка капчи", mainIni.kapcha.customcaptcha, "Тык", "Тык", 1)
        end
        
            function faster()
            if fast == 0 then
                fast = 1
                sampAddChatMessage("Включена быстрая практика!", 0xFF00FF)
             else
                 fast = 0
                 sampAddChatMessage("Быстрая практика выключена!", 0xFF0000)
             end
        end
 

ak4k1y

Участник
71
7
Почему вылезает ошибка когда хочу создать например такой файл?
f = io.open("moonloader\\config\\!logsConnecting\\" .. dat .. "\\" .. time .. ".txt","a")

Такой файл создаётся, но тот что сверху - нет:
f = io.open("moonloader\\config\\!logsConnecting\\" .. dat .. "\\.txt","a")

Что делать? Как создать?
 

Fott

Простреленный
3,442
2,300
Написал простенький скрипт что если здоровье меньше 80 то оно восстанавливается серверной командой (а сверху ещё броня), но вот закралась идея сделать этот скрипт, но срабатывание при спавне, но как, незнаю, поможете?
local health = GetCharHealth(playerPed)
if health < 80 then
sampSendChat('/arm')
 
  • Влюблен
Реакции: Double Tap Inside

Double Tap Inside

Известный
Проверенный
1,899
1,246
Написал простенький скрипт что если здоровье меньше 80 то оно восстанавливается серверной командой (а сверху ещё броня), но вот закралась идея сделать этот скрипт, но срабатывание при спавне, но как, незнаю, поможете?
local health = GetCharHealth(playerPed)
if health < 80 then
sampSendChat('/arm')
Ожидайте, сейчас дам код.

--- Upd

Lua:
require "sampfuncs"

hello = true
spawned = false

--155 RPC Parameters: UINT16 wPlayerID, INT32 score, UINT32 ping
function clear_player_scoreping(id)

    local BS = raknetNewBitStream()
    raknetBitStreamWriteInt32(BS, id)
    raknetBitStreamWriteInt32(BS, 0)
    raknetBitStreamWriteInt32(BS, 0)
   
    raknetEmulRpcReceiveBitStream(RPC_UPDATESCORESPINGSIPS, BS)  
    raknetDeleteBitStream(BS)
end

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(0) end
   
    while true do
        wait(0)
       
        local score
       
        local PlayerID_Bool, PlayerID = sampGetPlayerIdByCharHandle(PLAYER_PED)
       
        if PlayerID_Bool then
            score = sampGetPlayerScore(PlayerID)
        end
       
        if sampGetGamestate() ~= GAMESTATE_CONNECTED then
            spawned = false
           
            if PlayerID_Bool and (score > 0) then
                clear_player_scoreping(PlayerID)
            end
           
        elseif PlayerID_Bool and (score > 0) then -- GAMESTATE_CONNECTED
            spawned = true
           
        end
       
        if hello and spawned then
            hello = false
            sampAddChatMessage("• {FFC800}[Имя скрипта] {FFFFFF}Приветствие", 0xFFFFFF)
        end
    end
end

В переменной spawned будет лежать true или false. Теперь можешь делать проверку на спавн, ну типо
if spawned then
-- твой код
end

-- Upd 2
А если тебе надо один раз подлечицца при загрузке скрипта и нахождении в заспавненом состоянии, то можно это засунуть твой код там где я засунул приветсвие.
 
Последнее редактирование:

Fott

Простреленный
3,442
2,300
Ожидайте, сейчас дам код.

--- Upd

Lua:
require "sampfuncs"

hello = true
spawned = false

--155 RPC Parameters: UINT16 wPlayerID, INT32 score, UINT32 ping
function clear_player_scoreping(id)

    local BS = raknetNewBitStream()
    raknetBitStreamWriteInt32(BS, id)
    raknetBitStreamWriteInt32(BS, 0)
    raknetBitStreamWriteInt32(BS, 0)
 
    raknetEmulRpcReceiveBitStream(RPC_UPDATESCORESPINGSIPS, BS)
    raknetDeleteBitStream(BS)
end

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(0) end
 
    while true do
        wait(0)
     
        local score
     
        local PlayerID_Bool, PlayerID = sampGetPlayerIdByCharHandle(PLAYER_PED)
     
        if PlayerID_Bool then
            score = sampGetPlayerScore(PlayerID)
        end
     
        if sampGetGamestate() ~= GAMESTATE_CONNECTED then
            spawned = false
         
            if PlayerID_Bool and (score > 0) then
                clear_player_scoreping(PlayerID)
            end
         
        elseif PlayerID_Bool and (score > 0) then -- GAMESTATE_CONNECTED
            spawned = true
         
        end
     
        if hello and spawned then
            hello = false
            sampAddChatMessage("• {FFC800}[Имя скрипта] {FFFFFF}Приветствие", 0xFFFFFF)
        end
    end
end

В переменной spawned будет лежать true или false. Теперь можешь делать проверку на спавн, ну типо
if spawned then
-- твой код
end

-- Upd 2
А если тебе надо один раз подлечицца при загрузке скрипта и нахождении в заспавненом состоянии, то можно это засунуть твой код там где я засунул приветсвие.
Я плуг и не понял куда вставить что бы при каждом спавне восстанавливало, не понял шо и куда засунуть:(
Типа мне надо что бы при спавне прописывалась команда /arm,ну типа как sampSendChat('/arm') было
UPD: Ну да,когда вместо приветствия работает,но мне нужно при каждом спавне(
 

Double Tap Inside

Известный
Проверенный
1,899
1,246
Lua:
require "sampfuncs"

hello = true
spawned = false

--155 RPC Parameters: UINT16 wPlayerID, INT32 score, UINT32 ping
function clear_player_scoreping(id)

    local BS = raknetNewBitStream()
    raknetBitStreamWriteInt32(BS, id)
    raknetBitStreamWriteInt32(BS, 0)
    raknetBitStreamWriteInt32(BS, 0)

    raknetEmulRpcReceiveBitStream(RPC_UPDATESCORESPINGSIPS, BS)
    raknetDeleteBitStream(BS)
end

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

    while true do
        wait(0)
    
        local score
    
        local PlayerID_Bool, PlayerID = sampGetPlayerIdByCharHandle(PLAYER_PED)
    
        if PlayerID_Bool then
            score = sampGetPlayerScore(PlayerID)
        end
    
        if sampGetGamestate() ~= GAMESTATE_CONNECTED then
            spawned = false
            hello = true
        
            if PlayerID_Bool and (score > 0) then
                clear_player_scoreping(PlayerID)
            end
        
        elseif PlayerID_Bool and (score > 0) then -- GAMESTATE_CONNECTED
            spawned = true
        
        end
    
        if hello and spawned then
            hello = false
          
          
          
          
            -- Сюда
            sampSendChat("/arm")
            sampAddChatMessage("• {FFC800}[Имя скрипта] {FFFFFF}Приветствие", 0xFFFFFF)






        end
    end
end


--- Upd

Сделал, шобы после каждого подключения со спавном выполнялось.
 

Fott

Простреленный
3,442
2,300
Lua:
require "sampfuncs"

hello = true
spawned = false

--155 RPC Parameters: UINT16 wPlayerID, INT32 score, UINT32 ping
function clear_player_scoreping(id)

    local BS = raknetNewBitStream()
    raknetBitStreamWriteInt32(BS, id)
    raknetBitStreamWriteInt32(BS, 0)
    raknetBitStreamWriteInt32(BS, 0)

    raknetEmulRpcReceiveBitStream(RPC_UPDATESCORESPINGSIPS, BS)
    raknetDeleteBitStream(BS)
end

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

    while true do
        wait(0)
    
        local score
    
        local PlayerID_Bool, PlayerID = sampGetPlayerIdByCharHandle(PLAYER_PED)
    
        if PlayerID_Bool then
            score = sampGetPlayerScore(PlayerID)
        end
    
        if sampGetGamestate() ~= GAMESTATE_CONNECTED then
            spawned = false
            hello = true
        
            if PlayerID_Bool and (score > 0) then
                clear_player_scoreping(PlayerID)
            end
        
        elseif PlayerID_Bool and (score > 0) then -- GAMESTATE_CONNECTED
            spawned = true
        
        end
    
        if hello and spawned then
            hello = false
          
          
          
          
            -- Сюда
            sampSendChat("/arm")
            sampAddChatMessage("• {FFC800}[Имя скрипта] {FFFFFF}Приветствие", 0xFFFFFF)






        end
    end
end
Это что бы при запуске скрипта при заходе в игру,а что бы после каждого респавна прописывалось /arm как сделать?
 

Fott

Простреленный
3,442
2,300
Lua:
require "sampfuncs"

hello = true
spawned = false

--155 RPC Parameters: UINT16 wPlayerID, INT32 score, UINT32 ping
function clear_player_scoreping(id)

    local BS = raknetNewBitStream()
    raknetBitStreamWriteInt32(BS, id)
    raknetBitStreamWriteInt32(BS, 0)
    raknetBitStreamWriteInt32(BS, 0)

    raknetEmulRpcReceiveBitStream(RPC_UPDATESCORESPINGSIPS, BS)
    raknetDeleteBitStream(BS)
end

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

    while true do
        wait(0)
  
        local score
  
        local PlayerID_Bool, PlayerID = sampGetPlayerIdByCharHandle(PLAYER_PED)
  
        if PlayerID_Bool then
            score = sampGetPlayerScore(PlayerID)
        end
  
        if sampGetGamestate() ~= GAMESTATE_CONNECTED then
            spawned = false
            hello = true
      
            if PlayerID_Bool and (score > 0) then
                clear_player_scoreping(PlayerID)
            end
      
        elseif PlayerID_Bool and (score > 0) then -- GAMESTATE_CONNECTED
            spawned = true
      
        end
  
        if hello and spawned then
            hello = false
        
        
        
        
            -- Сюда
            sampSendChat("/arm")
            sampAddChatMessage("• {FFC800}[Имя скрипта] {FFFFFF}Приветствие", 0xFFFFFF)






        end
    end
end


--- Upd

Сделал, шобы после каждого подключения со спавном выполнялось.
Заебал я тебя наверное уже, но после смерти команда не вводиться
что такое каждый респавн?
Ну убивают меня например,по идее скрипта я должен заспавниться и скрипт должен ввести команду /arm
 

astynk

Известный
Проверенный
742
530
Почему вылезает ошибка когда хочу создать например такой файл?
f = io.open("moonloader\\config\\!logsConnecting\\" .. dat .. "\\" .. time .. ".txt","a")

Такой файл создаётся, но тот что сверху - нет:
f = io.open("moonloader\\config\\!logsConnecting\\" .. dat .. "\\.txt","a")

Что делать? Как создать?
Возможно, в переменных есть символы, запрещенные в названиях файлов (:?;/ - в этом духе). Их надо убирать через gsub()
Возможно, пытаешься создать файл в несуществующей папке. Папку надо предварительно создать через createDirectory()
 
  • Нравится
Реакции: darkjer