Logo ACStudioACSTUDIOFIVEM DEVELOPMENT
cdt_admin / DOCUMENTATION

Configurer votre inventaire

Pour une intégration simple, modifiez uniquement config/inventory.lua. Ce fichier regroupe le fournisseur, la ressource, les images, les capacités de secours et les appels personnalisés serveur/client. Redémarrez cdt_admin après modification. Ces réglages ne sont pas enregistrés dans la configuration SQL ni dans le menu en jeu.

1. Inventaire déjà intégré

Choisissez provider dans le fichier :

ValeurRessource par défaut
autoLe seul inventaire connu réellement démarré
oxox_inventory
qsqs-inventory
tgianntgiann-inventory (API Ox de la version 2)
origenorigen_inventory
corecore_inventory
codemcodem-inventoryv2
wasabiwasabi_inventory
ak47ak47_inventory
esxInventaire natif de es_extended, avec CustomInventory désactivé
customRessource définie dans custom.resource

La compatibilité dépend de l'API et de la version réellement installées. Le tableau présente les intégrations existantes de CDT, pas une garantie pour toutes les versions commerciales. Consultez INVENTORY_BRIDGE.md pour le détail des appels natifs et des transferts.

auto refuse de choisir entre plusieurs inventaires connus actifs. Il ne confond pas un alias provide 'ox_inventory' avec une véritable installation Ox. Le natif ESX est utilisé seulement sans autre fournisseur sélectionné et si ESX n'utilise pas un inventaire personnalisé.

Les anciennes convars restent prioritaires : cdt_admin:inventory, cdt_admin:inventoryImages, cdt_admin:inventorySlots et cdt_admin:inventoryMaxWeight. Retirez-les pour configurer ces valeurs uniquement dans le fichier. Si vous conservez le choix par convar, utilisez une valeur répliquée (setr) afin que serveur et clients sélectionnent le même inventaire.

Exemple : modifier le nom d'une ressource et son chemin d'images :

provider='qs',
providers={
    qs={resource='mon_quasar',images='nui://mon_quasar/html/images'},
},

Les images configurées globalement dans images passent avant le chemin du fournisseur. Sinon, CDT utilise celui du fournisseur et les règles natives Ox/CodeM. Une URL complète fournie par l'objet reste prioritaire. Pour AK47 ou un inventaire sans chemin connu, renseignez explicitement le chemin de votre version.

slots et maxWeight servent uniquement si la lecture d'inventaire ne fournit pas ces capacités. La valeur 0 signifie qu'aucune capacité fixe n'a été renseignée. Utilisez l'unité de poids du fournisseur et des valeurs correspondant à votre serveur. Les champs slots et maxWeight peuvent également être placés dans un fournisseur précis. Les capacités variables par joueur doivent être renvoyées par GetInventory.

2. Inventaire personnalisé

Voici un exemple complet. Les noms mon_inventaire, GetItemList, GetInventory, etc. sont des exemples, à remplacer par les appels documentés par votre inventaire et leur ordre exact de paramètres.

return {
    provider='custom',
    images='',slots=0,maxWeight=0,
    providers={},
    custom={
        resource='mon_inventaire',
        images='nui://mon_inventaire/images',
        family='custom',
        server={
            Items={type='export',name='GetItemList',args={},lookup=true},
            GetInventory={type='export',name='GetInventory',args={'$playerId'}},
            CanCarryItem={type='export',name='CanCarryItem',args={'$playerId','$item','$count'}},
            AddItem={type='export',name='AddItem',args={'$playerId','$item','$count'}},
            RemoveItem={type='export',name='RemoveItem',args={'$playerId','$item','$count','$slot','$metadata'}},
        },
        client={
            openInventory={type='event',name='mon_inventaire:open',args={}},
            close={type='event',name='mon_inventaire:close',args={}},
            isOpen={type='state',key='invOpen',value=true},
        },
    },
}

server contient les appels exécutés sur le serveur ; client contient ceux exécutés chez le joueur concerné. Les exports ciblent toujours la ressource du fournisseur sélectionné. Les événements sont locaux au côté choisi ; cette configuration ne permet pas d'envoyer directement un événement réseau client vers le serveur.

Pour un inventaire personnalisé, renseignez au minimum Items, GetInventory, AddItem et RemoveItem pour les fonctions d'administration souhaitées. GetSlot peut être omis : CDT lit alors l'emplacement dans GetInventory. CanCarryItem est facultatif si votre export d'ajout vérifie déjà la capacité ; configurez-le si votre inventaire peut déposer les objets au sol quand il est plein.

family='ox' permet de conserver les appels natifs génériques Ox seulement si votre ressource expose effectivement cette API. Sinon, laissez family='custom' : les appels manquants ne sont pas devinés. Pour les fournisseurs déjà intégrés, une opération absente garde son implémentation native. Une opération à false est désactivée ; une configuration invalide est refusée sans basculer vers une autre API.

3. Opérations et paramètres disponibles

CôtéOpérationParamètres de substitution
ServeurItems$name (facultatif : objet demandé)
ServeurGetInventory$playerId
ServeurGetSlot$playerId, $slot
ServeurCanCarryItem, AddItem$playerId, $item, $count
ServeurRemoveItem$playerId, $item, $count, $metadata, $slot, $ignore, $strict
ServeuropenOwn, close$playerId
ServeurforceOpenInventory$playerId (staff), $kind, $targetId (cible)
ClientItems$name, $playerId
ClientopenInventory, close, isOpen$playerId
ClientweaponWheel$enabled, $playerId

$playerId est toujours un identifiant serveur, même côté client. Choisissez les paramètres réellement attendus par votre API ; un appel client local n'attend souvent aucun identifiant. $metadata, $slot, $ignore, $strict et $name peuvent être absents suivant l'appel. CDT conserve la position de ces arguments, y compris si un argument intermédiaire vaut nil ou false.

args est une liste sans trous. Les chaînes, nombres, booléens et tableaux imbriqués sont acceptés, avec substitution dans ces tableaux. Les noms d'API et paramètres proviennent du fichier installé, pas d'une requête de l'interface.

Les lectures (Items, GetInventory, GetSlot, CanCarryItem) et les mutations (AddItem, RemoveItem) nécessitent des exports serveur avec retour. Les événements sont autorisés pour l'ouverture, la fermeture et la roue d'armes, mais pas pour lire des objets ou confirmer un don/retrait.

4. Formats de retour

  • Items renvoie un registre indexé par nom d'objet, ou la définition demandée. Si l'export renvoie toujours le registre complet, utilisez lookup=true pour que CDT recherche $name automatiquement.
  • GetInventory renvoie {items=...,weight=...,maxWeight=...,slots=...}, {content=...}, ou directement une liste d'objets. Chaque objet doit avoir name, slot (ou une clé numérique d'emplacement), count ou amount, et éventuellement metadata ou info, label, weight, image, bridgeId. CDT normalise ces champs et copie les métadonnées.
  • GetSlot renvoie l'objet de l'emplacement demandé au même format, ou nil si vide.
  • CanCarryItem doit renvoyer true pour autoriser l'ajout. Un retour absent ne prouve pas la capacité.
  • AddItem et RemoveItem peuvent renvoyer true ou false, message. Sans retour booléen, CDT relit les quantités et exige la variation exacte. Un export absent ou une modification non confirmée ne devient pas un succès.

Si une API renvoie une enveloppe, configurez resultPath pour lire un champ imbriqué. Les segments correspondent à des clés texte, sans exécuter d'expression. Exemple pour {data={items=registre}} :

Items={type='export',name='Catalogue',args={},resultPath='data.items',lookup=true},

Un format nécessitant des calculs, une conversion de catalogue en liste, ou des identifiants de piles spécifiques doit passer par un adaptateur avancé.

5. Confirmer l'interface ouverte

Une ouverture personnalisée doit être confirmée par isOpen, même si l'export d'ouverture renvoie true. Vous pouvez lire un export client :

isOpen={type='export',name='IsInventoryOpen',args={}},

Ou un champ réel de LocalPlayer.state :

isOpen={type='state',key='invOpen',value=true},

Adaptez la clé et la valeur à votre version. Une interface qui ne s'ouvre pas réellement est refusée. Un événement de fermeture confirme seulement son déclenchement. Pour piloter l'ouverture personnelle depuis un export/événement serveur, renseignez server.openOwn ; CDT confirme également l'état auprès du client ciblé.

6. Inspection d'un autre joueur et options avancées

La consultation et les dons/retraits peuvent utiliser le panneau CDT, avec ses permissions, sa protection de cible, ses motifs, ses snapshots et son anti-rejeu. L'ouverture de l'interface native d'un autre joueur exige en plus le contrôle serveur des transferts et une confirmation après l'opération réelle. Déclarer server.forceOpenInventory ne désactive pas cette exigence. Aucun réglage transfersReady=true dans ce fichier partagé n'active ces droits.

Pour raccorder les transferts, enchaîner plusieurs appels, interpréter des retours complexes ou convertir les identifiants, conservez les fonctions avancées dans config/inventory_server.lua et config/inventory_client.lua. Elles sont prioritaires sur les appels simples du côté concerné. Les adaptateurs enregistrés par la ressource inventaire conservent également leur priorité. Le raccordement des hooks et des confirmations fiables est documenté dans INVENTORY_BRIDGE.md.

Tous les fichiers de cette distribution sont exclus de la protection Asset Escrow (escrow_ignore { '**/*' }), y compris les trois configurations d’inventaire. Les fichiers commun et client sont distribués aux joueurs ; les fonctions privées restent dans le fichier serveur.

Vérifier l'installation

  1. Démarrez l'inventaire avant cdt_admin, choisissez le fournisseur et redémarrez cdt_admin.
  2. Avec un staff autorisé en service, consultez un inventaire contenant plusieurs piles et métadonnées.
  3. Testez un don, un retrait ciblé et un refus lorsque l'inventaire est plein. Vérifiez les quantités et les logs.
  4. Vérifiez les images, poids, capacités et l'ouverture personnelle. Testez sur un second joueur pour confirmer la cible.

Les tests automatisés couvrent les paramètres et les contrats du bridge. L'intégration avec votre version réelle d'inventaire doit être validée en jeu.

← Tous les guides