# Integrationen

cxg-tattoos kann mit verschiedenen Frameworks verbunden werden, um Käufe abzurechnen und administrative Berechtigungen zu prüfen. Die Erscheinungsintegration wendet gespeicherte Tattoos erneut an, wenn der Charakter geladen oder sein Skin gewechselt wird. Jeder Teil wird separat konfiguriert.

Siehe auch [Einführung](https://docs.cxgstudios.com/docs/de/01-cxg-tattoos/01-introduccion.md), [Installation](https://docs.cxgstudios.com/docs/de/01-cxg-tattoos/02-instalacion.md), [Konfiguration](https://docs.cxgstudios.com/docs/de/01-cxg-tattoos/03-configuracion.md), [Katalog](https://docs.cxgstudios.com/docs/de/01-cxg-tattoos/04-catalogo.md) und [Oberfläche](https://docs.cxgstudios.com/docs/de/01-cxg-tattoos/06-interfaz.md).

## Verfügbare Frameworks

| System | Konfigurationskennung | Standardressource | Zahlungen | Berechtigungen |
| --- | --- | --- | --- | --- |
| Qbox | `qbx` | `qbx_core` | Ja | Ja |
| QBCore | `qbcore` | `qb-core` | Ja | Ja |
| ESX | `esx` | `es_extended` | Ja | Ja |
| Ohne Framework | `standalone` | Nicht zutreffend | Eigener Callback oder kostenlose Käufe | ACE oder eigene Prüfung |

Mit `auto` erkennt die Ressource Qbox, QBCore oder ESX, wenn diese gestartet sind. Wird keines gefunden, verwendet sie `standalone`. Du kannst das Framework festlegen, wenn mehrere Frameworks auf dem Server aktiv sind oder ein anderer Ressourcenname verwendet wird:

```lua
Config.Purchases.framework = 'qbx' -- auto | qbx | qbcore | esx | standalone
Config.Purchases.resources.qbx = 'qbx_core'
Config.Purchases.accounts = { 'cash', 'bank' }
Config.Purchases.esxAccountMap.cash = 'money'
Config.Purchases.esxAccountMap.bank = 'bank'
Config.Purchases.allowFreePurchases = false
```

Die Konten werden in der angegebenen Reihenfolge geprüft. Die Abbuchung erfolgt von einem einzelnen Konto; reicht dessen Guthaben nicht aus, wird das nächste geprüft. In ESX übersetzt `esxAccountMap` `cash` in den Kontonamen `money`.

`Config.Purchases.reason` und `refundReason` legen den Buchungsgrund für Provider fest, die ihn unterstützen. Die Anfangswerte sind `tattoo-purchase` und `tattoo-purchase-refund`. Mit `allowFreePurchases` lassen sich Abbuchungen im Standalone-Adapter auslassen; Käufe anderer Frameworks werden dadurch nicht kostenlos.

## Zahlungen ohne Framework

Verbinde im Modus `standalone` `tryCharge` und `refund` mit der Wirtschaft deines Servers. Für Käufe müssen beide Callbacks vorhanden sein: Mit der Rückerstattung kann eine Abbuchung zurückgezahlt werden, falls das Speichern des Tattoos fehlschlägt.

```lua
Config.Purchases.framework = 'standalone'
Config.Purchases.standalone.tryCharge = function(source, totalAmount, context)
    -- Sustituye esta llamada por la API de economía de tu servidor.
    local charged, receipt = MyEconomy.charge(source, totalAmount, context)
    if charged then
        return true, receipt
    end
    return false, 'No tienes saldo suficiente.'
end

Config.Purchases.standalone.refund = function(source, totalAmount, context, receiptData)
    -- Usa receiptData para devolver el mismo cobro aprobado.
    return MyEconomy.refund(source, totalAmount, receiptData) == true
end
```

`MyEconomy` steht stellvertretend für die API deines Servers; ersetze es durch den tatsächlichen Namen und die passenden Aufrufe. Um Käufe absichtlich kostenlos zuzulassen, setze `allowFreePurchases = true`.

Die Zahlungsadapter stellen `isAvailable(settings)`, `charge(source, amount, context, settings)` und `refund(source, amount, context, settings)` bereit. Eine genehmigte Zahlung muss den Beleg in `context.paymentReceipt` speichern; cxg-tattoos verwendet ihn, um eine Rückerstattung an dasselbe Zahlungssystem zu senden. Für eine eigene Wirtschaft sind die Standalone-Callbacks `tryCharge` und `refund` der direkte Konfigurationsweg.

## Administrationsberechtigungen

Die Berechtigungen werden auf dem Server geprüft, bevor das Administrationspanel geöffnet oder bedient werden kann. Das Verbergen oder Ändern der Clientoberfläche gewährt keinen Zugriff.

Die Anfangskonfiguration verwendet das erkannte Framework und ACE als Rückfall:

```lua
Config.Permissions = {
    framework = 'auto', -- auto | qbx | qbcore | esx | standalone
    mode = 'hybrid',    -- framework | ace | hybrid | custom
    acePrefix = 'cxg-tattoos.',
    resources = {
        qbx = 'qbx_core',
        qbcore = 'qb-core',
        esx = 'es_extended',
    },
    bindings = {
        admin = {
            ace = { 'cxg-tattoos.admin', 'group.admin', 'admin' },
            qbx = { 'god', 'admin', 'group.admin' },
            qbcore = { 'god', 'admin', 'group.admin' },
            esx = { 'superadmin', 'admin' },
        },
    },
}
```

Der Modus `framework` fragt die Framework-Rollen ab. `ace` verwendet die ACE-Einträge der Bindung. `hybrid` erlaubt den Zugriff über einen der beiden Wege. In `standalone` ist die Framework-Autorisierung nicht verfügbar; konfiguriere ACE oder eine eigene Prüfung.

Um beispielsweise Mitgliedern des ACE-Principals `group.admin` Zugriff zu geben:

```cfg
add_ace group.admin cxg-tattoos.admin allow
```

Um eine Entscheidung an dein eigenes System zu delegieren, verwende `mode = 'custom'`. Der Callback erhält die Spieler-ID, die Berechtigung, den Operationskontext und die konfigurierte Bindung; nur der boolesche Wert `true` autorisiert:

```lua
Config.Permissions.mode = 'custom'
Config.Permissions.custom = {
    hasPermission = function(source, permission, context, binding)
        return exports.my_permissions:hasPermission(source, permission) == true
    end,
}
```

Passe `my_permissions` an die auf deinem Server installierte API an. Fehlt der Callback, schlägt er fehl oder gibt er einen anderen Wert zurück, wird der Zugriff abgelehnt.

Auch der Befehl zum Öffnen des Panels wird konfiguriert. `permission` muss einem Schlüssel in `Config.Permissions.bindings` entsprechen:

```lua
Config.AdminCommand.enabled = true
Config.AdminCommand.name = 'tattooadmin'
Config.AdminCommand.permission = 'admin'
```

Mit diesen Werten schützt die Berechtigung `admin` den Befehl `/tattooadmin` und die administrativen Aktionen. Setze `enabled = false`, um den Befehl zu deaktivieren; die Berechtigung wird auf den übrigen Administrationswegen weiterhin geprüft.

### Bearbeitbare Integrationsdateien

Die bearbeitbaren Bridges bündeln die Verbindungen zu externen Systemen. Für benutzerdefinierte Berechtigungen oder Zahlungen empfiehlt sich die Konfiguration der oben beschriebenen Callbacks. Wenn du eine bestehende Bridge anpasst, behalte ihren Vertrag bei:

| Datei oder Gruppe | Verwendung | Adaptervertrag |
| --- | --- | --- |
| `bridge/permissions/server.lua` | Auswahl des Frameworks und Anwendung des Modus `framework`, `ace`, `hybrid` oder `custom` | `TattooPermissions.Has(source, permission, context)` gibt nur bei erteilter Berechtigung `true` zurück. |
| `bridge/permissions/registry.lua` | Registrierung und gemeinsame Berechtigungswerkzeuge | `TattooPermissionBridge.register(name, adapter)` |
| `bridge/permissions/qbx.lua`, `qbcore.lua`, `esx.lua`, `standalone.lua` | Prüfungen je Framework oder für den Modus ohne Framework | `isAvailable(settings)` und `hasPermission(source, binding, settings, permission)`; bei Anpassung wird auch `context` akzeptiert. |
| `bridge/payments/server.lua` | Auswahl des Providers, Abbuchung und Rückerstattung | `Config.TryChargePlayer(source, totalAmount, context)` und `Config.RefundPlayer(source, totalAmount, context)` |
| `bridge/payments/registry.lua` | Registrierung und gemeinsame Zahlungswerkzeuge | `TattooPaymentBridge.register(name, adapter)` und Belegwerkzeuge |
| `bridge/payments/qbx.lua`, `qbcore.lua`, `esx.lua`, `standalone.lua` | Zahlungsabläufe je Framework oder über eigene Callbacks | `isAvailable(settings)`, `charge(...)` und `refund(...)` |
| `bridge/appearance.lua` | Skin-Ladeereignisse und Abruf gespeicherter Tattoos | Fordert die Tattoo-Liste des Charakters an und wendet sie nach Abschluss des Erscheinungsladevorgangs an. |

Der Berechtigungs-Callback erhält `context` als fünftes Argument, wenn die Bridge ihn aufruft. Die Registrierung enthält die mitgelieferten Provider (`qbx`, `qbcore`, `esx`, `standalone`); für benutzerdefinierte Optionen muss kein weiterer Provider hinzugefügt werden.

Bewahre in einem Zahlungsadapter die Belegregistrierung mit `TattooPaymentBridge.setReceipt(context, provider, account, amount, identifier, data)`. Die Rückerstattung muss denselben Provider und Betrag mit `getReceipt(context, provider, amount)` prüfen und den Beleg nach bestätigter Rückzahlung als erstattet markieren. Passe die Datei des Providers an, den du bereits verwendest; für eine eigene Integration ohne Änderungen an den Adaptern nutze die Standalone-Callbacks.

## Erscheinung und Charakterladen

Die Ressource verarbeitet übliche Ereignisse von `illenium-appearance`, `fivem-appearance`, QBCore, ESX und `spawnmanager`; anschließend ruft sie gespeicherte Tattoos ab und wendet sie erneut an. In Qbox verwendet die Multicharacter-Vorschaukonfiguration `playerskins.skin`, um gespeicherte Tattoos bei der Charakterauswahl anzuzeigen.

Wenn dein Erscheinungssystem ein anderes Ereignis verwendet, fordere die Anwendung an, nachdem der Skin fertig geladen wurde:

```lua
TriggerServerEvent('cxg-tattoos:fetchMyTattoos')
```

Das Ereignis sendet dem Client die Tattoos des aktuellen Charakters zurück. Sende die Liste nicht aus einer vom Spieler ausgewählten Quelle: Die Zugehörigkeit wird auf dem Server ermittelt und geprüft.

Die Qbox-Multicharacter-Vorschau wird über diese Felder angepasst:

```lua
Config.QbxMulticharacterPreview.enabled = true
Config.QbxMulticharacterPreview.resource = 'qbx_core'
Config.QbxMulticharacterPreview.playerskinsTable = 'playerskins'
Config.QbxMulticharacterPreview.playersTable = 'players'
Config.QbxMulticharacterPreview.syncExistingOnStart = true
```

`enabled` aktiviert die Integration; `resource` gibt den installierten Qbox-Ressourcennamen an. `playerskinsTable` und `playersTable` legen die Tabellen für Aussehen und Charaktere fest, die diese Installation verwendet. Mit `syncExistingOnStart` lassen sich bereits gespeicherte Tattoos beim Start von cxg-tattoos synchronisieren, damit sie auch in der Multicharacter-Auswahl erscheinen. Wenn dein Server die Tabellen umbenannt hat, aktualisiere diese beiden Felder. Änderungen an `qbx_core` sind nicht erforderlich.
