تسمح عمليات الغش للعملاء الخبيثين بتشغيل الأحداث في أي سياق. تعرف على كيفية تأمين الاتصال بين العميل والخادم، وتطبيق التحقق من جانب الخادم، وتكوين متغيرات أمان FXServer.
يحاول فريق مكافحة الغش دائمًا تحسين مكافحة الغش، ولكن في بعض الأحيان تتسلل بعض الأشياء.
في هذا الدليل، سنحاول المساعدة في تغطية بعض الممارسات الشائعة التي يمكنك القيام بها لجعل خادمك أكثر أمانًا من خلال قفل أحداثك بشكل صحيح.
يمكن أن تسمح عمليات الغش للعميل بتشغيل الأحداث في أي سياق.
عندما نقول السياق، فإننا نعني أنه يمكنهم تنفيذ عميل->خادم (عبر TriggerServerEvent) أو مورد عميل->مورد عميل (عبر TriggerEvent).
عند العمل مع الأحداث في Lua، من الأهمية بمكان تسجيلها بشكل صحيح بناءً على ما إذا كان يتم استدعاؤها بواسطة العميل أو الخادم.
من الأخطاء الشائعة تسجيل أحداث الخادم التي لا يُفترض أن يستدعيها العميل، أو العكس، مما قد يؤدي إلى ثغرات أمنية خطيرة.
استخدم AddEventHandler عندما يكون الحدث مخصصًا للتشغيل داخل نفس السياق، إما عميل-عميل أو خادم-خادم. يضمن ذلك عدم توصيل الأحداث بالشبكة وعدم إمكانية استدعائها من الجانب الآخر.
AddEventHandler("eventName", function(eventParam1, eventParam2)
-- سيتم تنفيذ الكود هنا بمجرد تشغيل الحدث في نفس السياق.
end)استخدم RegisterNetEvent عندما يلزم تشغيل الحدث عبر سياقات مختلفة، مثل من العميل إلى الخادم أو من الخادم إلى العميل.
RegisterNetEvent("eventName", function(eventParam1, eventParam2)
-- سيتم تنفيذ الكود هنا بمجرد تشغيل الحدث عبر سياقات مختلفة.
end)هذا المثال مخصص للعميل، وكما هو الحال مع أي شيء على العميل، فهو ليس محصنًا ويمكن التلاعب به بواسطة عملاء الغش.
إذا كنت تريد منع التنفيذ من نفس السياق (مثل منع تشغيل حدث شبكة من خادم إلى خادم بواسطة العميل)، فيجب عليك تسجيل الحدث والتحقق من مصدر المرسل:
RegisterNetEvent("eventName", function(eventParam1, eventParam2)
-- سيرسل الخادم معرف الشبكة `65535` للأحداث القادمة من الخادم
if source ~= 65535 then return end
end)حتى إذا قمت ببناء نظام قوي لمكافحة الغش، فإن إضافة الفحوصات على أحداث الخادم تجعلها أكثر أمانًا بشكل كبير. هذه ممارسة موصى بها بشدة، على الرغم من أنها لا تمنع كل شيء. أدناه، نشارك بعض النصائح الجيدة.
يضمن ذلك سلامة وأمن بيئة اللعب الخاصة بك.
تفترض جميع الأمثلة أدناه وجود نوع من إطارات العمل (مثل ESX أو QB-Core، إلخ).
هذا مخصص لتوضيح الطرق السيئة للتعامل مع الأحداث، لا يجب عليك فعل هذا أبدًا. إن إضافة العناصر مباشرة إلى المستخدم من إدخاله الخاص هو أمر غير آمن دائمًا: يجب عليك دائمًا التحقق من إدخال المستخدم.
RegisterNetEvent("job:givePlayerItem", function(item, count)
local ply = FX.GetPlayerFromSource(source)
-- إضافة العناصر مباشرة إلى المستخدم من إدخاله الخاص هو أمر غير آمن!
ply.addItem(item, count)
end)إليك نمط أمني قوي. يتتبع الخادم حالة اللاعب وإحداثياته، ويتحقق من الإجراءات باستخدام تكتكات جانب الخادم بدلاً من الاعتماد فقط على مشغلات العميل.
-- إحداثيات عشوائية
local VALID_JOB_COORD = vector3(125.0, 111.1, 35.83)
local MAX_ITEM_COUNT = 10
-- إحداثيات عشوائية
local VALID_TURNIN_COORD = vector3(1888.0, 1254.1, 48.0)
local ITEM_NAME = 'log'
-- قائمة اللاعبين الذين لديهم وظائف نشطة
local activeJobs = {}
AddEventHandler("playerDropped", function ()
if not activeJobs[source] then return end
activeJobs[source] = nil
end)
function isPedWithinRange(ped, tgtCoords)
return #(GetEntityCoords(ped) - tgtCoords) < 15.0
end
-- معالجة تكتك الوظيفة وزيادة العناصر من جانب الخادم
CreateThread(function()
while true do
for src, data in pairs(activeJobs) do
local ped = GetPlayerPed(src)
-- إذا لم يكونوا ضمن النطاق، فلا نريد إعطائهم العنصر
if isPedWithinRange(ped, VALID_JOB_COORD) then
-- إعطائهم العنصر، ولكن بحد أقصى MAX_ITEM_COUNT
data.itemCount = math.min(data.itemCount + 1, MAX_ITEM_COUNT)
end
end
-- معالجة تكتك الوظيفة مرة واحدة في الثانية
Wait(1000)
end
end)
RegisterNetEvent("job:startJob", function()
local ped = GetPlayerPed(source)
-- إذا كانوا ضمن 15 وحدة، فهم يقومون بالوظيفة
if isPedWithinRange(ped, VALID_JOB_COORD) then
activeJobs[source] = {
itemCount = 0,
}
end
end)
RegisterNetEvent("job:givePlayerItem", function()
local ply = FX.GetPlayerFromSource(source)
-- إذا لم يكن لديهم وظيفة نشطة، فلا ينبغي أن يصلوا إلى هذا!
local jobData = activeJobs[source]
if not jobData then return end
local ped = GetPlayerPed(source)
-- هم ليسوا ضمن نطاق إحداثيات التسليم، ارفض تغييراتهم
if not isPedWithinRange(ped, VALID_TURNIN_COORD) then return end
-- إعادة تعيين بيانات العنصر حتى لا يتمكنوا من تشغيله عدة مرات
activeJobs[source] = nil
-- إضافة العناصر إلى المستخدم بعد التحقق منها من جانب الخادم
ply.addItem(ITEM_NAME, jobData.itemCount)
end)يرجى ملاحظة أنه لا ينبغي تعديل الإعدادات التالية إلا إذا كنت تعرف بالضبط ما تفعله. يعمل فريق Cfx.re / Adhesive بجد دائمًا لمنع المخادعين. ستكون معظم هذه الميزات ممكّنة افتراضيًا مع إصدار بناء FXServer 8450 وما فوق.
سيؤدي تفعيل هذه المتغيرات على الأرجح إلى طرد اللاعب بالسبب التالي: Connection to CNL timed out.
لا يعني الطرد حظر اللاعب تلقائيًا على المستوى العالمي (Global Ban). ومع ذلك، فإنه يوفر مؤشرًا قويًا على موثوقية اللاعب، وهو أمر مفيد للغاية لتقييم الجدارة بالثقة.
الأكواد المقدمة ليست مخصصة للعمل بطريقة النسخ واللصق المباشر. هذه مجرد نصائح لمنع بعض الإجراءات التي قد تحدث في الخادم. يتطلب ذلك بعض المعرفة البرمجية. يمكنك دائمًا الانضمام إلى Discord الخاص بنا للحصول على مساعدة إضافية.