Início › Documentação › Personalização · origen_parking

Personalização · origen_parking

A pasta custom/ permite-te integrar qualquer framework, sistema de chaves ou sistema de combustível sem mexer no núcleo. Todos os ficheiros aqui presentes sobrevivem às atualizações.

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

Devolve o identificador único de um jogador (citizenid / license). É chamado em cada ação de estacionar ou recuperar.

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

Framework.GetVehicleOwner(plate) → string | nil

Devolve o identificador do proprietário de uma matrícula a partir da tabela de veículos da framework.

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

Framework.SetVehicleStorageState(plate, stored)

Marca um veículo como guardado (stored = true) ou fora (stored = false) na tabela de veículos da framework.

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

Framework.HasAdminPermission(source, permission) → boolean

É chamado em todos os callbacks de administração. Os sistemas de permissões são verificados por esta ordem:

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

Framework.Notify(source, message, ntype)

Envia uma notificação a um jogador. ntype: 'info' | 'success' | 'error'

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

Framework.GetGarages() → table[]

Devolve uma lista de garagens para o painel de administração. Cada entrada: { id, name, label }.

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

Framework.GetMoney(source) → number

Devolve o saldo em dinheiro de um jogador. É usado pelo sistema de custo de estacionamento.

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

Framework.RemoveMoney(source, amount) → boolean

Desconta dinheiro a um jogador. Devolve true em caso de sucesso.

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

Framework.GetVehicleState(plate) → number | nil

Devolve o estado de armazenamento de um veículo segundo a tabela da framework (1 = fora, 0 = guardado, ou nil se não for encontrado).

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

Integração do sistema de chaves

O sistema de estacionamento comunica com o teu sistema de chaves através de dois ficheiros ponte: custom/sv_keys.lua (dar chaves e definir o bloqueio) e custom/cl_keys.lua (ler o estado do bloqueio). O caminho que corre depende de Config.KeySystem:

Config.KeySystem Comportamento
qbx_vehiclekeys GiveKeys + SetLockState através dos exports do qbx, com alternativa nativa.
qb-vehiclekeys GiveKeys através do export do qb, bloqueio aplicado com o nativo + state bag.
qs-vehiclekeys GiveKeys + setLocked através dos exports do qs, com alternativa nativa.
rk-keys addKey através do export do rk, bloqueio nativo.
none Não são dadas chaves, os veículos aparecem desbloqueados.
custom Implementas a ponte em sv_keys.lua / cl_keys.lua.

Seja qual for o Config.KeySystem, a forma recomendada de controlar o estacionar/desestacionar a partir do teu sistema de chaves são os hooks de cliente explícitos abaixo. São determinísticos e executam todas as verificações de elegibilidade, sem adivinhar nada.


Chama estes exports de cliente a partir do teu sistema de chaves sempre que o jogador bloquear ou desbloquear um veículo. O sistema de estacionamento trata do resto (verificações de elegibilidade, estacionar/desestacionar no servidor). Ambos aceitam um handle de entidade do veículo e não fazem nada se o veículo não for elegível.

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

Ligação a partir de um evento de bloqueio/desbloqueio (a maioria dos sistemas de chaves de qb / esx dispara um):

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)

Ligação a partir do state bag do bloqueio das portas (qbx_vehiclekeys e semelhantes publicam 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)

Os sistemas de chaves que só usam nativos bloqueiam o carro no servidor, pelo que o cliente dono da entidade nem sempre consegue observar o bloqueio através da verificação nativa periódica. Para esses sistemas, os hooks explícitos acima são o único gatilho fiável: usa-os em vez de Config.AutomaticParking.


sv_keys.lua

Keys.GiveKeys(source, entity, plate)

Dá as chaves do veículo a um jogador quando este aparece. Só corre quando Config.GiveKeysOnSpawn = true. Cada ramo verifica se o recurso de chaves está em started e envolve o export em pcall, pelo que um sistema de chaves em falta nunca estraga o aparecimento.

Parâmetro Tipo Descrição
source number ID de servidor do jogador que recebe as chaves.
entity number Handle de entidade do veículo (pode ser 0 se ainda não tiver aparecido: usa plate).
plate string Matrícula do veículo.

Suportados de origem: qbx_vehiclekeys, qb-vehiclekeys, qs-vehiclekeys, rk-keys. Para custom, acrescenta a tua própria chamada ao export:

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

Keys.SetLock(entity, locked)

Bloqueia ou desbloqueia uma entidade de veículo no servidor. Só corre quando Config.LockVehiclesOnSpawn = true. locked = true → bloqueado (estado 2), false → desbloqueado (estado 1). Todos os ramos recorrem ao nativo + state bag para que os outros jogadores vejam o veículo estacionado como bloqueado.

Parâmetro Tipo Descrição
entity number Handle de entidade do veí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

Devolve, no cliente, o identificador único do jogador local.

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

Framework.NotifyClient(message, notifyType)

Mostra uma notificação ao jogador local. notifyType: 'info' | 'success' | 'error'

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

Framework.OnPlayerLoaded(callback)

Regista um callback que é disparado quando os dados do jogador estão prontos. Usa-se para a sincronização inicial.

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

cl_keys.lua

Keys.IsLocked(vehicle) → boolean

Devolve true se o veículo estiver bloqueado nesse momento. É usado apenas pela verificação periódica opcional de estacionamento automático (Config.AutomaticParking) para detetar quando o jogador bloqueia o carro depois de sair. Verifica tanto o estado de bloqueio nativo como o state bag doorslockstate, sem nunca sair mais cedo por causa de um state bag desbloqueado, para que um bag desatualizado não esconda um bloqueio nativo real.

Parâmetro Tipo Descrição
vehicle number Handle de entidade do veí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

Se a deteção automática não for fiável no teu sistema de chaves, dispensa a verificação periódica e usa os hooks explícitos (onVehicleLocked / onVehicleUnlocked) documentados acima em Integração do sistema de chaves.


cl_fuel.lua

Fuel.Get(vehicle) → number

Devolve o nível de combustível atual (0–100) de um veículo.

Ordem de deteção automática: ox_fuel → LegacyFuel → ps-fuel → cdn-fuel → native.

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

Fuel.Set(vehicle, level)

Define o nível de combustível (0–100) de um veículo. Chama sempre SetVehicleFuelLevel como base e depois o sistema ativo por cima.

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