Integrare CXG-GTFAT con altre risorse
I file bridge/*.lua sono punti modificabili per collegare permessi, persistenza, notifiche, stazioni e formati dell’aspetto. Le patch per i menu sono modifiche manuali per versioni specifiche; durante l’installazione la risorsa non modifica altri resource.
Menu dell’aspetto
Sono disponibili patch per questi repository e revisioni:
| Menu | Revisione sorgente | Azione aggiuntiva |
|---|---|---|
| illenium-appearance | 1b003ec169b15f145d519438ba7c6454bf746f27 | Applicare la patch Lua per il salvataggio dei componenti. |
| fivem-appearance | b06da32881ed49042909b38a778c10dd9bd9eaed | Applicare la patch e ricostruire il bundle TypeScript del gioco con il flusso build:game. |
| qb-clothing | 8cca4009dd473ab30c30e443ecad50830b816ed7 | Applicare la patch ai punti di salvataggio di skin e outfit. |
| esx_skin / skinchanger | fe59ca0bd6da59e2ec6eb4a8d06ece312e96ae7a | La patch è relativa alla radice del repository esx_core. |
La cartella integrations del pacchetto contiene illenium-appearance.patch, fivem-appearance.patch, qb-clothing.patch e skinchanger.patch. Non vengono applicate automaticamente. In un checkout di sviluppo del menu, verificare la patch giusta prima di applicarla:
git apply --check /ruta/al/parche-correcto.patch
git apply /ruta/al/parche-correcto.patch
Se il controllo non riesce, fermarsi e adattare la modifica alla versione installata; non forzare la patch. Fork e revisioni più recenti possono differire. La patch fivem-appearance richiede di ricostruire il bundle con il flusso build:game del menu. Le patch non certificano tutte le versioni né sostituiscono un test sul server.
Il salvataggio rimuove il decal tecnico dall’aspetto salvato, evitando che il menu lo persista come scelta ordinaria del giocatore. I menu che mantengono una propria tabella dell’aspetto devono chiamare la sanitizzazione nel punto di salvataggio. Il peso resta separato dagli outfit.
Salvare un aspetto personalizzato
L’export client SanitizeAppearance restituisce una copia dell’aspetto. I formati inclusi sono components, qb ed esx:
local appearanceCopy = exports['CXG_GTFAT']:SanitizeAppearance(
ped,
appearance,
'components'
)
GuardarApariencia(appearanceCopy)
GuardarApariencia è una chiamata di esempio: sostituirla con la funzione di salvataggio del menu. components accetta un array di componenti o un oggetto con la proprietà components; ogni componente usa component_id, drawable, texture e, facoltativamente, palette. Il formato qb usa il campo decals con item e texture; esx usa decals_1 e decals_2. L’export restituisce una copia profonda, conserva gli altri campi e non modifica temporaneamente il ped. Se l’adattatore fallisce o il formato non è riconosciuto, restituisce la copia invariata e registra una diagnosi.
Registrare un ped di anteprima
Se il menu usa un ped di anteprima distinto dal personaggio, registrare l’anteprima del personaggio attivo. Rimuoverne la registrazione prima di eliminare 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 ed EliminarPreview sono chiamate di esempio: sostituirle con le funzioni del menu. Registrare solo l’anteprima del personaggio attivo, non i ped del mondo né le anteprime di altri personaggi. In alternativa, impostare Config.GetPreviewPed in modo che restituisca il ped corrente o nil. RefreshAppearance(previewPed) richiede una nuova valutazione di un ped già gestito; non attiva Fat da solo.
Export per risorse server
Gli export server sono API privilegiate per altre risorse server. Non inoltrarli direttamente da un evento che il client può invocare.
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’argomento source è l’ID del giocatore sul server, non un valore inviato dal client. Tutti i valori sono in kg. GetWeight restituisce il peso oppure nil, error. SetWeight e AddWeight restituiscono il peso applicato normalizzato in kg oppure nil, error; SetWeight rifiuta valori fuori intervallo e arrotonda all’incremento più vicino, con i pareggi arrotondati per eccesso. AddWeight accetta incrementi negativi. ResetWeight imposta defaultKg e restituisce anche il peso applicato in kg; non elimina il valore memorizzato.
Per aprire l’interfaccia a un giocatore da un’altra risorsa server:
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
Come secondo argomento si può passare un ID stazione facoltativo: OpenWeightUI(source, 'gimnasio'). Senza stazione, si applica la policy di accesso dei comandi anche se la registrazione dei comandi è disabilitata. Il risultato true conferma l’autorizzazione e l’invio della richiesta di apertura, non che l’interfaccia sia già stata renderizzata dal client.
Export server
| Export | Uso |
|---|---|
GetWeight(source) | Restituisce kg oppure nil, error. |
SetWeight(source, kg) | Imposta un peso convalidato e restituisce i kg applicati oppure nil, error. |
AddWeight(source, deltaKg) | Aggiunge una variazione e restituisce i kg applicati oppure nil, error. |
ResetWeight(source) | Salva e restituisce il peso iniziale configurato in kg oppure nil, error. |
GetWeightSettings() | Restituisce una copia dei limiti attivi. |
OpenWeightUI(source, stationId?) | Richiede l’apertura della bilancia secondo la policy applicabile. |
RefreshCharacter(source) | Ricarica identità e peso dopo il cambio del personaggio previsto da parte del framework. |
ReconcileStorage(source) | Riconcilia l’archiviazione dopo uno stato incerto se l’adattatore può confermare scritture precedenti. |
RefreshCharacter è facoltativo per le integrazioni multicharacter; chiamarlo dopo che il framework ha reso disponibile l’identità prevista. La risorsa non collega automaticamente Qbox.
Gli errori possono includere not_ready, invalid_source, player_unavailable, character_unavailable, invalid_weight, out_of_range, permission_denied, context_denied, busy, storage_failed, storage_timeout, storage_unknown o not_synced. Non interpretare un errore di archiviazione come peso confermato e non ripetere automaticamente una scrittura con risultato storage_timeout o storage_unknown.
Export 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 restituisce nil, 'not_synced' finché non riceve un valore confermato dal server. GetFatStatus(ped?) e GetReservedDecals(ped) forniscono informazioni in sola lettura e non dimostrano che la geometria sia stata renderizzata. GetReservedDecals può servire a nascondere i decal riservati nei menu. RefreshAppearance(previewPed?) aggiorna soltanto l’aspetto gestito del giocatore o di un’anteprima registrata.
RegisterPreviewPed(ped) e UnregisterPreviewPed(ped) permettono a un menu di consegnare l’entità di anteprima al selettore. Solo la risorsa che ha registrato il ped può rimuoverlo. Le anteprime registrate vengono eliminate quando si arresta la risorsa proprietaria.
SanitizeAppearance(ped, appearance, format) restituisce una copia dell’aspetto; nil, error non segnala un errore. RegisterPreviewPed e UnregisterPreviewPed restituiscono true se l’operazione riesce e false se il ped non può essere registrato o rimosso.
Bridge modificabili
| File | Adattamento |
|---|---|
bridge/server.lua | CanAccess, identità, caricamento/salvataggio del peso e hook server. |
bridge/client.lua | Ped di anteprima, notifiche e hook per variazioni di peso/interfaccia. |
bridge/interaction.lua | Registrazione delle stazioni in un target o sostituzione di TextUI. |
bridge/appearance.lua | Lettura/scrittura dei decal in un formato di aspetto personalizzato. |
Per impostazione predefinita, CanAccess riconosce solo ace ed everyone. Per jobs, groups o custom, implementare il controllo con l’API reale del server e restituire esattamente true quando l’accesso è concesso. Le eccezioni e gli altri valori negano l’accesso. I campi di policy job, group e custom sono dati interpretati dall’adattatore.
Un provider di archiviazione personalizzato implementa le firme LoadWeight(characterId, context, done), SaveWeight(characterId, kg, context, done) e, se serve riconciliare scritture incerte, ReconcileWeight(characterId, context, done). Il caricamento chiama done(true, kg) (usare kg = nil se non esiste un valore) oppure done(false, 'storage_failed'). Il salvataggio chiama done(true) solo dopo la conferma, altrimenti done(false, 'storage_failed'). La riconciliazione chiama done(true, true) solo se nessuna scrittura precedente potrà completarsi in seguito; se non è possibile garantirlo, chiamare done(false, 'storage_unknown'). Per salvataggi realmente asincroni, impostare AsyncStorage = true; il callback deve terminare in un contesto FiveM che supporti l’attesa. L’API attende fino a 10 secondi prima di segnalare un timeout. Non ripetere automaticamente dopo storage_timeout; prima riconciliare con un provider che garantisca che una scrittura precedente non verrà applicata in seguito. Non dichiarare asincrono un provider che restituisce il controllo prima di avviare o accodare la scrittura.
Gli hook OnWeightChanged, OnCharacterChanged, OnUIOpened, OnUIClosed e Log servono a osservare o registrare le modifiche. Gli hook non concedono accesso né annullano operazioni confermate.
Verifiche prima dell’attivazione
Patch e adattatori vanno verificati con le versioni e le risorse effettivamente presenti sul server. Prima di abilitare l’integrazione per i giocatori:
- Ripetere il cambio Normal/Fat con personaggi freemode maschili e femminili.
- Con Fat attivo, salvare e ricaricare aspetto e outfit. Verificare che il decal tecnico non venga salvato come scelta normale e che il peso rimanga separato dall’outfit.
- Con la persistenza per personaggio attiva, riavviare la risorsa e riconnettersi. Verificare che lo stesso personaggio recuperi il proprio peso e che un altro non lo erediti.
- Aprire il menu dell’aspetto con un’anteprima registrata e controllare che rappresenti il personaggio corrente. Quando si annulla o chiude il menu, rimuovere la registrazione prima di eliminare l’entità.
Questi controlli sul server sono necessari per verificare la specifica combinazione di menu, framework e abiti. La presenza di una patch non certifica da sola questi risultati.