Agency Docs
QBESXStandalone

Agency-Phone Stockage des Médias

Désormais avec AgencyOS27 : une mise à jour gratuite pour tous ceux qui ont déjà le téléphone.

v27.1.1Payant8 Pages

Où sont stockés les photos, vidéos et messages vocaux

Chaque photo, clip vidéo, enregistrement d'écran et message vocal de Agency Phone est enregistré par le script lui-même, à partir de la version 27.1.1. Vous choisissez l'emplacement :

StockageMise en placeAdapté pour
Local (par défaut)Aucune. Fonctionne dès l'installation.Tous les serveurs. Les fichiers restent sur votre propre serveur, dans votre base de données.
Cloudflare R2Environ 10 minutes, une seule fois. Gratuit jusqu'à 10 Go.Les serveurs avec beaucoup de vidéo, ou un très grand nombre de joueurs.

Fivemanage et Discord ne sont plus utilisés comme stockage. Les webhooks Discord restent disponibles pour les logs.

Stockage local (par défaut)

Il n'y a rien à configurer. Le script crée deux tables dans votre base de données à son premier démarrage (agency_media et agency_media_parts) et y stocke les fichiers. Vous avez uniquement besoin d'oxmysql, dont le script a de toute façon besoin.

Ce que cela signifie pour vous :

  • Pas de compte, pas de clé API, pas de resource supplémentaire. Rien ne tourne en dehors de votre serveur.
  • Les mises à jour sont sans risque. Les fichiers sont dans la base de données, pas dans le dossier de la resource : remplacer le dossier lors d'une mise à jour conserve toutes les photos.
  • Les sauvegardes de votre base de données incluent les médias. La base grossit d'environ un tiers de plus que les fichiers eux-mêmes. Une photo pèse environ 150 Ko.
  • Agency Phone et Agency Pad partagent le stockage. Une photo prise avec l'un des deux apparaît sur l'autre, y compris les photos synchronisées avec Agency Cloud.
  • L'application Agency Companion les affiche aussi, sur iOS, Android et dans l'application web. Là non plus, rien à configurer.

Vitesse

Les fichiers passent par la connexion FiveM elle-même, sans bloquer le jeu. FiveM limite la vitesse à laquelle un joueur peut envoyer des données au serveur (environ 165 Ko par seconde), donc :

ÉlémentDurée d'enregistrement d'environ
Photo1 seconde
Message vocalmoins de 1 seconde
Clip vidéo de 15 secondes20 secondes (la caméra affiche la progression en pourcentage)

L'affichage d'un fichier aux autres joueurs est rapide : un clip entier arrive en quelques secondes. Si votre serveur enregistre beaucoup de vidéo, Cloudflare R2 enregistre les clips presque instantanément.

Paramètres dans config.lua

AgencyConfig.MediaStorage = {
    Provider = 'local',                -- 'local' or 'cloudflare'

    MaxFileMegabytes = 10,             -- largest single file (clips, recordings)
    TransferKilobytesPerSecond = 1000, -- 'local': how fast files are sent to players

    Local = {
        RetentionDays = 30,            -- delete files older than this (0 = keep forever)
        MaxStorageGigabytes = 10,      -- delete the oldest files above this (0 = no limit)
    },
}
ParamètreCe qu'il fait
RetentionDaysLes fichiers plus anciens que cette valeur sont supprimés automatiquement une fois par heure. Une photo supprimée affiche un petit espace réservé dans la galerie. Mettez 0 pour tout conserver.
MaxStorageGigabytesLorsque l'ensemble des fichiers dépasse cette taille, les plus anciens sont supprimés en premier. Mettez 0 pour ne pas avoir de limite.
MaxFileMegabytesLes fichiers plus gros sont refusés. Limite aussi les clips vidéo et les enregistrements d'écran.
TransferKilobytesPerSecondVitesse par joueur lors de l'envoi des fichiers aux joueurs. Le jeu garde toujours la priorité.

Cloudflare R2, étape par étape

Cloudflare R2 est gratuit jusqu'à 10 Go de stockage, 1 million d'envois et 10 millions de téléchargements par mois, et les téléchargements ne coûtent jamais rien. Cloudflare demande un moyen de paiement lors de l'activation de R2, même pour l'offre gratuite. Vous ne payez que si vous dépassez les limites gratuites.

1. Activer R2

  1. Connectez-vous sur dash.cloudflare.com (un compte gratuit suffit).
  2. Dans le menu de gauche, ouvrez Storage & databases puis R2 Object Storage.
  3. Ajoutez l'abonnement R2. L'aperçu affiche $0.00 à payer maintenant. Acceptez les conditions et cliquez sur Activate.

2. Créer un bucket

  1. Cliquez sur Create bucket.
  2. Donnez-lui un nom, par exemple myserver-media. Le nom ne peut plus être modifié ensuite.
  3. Laissez l'emplacement sur Automatic et la classe de stockage sur Standard.
  4. Cliquez sur Create bucket.

3. Rendre les fichiers consultables

  1. Ouvrez votre bucket et allez dans Settings.
  2. Sous Public Development URL, cliquez sur Enable, saisissez allow et confirmez.
  3. Copiez l'adresse qui apparaît, elle ressemble à https://pub-1a2b3c….r2.dev. C'est votre PublicUrl.

Cloudflare limite l'adresse r2.dev pour les serveurs très fréquentés. Si vous avez votre propre domaine sur Cloudflare, vous pouvez l'ajouter sous Custom Domains au même endroit et utiliser cette adresse comme PublicUrl à la place.

4. Autoriser les envois depuis le jeu

  1. Toujours dans Settings, trouvez CORS Policy et cliquez sur Add.
  2. Supprimez tout le contenu du champ de texte, collez ce qui suit et cliquez sur Save :
[
  {
    "AllowedOrigins": ["https://cfx-nui-agency-phone", "https://cfx-nui-agency-pad"],
    "AllowedMethods": ["PUT", "GET"],
    "AllowedHeaders": ["*"],
    "MaxAgeSeconds": 3600
  }
]

Sans cette étape, le jeu ne peut pas envoyer de fichiers et l'enregistrement des photos échoue. Si vous avez renommé le dossier de la resource, mettez le nom de votre dossier après cfx-nui-.

5. Créer une clé

  1. Revenez à R2 Object Storage et cliquez sur Manage API tokens.
  2. Cliquez sur Create API token (un jeton de compte convient).
  3. Autorisations : Object Read & Write.
  4. Dans le choix du bucket, sélectionnez uniquement votre bucket.
  5. Cliquez sur Create. Cloudflare n'affiche l'Access Key ID et la Secret Access Key qu'une seule fois, copiez-les toutes les deux maintenant.
  6. Votre Account ID est affiché dans l'aperçu R2, et c'est aussi la première partie de l'adresse S3 (https://<Account ID>.r2.cloudflarestorage.com).

6. La saisir dans le script

Les clés vont dans config_server.lua. Ce fichier n'est lu que par le serveur et n'est jamais envoyé aux joueurs. Ne les mettez pas dans config.lua : ce fichier est envoyé à chaque joueur.

-- config_server.lua
AgencyServerConfig.Cloudflare = {
    AccountId       = 'your account id',
    Bucket          = 'myserver-media',
    AccessKeyId     = 'your access key id',
    SecretAccessKey = 'your secret access key',
    PublicUrl       = 'https://pub-1a2b3c....r2.dev',
}

Définissez ensuite le fournisseur dans config.lua et redémarrez la resource :

AgencyConfig.MediaStorage = {
    Provider = 'cloudflare',
    ...
}

La console du serveur affiche maintenant Media: storage: Cloudflare R2, bucket myserver-media. S'il manque quelque chose, la console indique quoi, et le script continue d'enregistrer en local jusqu'à la correction, de sorte que la caméra ne cesse jamais de fonctionner.

Vous utilisez Agency Phone et Agency Pad ensemble ? Les deux peuvent utiliser le même bucket et la même clé, chacun conserve ses fichiers dans son propre dossier.

Vérifier que cela fonctionne

Exécutez ceci dans la console du serveur (ou en tant qu'administrateur en jeu), avec l'ID d'un joueur en ligne :

phonemediatest 1

Le Agency Phone du joueur enregistre une petite image de test, la recharge comme le ferait n'importe quel autre joueur, l'affiche et lit un court message vocal. La console répond :

Media test passed for player 1 in 1361 ms: upload ok, download ok, shown as picture ok, app markup and backgrounds ok, voice message plays ok

Ajoutez big pour tester aussi un clip vidéo de 6 Mo : phonemediatest 1 big.

Problèmes et solutions

Ce que vous voyezSolution
could not create the media tables dans la consoleoxmysql ne tourne pas ou ne peut pas joindre la base de données. Démarrez oxmysql avant agency-phone.
Provider is 'cloudflare', but config_server.lua is missing ...L'une des cinq valeurs est vide, ou PublicUrl ne commence pas par https://. Vérifiez l'étape 6.
Les photos échouent avec Cloudflare HTTP 403La clé n'a pas l'autorisation d'écriture pour ce bucket, ou le nom du bucket est incorrect. Vérifiez l'étape 5.
Les photos échouent avec Failed to fetch sur CloudflareLa politique CORS de l'étape 4 est absente ou contient un nom de resource différent.
Les photos enregistrées ne s'affichent pas sur CloudflareLa Public Development URL de l'étape 3 est désactivée, ou PublicUrl pointe vers un autre bucket.
Une vidéo met longtemps à s'enregistrerNormal avec le stockage local, voir Vitesse plus haut. Utilisez Cloudflare R2 pour des clips instantanés.
Les anciennes photos ont disparuRetentionDays les a supprimées. Augmentez la valeur ou mettez 0.

Si vous venez de Fivemanage ou Discord

Il n'y a rien à migrer. Les photos enregistrées auparavant conservent leurs anciens liens et restent visibles tant que ce service les fournit. Tout ce qui est nouveau va dans le stockage que vous avez choisi. Les anciens paramètres MediaStorageProvider, FiveManageApiUrl, FiveManageApiKey et ScreenshotWebhook sont ignorés et peuvent être supprimés de votre configuration.

Sécurité

  • Seuls les joueurs connectés à votre serveur peuvent envoyer des fichiers. Chaque envoi est d'abord annoncé, puis vérifié pour son type et sa taille.
  • Le contenu est vérifié d'après ses premiers octets. Une page web ou un script ne peut jamais être stocké déguisé en photo.
  • Les noms de fichiers sont aléatoires sur 128 bits : ils ne peuvent ni être devinés ni être listés.
  • Les envois et les téléchargements sont limités par joueur.
  • Avec Cloudflare, chaque envoi reçoit son propre lien, valable 5 minutes, pour exactement un fichier d'un seul type et d'une seule taille. La clé secrète ne quitte jamais votre serveur.

Toujours bloqué après cette page ? Notre support prend le relais.