Çok Oyunculu Hile Engelleme


10

Küçük bir indie tarzı çok oyunculu oyun geliştirmeyi neredeyse tamamlıyorum. İnsanların tek oyunculu hile yapmalarına izin vermek istesem de, bu çok oyunculu oyunlarda kabul edilemez. Herkes ortalama Joe oyunun bölümlerini değiştirmek için Cheat-Engine gibi bir şey kullanmak durdurmak için herhangi bir yolu biliyor mu? Şu anda istemcinin, oyunun kullandığı (XML olarak depolanan) her ayar dosyasının MD5 karmasını birkaç saniyede bir doğrulama için oyun sunucusuna yüklemesini planlıyorum, ancak bellek editörleri, vb. Şeyleri durdurmak için yapabileceğim bir şey var. ?


2
Çok oyunculu Oyunlar Oluşturma - Güvenlik , çok oyunculu bir API için yazılmış bu makaleyi tavsiye ederim , ancak fikirler iyi ve hala geçerli
Cyral

Yanıtlar:


8

Yerel olarak değiştirilmiş koddan endişe ediyorsanız, birinin beklediğiniz gibi MD5 karmalarının statik bir listesini göndermek için bildirim kodunuzu basitçe değiştirmediğinden nasıl emin olabilirsiniz? Aslında, bunu yapmak için kod modifikasyonuna bile ihtiyacınız yok, sadece oldukça temel bir proxy'ye ihtiyacınız var (SSL olmadığı varsayılarak, ancak bu biraz daha fazla çaba ile taklit edilebilir).

İstediğinizi yapmanın tek yolu bir sunucuya sahip olmak ve istemciye hiç güvenmemek. Tüm hesaplamalar sunucuda gerçekleştirilmeli ve tüm eylemlerin en azından bir şekilde mümkün olduğu doğrulanmalıdır. Örneğin, bir an önce diğer tarafta olduklarını bildiğinizde, müşterinin haritanın bir tarafına geçmek istediklerini söylemesine izin vermeyin. Ortada bir sunucu oyun için hayati olan her şeyi yapmadan , hile yapmak imkansızdır , çünkü akıllı biri her zamanmüşteriye inşa edebileceğiniz her şeyin etrafında bir yol bulun. Biriyle bile, durumu biraz manipüle etmenin farklı yollarını düşünmüyorsanız hala mümkündür. Örneğin, daha önce bahsettiğim hareket doğrulaması: Basit bir noktadan noktaya hesaplama yaparsanız insanlar yine de duvarlardan ışınlanabilirler.

Soru şu: 'ortalama Joe' ne kadar ortalama? Kod düzenleme ve bellek editörlerinden daha önce bahsetmiştiniz. Bu, kişisel olarak ortalama seviyenin üzerinde düşündüğümün üstünde ve bu seviye hakkında endişelenmek istiyorsanız, tüm ağır kaldırma yapan ayrı bir güvenilir sunucu gereklidir ve istemci esasen sadece ekran ve giriş cihazları olmak için kaynatılır.


2
@ user185812: Kabul edilen bir cevabı işaretlemeden önce en az birkaç saat beklemek genellikle iyi bir fikirdir. Şahsen ben cevabımın oldukça büyük (yanlı olduğumu) düşünürken, diğerlerinin muhtemelen daha fazla girdisi olacak ve kabul edilen bir cevap görmek çoğu zaman diğerlerinin cevaplaması için caydırıcı olacaktır.
Matthew Scharley

@ MatthewScharley - endişelenme. ;)
Martin Sojka

11

Müşteri düşmanın elinde. ( Çevrimiçi Dünya Tasarım Yasaları )

Gerçekten, çoğu hileyi yenmenin tek yolu, müşterinin "ince istemci" olmasını sağlamaktır, yani: Yalnızca bir girdi ve çıktı aygıtı olarak davranmak ve ona kesinlikle ihtiyaç duyduğundan daha fazla bilgi vermemektir.

Bu otomasyonu durdurmaz ve bu pasif bilgi toplama ve analizini durdurmaz, ancak oyununuzu önemli bir etkisi olmayacak şekilde tasarlayabilirsiniz.

Bu, kullanıcıların sunucunun güvendiği hatalı biçimlendirilmiş mesajlarla birbirlerini hacklemesini engellemez - istemcinizin, web sitelerinizi SQL enjeksiyon saldırılarına karşı koruyacağınız gibi sunucudan gelen mesajlara karşı koruma sağlaması gerekir.

Tek oyunculu oyun için aynı istemciyi de kullanmak istediğiniz için, bir çözüm yerel bir sunucuyu ayrı bir işlemde / iş parçacığında çalıştırmak ve bunu dahili olarak bir istemci / sunucu ayarı olarak işlemek olacaktır. "Hileleri" daha sonra sunucu tarafında çalışır. Minecraft benzer bir şey yapar, ancak hiçbir şekilde oyun motorunu arayüzünden bu şekilde ayıran ilk oyun değildir.

Önerilen Okuma:


2

Basit bir çok oyunculu oyunda Cheat-Engine türünde hile yapmak işe yaramaz. İstemciler yalnızca tasarladığınız verileri ve eylemleri gönderir. Genellikle bu, oyuncunun "ne" yaptığından çok daha fazla değildir, örneğin hangi yönde koştuğunu, vuruyorsa vb. Bu yüzden hafızada yaptığı değişiklikler sadece kendi oyununu etkileyecek, ancak diğer oyuncular hiçbir değişiklik görmeyecek, desync olarak adlandırılacak. Çoğu oyun böyle desyncleri algılar ve desynced oynatıcıyı oyundan kaldırır.

Şimdi aldatmanın başka yolları da var, ama bunların hepsi oyununuzun nasıl tasarlandığıyla ilgili.

Ağ iletilerini taklit eden en kolay hack'lerden korumak için, sunucu bu paketi akıl sağlığı için kontrol etmelidir. "O adam sadece 5 ekran atladı? Bu imkansız, paketi inkar." (Ayrıca her şeyin senkronize olduğu ve yalnızca "Oynatıcı hangi düğmelere bastı" anlamına gelen tam senkronize edilmiş rotayı da kullanabileceğinizi unutmayın.

Çok oyunculu hile yapmanın son yolu, istemciyi bilmediği oyuncuya veri gösterecek şekilde değiştiren görünürlük korsanlığıdır. Buna örnek olarak savaş sisi gösterilmiyor, duvarlara bakabiliyor, bir mini harita veya başka şeyler gösterilebiliyor. Bunları önlemek imkansızdır.


Görünürlük saldırılarına katılmıyorum. Karakterleri farkında olana kadar müşteriye bilgi vermeyerek bunlar önlenemez mi? Beni yanlış anlamayın, bu iyi bir tasarım olmayabilir. Fakat bu imkansız olmaktan farklıdır.
xuincherguixe

@xuincherguixe Bazı durumlarda bunun imkansız olduğunu düşünüyorum. Örneğin, her iki istemci de aynı IP ve aynı bağlantı noktası altında oynuyor. Böyle bir durumda, diğeri için olan verileri okumasını engelleyen sadece bir müşterinin iyi niyetidir.
Wodzu

1

Değişkenlerinizin değerlerini işleyen temel Cheat Engine saldırılarını önlemek için bu değerleri gizlemeniz gerekir. Genellikle Cheat Engine, söz konusu değişkenin bilinen değeri için bir arama yaparak, oyunun daha fazla oynatılması ve değerin Cheat Engine, önceki yeni değer aramasının sonucundan yeni bir arama yapar. Bu, cheater'ın değerin bellek konumunu yakınlaştırmasını sağlar, şimdi Cheat Engine'i kullanarak o bellek konumunun değerini değiştirebilirler.

Örneğin, 245 GOLD'um var ... Cheat Engine ile 245 için bir arama yapıyorum ve birçok bellek yeri buluyorum. Sonra biraz daha oynuyorum ve altımı 314'e getiriyorum, daha sonra önceki arama çıktısını 314 değeri için araştırıyorum ve GOLD'un depolandığı bellek konumunu kolayca buluyorum.

Bunu önlemenin yolu hiçbir zaman gerçek değerin bir bellek konumunda saklanmamasıdır. Örneğin, değeri gerektiğinde istek üzerine gerçek değeri hesaplaması gereken bir nesnede saklıyorum. Diyelim ki oyuncu 245 ALTIN. 245 değerine sahip bir bellek konumu için arama yaparlarsa, birçoğu bulabilirler, ancak hiçbiri altın değerinin gerçekte depolandığı bellek konumu değildir, çünkü 245 değerini altın için saklamamanızdır. Oyunun ne kadar altın olduğunu bilmesi gerektiğinde, değerini tutan nesneye sorar ve talep üzerine hesaplar.

Şimdi soru şu: Bir değeri tam olarak ortaya koymayacak şekilde nasıl saklıyorsunuz? Bu biraz zor ve çirkin olur ve eminim ki yapılabilecek birçok yol vardır. Ne yapmak istiyorum bir boolean dizi (veya bayt dizisi) saklamaktır. Dizinin uzunluğu herhangi bir şey olabilir, ama diyelim ki 13'tür. Sonra 13'ün gerçek değere kaç kez gittiğini gösteren bir sayacınız var. Eğer 245'i temsil etmek istersek sayacın değeri 18 olacaktır. Şimdi dizi 245 / 13'ün geri kalanı için tüm boolean'ları true olarak ayarlayacaktı ... temelde modül. Bu durumda 11 olur, bu nedenle dizideki ilk 11 boole değeri true değerine, geri kalanı false değerine ayarlanır. Değeri almak için tek yapmanız gereken sayacı dizi uzunluğuyla çarpmaktır, ardından true değerine her bir boole kümesi için 1 ekleyin (ilk yanlışta durma). Şimdi 245 sayısı asla hiçbir yerde saklanmayacak ve altın miktarını değiştirmek için manipüle edilmesi gereken bellek yerini bulmak zor olacaktır. Bu nesne oluşturulduğunda dizi uzunluğunu farklı boyutlara (belki de makul bir aralık arasında rastgele bir sayı seçerek) ayarlamak isteyebilirsiniz.

EDIT: Bu çok oyunculu ve tek oyuncu için kullanışlıdır. Paketlerdeki değerlerin değiştirilebileceği çok oyunculu olarak da yapılabilecek hile var. Bu, her paketi imzalamak gibi önlemek için farklı teknikler gerektirir.


1
Genellikle, hile yapmayı önlemek için, çok oyunculu oyunlar sunucudaki her şeyi hesaplar, bu nedenle istemcide veya sunucuya gönderilen bir pakette bir değeri değiştirmek, gerçek oyunda bir şey değiştirmez. Ama yine de, cevabın geri kalanı ilginç.
Vaillancourt

@AlexandreVaillancourt İyi bir nokta. Sunucunun CPU hesaplarını imzalamayı yavaşlatmakla ilgileniyorum. Sadece iki oyuncu arasında paketleri geçirerek sunucuyu hızlı tutmak istiyorum, ama şimdi dikkat çektiğinize yakından bakacağım.
Jose Martinez

Girişleri yalnızca istemciden sunucuya gönderirseniz, her paketi imzalamanız gerekmez. Sunucuya girdikten sonra, giriş mantıklı değilse, ya basitçe reddedilir veya istemci hile için dışarı atılır. Sunucu oyunun bir sonraki durumunu hesaplar, daha sonra yeni durumu tüm oyunculara gönderir, tipik olarak hile nasıl önlenir (böyle botlardan kurtulmazsınız, ama en azından oyunculardan sıradan hile yapmaktan kaçınırsınız) .
Vaillancourt

1
Bundan kaçınmak için, sunucunun yeni hayatı güncellemesine izin verin, ardından yeni hayatı istemciye gönderin. Her şey sunucuda hesaplanır ve tüm önemli şeyler için istemcilerin basitçe "aptal terminaller" olmasına izin verin: müşteri oynatıcıdan gelen girdileri yakalamaktan sorumlu olacaktır ("x'de y, y'de T", "tuşuna basın T düğmesine X) basın, sunucuya gönderin ve sunucudan yeni durumu alın ("oynatıcı şimdi X, Y konumunda", "oynatıcıda ZZZ ömrü var") ve oynatıcıya gösterilir.
Vaillancourt

1
Bununla, dolandırıcı (ortadaki adam) paketlerle istedikleri her şeyi karıştırabilir, sunucudaki oyunun durumunu değiştirmeyecektir, çünkü sunucu girişin geçerli olduğundan emin olacaktır ("hmm istemci tıkladı son 0.03 saniye içinde beş farklı yerde, bu normal değil, bu tıklamaları reddedelim ") ve tüm simülasyonun kendisini gerçekleştirelim.
Vaillancourt
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.