Как сделать задержку wait IMGUI | LUA

ManstikosUA

Участник
Автор темы
66
15
Привет, помогите сделать пожалуйста задержку в imgui похожую на ту как в мвд хелпере:


строка multiline:
привет
wait_1000
привет
задержка в милисекундах, и при этом оно должно сохраняться, даже после перезапуска
 
Решение
не подскажешь как подключить библиотеку JSON?
и как сделать сохранения, похожие на те, что в inicfg, краткий пример?)
Ты меня спасаешь просто)
Это не библиотека, просто файл с расширением .json через стандартные функции создаётся, читается и записывается.

Разбирай.
1704980027849.png

1704980033891.png

Lua:
local imgui     = require 'imgui'
local encoding   = require "encoding"

local u8         = encoding.UTF8
encoding.default = "CP1251"
local window    = imgui.ImBool(true)
local path      = getGameDirectory()..'\\moonloader\\test.json' -- Наш конфиг-файл.

local...

neronedadaz?

Участник
23
11
hz:
local inicfg = require 'inicfg' -- подгружаем
local mainIni = inicfg.load({
config = {
X= '1500'
},
}, "Test") -- загрузка стандарта




local status = inicfg.load(mainIni, 'Test.ini')
if not doesFileExist('moonloader/config/Test.ini') then inicfg.save(mainIni, 'Test.ini') end -- если нету то создаем


   lua_thread.create(function() -- цикл
--Тут твой код перед задержкой

        wait(mainIni.config.X)
    end)
 

RedHolms

Известный
Проверенный
617
360
Привет, помогите сделать пожалуйста задержку в imgui похожую на ту как в мвд хелпере:


строка multiline:
привет
wait_1000
привет
задержка в милисекундах, и при этом оно должно сохраняться, даже после перезапуска
Вопрос поставлен изначально не очень правильно. Насколько я понял, ты хочешь сделать биндер. Лучше использовать JSON.
Вот пример:
(кода много, мейби оверкомпликатед, но довольно удобно)
Lua:
local settings = {
  -- например, сохраним команду меню скрипта
  command = "ПО УМОЛЧАНИЮ",

  -- список наших биндов
  binds = {
    -- Оставь это просто 1
    _k = 1,

    -- Тут "пример" бинда
    _d = {
      -- Название
      name = "ПО УМОЛЧАНИЮ",
      -- Текст (можно и с переносом строк, т.е. сразу из ImGui.InputMultiline())
      text = ""
    }
  }
}

local prepareTypedTableForJson

function main()
  settings:load()
  --- ...
end

function onScriptTerminate(scr)
  if scr == thisScript() then
    settings:save()
  end
end

prepareTypedTableForJson = function(t)
  for k, v in pairs(t) do
    if
        k == "_d" or
        k == "_k" or
        type(v) == "function"
    then
      t[k] = nil
    elseif type(v) == "table" then
      prepareTypedTableForJson(v)
    end
  end
end

function settings:load()
  SettingsLoaded = true

  local f, err = io.open(CFG.SETTINGS_FILEPATH, "r")
  if not f then
    print("failed to load settings: ", tostring(err))
    return
  end

  local c = f:read("*a")
  f:close()

  local loaded = decodeJson(c)
  if loaded then
    table.merge(self, loaded)
  end
end

function settings:save()
  if not SettingsLoaded then return end

  local f, err = io.open(CFG.SETTINGS_FILEPATH, "w+")
  if not f then
    print("failed to save settings: ", err)
    return
  end

  local to_encode = table.copy(self)

  prepareTypedTableForJson(to_encode)

  local encoded = encodeJson(to_encode)

  if encoded then
    f:write(encoded)
  end

  f:close()
end

function table.merge(p, s)
  if next(s) then
    if p._k then
      -- remove all default values
      for k, _ in pairs(p) do
        if k ~= "_k" and k ~= "_d" then
          p[k] = nil
        end
      end
    end

    for k, v in pairs(s) do
      if p._d and not p[k] and ((p._k and type(k) == type(p._k)) or (not p._k)) then
        p[k] = table.copy(p._d)
      end

      if type(v) == type(p[k]) then
        if type(v) == "table" then
          p[k] = table.merge(p[k], v)
        else
          p[k] = v
        end
      end
    end
  end

  return p
end

function table.copy(t, _seen)
  if type(t) ~= "table" then return t end
  local seen = _seen or {}
  if seen[t] then return seen[t] end
  local _copy = setmetatable({}, getmetatable(t))
  seen[t] = _copy
  for k, v in pairs(t) do _copy[k] = table.copy(v, seen) end
  return _copy
end

Затем в потоке можем просто обрабатывать эти строки
Lua:
lua_thread.create(function(text)
  for line in text:gmatch("^[^\r\n]+") do
    if line == "wait" then
      wait(1000)
      goto continue
    end

    sampSendChat(line)
    ::continue::
  end
end)

Если ты не поймёшь как что-то сделать (а скорее всего так и будет) - советую для начала подучиться, а потом пытаться делать что-то серьёзное
 
  • Эм
Реакции: MLycoris

ManstikosUA

Участник
Автор темы
66
15
Вопрос поставлен изначально не очень правильно. Насколько я понял, ты хочешь сделать биндер. Лучше использовать JSON.
Вот пример:
(кода много, мейби оверкомпликатед, но довольно удобно)
Lua:
local settings = {
  -- например, сохраним команду меню скрипта
  command = "ПО УМОЛЧАНИЮ",

  -- список наших биндов
  binds = {
    -- Оставь это просто 1
    _k = 1,

    -- Тут "пример" бинда
    _d = {
      -- Название
      name = "ПО УМОЛЧАНИЮ",
      -- Текст (можно и с переносом строк, т.е. сразу из ImGui.InputMultiline())
      text = ""
    }
  }
}

local prepareTypedTableForJson

function main()
  settings:load()
  --- ...
end

function onScriptTerminate(scr)
  if scr == thisScript() then
    settings:save()
  end
end

prepareTypedTableForJson = function(t)
  for k, v in pairs(t) do
    if
        k == "_d" or
        k == "_k" or
        type(v) == "function"
    then
      t[k] = nil
    elseif type(v) == "table" then
      prepareTypedTableForJson(v)
    end
  end
end

function settings:load()
  SettingsLoaded = true

  local f, err = io.open(CFG.SETTINGS_FILEPATH, "r")
  if not f then
    print("failed to load settings: ", tostring(err))
    return
  end

  local c = f:read("*a")
  f:close()

  local loaded = decodeJson(c)
  if loaded then
    table.merge(self, loaded)
  end
end

function settings:save()
  if not SettingsLoaded then return end

  local f, err = io.open(CFG.SETTINGS_FILEPATH, "w+")
  if not f then
    print("failed to save settings: ", err)
    return
  end

  local to_encode = table.copy(self)

  prepareTypedTableForJson(to_encode)

  local encoded = encodeJson(to_encode)

  if encoded then
    f:write(encoded)
  end

  f:close()
end

function table.merge(p, s)
  if next(s) then
    if p._k then
      -- remove all default values
      for k, _ in pairs(p) do
        if k ~= "_k" and k ~= "_d" then
          p[k] = nil
        end
      end
    end

    for k, v in pairs(s) do
      if p._d and not p[k] and ((p._k and type(k) == type(p._k)) or (not p._k)) then
        p[k] = table.copy(p._d)
      end

      if type(v) == type(p[k]) then
        if type(v) == "table" then
          p[k] = table.merge(p[k], v)
        else
          p[k] = v
        end
      end
    end
  end

  return p
end

function table.copy(t, _seen)
  if type(t) ~= "table" then return t end
  local seen = _seen or {}
  if seen[t] then return seen[t] end
  local _copy = setmetatable({}, getmetatable(t))
  seen[t] = _copy
  for k, v in pairs(t) do _copy[k] = table.copy(v, seen) end
  return _copy
end

Затем в потоке можем просто обрабатывать эти строки
Lua:
lua_thread.create(function(text)
  for line in text:gmatch("^[^\r\n]+") do
    if line == "wait" then
      wait(1000)
      goto continue
    end

    sampSendChat(line)
    ::continue::
  end
end)

Если ты не поймёшь как что-то сделать (а скорее всего так и будет) - советую для начала подучиться, а потом пытаться делать что-то серьёзное
у меня не биндер, у меня луа скрипт, помощник лидеров и замов, почти готов. Темы, второе окно для собеседований и т.д. уже готово. Осталось онли задержку сделать. На джосе я не думаю что смогу что-то сделать)
 

RedHolms

Известный
Проверенный
617
360
у меня не биндер, у меня луа скрипт, помощник лидеров и замов, почти готов. Темы, второе окно для собеседований и т.д. уже готово. Осталось онли задержку сделать. На джосе я не думаю что смогу что-то сделать)
Ну тогда поясни, какую задержку и где именно тебе надо сделать. Для задержки всегда используется lua_thread.create(...)
 

ManstikosUA

Участник
Автор темы
66
15
Ну тогда поясни, какую задержку и где именно тебе надо сделать. Для задержки всегда используется lua_thread.create(...)
вот код:


Lua:
function imgui.OnDrawFrame()
    if main_window_state.v then
        imgui.SetNextWindowPos(imgui.ImVec2(500, 500), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        imgui.SetNextWindowSize(imgui.ImVec2(700, 300), imgui.Cond.Always)
        imgui.Begin(u8'Пример', WinState, imgui.WindowFlags.NoResize)
        for numberTab,nameTab in pairs({'Основное','Собеседование','Настройки','Инфа'}) do -- создаём и парсим таблицу с названиями будущих вкладок
            if imgui.Button(u8(nameTab), imgui.ImVec2(100,50)) then -- 2ым аргументом настраивается размер кнопок (подробнее в гайде по мимгуи)
                tab = numberTab -- меняем значение переменной tab на номер нажатой кнопки
            end
        end
        imgui.SetCursorPos(imgui.ImVec2(120, 28)) -- [Для декора] Устанавливаем позицию для чайлда ниже
        if imgui.BeginChild('Name##'..tab, imgui.ImVec2(555, 250), true) then -- [Для декора] Создаём чайлд в который поместим содержимое
            -- == [Основное] Содержимое вкладок == --

          
            if tab == 1 then -- если значение tab == 1
                -- == Содержимое вкладки №1
                imgui.Text(u8'Открыта первая вкладка "Основное"')
                imgui.Text(u8"Ваш ник (RUS): ")
                if imgui.InputText(u8'', rusname, imgui.InputTextFlags.None, nil, nil, maxChars) then
                    mainIni.config.rusname = u8:decode(rusname.v)
                    inicfg.save(mainIni, "pdhelperManstikosUA.ini")
                end
            imgui.Text(u8"Ваша должность: ")
        if imgui.InputText(u8' ', rang, imgui.InputTextFlags.None, nil, nil, maxChars) then
            mainIni.config.rang = u8:decode(rang.v)
            inicfg.save(mainIni, "pdhelperManstikosUA.ini")
        end
        if imgui.Button(u8"Сохранить", imgui.ImVec2(100, 20)) then
            mainIni.config.rusname = u8:decode(rusname.v)
            mainIni.config.rang = u8:decode(rang.v)
            sampAddChatMessage("{FFFFFF}Вы успешно изменили ник на:{00BFFF} " .. u8:decode(rusname.v), -1)
            sampAddChatMessage("{FFFFFF}Ваш ранг:{00BFFF} " .. u8:decode(rang.v), -1)
            if inicfg.save(mainIni, directIni) then
                sampAddChatMessage("Сохранено! 2", -1)
            end
        end
                if imgui.Button(u8'Кнопка') then
                    sampAddChatMessage('Вы нажали кнопку во вкладке номер '..tab, -1)
                end
  
    -------------------вкладка 3
            elseif tab == 2 then
                imgui.CenterText("Настройка текста для собеседования")
                imgui.Text(u8"Введите текст для приветствия:")
                if imgui.InputText("  ", sobes_privet, imgui.InputTextFlags.None, nil, nil, maxChars) then
                    mainIni.sobes.sobes_privet = u8:decode(sobes_privet.v)
                    inicfg.save(mainIni, "pdhelperManstikosUA.ini")
                end
                if imgui.Button(u8"Вывести в чат") then
                    sampSendChat(u8:decode(sobes_privet.v))
                end
                imgui.Text(u8"Текст для документов:")
                imgui.Text(u8"Это уже для большого количества текста")
                -----------------------------------------------------------------------вот тут нужна задержка
                if imgui.InputTextMultiline('#sobes_dokitext', sobes_dokiMultiLine) then
                    mainIni.sobes.sobes_dokiMultiLine = u8:decode(sobes_dokiMultiLine.v)
                    inicfg.save(mainIni, "pdhelperManstikosUA")
                    wait(mainIni.config.X)
  
                end
                 -----------------------------------------------------------------------вот тут нужна задержка
                if imgui.Button(u8"Вывести в чат") then
                    sampAddChatMessage('', -1)
                end
              
                if imgui.Button(u8"Сохранить") then
                    mainIni.sobes.sobes_privet = u8:decode(sobes_privet.v)
                    mainIni.sobes.sobes_dokiMultiLine = u8:decode(sobes_dokiMultiLine.v)
                    if inicfg.save(mainIni, directIni) then
                        sampAddChatMessage('Успешно сохранено!', -1)
                    end
                  
                end
              
            elseif tab == 3 then -- если значение tab == 2
                -- == Содержимое вкладки №2
                imgui.Text(u8'Открыта первая вкладка "Настройки"')
                imgui.BeginChild("themespon", imgui.ImVec2(200, 175), true)
                    for i, value in ipairs(themes.colorThemes) do
                        if imgui.RadioButton(value, checked_radio, i) then
                            themes.SwitchColorTheme(i)
                        end
                    end
                    imgui.EndChild()
                if imgui.Button(u8'Кнопка') then
                    sampAddChatMessage('Вы нажали кнопку во вкладке номер '..tab, -1)
                end
            elseif tab == 4 then -- если значение tab == 3
                -- == Содержимое вкладки №3
                imgui.Text(u8'Открыта первая вкладка "Инфа"')
                imgui.Text(u8"Команда /pas - показывает паспорт (/pas ID)")
                imgui.Text(u8"Команда /lics - показывает лицензии(/lics ID)")
                imgui.Text(u8"Команда /medka - отыгрывает рп для мед.карты(передавать нужно вручную)")
                imgui.Text(u8"Команда /udost - отыгрывает рп для удостоверения(передавать нужно вручную)")
                imgui.Text(u8"Команда /cuff - надеть на игрока наручники, есть отыгровка(/cuff ID)")
                imgui.Text(u8"Команда /gotome - потащить игрока за собой, есть отыгровка(/gotome ID)")
                imgui.Text(u8"Команда /cput - посадить игрока в машину, есть отыгровка(/cput ID)")
                imgui.Text(u8"Команда /bodycam - включает отыгровку фрапса")
                imgui.Text(u8"Команда /ticket - отыгровка рп для штарафа + выписка штрафа(/ticket ID)")
                imgui.Text(u8"Команда /frisk - отыгровка рп для обыска + обыск(/frisk ID)")
                imgui.Text(u8"Команда /arrest - отыгровка ареста + арест(/arrest ID)")
                imgui.Text(u8"Команда /uncuff - снять наручники + отыгровка(/uncuff ID)")
                imgui.Text(u8"Команда /su - выдать розыск + отыгровка(/su ID)")
                imgui.Text(u8"Команда /clear - очистить розыск + отыгровка(/clear ID)")
                imgui.Text(u8"Команда /doki - запросить документы(/doki ID)")
                imgui.Text(u8"Команда /meg - просьба остановить машину в мегафон(/meg)")
                imgui.Text(u8"Команда /setpaswrld - установить пароль для быстрого захода")
                imgui.Text(u8"Команда /chatclear - визуально очистить чат")
                imgui.Text(u8"Команда /ecspertiza - отыгровка рп экспертизы")
                imgui.Text(u8"Команда /drug количество - употребить наркотики с рп")
                imgui.Text(u8"Зажать клавишу L.ALT - сирена+стробоскопы")
                imgui.Text(u8"Команда /statistiko - вывести статистику персонажа")
  
                if imgui.Button(u8'Кнопка') then
                    sampAddChatMessage('Вы нажали кнопку во вкладке номер '..tab, -1)
                end
            end
            -- == [Основное] Содержимое вкладок закончилось == --
            imgui.EndChild()
        end
        imgui.End() 
    end
  

    if sobes_window_state.v then
        imgui.SetNextWindowPos(imgui.ImVec2(1100, 800), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        imgui.SetNextWindowSize(imgui.ImVec2(200, 300), imgui.Cond.Always)
        imgui.Begin(u8'Меню собеседований', WinState, imgui.WindowFlags.NoResize)
        imgui.CenterText(u8"Как использовать?")
        imgui.PushFont(fontsize)
            imgui.Text(u8'Нажмите на вкладку "Приветствие", \nчтобы открыть меню с приветствием. \nЧтобы послать уведомление - "Послать"')
        imgui.PopFont()
        imgui.Separator()
        -----------------------------------------------
        if imgui.Button(u8'Приветствие', imgui.ImVec2(0,0)) then
            sobestab = 1
        end
  
        imgui.SameLine()
        if imgui.Button(u8'sobestipo', imgui.ImVec2(0,0)) then
            sobestab = 2
        end

        if imgui.Button(u8"Тесты", imgui.ImVec2(0,0)) then
            sobestab = 3
        end

        imgui.SameLine()
        if imgui.Button(u8"Принятие", imgui.ImVec2(0,0)) then
            sobestab = 4
        end


        imgui.Separator()
        ------------------------------------------------
        for numberTab,nameTab in pairs({'Приветствие', 'Документы', 'Тесты', 'Принятие'}) do -- создаём и парсим таблицу с названиями будущих вкладок
            if imgui.Button(u8(nameTab), imgui.ImVec2(0.1,0.1)) then
                sobestab = numberTab -- меняем значение переменной tab на номер нажатой кнопки
            end
        end

            -- == [Основное] Содержимое вкладок == --
        if sobestab == 1 then -- если значение tab == 1
            imgui.PushFont(fontsize)
            imgui.Text(u8"Текст, который будет отправлен:")
            imgui.Text(u8(mainIni.sobes.sobes_privet))
            imgui.PopFont()

          
        -----2 вкладка
            imgui.SameLine()
        elseif sobestab == 2 then
            imgui.Text("sss 2")

        elseif sobestab == 3 then
            imgui.Text("da ya nigers")
        end



        imgui.End()
    end
end


56 строчка
 
Последнее редактирование:

Dmitriy Makarov

25.05.2021
Проверенный
2,478
1,113
Тут хороший пример. И прикол с задержкой тоже оттуда взят, который ниже.

С JSON пример. Замени на свой inicfg, у меня просто шаблон с JSON только был под рукой..
Lua:
local path = getGameDirectory().."\\moonloader\\test.json" -- Путь до конфиг-файла.

-- Конфиг.
local config = {
    text = ""
}

-- Созание/чтение конфига.
if not doesFileExist(path) then
    local f = io.open(path, 'w+')
    f:write(encodeJson(config)):close()
else
    local f = io.open(path, "r")
    a = f:read("*a")
    config = decodeJson(a)
    f:close()
end

-- Переменная InputMultiline, в котором содержится текст из конфига, если он есть, и пустота, если его нет.
local buffer = imgui.ImBuffer(u8(config.text) or "", 1024)

-- OnDrawFrame()
if imgui.InputTextMultiline("##", buffer) then
    config.text = u8:decode(buffer.v)
    local f = io.open(path, 'w') -- Эту строку и строку ниже можешь попробовать заменить на свой inicfg.save.
    f:write(encodeJson(config)):close()
end
-- Кнопка, при нажатии которой будет отправляться текст из конфига (Miltiline).
if imgui.Button("Send") then
    -- Начиная отсюда и заканчивая на 39-й строке включительно, ты можешь вырезать код и сделать отдельную функцию, чтобы вызывать это функцию там, где ты хочешь бинд отправить.
    lua_thread.create(function()
        for line in buffer.v:gmatch('[^\n]+') do
            if line:find('^{wait:%d+}$') then -- Проверка, указана ли задержка. Задержка указывается как {wait:1} где "1" - 1 секунда.
                wait(tonumber(line:match('^{wait:(%d+)}$')) * 1000) -- Если задержка указана, то добавляешь в бинд эту задержку. Задержка из миллисекунд переводится в секунды, умножая на 1000, поэтому указывай задержку в секундах.
            else
                sampAddChatMessage(u8:decode(line), -1) -- Если задержки нет, то просто сразу весь чат отправляешь.
            end
        end
    end)
end
 

ManstikosUA

Участник
Автор темы
66
15
Тут хороший пример. И прикол с задержкой тоже оттуда взят, который ниже.

С JSON пример. Замени на свой inicfg, у меня просто шаблон с JSON только был под рукой..
Lua:
local path = getGameDirectory().."\\moonloader\\test.json" -- Путь до конфиг-файла.

-- Конфиг.
local config = {
    text = ""
}

-- Созание/чтение конфига.
if not doesFileExist(path) then
    local f = io.open(path, 'w+')
    f:write(encodeJson(config)):close()
else
    local f = io.open(path, "r")
    a = f:read("*a")
    config = decodeJson(a)
    f:close()
end

-- Переменная InputMultiline, в котором содержится текст из конфига, если он есть, и пустота, если его нет.
local buffer = imgui.ImBuffer(u8(config.text) or "", 1024)

-- OnDrawFrame()
if imgui.InputTextMultiline("##", buffer) then
    config.text = u8:decode(buffer.v)
    local f = io.open(path, 'w') -- Эту строку и строку ниже можешь попробовать заменить на свой inicfg.save.
    f:write(encodeJson(config)):close()
end
-- Кнопка, при нажатии которой будет отправляться текст из конфига (Miltiline).
if imgui.Button("Send") then
    -- Начиная отсюда и заканчивая на 39-й строке включительно, ты можешь вырезать код и сделать отдельную функцию, чтобы вызывать это функцию там, где ты хочешь бинд отправить.
    lua_thread.create(function()
        for line in buffer.v:gmatch('[^\n]+') do
            if line:find('^{wait:%d+}$') then -- Проверка, указана ли задержка. Задержка указывается как {wait:1} где "1" - 1 секунда.
                wait(tonumber(line:match('^{wait:(%d+)}$')) * 1000) -- Если задержка указана, то добавляешь в бинд эту задержку. Задержка из миллисекунд переводится в секунды, умножая на 1000, поэтому указывай задержку в секундах.
            else
                sampAddChatMessage(u8:decode(line), -1) -- Если задержки нет, то просто сразу весь чат отправляешь.
            end
        end
    end)
end
так у него mimgui, а у меня imgui



можешь пожалуйста на моём коде это показать?
 

ManstikosUA

Участник
Автор темы
66
15

Dmitriy Makarov

25.05.2021
Проверенный
2,478
1,113
тоесть мне его вставить просто под кнопку мою кнопку "Отправить"?
Lua:
-----------------------------------------------------------------------вот тут нужна задержка
if imgui.InputTextMultiline('#sobes_dokitext', sobes_dokiMultiLine) then
    mainIni.sobes.sobes_dokiMultiLine = u8:decode(sobes_dokiMultiLine.v)
    inicfg.save(mainIni, "pdhelperManstikosUA")
end
-----------------------------------------------------------------------вот тут нужна задержка
if imgui.Button(u8"Вывести в чат") then
    lua_thread.create(function()
        for line in sobes_dokiMultiLine.v:gmatch('[^\n]+') do
            if line:find('^{wait:%d+}$') then
                wait(tonumber(line:match('^{wait:(%d+)}$')) * 1000)
            else
                sampAddChatMessage(u8:decode(line), -1)
            end
        end
    end)
end
Screenshot_1.png


Опечатка: 1 секунда.*
 
  • Нравится
Реакции: ChromiusJ

ManstikosUA

Участник
Автор темы
66
15
Lua:
-----------------------------------------------------------------------вот тут нужна задержка
if imgui.InputTextMultiline('#sobes_dokitext', sobes_dokiMultiLine) then
    mainIni.sobes.sobes_dokiMultiLine = u8:decode(sobes_dokiMultiLine.v)
    inicfg.save(mainIni, "pdhelperManstikosUA")
end
-----------------------------------------------------------------------вот тут нужна задержка
if imgui.Button(u8"Вывести в чат") then
    lua_thread.create(function()
        for line in sobes_dokiMultiLine.v:gmatch('[^\n]+') do
            if line:find('^{wait:%d+}$') then
                wait(tonumber(line:match('^{wait:(%d+)}$')) * 1000)
            else
                sampAddChatMessage(u8:decode(line), -1)
            end
        end
    end)
end
Посмотреть вложение 226943

Опечатка: 1 секунда.*
Какие нужные библиотеки подключать?