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

Ononimus

Потрачен
60
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
почему после ввода /as скорипт крашит?
код:
local sampev = require 'lib.samp.events'
local inicfg = require 'inicfg'
local imgui = require 'imgui'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8

-- ini файл --

local directIni = 'moonloader\\config\\report-plus.ini'
local mainIni = inicfg.load({
    config = {
        bindClock = "[18,82]"
    }
}, directIni)
if not doesFileExist("moonloader/config/report-plus.ini") then inicfg.save(mainIni, "report-plus.ini") end

-- Imgui окно --

local main_window_state = imgui.ImBool(false)
local text_buffer = imgui.ImBuffer(256)
local sw, sh = getScreenResolution()
local rkeys = require 'rkeys'
imgui.HotKey = require ('imgui_addons').HotKey
local tLastKeys = {}
local ActiveClockMenu = {
    v = decodeJson(mainIni.config.bindClock)
}

-- Жёлтое Imgui окно --

function apply_custom_style()
    imgui.SwitchContext()
    local style = imgui.GetStyle()
    local colors = style.Colors
    local clr = imgui.Col
    local ImVec4 = imgui.ImVec4
 
    style.WindowRounding = 2.0
    style.WindowTitleAlign = imgui.ImVec2(0.5, 0.84)
    style.ChildWindowRounding = 2.0
    style.FrameRounding = 2.0
    style.ItemSpacing = imgui.ImVec2(5.0, 4.0)
    style.ScrollbarSize = 13.0
    style.ScrollbarRounding = 0
    style.GrabMinSize = 8.0
    style.GrabRounding = 1.0

    colors[clr.FrameBg]                = ImVec4(0.76, 0.6, 0, 0.74)--
    colors[clr.FrameBgHovered]         = ImVec4(0.84, 0.68, 0, 0.83)--
    colors[clr.FrameBgActive]          = ImVec4(0.92, 0.77, 0, 0.87)--
    colors[clr.TitleBg]                = ImVec4(0.04, 0.04, 0.04, 1.00)--
    colors[clr.TitleBgActive]          = ImVec4(0.92, 0.77, 0, 0.85)--
    colors[clr.TitleBgCollapsed]       = ImVec4(0.00, 0.00, 0.00, 0.51)--
    colors[clr.CheckMark]              = ImVec4(1.00, 1.00, 1.00, 1.00)
    colors[clr.SliderGrab]             = ImVec4(0.84, 0.68, 0, 1.00)
    colors[clr.SliderGrabActive]       = ImVec4(0.92, 0.77, 0, 1.00)
    colors[clr.Button]                 = ImVec4(0.76, 0.6, 0, 0.85)
    colors[clr.ButtonHovered]          = ImVec4(0.84, 0.68, 0, 1.00)
    colors[clr.ButtonActive]           = ImVec4(0.92, 0.77, 0, 1.00)
    colors[clr.Header]                 = ImVec4(0.84, 0.68, 0, 0.75)
    colors[clr.HeaderHovered]          = ImVec4(0.84, 0.68, 0, 0.90)
    colors[clr.HeaderActive]           = ImVec4(0.92, 0.77, 0, 1.00)
    colors[clr.Separator]              = colors[clr.Border]
    colors[clr.SeparatorHovered]       = ImVec4(0.84, 0.68, 0, 0.78)
    colors[clr.SeparatorActive]        = ImVec4(0.84, 0.68, 0, 1.00)
    colors[clr.ResizeGrip]             = ImVec4(0.76, 0.6, 0, 0.25)
    colors[clr.ResizeGripHovered]      = ImVec4(0.84, 0.68, 0, 0.67)
    colors[clr.ResizeGripActive]       = ImVec4(0.92, 0.77, 0, 0.95)
    colors[clr.TextSelectedBg]         = ImVec4(0.52, 0.34, 0, 0.85)
    colors[clr.Text]                   = ImVec4(1.00, 1.00, 1.00, 1.00)
    colors[clr.TextDisabled]           = ImVec4(0.50, 0.50, 0.50, 1.00)
    colors[clr.WindowBg]               = ImVec4(0.06, 0.06, 0.06, 0.94)
    colors[clr.ChildWindowBg]          = ImVec4(1.00, 1.00, 1.00, 0.00)
    colors[clr.PopupBg]                = ImVec4(0.08, 0.08, 0.08, 0.94)
    colors[clr.ComboBg]                = colors[clr.PopupBg]
    colors[clr.Border]                 = ImVec4(0.43, 0.43, 0.50, 0.50)
    colors[clr.BorderShadow]           = ImVec4(0.00, 0.00, 0.00, 0.00)
    colors[clr.MenuBarBg]              = ImVec4(0.14, 0.14, 0.14, 1.00)
    colors[clr.ScrollbarBg]            = ImVec4(0.02, 0.02, 0.02, 0.53)
    colors[clr.ScrollbarGrab]          = ImVec4(0.31, 0.31, 0.31, 1.00)
    colors[clr.ScrollbarGrabHovered]   = ImVec4(0.41, 0.41, 0.41, 1.00)
    colors[clr.ScrollbarGrabActive]    = ImVec4(0.51, 0.51, 0.51, 1.00)
    colors[clr.CloseButton]            = ImVec4(0.41, 0.41, 0.41, 0.50)
    colors[clr.CloseButtonHovered]     = ImVec4(0.98, 0.39, 0.36, 1.00)
    colors[clr.CloseButtonActive]      = ImVec4(0.98, 0.39, 0.36, 1.00)
    colors[clr.PlotLines]              = ImVec4(0.61, 0.61, 0.61, 1.00)
    colors[clr.PlotLinesHovered]       = ImVec4(1.00, 0.43, 0.35, 1.00)
    colors[clr.PlotHistogram]          = ImVec4(0.90, 0.70, 0.00, 1.00)
    colors[clr.PlotHistogramHovered]   = ImVec4(1.00, 0.60, 0.00, 1.00)
    colors[clr.ModalWindowDarkening]   = ImVec4(0.80, 0.80, 0.80, 0.35)
end
apply_custom_style()

-- Главная Функция --

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

    sampAddChatMessage('{ffff00}[Репорт PLUS] {FFFFFF}Скрипт успешно загружен!')
    sampAddChatMessage('{ffff00}[Репорт PLUS] {FFFFFF}Активация: /as или ' .. table.concat(rkeys.getKeysName(ActiveClockMenu.v), " + "))
    sampAddChatMessage('{ffff00}[Репорт PLUS] {FFFFFF}Автор: Sadow')

    sampRegisterChatCommand('as', cmd_as)

    imgui.Process = false

    bindClock = rkeys.registerHotKey(ActiveClockMenu.v, true, clockFunc)


    while true do
        wait(0)

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

    end
end

-- Команда /as --

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

-- Функция с комбинацией клавиш --

function clockFunc()
    cmd_as()
end

-- Переменные необходимые для Imgui окна --


function sampev.onServerMessage(color, text)
    local text = text:gsub('{......}', '')
    if text:find('%[Вопрос%] (.+)%[(%d+)%]: (.+)') then
        mainIni.config.nick, mainIni.config.id, mainIni.config.report = text:match('%[Вопрос%] (.+)%[(%d+)%]: (.+)')
        inicfg.save(mainIni, directIni)
    end
end

-- Функция информации в Imgui окне --

function imgui.Ques(text)
    imgui.SameLine()
    imgui.TextDisabled("(?)")
    if imgui.IsItemHovered() then
        imgui.BeginTooltip()
        imgui.TextUnformatted(u8(text))
        imgui.EndTooltip()
    end
end

-- Само Imgui окно --

function imgui.OnDrawFrame()
    imgui.SetNextWindowPos(imgui.ImVec2(sw / 2, sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    imgui.SetNextWindowSize(imgui.ImVec2(570, 300), imgui.Cond.FirstUseEver)
    imgui.Begin(u8"Репорт PLUS", main_window_state, imgui.WindowFlags.NoResize + imgui.WindowFlags.NoMove + imgui.WindowFlags.NoCollapse)
    imgui.Text(u8'Репорт от: ' .. nick)
    imgui.Text(u8'Репорт: ' .. report)
    imgui.Text(' ')
    imgui.InputText(u8'Ответить на репорт', text_buffer)
    sampSendChat('/pm' .. id .. text_buffer)
    imgui.Text(' ')
    if imgui.HotKey(u8'Комбинация Клавиш', ActiveClockMenu, tLastKey, 100) then
        rkeys.changeHotKey(bindClock, ActiveClockMenu.v)
        mainIni.config.bindClock = encodeJson(ActiveClockMenu.v)
        inicfg.save(mainIni, directIni)
    end
    imgui.End()
end
 

YarikVL

Известный
Проверенный
4,740
1,816
почему после ввода /as скорипт крашит?
код:
local sampev = require 'lib.samp.events'
local inicfg = require 'inicfg'
local imgui = require 'imgui'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8

-- ini файл --

local directIni = 'moonloader\\config\\report-plus.ini'
local mainIni = inicfg.load({
    config = {
        bindClock = "[18,82]"
    }
}, directIni)
if not doesFileExist("moonloader/config/report-plus.ini") then inicfg.save(mainIni, "report-plus.ini") end

-- Imgui окно --

local main_window_state = imgui.ImBool(false)
local text_buffer = imgui.ImBuffer(256)
local sw, sh = getScreenResolution()
local rkeys = require 'rkeys'
imgui.HotKey = require ('imgui_addons').HotKey
local tLastKeys = {}
local ActiveClockMenu = {
    v = decodeJson(mainIni.config.bindClock)
}

-- Жёлтое Imgui окно --

function apply_custom_style()
    imgui.SwitchContext()
    local style = imgui.GetStyle()
    local colors = style.Colors
    local clr = imgui.Col
    local ImVec4 = imgui.ImVec4
 
    style.WindowRounding = 2.0
    style.WindowTitleAlign = imgui.ImVec2(0.5, 0.84)
    style.ChildWindowRounding = 2.0
    style.FrameRounding = 2.0
    style.ItemSpacing = imgui.ImVec2(5.0, 4.0)
    style.ScrollbarSize = 13.0
    style.ScrollbarRounding = 0
    style.GrabMinSize = 8.0
    style.GrabRounding = 1.0

    colors[clr.FrameBg]                = ImVec4(0.76, 0.6, 0, 0.74)--
    colors[clr.FrameBgHovered]         = ImVec4(0.84, 0.68, 0, 0.83)--
    colors[clr.FrameBgActive]          = ImVec4(0.92, 0.77, 0, 0.87)--
    colors[clr.TitleBg]                = ImVec4(0.04, 0.04, 0.04, 1.00)--
    colors[clr.TitleBgActive]          = ImVec4(0.92, 0.77, 0, 0.85)--
    colors[clr.TitleBgCollapsed]       = ImVec4(0.00, 0.00, 0.00, 0.51)--
    colors[clr.CheckMark]              = ImVec4(1.00, 1.00, 1.00, 1.00)
    colors[clr.SliderGrab]             = ImVec4(0.84, 0.68, 0, 1.00)
    colors[clr.SliderGrabActive]       = ImVec4(0.92, 0.77, 0, 1.00)
    colors[clr.Button]                 = ImVec4(0.76, 0.6, 0, 0.85)
    colors[clr.ButtonHovered]          = ImVec4(0.84, 0.68, 0, 1.00)
    colors[clr.ButtonActive]           = ImVec4(0.92, 0.77, 0, 1.00)
    colors[clr.Header]                 = ImVec4(0.84, 0.68, 0, 0.75)
    colors[clr.HeaderHovered]          = ImVec4(0.84, 0.68, 0, 0.90)
    colors[clr.HeaderActive]           = ImVec4(0.92, 0.77, 0, 1.00)
    colors[clr.Separator]              = colors[clr.Border]
    colors[clr.SeparatorHovered]       = ImVec4(0.84, 0.68, 0, 0.78)
    colors[clr.SeparatorActive]        = ImVec4(0.84, 0.68, 0, 1.00)
    colors[clr.ResizeGrip]             = ImVec4(0.76, 0.6, 0, 0.25)
    colors[clr.ResizeGripHovered]      = ImVec4(0.84, 0.68, 0, 0.67)
    colors[clr.ResizeGripActive]       = ImVec4(0.92, 0.77, 0, 0.95)
    colors[clr.TextSelectedBg]         = ImVec4(0.52, 0.34, 0, 0.85)
    colors[clr.Text]                   = ImVec4(1.00, 1.00, 1.00, 1.00)
    colors[clr.TextDisabled]           = ImVec4(0.50, 0.50, 0.50, 1.00)
    colors[clr.WindowBg]               = ImVec4(0.06, 0.06, 0.06, 0.94)
    colors[clr.ChildWindowBg]          = ImVec4(1.00, 1.00, 1.00, 0.00)
    colors[clr.PopupBg]                = ImVec4(0.08, 0.08, 0.08, 0.94)
    colors[clr.ComboBg]                = colors[clr.PopupBg]
    colors[clr.Border]                 = ImVec4(0.43, 0.43, 0.50, 0.50)
    colors[clr.BorderShadow]           = ImVec4(0.00, 0.00, 0.00, 0.00)
    colors[clr.MenuBarBg]              = ImVec4(0.14, 0.14, 0.14, 1.00)
    colors[clr.ScrollbarBg]            = ImVec4(0.02, 0.02, 0.02, 0.53)
    colors[clr.ScrollbarGrab]          = ImVec4(0.31, 0.31, 0.31, 1.00)
    colors[clr.ScrollbarGrabHovered]   = ImVec4(0.41, 0.41, 0.41, 1.00)
    colors[clr.ScrollbarGrabActive]    = ImVec4(0.51, 0.51, 0.51, 1.00)
    colors[clr.CloseButton]            = ImVec4(0.41, 0.41, 0.41, 0.50)
    colors[clr.CloseButtonHovered]     = ImVec4(0.98, 0.39, 0.36, 1.00)
    colors[clr.CloseButtonActive]      = ImVec4(0.98, 0.39, 0.36, 1.00)
    colors[clr.PlotLines]              = ImVec4(0.61, 0.61, 0.61, 1.00)
    colors[clr.PlotLinesHovered]       = ImVec4(1.00, 0.43, 0.35, 1.00)
    colors[clr.PlotHistogram]          = ImVec4(0.90, 0.70, 0.00, 1.00)
    colors[clr.PlotHistogramHovered]   = ImVec4(1.00, 0.60, 0.00, 1.00)
    colors[clr.ModalWindowDarkening]   = ImVec4(0.80, 0.80, 0.80, 0.35)
end
apply_custom_style()

-- Главная Функция --

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

    sampAddChatMessage('{ffff00}[Репорт PLUS] {FFFFFF}Скрипт успешно загружен!')
    sampAddChatMessage('{ffff00}[Репорт PLUS] {FFFFFF}Активация: /as или ' .. table.concat(rkeys.getKeysName(ActiveClockMenu.v), " + "))
    sampAddChatMessage('{ffff00}[Репорт PLUS] {FFFFFF}Автор: Sadow')

    sampRegisterChatCommand('as', cmd_as)

    imgui.Process = false

    bindClock = rkeys.registerHotKey(ActiveClockMenu.v, true, clockFunc)


    while true do
        wait(0)

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

    end
end

-- Команда /as --

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

-- Функция с комбинацией клавиш --

function clockFunc()
    cmd_as()
end

-- Переменные необходимые для Imgui окна --


function sampev.onServerMessage(color, text)
    local text = text:gsub('{......}', '')
    if text:find('%[Вопрос%] (.+)%[(%d+)%]: (.+)') then
        mainIni.config.nick, mainIni.config.id, mainIni.config.report = text:match('%[Вопрос%] (.+)%[(%d+)%]: (.+)')
        inicfg.save(mainIni, directIni)
    end
end

-- Функция информации в Imgui окне --

function imgui.Ques(text)
    imgui.SameLine()
    imgui.TextDisabled("(?)")
    if imgui.IsItemHovered() then
        imgui.BeginTooltip()
        imgui.TextUnformatted(u8(text))
        imgui.EndTooltip()
    end
end

-- Само Imgui окно --

function imgui.OnDrawFrame()
    imgui.SetNextWindowPos(imgui.ImVec2(sw / 2, sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    imgui.SetNextWindowSize(imgui.ImVec2(570, 300), imgui.Cond.FirstUseEver)
    imgui.Begin(u8"Репорт PLUS", main_window_state, imgui.WindowFlags.NoResize + imgui.WindowFlags.NoMove + imgui.WindowFlags.NoCollapse)
    imgui.Text(u8'Репорт от: ' .. nick)
    imgui.Text(u8'Репорт: ' .. report)
    imgui.Text(' ')
    imgui.InputText(u8'Ответить на репорт', text_buffer)
    sampSendChat('/pm' .. id .. text_buffer)
    imgui.Text(' ')
    if imgui.HotKey(u8'Комбинация Клавиш', ActiveClockMenu, tLastKey, 100) then
        rkeys.changeHotKey(bindClock, ActiveClockMenu.v)
        mainIni.config.bindClock = encodeJson(ActiveClockMenu.v)
        inicfg.save(mainIni, directIni)
    end
    imgui.End()
end
С какой ошибкой в мунлоге?
 

coderko61

Участник
55
0
samp.lua ловит только сообщения от сервера, ты лучше хукай именно отправку пакетов коннекта/дисконнекта
Это я сделаю иначе. он не пишет в файл. я много способов перепробовал. файл создал, но не пишет. помогите
 

Sadow

Известный
1,427
592
Как прослушивать сообщения с чата (Хотя бы серверные) на лаунчере аризоны?
 

chapo

tg/inst: @moujeek
Модератор
9,072
12,034
Как прослушивать сообщения с чата (Хотя бы серверные) на лаунчере аризоны?
SAMP.lua -> onServerMessage

Это я сделаю иначе. он не пишет в файл. я много способов перепробовал. файл создал, но не пишет. помогите
он не пишет в файл потому что схуяли ему писать в файл если условие по нахождению текста "Connected" не было выполнено?
 

coderko61

Участник
55
0
SAMP.lua -> onServerMessage


он не пишет в файл потому что схуяли ему писать в файл если условие по нахождению текста "Connected" не было выполнено?
привязал к другому сообщению. сообщение серверное. все так же

Lua:
require "lib.moonloader"
local sampev = require 'lib.samp.events'

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

time = os.clock()

function sampev.onServerMessage(color, text)
    if text:find('Последний заход') then
        local file = io.open('moonloader\savelog.txt', 'w')
        file:write('Connected: '..time..'\n')
        file:close()
    end
end
 

Sadow

Известный
1,427
592
Как можно ловить сообщения клиента (Скриптов и естественно самого клиента)? Нужен способ не через ffi

В каком смысле прослушивать?
Ловить сообщения и присылать мне в телеграмм

Как исправить баг? Как только я прописываю /as (Команда активирующая мой скрипт) меня кикает античит якобы за флуд функцией Callback.
 
Последнее редактирование:

whyega52

Eblang головного мозга
Модератор
2,839
2,778
Как можно ловить сообщения клиента (Скриптов и естественно самого клиента)? Нужен способ не через ffi


Ловить сообщения и присылать мне в телеграмм

Как исправить баг? Как только я прописываю /as (Команда активирующая мой скрипт) меня кикает античит якобы за флуд функцией Callback.
Ffi как я знаю это для работы с си, а для отлавливания сообщения тебе нужен samp.lua или хукать через сампфункс, раклуа и тд
 

artie

Участник
70
21
можете пожалуйста помочь чтобы при нажатии на X писался текст в чат, почему-то не работает это:
Lua:
function main()
    while not isSampAvailable() do wait(100) end
    sampRegisterChatCommand('dialog', function()
        dialog = not dialog
        if dialog then
            sampAddChatMessage("{ffb400}[Dialog]{FFFFFF} Скрипт включен.", -1)
        else
            sampAddChatMessage("{ffb400}[Dialog]{FFFFFF} Скрипт выключен.", -1)
        end
    end)
    sampRegisterChatCommand('gpso', function()
        falsegps = true
        sampSendChat('/gps')
        sampSendDialogResponse(25305, 1, 41, nil)
        lua_thread.create(function()
            wait(300)
            falsegps = false
        end)
    end)
    sampRegisterChatCommand('gpsc', function()
        chargegps = true
        sampSendChat('/gps')
        sampSendDialogResponse(25305, 1, 30, nil)
        lua_thread.create(function()
            wait(300)
            chargegps = false
        end)
    end)
    sampRegisterChatCommand('gpsg', function()
        gasgps = true
        sampSendChat('/gps')
        sampSendDialogResponse(25305, 1, 14, nil)
        lua_thread.create(function()
            wait(300)
            gasgps = false
        end)
    end)
    sampRegisterChatCommand('gpss', function()
        gpsshop = true
        sampSendChat('/gps')
        sampSendDialogResponse(25305, 1, 16, nil)
        lua_thread.create(function()
            wait(300)
            gpsshop = false
        end)
    end)
    for k, v in ipairs(commands) do
        sampRegisterChatCommand(v, function(args)
            local id = tonumber(args:match("%d+"))
            if id ~= nil then
                sampSendChat("/"..v.." "..id)
            else
                sampSendChat("/"..v.." "..select(2, sampGetPlayerIdByCharHandle(playerPed)))
            end
        end)
    end
    while true do
        wait(1)
        if isKeyControlAvailable() then
            if isKeyDown(VK_X) then
                sampAddChatMessage('asd')
            end
        end
    end
end

function isKeyControlAvailable()
    if not isSampLoaded() then return true end
    if not isSampfuncsLoaded() then return not sampIsChatInputActive() and not sampIsDialogActive() end
    return not sampIsChatInputActive() and not sampIsDialogActive() and not isSampfuncsConsoleActive()
end