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

qwеty

Известный
484
156
Чего так мало отступов, можно было бы побольше сделать...
Примерное такое:
mimgui:
function imgui.TextButton(text, bool)
    imgui.TextColoredRGB(string.format('[  %s', bool[0] and '{00ff00}ON' or '{ff0000}OFF'))
    if imgui.IsItemClicked() then bool[0] = not bool[0] end
    imgui.SameLine()
    imgui.Text('] '..text)
    return bool[0]
end

--Usage:
local active = imgui.new.bool(false)

--render
imgui.TextButton('func', active)
moonimgui:
function imgui.TextButton(text, bool)
    imgui.TextColoredRGB(string.format('[  %s', bool.v and '{00ff00}ON' or '{ff0000}OFF'))
    if imgui.IsItemClicked() then bool.v = not bool.v end
    imgui.SameLine()
    imgui.Text('] '..text)
    return bool.v
end

--Usage:
local active = imgui.ImBool(false)

--render
imgui.TextButton('func', active)
В чём проблема? При нажатии на imgui.TextButton в конфиг сохраняется значение true, нажимаю ещё раз и значение в конфиге должно было бы измениться на false, но оно не изменяется, а остается положительным, то есть true (после нажатия функция всё время возвращает true). В свою очередь, с imgui.Checkbox всё нормально работает, значения сохраняються как и должны сохраняться.
jopa:
require 'lib.moonloader'

local imgui = require 'imgui'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8
local inicfg = require 'inicfg'

local window_menu = imgui.ImBool(false)
local sw, sh = getScreenResolution()

local directIni = 'moonloader/config/imguihui.ini'
local mainIni = inicfg.load({
    config = {
            func = false,
            func1 = false
        }
}, directIni)

local func = imgui.ImBool(mainIni.config.func)
local func1 = imgui.ImBool(mainIni.config.func1)

function main()
    while not isSampAvailable() do wait(100) end
        if not doesFileExist('moonloader/config/imguihui.ini') then inicfg.save(mainIni, 'imguihui.ini') end
        sampRegisterChatCommand('window', windowmenu)
        while true do
            wait(0)
        end
end

function windowmenu()
    window_menu.v = not window_menu.v
    imgui.Process = window_menu.v
end

function imgui.TextColoredRGB(text)
    local style = imgui.GetStyle()
    local colors = style.Colors
    local ImVec4 = imgui.ImVec4

    local explode_argb = function(argb)
        local a = bit.band(bit.rshift(argb, 24), 0xFF)
        local r = bit.band(bit.rshift(argb, 16), 0xFF)
        local g = bit.band(bit.rshift(argb, 8), 0xFF)
        local b = bit.band(argb, 0xFF)
        return a, r, g, b
    end

    local getcolor = function(color)
        if color:sub(1, 6):upper() == 'SSSSSS' then
            local r, g, b = colors[1].x, colors[1].y, colors[1].z
            local a = tonumber(color:sub(7, 8), 16) or colors[1].w * 255
            return ImVec4(r, g, b, a / 255)
        end
        local color = type(color) == 'string' and tonumber(color, 16) or color
        if type(color) ~= 'number' then return end
        local r, g, b, a = explode_argb(color)
        return imgui.ImColor(r, g, b, a):GetVec4()
    end

    local render_text = function(text_)
        for w in text_:gmatch('[^\r\n]+') do
            local text, colors_, m = {}, {}, 1
            w = w:gsub('{(......)}', '{%1FF}')
            while w:find('{........}') do
                local n, k = w:find('{........}')
                local color = getcolor(w:sub(n + 1, k - 1))
                if color then
                    text[#text], text[#text + 1] = w:sub(m, n - 1), w:sub(k + 1, #w)
                    colors_[#colors_ + 1] = color
                    m = n
                end
                w = w:sub(1, n - 1) .. w:sub(k + 1, #w)
            end
            if text[0] then
                for i = 0, #text do
                    imgui.TextColored(colors_[i] or colors[1], u8(text[i]))
                    imgui.SameLine(nil, 0)
                end
                imgui.NewLine()
            else imgui.Text(u8(w)) end
        end
    end
        render_text(text)
end

function imgui.TextButton(text, bool)
    imgui.TextColoredRGB(string.format('[    %s', bool.v and '{00ff00}ON' or '{ff0000}OFF'))
    if imgui.IsItemClicked() then bool.v = not bool.v end
    imgui.SameLine()
    imgui.Text('  ]  '..text)
    return bool.v
end

function imgui.OnDrawFrame()
        if window_menu.v then
            imgui.SetNextWindowSize(imgui.ImVec2(180, 320), imgui.Cond.FirstUseEver)
            imgui.SetNextWindowPos(imgui.ImVec2(sw / 2, sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
            imgui.ShowCursor = true
            imgui.Begin('Window')
            if imgui.TextButton('gmcar1', func1) then
                mainIni.config.func1 = func1.v
                inicfg.save(mainIni, 'imguihui.ini')
            end
            if imgui.Checkbox('gmcar', func) then
                mainIni.config.func = func.v
                inicfg.save(mainIni, 'imguihui.ini')
            end
        else
            imgui.ShowCursor = false
        end
        imgui.End()
end
 
Последнее редактирование:

ARMOR

kjor32 is legend
Модератор
4,852
6,082
В чём проблема? При нажатии на imgui.TextButton в конфиг сохраняется значение true, нажимаю ещё раз и значение в конфиге должно было бы измениться на false, но оно не изменяеться, а остаеться положительным, то есть true. В свою очередь, с imgui.Checkbox всё нормально работает, значения сохраняються как и должны сохраняться.
jopa:
require 'lib.moonloader'

local imgui = require 'imgui'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8
local inicfg = require 'inicfg'

local window_menu = imgui.ImBool(false)
local sw, sh = getScreenResolution()

local directIni = 'moonloader/config/imguihui.ini'
local mainIni = inicfg.load({
    config = {
            func = false,
            func1 = false
        }
}, directIni)

local func = imgui.ImBool(mainIni.config.func)
local func1 = imgui.ImBool(mainIni.config.func1)

function main()
    while not isSampAvailable() do wait(100) end
        if not doesFileExist('moonloader/config/imguihui.ini') then inicfg.save(mainIni, 'imguihui.ini') end
        sampRegisterChatCommand('window', windowmenu)
        while true do
            wait(0)
        end
end

function windowmenu()
    window_menu.v = not window_menu.v
    imgui.Process = window_menu.v
end

function imgui.TextColoredRGB(text)
    local style = imgui.GetStyle()
    local colors = style.Colors
    local ImVec4 = imgui.ImVec4

    local explode_argb = function(argb)
        local a = bit.band(bit.rshift(argb, 24), 0xFF)
        local r = bit.band(bit.rshift(argb, 16), 0xFF)
        local g = bit.band(bit.rshift(argb, 8), 0xFF)
        local b = bit.band(argb, 0xFF)
        return a, r, g, b
    end

    local getcolor = function(color)
        if color:sub(1, 6):upper() == 'SSSSSS' then
            local r, g, b = colors[1].x, colors[1].y, colors[1].z
            local a = tonumber(color:sub(7, 8), 16) or colors[1].w * 255
            return ImVec4(r, g, b, a / 255)
        end
        local color = type(color) == 'string' and tonumber(color, 16) or color
        if type(color) ~= 'number' then return end
        local r, g, b, a = explode_argb(color)
        return imgui.ImColor(r, g, b, a):GetVec4()
    end

    local render_text = function(text_)
        for w in text_:gmatch('[^\r\n]+') do
            local text, colors_, m = {}, {}, 1
            w = w:gsub('{(......)}', '{%1FF}')
            while w:find('{........}') do
                local n, k = w:find('{........}')
                local color = getcolor(w:sub(n + 1, k - 1))
                if color then
                    text[#text], text[#text + 1] = w:sub(m, n - 1), w:sub(k + 1, #w)
                    colors_[#colors_ + 1] = color
                    m = n
                end
                w = w:sub(1, n - 1) .. w:sub(k + 1, #w)
            end
            if text[0] then
                for i = 0, #text do
                    imgui.TextColored(colors_[i] or colors[1], u8(text[i]))
                    imgui.SameLine(nil, 0)
                end
                imgui.NewLine()
            else imgui.Text(u8(w)) end
        end
    end
        render_text(text)
end

function imgui.TextButton(text, bool)
    imgui.TextColoredRGB(string.format('[    %s', bool.v and '{00ff00}ON' or '{ff0000}OFF'))
    if imgui.IsItemClicked() then bool.v = not bool.v end
    imgui.SameLine()
    imgui.Text('  ]  '..text)
    return bool.v
end

function imgui.OnDrawFrame()
        if window_menu.v then
            imgui.SetNextWindowSize(imgui.ImVec2(180, 320), imgui.Cond.FirstUseEver)
            imgui.SetNextWindowPos(imgui.ImVec2(sw / 2, sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
            imgui.ShowCursor = true
            imgui.Begin('Window')
            if imgui.TextButton('gmcar1', func1) then
                mainIni.config.func1 = func1.v
                inicfg.save(mainIni, 'imguihui.ini')
            end
            if imgui.Checkbox('gmcar', func) then
                mainIni.config.func = func.v
                inicfg.save(mainIni, 'imguihui.ini')
            end
        else
            imgui.ShowCursor = false
        end
        imgui.End()
end
jopa:
require 'lib.moonloader'

local imgui = require 'imgui'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8
local inicfg = require 'inicfg'

local window_menu = imgui.ImBool(false)
local sw, sh = getScreenResolution()

local directIni = 'moonloader/config/imguihui.ini'
local mainIni = inicfg.load({
    config = {
            func = false,
            func1 = false
        }
}, directIni)

local func = imgui.ImBool(mainIni.config.func)
local textbutton = imgui.ImBool(mainIni.config.func)

function main()
    while not isSampAvailable() do wait(100) end
        if not doesFileExist('moonloader/config/imguihui.ini') then inicfg.save(mainIni, 'imguihui.ini') end
        sampRegisterChatCommand('window', windowmenu)
        while true do
            wait(0)
        end
end

function windowmenu()
    window_menu.v = not window_menu.v
    imgui.Process = window_menu.v
end

function imgui.TextColoredRGB(text)
    local style = imgui.GetStyle()
    local colors = style.Colors
    local ImVec4 = imgui.ImVec4

    local explode_argb = function(argb)
        local a = bit.band(bit.rshift(argb, 24), 0xFF)
        local r = bit.band(bit.rshift(argb, 16), 0xFF)
        local g = bit.band(bit.rshift(argb, 8), 0xFF)
        local b = bit.band(argb, 0xFF)
        return a, r, g, b
    end

    local getcolor = function(color)
        if color:sub(1, 6):upper() == 'SSSSSS' then
            local r, g, b = colors[1].x, colors[1].y, colors[1].z
            local a = tonumber(color:sub(7, 8), 16) or colors[1].w * 255
            return ImVec4(r, g, b, a / 255)
        end
        local color = type(color) == 'string' and tonumber(color, 16) or color
        if type(color) ~= 'number' then return end
        local r, g, b, a = explode_argb(color)
        return imgui.ImColor(r, g, b, a):GetVec4()
    end

    local render_text = function(text_)
        for w in text_:gmatch('[^\r\n]+') do
            local text, colors_, m = {}, {}, 1
            w = w:gsub('{(......)}', '{%1FF}')
            while w:find('{........}') do
                local n, k = w:find('{........}')
                local color = getcolor(w:sub(n + 1, k - 1))
                if color then
                    text[#text], text[#text + 1] = w:sub(m, n - 1), w:sub(k + 1, #w)
                    colors_[#colors_ + 1] = color
                    m = n
                end
                w = w:sub(1, n - 1) .. w:sub(k + 1, #w)
            end
            if text[0] then
                for i = 0, #text do
                    imgui.TextColored(colors_[i] or colors[1], u8(text[i]))
                    imgui.SameLine(nil, 0)
                end
                imgui.NewLine()
            else imgui.Text(u8(w)) end
        end
    end
        render_text(text)
end

function imgui.TextButton(text, bool)
    imgui.TextColoredRGB(string.format('[    %s', bool.v and '{00ff00}ON' or '{ff0000}OFF'))
    if imgui.IsItemClicked() then bool.v = not bool.v end
    imgui.SameLine()
    imgui.Text('  ]  '..text)
    return bool.v
end

function imgui.OnDrawFrame()
        if window_menu.v then
            imgui.SetNextWindowSize(imgui.ImVec2(180, 320), imgui.Cond.FirstUseEver)
            imgui.SetNextWindowPos(imgui.ImVec2(sw / 2, sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
            imgui.ShowCursor = true
            imgui.Begin('Window')
            if imgui.TextButton('gmcar1', func1) then
                textbutton = not textbutton
                mainIni.config.func1 = textbutton
                inicfg.save(mainIni, 'imguihui.ini')
            end
            if imgui.Checkbox('gmcar', func) then
                mainIni.config.func = func.v
                inicfg.save(mainIni, 'imguihui.ini')
            end
        else
            imgui.ShowCursor = false
        end
        imgui.End()
end
 

Shepi

Активный
178
37
Как можно через testCheat на одну клавишу показать курсор и скрыть его?
 

Dmitriy Makarov

25.05.2021
Проверенный
2,478
1,113
как выровнять кнопки по длине?
В смысле? Не особо понял, поэтому лови эти 3 варианта. Надеюсь там подходящий тебе есть.
ezgif-4-eebfeba75cf9.gif

Lua:
imgui.Button("Button 1", imgui.ImVec2(80, 50)) -- Тут меняется размер кнопки по X(80) и Y(50)

imgui.SetCursorPos(imgui.ImVec2(100, 100)) -- Меняем расположение кнопки ниже по X(100) и Y(100)
imgui.Button("Button 2") -- Изменится расположение этой кнопки.
-- Если хочешь только по X или только по Y, то есть функции: imgui.SetCursorPosX(pos), imgui.SetCursorPosY(pos)

imgui.Button("Button 3", imgui.ImVec2(-1, 50)) -- Если -1 поставить то будет так как на видео (хз как объяснить это)

Как можно через testCheat на одну клавишу показать курсор и скрыть его?
Lua:
-- while true do
if testCheat("C") then -- На английскую C курсор будет активироваться/деактивироваться
    cursorEnabled = not cursorEnabled
    showCursor(cursorEnabled)
end
 
Последнее редактирование:
  • Влюблен
Реакции: Shepi

Rice.

https://t.me/riceoff
Модератор
1,691
1,437
Как узнать уровень игрока? Использовал sampGetPlayerScore и оно то нормально работает, то крашит. Есть ли другой способ?
Код:
sampRegisterChatCommand('score', function(arg)
    if sampIsPlayerConnected(tonumber(arg)) then
        sampAddChatMessage(sampGetPlayerScore(tonumber(arg)), -1)
    end
end)
P.S. Краш скрипта происходит из-за того, что ты пытаешься вывести уровень человека, которого нет в игре
 
Последнее редактирование:

nightaiga

Известный
261
93
Lua:
openStats = true
sampSendChat('/stats')

function sampev.onShowDialog(dialogid, style, title, button1, button2, text)
    if openStats and dialogid == 1500 then
        text:match('{66FFCC}Эксперт')
    else
        thisScript():unload()
        openStats = false
        return false
   end
что не так? скрипт оффается ещё до того как игрок не зашёл на сервер
 

Rice.

https://t.me/riceoff
Модератор
1,691
1,437
Lua:
openStats = true
sampSendChat('/stats')

function sampev.onShowDialog(dialogid, style, title, button1, button2, text)
    if openStats and dialogid == 1500 then
        text:match('{66FFCC}Эксперт')
    else
        thisScript():unload()
        openStats = false
        return false
   end
что не так? скрипт оффается ещё до того как игрок не зашёл на сервер
Lua:
local openStats = false

function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(200) end
    
    sampAddChatMessage('Loaded!', -1)
    
    while not sampIsLocalPlayerSpawned() do wait(0) end
    wait(2000)
    
    lua_thread.create(check)
    
    while true do
    wait(0)
    end
end
    
function check()
    openStats = true
    sampSendChat('/stats')
end

function sampev.onShowDialog(dialogid, style, title, button1, button2, text)
    if openStats and dialogid == 1500 then
       text:match('{66FFCC}Эксперт')
    else
       thisScript():unload()
       openStats = false
       return false
    end
end
 

Anton Nixon

Активный
474
48
вопрос такого характера, есть такой вот код чекера

lua:
if imgui_imbool.friend_online.v then -- друзья в сети
                FriendTitle = "Друзья в сети:"
                renderFontDrawText(friendfont, FriendTitle, check_X, check_Y, 4211081215)
                local string_friend_height = renderGetFontDrawHeight(friendfont)
                local new_Y = string_friend_height + 0.5
                check_Y = check_Y - new_Y
                local last_friend_list = ""
                local count = 1
                local FriendText = ""
                for k, v in pairs(friends) do
                    friendStreamed = sampGetCharHandleBySampPlayerId(idbynick(v.nick))
                    friendPaused = sampIsPlayerPaused(idbynick(v.nick))
                    friendColor = sampGetPlayerColor(idbynick(v.nick))
                    local aa, rr, gg, bb = explode_argb(friendColor)
                    if sampIsLocalPlayerSpawned() then
                        if sampIsPlayerConnected(idbynick(v.nick)) then
                            if friendStreamed then
                                if friendPaused then
                                    friendList = string.format("{%0.2X%0.2X%0.2X}%i. %s [%i] {FF0000}[AFK] {808080}[#]", rr, gg, bb, count, v.nick, idbynick(v.nick))
                                else
                                    friendList = string.format("{%0.2X%0.2X%0.2X}%i. %s [%i] {808080}[#]", rr, gg, bb, count, v.nick, idbynick(v.nick))
                                end
                            else
                                friendList = string.format("{%0.2X%0.2X%0.2X}%i. %s [%i]", rr, gg, bb, count, v.nick, idbynick(v.nick))
                            end
                            count = count + 1
                            FriendText = string.format("%s\n", friendList)
                        end
                    end
                    local string_lead_height = renderGetFontDrawHeight(friendfont)
                    if last_friend_list ~= friendList then
                        local new_Y = string_friend_height + 0.5
                        check_Y = check_Y + new_Y
                        renderFontDrawText(friendfont, FriendText, check_X, check_Y, 4294967295)
                    end
                    last_friend_list = friendList
                end
                if FriendText:len() <= 0 then
                    FriendText = '{808080}Друзей в сети нет'
                    local new_Y = string_friend_height + 0.5
                    check_Y = check_Y + new_Y
                    renderFontDrawText(friendfont, FriendText, check_X, check_Y, 1694498815)
                end
                local string_friend_height = renderGetFontDrawHeight(friendfont)
                local new_Y = string_friend_height * 1.3
                check_Y = check_Y + new_Y
            end
Вот так это выглядит
Посмотреть вложение 117702
Все работает +- хорошо, но когда сети всего лишь один человек из списка, то ничего не отображается
Посмотреть вложение 117703
Помогите исправить, чтобы все ровно отображалось
актуально
 

Anton Nixon

Активный
474
48
Почему всегда выводится, что Игрок не в сети, хотя он в сети
lua:
if adm_command:find("/hp") then
                    adm_chat_cmd_player_id, adm_chat_cmd_player_val = string.match(adm_command, "/hp%s+(%d+)%s+(%d+)") -- hp
                    if adm_chat_cmd_player_id ~= nil then
                        local player_conn = sampIsPlayerConnected(adm_chat_cmd_player_id)
                        if player_conn then
                            adm_chat_cmd_player_name = sampGetPlayerNickname(adm_chat_cmd_player_id)
                            text = string.format("Администратор %s[%d] хочет изменить HP игроку {ffd700}%s[%d]{ffffff}.", adm_name, adm_id, adm_chat_cmd_player_name, adm_chat_cmd_player_id)
                            message(text)
                            command_from_admin_chat_status = false
                            adm_chat_cmd_tick = localClock()
                        else
                            if imgui_imbool.notf_chat.v == true then
                                command_from_admin_chat_status = false
                                adm_name = string.match(adm_name, "%a+")
                                notf_text = string.format("/a %s, игрока с ID %d нет в сети.", adm_name, adm_chat_cmd_player_id)
                                sampSendChat(notf_text)
                                --sampAddChatMessage(adm_chat_cmd_player_val, -1)
                            end
                        end
                    end
                end
 

MAHEKEH

Известный
1,990
494
как задать шрифт для текста окна имгуи?
еще интересует как придать обводку окну как на картинке

2021-10-13_113526.jpg
 

savasmentukas

Новичок
16
1
Привет, видите ли, в окне чата я получаю процент до того, сколько времени ждать, когда 3dtext будет таким же, как в окне чата, я хочу автоматически нажимать "Y", как это сделать?
проценты могут быть разными, не обязательно "45"
 
Последнее редактирование: