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

SamperJostkiy

Участник
172
19
Недавно решил сделать новую версию скрипта, взял старый код. зашёл на монсер, на гв, и мой скрипт сломался, я даже не понимаю почему, раньше использовал, скрипт работал, кажется я уже все перепробывал что бы он работал, но все ровно не работает
code:
local hook = require 'samp.events'

local work = true

function main()
    sampRegisterChatCommand("Leader", function()
        work = not work
        sampAddChatMessage("Авто взятие лидерки: "..(work and "Включено" or "Выключено"), -1)
    end)
    wait(-1)
end

function hook.onServerMessage(color,text)
    if not sampIsCursorActive() and text:find('%{42AAFF%}Вы лидируете по убийствам среди членов банды, желаете стать лидером банды?') and work then
        lua_thread.create(function()
            wait(1000)
            sampAddChatMessage("Ооo тебе предлагают стать лидером, я сам это сделаю!!!", 0xFF004D)
            setVirtualKeyDown(89, true)
            wait(250)
            setVirtualKeyDown(89, false)
        end)
    end
end
Вот что пишет в консоли SF:
[ML] (error) AutoLeader 1.1.lua: cannot resume non-suspended coroutine
stack traceback:
[C]: in function 'setVirtualKeyDown'
E:\NoRead\MyGTA\moonloader\AutoLeader 1.1.lua:27: in function <E:\DaVid\MyGTA\moonloader\AutoLeader 1.1.lua:24>
[ML] (error) AutoLeader 1.1.lua: Script died due to an error. (01DBCC9C)
 
Последнее редактирование:

Morse

Потрачен
436
70
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Недавно решил сделать новую версию скрипта, взял старый код. зашёл на монсер, на гв, и мой скрипт сломался, я даже не понимаю почему, раньше использовал, скрипт работал, кажется я уже все перепробывал что бы он работал, но все ровно не работает
code:
local hook = require 'samp.events'

local work = true

function main()
    sampRegisterChatCommand("Leader", function()
        work = not work
        sampAddChatMessage("Авто взятие лидерки: "..(work and "Включено" or "Выключено"), -1)
    end)
    wait(-1)
end

function hook.onServerMessage(color,text)
    if not sampIsCursorActive() and text:find('%{42AAFF%}Вы лидируете по убийствам среди членов банды, желаете стать лидером банды?') and work then
        lua_thread.create(function()
            wait(1000)
            sampAddChatMessage("Ооo тебе предлагают стать лидером, я сам это сделаю!!!", 0xFF004D)
            setVirtualKeyDown(89, true)
            wait(250)
            setVirtualKeyDown(89, false)
        end)
    end
end
Вот что пишет в консоли SF:
[ML] (error) AutoLeader 1.1.lua: cannot resume non-suspended coroutine
stack traceback:
[C]: in function 'setVirtualKeyDown'
E:\NoRead\MyGTA\moonloader\AutoLeader 1.1.lua:27: in function <E:\DaVid\MyGTA\moonloader\AutoLeader 1.1.lua:24>
[ML] (error) AutoLeader 1.1.lua: Script died due to an error. (01DBCC9C)
Что на 24 и 27 строке
 

SamperJostkiy

Участник
172
19
ты утверждаешь даже не дав код
Верхний код |

Кхмм, прошу прощения, не то скинул, вот теперь правильный код:
code:
require "lib.moonloader"
local hook = require 'samp.events'
local work = true

function main()
    sampRegisterChatCommand("Leader", function()
        work = not work
        sampAddChatMessage("Авто взятие лидерки: "..(work and "Включено" or "Выключено"), -1)
    end)
    wait(-1)
end

function hook.onServerMessage(color,text)
    if not sampIsCursorActive() and work and text:find('%{42AAFF%}Вы лидируете по убийствам среди членов банды, желаете стать лидером банды?') then
        lua_thread.create(function()
            wait(1000)
            sampAddChatMessage("Ооo тебе предлагают стать лидером, я сам это сделаю!!!", 0xFF004D)
            setVirtualKeyDown(89, true)
            wait(250)
            setVirtualKeyDown(89, false)
        end)
    end
end

и ошибка в SF консоли:
[ML] (error) Auto Leader.lua: cannot resume non-suspended coroutine
stack traceback:
[C]: in function 'setVirtualKeyDown'
E:\NoRead\MyGTA\moonloader\Auto Leader.lua:18: in function <E:\DaVid\MyGTA\moonloader\Auto Leader.lua:15>
[ML] (error) Auto Leader.lua: Script died due to an error. (01D5E38C)

Все библиотеки, у меня есть
 
Последнее редактирование:

Gorskin

♥ Love Lua ♥
Проверенный
1,343
1,181
как подгрузить в игру cleo, sf и аси скрипты/плагины по названию файла?
в консоль sampfuncs. cleo: cs "name.cs" 1 --загрузить, 0 - выгрузить, sfplugin: pload "name.sf", .asi - .dll: inject dll - где-то в снипетах видел функцию.
 
  • Нравится
Реакции: ShitKatsan

Shepi

Активный
178
37
Ку, я сделал скрипт с имгуи окном, как сделать так, что-бы при открытии данного окна, все, что не касалось имгуи, становилось более темным? К примеру как в воленте :
IMG_20210908_201543.jpg
 
  • Bug
Реакции: Sanchez.

SamperJostkiy

Участник
172
19
Верхний код |

Кхмм, прошу прощения, не то скинул, вот теперь правильный код:
code:
require "lib.moonloader"
local hook = require 'samp.events'
local work = true

function main()
    sampRegisterChatCommand("Leader", function()
        work = not work
        sampAddChatMessage("Авто взятие лидерки: "..(work and "Включено" or "Выключено"), -1)
    end)
    wait(-1)
end

function hook.onServerMessage(color,text)
    if not sampIsCursorActive() and work and text:find('%{42AAFF%}Вы лидируете по убийствам среди членов банды, желаете стать лидером банды?') then
        lua_thread.create(function()
            wait(1000)
            sampAddChatMessage("Ооo тебе предлагают стать лидером, я сам это сделаю!!!", 0xFF004D)
            setVirtualKeyDown(89, true)
            wait(250)
            setVirtualKeyDown(89, false)
        end)
    end
end

и ошибка в SF консоли:
[ML] (error) Auto Leader.lua: cannot resume non-suspended coroutine
stack traceback:
[C]: in function 'setVirtualKeyDown'
E:\NoRead\MyGTA\moonloader\Auto Leader.lua:18: in function <E:\DaVid\MyGTA\moonloader\Auto Leader.lua:15>
[ML] (error) Auto Leader.lua: Script died due to an error. (01D5E38C)

Все библиотеки, у меня есть
Помогите
 

Smeruxa

Известный
1,372
726
Ку, я сделал скрипт с имгуи окном, как сделать так, что-бы при открытии данного окна, все, что не касалось имгуи, становилось более темным? К примеру как в воленте :Посмотреть вложение 113726
renderDrawBox() и установить alpha 100 +-

Ты библиотеку не подключил
Lua:
local keys = require 'vkeys'
он id клавиши использует..
 
  • Злость
Реакции: Sanchez.

abnomegd

Активный
335
34
script:
require "lib.moonloader"
local keys = require "vkeys"
local imgui = require 'imgui'
local sampev   = require 'lib.samp.events'
local inicfg = require 'inicfg'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8

local directIni = "moonloader\\config\\advanceFixSettings.ini"

local mainIni = inicfg.load(nil, directIni)

local mainIni = inicfg.load({
    hotkey = {
        bindClock = "[18,82]",
        bindInvent = "[18,83]",
        bindLock = "[18,84]"
    }
}, directIni)

local config = inicfg.load(
    {
        scriptActivation = {
            fastBuy    = true
        }
    },
    'settings'
)

local rkeys = require 'rkeys'
imgui.HotKey = require('imgui_addons').HotKey

local tLastKeys = {}

local ActiveClockMenu = {
    v = decodeJson(mainIni.hotkey.bindClock)
}

local ActiveInventMenu = {
    v = decodeJson(mainIni.hotkey.bindInvent)
}

local ActiveLockMenu = {
    v = decodeJson(mainIni.hotkey.bindLock)
}

main_window_state = imgui.ImBool(false)

-- Initialising script variables
local report = false -- ExtraReport by AppleThe
local msg    = "" -- ExtraReport by AppleThe

-- Loading config values
local config = inicfg.load(
    {
        scriptActivation = {
            engineFix    = true,
            maskReset    = true,
            historyCheck = true,
            maskTimer    = true,
            fastSpeedup  = true,
            extraReport  = true
        }
    },
    'advanceFeatureSettings'
)

-- Loading configuration descriptions
local configDescriptions = {
    engineFix    = u8'EngineFix (фикс отключения двигателя при столкновении)',
    maskReset    = u8'MaskReset (автоматически скрывает маску при надевании)',
    historyCheck = u8'HistoryCheck (позволяет пробивать /history по id игрока в сети)',
    maskTimer    = u8'MaskTimer (отображает десятиминутный таймер при активации маски)',
    fastSpeedup  = u8'FastSpeedup (увеличение частоты обновления спидометра)',
    extraReport  = u8'ExtraReport (быстрый репорт на /report)'
}

-- Main loop
function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(100) end
    while sampGetCurrentServerName() == "SA-MP" do wait(100) end
    if not sampGetCurrentServerName():find("Advance") then thisScript():unload() end
    sampAddChatMessage("[AdvanceFeatures]: {FFFFFF}Скрипт загружен! Активация: {00ff00}/af", 0x5CBCFF)
    sampRegisterChatCommand("af", cmd_af)
    sampRegisterChatCommand("fbuy", function(arg)
        lua_thread.create(function()
            local var1, var2 = string.match(arg, "(%w+) (%d+)")
            if var1 == nil or var1 == "" or var2 == nil or var2 == "" then
                sampAddChatMessage("[FBuy]: {FFFFFF}Ошибка, небыло введено нужное количество аптечек/масок!", 0x5CBCFF)
            else
                if var1 == "heal" then
                    sampAddChatMessage("[FBuy]: {FFFFFF}Вы начали скупать: {5CBCFF}" .. var2 .. " {FFFFFF}аптечек", 0x5CBCFF)
                    for i = 0, var2 do
                        sampSendChat("/buy")
                        wait(300)
                        sampSendDialogResponse(101, 1, 3,nil)
                        wait(200)
                        sampSendDialogResponse(374, 1, 0,nil)
                        i = i + 1
                        wait(200)
                    end
                elseif var1 == "mask" then
                    sampAddChatMessage("[FBuy]: {FFFFFF}Вы начали скупать: {5CBCFF}" .. var2 .. " {FFFFFF}маcок", 0x5CBCFF)
                    for i = 0, var2 do
                        sampSendChat("/buy")
                        wait(300)
                        sampSendDialogResponse(101, 1, 9,nil)
                        wait(200)
                        sampSendDialogResponse(374, 1, 0,nil)
                        i = i + 1
                        wait(200)
                    end
                end
            end
        end)
    end)

    -- Historycheck source
    sampRegisterChatCommand("history", function(param)
        if config.scriptActivation.historyCheck and param:match('^(%d+)$') and sampIsPlayerConnected(param) then
            local playerNickname = sampGetPlayerNickname(param)
            if playerNickname then sampSendChat("/history " .. playerNickname) end
        else sampSendChat("/history " .. param) end
        end)

        -- ExtraReport By AppleThe
        sampRegisterChatCommand("report", function(_msg)
                if config.scriptActivation.extraReport and _msg ~= "" then
                    report = true
                    msg = _msg
                    sampSendChat("/mn")
                end
            end)

    -- Imgui handler

    imgui.Process = false

    bindClock = rkeys.registerHotKey(ActiveClockMenu.v, true, clockFunc)
    bindInvent = rkeys.registerHotKey(ActiveInventMenu.v, true, inventFunc)
    bindLock = rkeys.registerHotKey(ActiveLockMenu.v, true, lockFunc)


    while true do
        wait(0)


    end
end

function cmd_af(arg)
    main_window_state.v = not main_window_state.v
    imgui.Process = main_window_state.v
end

function clockFunc()
    sampSendChat("/c 60")
end

function inventFunc()
    sampSendChat("/i")
end

function lockFunc()
    sampSendChat("/lock 1")
end

function imgui.OnDrawFrame()

    if not main_window_state.v then
        imgui.Process = false
    end

    if main_window_state.v then
        local sw, sh = getScreenResolution()

        imgui.SetNextWindowPos(imgui.ImVec2(sw / 2, sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        imgui.SetNextWindowSize(imgui.ImVec2(500, 360), imgui.Cond.FirstUseEver)
        imgui.RenderInMenu = true -- Allowing rendering menu in afk

        apply_custom_style() -- Changing gui style

        imgui.Begin(u8'Настройки / AdvanceFeatures', nil, imgui.WindowFlags.NoResize
         + imgui.WindowFlags.NoCollapse) -- Creating gui window

         -- Initialising checkboxes
         for key, value in pairs(configDescriptions) do
             if imgui.Checkbox(value, imgui.ImBool(config.scriptActivation[key])) then
                 config.scriptActivation[key] = not config.scriptActivation[key]
             end
         end

        imgui.Text(u8"Посмотреть время")
        imgui.SameLine()
        if imgui.HotKey("##1", ActiveClockMenu, tLastKeys, 100) then
            rkeys.changeHotKey(bindClock, ActiveClockMenu.v)
            sampAddChatMessage("Успешно! Старое значение: {F4A460}" .. table.concat(rkeys.getKeysName(tLastKeys.v), " + ") .. "{ffffff} | Новое: {F4A460}" .. table.concat(rkeys.getKeysName(ActiveClockMenu.v), " + "), -1)
            sampAddChatMessage("Строчное значение: {F4A460}" .. encodeJson(ActiveClockMenu.v), -1)

            mainIni.hotkey.bindClock = encodeJson(ActiveClockMenu.v)
            inicfg.save(mainIni, directIni)
        end

        imgui.Text(u8"Посмотреть инвентарь")
        imgui.SameLine()
        if imgui.HotKey("##2", ActiveInventMenu, tLastKeys, 100) then
            rkeys.changeHotKey(bindInvent, ActiveInventMenu.v)
            sampAddChatMessage("Успешно! Старое значение: {F4A460}" .. table.concat(rkeys.getKeysName(tLastKeys.v), " + ") .. "{ffffff} | Новое: {F4A460}" .. table.concat(rkeys.getKeysName(ActiveInventMenu.v), " + "), -1)
            sampAddChatMessage("Строчное значение: {F4A460}" .. encodeJson(ActiveInventMenu.v), -1)

            mainIni.hotkey.bindInvent = encodeJson(ActiveInventMenu.v)
            inicfg.save(mainIni, directIni)
        end

        imgui.Text(u8"Открыть/закрыть автомобиль-мотоцикл")
        imgui.SameLine()
        if imgui.HotKey("##3", ActiveLockMenu, tLastKeys, 100) then
            rkeys.changeHotKey(bindLock, ActiveLockMenu.v)
            sampAddChatMessage("Успешно! Старое значение: {F4A460}" .. table.concat(rkeys.getKeysName(tLastKeys.v), " + ") .. "{ffffff} | Новое: {F4A460}" .. table.concat(rkeys.getKeysName(ActiveLockMenu.v), " + "), -1)
            sampAddChatMessage("Строчное значение: {F4A460}" .. encodeJson(ActiveLockMenu.v), -1)

            mainIni.hotkey.bindLock = encodeJson(ActiveLockMenu.v)
            inicfg.save(mainIni, directIni)
        end

-- Setting cursor position
imgui.SetCursorPosX(imgui.GetWindowSize().x / 2.7 - imgui.CalcTextSize('Скрыть').x + imgui.GetStyle().ItemSpacing.x)
imgui.SetCursorPosY(imgui.GetWindowSize().y - imgui.CalcTextSize('Скрыть').y - imgui.GetStyle().WindowPadding.y - imgui.GetStyle().ItemSpacing.y)

-- Handles button pressing
if imgui.Button(u8'Скрыть') then
    imgui.Process = not imgui.Process
end

        imgui.End()
    end
end

-- Savaing data in config while script dies
function onScriptTerminate(script, quitGame)
    if script == thisScript() then
        inicfg.save(config, 'advanceFixSettings')
    end
end

--
-- EngineFix source
--
local textShow = false

function sampev.onDisplayGameText(style, time, text)
    if config.scriptActivation.engineFix and text == "~r~~h~Engine Off" then
        textShow = true
        local vehicle = storeCarCharIsInNoSave(PLAYER_PED)
        lua_thread.create(checkEng, vehicle)
        return false
    end
end

function checkEng(vehicle)
    repeat
        wait(10)
        if not isCarEngineOn(vehicle) then
            switchCarEngine(vehicle, true)
            sampSendChat("/e")
            textShow = false
        end
    until not textShow
end


--
-- MaskTimer and MaskReset source
--
local xCoord      = 610
local yCoord      = 435
local timerActive = false

function startMaskTimer()
    wait(1)
    timerActive = true
    local offMaskTime = os.clock() * 1000 + 600000
    sampTextdrawCreate(102, "00:00", xCoord, yCoord)
    while sampTextdrawIsExists(102) do
        local remainingTime = math.floor((offMaskTime - os.clock() * 1000 ) / 1000)
        local seconds = remainingTime % 60
        local minutes = math.floor(remainingTime / 60)
        if sampTextdrawIsExists(102) then
            if seconds >= 10 then
                sampTextdrawSetString(102, minutes .. ":" .. seconds, xCoord, yCoord)
            else
                sampTextdrawSetString(102, minutes .. ":0" .. seconds, xCoord, yCoord)
            end
            if seconds < 0 or minutes < 0 then
                sampTextdrawDelete(102)
            end
        end
        wait(100)
    end
    timerActive = false
end

-- Handle clist color changing
function sampev.onSetPlayerColor(playerId, color)
    local result, id = sampGetPlayerIdByCharHandle(PLAYER_PED)
    if playerId == id then
        if color ~= 572662272 and timerActive then
            sampTextdrawDelete(102)
        elseif config.scriptActivation.maskTimer and color == 572662272 and timerActive then
            lua_thread.create(function()
                sampTextdrawDelete(102)
                while timerActive do
                    wait(100)
                end
                lua_thread.create(startMaskTimer)
            end)
        elseif config.scriptActivation.maskTimer and color == 572662272 and not timerActive then
            lua_thread.create(startMaskTimer)
        end
    end
    if config.scriptActivation.maskReset and playerId == id and color == 572662272 then
        lua_thread.create(function()
            wait(0)
            sampSendChat("/reset")
        end)
    end
end

--
-- ExtraReport by AppleThe source
--
function sampev.onShowDialog(id, style, title, button1, button2, text)
    if title == ("{0099CC}Меню игрока") and report then
        sampSendDialogResponse(id, 1, 5, 0)
        return false
    elseif title == ("{FFCD00}Связь с администрацией") and report then
        sampSendDialogResponse(id, 1, 0, msg)
        report = false
        return false
    end
end


--
-- FastSpeedup source
--

local inVehicle = false
local textDrawID = 0

function sampev.onSendEnterVehicle(id, passenger)
    if config.scriptActivation.fastSpeedup and not passenger then
        inVehicle = true
        lua_thread.create(updateSpeedup)
    end
end

function sampev.onSendExitVehicle(id)
    inVehicle = false
end

function onReceiveRpc(id,bitstream)
    if id == 105 then
    textDrawID = raknetBitStreamReadInt16(bitstream)
end
end

function updateSpeedup()
    while inVehicle do
        while not isCharInAnyCar(PLAYER_PED) do wait(100) end
        carSpeed = getCarSpeed(storeCarCharIsInNoSave(PLAYER_PED))
      textDrawText = sampTextdrawGetString(textDrawID)
        if textDrawText:find("Fuel") then
            sampTextdrawSetString(textDrawID, textDrawText:gsub("%d+", math.ceil(carSpeed*2), 1))
        end
        wait(20)
    end
end

-- Imgui style initialiser
function apply_custom_style()
    imgui.SwitchContext()
    local style  = imgui.GetStyle()
    local colors = style.Colors
    local clr    = imgui.Col
    local ImVec4 = imgui.ImVec4
    local ImVec2 = imgui.ImVec2

    style.WindowPadding     = ImVec2(15, 15)
    style.WindowRounding    = 5.0
    style.FramePadding      = ImVec2(5, 5)
    style.FrameRounding     = 4.0
    style.ItemSpacing       = ImVec2(12, 8)
    style.ItemInnerSpacing  = ImVec2(8, 6)
    style.IndentSpacing     = 25.0
    style.ScrollbarSize     = 15.0
    style.ScrollbarRounding = 9.0
    style.GrabMinSize       = 5.0
    style.GrabRounding      = 3.0

    colors[clr.Text]                 = ImVec4(0.80, 0.80, 0.83, 1.00)
    colors[clr.TextDisabled]         = ImVec4(0.24, 0.23, 0.29, 1.00)
    colors[clr.WindowBg]             = ImVec4(0.06, 0.05, 0.07, 1.00)
    colors[clr.ChildWindowBg]        = ImVec4(0.07, 0.07, 0.09, 1.00)
    colors[clr.PopupBg]              = ImVec4(0.07, 0.07, 0.09, 1.00)
    colors[clr.Border]               = ImVec4(0.80, 0.80, 0.83, 0.88)
    colors[clr.BorderShadow]         = ImVec4(0.92, 0.91, 0.88, 0.00)
    colors[clr.FrameBg]              = ImVec4(0.10, 0.09, 0.12, 1.00)
    colors[clr.FrameBgHovered]       = ImVec4(0.24, 0.23, 0.29, 1.00)
    colors[clr.FrameBgActive]        = ImVec4(0.56, 0.56, 0.58, 1.00)
    colors[clr.TitleBg]              = ImVec4(0.10, 0.09, 0.12, 1.00)
    colors[clr.TitleBgCollapsed]     = ImVec4(1.00, 0.98, 0.95, 0.75)
    colors[clr.TitleBgActive]        = ImVec4(0.07, 0.07, 0.09, 1.00)
    colors[clr.MenuBarBg]            = ImVec4(0.10, 0.09, 0.12, 1.00)
    colors[clr.ScrollbarBg]          = ImVec4(0.10, 0.09, 0.12, 1.00)
    colors[clr.ScrollbarGrab]        = ImVec4(0.80, 0.80, 0.83, 0.31)
    colors[clr.ScrollbarGrabHovered] = ImVec4(0.56, 0.56, 0.58, 1.00)
    colors[clr.ScrollbarGrabActive]  = ImVec4(0.06, 0.05, 0.07, 1.00)
    colors[clr.ComboBg]              = ImVec4(0.19, 0.18, 0.21, 1.00)
    colors[clr.CheckMark]            = ImVec4(0.80, 0.80, 0.83, 0.31)
    colors[clr.SliderGrab]           = ImVec4(0.80, 0.80, 0.83, 0.31)
    colors[clr.SliderGrabActive]     = ImVec4(0.06, 0.05, 0.07, 1.00)
    colors[clr.Button]               = ImVec4(0.10, 0.09, 0.12, 1.00)
    colors[clr.ButtonHovered]        = ImVec4(0.24, 0.23, 0.29, 1.00)
    colors[clr.ButtonActive]         = ImVec4(0.56, 0.56, 0.58, 1.00)
    colors[clr.Header]               = ImVec4(0.10, 0.09, 0.12, 1.00)
    colors[clr.HeaderHovered]        = ImVec4(0.56, 0.56, 0.58, 1.00)
    colors[clr.HeaderActive]         = ImVec4(0.06, 0.05, 0.07, 1.00)
    colors[clr.ResizeGrip]           = ImVec4(0.00, 0.00, 0.00, 0.00)
    colors[clr.ResizeGripHovered]    = ImVec4(0.56, 0.56, 0.58, 1.00)
    colors[clr.ResizeGripActive]     = ImVec4(0.06, 0.05, 0.07, 1.00)
    colors[clr.CloseButton]          = ImVec4(0.40, 0.39, 0.38, 0.16)
    colors[clr.CloseButtonHovered]   = ImVec4(0.40, 0.39, 0.38, 0.39)
    colors[clr.CloseButtonActive]    = ImVec4(0.40, 0.39, 0.38, 1.00)
    colors[clr.PlotLines]            = ImVec4(0.40, 0.39, 0.38, 0.63)
    colors[clr.PlotLinesHovered]     = ImVec4(0.25, 1.00, 0.00, 1.00)
    colors[clr.PlotHistogram]        = ImVec4(0.40, 0.39, 0.38, 0.63)
    colors[clr.PlotHistogramHovered] = ImVec4(0.25, 1.00, 0.00, 1.00)
    colors[clr.TextSelectedBg]       = ImVec4(0.25, 1.00, 0.00, 0.43)
    colors[clr.ModalWindowDarkening] = ImVec4(1.00, 0.98, 0.95, 0.73)
    end
почему не сохраняются хоткей после перезаходу на сервер.?
up