دمج CXG-GTFAT مع موارد أخرى
ملفات bridge/*.lua نقاط قابلة للتعديل لربط الصلاحيات والحفظ الدائم والإشعارات والمحطات وتنسيقات المظهر. تعديلات القوائم يدوية ومخصصة لإصدارات بعينها؛ ولا يغيّر المورد موارد أخرى عند تثبيته.
قوائم المظهر
تتوفر تصحيحات لهذه المستودعات والمراجعات:
| القائمة | مراجعة المصدر | إجراء إضافي |
|---|---|---|
| illenium-appearance | 1b003ec169b15f145d519438ba7c6454bf746f27 | تطبيق تصحيح Lua لحفظ المكوّنات. |
| fivem-appearance | b06da32881ed49042909b38a778c10dd9bd9eaed | تطبيق التصحيح وإعادة بناء حزمة TypeScript للعبة باستخدام سير العمل build:game. |
| qb-clothing | 8cca4009dd473ab30c30e443ecad50830b816ed7 | تطبيق التصحيح عند حفظ skin وoutfit. |
| esx_skin / skinchanger | fe59ca0bd6da59e2ec6eb4a8d06ece312e96ae7a | مسار التصحيح نسبةً إلى جذر مستودع esx_core. |
يحتوي مجلد integrations في الحزمة على illenium-appearance.patch وfivem-appearance.patch وqb-clothing.patch وskinchanger.patch. لا تُطبّق تلقائياً. في نسخة تطوير من القائمة، تحقّق من التصحيح الصحيح قبل تطبيقه:
git apply --check /ruta/al/parche-correcto.patch
git apply /ruta/al/parche-correcto.patch
إذا فشل التحقق، فتوقف وكيّف التعديل مع الإصدار المثبّت؛ ولا تفرض التصحيح. قد تختلف الفروع والمراجعات الأحدث. يتطلب تصحيح fivem-appearance إعادة بناء الحزمة عبر سير عمل build:game وفق تعليمات تلك القائمة. لا تؤكد هذه التصحيحات التوافق مع كل الإصدارات ولا تحل محل الاختبار على خادمك.
ينظّف الحفظ decal التقني كي لا تحفظه القائمة كاختيار عادي للاعب. يجب أن تستدعي القوائم التي تحتفظ بجدول مظهر خاص بها أداة التنظيف في موضع الحفظ. يُحفظ الوزن منفصلاً عن الأزياء.
حفظ مظهر مخصص
يعيد export العميل SanitizeAppearance نسخة من المظهر. التنسيقات المتضمنة هي components وqb وesx:
local appearanceCopy = exports['CXG_GTFAT']:SanitizeAppearance(
ped,
appearance,
'components'
)
GuardarApariencia(appearanceCopy)
GuardarApariencia استدعاء مثالي؛ استبدله بوظيفة الحفظ الخاصة بقائمتك. يقبل components مصفوفة مكونات أو كائناً يحوي الخاصية components؛ ويستخدم كل مكوّن component_id وdrawable وtexture، ويمكن أن يستخدم palette. يستخدم تنسيق qb الحقل decals مع item وtexture، بينما يستخدم esx الحقلين decals_1 وdecals_2. يعيد export نسخة عميقة ويحافظ على الحقول الأخرى دون تغيير ped مؤقتاً. إذا فشل محوّل التنسيق أو لم يُعرف التنسيق، يعيد النسخة دون تعديل ويسجل تشخيصاً.
تسجيل ped للمعاينة
إذا استخدمت القائمة ped معاينة منفصلاً عن الشخصية، فسجّل معاينة الشخصية النشطة. ألغِ التسجيل قبل حذف الكيان:
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 وEliminarPreview استدعاءان مثاليان؛ استبدلهما بوظائف قائمتك. سجّل معاينة الشخصية النشطة فقط، لا شخصيات ped في العالم أو معاينات الشخصيات الأخرى. يمكنك بدلاً من ذلك ضبط Config.GetPreviewPed لإعادة ped الحالي أو nil. يطلب RefreshAppearance(previewPed) إعادة تقييم ped تتم إدارته مسبقاً؛ ولا يفعّل Fat بمفرده.
exports لموارد الخادم
exports الخادم واجهات API ذات صلاحيات مرتفعة لموارد الخادم الأخرى. لا تمررها مباشرة عبر حدث يستطيع العميل استدعاءه.
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
تمثل source معرّف اللاعب على الخادم، وليس قيمة يرسلها العميل. جميع القيم بوحدة kg. يعيد GetWeight الوزن أو nil, error. ويعيد SetWeight وAddWeight الوزن المطبّع المطبق بوحدة kg أو nil, error؛ ويرفض SetWeight القيم خارج النطاق ويقرّب إلى أقرب خطوة مع تقريب المنتصف إلى الأعلى. يقبل AddWeight زيادات سالبة. يكتب ResetWeight قيمة defaultKg ويعيد الوزن المطبق بوحدة kg؛ لكنه لا يحذف القيمة المخزنة.
لفتح الواجهة للاعب من مورد خادم آخر:
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
يمكن تمرير معرّف محطة اختياري كوسيط ثانٍ: OpenWeightUI(source, 'gimnasio'). عند عدم تحديد محطة، تطبق سياسة وصول الأوامر حتى لو كان تسجيل الأوامر معطلاً. تؤكد نتيجة true التفويض وإرسال طلب الفتح، ولا تؤكد أن العميل عرض الواجهة.
exports الخادم
| Export | الاستخدام |
|---|---|
GetWeight(source) | يعيد kg أو nil, error. |
SetWeight(source, kg) | يضبط وزناً تم التحقق منه ويعيد kg المطبق أو nil, error. |
AddWeight(source, deltaKg) | يضيف فرقاً ويعيد kg المطبق أو nil, error. |
ResetWeight(source) | يحفظ الوزن الافتراضي المضبوط ويعيده بوحدة kg أو nil, error. |
GetWeightSettings() | يعيد نسخة من الحدود النشطة. |
OpenWeightUI(source, stationId?) | يطلب فتح الميزان وفق السياسة المعمول بها. |
RefreshCharacter(source) | يعيد تحميل المعرّف والوزن بعد تبديل إطار العمل إلى الشخصية المطلوبة. |
ReconcileStorage(source) | يوفّق التخزين بعد حالة غير مؤكدة عندما يستطيع المحوّل تأكيد الكتابات السابقة. |
RefreshCharacter اختياري للتكاملات متعددة الشخصيات؛ استدعه بعد أن يتيح إطار العمل المعرّف المطلوب. لا يتصل المورد بـQbox تلقائياً.
قد تتضمن الأخطاء not_ready أو invalid_source أو player_unavailable أو character_unavailable أو invalid_weight أو out_of_range أو permission_denied أو context_denied أو busy أو storage_failed أو storage_timeout أو storage_unknown أو not_synced. لا تعتبر خطأ التخزين وزناً مؤكداً ولا تعِد الكتابة تلقائياً بعد storage_timeout أو storage_unknown.
exports العميل
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 القيمة nil, 'not_synced' حتى وصول قيمة مؤكدة من الخادم. يوفّر GetFatStatus(ped?) وGetReservedDecals(ped) معلومات للقراءة فقط ولا يثبتان أن الهندسة ظهرت فعلاً. يمكن استخدام GetReservedDecals لإخفاء decals المحجوزة في القوائم. يحدّث RefreshAppearance(previewPed?) مظهر اللاعب المدار أو معاينة مسجّلة فقط.
يسمح RegisterPreviewPed(ped) وUnregisterPreviewPed(ped) للقائمة بتمرير كيان المعاينة إلى المحدد. وحده المورد الذي سجّل ped يستطيع إلغاء تسجيله. تُنظّف المعاينات المسجلة عند توقف المورد المالك.
يعيد SanitizeAppearance(ped, appearance, format) نسخة من المظهر؛ ولا تشير nil, error إلى فشل. يعيد RegisterPreviewPed وUnregisterPreviewPed true عند النجاح وfalse إذا تعذّر تسجيل ped أو إزالته.
Bridges قابلة للتعديل
| الملف | التكييف |
|---|---|
bridge/server.lua | CanAccess والمعرّف وتحميل/حفظ الوزن وhooks الخادم. |
bridge/client.lua | ped المعاينة والإشعارات وhooks تغير الوزن/الواجهة. |
bridge/interaction.lua | تسجيل المحطات في target أو استبدال TextUI. |
bridge/appearance.lua | قراءة/كتابة decals بتنسيق مظهر مخصص. |
افتراضياً، لا يتعرف CanAccess إلا على ace وeveryone. لـjobs أو groups أو custom، نفّذ الفحص باستخدام API الخادم الفعلي وأعد true تحديداً عند منح الوصول. تؤدي الاستثناءات والقيم الأخرى إلى الرفض. يفسر المحوّل حقول سياسات job وgroup وcustom.
يطبّق مزوّد تخزين مخصص التواقيع LoadWeight(characterId, context, done) وSaveWeight(characterId, kg, context, done)، وكذلك ReconcileWeight(characterId, context, done) عند الحاجة إلى التوفيق بين الكتابات غير المؤكدة. يستدعي التحميل done(true, kg) (استخدم kg = nil عند غياب قيمة) أو done(false, 'storage_failed'). ولا يستدعي الحفظ done(true) إلا بعد تأكيده، وإلا يستدعي done(false, 'storage_failed'). ولا يستدعي التوفيق done(true, true) إلا إذا استحال اكتمال كتابة سابقة لاحقاً؛ وإلا فاستدعِ done(false, 'storage_unknown'). للحفظ غير المتزامن فعلياً، عيّن AsyncStorage = true؛ ويجب أن يكتمل callback ضمن سياق FiveM يدعم الانتظار. تسمح الواجهة بمهلة تصل إلى 10 ثوانٍ قبل الإبلاغ عن timeout. لا تكرر تلقائياً بعد storage_timeout؛ بل وفّق أولاً مع مزوّد يضمن ألا تُطبّق كتابة سابقة لاحقاً. لا تصف مزوّداً بأنه غير متزامن إذا أعاد التحكم قبل بدء الكتابة أو ترتيبها.
تستخدم hooks OnWeightChanged وOnCharacterChanged وOnUIOpened وOnUIClosed وLog للمراقبة أو التسجيل. لا تمنح hooks صلاحيات ولا تلغي العمليات المؤكدة.
التحقق قبل التفعيل
يجب التحقق من التصحيحات والمحوّلات باستخدام إصدارات وموارد الخادم الفعلية. قبل إتاحة التكامل للاعبين:
- أعد تجربة التحول بين Normal وFat باستخدام شخصيات freemode ذكورية وأنثوية.
- مع تفعيل Fat، احفظ المظهر والزي ثم أعد تحميلهما. تأكد من عدم حفظ decal التقني كاختيار عادي ومن بقاء الوزن مستقلاً عن الزي.
- مع تفعيل الحفظ لكل شخصية، أعد تشغيل المورد ثم اتصل مجدداً. تأكد من استعادة الشخصية نفسها لوزنها وعدم انتقاله إلى شخصية أخرى.
- افتح قائمة المظهر مع معاينة مسجلة وتأكد من أنها تمثل الشخصية الحالية. عند إلغاء القائمة أو إغلاقها، ألغِ تسجيل المعاينة قبل حذف الكيان.
يلزم إكمال هذه الخطوات على خادمك للتحقق من المجموعة المحددة من القائمة وإطار العمل والملابس. وجود تصحيح لا يؤكد هذه النتائج وحده.