# Integracje

cxg-tattoos może łączyć się z różnymi frameworkami w celu pobierania opłat za zakupy i sprawdzania uprawnień administracyjnych. Integracja wyglądu ponownie nakłada zapisane tatuaże po wczytaniu postaci lub zmianie jej skórki. Każdą część konfiguruje się osobno.

Zobacz także: [Wprowadzenie](https://docs.cxgstudios.com/docs/pl/01-cxg-tattoos/01-introduccion.md), [Instalacja](https://docs.cxgstudios.com/docs/pl/01-cxg-tattoos/02-instalacion.md), [Konfiguracja](https://docs.cxgstudios.com/docs/pl/01-cxg-tattoos/03-configuracion.md), [Katalog](https://docs.cxgstudios.com/docs/pl/01-cxg-tattoos/04-catalogo.md) i [Interfejs](https://docs.cxgstudios.com/docs/pl/01-cxg-tattoos/06-interfaz.md).

## Dostępne frameworki

| System | Identyfikator konfiguracji | Domyślny zasób | Płatności | Uprawnienia |
| --- | --- | --- | --- | --- |
| Qbox | `qbx` | `qbx_core` | Tak | Tak |
| QBCore | `qbcore` | `qb-core` | Tak | Tak |
| ESX | `esx` | `es_extended` | Tak | Tak |
| Bez frameworka | `standalone` | Nie dotyczy | Własny callback lub darmowe zakupy | ACE lub własna kontrola |

W trybie `auto` zasób wykrywa uruchomiony Qbox, QBCore lub ESX; jeśli żadnego nie znajdzie, używa `standalone`. Możesz ustawić framework na stałe, gdy serwer ma aktywnych kilka frameworków albo używa innej nazwy zasobu:

```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
```

Konta są sprawdzane w podanej kolejności. Opłata jest pobierana z jednego konta; jeśli saldo jest niewystarczające, sprawdzane jest następne. W ESX `esxAccountMap` mapuje `cash` na nazwę konta `money`.

`Config.Purchases.reason` i `refundReason` określają przyczynę transakcji dla providerów, którzy ją obsługują. Wartości początkowe to `tattoo-purchase` i `tattoo-purchase-refund`. Opcja `allowFreePurchases` pozwala pominąć opłatę w adapterze standalone; nie sprawia, że zakupy w innych frameworkach są darmowe.

## Płatności bez frameworka

W trybie `standalone` podłącz `tryCharge` i `refund` do systemu ekonomii serwera. Oba callbacki są wymagane, aby przyjmować zakupy: zwrot pozwala oddać opłatę, jeśli zapis tatuażu się nie powiedzie.

```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` oznacza API Twojego serwera; zastąp je rzeczywistą nazwą i wywołaniami. Aby świadomie zezwolić na bezpłatne zakupy, ustaw `allowFreePurchases = true`.

Adaptery płatności udostępniają `isAvailable(settings)`, `charge(source, amount, context, settings)` i `refund(source, amount, context, settings)`. Zatwierdzona płatność musi zachować potwierdzenie w `context.paymentReceipt`; cxg-tattoos użyje go, aby zwrócić pieniądze przez ten sam system płatności. Własną ekonomię najłatwiej podłączyć bezpośrednio przez callbacki `tryCharge` i `refund` dla `standalone`.

## Uprawnienia administracyjne

Uprawnienia są sprawdzane na serwerze podczas otwierania i obsługi panelu administracyjnego. Ukrycie lub zmiana interfejsu klienta nie przyznaje dostępu.

Początkowa konfiguracja używa wykrytego frameworka i ACE jako rozwiązania zapasowego:

```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' },
        },
    },
}
```

Tryb `framework` sprawdza role frameworka. `ace` korzysta z wpisów ACE w powiązaniu. `hybrid` dopuszcza dostęp przez dowolny z tych dwóch sposobów. W `standalone` autoryzacja frameworka jest niedostępna; skonfiguruj ACE albo własne sprawdzanie.

Na przykład, aby zezwolić członkom principal ACE `group.admin`:

```cfg
add_ace group.admin cxg-tattoos.admin allow
```

Aby przekazać decyzję własnemu systemowi, ustaw `mode = 'custom'`. Callback otrzymuje identyfikator gracza, uprawnienie, kontekst operacji i skonfigurowane powiązanie; dostęp przyznaje wyłącznie wartość logiczna `true`:

```lua
Config.Permissions.mode = 'custom'
Config.Permissions.custom = {
    hasPermission = function(source, permission, context, binding)
        return exports.my_permissions:hasPermission(source, permission) == true
    end,
}
```

Dostosuj `my_permissions` do API zainstalowanego na serwerze. Jeśli callbacku brakuje, wystąpi błąd albo zwróci inną wartość, dostęp zostanie odrzucony.

Konfigurowalne jest również polecenie otwierające panel. `permission` musi odpowiadać kluczowi w `Config.Permissions.bindings`:

```lua
Config.AdminCommand.enabled = true
Config.AdminCommand.name = 'tattooadmin'
Config.AdminCommand.permission = 'admin'
```

Przy tych wartościach uprawnienie `admin` chroni polecenie `/tattooadmin` i działania administracyjne. Ustaw `enabled = false`, aby wyłączyć polecenie; uprawnienia nadal będą sprawdzane w pozostałych ścieżkach administracyjnych.

### Edytowalne pliki integracji

Edytowalne bridge'e grupują połączenia z systemami zewnętrznymi. Własne uprawnienia lub płatności najlepiej skonfigurować za pomocą opisanych wyżej callbacków. Jeśli dostosowujesz istniejący bridge, zachowaj jego kontrakt:

| Plik lub grupa | Zastosowanie | Kontrakt adaptera |
| --- | --- | --- |
| `bridge/permissions/server.lua` | Wybór frameworka i obsługa trybu `framework`, `ace`, `hybrid` lub `custom` | `TattooPermissions.Has(source, permission, context)` zwraca `true` tylko po autoryzacji |
| `bridge/permissions/registry.lua` | Rejestr i wspólne narzędzia uprawnień | `TattooPermissionBridge.register(name, adapter)` |
| `bridge/permissions/qbx.lua`, `qbcore.lua`, `esx.lua`, `standalone.lua` | Kontrole dla każdego frameworka lub trybu bez frameworka | `isAvailable(settings)` i `hasPermission(source, binding, settings, permission)`; można dodać `context` |
| `bridge/payments/server.lua` | Wybór providera, obciążenie i zwrot | `Config.TryChargePlayer(source, totalAmount, context)` oraz `Config.RefundPlayer(source, totalAmount, context)` |
| `bridge/payments/registry.lua` | Rejestr i wspólne narzędzia płatności | `TattooPaymentBridge.register(name, adapter)` oraz narzędzia do potwierdzeń |
| `bridge/payments/qbx.lua`, `qbcore.lua`, `esx.lua`, `standalone.lua` | Obsługa płatności według frameworka lub własnych callbacków | `isAvailable(settings)`, `charge(...)` i `refund(...)` |
| `bridge/appearance.lua` | Zdarzenia wczytywania skórki i pobieranie zapisanych tatuaży | Pobiera listę tatuaży postaci i nakłada je po zakończeniu wczytywania wyglądu |

Callback uprawnień otrzymuje także `context` jako piąty argument podczas wywołania przez bridge. Rejestr zawiera dołączonych providerów (`qbx`, `qbcore`, `esx`, `standalone`); własne opcje nie wymagają dodawania kolejnego providera.

W adapterze płatności zachowaj rejestrację potwierdzenia przez `TattooPaymentBridge.setReceipt(context, provider, account, amount, identifier, data)`. Zwrot musi sprawdzić tego samego providera i kwotę przez `getReceipt(context, provider, amount)`, a po potwierdzonym zwrocie oznaczyć potwierdzenie jako zwrócone. Dostosuj plik providera, którego używasz; własną integrację bez zmiany adapterów skonfigurujesz callbackami standalone.

## Wygląd i wczytywanie postaci

Zasób nasłuchuje typowych zdarzeń `illenium-appearance`, `fivem-appearance`, QBCore, ESX i `spawnmanager`; następnie pobiera zapisane tatuaże i nakłada je ponownie. W Qbox konfiguracja podglądu multicharacter używa `playerskins.skin`, aby pokazywać zapisane tatuaże na ekranie wyboru postaci.

Jeśli system wyglądu używa innego zdarzenia, zażądaj nałożenia tatuaży po zakończeniu wczytywania skórki:

```lua
TriggerServerEvent('cxg-tattoos:fetchMyTattoos')
```

Zdarzenie zwraca klientowi tatuaże bieżącej postaci. Nie wysyłaj listy z wybranego przez gracza źródła: własność jest ustalana i sprawdzana na serwerze.

Podgląd multicharacter w Qbox konfiguruje się za pomocą pól:

```lua
Config.QbxMulticharacterPreview.enabled = true
Config.QbxMulticharacterPreview.resource = 'qbx_core'
Config.QbxMulticharacterPreview.playerskinsTable = 'playerskins'
Config.QbxMulticharacterPreview.playersTable = 'players'
Config.QbxMulticharacterPreview.syncExistingOnStart = true
```

`enabled` włącza integrację; `resource` określa zainstalowaną nazwę Qbox. `playerskinsTable` i `playersTable` wskazują tabele wyglądu i postaci używane przez daną instalację. `syncExistingOnStart` pozwala synchronizować zapisane już tatuaże przy uruchamianiu cxg-tattoos, aby pojawiały się także na ekranie wyboru postaci. Jeśli serwer zmienił nazwy tabel, zaktualizuj te dwa pola. Nie trzeba modyfikować `qbx_core`.
