Skip to content

Commit

Permalink
feat: qb-vehiclekeys bridge (#132)
Browse files Browse the repository at this point in the history
  • Loading branch information
Manason authored Sep 28, 2024
1 parent 73efdcc commit 738744b
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 31 deletions.
13 changes: 13 additions & 0 deletions bridge/qb/client.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
if GetConvar('qbx_vehiclekeys:enableBridge', 'true') ~= 'true' then return end

RegisterNetEvent('qb-vehiclekeys:client:AddKeys', function(plate)
TriggerServerEvent('qb-vehiclekeys:server:AcquireVehicleKeys', plate)
end)

RegisterNetEvent('qb-vehiclekeys:client:RemoveKeys', function(plate)
TriggerServerEvent('qb-vehiclekeys:server:removeKeys', plate)
end)

RegisterNetEvent('vehiclekeys:client:SetOwner', function(plate)
TriggerServerEvent('qb-vehiclekeys:server:AcquireVehicleKeys', plate)
end)
29 changes: 29 additions & 0 deletions bridge/qb/server.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
if GetConvar('qbx_vehiclekeys:enableBridge', 'true') ~= 'true' then return end

local function giveKeys(source, plate)
local vehicles = plate and GetVehiclesFromPlate(plate) or {GetVehiclePedIsIn(GetPlayerPed(source), false)}
local success = nil
for i = 1, #vehicles do
success = success or GiveKeys(source, vehicles[i])
end
return success
end

CreateQbExport('GiveKeys', giveKeys)

local function removeKeys(source, plate)
local vehicles = GetVehiclesFromPlate(plate)
for i = 1, #vehicles do
RemoveKeys(source, vehicles[i])
end
end

CreateQbExport('RemoveKeys', removeKeys)

RegisterNetEvent('qb-vehiclekeys:server:AcquireVehicleKeys', function(plate)
giveKeys(source, plate)
end)

RegisterNetEvent('qb-vehiclekeys:server:removeKeys', function(plate)
removeKeys(source, plate)
end)
31 changes: 31 additions & 0 deletions bridge/qb/shared.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
if GetConvar('qbx_vehiclekeys:enableBridge', 'true') ~= 'true' then return end

function CreateQbExport(name, cb)
AddEventHandler(('__cfx_export_qb-vehiclekeys_%s'):format(name), function(setCB)
setCB(cb)
end)
end

function GetVehiclesFromPlate(plate)
local vehicles = GetAllVehicles()
local vehEntityFromPlate = {}

for i = 1, #vehicles do
local vehicle = vehicles[i]
local vehPlate = qbx.getVehiclePlate(vehicle)
if plate == vehPlate then
vehEntityFromPlate[#vehEntityFromPlate + 1] = vehicle
end
end

return vehEntityFromPlate
end

CreateQbExport('HasKeys', function(source, plate)
local vehicles = GetVehiclesFromPlate(plate)
local success = nil
for i = 1, #vehicles do
success = success or HasKeys(source, vehicles[i])
end
return success
end)
6 changes: 3 additions & 3 deletions client/functions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,19 @@ end
---Checks if player has vehicle keys
---@param vehicle number
---@return boolean? `true` if player has vehicle keys, `nil` otherwise.
function public.hasKeys(vehicle)
function HasKeys(vehicle)
local keysList = LocalPlayer.state.keysList or {}
local sessionId = Entity(vehicle).state.sessionId
return keysList[sessionId]
end

exports('HasKeys', public.hasKeys)
exports('HasKeys', HasKeys)

---Checks if player has vehicle keys of or access to the vehicle is provided as part of his job.
---@param vehicle number The entity number of the vehicle.
---@return boolean? `true` if player has access to the vehicle, `nil` otherwise.
function public.getIsVehicleAccessible(vehicle)
return public.hasKeys(vehicle) or public.areKeysJobShared(vehicle)
return HasKeys(vehicle) or public.areKeysJobShared(vehicle)
end

function public.toggleEngine(vehicle)
Expand Down
10 changes: 7 additions & 3 deletions fxmanifest.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,33 @@ shared_scripts {
'@ox_lib/init.lua',
'@qbx_core/modules/lib.lua',
'shared/types.lua',
'bridge/qb/shared.lua',
}

client_scripts {
'@qbx_core/modules/playerdata.lua',
'client/main.lua',
'client/carjack.lua',
'bridge/qb/client.lua',
}

server_scripts {
'@oxmysql/lib/MySQL.lua',
'server/version.lua',
'server/keys.lua',
'server/main.lua',
'server/commands.lua'
'server/commands.lua',
'bridge/qb/server.lua',
}

files {
'client/*.lua',
'shared/*.lua',
'client/functions.lua',
'shared/functions.lua',
'locales/*.json',
'config/client.lua',
'config/shared.lua'
}

lua54 'yes'
use_experimental_fxv2_oal 'yes'
provide 'qb-vehiclekeys'
13 changes: 1 addition & 12 deletions server/commands.lua
Original file line number Diff line number Diff line change
@@ -1,14 +1,3 @@
---@param src number
---@param vehicle number
---@return boolean
local function hasKeys(src, vehicle)
local keysList = Player(src).state.keysList or {}
local sessionId = Entity(vehicle).state.sessionId
return keysList[sessionId]
end

exports('HasKeys', hasKeys)

---@param src number
---@return number?
local function getClosestPlayer(src)
Expand Down Expand Up @@ -39,7 +28,7 @@ local function transferKeys(source, target, enforceSrcHasKeys)
exports.qbx_core:Notify(source, locale('notify.vehicle_not_near'), 'error')
return
end
if enforceSrcHasKeys and not hasKeys(source, vehicle) then
if enforceSrcHasKeys and not HasKeys(source, vehicle) then
exports.qbx_core:Notify(source, locale('notify.no_keys'), 'error')
return
end
Expand Down
41 changes: 28 additions & 13 deletions server/keys.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ local debug = GetConvarInt(('%s-debug'):format(GetCurrentResourceName()), 0) ==
---@alias CitizenId string
---@alias SessionId integer
---@type table<CitizenId, table<SessionId, boolean>>
local keysList = {} ---holds key status for some time after player logs out (Prevents frustration by crashing the client)
local loggedOutKeys = {} ---holds key status for some time after player logs out (Prevents frustration by crashing the client)

---@alias LogoutTime integer
---@type table<CitizenId, LogoutTime>
local keysLifetime = {} ---Life timestamp of the keys of a character who has logged out
local logedOutTime = {} ---Life timestamp of the keys of a character who has logged out

---Gets Citizen Id based on source
---@param source number ID of the player
Expand All @@ -24,18 +24,18 @@ RegisterNetEvent('QBCore:Server:OnPlayerLoaded', function()
local src = source
local citizenId = getCitizenId(src)
if not citizenId then return end
if keysList[citizenId] then
Player(src).state:set('keysList', keysList[citizenId], true)
keysList[citizenId] = nil
keysLifetime[citizenId] = nil
if loggedOutKeys[citizenId] then
Player(src).state:set('keysList', loggedOutKeys[citizenId], true)
loggedOutKeys[citizenId] = nil
logedOutTime[citizenId] = nil
end
end)

local function onPlayerUnload(src)
local citizenId = getCitizenId(src)
if not citizenId then return end
keysList[citizenId] = Player(src).state.keysList
keysLifetime[citizenId] = os.time()
loggedOutKeys[citizenId] = Player(src).state.keysList
logedOutTime[citizenId] = os.time()
end

RegisterNetEvent('QBCore:Server:OnPlayerUnload', onPlayerUnload)
Expand All @@ -48,10 +48,10 @@ end)
lib.cron.new('*/'..config.runClearCronMinutes ..' * * * *', function ()
local time = os.time()
local seconds = config.runClearCronMinutes * 60
for citizenId, lifetime in pairs(keysLifetime) do
for citizenId, lifetime in pairs(logedOutTime) do
if lifetime + seconds < time then
keysList[citizenId] = nil
keysLifetime[citizenId] = nil
loggedOutKeys[citizenId] = nil
logedOutTime[citizenId] = nil
end
end
end, {debug = debug})
Expand All @@ -61,10 +61,11 @@ end, {debug = debug})
---@param vehicle number
function RemoveKeys(source, vehicle)
local citizenid = getCitizenId(source)

if not citizenid then return end

local keys = Player(source).state.keysList or {}
local keys = Player(source).state.keysList
if not keys then return end

local sessionId = Entity(vehicle).state.sessionId
if not keys[sessionId] then return end
keys[sessionId] = nil
Expand Down Expand Up @@ -97,3 +98,17 @@ function GiveKeys(source, vehicle)
end

exports('GiveKeys', GiveKeys)

---@param src number
---@param vehicle number
---@return boolean?
function HasKeys(src, vehicle)
local keysList = Player(src).state.keysList
if not keysList then return end

local sessionId = Entity(vehicle).state.sessionId
return keysList[sessionId]
end

exports('HasKeys', HasKeys)

0 comments on commit 738744b

Please sign in to comment.