Inicio › Documentación › Personalización · origen_parking

Personalización · origen_parking

La carpeta custom/ te permite integrar cualquier framework, sistema de llaves o sistema de combustible sin tocar el núcleo. Todos los ficheros de aquí sobreviven a las actualizaciones.

text
custom/
├── sv_framework.lua  — server-side: identifier, permissions, money, notifications, garages
├── sv_keys.lua       — server-side: give keys, set lock state
├── cl_framework.lua  — client-side: identifier, notifications, player loaded event
├── cl_keys.lua       — client-side: read lock state
└── cl_fuel.lua       — client-side: get/set fuel level

sv_framework.lua

Framework.GetIdentifier(source) → string | nil

Devuelve el identificador único de un jugador (citizenid / license). Se llama en cada acción de aparcar o recuperar.

lua
function Framework.GetIdentifier(source)
    -- Config.Framework == 'custom'
    return nil -- replace with your own logic
end

Framework.GetVehicleOwner(plate) → string | nil

Devuelve el identificador del propietario de una matrícula a partir de la tabla de vehículos del framework.

lua
function Framework.GetVehicleOwner(plate)
    -- Config.Framework == 'custom'
    return nil
end

Framework.SetVehicleStorageState(plate, stored)

Marca un vehículo como guardado (stored = true) o fuera (stored = false) en la tabla de vehículos del framework.

lua
function Framework.SetVehicleStorageState(plate, stored)
    -- Config.Framework == 'custom'
end

Framework.HasAdminPermission(source, permission) → boolean

Se llama en todos los callbacks de administración. Los sistemas de permisos se comprueban en este orden:

  1. origen_admin — exports['origen_admin']:HasPermission(src, permission)
  2. ace — IsPlayerAceAllowed(src, Config.AdminAceNode)
  3. qbx / qb — comprueba PlayerData.group para god, superadmin, admin
  4. esx — comprueba xPlayer.getGroup() para superadmin, admin
  5. custom — impleméntalo más abajo
lua
function Framework.HasAdminPermission(source, permission)
    -- Config.AdminSystem == 'custom'
    return false
end

Framework.Notify(source, message, ntype)

Envía una notificación a un jugador. ntype: 'info' | 'success' | 'error'

lua
function Framework.Notify(source, message, ntype)
    -- Config.NotifySystem == 'custom'
end

Framework.GetGarages() → table[]

Devuelve una lista de garajes para el panel de administración. Cada entrada: { id, name, label }.

lua
function Framework.GetGarages()
    -- Config.GarageIntegration == 'custom'
    return {}
end

Framework.GetMoney(source) → number

Devuelve el saldo en efectivo de un jugador. Lo usa el sistema de coste de aparcamiento.

lua
function Framework.GetMoney(source)
    -- Config.Framework == 'custom'
    return 0
end

Framework.RemoveMoney(source, amount) → boolean

Descuenta efectivo a un jugador. Devuelve true si lo consigue.

lua
function Framework.RemoveMoney(source, amount)
    -- Config.Framework == 'custom'
    return false
end

Framework.GetVehicleState(plate) → number | nil

Devuelve el estado de almacenamiento de un vehículo según la tabla del framework (1 = fuera, 0 = guardado, o nil si no se encuentra).

lua
function Framework.GetVehicleState(plate)
    -- Config.Framework == 'custom'
    return nil
end

Integración del sistema de llaves

El sistema de aparcamiento se comunica con tu sistema de llaves mediante dos ficheros puente: custom/sv_keys.lua (dar llaves y fijar el bloqueo) y custom/cl_keys.lua (leer el estado del bloqueo). El camino que se ejecuta depende de Config.KeySystem:

Config.KeySystem Comportamiento
qbx_vehiclekeys GiveKeys + SetLockState mediante los exports de qbx, con respaldo nativo.
qb-vehiclekeys GiveKeys mediante el export de qb, bloqueo aplicado con el nativo + state bag.
qs-vehiclekeys GiveKeys + setLocked mediante los exports de qs, con respaldo nativo.
rk-keys addKey mediante el export de rk, bloqueo nativo.
none No se dan llaves, los vehículos aparecen desbloqueados.
custom Implementas el puente en sv_keys.lua / cl_keys.lua.

Sea cual sea Config.KeySystem, la forma recomendada de controlar el aparcar/desaparcar desde tu sistema de llaves son los hooks de cliente explícitos que verás a continuación. Son deterministas y ejecutan todas las comprobaciones de elegibilidad, sin adivinar nada.


Llama a estos exports de cliente desde tu sistema de llaves cada vez que el jugador bloquee o desbloquee un vehículo. El sistema de aparcamiento se encarga del resto (comprobaciones de elegibilidad, aparcar/desaparcar en el servidor). Ambos aceptan un handle de entidad del vehículo y no hacen nada si el vehículo no es elegible.

lua
exports['origen_parking']:onVehicleLocked(vehicle)    -- park this vehicle
exports['origen_parking']:onVehicleUnlocked(vehicle)  -- unpark this vehicle

Conexión desde un evento de bloqueo/desbloqueo (la mayoría de los sistemas de llaves de qb / esx lanzan uno):

lua
AddEventHandler('my_keys:client:vehicleLocked', function(veh)
    exports['origen_parking']:onVehicleLocked(veh)
end)
 
AddEventHandler('my_keys:client:vehicleUnlocked', function(veh)
    exports['origen_parking']:onVehicleUnlocked(veh)
end)

Conexión desde el state bag del bloqueo de puertas (qbx_vehiclekeys y similares publican doorslockstate):

lua
AddStateBagChangeHandler('doorslockstate', nil, function(bagName, _, value)
    local veh = GetEntityFromStateBagName(bagName)
    if veh == 0 then return end
    if value and value >= 2 then
        exports['origen_parking']:onVehicleLocked(veh)
    else
        exports['origen_parking']:onVehicleUnlocked(veh)
    end
end)

Los sistemas de llaves que solo usan nativos bloquean el coche en el servidor, así que el cliente propietario de la entidad no siempre puede observar el bloqueo mediante el sondeo nativo. Para esos sistemas, los hooks explícitos de arriba son el único disparador fiable: úsalos en lugar de Config.AutomaticParking.


sv_keys.lua

Keys.GiveKeys(source, entity, plate)

Da las llaves del vehículo a un jugador al aparecer. Solo se ejecuta cuando Config.GiveKeysOnSpawn = true. Cada rama comprueba que el recurso de llaves esté en started y envuelve el export en pcall, de modo que un sistema de llaves ausente nunca rompe la aparición.

Parámetro Tipo Descripción
source number ID de servidor del jugador que recibe las llaves.
entity number Handle de entidad del vehículo (puede ser 0 si aún no ha aparecido: usa plate).
plate string Matrícula del vehículo.

Soportados de serie: qbx_vehiclekeys, qb-vehiclekeys, qs-vehiclekeys, rk-keys. Para custom, añade tu propia llamada al export:

lua
function Keys.GiveKeys(source, entity, plate)
    -- Config.KeySystem == 'custom'
    -- exports['my_key_resource']:GiveKey(source, plate)
end

Keys.SetLock(entity, locked)

Bloquea o desbloquea una entidad de vehículo en el servidor. Solo se ejecuta cuando Config.LockVehiclesOnSpawn = true. locked = true → bloqueado (estado 2), false → desbloqueado (estado 1). Todas las ramas recurren al nativo + state bag para que los demás jugadores vean el vehículo aparcado como bloqueado.

Parámetro Tipo Descripción
entity number Handle de entidad del vehículo.
locked boolean true para bloquear, false para desbloquear.
lua
function Keys.SetLock(entity, locked)
    -- Config.KeySystem == 'custom' / 'none' / 'rk-keys' → native fallback:
    SetVehicleDoorsLocked(entity, locked and 2 or 1)
    Entity(entity).state.doorslockstate = locked and 2 or 1
end

cl_framework.lua

Framework.GetLocalIdentifier() → string | nil

Devuelve, en el cliente, el identificador único del jugador local.

lua
function Framework.GetLocalIdentifier()
    -- Config.Framework == 'custom'
    return nil
end

Framework.NotifyClient(message, notifyType)

Muestra una notificación al jugador local. notifyType: 'info' | 'success' | 'error'

lua
function Framework.NotifyClient(message, notifyType)
    -- Config.NotifySystem == 'custom'
end

Framework.OnPlayerLoaded(callback)

Registra un callback que se dispara cuando los datos del jugador están listos. Se usa para la sincronización inicial.

lua
function Framework.OnPlayerLoaded(callback)
    -- Config.Framework == 'custom'
    CreateThread(function() Wait(0); callback() end)
end

cl_keys.lua

Keys.IsLocked(vehicle) → boolean

Devuelve true si el vehículo está bloqueado en ese momento. Lo usa únicamente el sondeo opcional de aparcamiento automático (Config.AutomaticParking) para detectar cuándo el jugador bloquea su coche después de bajarse. Comprueba tanto el estado de bloqueo nativo como el state bag doorslockstate, sin salir nunca antes por un state bag desbloqueado, para que un bag obsoleto no oculte un bloqueo nativo real.

Parámetro Tipo Descripción
vehicle number Handle de entidad del vehículo.
lua
function Keys.IsLocked(vehicle)
    -- Native lock: 0=None 1=Unlocked 2=Locked 3=LockedForPlayer 4=StuckForPlayer
    if GetVehicleDoorLockStatus(vehicle) >= 2 then return true end
 
    local stateBagLock = Entity(vehicle).state.doorslockstate
    if stateBagLock ~= nil and stateBagLock >= 2 then return true end
 
    return false
end

Si la detección automática no es fiable con tu sistema de llaves, prescinde del sondeo y usa los hooks explícitos (onVehicleLocked / onVehicleUnlocked) documentados arriba en Integración del sistema de llaves.


cl_fuel.lua

Fuel.Get(vehicle) → number

Devuelve el nivel de combustible actual (0–100) de un vehículo.

Orden de autodetección: ox_fuel → LegacyFuel → ps-fuel → cdn-fuel → native.

lua
function Fuel.Get(vehicle)
    -- Config.FuelSystem == 'custom'
    return GetVehicleFuelLevel(vehicle)
end

Fuel.Set(vehicle, level)

Establece el nivel de combustible (0–100) de un vehículo. Llama siempre a SetVehicleFuelLevel como base y después al sistema activo por encima.

lua
function Fuel.Set(vehicle, level)
    -- Config.FuelSystem == 'custom'
    SetVehicleFuelLevel(vehicle, level + 0.0)
end