Les exports personnalisés et les correspondances de champs/états sont désormais configurables directement dans config/garages.lua, avec les adaptations avancées conservées. Voir GARAGE_CONFIGURATION.md pour le guide acheteur et les exemples.
CDT Admin utilise server/vehicle_bridge.lua pour consulter les véhicules,
vérifier leur propriétaire, les localiser, se téléporter vers le véhicule ou sa
destination, sauvegarder leurs propriétés et modifier garage/fourrière et frais.
Le menu, les permissions, le service staff, les vérifications des occupants et
les journaux des actions gardent leurs fonctions actuelles.
Deux fournisseurs indépendants
Configurer config/garages.lua, ou ces convars avant le démarrage de CDT Admin :
set cdt_admin:garages "qbx"
set cdt_admin:vehicles "qbx"
Les clés disponibles sont qbx, esx, jg, qs, cd, origen, okok, ou une clé
ajoutée dans providers. Le nom réel de ressource est également accepté.
garageschoisit les destinations, leurs positions, les changements de garage/fourrière et les frais.vehicleschoisit le registre des propriétaires et la sauvegarde.autorefuse plusieurs garages actifs. Pour la propriété, il utilise le garage sélectionné lorsqu'un export de lecture, un adaptateur ou un stockage SQL est déclaré pour lui ; sinon il utiliseqbx_vehicless'il est installé.qbxcôté véhicules fonctionne même siqbx_garagesest arrêté.
Un garage complet peut donc remplacer les deux dans CDT Admin : sélectionner
sa clé pour les deux rôles et renseigner ses opérations. Un garage remplaçant
uniquement les destinations peut conserver vehicles="qbx". Aucun appel ne
bascule silencieusement vers un autre registre après un échec.
Ce bridge supprime la dépendance de CDT Admin à qbx_vehicles avec un autre
registre. Il ne supprime pas les dépendances des autres ressources du serveur.
Le module de persistance du qbx_core installé utilise notamment
qbx_vehicles lorsqu'il est activé. Le désinstaller sur tout le serveur exige
donc de vérifier aussi les garages, concessionnaires et autres consommateurs.
API utilisées par les raccordements natifs
| Clé / ressource | Raccordements natifs utilisés | Adaptations nécessaires pour les fonctions CDT complètes |
|---|---|---|
qbx / qbx_garages + qbx_vehicles | Catalogue de garages, registre propriétaire, sauvegarde, changement garage/état et frais, audit vehicleSaved | Aucun remplacement de ces API ; validation en jeu après redémarrage |
esx / esx_garage 2.x officiel | getGarages, getImpounds ; lecture du schéma officiel owned_vehicles ; classe ESX ExtendedVehicle pour sauvegarder/supprimer les véhicules actifs | Écritures activables avec esxWritable=true ; frais individuels et audit indisponibles. Les anciennes versions et forks demandent un adaptateur |
jg / jg-advancedgarages v4 | getAllGarages pour les destinations/positions ; deleteOutsideVehicle pour le registre des véhicules sortis | Propriété, sauvegarde, changement destination/état, frais, audit. L'API décrit type comme la classe car/air/sea : préciser garage/depot et bucket via garageOverrides ou GetGarages |
qs / qs-advancedgarages | updatePersistentVehicleProps pour sauvegarder les propriétés quand QS est le fournisseur véhicule ; removeVehicleFromPersistent avant suppression | Catalogue des garages, registre propriétaire, destination précise/état, frais et audit. L'export impound(plate) ne choisit pas la destination ni les frais : il ne remplace pas ces opérations |
cd / cd_garage actuel | GetGarageLocations serveur pour destinations, positions, types garage/fourrière et classes véhicules | Registre propriétaire et mutations : la documentation publique ne fournit pas de contrat complet. Déclarer les opérations et la synchronisation nécessaires ; la version actuelle demande aussi cd_bridge |
origen / origen_garages | Sélection/configuration ; les mappings Qbox des tables et états sont documentés | Déclarer les destinations, la lecture/sauvegarde, changement garage/frais et audit, éventuellement via stockage SQL explicite. impoundVehicle(plate) seul ne conserve pas la destination choisie ni les frais |
okok / okokGarage | Sélection/configuration du fournisseur | Documentation consultée pour QBCore/ESX, sans garantie Qbox native. Adapter les opérations et le schéma réel ; ne pas assimiler parking, garage et état automatiquement |
Ces entrées ne signifient pas que tous les produits sont prêts sans configuration. Les tests des alternatives utilisent des doubles des API et des adaptateurs, pas les ressources commerciales. Les schémas de stockage et mutations non documentés ne sont pas devinés. Wasabi n'a pas été ajouté : aucune API de garage pertinente n'a été établie pendant cette recherche.
ESX Garage officiel 2.x
Lorsque esx_garage est le seul garage actif, auto sélectionne ses destinations
et son registre propriétaire. La version de la ressource doit commencer par
2. ; un ancien garage qui porte le même nom n'est pas assimilé à ce schéma.
Les fournisseurs commerciaux ne reçoivent jamais automatiquement ce mapping.
Les listes de garages et fourrières viennent des exports serveur getGarages
et getImpounds. Les identifiants communs aux deux listes sont refusés : CDT
utilise un identifiant unique de destination. Les positions proviennent de
entryPoint et getOutPoint.
La lecture filtre owned_vehicles.owner avec l'identifiant complet du
personnage, préfixe multicharacter compris. La plaque originale sert d'ID et
remplace toute plaque différente dans les propriétés JSON. Pour l'état,
stored=0 signifie sorti ; stored=1 avec pound rempli signifie fourrière,
sinon garé. La destination est pound ou parking selon ce cas.
Les écritures sont désactivées par défaut. Pour ce garage officiel seulement,
activer esxWritable=true dans config/garages.lua permet les transferts avec
confirmation par relecture. Les fonctions personnalisées de adapters.esx
restent prioritaires. Aucune table n'est créée ou modifiée au démarrage de CDT.
Un véhicule actif géré par ESX est sauvegardé avec setProps et supprimé avec
delete, après vérification du propriétaire et de l'entité : le registre ESX
est ainsi nettoyé. Un véhicule non enregistré utilise une sauvegarde SQL
filtrée et confirmée, puis DeleteEntity. La plaque et le modèle persistés
sont conservés. Une destination ne peut être écrite pendant qu'ESX conserve
encore le véhicule actif dans son registre.
Le tarif ESX est attaché à la fourrière. La modification individuelle des
frais est refusée dès la vérification préalable, avant toute suppression.
Ne pas envoyer depotPrice pour un transfert ESX. Aucun événement client
n'est utilisé pour contourner les contrôles du garage.
Cette implémentation vise la ressource officielle 2.x et sa classe véhicule
actuelle. Un fork, une autre persistance ou un autre garage ESX doit utiliser
ses propres adaptateurs. Le choix explicite vehicles="esx" exige aussi que
esx_garage soit démarré ; es_extended seul ne garantit pas ce stockage.
Adaptations dans config/garages.lua
providers permet de changer le nom de ressource ou d'ajouter un fournisseur.
Une nouvelle clé doit au minimum préciser resource. vehicleResource est
facultatif si le même script gère les deux rôles. Renommer une ressource dans
CDT ne garantit pas que le fournisseur lui-même accepte ce renommage ; JG
demande de garder son nom d'origine.
adapters est indexé par clé du fournisseur ou nom de ressource. Chaque fonction
remplace seulement l'opération correspondante. Le fichier contient les modèles
de signatures. Il reste exclusivement côté serveur ; redémarrer CDT après
modification.
| Fonction | Arguments | Résultat |
|---|---|---|
GetPlayerVehicles | citizenid | liste de véhicules normalisés, ou nil + erreur |
GetPlayerVehicle | id, citizenid | véhicule normalisé, ou nil + erreur ; citizenid peut être nil pour un audit serveur |
GetGarages | aucun | table indexée par nom texte de destination |
SaveVehicle | entité, options {props,coords}, véhicule normalisé | true après sauvegarde réelle, sinon false + erreur |
SetVehicleGarage | véhicule normalisé, nom destination, définition destination | true après changement destination et état, sinon false + erreur |
SetVehicleDepotPrice | véhicule normalisé, prix | true après mutation réelle, sinon false + erreur |
MatchesEntity | entité, véhicule normalisé | booléen ; comparaison native par vehicleid ou plaque non vide sinon |
DeleteVehicle | entité, véhicule normalisé | true après suppression réelle et retrait des persistances/registres externes |
CanMove | véhicule, destination, définition, prix optionnel, véhicule actif | true si toute l'opération peut être effectuée, sinon false + erreur |
InstallAudit | callback reportSaved(id,citizenid) | fonction de nettoyage des callbacks serveur installés |
AfterStorageWrite | véhicule, champs écrits | synchronisation éventuelle après une écriture SQL confirmée |
Un véhicule normalisé fournit {id, citizenid, modelName, props, garage, state, depotPrice, coords?}. props.plate contient la plaque. Les états sont : 0 sorti,
1 garé, 2 fourrière. Les identifiants peuvent être numériques ou textuels, par
exemple une plaque ou un UUID ; le bridge revalide le propriétaire côté serveur
à chaque action. Ne jamais prendre le propriétaire ou les propriétés persistées
directement depuis des données du menu.
Une destination fournit {label, type, accessPoints={{coords={x,y,z,w}}}, bucket?}.
Pour les adaptateurs, type vaut garage ou depot. bucket vaut zéro par
défaut et permet une position dans une instance explicitement configurée.
providers.<clé>.garages peut fournir une liste statique si aucun export public
ne donne les destinations. JG accepte garageOverrides pour compléter les
destinations renvoyées par son export.
Les retours void ne sont pas traités comme des succès de mutation. Un adaptateur doit confirmer l'effet réel avant de renvoyer true. Les capacités de déplacement sont vérifiées avant de supprimer un véhicule actif. Un échec des frais après un changement de garage est signalé comme résultat partiel, comme auparavant.
La suppression native retire d'abord la persistance Qbox, puis les registres
JG/Quasar lorsqu'ils sont sélectionnés, puis l'entité via qbx_core:DeleteVehicle.
Utiliser DeleteVehicle dans l'adaptateur si un autre système de persistance
doit être désactivé. InstallAudit doit écouter des confirmations serveur
de sauvegarde ; il ne doit pas faire confiance à un événement client.
Stockage SQL facultatif
Le fichier propose un exemple de mapping providers.origen.storage, désactivé
par défaut. Les mappings owner/mods/state/garage pour Qbox sont documentés par
Origen ; les autres colonnes de l'exemple doivent correspondre au serveur réel.
La déclaration est un choix explicite du responsable serveur, pas une migration
automatique. Aucun SQL n'est exécuté au chargement du bridge.
Le mapping columns associe les champs normalisés aux colonnes réelles.
states traduit les valeurs out/stored/impounded. Les lectures filtrent par
propriétaire et, pour un véhicule, par identifiant. Les valeurs utilisent des
paramètres SQL ; les noms de tables/colonnes sont validés. Les écritures sont
refusées tant que writable n'est pas true. Elles filtrent également par
propriétaire et leur effet est vérifié par relecture de la ligne.
Ne pas activer ces écritures lorsque le garage repose sur plusieurs tables ou un cache que la déclaration ne synchronise pas. Dans ce cas, utiliser ses API via les adaptateurs. Le stockage ne met pas à jour les registres de persistence à la place du fournisseur. L'exemple n'affirme pas connaître le schéma complet des dernières versions commerciales.
Sources
- ESX Garage officiel : registre et exports
- ESX Garage officiel : accès aux véhicules
- ESX Garage officiel : modèle de données
- ESX Core : classe ExtendedVehicle
- Qbox : qbx_garages
- Qbox : qbx_vehicles
- Qbox : suppression et persistance
- JG v4 : API serveur
- JG : installation
- Quasar : API garages
- Codesign : exports
- Codesign : installation
- Origen : exports
- Origen : mappings et états
- okok : documentation
Vérifications locales
tests/vehicle-bridge.lua, tests/vehicle-storage.lua, tests/gameplay.lua,
tests/player-self-actions.lua, tests/integrations.lua et
tests/vehicles-ui.cjs couvrent notamment la propriété, les deux rôles séparés
ou réunis, l'absence de qbx_vehicles, la sélection ambiguë, les IDs texte,
les droits, les occupants, les échecs, la persistance et les écritures SQL.
Une validation en jeu avec chaque fournisseur configuré reste nécessaire.
tests/garage-esx-api.lua vérifie les exports officiels, le préfixe personnage,
les états ESX, les plaques avec espaces, la lecture seule par défaut,
les garde-fous avant transfert, les frais refusés et le nettoyage du registre
véhicule ESX via son API. Ces tests utilisent des doubles des API publiques.
Compléments des raccordements présents dans CDT
Le catalogue Codesign est maintenant raccordé à l'export serveur
GetGarageLocations. Son garage_id sert de destination, garage_label de
libellé, location_type=impound de fourrière et coords.open de position.
garageOverrides peut préciser les buckets. Les garages privés et de métier
restent identifiés par accessType : ce catalogue administratif ne constitue
pas une autorisation de stockage pour les joueurs.
Les ressources commerciales ci-dessous n'ont pas été trouvées dans les ressources locales lors de cette vérification. Un nom reconnu permet de sélectionner le produit, mais ne garantit pas que toutes ses fonctions sont raccordées. Voici précisément ce qui empêche encore une intégration complète :
| Fournisseur actuel | API publique exploitable déjà raccordée | Contrat restant nécessaire |
|---|---|---|
| JG Advanced Garages v4 | Catalogue getAllGarages ; registre extérieur deleteOutsideVehicle | Lecture véhicules/propriétaires, propriétés persistées, destination/état/frais, synchronisation et confirmation de sauvegarde. La documentation renvoie au SQL install/run-esx.sql du produit, absent localement |
| Quasar Advanced Garages actuel | Sauvegarde persistante updatePersistentVehicleProps ; retrait removeVehicleFromPersistent | Catalogue serveur, propriétaires, destination/état/frais et audit. La documentation renvoie au dossier SQL livré avec l'achat, absent localement. impound(plate) ne choisit ni destination ni frais |
| Codesign Garage actuel | Catalogue GetGarageLocations | Registre propriétaire, sauvegarde, transfert, frais, retrait du registre extérieur, audit. GetVehicleImpoundData donne des informations de fourrière, pas un registre complet des véhicules possédés |
| Origen Garages actuel | Infrastructure d'adaptateurs ; mappings ESX documentés | Catalogue et schéma exact de la version installée, cache et opérations save/move/delete/audit. L'export impoundVehicle(plate) ne choisit pas une destination et le tarif documenté est global |
| okokGarage actuel | Infrastructure d'adaptateurs | Version installée, signification réelle des états et colonnes, catalogue et API de mutations/synchronisation/audit. Les instructions SQL publiques seules ne définissent pas ces contrats |
Pour compléter ces fournisseurs, les fichiers accessibles de la version
achetée doivent être présents : manifeste/version, configuration, SQL et
fonctions d'intégration serveur ou bridge fournis par l'éditeur. CDT possède
déjà les points d'entrée GetPlayerVehicles, GetPlayerVehicle, SaveVehicle,
SetVehicleGarage, SetVehicleDepotPrice, DeleteVehicle, CanMove et
InstallAudit. Les opérations indisponibles échouent explicitement ; aucune
écriture générique sur une table commerciale n'est activée pour les simuler.
Les références et signatures ci-dessus décrivent les raccordements présents dans CDT ; elles ne certifient pas les dernières versions des produits tiers. Les fichiers tests/ cités appartiennent au dépôt de développement et ne sont pas inclus dans le ZIP.
