Intégrer CXG-GTFAT à d’autres ressources
Les fichiers bridge/*.lua sont des points d’adaptation modifiables pour connecter les permissions, la persistance, les notifications, les stations et les formats d’apparence. Les correctifs des menus sont des modifications manuelles propres à certaines versions ; la ressource ne modifie pas les autres ressources à l’installation.
Menus d’apparence
Des correctifs sont préparés pour les dépôts et révisions suivants :
| Menu | Révision source | Action complémentaire |
|---|---|---|
| illenium-appearance | 1b003ec169b15f145d519438ba7c6454bf746f27 | Appliquer le correctif Lua de sauvegarde des composants. |
| fivem-appearance | b06da32881ed49042909b38a778c10dd9bd9eaed | Appliquer le correctif et reconstruire le bundle TypeScript du jeu avec le flux build:game. |
| qb-clothing | 8cca4009dd473ab30c30e443ecad50830b816ed7 | Appliquer le correctif aux limites de sauvegarde de skin et d’outfit. |
| esx_skin / skinchanger | fe59ca0bd6da59e2ec6eb4a8d06ece312e96ae7a | Le correctif est relatif à la racine du dépôt esx_core. |
Le dossier integrations du paquet contient illenium-appearance.patch, fivem-appearance.patch, qb-clothing.patch et skinchanger.patch. Ils ne sont pas appliqués automatiquement. Dans un checkout de développement du menu, vérifiez le bon correctif avant de l’appliquer :
git apply --check /ruta/al/parche-correcto.patch
git apply /ruta/al/parche-correcto.patch
Si la vérification échoue, arrêtez-vous et adaptez la modification à la version installée ; ne forcez pas le correctif. Les forks et révisions plus récentes peuvent différer. Le correctif fivem-appearance nécessite de reconstruire le bundle avec son flux build:game. Ces correctifs ne certifient pas toutes les versions et ne remplacent pas un test sur votre serveur.
La sauvegarde assainit le decal technique afin qu’un menu ne l’enregistre pas comme choix ordinaire du joueur. Les menus qui gèrent leur propre table d’apparence doivent appeler l’assainissement au moment de la sauvegarde. Le poids reste séparé des tenues.
Sauvegarder une apparence personnalisée
L’export client SanitizeAppearance renvoie une copie de l’apparence. Les formats inclus sont components, qb et esx :
local appearanceCopy = exports['CXG_GTFAT']:SanitizeAppearance(
ped,
appearance,
'components'
)
GuardarApariencia(appearanceCopy)
GuardarApariencia est un appel d’exemple ; remplacez-le par la fonction de sauvegarde de votre menu. components accepte un tableau de composants ou un objet contenant la propriété components ; chaque composant utilise component_id, drawable, texture et éventuellement palette. Le format qb utilise le champ decals avec item et texture ; esx utilise decals_1 et decals_2. L’export renvoie une copie profonde, conserve les autres champs et ne modifie pas temporairement le ped. Si l’adaptateur échoue ou si le format est inconnu, il renvoie la copie inchangée et consigne un diagnostic.
Enregistrer un ped d’aperçu
Si le menu utilise un ped d’aperçu distinct du personnage, enregistrez l’aperçu du personnage actif. Désenregistrez-le avant de supprimer l’entité :
local previewPed = ObtenerPreviewActual()
if previewPed and DoesEntityExist(previewPed) then
exports['CXG_GTFAT']:RegisterPreviewPed(previewPed)
end
-- Al cerrar o cancelar el menú, antes de eliminar el ped:
exports['CXG_GTFAT']:UnregisterPreviewPed(previewPed)
EliminarPreview(previewPed)
ObtenerPreviewActual et EliminarPreview sont des appels d’exemple ; remplacez-les par les fonctions de votre menu. Enregistrez uniquement l’aperçu du personnage actif, pas les peds du monde ni les aperçus d’autres personnages. Vous pouvez aussi définir Config.GetPreviewPed pour renvoyer le ped actuel ou nil. RefreshAppearance(previewPed) demande la réévaluation d’un ped déjà géré ; il n’active pas Fat à lui seul.
Exports pour les ressources serveur
Les exports serveur sont des API privilégiées pour les autres ressources serveur. Ne les relayez pas directement depuis un événement que le client peut appeler.
local playerSource = source -- ID del jugador en el servidor
local kg, err = exports['CXG_GTFAT']:GetWeight(playerSource)
if kg == nil then
print('No hay un peso confirmado:', err)
end
local appliedKg, setError = exports['CXG_GTFAT']:SetWeight(playerSource, 92.5)
if appliedKg == nil then
print('No se pudo fijar el peso:', setError)
end
local addedKg, addError = exports['CXG_GTFAT']:AddWeight(playerSource, -2.0)
if addedKg == nil then
print('No se pudo sumar peso:', addError)
end
local resetKg, resetError = exports['CXG_GTFAT']:ResetWeight(playerSource)
if resetKg == nil then
print('No se pudo restablecer el peso:', resetError)
end
L’argument source est l’identifiant du joueur côté serveur, et non une valeur envoyée par le client. Toutes les valeurs sont en kg. GetWeight renvoie le poids ou nil, error. SetWeight et AddWeight renvoient le poids appliqué normalisé en kg ou nil, error ; SetWeight rejette les valeurs hors plage et arrondit au pas le plus proche, les égalités étant arrondies vers le haut. AddWeight accepte des incréments négatifs. ResetWeight écrit defaultKg et renvoie aussi le poids appliqué en kg ; il ne supprime pas la valeur stockée.
Pour ouvrir l’interface d’un joueur depuis une autre ressource serveur :
local playerSource = source -- ID del jugador en el servidor
local opened, err = exports['CXG_GTFAT']:OpenWeightUI(playerSource)
if not opened then
print('No se pudo abrir la báscula:', err)
end
Un identifiant de station facultatif peut être fourni en deuxième argument : OpenWeightUI(source, 'gimnasio'). Sans station, la politique d’accès des commandes s’applique, même si leur enregistrement est désactivé. Un résultat true confirme l’autorisation et l’envoi de la demande d’ouverture, pas le rendu de l’interface chez le client.
Exports serveur
| Export | Utilisation |
|---|---|
GetWeight(source) | Renvoie kg ou nil, error. |
SetWeight(source, kg) | Définit un poids validé et renvoie la valeur appliquée en kg ou nil, error. |
AddWeight(source, deltaKg) | Ajoute une différence et renvoie la valeur appliquée en kg ou nil, error. |
ResetWeight(source) | Enregistre et renvoie le poids initial configuré en kg ou nil, error. |
GetWeightSettings() | Renvoie une copie des limites actives. |
OpenWeightUI(source, stationId?) | Demande l’ouverture de la balance selon la politique applicable. |
RefreshCharacter(source) | Recharge l’identité et le poids lorsque le framework bascule sur le personnage prévu. |
ReconcileStorage(source) | Réconcilie le stockage après un état incertain si l’adaptateur peut confirmer les écritures précédentes. |
RefreshCharacter est facultatif pour les intégrations multpersonnages ; appelez-le après que le framework a rendu disponible l’identité prévue. La ressource ne connecte pas automatiquement Qbox.
Les erreurs peuvent inclure not_ready, invalid_source, player_unavailable, character_unavailable, invalid_weight, out_of_range, permission_denied, context_denied, busy, storage_failed, storage_timeout, storage_unknown ou not_synced. Ne traitez pas une erreur de stockage comme un poids confirmé et ne relancez pas automatiquement une écriture ayant renvoyé storage_timeout ou storage_unknown.
Exports client
local kg, err = exports['CXG_GTFAT']:GetWeight()
local settings = exports['CXG_GTFAT']:GetWeightSettings()
local isOpen = exports['CXG_GTFAT']:IsWeightUIOpen()
local closed = exports['CXG_GTFAT']:CloseWeightUI()
local status, statusError = exports['CXG_GTFAT']:GetFatStatus()
local reserved, reservedError = exports['CXG_GTFAT']:GetReservedDecals(PlayerPedId())
GetWeight renvoie nil, 'not_synced' jusqu’à la réception d’une valeur confirmée par le serveur. GetFatStatus(ped?) et GetReservedDecals(ped) fournissent des informations en lecture seule ; ils ne prouvent pas que la géométrie a été rendue. GetReservedDecals peut servir à masquer les decals réservés dans les menus. RefreshAppearance(previewPed?) actualise uniquement l’apparence gérée du joueur ou d’un aperçu enregistré.
RegisterPreviewPed(ped) et UnregisterPreviewPed(ped) permettent à un menu de confier son entité d’aperçu au sélecteur. Seule la ressource qui a enregistré le ped peut le désenregistrer. Les aperçus enregistrés sont nettoyés lorsque la ressource propriétaire s’arrête.
SanitizeAppearance(ped, appearance, format) renvoie une copie de l’apparence ; nil, error n’indique pas un échec. RegisterPreviewPed et UnregisterPreviewPed renvoient true si l’opération réussit et false si le ped ne peut pas être enregistré ou retiré.
Bridges modifiables
| Fichier | Adaptation |
|---|---|
bridge/server.lua | CanAccess, identité, chargement/sauvegarde du poids et hooks serveur. |
bridge/client.lua | Ped d’aperçu, notifications et hooks de changement de poids/interface. |
bridge/interaction.lua | Enregistrement des stations dans un target ou remplacement du TextUI. |
bridge/appearance.lua | Lecture/écriture des decals dans un format d’apparence personnalisé. |
Par défaut, CanAccess ne reconnaît que ace et everyone. Pour jobs, groups ou custom, implémentez la vérification avec l’API réelle du serveur et renvoyez exactement true lorsque l’accès est accordé. Les exceptions et les autres valeurs refusent l’accès. Les champs de politique job, group ou custom sont des données interprétées par votre adaptateur.
Un fournisseur de stockage personnalisé implémente les signatures LoadWeight(characterId, context, done), SaveWeight(characterId, kg, context, done) et, s’il doit réconcilier les écritures incertaines, ReconcileWeight(characterId, context, done). Le chargement appelle done(true, kg) (utilisez kg = nil en l’absence de valeur) ou done(false, 'storage_failed'). La sauvegarde appelle done(true) uniquement après confirmation, sinon done(false, 'storage_failed'). La réconciliation appelle done(true, true) uniquement si aucune écriture précédente ne pourra être appliquée plus tard ; sinon appelez done(false, 'storage_unknown'). Pour les véritables sauvegardes asynchrones, définissez AsyncStorage = true ; le callback doit se terminer dans un contexte FiveM prenant en charge l’attente. L’API attend jusqu’à 10 secondes avant de signaler un délai dépassé. Ne réessayez pas automatiquement après storage_timeout ; réconciliez d’abord avec un fournisseur garantissant qu’une écriture antérieure ne sera pas appliquée plus tard. Ne déclarez pas un fournisseur asynchrone s’il renvoie avant d’avoir commencé ou ordonné l’écriture.
Les hooks OnWeightChanged, OnCharacterChanged, OnUIOpened, OnUIClosed et Log servent à observer ou consigner les changements. Ils n’accordent pas l’accès et n’annulent pas les opérations confirmées.
Vérifications avant activation
Les correctifs et adaptateurs doivent être validés avec les versions et ressources réelles du serveur. Avant d’activer l’intégration pour les joueurs :
- Répétez le changement Normal/Fat avec des personnages freemode masculins et féminins.
- Avec Fat actif, sauvegardez puis rechargez l’apparence et la tenue. Vérifiez que le decal technique n’est pas enregistré comme choix ordinaire et que le poids reste indépendant de la tenue.
- Avec la persistance par personnage activée, redémarrez la ressource et reconnectez-vous. Vérifiez que le même personnage récupère son poids et qu’un autre ne l’hérite pas.
- Ouvrez le menu d’apparence avec un aperçu enregistré et vérifiez qu’il représente le personnage actuel. Lors de l’annulation ou de la fermeture du menu, désenregistrez-le avant de supprimer l’entité.
Ces vérifications sur votre serveur sont nécessaires pour valider votre combinaison de menu, de framework et de vêtements. La présence d’un correctif ne certifie pas à elle seule ces résultats.