Kafayı yiyecektim. Kendi küçük Unity oyunumun sunucusunda, birkaç arkadaşla oynuyorduk. Bir anda birisi inanılmaz hızlı skor yapmaya başladı. "Kesin hile" dedim ve basit bir anti-cheat yazmaya karar verdim. Ne olabilirdi ki? İstemciden gelen pozisyon paketlerini kontrol edecektim, fizik kurallarına uymuyorsa ban. Çok mantıklıydı.
C# ile sunucu tarafında şöyle bir kontrol koydum: Bir oyuncu, fiziksel olarak imkansız bir sürede A noktasından B noktasına ulaşırsa, bu hileydi. Time.deltaTime ve mesafe hesapları... Her şey harika görünüyordu.
C#:
float allowedDistance = playerSpeed elapsedTime safetyMargin;
if (traveledDistance > allowedDistance) {
BanPlayer(playerId, "Speedhack Detected!");
}
İlk testlerde "hileci" sandığım 2 oyuncuyu banladım. Zafer sarhoşluğu içindeydim. Meğerse ilk kurbanlarım, sunucu gecikmesi (lag) yaşayan ve paketleri bir anda yığılı gelen legit arkadaşlarımdı. Oops.
"Tamam," dedim, "lag toleransı ekleyeyim." safetyMargin değerini artırdım. Bu sefer de gerçek hileciler içinden sıyrılıp geçmeye başladı. Ayarlarla oynadıkça, bir türlü doğru dengeyi kuramıyordum. Biri lag'tan ban yerken, diğeri açık ara hile yapıp yakalanmıyordu. Sürekli kural değiştirip duruyordum. Whack-a-mole (köstebek vurma) oyununa dönmüştü işin özü. Bir bug'ı düzeltiyor, başka bir yerden iki tane daha çıkıyordu.
Anti-cheat yazmak, sandığımdan çok daha karmaşık bir savaş alanıymış. False-positive (yanlış pozitif) denen canavarla tanıştım. Sunucu-client mimarisi, tahmin edilemeyen gecikmeler, paket kayıpları... Hepsi hesaba katılmalıydı. Şaka gibi ama, en sonunda biraz daha akıllı, istatistiksel threshold'lar ve davranış analizine dayalı basit bir sistem kurmayı denedim. Mükemmel değil ama en azından en yakın arkadaşlarımı banlamıyor artık.
Siz de benim gibi "basit bir şey yapayım" derken kendinizi bitmeyen bir whack-a-mole savaşının içinde buldunuz mu? Özellikle multiplayer sistemlerde false-positive'leri azaltmak için ne gibi yöntemler kullanıyorsunuz? Fikirlerinizi merak ediyorum!