From ae19c7cd253aadaec7eab0977d67e3f07c19bded Mon Sep 17 00:00:00 2001 From: SNAILX Date: Tue, 28 Oct 2025 18:29:36 +0100 Subject: [PATCH 1/4] Refactor keybind registration to use xLib.addKeybind --- [core]/es_extended/client/compat.lua | 4 +- [core]/es_extended/client/functions.lua | 16 --- [core]/es_extended/fxmanifest.lua | 4 +- [core]/esx_lib/imports/addKeybind/client.lua | 107 +++++++++++++++++++ 4 files changed, 112 insertions(+), 19 deletions(-) create mode 100644 [core]/esx_lib/imports/addKeybind/client.lua diff --git a/[core]/es_extended/client/compat.lua b/[core]/es_extended/client/compat.lua index 254148ac..6b1babe8 100644 --- a/[core]/es_extended/client/compat.lua +++ b/[core]/es_extended/client/compat.lua @@ -1 +1,3 @@ ---All client-side functions outsourced from the Core to the lib will be stored here for compatability, e.g: \ No newline at end of file +--All client-side functions outsourced from the Core to the lib will be stored here for compatability, e.g: + +ESX.RegisterInput = xLib.addKeybind \ No newline at end of file diff --git a/[core]/es_extended/client/functions.lua b/[core]/es_extended/client/functions.lua index 953296d2..2884bc93 100644 --- a/[core]/es_extended/client/functions.lua +++ b/[core]/es_extended/client/functions.lua @@ -245,22 +245,6 @@ function ESX.RefreshContext(...) return IsResourceFound('esx_context') and exports['esx_context']:Refresh(...) end ----@param command_name string The command name ----@param label string The label to show ----@param input_group string The input group ----@param key string The key to bind ----@param on_press function The function to call on press ----@param on_release? function The function to call on release -function ESX.RegisterInput(command_name, label, input_group, key, on_press, on_release) - local command = on_release and '+' .. command_name or command_name - RegisterCommand(command, on_press, false) - Core.Input[command_name] = ESX.HashString(command) - if on_release then - RegisterCommand('-' .. command_name, on_release, false) - end - RegisterKeyMapping(command, label or '', input_group or 'keyboard', key or '') -end - ---@param menuType string ---@param open function The function to call on open ---@param close function The function to call on close diff --git a/[core]/es_extended/fxmanifest.lua b/[core]/es_extended/fxmanifest.lua index 88f1b760..f4005de1 100644 --- a/[core]/es_extended/fxmanifest.lua +++ b/[core]/es_extended/fxmanifest.lua @@ -6,6 +6,7 @@ lua54 'yes' version '1.13.3' shared_scripts { + '@esx_lib/imports.lua', 'locale.lua', 'shared/config/main.lua', @@ -44,6 +45,7 @@ server_scripts { client_scripts { 'client/main.lua', 'client/functions.lua', + 'client/compat.lua', 'client/modules/wrapper.lua', 'client/modules/callback.lua', 'client/modules/adjustments.lua', @@ -57,8 +59,6 @@ client_scripts { 'client/modules/interactions.lua', 'client/modules/scaleform.lua', 'client/modules/streaming.lua', - - 'shared/compat.lua' } ui_page { diff --git a/[core]/esx_lib/imports/addKeybind/client.lua b/[core]/esx_lib/imports/addKeybind/client.lua new file mode 100644 index 00000000..8533c8f7 --- /dev/null +++ b/[core]/esx_lib/imports/addKeybind/client.lua @@ -0,0 +1,107 @@ +--[[ + https://github.com/overextended/ox_lib + + This file is licensed under LGPL-3.0 or higher + + Copyright © 2025 Linden +]] + +---@class KeybindProps +---@field name string +---@field description string +---@field defaultMapper? string (see: https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/) +---@field defaultKey? string +---@field disabled? boolean +---@field disable? fun(self: CKeybind, toggle: boolean) +---@field onPressed? fun(self: CKeybind) +---@field onReleased? fun(self: CKeybind) +---@field remove fun(self: CKeybind) +---@field [string] any + +---@class CKeybind : KeybindProps +---@field currentKey string +---@field disabled boolean +---@field isPressed boolean +---@field hash number +---@field getCurrentKey fun(): string +---@field isControlPressed fun(): boolean + +local keybinds = {} + +local IsPauseMenuActive = IsPauseMenuActive +local GetControlInstructionalButton = GetControlInstructionalButton + +local keybind_mt = { + disabled = false, + isPressed = false, + defaultKey = '', + defaultMapper = 'keyboard', +} + +function keybind_mt:__index(index) + return index == 'currentKey' and self:getCurrentKey() or keybind_mt[index] +end + +function keybind_mt:getCurrentKey() + return GetControlInstructionalButton(0, self.hash, true):sub(3) +end + +function keybind_mt:isControlPressed() + return self.isPressed +end + +function keybind_mt:disable(toggle) + self.disabled = toggle +end + +function keybind_mt:remove() + if not keybinds[self.name] then return end + keybinds[self.name] = nil +end + +---@param command_name string The keybind name +---@param label string The description to show +---@param input_group? string The input group (default: 'keyboard') +---@param key? string The default key +---@param on_press? function The function to call on press +---@param on_release? function The function to call on release +---@return CKeybind +function xLib.addKeybind(command_name, label, input_group, key, on_press, on_release) + + local data = { + name = command_name, + description = label, + defaultMapper = input_group or 'keyboard', + defaultKey = key or '', + onPressed = on_press, + onReleased = on_release, + hash = joaat('+' .. command_name) | 0x80000000 + } + + keybinds[data.name] = setmetatable(data, keybind_mt) + + RegisterCommand('+' .. data.name, function() + if data.disabled or IsPauseMenuActive() then return end + data.isPressed = true + if not keybinds[data.name] then return end + if data.onPressed then data:onPressed() end + end) + + RegisterCommand('-' .. data.name, function() + if data.disabled or IsPauseMenuActive() then return end + data.isPressed = false + if not keybinds[data.name] then return end + if data.onReleased then data:onReleased() end + end) + + RegisterKeyMapping('+' .. data.name, data.description, data.defaultMapper, data.defaultKey) + + SetTimeout(500, function() + TriggerEvent('chat:removeSuggestion', ('/+%s'):format(data.name)) + TriggerEvent('chat:removeSuggestion', ('/-%s'):format(data.name)) + end) + + return data +end + +return xLib.addKeybind \ No newline at end of file From fa52482720d756166cb86fef9ca89de170429977 Mon Sep 17 00:00:00 2001 From: SNAILX Date: Wed, 29 Oct 2025 01:54:53 +0100 Subject: [PATCH 2/4] Fix keybind command order for proper validation --- [core]/esx_lib/imports/addKeybind/client.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/[core]/esx_lib/imports/addKeybind/client.lua b/[core]/esx_lib/imports/addKeybind/client.lua index 8533c8f7..01233d11 100644 --- a/[core]/esx_lib/imports/addKeybind/client.lua +++ b/[core]/esx_lib/imports/addKeybind/client.lua @@ -81,16 +81,16 @@ function xLib.addKeybind(command_name, label, input_group, key, on_press, on_rel keybinds[data.name] = setmetatable(data, keybind_mt) RegisterCommand('+' .. data.name, function() + if not keybinds[data.name] then return end if data.disabled or IsPauseMenuActive() then return end data.isPressed = true - if not keybinds[data.name] then return end if data.onPressed then data:onPressed() end end) RegisterCommand('-' .. data.name, function() + if not keybinds[data.name] then return end if data.disabled or IsPauseMenuActive() then return end data.isPressed = false - if not keybinds[data.name] then return end if data.onReleased then data:onReleased() end end) From 7ebc92ec0fdfcff34e345c514568c783d71a9d6f Mon Sep 17 00:00:00 2001 From: zykem#0643 <86602828+Zykem@users.noreply.github.com> Date: Thu, 30 Oct 2025 19:14:08 +0100 Subject: [PATCH 3/4] refactor(lib/keybind) Change args structure --- [core]/esx_lib/imports/addKeybind/client.lua | 23 ++++---------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/[core]/esx_lib/imports/addKeybind/client.lua b/[core]/esx_lib/imports/addKeybind/client.lua index 01233d11..65c4467c 100644 --- a/[core]/esx_lib/imports/addKeybind/client.lua +++ b/[core]/esx_lib/imports/addKeybind/client.lua @@ -15,7 +15,7 @@ ---@field disable? fun(self: CKeybind, toggle: boolean) ---@field onPressed? fun(self: CKeybind) ---@field onReleased? fun(self: CKeybind) ----@field remove fun(self: CKeybind) +---@field remove? fun(self: CKeybind) ---@field [string] any ---@class CKeybind : KeybindProps @@ -59,25 +59,10 @@ function keybind_mt:remove() keybinds[self.name] = nil end ----@param command_name string The keybind name ----@param label string The description to show ----@param input_group? string The input group (default: 'keyboard') ----@param key? string The default key ----@param on_press? function The function to call on press ----@param on_release? function The function to call on release +---@param data KeybindProps ---@return CKeybind -function xLib.addKeybind(command_name, label, input_group, key, on_press, on_release) - - local data = { - name = command_name, - description = label, - defaultMapper = input_group or 'keyboard', - defaultKey = key or '', - onPressed = on_press, - onReleased = on_release, - hash = joaat('+' .. command_name) | 0x80000000 - } - +function xLib.addKeybind(data) + data.hash = joaat("+" .. data.name) | 0x80000000 keybinds[data.name] = setmetatable(data, keybind_mt) RegisterCommand('+' .. data.name, function() From cb41916ad1a1018818df0fde95fbbdd13a25e139 Mon Sep 17 00:00:00 2001 From: zykem#0643 <86602828+Zykem@users.noreply.github.com> Date: Thu, 30 Oct 2025 19:14:24 +0100 Subject: [PATCH 4/4] refactor(lib/addKeybind) Compat for old core structure --- [core]/es_extended/client/compat.lua | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/[core]/es_extended/client/compat.lua b/[core]/es_extended/client/compat.lua index 6b1babe8..a173f77b 100644 --- a/[core]/es_extended/client/compat.lua +++ b/[core]/es_extended/client/compat.lua @@ -1,3 +1,12 @@ --All client-side functions outsourced from the Core to the lib will be stored here for compatability, e.g: -ESX.RegisterInput = xLib.addKeybind \ No newline at end of file +function ESX.RegisterInput(command_name, label, input_group, key, on_press, on_release) + return xLib.addKeybind({ + name = command_name, + description = label, + defaultMapper = input_group, + defaultKey = key, + onPressed = on_press, + onReleased = on_release + }) +end \ No newline at end of file