# التكاملات

يمكن ربط cxg-tattoos بأطر عمل مختلفة لتحصيل ثمن المشتريات والتحقق من أذونات الإدارة. يعيد تكامل المظهر تطبيق الوشوم المحفوظة عند تحميل الشخصية أو تغيير مظهرها. يُضبط كل جزء على حدة.

راجع أيضًا [المقدمة](https://docs.cxgstudios.com/docs/ar/01-cxg-tattoos/01-introduccion.md) و[التثبيت](https://docs.cxgstudios.com/docs/ar/01-cxg-tattoos/02-instalacion.md) و[الإعداد](https://docs.cxgstudios.com/docs/ar/01-cxg-tattoos/03-configuracion.md) و[الكتالوج](https://docs.cxgstudios.com/docs/ar/01-cxg-tattoos/04-catalogo.md) و[الواجهة](https://docs.cxgstudios.com/docs/ar/01-cxg-tattoos/06-interfaz.md).

## أطر العمل المتاحة

| النظام | معرّف الإعداد | المورد الافتراضي | المدفوعات | الأذونات |
| --- | --- | --- | --- | --- |
| Qbox | `qbx` | `qbx_core` | نعم | نعم |
| QBCore | `qbcore` | `qb-core` | نعم | نعم |
| ESX | `esx` | `es_extended` | نعم | نعم |
| من دون إطار عمل | `standalone` | لا ينطبق | عملية استدعاء مخصصة أو مشتريات مجانية | ACE أو تحقق مخصص |

باستخدام `auto`، يكتشف المورد Qbox أو QBCore أو ESX إذا كان أي منها قيد التشغيل؛ وإذا لم يجد أيًا منها، يستخدم `standalone`. يمكنك تحديد إطار العمل صراحةً إذا كان الخادم يشغّل عدة أطر عمل أو يستخدم اسم مورد مختلفًا:

```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
```

تُجرّب الحسابات بالترتيب المحدد. يُخصم المبلغ من حساب واحد فقط؛ وإذا لم يكفِ رصيده، يُجرّب الحساب التالي. وفي ESX، يحوّل `esxAccountMap` اسم `cash` إلى اسم الحساب `money`.

يحدد `Config.Purchases.reason` و`refundReason` سبب الحركات لدى موفّري الخدمات الذين يدعمون ذلك. وقيمتاهما الأوليتان هما `tattoo-purchase` و`tattoo-purchase-refund`. يتيح `allowFreePurchases` تخطي الخصم في محوّل standalone؛ لكنه لا يجعل المشتريات مجانية في أطر العمل الأخرى.

## المدفوعات من دون إطار عمل

في وضع `standalone`، اربط `tryCharge` و`refund` بمورد الاقتصاد في خادمك. يلزم كلا الإجرائين لقبول المشتريات: فإجراء الاسترداد يعيد المبلغ إذا فشل حفظ الوشم.

```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` واجهة الاقتصاد في خادمك؛ استبدله بالاسم والاستدعاءات الفعلية. للسماح عمدًا بالمشتريات المجانية، اضبط `allowFreePurchases = true`.

توفر محوّلات الدفع `isAvailable(settings)` و`charge(source, amount, context, settings)` و`refund(source, amount, context, settings)`. يجب حفظ إيصال الدفع المعتمد في `context.paymentReceipt`؛ ويستخدمه cxg-tattoos لإرسال أي استرداد إلى نظام الدفع نفسه. أما عند استخدام اقتصاد خاص، فإجراءا `tryCharge` و`refund` في `standalone` هما طريقة الإعداد المباشر.

## أذونات الإدارة

يتحقق الخادم من الأذونات قبل فتح لوحة الإدارة واستخدامها. إخفاء واجهة العميل أو تعديلها لا يمنح صلاحية الوصول.

يستخدم الإعداد الأولي إطار العمل المكتشف وACE كخيار احتياطي:

```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' },
        },
    },
}
```

يستعلم الوضع `framework` عن أدوار إطار العمل. ويستخدم الوضع `ace` إدخالات ACE في ربط الصلاحية. أما `hybrid` فيقبل أيًا من المسارين. في وضع `standalone`، لا يتوفر التحقق عبر إطار العمل؛ لذا اضبط ACE أو أضف تحققًا مخصصًا.

على سبيل المثال، للسماح لأعضاء principal ACE `group.admin`:

```cfg
add_ace group.admin cxg-tattoos.admin allow
```

لتفويض قرار الصلاحية إلى نظامك، استخدم `mode = 'custom'`. يتلقى الإجراء الراجع معرّف اللاعب والصلاحية وسياق العملية وربط الصلاحية المضبوط؛ ولا يمنح الإذن إلا إذا أعاد القيمة المنطقية `true`:

```lua
Config.Permissions.mode = 'custom'
Config.Permissions.custom = {
    hasPermission = function(source, permission, context, binding)
        return exports.my_permissions:hasPermission(source, permission) == true
    end,
}
```

كيّف `my_permissions` مع واجهة النظام المثبت في خادمك. إذا لم يكن الإجراء الراجع موجودًا، أو أخفق، أو أعاد قيمة أخرى، فسيُرفض الوصول.

يمكن أيضًا ضبط الأمر الذي يفتح اللوحة. يجب أن تطابق `permission` مفتاحًا في `Config.Permissions.bindings`:

```lua
Config.AdminCommand.enabled = true
Config.AdminCommand.name = 'tattooadmin'
Config.AdminCommand.permission = 'admin'
```

بهذه القيم، تحمي صلاحية `admin` الأمر `/tattooadmin` والإجراءات الإدارية. اضبط `enabled = false` لتعطيل الأمر؛ وسيظل التحقق من الصلاحية قائمًا في مسارات الإدارة الأخرى.

### ملفات التكامل القابلة للتحرير

تجمع الجسور القابلة للتحرير الاتصالات بالأنظمة الخارجية. لإعداد إذن أو عملية دفع مخصصة، يُفضّل ضبط عمليات الاستدعاء الموضحة أعلاه. وإذا كنت ستكيّف جسرًا موجودًا، فحافظ على عقده:

| الملف أو المجموعة | الاستخدام | عقد المحوّل |
| --- | --- | --- |
| `bridge/permissions/server.lua` | اختيار إطار العمل وتطبيق الوضع `framework` أو `ace` أو `hybrid` أو `custom` | تعيد `TattooPermissions.Has(source, permission, context)` القيمة `true` عند السماح فقط |
| `bridge/permissions/registry.lua` | التسجيل وأدوات الأذونات المشتركة | `TattooPermissionBridge.register(name, adapter)` |
| `bridge/permissions/qbx.lua`, `qbcore.lua`, `esx.lua`, `standalone.lua` | عمليات التحقق لكل إطار عمل أو لوضع عدم استخدام إطار عمل | `isAvailable(settings)` و`hasPermission(source, binding, settings, permission)`؛ ويقبل `context` إضافيًا عند تكييفه |
| `bridge/payments/server.lua` | اختيار الموفّر والتحصيل والاسترداد | `Config.TryChargePlayer(source, totalAmount, context)` و`Config.RefundPlayer(source, totalAmount, context)` |
| `bridge/payments/registry.lua` | التسجيل وأدوات الدفع المشتركة | `TattooPaymentBridge.register(name, adapter)` وأدوات الإيصالات |
| `bridge/payments/qbx.lua`, `qbcore.lua`, `esx.lua`, `standalone.lua` | عمليات الدفع حسب إطار العمل أو عبر عمليات استدعاء مخصصة | `isAvailable(settings)` و`charge(...)` و`refund(...)` |
| `bridge/appearance.lua` | أحداث تحميل المظهر وطلب الوشوم المحفوظة | يطلب قائمة وشوم الشخصية ويعيد تطبيقها بعد اكتمال تحميل المظهر |

يتلقى إجراء التحقق من الإذن أيضًا `context` وسيطًا خامسًا عند استدعائه من الجسر. يتضمن السجل الموفّرين المرفقين (`qbx` و`qbcore` و`esx` و`standalone`)؛ ولا تتطلب الخيارات المخصصة إضافة موفّر آخر.

في محوّل الدفع، احتفظ بتسجيل الإيصال باستخدام `TattooPaymentBridge.setReceipt(context, provider, account, amount, identifier, data)`. يجب أن يتحقق الاسترداد من الموفّر نفسه والمبلغ نفسه باستخدام `getReceipt(context, provider, amount)`، وأن يضع علامة على الإيصال بأنه مسترد بعد تأكيد الاسترداد. كيّف ملف الموفّر الذي تستخدمه بالفعل؛ ولإضافة تكامل خاص من دون تغيير المحوّلات، استخدم عمليات استدعاء `standalone`.

## المظهر وتحميل الشخصية

يستمع المورد إلى الأحداث المعتادة في `illenium-appearance` و`fivem-appearance` وQBCore وESX و`spawnmanager`؛ ثم يستعيد الوشوم المحفوظة ويعيد تطبيقها. وفي Qbox، يستخدم إعداد معاينة تعدد الشخصيات `playerskins.skin` لعرض الوشوم المحفوظة عند اختيار الشخصية.

إذا كان نظام المظهر لديك يستخدم حدثًا مختلفًا، فاطلب تطبيق الوشوم بعد اكتمال تحميل المظهر:

```lua
TriggerServerEvent('cxg-tattoos:fetchMyTattoos')
```

يعيد الحدث إلى العميل وشوم الشخصية الحالية. لا ترسل القائمة من مصدر يختاره اللاعب؛ إذ تُحل الملكية ويجري التحقق منها على الخادم.

تُضبط معاينة تعدد الشخصيات في Qbox بهذه الحقول:

```lua
Config.QbxMulticharacterPreview.enabled = true
Config.QbxMulticharacterPreview.resource = 'qbx_core'
Config.QbxMulticharacterPreview.playerskinsTable = 'playerskins'
Config.QbxMulticharacterPreview.playersTable = 'players'
Config.QbxMulticharacterPreview.syncExistingOnStart = true
```

يفعّل `enabled` التكامل؛ ويحدد `resource` اسم Qbox المثبت. ويحدّد `playerskinsTable` و`playersTable` جدولي المظهر والشخصيات المستخدمين في ذلك التثبيت. يتيح `syncExistingOnStart` مزامنة الوشوم المحفوظة مسبقًا عند بدء cxg-tattoos، لتظهر أيضًا في شاشة اختيار الشخصية المتعددة. إذا غيّر خادمك اسمي الجدولين، فحدّث هذين الحقلين. لا حاجة إلى تعديل `qbx_core`.
