Aller au contenu
Blog

Servir les images d’items d’ox_inventory depuis un CDN

Déplacez web/images d’ox_inventory vers un CDN avec un zip et un convar : resource plus légère, connexions plus rapides, images modifiables sans restart.

Par Termi

8 min de lecture
  • ox_inventory
  • CDN
  • Performance
Sur cette page

Chaque item d’ox_inventory a un PNG dans ox_inventory/web/images. Sur un serveur avec quelques centaines d’items personnalisés, ce dossier atteint vite plusieurs dizaines de mégaoctets, et tout cela fait partie d’une resource que chaque joueur télécharge avant de pouvoir jouer. Ce guide déplace les images vers un CDN : un upload de zip, une ligne dans server.cfg, et l’inventaire charge ses images depuis cdn.fivedock.dev.

Pourquoi sortir les images de la resource

Le fxmanifest.lua d’ox_inventory liste web/images/*.png sous files, ce qui fait de chaque image un fichier de la resource : le serveur l’envoie à chaque client, et le client la garde dans son cache FiveM. Cela a quelques coûts :

  • Un nouveau joueur télécharge tout le dossier avant d’apparaître, y compris les images d’items qu’il n’aura jamais en main, donc la connexion est plus longue.
  • FiveM met en cache les fichiers de resource par hash, une image inchangée n’est donc pas téléchargée deux fois. Mais chaque image que vous ajoutez ou remplacez est un fichier de plus que chaque joueur télécharge à sa prochaine connexion.
  • Un nouveau fichier dans la resource n’atteint les joueurs qu’après un restart d’ox_inventory, et sur un serveur en production c’est la resource que vous voulez le moins redémarrer.

Avec un CDN, les images ne font plus du tout partie de la resource. La page navigateur de l’inventaire ne demande une image que quand elle doit afficher cet item, et la garde dans son cache HTTP pour la fois suivante. Un joueur qui n’ouvre jamais l’armurerie ne télécharge jamais les images d’armes.

Comment ox_inventory trouve une image

ox_inventory lit le convar répliqué inventory:imagepath et construit chaque lien d’image sous la forme <imagepath>/<item name>.png. La valeur par défaut pointe dans la resource elle-même :

image links
default  nui://ox_inventory/web/images/burger.png
CDN      https://cdn.fivedock.dev/o/<your-workspace>/items/burger.png

Il lui faut donc seulement un dossier sur le web où chaque image porte exactement le nom de son item. Deux détails tirés du code source d’ox_inventory :

  • L’extension est toujours .png. Gardez les images en fichiers PNG nommés d’après l’item : burger.png, pas Burger.PNG ni burger.webp.
  • Le client.image propre à un item reste prioritaire. Une URL complète y est utilisée telle quelle ; un simple nom de fichier comme burger_deluxe.png est cherché sous l’imagepath, et passe donc au CDN avec tout le reste.

Envoyer les images

Sur FiveDock, un fichier envoyé avec une clé reçoit un lien qui ne change jamais : https://cdn.fivedock.dev/o/<your-workspace>/<key>. Envoyez les images de façon que burger.png ait la clé items/burger.png ; l’imagepath est alors …/items. Le slug de votre organisation est le nom court affiché dans le panel, et c’est aussi le nom de votre bucket S3.

Depuis le panel

  1. Zippez le contenu du dossier, pas le dossier lui-même : sous Windows, ouvrez ox_inventory/web/images, sélectionnez tous les fichiers avec Ctrl+A, faites un clic droit et choisissez Envoyer vers → Dossier compressé, ou lancez zip -r ../images.zip . dans ox_inventory/web/images.
  2. Dans le panel, ouvrez Fichiers, créez un dossier nommé items et ouvrez-le.
  3. Cliquez sur Envoyer un fichier et déposez le zip. Garder les noms de fichiers est activé par défaut pour les archives ; laissez-le activé.

FiveDock décompresse l’archive et stocke chaque image comme un fichier à part. Les dossiers de l’archive sont conservés, c’est pourquoi vous zippez les images et non le dossier images : burger.png devient items/burger.png, pas items/images/burger.png. Tout ce qui n’est pas une image acceptée, comme un readme.txt oublié, est ignoré et listé dans le résultat.

Par l’API

La même chose en une requête, avec un token d’API (fd_live_…, créé sur la page Jetons) ayant le scope files:write :

bash
cd ox_inventory/web/images
zip -r ../images.zip .

curl -X POST https://api.fivedock.dev/api/v3/file/archive \
  -H "Authorization: Bearer fd_live_…" \
  -F "file=@../images.zip" \
  -F "path=items"
response
{
  "status": "ok",
  "data": {
    "uploaded": [
      {
        "key": "items/burger.png",
        "url": "https://cdn.fivedock.dev/o/my-city/items/burger.png",
        "fileUrl": "https://cdn.fivedock.dev/f/…png",
        "filename": "burger.png",
        "path": "/items",
        "size": 18233,
        "mime_type": "image/png",
        "deduplicated": false
      }
    ],
    "skipped": [{ "name": "readme.txt", "reason": "unsupported_type" }]
  }
}

url est le lien à clé stable ; fileUrl est le lien propre à chaque upload que reçoit aussi tout fichier. Une archive peut contenir jusqu’à 5 000 fichiers, ce qui couvre presque n’importe quelle liste d’items. Si la vôtre est plus grosse, envoyez-la en deux archives ou utilisez rclone.

Avec rclone (S3)

Si vous gardez votre serveur dans Git ou le déployez par scripts, l’endpoint S3 est la voie la plus confortable. Configurez un remote rclone nommé fivedock comme dans la doc des uploads, puis :

rclone
# my-city = your workspace slug (it is also your S3 bucket name)
rclone sync ./ox_inventory/web/images fivedock:my-city/items --dry-run
rclone sync ./ox_inventory/web/images fivedock:my-city/items

rclone sync aligne la destination sur la source, ce qui inclut la suppression des fichiers de items absents de votre dossier local. Lancez-le d’abord avec --dry-run, ou utilisez rclone copy si vous ne faites qu’ajouter et mettre à jour.

Les objets que vous envoyez via S3 sont aussi des fichiers à clé, ils ont donc les mêmes liens stables.

Pointer ox_inventory vers le CDN

Ajoutez le convar dans server.cfg, au-dessus de la ligne qui démarre ox_inventory :

server.cfg
setr inventory:imagepath "https://cdn.fivedock.dev/o/<your-workspace>/items"

ensure ox_inventory
  • Utilisez setr, pas set : l’UI de l’inventaire tourne côté client, et seuls les convars setr sont répliqués aux clients.
  • Pas de slash final, ox_inventory l’ajoute.
  • ox_inventory lit le convar à son démarrage : redémarrez-le (ou le serveur) une fois.

Avant de redémarrer, ouvrez une image dans votre navigateur pour vérifier le lien, par exemple https://cdn.fivedock.dev/o/<your-workspace>/items/burger.png.

Retirer les images de la resource

Connectez-vous au serveur, ouvrez votre inventaire et une boutique ou deux, et vérifiez que les images se chargent. Une fois que c’est le cas, sortez les fichiers PNG de ox_inventory/web/images et gardez-les ailleurs : ce dossier est désormais la source de vos uploads, il ne fait plus partie du serveur.

Quand vous mettrez ox_inventory à jour plus tard, laissez web/images hors de la copie, ou videz-le de nouveau ensuite.

Ajouter et remplacer des images plus tard

Pour ajouter l’image d’un nouvel item ou en corriger une ancienne, envoyez le PNG avec la clé qu’il doit avoir : Envoyer un fichier dans le dossier items du panel avec Garder les noms de fichiers activé, ou l’API :

bash
curl -X POST https://api.fivedock.dev/api/v3/file \
  -H "Authorization: Bearer fd_live_…" \
  -F "[email protected]" \
  -F "key=items/burger.png"

Si items/burger.png existe déjà, l’upload le remplace derrière le même lien ; l’ancienne version est conservée 7 jours avant d’être purgée. Les liens à clé sont mis en cache 5 minutes puis revalidés : les joueurs voient la nouvelle image en cinq minutes environ, sans restart et sans rien de nouveau à télécharger à la connexion.

Si une image ne s’affiche pas

  • Un item a une image cassée. Le nom du fichier doit correspondre exactement au nom de l’item, casse comprise : WEAPON_PISTOL.png pour WEAPON_PISTOL. Les clés construites à partir des noms de fichiers transforment les espaces en - et les autres caractères inhabituels en _, donc une image nommée my item.png devient my-item.png.
  • Toutes les images sont cassées. Ouvrez l’imagepath plus /burger.png dans un navigateur. Un 404 signifie en général que le dossier est décalé (items/images/burger.png au lieu de items/burger.png) ou que le slug de l’organisation est faux. Vérifiez aussi que vous avez utilisé setr.
  • L’ancienne image est toujours là après un remplacement. Laissez cinq minutes ; les joueurs gardent la copie précédente jusqu’à l’expiration de leur cache.
  • Un item ignore le CDN. Il définit sans doute client.image avec une URL complète. Retirez-le, ou faites-le pointer vers le CDN.

Les mêmes liens à clé fonctionnent pour toute autre image que votre UI charge, comme les vignettes de véhicules ou les mugshots : envoyez une fois et utilisez le lien partout où vous en avez besoin.

Questions fréquentes

D’où ox_inventory charge-t-il les images des items ?

Du convar répliqué inventory:imagepath, qui vaut par défaut nui://ox_inventory/web/images, soit le dossier web/images dans la resource. Pour chaque item, ox_inventory construit le lien <imagepath>/<item name>.png. Le client.image propre à un item prime : une URL complète est utilisée telle quelle, et un simple nom de fichier est cherché sous l’imagepath.

Comment changer l’imagepath d’ox_inventory ?

Ajoutez setr inventory:imagepath "https://cdn.fivedock.dev/o/<your-workspace>/items" à server.cfg au-dessus de ensure ox_inventory, sans slash final, et redémarrez ox_inventory une fois. Il faut setr, car l’UI de l’inventaire tourne côté client et seuls les convars setr atteignent les clients. Chaque image doit ensuite se trouver à cette adresse, nommée exactement comme son item, avec l’extension .png.

Pourquoi les images de mes items ox_inventory ne s’affichent-elles pas ?

En général, le nom du fichier ne correspond pas exactement au nom de l’item, majuscules et minuscules comprises, ou le fichier n’est pas un .png. Si toutes les images manquent, ouvrez l’imagepath plus /burger.png dans un navigateur : un 404 signifie que le dossier ou le slug de l’organisation dans le chemin est faux. Vérifiez aussi que le convar a été défini avec setr et non set.

ox_inventory peut-il utiliser des images d’items en WebP ou JPG ?

Seulement item par item. La recherche par imagepath ajoute toujours .png au nom de l’item, donc un burger.webp à côté n’est jamais demandé. Définissez le client.image de l’item sur burger.webp, qui est cherché sous l’imagepath, ou sur une URL complète, et la page NUI de l’inventaire le charge comme le ferait n’importe quel navigateur.

Dois-je redémarrer ox_inventory pour changer l’image d’un item ?

Pas quand les images sont sur un CDN. Envoyez le nouveau PNG sur la même clé, comme items/burger.png, et les joueurs le voient en cinq minutes environ, quand leur copie en cache expire. Les images dans web/images n’atteignent les joueurs qu’après un restart d’ox_inventory.

Tous les articles