Zum Inhalt springen
CXGdocs.ANLEITUNGEN
Cxg gtfatCXG-GTFAT in andere Ressourcen integrieren
CXG DOCUMENTATION

CXG-GTFAT in andere Ressourcen integrieren

Die Dateien bridge/*.lua sind bearbeitbare Anpassungspunkte für Berechtigungen, Speicherung, Hinweise, Stationen und Erscheinungsbild-Formate. Menü-Patches sind manuelle Änderungen für bestimmte Versionen; die Ressource verändert bei der Installation keine anderen Ressourcen.

Erscheinungsbild-Menüs

Für folgende Repositories und Revisionen sind Patches vorbereitet:

MenüQuellrevisionZusätzliche Aktion
illenium-appearance1b003ec169b15f145d519438ba7c6454bf746f27Lua-Patch zum Speichern der Komponenten anwenden.
fivem-appearanceb06da32881ed49042909b38a778c10dd9bd9eaedPatch anwenden und das TypeScript-Spielbundle mit dem Ablauf build:game neu erstellen.
qb-clothing8cca4009dd473ab30c30e443ecad50830b816ed7Patch an den Speichergrenzen von Skin und Outfit anwenden.
esx_skin / skinchangerfe59ca0bd6da59e2ec6eb4a8d06ece312e96ae7aDer Patch bezieht sich auf das Stammverzeichnis des esx_core-Repositorys.

Der Ordner integrations des Pakets enthält illenium-appearance.patch, fivem-appearance.patch, qb-clothing.patch und skinchanger.patch. Sie werden nicht automatisch angewendet. Prüfe in einem Entwicklungs-Checkout des Menüs vor dem Anwenden den passenden Patch:

Code
git apply --check /ruta/al/parche-correcto.patch
git apply /ruta/al/parche-correcto.patch

Schlägt die Prüfung fehl, halte an und passe die Änderung an die installierte Version an; erzwinge den Patch nicht. Forks und neuere Revisionen können abweichen. Der Patch für fivem-appearance erfordert ein erneutes Erstellen des Bundles über dessen build:game-Ablauf. Die Patches zertifizieren nicht alle Versionen und ersetzen keinen Test auf deinem Server.

Beim Speichern wird das technische Decal bereinigt, damit ein Menü es nicht als normale Auswahl des Spielers speichert. Menüs mit eigener Erscheinungsbild-Tabelle müssen die Bereinigung an ihrem Speicherpunkt aufrufen. Das Gewicht wird getrennt von Outfits gespeichert.

Ein eigenes Erscheinungsbild speichern

Der Client-Export SanitizeAppearance gibt eine Kopie des Erscheinungsbilds zurück. Unterstützte Formate sind components, qb und esx:

Code
local appearanceCopy = exports['CXG_GTFAT']:SanitizeAppearance(
    ped,
    appearance,
    'components'
)

GuardarApariencia(appearanceCopy)

GuardarApariencia ist ein Beispielaufruf; ersetze ihn durch die Speicherfunktion deines Menüs. components akzeptiert ein Komponenten-Array oder ein Objekt mit der Eigenschaft components; jede Komponente verwendet component_id, drawable, texture und optional palette. Das qb-Format nutzt das Feld decals mit item und texture; esx verwendet decals_1 und decals_2. Der Export gibt eine tiefe Kopie zurück, erhält die übrigen Felder und verändert den Ped nicht vorübergehend. Bei einem Fehler des Formatadapters oder unbekanntem Format gibt er die unveränderte Kopie zurück und protokolliert eine Diagnose.

Einen Vorschau-Ped registrieren

Wenn das Menü einen vom Charakter getrennten Vorschau-Ped verwendet, registriere die Vorschau des aktiven Charakters. Hebe die Registrierung auf, bevor du die Entität löschst:

Code
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 und EliminarPreview sind Beispielaufrufe; ersetze sie durch die Funktionen deines Menüs. Registriere nur die Vorschau des aktiven Charakters, keine Welt-Peds oder Vorschauen anderer Charaktere. Alternativ kannst du Config.GetPreviewPed so definieren, dass es den aktuellen Ped oder nil zurückgibt. RefreshAppearance(previewPed) fordert eine erneute Prüfung eines bereits verwalteten Peds an; es aktiviert Fat nicht selbst.

Exports für Server-Ressourcen

Server-Exports sind privilegierte APIs für andere Server-Ressourcen. Leite sie nicht direkt über ein Ereignis weiter, das ein Client auslösen kann.

Code
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

Das Argument source ist die Spieler-ID auf dem Server und kein vom Client gesendeter Wert. Alle Werte sind in kg. GetWeight gibt das Gewicht oder nil, error zurück. SetWeight und AddWeight geben das normalisierte angewendete Gewicht in kg oder nil, error zurück; SetWeight weist Werte außerhalb des Bereichs zurück und rundet auf den nächsten Schritt, bei Gleichstand aufwärts. AddWeight erlaubt negative Änderungen. ResetWeight schreibt defaultKg und gibt ebenfalls das angewendete Gewicht in kg zurück; der gespeicherte Wert wird nicht gelöscht.

So öffnest du die Oberfläche für einen Spieler aus einer anderen Server-Ressource:

Code
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

Als zweites Argument kann optional die Stations-ID übergeben werden: OpenWeightUI(source, 'gimnasio'). Ohne Station gilt die Zugriffsrichtlinie der Befehle, auch wenn die Befehlsregistrierung deaktiviert ist. Das Ergebnis true bestätigt die Berechtigung und das Senden der Öffnungsanforderung, nicht das Rendern der Oberfläche beim Client.

Server-Exports

ExportVerwendung
GetWeight(source)Gibt kg oder nil, error zurück.
SetWeight(source, kg)Setzt ein geprüftes Gewicht und gibt den angewendeten Wert in kg oder nil, error zurück.
AddWeight(source, deltaKg)Addiert eine Differenz und gibt den angewendeten Wert in kg oder nil, error zurück.
ResetWeight(source)Speichert und gibt das konfigurierte Standardgewicht in kg oder nil, error zurück.
GetWeightSettings()Gibt eine Kopie der aktiven Grenzwerte zurück.
OpenWeightUI(source, stationId?)Fordert das Öffnen der Waage gemäß der geltenden Richtlinie an.
RefreshCharacter(source)Lädt Identität und Gewicht neu, nachdem das Framework zum vorgesehenen Charakter gewechselt ist.
ReconcileStorage(source)Gleicht den Speicher bei unklarem Zustand ab, sofern der Adapter frühere Schreibvorgänge bestätigen kann.

RefreshCharacter ist für Integrationen mit mehreren Charakteren optional. Rufe es auf, nachdem das Framework die vorgesehene Identität bereitgestellt hat. Die Ressource bindet Qbox nicht automatisch an.

Fehler können not_ready, invalid_source, player_unavailable, character_unavailable, invalid_weight, out_of_range, permission_denied, context_denied, busy, storage_failed, storage_timeout, storage_unknown oder not_synced enthalten. Werte einen Speicherfehler nicht als bestätigtes Gewicht und wiederhole Schreibvorgänge nach storage_timeout oder storage_unknown nicht automatisch.

Client-Exports

Code
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 gibt nil, 'not_synced' zurück, bis ein vom Server bestätigter Wert eintrifft. GetFatStatus(ped?) und GetReservedDecals(ped) liefern lesende Informationen; sie beweisen nicht, dass die Geometrie gerendert wurde. Mit GetReservedDecals können reservierte Decals in Menüs ausgeblendet werden. RefreshAppearance(previewPed?) aktualisiert nur das verwaltete Erscheinungsbild des Spielers oder einer registrierten Vorschau.

RegisterPreviewPed(ped) und UnregisterPreviewPed(ped) ermöglichen einem Menü, seine Vorschau-Entität an den Selektor zu übergeben. Nur die Ressource, die den Ped registriert hat, darf die Registrierung aufheben. Registrierte Vorschauen werden beim Stoppen ihrer Eigentümer-Ressource bereinigt.

SanitizeAppearance(ped, appearance, format) gibt eine Kopie des Erscheinungsbilds zurück; nil, error zeigt keinen Fehler an. RegisterPreviewPed und UnregisterPreviewPed geben bei Erfolg true und dann false zurück, wenn der Ped nicht registriert oder entfernt werden kann.

Bearbeitbare Bridges

DateiAnpassung
bridge/server.luaCanAccess, Identität, Laden/Speichern des Gewichts und Server-Hooks.
bridge/client.luaVorschau-Ped, Benachrichtigungen und Hooks für Gewichts-/Oberflächenänderungen.
bridge/interaction.luaRegistrierung von Stationen in einem Target oder Ersatz von TextUI.
bridge/appearance.luaDecals in einem eigenen Erscheinungsbild-Format lesen und schreiben.

Standardmäßig erkennt CanAccess nur ace und everyone. Für jobs, groups oder custom implementiere die Prüfung mit der tatsächlichen Server-API und gib bei gewährtem Zugriff genau true zurück. Ausnahmen und andere Werte verweigern den Zugriff. Job-, Gruppen- und Custom-Richtlinienfelder werden von deinem Adapter interpretiert.

Ein eigener Speicheranbieter implementiert die Signaturen LoadWeight(characterId, context, done), SaveWeight(characterId, kg, context, done) und bei Bedarf für den Abgleich unsicherer Schreibvorgänge ReconcileWeight(characterId, context, done). Beim Laden wird done(true, kg) (kg = nil, falls kein Wert vorhanden ist) oder done(false, 'storage_failed') aufgerufen. Beim Speichern wird done(true) erst nach Bestätigung oder andernfalls done(false, 'storage_failed') aufgerufen. Der Abgleich ruft done(true, true) nur dann auf, wenn kein früherer Schreibvorgang später noch abgeschlossen werden kann; ist das nicht sichergestellt, muss done(false, 'storage_unknown') aufgerufen werden. Für tatsächlich asynchrone Speicherungen setze AsyncStorage = true; der Callback muss in einem FiveM-Kontext abgeschlossen werden, der Warten unterstützt. Die API wartet bis zu 10 Sekunden, bevor sie einen Timeout meldet. Wiederhole nach storage_timeout nichts automatisch; gleiche zuerst mit einem Anbieter ab, der garantiert, dass ein früherer Schreibvorgang nicht später angewendet wird. Kennzeichne einen Anbieter nicht als asynchron, wenn er vor dem Start oder der Einreihung des Schreibvorgangs zurückkehrt.

Die Hooks OnWeightChanged, OnCharacterChanged, OnUIOpened, OnUIClosed und Log dienen der Beobachtung und Protokollierung. Sie erteilen keinen Zugriff und machen bestätigte Vorgänge nicht rückgängig.

Vor der Aktivierung prüfen

Patches und Adapter müssen mit den tatsächlichen Server-Ressourcen und Versionen geprüft werden. Vor der Freigabe für Spieler:

  1. Prüfe den Wechsel zwischen Normal und Fat mit männlichen und weiblichen Freemode-Charakteren.
  2. Speichere bei aktivem Fat das Erscheinungsbild und Outfit und lade beides erneut. Stelle sicher, dass das technische Decal nicht als normale Auswahl gespeichert wurde und das Gewicht vom Outfit getrennt bleibt.
  3. Starte bei aktivierter Speicherung pro Charakter die Ressource neu und verbinde dich erneut. Prüfe, ob derselbe Charakter sein Gewicht zurückerhält und ein anderer es nicht übernimmt.
  4. Öffne das Erscheinungsbild-Menü mit einer registrierten Vorschau und prüfe, ob sie den aktuellen Charakter darstellt. Hebe beim Abbrechen oder Schließen des Menüs die Registrierung auf, bevor du die Entität löschst.

Diese Schritte auf deinem Server sind erforderlich, um die konkrete Kombination aus Menü, Framework und Kleidung zu prüfen. Ein vorhandener Patch allein bestätigt diese Ergebnisse nicht.

CXG · DokumentationEine gute Grundlage. Unendliche Möglichkeiten.
CXG-GTFAT in andere Ressourcen integrieren · cxg-gtfat · CXG Docs