Prevenire gli imbrogli multigiocatore


10

Sto quasi completando lo sviluppo di un piccolo gioco multiplayer in stile indie. Mentre intendo permettere alle persone di imbrogliare in single-player, questo non è ovviamente accettabile in multi-player. Qualcuno sa come impedire a Joe medio di usare qualcosa come Cheat-Engine per modificare parti del gioco? Al momento ho in programma di fare in modo che il client carichi un hash MD5 di ogni file di impostazione utilizzato dal gioco (archiviato come XML) sul server di gioco per la verifica ogni pochi secondi, ma c'è qualcosa che posso fare per fermare cose come editor di memoria, ecc. ?


2
Consiglierei questo articolo, Costruire giochi multiplayer - Sicurezza, è scritto per alcune API multiplayer, ma le idee sono buone e si applicano ancora
Cyral

Risposte:


8

Se sei preoccupato per il codice modificato localmente, come puoi essere sicuro che qualcuno non abbia semplicemente modificato il tuo codice di notifica per inviare un elenco statico di hash MD5, gli stessi che ti aspetti? In effetti, non è nemmeno necessaria la modifica del codice per eseguire questa operazione, è sufficiente un proxy abbastanza semplice (presupponendo che non sia presente SSL, ma che potrebbe essere simulato con un po 'più di sforzo).

L'unico modo per fare quello che vuoi è avere un server e semplicemente non fidarti del client. Tutti i calcoli devono essere gestiti sul server e tutte le azioni devono essere verificate almeno in qualche modo possibili. Ad esempio, non consentire al cliente di dire che vogliono spostarsi da un lato della mappa quando sai che si trovavano dall'altro lato un momento fa. Senza un server nel mezzo che fa tutto ciò che è vitale per il gioco, è impossibile non imbrogliare, perché qualcuno intelligente sarà sempretrova un modo per aggirare tutto ciò che puoi incorporare nel client. Anche con uno, è ancora possibile se non pensi attraverso tutti i diversi modi di manipolare leggermente la situazione. Ad esempio, la convalida del movimento che ho menzionato prima: se si esegue un semplice calcolo punto a punto, le persone potrebbero essere comunque in grado di teletrasportarsi attraverso i muri.

Quindi la domanda è: quanto è media 'Joe medio'? Hai già menzionato la modifica del codice e gli editor di memoria. Questo è al di sopra di quello che personalmente considererei il livello medio, e se vuoi preoccuparti di quel livello, allora è richiesto un server fidato separato che fa tutto il lavoro pesante e il client si ridurrà essenzialmente a essere solo dispositivi di visualizzazione e input.


2
@ user185812: Di solito è una buona idea attendere almeno alcune ore prima di contrassegnare una risposta accettata. Mentre personalmente penso che la mia risposta sia piuttosto grande (sono di parte), probabilmente altri avranno più input e vedere una risposta accettata è abbastanza spesso un deterrente per gli altri a cui rispondere.
Matthew Scharley,

@MatthewScharley - nessuna preoccupazione. ;)
Martin Sojka,

11

Il cliente è nelle mani del nemico. ( Le leggi del design mondiale online )

In realtà, l'unico modo per battere la maggior parte dei cheat è avere il client come "thin client", ovvero: agire solo come un dispositivo di input e output e non dargli mai più informazioni di quante ne abbia bisogno.

Questo non fermerà l'automazione e questo non fermerà la raccolta e l'analisi passive di informazioni, ma puoi progettare il tuo gioco in modo che non abbia un impatto significativo.

Questo non impedirà alle persone di hackerarsi a vicenda tramite messaggi non validi fatti valere dal server: il tuo client deve proteggersi dai messaggi dal server come se stessi proteggendo i tuoi siti Web dagli attacchi di SQL injection.

Dato che si desidera utilizzare lo stesso client anche per il gioco a giocatore singolo, una soluzione sarebbe quella di eseguire un server locale in un processo / thread separato e trattarlo internamente come impostazione client / server. I "cheat" funzionerebbero quindi sul lato server. Minecraft fa qualcosa di simile, anche se non è affatto il primo gioco a dividere il motore di gioco dalla sua interfaccia in questo modo.

Letture consigliate:


2

In una partita multiplayer di base imbrogliare nel tipo di Cheat-Engine semplicemente non funzionerà. I client inviano solo i dati e le azioni per cui sono stati progettati. Di solito non è molto più di ciò che il giocatore "ha fatto", ad esempio in quale direzione sta correndo, se sta sparando e così via. Quindi le modifiche apportate alla memoria influenzeranno solo il suo stesso gioco, ma gli altri giocatori non vedranno alcun cambiamento, una cosiddetta desincronizzazione. La maggior parte dei giochi rileva i desincronizzazione in quel modo e rimuove il giocatore desincronizzato dal gioco.

Ora ci sono anche altri modi per imbrogliare, ma quelli riguardano la progettazione del gioco.

Per proteggersi dagli hack più semplici, che stanno falsificando i messaggi di rete, il server dovrebbe controllare quei pacchetti per la loro sanità mentale. "Quel ragazzo ha appena saltato 5 schermi? È impossibile, negare il pacchetto." (Nota che puoi anche seguire il percorso completamente sincronizzato, il che significa che tutto è sincronizzato e solo "Quali pulsanti ha premuto il lettore." - I tipi di messaggi vengono inviati - Il che rende inutili i messaggi di rete falsi in base alla progettazione.)

L'ultimo modo di imbrogliare nel multigiocatore sono gli hack di visibilità, ovvero modificare il client in modo che mostri al giocatore dati che non conosce. Esempi per questo non sono mostrare la nebbia della guerra, essere in grado di guardare attraverso i muri, mostrare una minimappa o altre cose. Questi sono impossibili da prevenire.


Non sono d'accordo sugli hack di visibilità. Non è possibile prevenirli non dando informazioni al cliente fino a quando il loro personaggio non ne sarà a conoscenza? Non fraintendetemi, potrebbe non essere un buon design. Ma è diverso dall'essere impossibile da prevenire.
xuincherguixe

@xuincherguixe Penso che sia impossibile in alcune circostanze. Ad esempio, entrambi i client stanno giocando con lo stesso IP e la stessa porta. In tal caso è solo la buona volontà di un cliente che gli impedisce di leggere i dati destinati all'altro.
Wodzu,

1

Per evitare gli hack di Cheat Engine di base che manipolano i valori delle variabili, è necessario nascondere tali valori. Tipicamente, Cheat Engine viene utilizzato per identificare la posizione della memoria di variabili interessanti (ad esempio la quantità di oro o di vita o il livello di potenziamento di un'abilità) facendo una ricerca del valore noto di detta variabile, giocare più del gioco e far sì che il valore cambia, quindi Cheat Engine eseguirà una nuova ricerca dal risultato della ricerca precedente per il nuovo valore. Ciò consente al cheat di ingrandire la posizione di memoria del valore, ora possono cambiare il valore di quella posizione di memoria usando Cheat Engine.

Ad esempio, ho 245 GOLD ... con Cheat Engine faccio una ricerca di 245 e trovo molte posizioni di memoria. Poi gioco ancora un po 'e porto il mio oro fino a 314, quindi cerco l'output di ricerca precedente per il valore 314 e trovo facilmente la posizione di memoria in cui è memorizzato GOLD.

Il modo per evitarlo è di non avere mai il valore reale archiviato in una posizione di memoria. Ad esempio, memorizzo il valore in un oggetto che deve calcolare il valore reale su richiesta quando richiesto. Quindi diciamo che il giocatore ha 245 ORO. Se eseguono una ricerca di una posizione di memoria con il valore 245, potrebbero trovarne molte, ma nessuna di esse sarà la posizione di memoria in cui è effettivamente memorizzato il valore dell'oro, perché non memorizzi il valore 245 per l'oro. Quando il gioco deve sapere quanto oro, chiederà all'oggetto che ne detiene il valore, che lo calcolerà su richiesta.

Quindi la domanda ora è: come si memorizza esattamente un valore in un modo che non lo rivela? Questo diventa un po 'complicato e brutto e sono sicuro che ci sono molti modi per farlo. Quello che mi piace fare è memorizzare un array booleano (o array di byte). La lunghezza dell'array può essere qualsiasi, ma diciamo che è 13. Quindi hai un contatore che rappresenta quante volte 13 vanno in quel valore reale. Quindi, se vogliamo rappresentare 245, il contatore avrebbe un valore di 18. Ora l'array avrebbe tutti i valori booleani impostati su true per il resto di 245/13 ... sostanzialmente il modulo. In questo caso è 11, quindi i primi 11 booleani nell'array sarebbero impostati su true, il resto su false. Per recuperare il valore, basta moltiplicare il contatore per la lunghezza dell'array, quindi aggiungere 1 per ogni set booleano su true (fermandosi al primo falso). Ora il numero 245 non sarebbe mai stato memorizzato da nessuna parte e sarebbe difficile trovare la posizione della memoria che avrebbe bisogno di essere manipolata per modificare la quantità di oro. Potresti voler impostare la lunghezza dell'array su dimensioni diverse (magari scegliere un numero a caso tra un intervallo ragionevole) quando viene creato questo oggetto.

EDIT: è utile per multiplayer e single player. Ci sono trucchi che possono essere fatti anche in multiplayer, in cui i valori nei pacchetti possono essere modificati. Ciò richiederebbe diverse tecniche per prevenire, come la firma di ogni pacchetto.


1
In genere, per evitare imbrogli, i giochi multiplayer calcolano tutto sul server, quindi la modifica di un valore sul client o in un pacchetto inviato al server non cambia nulla nel gioco reale. Tuttavia, il resto della risposta è interessante.
Vaillancourt

@AlexandreVaillancourt Un buon punto. Mi preoccupo di impantanare le firme di calcolo della CPU del server. Voglio mantenere il server veloce semplicemente passando i pacchetti tra i due giocatori, ma ora darò un'occhiata da vicino, dopo averlo sottolineato.
Jose Martinez

Se si inviano solo input dal client al server, non è necessario firmare tutti i pacchetti. Una volta sul server, se l'input non ha senso, vengono semplicemente rifiutati o il client viene espulso per barare. Il server calcola il prossimo stato del gioco, quindi invia il nuovo stato a tutti i giocatori, in questo modo viene evitato di imbrogliare (non ci si sbarazza di robot come questo, ma almeno si evita di imbrogliare casualmente dai giocatori) .
Vaillancourt

1
Per evitare ciò, si consente al server di aggiornare la nuova vita, quindi inviare la nuova vita al client. Tutto viene calcolato sul server e lascia che i client siano semplicemente "terminali stupidi" per tutte le cose importanti: il client sarà responsabile della cattura degli input dal player ("cliccato su x, y al momento T", "hit pulsante X al momento T "), inviandoli al server e ricevendo il nuovo stato dal server (" il giocatore è ora in posizione X, Y "," il giocatore ha ZZZ vita ") e lo visualizza al giocatore.
Vaillancourt

1
Con questo, il cheater (man in the middle) può pasticciare tutto ciò che vuole con i pacchetti, non cambierà lo stato del gioco sul server perché il server si assicurerà che l'input sia valido ("hmm il client ha cliccato in cinque punti diversi negli ultimi 0,03 secondi, non è normale, rifiutiamo questi clic ") ed eseguiamo tutta la simulazione stessa.
Vaillancourt
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.