20 Mayıs 2026
5 min read
ZeroTrust Team

Etkinliklerinizi Güvenli Hale Getirin: FiveM Lua Etkinlik Güvenliği Kılavuzu

Hileler, kötü niyetli istemcilerin herhangi bir bağlamda etkinlikleri tetiklemesine izin verir. İstemci-sunucu iletişimini nasıl güvence altına alacağınızı, sunucu tarafı doğrulamayı nasıl uygulayacağınızı ve FXServer güvenlik convarlarını nasıl yapılandıracağınızı öğrenin.

Anti-cheat ekibi her zaman anti-cheat'i geliştirmeye çalışıyor, ancak bazen bazı şeyler gözden kaçabiliyor.

Bu kılavuzda, etkinliklerinizi düzgün bir şekilde kilitleyerek sunucunuzu daha güvenli hale getirmek için yapabileceğiniz bazı yaygın uygulamaları ele almaya çalışacağız.

FiveM'de Ağ Etkinliklerini Anlamak

Hileler, istemcinin herhangi bir bağlamda etkinlikleri tetiklemesine izin verebilir.

Bağlam derken, istemciden sunucuya (TriggerServerEvent aracılığıyla) veya istemci kaynağından istemci kaynağına (TriggerEvent aracılığıyla) yürütme yapabileceklerini kastediyoruz.

Lua'da Etkinlik İşleyicilerinin Doğru Kullanımı

Lua'da etkinliklerle çalışırken, istemci veya sunucu tarafından çağrılmalarına bağlı olarak bunları doğru şekilde kaydetmek çok önemlidir.

Sık yapılan bir hata, istemci tarafından çağrılmaması gereken sunucu etkinliklerini kaydetmek veya tam tersidir; bu durum ciddi güvenlik açıklarına yol açabilir.

AddEventHandler

Etkinliğin aynı bağlamda tetiklenmesi amaçlandığında (istemci-istemci veya sunucu-sunucu) AddEventHandler kullanın. Bu, etkinliklerin ağa aktarılmamasını ve karşı tarafça çağrılamamasını sağlar.

AddEventHandler("eventName", function(eventParam1, eventParam2)
    -- Buradaki kod, etkinlik aynı bağlamda tetiklendiğinde yürütülecektir.
end)

RegisterNetEvent

Etkinliğin istemciden sunucuya veya sunucudan istemciye gibi farklı bağlamlar arasında tetiklenmesi gerektiğinde RegisterNetEvent kullanın.

Perde Arkası

NOT: Bu, aynı bağlamdan yürütmeyi engellemez. Perde arkasında RegisterNetEvent, sadece aşağıdakinden ibaret olan bir sarmalayıcıdır: RegisterNetEvent("eventName") AddEventHandler("eventName", function() ... end)
RegisterNetEvent("eventName", function(eventParam1, eventParam2)
    -- Buradaki kod, etkinlik farklı bağlamlar arasında tetiklendiğinde yürütülecektir.
end)

Bu örnek istemci içindir ve istemcideki her şey gibi kurşun geçirmez değildir ve hileli istemciler tarafından manipüle edilebilir.

Aynı bağlamdan yürütmeyi engellemek istiyorsanız (sunucudan sunucuya ağ etkinliğinin istemci tarafından tetiklenmesini önlemek gibi), etkinliğinizi kaydetmeli ve gönderen kaynağını doğrulamalısınız:

RegisterNetEvent("eventName", function(eventParam1, eventParam2)
    -- Sunucu, sunucudan gelen etkinlikler için net id `65535` gönderecektir
    if source ~= 65535 then return end
end)

Kontroller ve Doğrulama Ekleme

Güçlü bir anti-cheat oluştursanız bile, sunucu etkinliklerine kontroller eklemek onları önemli ölçüde daha güvenli hale getirir. Bu, her şeyi engellemese de şiddetle tavsiye edilen bir uygulamadır. Aşağıda bazı iyi ipuçları paylaşıyoruz.

  • Oyuncu parası: Bakiye ve işlemleri sunucu tarafında doğrulayın.
  • Oyuncu state bag'leri: Aktif oturumlardaki durum verilerini doğrulayın.
  • Oyuncu envanter öğeleri: Öğe adlarını ve sayılarını kontrol edin.
  • Oyuncu konumu: Menzilleri ve mesafeleri doğrulayın.
  • Oyuncu deneyimi ve seviyesi: İstatistiklerin sunucu tarafında hesaplandığından emin olun.
  • Oyuncu izinleri ve rolleri: Sunucu tarafı ACL'yi doğrulayın.

Altın Kural

Oyuncuların değerleri sağlamasına veya değiştirmesine izin vermeden tüm değerleri sunucu tarafındaki yöntemleri kullanarak aldığınızdan emin olun. İstemci kontrollerinin UX (kullanıcı deneyimi) için iyi bir uygulama olabileceğini ancak kolayca geçersiz kılınabileceğini lütfen unutmayın.

Bu, oyun ortamınızın bütünlüğünü ve güvenliğini sağlar.

Ortak Güvenlik Modelleri Örnekleri

Aşağıdaki tüm örnekler bir tür framework (ESX, QB-Core vb.) kullandığınızı varsayar.

Kötü Güvenlik (Asla Bunu Yapmayın)

Bu, size etkinlikleri yapmanın kötü yollarını göstermek içindir, bunu asla yapmamalısınız. Kullanıcının kendi girdisinden doğrudan öğe eklemek her zaman kötü bir uygulamadır: kullanıcı girdilerini her zaman doğrulamalısınız.

RegisterNetEvent("job:givePlayerItem", function(item, count)
    local ply = FX.GetPlayerFromSource(source)
    -- Kullanıcının kendi girdisinden doğrudan öğe eklemek güvenli değildir!
    ply.addItem(item, count)
end)

İyi Güvenlik (Önerilen)

İşte sağlam bir güvenlik deseni. Sunucu oyuncu durumunu ve koordinatlarını takip eder ve yalnızca istemci tetikleyicilerine güvenmek yerine sunucu tarafı tiklerini kullanarak eylemleri doğrular.

-- rastgele koordinat
local VALID_JOB_COORD = vector3(125.0, 111.1, 35.83)
local MAX_ITEM_COUNT = 10

-- rastgele koordinat
local VALID_TURNIN_COORD = vector3(1888.0, 1254.1, 48.0)

local ITEM_NAME = 'log'

-- aktif işleri olan oyuncuların listesi
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

-- iş tikini işleme ve sunucu tarafında öğe sayısını artırma
CreateThread(function()
    while true do
        for src, data in pairs(activeJobs) do
            local ped = GetPlayerPed(src)
            -- menzil içinde değillerse onlara öğeyi vermek istemiyoruz
            if isPedWithinRange(ped, VALID_JOB_COORD) then
                -- onlara öğeyi ver ama MAX_ITEM_COUNT ile sınırla
                data.itemCount = math.min(data.itemCount + 1, MAX_ITEM_COUNT)
            end
        end
        -- iş tikini saniyede bir kez işle
        Wait(1000)
    end
end)

RegisterNetEvent("job:startJob", function()
    local ped = GetPlayerPed(source)
    -- 15 birim içindelerse işi yapıyorlar demektir
    if isPedWithinRange(ped, VALID_JOB_COORD) then
        activeJobs[source] = {
            itemCount = 0,
        }
    end
end)

RegisterNetEvent("job:givePlayerItem", function()
    local ply = FX.GetPlayerFromSource(source)
    -- aktif bir işleri yoksa buraya ulaşmamalılar!
    local jobData = activeJobs[source]
    if not jobData then return end

    local ped = GetPlayerPed(source)
    -- teslimat koordinatlarının menzilinde değiller, değişikliklerini reddet
    if not isPedWithinRange(ped, VALID_TURNIN_COORD) then return end

    -- öğe verilerini sıfırla, böylece birden çok kez tetikleyemesinler
    activeJobs[source] = nil

    -- sunucu tarafında doğrulanmış öğeleri kullanıcıya ekle
    ply.addItem(ITEM_NAME, jobData.itemCount)
end)

Sunucu Sahibi Seçenekleri (Convarlar)

Lütfen ne yaptığınızı tam olarak bilmediğiniz sürece aşağıdaki ayarların değiştirilmemesi gerektiğini unutmayın. Cfx.re / Adhesive ekibi hilecileri önlemek için her zaman çok sıkı çalışıyor. FXServer 8450 derleme sürümü ve daha yüksek sürümlerde bu özelliklerin çoğu varsayılan olarak etkin olacaktır.

  • sv_kick_players_cnl_timeout_sec: Sunucunun oyuncuyu atacağı zaman aşımı süresidir (örn. bu 600 ise, 10 dakika boyunca CnL bağlantısı olmadığında oyuncuyu atar).
  • sv_kick_players_cnl_update_rate_sec: CnL'nin oyuncu listesiyle sorgulanma sıklığıdır.
  • sv_pure_verify_client_settings: İstemcideki info.json dosyasına yapılan periyodik isteğin yerini alır. Adhesive ile svadhesive arasında güvenli bir bağlantı kurar ve pureLevel, scripthook ve diğer bazı sv_settings yapılandırmalarını doğrular.
  • sv_kick_players_cnl_consecutive_failures: Oyuncuyu atmak için timeout_sec üzerinde üst üste kaç kez başarısızlık görülmesi gerektiği. Varsayılan değer 2 olarak ayarlanmıştır; bu, bir oyuncunun 10 dakika boyunca kontrol yapamaması ve ardından bir sonraki kontrol güncellemesini kaçırması durumunda atılacağını belirtir. Bu bir emniyet mekanizması görevi görür.
  • sv_authMaxVariance: Sapma (variance), kullanıcının kimliğinin belirli bir sağlayıcı (yani 'steam', 'ip' veya 'license') için ne kadar olası değişeceğini gösterir.
  • sv_authMinTrust: Güven (trust), kullanıcının kimliğinin kötü niyetli bir istemci tarafından taklit edilmesinin ne kadar olası olmadığını gösterir.
  • sv_filterRequestControl: Yapılandırılabilir bir politikaya göre REQUEST_CONTROL_EVENT yönlendirmesini engellemek için kullanılan bir konsol değişkeni.
  • sv_disableClientReplays: Bunu etkinleştirmek hile seçenekleri şansını azaltmayı amaçlayacaktır. Lütfen bunun Rockstar Editor'ü devre dışı bırakacağını unutmayın.

Oyuncu Üzerindeki Sonuçlar

Bu convarların aktif olması muhtemelen oyuncunun aşağıdaki nedenle atılmasına yol açacaktır: Connection to CNL timed out.

Atılmak, oyuncunun otomatik olarak Global Yasaklı (Global Banned) olduğu anlamına gelmez. Ancak, oyuncunun güvenilirliği hakkında güçlü bir gösterge sağlar ve bu da güvenilirliği değerlendirmek için son derece yararlıdır.

Bilinmesi Gereken Önemli Noktalar

Sağlanan kodların kopyala-yapıştır yöntemiyle çalışması amaçlanmamıştır. Bunlar sadece sunucuda meydana gelebilecek bazı eylemleri önlemek için bazı ipuçlarıdır. Bu, biraz kodlama bilgisi gerektirir. Ek yardım almak için her zaman Discord'umuza katılmakta özgürsünüz.