Hallo zusammen!
Ich arbeite in einer Gruppe an einem relativ umfangreichen Spiele-Projekt und bin hier für den Online-Part zuständig.
Hier erstmal ein paar grundlegende Informationen:
Ich möchte gerne von Anfang an die ganze Client-Server-Architektur möglichst "professionell" aufbauen, um Sicherheit(Account-Hack, Cheat, Abfangen von Datenströmen) und Zuverlässigkeit(möglichst viele Online-Spiele) auch bei größerer Nachfrage zu gewährleisten.
Die entscheidenden Fragen liegen hier eher bei der gesamten Architektur, als bei der Implementierung.
Meine Ansätze:
Verbindung:
Auf dem Server existiert eine MainServer-Klasse, die an einem Port lauscht und ankommende Anfragen an ConnectionHandler(Thread) weiterleitet.
D.h. jeder Client ist einem eigenen ConnectionHandler zugewiesen, der mit dem Clienten kommuniziert.
Der ConnectionHandler ist auch für das Login-Verfahren des Spielers verantwortlich.
Solange der Spieler nicht erfolgreich eingeloggt ist, nimmt der ConnectionHandler keine Anfragen außer "Einloggen" und "Verbindung Trennen" entgegen.
Haben zwei Spieler ein Spiel gestartet, werden die jeweiligen ConnectionHandler einem MatchHandler(Thread) übergeben, der dann die direkte Kommunikation zwischen den Spielern ermöglicht.
Kommunikation:
Die Verbindung wäre somit eine TCP-Verbindung zwischen Client und Server.
Die komplette Spiellogik (Controller-Klassen) findet auf dem Server statt um Manipulationen vorzubeugen.
Macht der Spieler bei sich also eine Eingabe, sendet der Client einen Stream an den Server.
Dieser würde dann aus einem "Anfangscode" und dem generellen Inhalt bestehen.
Der Anfangscode dient dem Server zur Identifizierung der Anfrage(Ist dieser Stream eine Nachricht? Oder ein Spielereignis? Etc.).
Der dahinter folgende Inhalt des Streams wäre dann der "Methodenaufruf" inkl. Parameter.
Hier habe ich mir überlegt Hexadezmalwerte zu verschicken, die der Server eindeutig einer Methode zuweist und diese dann mit dem angehängtem Parameter aufruft.
Beispiel: $TYP$METHODE$PARAMETER1$PARAMETER2$...
Das gleiche Prinzip wird auch für Nachrichten vom Server an den Client genutzt.
Drück also der Spieler einen Knopf, wertet der Server über die Controller-Klassen die Aktion aus und schickt Änderungen an beide Spieler zurück, damit diese ihre Ansicht aktualisieren.
Das Spiel läuft somit komplett Server-seitig. Der Client dient im Grunde nur noch zur Anzeige und Nutzereingabe.
Sicherheit:
Um Manipulationen am Online-Spiel(offline ist dies egal), d.h. Spielverlauf und Daten zu verhindern habe ich mir ebenfalls Gedanken gemacht.
Die Verbindung mit dem Server wird mit SSL aufgebaut, d.h. die Kommunikation verschlüsselt.
Bei jeder Anfrage schickt der Client den Hashcode des gesamten Programms mit. Dieser wird beim Starten des Spieles einmal berechnet. Jede vorhandene Klasse gibt ihren eigenen Hashcode wieder und diese werden in einer speziellen Klasse zusammengefügt.
Ich als Entwickler kenne alle Versionen meines Spieles und somit auch alle Hashcodes und könnte diese auf dem Server vergleichen.
Wenn ein nicht bekannter Hashcode vom Client kommt, kann ich also davon ausgehen, dass das Programm manipuliert wurde oder eine nicht mehr zulässige Version des Spieles nutzt und somit jede weitere Anfrage abblocken.
Des weiteren wird immer überprüft ob der Spieler noch eingeloggt ist. Ein Spieler kann sich nur "einmal gleichzeitig" einloggen, was eine Manipulation durch mehrere Spiele-Instanzen verhindern soll.
Leistet dieses Modell die von mir geforderte Sicherheit und Stabilität?
Wären andere Lösungsansätze effizienter?
Was muss ich noch beachten?
Ich hoffe mein Anliegen ist einigermaßen deutlich geworden.
Wenn nicht, einfach nachhaken!
Schon mal vielen Dank für eure Hilfe!
Ich arbeite in einer Gruppe an einem relativ umfangreichen Spiele-Projekt und bin hier für den Online-Part zuständig.
Hier erstmal ein paar grundlegende Informationen:
- Generelle Umsetzung mit MVC-Modell
- Es wird einen Offline-/Singleplayer-Modus mit entsprechenden Controller-Klassen geben.
- Eigener Server ist vorhanden. Persistente Daten sollen in MySQL-Datenbanken gespeichert werden.
- Spieler sollen über eine Lobby ein Online-Spiel mit einem anderen Spieler beginnen können.
- Im laufenden Online-Spiel soll eine Chat-Funktion integriert sein
- Es handelt sich nicht um ein Runden-basiertes Spiel. Dass beide Spieler also auf dem möglichst gleichem Stand sind, was die Ansicht angeht, ist ziemlich wichtig
- Da das Online-System mit einer Rangliste fungiert, soll eine Manipulation (Cheaten) der Spieler möglichst verhindert werden
- Vor dem Betreten der Lobby, muss sich der Spieler auf dem Server anmelden(es muss also zuvor ein Account angelegt werden)
- Sämtliche virtuelle Besitztümer des Spielers im Spiel werden ausschließlich auf dem Server gespeichert. Online- und Offline-Spiel sind somit strikt von einander getrennt.
Ich möchte gerne von Anfang an die ganze Client-Server-Architektur möglichst "professionell" aufbauen, um Sicherheit(Account-Hack, Cheat, Abfangen von Datenströmen) und Zuverlässigkeit(möglichst viele Online-Spiele) auch bei größerer Nachfrage zu gewährleisten.
Die entscheidenden Fragen liegen hier eher bei der gesamten Architektur, als bei der Implementierung.
Meine Ansätze:
Verbindung:
Auf dem Server existiert eine MainServer-Klasse, die an einem Port lauscht und ankommende Anfragen an ConnectionHandler(Thread) weiterleitet.
D.h. jeder Client ist einem eigenen ConnectionHandler zugewiesen, der mit dem Clienten kommuniziert.
Der ConnectionHandler ist auch für das Login-Verfahren des Spielers verantwortlich.
Solange der Spieler nicht erfolgreich eingeloggt ist, nimmt der ConnectionHandler keine Anfragen außer "Einloggen" und "Verbindung Trennen" entgegen.
Haben zwei Spieler ein Spiel gestartet, werden die jeweiligen ConnectionHandler einem MatchHandler(Thread) übergeben, der dann die direkte Kommunikation zwischen den Spielern ermöglicht.
Kommunikation:
Die Verbindung wäre somit eine TCP-Verbindung zwischen Client und Server.
Die komplette Spiellogik (Controller-Klassen) findet auf dem Server statt um Manipulationen vorzubeugen.
Macht der Spieler bei sich also eine Eingabe, sendet der Client einen Stream an den Server.
Dieser würde dann aus einem "Anfangscode" und dem generellen Inhalt bestehen.
Der Anfangscode dient dem Server zur Identifizierung der Anfrage(Ist dieser Stream eine Nachricht? Oder ein Spielereignis? Etc.).
Der dahinter folgende Inhalt des Streams wäre dann der "Methodenaufruf" inkl. Parameter.
Hier habe ich mir überlegt Hexadezmalwerte zu verschicken, die der Server eindeutig einer Methode zuweist und diese dann mit dem angehängtem Parameter aufruft.
Beispiel: $TYP$METHODE$PARAMETER1$PARAMETER2$...
Das gleiche Prinzip wird auch für Nachrichten vom Server an den Client genutzt.
Drück also der Spieler einen Knopf, wertet der Server über die Controller-Klassen die Aktion aus und schickt Änderungen an beide Spieler zurück, damit diese ihre Ansicht aktualisieren.
Das Spiel läuft somit komplett Server-seitig. Der Client dient im Grunde nur noch zur Anzeige und Nutzereingabe.
Sicherheit:
Um Manipulationen am Online-Spiel(offline ist dies egal), d.h. Spielverlauf und Daten zu verhindern habe ich mir ebenfalls Gedanken gemacht.
Die Verbindung mit dem Server wird mit SSL aufgebaut, d.h. die Kommunikation verschlüsselt.
Bei jeder Anfrage schickt der Client den Hashcode des gesamten Programms mit. Dieser wird beim Starten des Spieles einmal berechnet. Jede vorhandene Klasse gibt ihren eigenen Hashcode wieder und diese werden in einer speziellen Klasse zusammengefügt.
Ich als Entwickler kenne alle Versionen meines Spieles und somit auch alle Hashcodes und könnte diese auf dem Server vergleichen.
Wenn ein nicht bekannter Hashcode vom Client kommt, kann ich also davon ausgehen, dass das Programm manipuliert wurde oder eine nicht mehr zulässige Version des Spieles nutzt und somit jede weitere Anfrage abblocken.
Des weiteren wird immer überprüft ob der Spieler noch eingeloggt ist. Ein Spieler kann sich nur "einmal gleichzeitig" einloggen, was eine Manipulation durch mehrere Spiele-Instanzen verhindern soll.
Leistet dieses Modell die von mir geforderte Sicherheit und Stabilität?
Wären andere Lösungsansätze effizienter?
Was muss ich noch beachten?
Ich hoffe mein Anliegen ist einigermaßen deutlich geworden.
Wenn nicht, einfach nachhaken!
Schon mal vielen Dank für eure Hilfe!
Zuletzt bearbeitet: