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

rayprod

Участник
96
1
Ребята, помогите пожалуйста, Вот код.
Когда активируют "Проверка на AFK w/o ESC", просто открывается чат и ничего больше. Как фиксануть? Дабы при активации вводилась команда эта, сразу скажу. Команда не серверная.
Lua:
       if show_recon_window.v then
    imgui.SetNextWindowPos(imgui.ImVec2(imgui.GetIO().DisplaySize.x / 2, imgui.GetIO().DisplaySize.y / 1.04), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    imgui.SetNextWindowSize(imgui.ImVec2(700, 100), imgui.Cond.FirstUseEver)
    imgui.Begin('Recon Helper', show_recon_window, imgui.WindowFlags.NoResize + imgui.WindowFlags.NoCollapse + imgui.WindowFlags.NoMove)
        if imgui.Button(u8'Проверка на AFK w/o ESC') then
            sampSendChat('/afk ' ..plid); sampSetChatInputEnabled(true)
        end
        imgui.SameLine()
        if imgui.Button(u8'Stats') then
            sampSendChat('/stats ' ..plid); sampSetChatInputEnabled(true)
        end
    imgui.End()
    end
end

function samp.onSendCommand(cmd)
    local reId = string.match(cmd, "^%/sp (%d+)")
    if reId then
        lastCmdRe = tonumber(reId)
    end
end

function samp.onTogglePlayerSpectating(state)
    show_recon_window.v = state
end

function samp.onSpectatePlayer(playerid, camtype)
    plid = playerid
end

function samp.onSpectateVehicle(carid, camtype)
    if plid ~= lastCmdRe and lastCmdRe >= 0 then
        plid = lastCmdRe
    end
end
 

f0Re3t

Poh production
Друг
876
808
Ребята, помогите пожалуйста, Вот код.
Когда активируют "Проверка на AFK w/o ESC", просто открывается чат и ничего больше. Как фиксануть? Дабы при активации вводилась команда эта, сразу скажу. Команда не серверная.
Lua:
       if show_recon_window.v then
    imgui.SetNextWindowPos(imgui.ImVec2(imgui.GetIO().DisplaySize.x / 2, imgui.GetIO().DisplaySize.y / 1.04), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    imgui.SetNextWindowSize(imgui.ImVec2(700, 100), imgui.Cond.FirstUseEver)
    imgui.Begin('Recon Helper', show_recon_window, imgui.WindowFlags.NoResize + imgui.WindowFlags.NoCollapse + imgui.WindowFlags.NoMove)
        if imgui.Button(u8'Проверка на AFK w/o ESC') then
            sampSendChat('/afk ' ..plid); sampSetChatInputEnabled(true)
        end
        imgui.SameLine()
        if imgui.Button(u8'Stats') then
            sampSendChat('/stats ' ..plid); sampSetChatInputEnabled(true)
        end
    imgui.End()
    end
end

function samp.onSendCommand(cmd)
    local reId = string.match(cmd, "^%/sp (%d+)")
    if reId then
        lastCmdRe = tonumber(reId)
    end
end

function samp.onTogglePlayerSpectating(state)
    show_recon_window.v = state
end

function samp.onSpectatePlayer(playerid, camtype)
    plid = playerid
end

function samp.onSpectateVehicle(carid, camtype)
    if plid ~= lastCmdRe and lastCmdRe >= 0 then
        plid = lastCmdRe
    end
end
sampProcessChatInput
 

rayprod

Участник
96
1
Ребята у меня тут проблемка, я хочу что-бы скрипт активировался на Space только когда я в слежке. Как это сделать, вот код:
Lua:
       --это main--
    function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(100) end
    sampRegisterChatCommand('admhelp', function() main_window_state.v = not main_window_state.v end)
    sampAddChatMessage("{FFF5EE}[Admin{00BFFF}Helper{FFF5EE}] {FFFAFA}Скрипт успешно был загружен. Версия скрипта: {00FFFF}1.7", -1)
    sampAddChatMessage("{FFF5EE}[Admin{00BFFF}Helper{FFF5EE}] {FFFAFA}Активировать подсказки: {00F0FF}/admhelp", -1)
    while true do
    wait(0)
    imgui.Process = main_window_state.v or show_recon_window.v
    --это рекон--
    if show_recon_window.v then
    imgui.SetNextWindowPos(imgui.ImVec2(imgui.GetIO().DisplaySize.x / 2, imgui.GetIO().DisplaySize.y / 1.07), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    imgui.SetNextWindowSize(imgui.ImVec2(718, 104), imgui.Cond.FirstUseEver)
    imgui.Begin('Recon Helper', show_recon_window, imgui.WindowFlags.NoResize + imgui.WindowFlags.NoCollapse + imgui.WindowFlags.NoMove)
        if imgui.Button(u8'Проверка на AFK w/o ESC') then
            sampProcessChatInput('/afk ' ..plid);
        end
        imgui.SameLine()
        if imgui.Button(u8'Stats') then
            sampSendChat('/stats ' ..plid); sampSetChatInputEnabled(true)
        end
    imgui.End()
    end
end

function samp.onSendCommand(cmd)
    local reId = string.match(cmd, "^%/sp (%d+)")
    if reId then
        lastCmdRe = tonumber(reId)
    end
end

function samp.onTogglePlayerSpectating(state)
    show_recon_window.v = state
end

function samp.onSpectatePlayer(playerid, camtype)
    plid = playerid
end

function samp.onSpectateVehicle(carid, camtype)
    if plid ~= lastCmdRe and lastCmdRe >= 0 then
        plid = lastCmdRe
    end
end
 

AterEX

Участник
44
1
Привет, есть у кого пример/исходник кода, где есть ивент onCreate3DText?
 

Bredd Lane

Известный
423
349
Ребята у меня тут проблемка, я хочу что-бы скрипт активировался на Space только когда я в слежке. Как это сделать, вот код:
Lua:
       --это main--
    function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(100) end
    sampRegisterChatCommand('admhelp', function() main_window_state.v = not main_window_state.v end)
    sampAddChatMessage("{FFF5EE}[Admin{00BFFF}Helper{FFF5EE}] {FFFAFA}Скрипт успешно был загружен. Версия скрипта: {00FFFF}1.7", -1)
    sampAddChatMessage("{FFF5EE}[Admin{00BFFF}Helper{FFF5EE}] {FFFAFA}Активировать подсказки: {00F0FF}/admhelp", -1)
    while true do
    wait(0)
    imgui.Process = main_window_state.v or show_recon_window.v
    --это рекон--
    if show_recon_window.v then
    imgui.SetNextWindowPos(imgui.ImVec2(imgui.GetIO().DisplaySize.x / 2, imgui.GetIO().DisplaySize.y / 1.07), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    imgui.SetNextWindowSize(imgui.ImVec2(718, 104), imgui.Cond.FirstUseEver)
    imgui.Begin('Recon Helper', show_recon_window, imgui.WindowFlags.NoResize + imgui.WindowFlags.NoCollapse + imgui.WindowFlags.NoMove)
        if imgui.Button(u8'Проверка на AFK w/o ESC') then
            sampProcessChatInput('/afk ' ..plid);
        end
        imgui.SameLine()
        if imgui.Button(u8'Stats') then
            sampSendChat('/stats ' ..plid); sampSetChatInputEnabled(true)
        end
    imgui.End()
    end
end

function samp.onSendCommand(cmd)
    local reId = string.match(cmd, "^%/sp (%d+)")
    if reId then
        lastCmdRe = tonumber(reId)
    end
end

function samp.onTogglePlayerSpectating(state)
    show_recon_window.v = state
end

function samp.onSpectatePlayer(playerid, camtype)
    plid = playerid
end

function samp.onSpectateVehicle(carid, camtype)
    if plid ~= lastCmdRe and lastCmdRe >= 0 then
        plid = lastCmdRe
    end
end
Ну, установи проверку на текстдрав рекона, если он имеется (sampTextdrawIsExists(id td) или же хукай onShowTextDraw(id, data))
 
  • Нравится
Реакции: rayprod

rayprod

Участник
96
1
Доброго времени суток, делаю скрипт, но вот столкнулся с такой проблемкой.
Хотел сделать статистику активаций команд. Пример.
Ввёл команду /ans и она где-то вписалась, как введенных команд /ans - 1. И этот счетчик будет меняться после того как команда будет вводиться.
Можете подсказать как это делается?
Кто то показывал что можно так, но как это сделать,не имею понятие.
Вот тот код, которые предлагал человек.​
Lua:
local ev = require "lib.samp.events"

local counts = {
    ["cmd"] = 0,
    ["ans"] = 0,
    ["rep"] = 0
}

function main()
    while true do
        wait(0)
    end
end

function ev.onSendChat(message)
    if message:find("%/") then
        local cmd, _, _ = message:match("%/(.+) (.+) (.+)")
        for i in ipairs(counts) do
            if i == cmd then
                counts.cmd = counts.cmd
            end
        end
    end
end
 

Anton Nixon

Активный
474
48
почему inicfg.save/load по дефолту работают с папкой config, как правильно указывать путь, чтобы вместо папки config использовалась moonloader?
 

Anton Nixon

Активный
474
48
почему крашит игру, если выбрать любой из этих пунктов
2020-06-21 13-59-01-270.png

Код этого окна и его элементов:
Lua:
if settings.v then -- настройки
        imgui.SetNextWindowPos(imgui.ImVec2(sw / 2, sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        imgui.SetNextWindowSize(imgui.ImVec2(650, 400), imgui.Cond.FirstUseEver)
        imgui.Begin(u8'Настройки', settings, imgui.WindowFlags.NoResize)
        imgui.Columns(2, _, false)
        imgui.SetColumnWidth(-1, 160)
        imgui.BeginChild('left panel', imgui.ImVec2(150, 0), true)
            if not selected then selected = 0 end
            for i = 1, #SeleList do
                if imgui.Selectable(u8(SeleList[i]),SeleListBool[i]) then selected = i end
            end
        imgui.EndChild()
        imgui.NextColumn()
        if selected == 1 then    -- общие настройки
            if imgui.Checkbox(u8"Отображать ХП и броню в цифрах", number) then
                MAIN.main.number = number.v
            end
            if imgui.Checkbox(u8"Выдавать временный скин", tempskin) then imgui.SameLine(); ShowHelpMarker("Какая-то подсказка")
                MAIN.main.tempskin = tempskin.v
            end
            if imgui.Checkbox(u8"Отображать текущие координаты", coords) then
                MAIN.main.coords = coords.v
            end
            if imgui.Checkbox(u8"Отслеживать админ. команды из админ. чата", admin_cmd) then imgui.SameLine(); ShowHelpMarker("Какая-то подсказка")
                MAIN.main.admin_cmd = admin_cmd.v
            end
            if imgui.Checkbox(u8"Автоматически назначать временным лидером", templeaders) then imgui.SameLine(); ShowHelpMarker("Какая-то подсказка")
                MAIN.main.templeaders = templeaders.v
            end
            if imgui.Checkbox(u8"Проверять обновления при входе в игру", check_update) then
                MAIN.main.check_update = check_update.v
            end
            if imgui.Checkbox(u8"Отображать собственный ID", self_id) then
                MAIN.main.self_id = self_id.v
            end
            if imgui.Checkbox(u8"Отображать панель с информацией об игроке", player_info) then
                MAIN.main.player_info = player_info.v
            end
            if imgui.Checkbox(u8"Отображать график пинга игрока", ping) then
                MAIN.main.ping = ping.v
            end
            if imgui.Checkbox(u8"Автоввод пароля при входе", auto_login) then imgui.SameLine(); ShowHelpMarker("Автоматический ввод пароля при входе в игру.")
                MAIN.main.auto_login = auto_login.v
            end
            if auto_login then
                imgui.PushItemWidth(220)
                imgui.InputText(u8"##pass", password, imgui.InputTextFlags.Password + imgui.InputTextFlags.EnterReturnsTrue + imgui.InputTextFlags.CharsNoBlank); imgui.SameLine(); imgui.Text(u8"Введите пароль")
                if imgui.Button(u8"Сохранить") then
                    MAIN.main.password = password.v
                end
                imgui.SameLine()
                if imgui.Button(u8"Удалить") then
                    password = ""
                    MAIN.main.password = ""
                end
            end
        elseif selected == 2 then    -- таблица наказаний
            imgui.Checkbox(u8"Выдавать наказания при входе в игру", punish_start); imgui.SameLine(); ShowHelpMarker("Какая-то подсказка")
            MAIN.punish.number = punish_start.v
        elseif selected == 3 then -- горячие клавиши
            imgui.BeginChild('preright panel', imgui.ImVec2(170, 330), true)
            imgui.Text(u8"Доступные клавиши:")
            imgui.Separator()
                if not beginchild then beginchild = 0 end
                for i = 1, #HotKeys do
                    if imgui.Selectable(u8(HotKeys[i]), HotKeysBool[i]) then beginchild = i end
                end
            imgui.EndChild()
            imgui.SameLine()
            imgui.BeginChild('right panel', imgui.ImVec2(0, 330), true)
                if beginchild == 1 then -- главное меню
                    imgui.Text(u8"Текущая клавиша: "..keys.bind_mm)
                    imgui.NewLine()
                    imgui.Text(u8"Назначить новую клавишу")
                        imgui.Button(u8"Одна клавиша")
                        imgui.Button(u8"Две клавиши")
                elseif beginchild == 2 then -- реконнект
                    imgui.Text(u8"Текущая клавиша: "..keys.bind_rec)
                    imgui.NewLine()
                    imgui.Text(u8"Назначить новую клавишу")
                        imgui.Button(u8"Одна клавиша")
                        imgui.Button(u8"Две клавиши")
                elseif beginchild == 3 then -- вх
                    imgui.Text(u8"Текущая клавиша: "..keys.bind_wh)
                    imgui.NewLine()
                    imgui.Text(u8"Назначить новую клавишу")
                        imgui.Button(u8"Одна клавиша")
                        imgui.Button(u8"Две клавиши")
                elseif beginchild == 4 then -- гм
                    imgui.Text(u8"Текущая клавиша: "..keys.bind_gm)
                    imgui.NewLine()
                    imgui.Text(u8"Назначить новую клавишу")
                        imgui.Button(u8"Одна клавиша")
                        imgui.Button(u8"Две клавиши")
                elseif beginchild == 5 then -- аирбрейк
                    imgui.Text(u8"Текущая клавиша: "..keys.bind_air)
                    imgui.NewLine()
                    imgui.Text(u8"Назначить новую клавишу")
                        imgui.Button(u8"Одна клавиша")
                        imgui.Button(u8"Две клавиши")
                elseif beginchild == 6 then -- подтверждение
                    imgui.Text(u8"Текущая клавиша: "..keys.bind_ok)
                    imgui.NewLine()
                    imgui.Text(u8"Назначить новую клавишу")
                        imgui.Button(u8"Одна клавиша")
                        imgui.Button(u8"Две клавиши")
                elseif beginchild == 7 then -- отмета
                    imgui.Text(u8"Текущая клавиша: "..keys.bind_cancel)
                    imgui.NewLine()
                    imgui.Text(u8"Назначить новую клавишу")
                        imgui.Button(u8"Одна клавиша")
                        imgui.Button(u8"Две клавиши")
                elseif beginchild == 8 then -- меню быстрых команд
                    imgui.Text(u8"Текущая клавиша: "..keys.bind_fastcmd)
                    imgui.NewLine()
                    imgui.Text(u8"Назначить новую клавишу")
                        imgui.Button(u8"Одна клавиша")
                        imgui.Button(u8"Две клавиши")
                elseif beginchild == 9 then -- предыдущийй ID
                    imgui.Text(u8"Текущая клавиша: "..keys.bind_backid)
                    imgui.NewLine()
                    imgui.Text(u8"Назначить новую клавишу")
                        imgui.Button(u8"Одна клавиша")
                        imgui.Button(u8"Две клавиши")
                elseif beginchild == 10 then -- следующий ID
                    imgui.Text(u8"Текущая клавиша: "..keys.bind_nextid)
                    imgui.NewLine()
                    imgui.Text(u8"Назначить новую клавишу")
                        imgui.Button(u8"Одна клавиша")
                        imgui.Button(u8"Две клавиши")
                end

                if beginchild ~= 0 then
                    clearHotKeysBool(beginchild)
                end
            imgui.EndChild()
            imgui.Button(u8"Сбросить все"); imgui.SameLine(); ShowHelpMarker("Какая-то подсказка")
        elseif selected == 4 then -- чекер
            imgui.Checkbox(u8"Отображать список лидеров онлайн", leader_online)
            MAIN.checker.leader_online = leader_online.v
            imgui.Checkbox(u8"Отображать список друзей онлайн", friend_online)
            MAIN.checker.friend_online = friend_online.v
            imgui.Checkbox(u8"Отображать список администраторов онлайн", admin_online)
            MAIN.checker.admin_online = admin_online.v
            imgui.Checkbox(u8"Автоматически обновлять список администраторов", admin_upd)
            MAIN.checker.admin_upd = admin_upd.v
            imgui.Checkbox(u8"Активировать счетчик предупреждений на захвате", warn_capture)
            MAIN.checker.warn_capture = warn_capture.v
            imgui.Text(u8"Изменить положение панели и чекера:")
            if imgui.Button(u8"Изменить") then
                -- code
            end
            imgui.SameLine()
            if imgui.Button(u8"Сбросить") then
            end
        elseif selected == 5 then -- читы
            imgui.Checkbox(u8"Отображать состояние читов", cheat_info)
            MAIN.cheats.cheat_info = cheat_info.v
            imgui.Checkbox(u8"Активировать GodMode при запуске игры", gm_start)
            MAIN.cheats.gm_start = gm_start.v
            imgui.Checkbox(u8"Активировать WallHack при запуске игры", wh_start)
            MAIN.cheats.wh_start = wh_start.v
            imgui.Checkbox(u8"Отображать информацию о транспорте", car_info)
            MAIN.cheats.car_info = car_info.v
            imgui.Checkbox(u8"Отображать ID игроков в маске и из МВД", show_ids)
            MAIN.cheats.show_ids = show_ids.v
        elseif selected == 6 then -- чат
            imgui.Checkbox(u8"Переносить строку при отправке сообщения", devide_messages)
            MAIN.chat.devide_messages = devide_messages.v
            imgui.Checkbox(u8"Отправлять уведомления в админ. чат", notf_chat)
            MAIN.chat.notf_chat = notf_chat.v
            imgui.Checkbox(u8"Отключать телефон при входе в игру", off_phone)
            MAIN.chat.off_phone = off_phone.v
            imgui.Checkbox(u8"Отображать ID игрока рядом с ником", chat_id)
            MAIN.chat.chat_id = chat_id.v
            imgui.Checkbox(u8"Указывать ник администратора в объявлении", ad_admnick)
            MAIN.chat.ad_admnick = ad_admnick.v
            imgui.NewLine()
            imgui.Text(u8"Уведомлять при:")
            imgui.Checkbox(u8"Обновление строчки античита на оружие", anticheat_gun)
            MAIN.chat.anticheat_gun = anticheat_gun.v
            imgui.Checkbox(u8"Обновление строчки античита на быстр. перемещение", anticheat_fastmove)
            MAIN.chat.anticheat_fastmove = anticheat_fastmove.v
            imgui.NewLine()
            imgui.Text(u8"Режим указания ника администратора при выдаче наказания по его просьбе:")
            if imgui.RadioButton(u8"В наказании", check_radio, 1) then imgui.SameLine(); ShowHelpMarker("Какая-то подсказка")
                MAIN.chat.check_radio = check_radio.v
            end
            if imgui.RadioButton(u8"В сообщении (/ans)", check_radio, 2) then imgui.SameLine(); ShowHelpMarker("Какая-то подсказка")
                MAIN.chat.check_radio = check_radio.v
            end
            if imgui.RadioButton(u8"Не указывать", check_radio, 3) then imgui.SameLine(); ShowHelpMarker("Какая-то подсказка")
                MAIN.chat.check_radio = check_radio.v
            end
        end

        if selected ~= 0 then
            clearSeleListBool(selected)
        end
        imgui.End()
    end
 

Fott

Простреленный
3,448
2,314
Знает кто как пофиксить чтобы небыло 100500 цифр? Появляется такое не всегда, а иногда, но раздражает(скрин 1) На втором то как должно быть
Screenshot_1.png
Screenshot_2.png
 

neverlane

t.me/neverlane00
Друг
1,002
1,142
  • Нравится
Реакции: Fott

samartinell1

Участник
98
14
1592740973674.png

почему-то не работает в этом блоке wait(), с ним скрипт крашится. Блок находится в самом низу, под беск циклом и его вроде как ничто не задевает, что можно сделать? wait прямо жизненно необходим, так как строк 5 тупо в 1 мгновение бросаются и часто сообщения либо не замечают либо антифлуд срабатывает