Fragen zu Event-Behandlung bei Online-Spiel



  • Ich habe einige Fragen zu Online-Spielen. Wenn man zum Beispiel vorwärts läuft, wer berechnet dann ob ein Hinderniss im Weg liegt, der Server oder der Client? Wenn es der Client berechnen und testen würde hätte der User ja reichlich Möglichkeiten zu schummeln, da er durch Wände gehen könnte, wenn man sich einen Bot CLient bauen würde oder den Client anderwertig austrickst.
    Wenn das jedoch über den Server laufen würde wäre dieser ja sehr stark belastet, ausserdem würde man 2 mal ein SIgnal über das internet schicken müssen wenn man sich bewegt, also einmal für den befehl und dann vom server zurück ob das möglich ist oder ob ein Hinderniss im weg liegt. Das wäre denke ich sicher gegen Betrug, doch vielleicht etwas zu langsam?

    Was meint ihr?



  • Entweder es testen beide oder nur der Client.
    Bei 3D-Spielen macht es i.d.R. nur der Client, da es für den Server eine zu große Belastung wäre, wie du schon sagtest. Wenn der Server es aber doch macht, überprüft er lediglich, ob die Bewegung erlaubt ist (also keine Hindernis im Weg ist) und wenn nicht, kann er die Verbindung sofort beenden, da man annehmen muss, dass es sich um einen Cheatversuch handelt (da ja schon der Client die Gültigkeit der Bewegung im Vorfeld getestet haben sollte). Wenn die Bewegung gültig ist, sendet er keine Antwort. Denn bei jedem Bewegungsschritt erst auf eine Bestätigung vom Server zu warten, ist nicht wirklich praktikabel (wenn du nicht noch eine geniale Idee hast, dann sieht das in der Praxis nämlich so aus, dass der Spieler in jedes Hindernis hineinläuft und dann bei Erhalt der Antwort des Servers eine halbe Sekunde später wieder zurückspringt - oder deine Bewegungen sind generell zeitverzögert).
    Wenn es sich um ein 2D-Spiel handelt, sollte der Server auf jeden Fall alle Bewegungen auf Gültigkeit überprüfen, da das sehr schnell gehen dürfte.



  • ok, danke.
    Nun ist mir noch was eingefallen, wie ist das mit der interaktion mit anderen Spielern, ich gehe nun mal von einem Shooter aus. Wenn man schießt, wer berechnet dann ob die Kugel trifft oder nicht.



  • `wenn ich jetzt nichts falsches erzähle berechnet eben der server die interaktion des clients also wo er sich hinbewegt und wohin er schiest. Darstellung halt auf client seite.

    Player1 läuft 3 Schritte gerade aus und sendet dies an den server, der server sendet diese veränderung an Player2. Player2 berechnet nun die bewegungs abläufe für die veränderung.

    So..wenn ich nicht high bin 🙂

    Berichtigt mich bitte 😉



  • Bei 3D-Spielen wird die aktuelle Position periodisch und die aktuelle Bewegungsrichtung an den Server übermittelt, dieser sendet die Informationen an alle Clients weiter. Wenn überhaupt, dann werden nur grobe Plausibilitätstests ausgeführt (wenn sich der Spieler innerhalb einer Sekunde über das gesamte Spielfeld bewegt hat, kann man das als Cheatversuch deuten). Oft wird aber nicht einmal das gemacht. Stattdessen verlässt man sich dann auf solche Systeme wie PunkBuster oder GameGuard, die jedoch keine wirkliche Sicherheit bieten, da sie vollständig auf dem Prinzip "security by obscurity" basieren.
    So wird es bei vielen kommerziellen Spielen gemacht, Verbesserungspotenzial gibt es dabei mehr als genug.



  • Wie genau schützen denn GameGuard und PunkBuster vor CheatVersuchen? Da ich nicht genau das Prinzip von security by obscurity verstanden habe.
    Zu testen ob die Dinge, die der Client sendet plausibel sind sollte man jedenfalls tun, ich denke dies benötigt auch nicht sehr viel mehr aufwand.



  • Security by obscurity verlässt sich darauf, dass ein Angreifer das zugrundeliegende System nicht kennt. Z.B. eine Verschlüsselung mithilfe eines Pseudozufallszahlengenerator mit festem oder errechnetem (aber reproduzierbarem) Seed. Ein Angreifer wird mit derart verschlüsselten Daten zunächst nichts anfangen können. Kennt er aber den verwendeten Algorithmus des Zufallszahlengenerators und den verwendeten Seed, ist das Entschlüssen einfach.

    Gängige Verschlüsselungssysteme sind dagegen sicher, d.h. einem Angreifer nützt auch das Wissen über den genauen Algorithmus, der meist bekannt ist, nichts.

    Die Funktionen von GameGuard und PunkBuster sind das Finden von bekannten Cheatprogrammen und das Blocken von bestimmten WinAPI-Funktionen (z.B. WriteProcessMemory). Letzteres ist zwar recht effektiv, sobald man aber weiss, wie diese Programme dies realisieren, ist auch das Umgehen leicht. Solche Programme übermitteln auch periodische "Heartbeats" mit Statusinformationen an den Server. Wüsste man, wie diese aufgebaut sind, könnte man diese einfach nachbauen und immer melden, dass alles in Ordnung ist.
    Generell kann man sagen, dass wenn bei dir der Gedanke, dass jemand an deinen Quellcode kommen könnte, sicherheitstechnisch kalte Schweißausbrüche auslöst, dann ist das ein Zeichen, dass du dich viel auf "security by obscurity" verlässt. 😉



  • Mich würd's interessieren was sonst noch außer Security by Obscurity zur Auswahl steht. Entwickelt man z.B ein onlinefähiges Spiel Quelloffen, so wirds da etwas schwer security by obscurity einzusetzen, so wie ich das sehe.

    Das eine wären dann also die Verschlüsselungsverfahren. Da frag ich mich aber wie man es verhindern kann, dass man nicht einfach einen modifizierten Clienten nimmt, der sich für den Server als gültig erklärt und die Verschlüsselung somit nicht wirklich viel schützt... (So seh ich das jetzt, wirklich Erfahrung hab ich nicht mit der Sache)



  • naja bei nem quelloffenen Spiel wird das dann relativ einfach eigentlich einen Bot zu programmieren, damit ist das Cheaten auch relativ einfach.
    Auch kann man den Server dann einfach nach bauen ohne die Abfragen die testen ob die Bewegungen möglich ist.
    Doch irgendwann macht das ja auch kein Spass mehr zu spielen.



  • Die Alternative ist, sämtliche Spiellogik auf dem Server zu halten und alles, was vom Client kommt, auf Gültigkeit zu überprüfen. Es darf nichts mehr ausmachen, wenn jemand den Client in Hinblick auf seinen eigenen Vorteil komplett neuprogrammiert, da der Server sowieso alles sanktionieren würde, was nicht rechtens ist.
    Das ist das Ziel, aber leicht zu erreichen ist es nicht. Die Bewegung ist z.B. immer ein heikles Thema, da man immer mit Netzwerkverzögerungen rechnen muss. Wenn der Client also alle 500 ms seine Position übermitteln soll und es vergehen mal nur 400 ms zwischen zwei Bewegungen, kann man ihn nicht einfach rauswerfen. Man kann die Bewegung zwar verwerfen, aber dann muss man dem Client auch mitteilen, dass er sich auf die vorherige Position zurückbewegen muss. Spieler mit schlechter Verbindung freuen sich dann darüber, dass ihr Charakter ständig zurückspringt. Alternativ kann man einen Langzeitdurchschnitt der Bewegungsgeschwindigkeit bilden. Nur muss man dann an andere Dinge denken. Beispielsweise, will man es, dass der Spieler zehn Sekunden lang mit doppelter Geschwindigkeit laufen kann, wenn er zuvor zehn Sekunden lang stehengeblieben ist? Wohl eher nicht, das muss also berücksichtigt werden. Ebenso muss man mögliche legale Geschwindigkeitssteigerungen in Betracht ziehen, z.B. durch ein Powerup.

    Edit: damit ist man jedoch noch nicht vor Bots sicher, die selbstständig spielen. Da hilft nur ein Spielsystem, das für Bots zu anspruchsvoll ist.
    Da braucht man aber neue Ideen, so etwas habe ich persönlich bisher noch nicht gesehen (man kann natürlich alle Spieler alle zehn Minuten ein Captcha lösen lassen... auch da wird Freude aufkommen).



  • Meiner Meinung nach sollte man daraufhin arbeiten, eine Sichere Gültigkeitsüberprüfung seitens des Clients zu implementieren. Dann könnte man auch mit seltenen Ticks zum Server auskommen. so an die 500 ms. Und wenn sich zwei Clients dann in der nähe zueinander befinden, könnte man eine höherfrequentige Verbindung zwischen den Beiden aufstellen, und die Daten der Beiden dann gesammelt zum Server befördern. Damit hätte man z.B die Möglichkeit, ein anspruchsvolles Kampf- und Navigationssystem in einen MMORPG umzusetzen, anstatt eines Point&Click oder eines ähnlichen Systems. Hm nur ne idee 🙂



  • wieso zur hölle redet ihr nur über interpolation und so weiter .. es gibt auch sowas wie modelhax oder wallhax whitewall blablabla ... da is nix so einfach mit logik. Die ESL z.b. hat da eine software entwickelt die alle paar random sekunden ein screenshot vom bildschirm macht .. man kann das tool zwar auch umgeben aber es liefert auch noch einen logfile mit der alles dokumentiert was seit beginn der exe passiert. Es ist nicht 100%ig sicher aber es gibt einem ein sichereres gefühl. -->> Aequitas heist das ding.. für cs und css kenn ichs nur ka obs scho für was anderes gibt.



  • Azrael, il Meraz schrieb:

    Meiner Meinung nach sollte man daraufhin arbeiten, eine Sichere Gültigkeitsüberprüfung seitens des Clients zu implementieren. Dann könnte man auch mit seltenen Ticks zum Server auskommen. so an die 500 ms.

    Genau hier ist das Problem. Den Client hat der Spieler am Wickel und kann ihn theoretisch beliebig manipulieren. Gültigkeitsprüfungen führt der Client sowieso durch, damit man nicht in Wände laufen kann usw. Prüfungen auf mögliche äußere Manipulation (mit Prüfsumme des Codebereichs, mehrfaches Abspeichern wichtiger Werte in unterschiedlichen Darstellungen (z.B. mit verschiedenen Werten ge-xort) usw. basieren ebenfalls auf dem Prinzip "security by obscurity", da diese Überprüfungen gezielt unschädlich gemacht werden können, wenn ein Angreifer weiß, wonach er suchen muss. Man sollte immer davon ausgehen, dass ein Angreifer über den gesamten Quellcode des Clients und Servers verfügt. Man hat nur echte Sicherheit, wenn ihm das nichts mehr nützt.

    Edit:

    PRIEST schrieb:

    es gibt auch sowas wie modelhax oder wallhax whitewall blablabla ... da is nix so einfach mit logik.

    Wenn man es konsequent durchziehen würde, dann müsste der Server bestimmen, ob ein Spieler einen bestimmten anderen Spieler sehen kann und ihm nur dann Informationen über diesen zu senden. Damit sind durchsichtige Wände ihrer Nützlichkeit zumindest teilweise beraubt.
    Alle anderen Vorteile, die man durch eine veränderte Darstellung der Spielszene erlangen kann, sind nicht feststellbar, da man sich hier auf Informationen des Clients verlassen muss. Die Screenshots, die zum Server gesendet werden, können z.B. etwas anderes zeigen, als was dann wirklich auf dem Bildschirm zu sehen ist.
    Man muss immer davon ausgehen, dass der Client (und da darf man nicht an die selbstgeschriebe Software denken) alle empfangenen Informationen zu seinem maximalen Nutzen verwendet. Wenn der Client etwas nicht wissen soll, darf man es nicht senden.
    In der Praxis steht man dabei aber vor vielen Problemen.



  • Nanyuki schrieb:

    Genau hier ist das Problem. Den Client hat der Spieler am Wickel und kann ihn theoretisch beliebig manipulieren. Gültigkeitsprüfungen führt der Client sowieso durch, damit man nicht in Wände laufen kann usw. Prüfungen auf mögliche äußere Manipulation (mit Prüfsumme des Codebereichs, mehrfaches Abspeichern wichtiger Werte in unterschiedlichen Darstellungen (z.B. mit verschiedenen Werten ge-xort) usw. basieren ebenfalls auf dem Prinzip "security by obscurity", da diese Überprüfungen gezielt unschädlich gemacht werden können, wenn ein Angreifer weiß, wonach er suchen muss. Man sollte immer davon ausgehen, dass ein Angreifer über den gesamten Quellcode des Clients und Servers verfügt. Man hat nur echte Sicherheit, wenn ihm das nichts mehr nützt.

    Vielleicht entwickeln wir uns auch irgendwann einfach mal zu einer Spezies die es nicht nötig hat, zu schummeln :D.

    Ich denke aber trotzdem an eine Möglichkeit das Cheaten clientseitig zu verhindern. Aber ne geniale Idee hab ich irgendwie (noch) nicht 😃



  • Man muss immer davon ausgehen, dass der Client (und da darf man nicht an die selbstgeschriebe Software denken) alle empfangenen Informationen zu seinem maximalen Nutzen verwendet. Wenn der Client etwas nicht wissen soll, darf man es nicht senden.

    So würde ich das auch sehen. ICh denke wenn die Internetverbindungen noch schneller werden und die Leistung der Server noch steigt kann man das vielleicht auch so machen. Das also der Client nur Darstellung und Empfangen von Input des Spielers übernimmt, Kollision, Schadensberechnung, usw... macht alles der Server.

    Vielleicht könnte man auch ein System realisieren, indem es keinen Server gibt, sondern nur die CLients, die sich alle selbstständig gegenseitig kontrollieren.

    Oder man hofft halt das man irgendwann nicht mehr schummeln muss.



  • Nanyuki schrieb:

    Bei 3D-Spielen wird die aktuelle Position periodisch und die aktuelle Bewegungsrichtung an den Server übermittelt, dieser sendet die Informationen an alle Clients weiter. Wenn überhaupt, dann werden nur grobe Plausibilitätstests ausgeführt (wenn sich der Spieler innerhalb einer Sekunde über das gesamte Spielfeld bewegt hat, kann man das als Cheatversuch deuten). Oft wird aber nicht einmal das gemacht. Stattdessen verlässt man sich dann auf solche Systeme wie PunkBuster oder GameGuard, die jedoch keine wirkliche Sicherheit bieten, da sie vollständig auf dem Prinzip "security by obscurity" basieren.
    So wird es bei vielen kommerziellen Spielen gemacht, Verbesserungspotenzial gibt es dabei mehr als genug.

    Mich würde mal interessieren wie die anderen Clients die Bewegung zwischen den übermittelten Bewegungs und Positionsdaten berechnet.

    z.B. Spieler A bewegt seine Figur etwas nach licks mit der Maus.
    Nun bekommen die anderen Clients zu Zeitpunkt 1 die Position des Spielers A und die Bewegung des Spielers (Auch die Bewegungsänderung?) mitgeteilt.
    Sie interpolieren linear bis zum erwarteten zeitpunkt 2 an dem die nächsten Positionsdaten kommen.

    Nun macht der Spieler A aber keine lineare Bewegung mit der Maus sondern z.B eine etwas "ruckeliege".

    Wenn jetzt die anderen Clients die Bewegung linear interpoliert haben (was soll man sonst auch machen wenn man ja nichts von der ruckeligen Mausbewegung zwischen den beiden Zeitpunkten mitbekommen kann) stimmen die berechneten Positionen ja nicht mit der tatsächlichen von A die zum Zeitpunkt 2 übermittelt wird überein.

    Mit würden folgende Lösungen spontan einfallen:

    1. Die Spielfigur A bei den anderen Clients korrogiert die Position schlagartig.
    (führt zu abrupten Sprüngen und Ruckeln)

    2.Die Spielfigur A bei den anderen Clients berechnet in die nächste lineraen Interpolation einfach den gemachten Fehler ein und versucht diesen bei der nächsten linearen Interpolation ausgleichen
    (Ich weiß nicht genau was hier an Fehlern passiern können. Eventuel schaukeln sich die Fehler immer mehr auf)

    3.Man ignoriert diese ungenauigkeiten erst einmal etwas und läßt eine gewisse ungenauigkeit zu und wendet 1. oder 2. nur an wenn der Fehler zu groß geworden ist.

    Dieses Problem wird ja noch durch verschieden lange Laufzeiten der TCP oder UDP Pakete, je nach Routerauslastungen die sich ja permanent ändern, verstärkt

    Wie wird mit diesem Problem nun wirklich angegangen?



  • Der Fachbegriff aus der Informatik dafür ist Dead-Reckoning.

    Die Interpolation, die du angesprochen ist Teil dieses Vorgangs.
    Im Endeffekt nimmt man die Positionsdaten des Servers und die vergangene Zeit und interpoliert linear/quadratisch.
    Wenn man nun ca. 60 Updates pro Sekunde vom Server bekommt, reicht das für ein flüssiges Spielen vollkommen aus. Die Pakete müssen auch nicht (zeitlich) äquidistant bei dir eintreffen, aber die Spieler mit den niedrigen Pings haben bei den meisten Protokollen Vorteile.

    Ein Problem bleibt die Latenz, d.h. Spieler 1 schickt sein Paket an den Server und der Server schickt es an Spieler 2.

    Leider gibts hier sehr viel Unwissen zu dem Thema, mehr als die Hälfte der Beiträge hier sind Vermutungen. Insbesondere was die Anti-Cheat-Tools angeht.

    Ein Punkt bleibt unbestritten : Verschiedene Spiele arbeiten verschieden.

    Aber: Alle HL/HL2/Q3/Q4-Games (beispielsweise) nutzen das gleiche Prinzip. Der Server prüft alles, validiert alles, interpoliert alles, macht Kollisionskontrolle, ... und zwar mit der "Tick-Rate" des Servers.
    In HL-CS-1.6 nimmt man gerne eine Tickrate von 1000Hz.
    In HL2 bringen 66Hz manche Server schon ins Schwitzen.

    In jedem Tick wird das ganze Game-Model/Entities neu berechnet. Was du aber davon tatsächlich als Client-Update erhälst, ist ein ganz anderes Thema ( Bandbreiten-Einsparung).

    Ein System/Spiel, was zu 100% Dead-Reckoning unterstützt kann nicht ruckeln!

    Zu jedem Positionsupdate ( Vector 3D ) gibts noch einen Speed-Vector ( 3D ) und evtl. einen BeschleunigungsVector(3D, quasi delta-Speed).

    Alternativ gibts auch noch DR-Modi, bei dem statt Geschwindigkeitsvektoren auch Winkelgeschwindigkeiten übertragen werden.
    Sehr praktisch, wenn man mit Flugzeugen/Raumschiffen Kurven fliegt. Denn für die Kurve musst du quasi sehr viele Updates schicken, obwohl sie mathematisch sehr einfach beschrieben werden kann.



  • das thread is ja schon etwas älter aber ich greifs mal auf:

    angenommen der client berechnet collisionen u.a. ist es dann trotzdem nicht wahnsinn wie schnell der ganze internet-udp-traffic funktionieren muss, damit das spiel flüssig läuft?
    mein udp-pack besteht aus 2 vektoren (position,direction) und einem integer. um den in einer byte-array zu serialisieren damit er per udp-pack gesendet werden kann, benötigt es schon ca 40ms. naja und wenn dann 20 client auf dem server sind, wobei jeder client alle 300ms seine position sendet, klappt das dann noch für ein flüssiges spiel ohne interpolation? (ich frag deswegen, weil ich selbst sowas programmiere und mit dem interpolieren nicht klarkomme: aufgrund des interpolierens könnte es ja vorkommen, dass 2 spieler wie geister durch sich durchlaufen und das is kacke.

    wusste garnicht, dass "normale" online-games wie counter-strike interpolation verweden, hab gedacht, es wird einfach periodisch die position gesendet und der spieler dann einfach auf die position gesetzt. lieber würde ich die performancec für ein schnelleren udp-traffic verweden anstatt für interpolation, oder?



  • Fachmann schrieb:

    das thread is ja schon etwas älter aber ich greifs mal auf:

    angenommen der client berechnet collisionen u.a. ist es dann trotzdem nicht wahnsinn wie schnell der ganze internet-udp-traffic funktionieren muss, damit das spiel flüssig läuft?
    mein udp-pack besteht aus 2 vektoren (position,direction) und einem integer. um den in einer byte-array zu serialisieren damit er per udp-pack gesendet werden kann, benötigt es schon ca 40ms. naja und wenn dann 20 client auf dem server sind, wobei jeder client alle 300ms seine position sendet, klappt das dann noch für ein flüssiges spiel ohne interpolation? (ich frag deswegen, weil ich selbst sowas programmiere und mit dem interpolieren nicht klarkomme: aufgrund des interpolierens könnte es ja vorkommen, dass 2 spieler wie geister durch sich durchlaufen und das is kacke.

    wusste garnicht, dass "normale" online-games wie counter-strike interpolation verweden, hab gedacht, es wird einfach periodisch die position gesendet und der spieler dann einfach auf die position gesetzt. lieber würde ich die performancec für ein schnelleren udp-traffic verweden anstatt für interpolation, oder?

    Du mußt ja auch bedenken, dass wenn der Server z.B. in den USA steht und du dich in Eurpa dort einwählst hast du schon Ping Zeiten von uber 100.
    Also wirst du um Interpolation nicht herumkommen.
    Aber auch die Interpolation gestaltet sich schwieriger als man zunächst denkt,
    weil wenn du am Client z.B alle 10 ms ein UDP Paket abschickst kommen diese aber nicht so schön in diesem Abstand an. Die Router können mal weniger oder mehr ausgelastet sein oder Pakete können unterschiedliche Wege zum Ziel nehmen.
    Es kann sogar vorkomman, das wenn du UDP Paket A abschickst und später Paket B, dass Paket B vor A ankommt. (oder Pakete kommen gar nicht an)
    (Das beduetet: die Spielfigur soll nur geradeauslaufen. Es kommt aber ein Paket nach einem davor abgesendeten an. Also würde die Figur nach vorne, kurz zurück und wieder nach vorne laufen. Das ruckelt dann wie blöde.)
    Es müssen also alle Pakete zusätzlich durchnummeriert werden oder noch besser die Absendezeit (z.B in ms seit Spielbeginn) mit übertragen werden.
    Noch besser wird die Interpolation wenn man nicht nur den Bewegungsvektor übermittelt, sondern auch noch einen Vektor der die Änderung der Bewegung angiebt. (Bis das wirklich flüssig wird, ist das ne echte bastelei).

    Am Anfang kannst du ja mal versuchen einfach das Spiel Pong netzwerkfähig zu mahen und die Bewegung der Kugel flüssig hinzubekommen. Hier wirst du schon sehen, dass du ohne Interpolation nicht auskommst. (Sogar bei nem lokalen Netzwerk gehts nicht ohne Interpolation).
    (Pong ist das Minimalbeispiel und hier wirst du schon auf die meisten Probleme stoßen, die die Shooter noch viel stärker zu lösen haben)



  • wie ich sehe ist der daten-traffic zwischen online-spielen eine eigene wissenschaft an sich. meiner meinung nach ist es auch eine der höchsten kunst des programmierens mit höheren sprachen, weil es eine nahezu perfekte effizienz aufweisen muss.
    die idee mit der richtungsänderung find ich an sich praktisch bei dem pong-spiel.
    die kugel läuft also 100% träge immer in eine richtung bis ein UDP-packet den richtungsvektor aktualisiert (vergleichbar wie träge masse und kräfte in der physik). bei dieser lösung ist es allerdings fatal wenn mal ein udp-pack nicht ankommt und die kugel geradeaus weiterläuft.
    ist es deshalb sinnvoll für diese idee das TCP-protokoll zu verweden? es ist zwar langsamer jedoch müssen auch weniger packs versendet werden.
    schwierig wird es hierbei dann wieder, wenn man ego-shooter (o.ä.) programmieren will. wenn der user mit seiner maus ständig hin- und herwackelt und daher seine richtung inerhalb kürzester zeit verändert wäre das TCP-protokoll dafür zu lahm.
    (einzige lösung vielleich noch: reliable UDP, woraus ich jetzt nicht näher eingehen will)
    letzendlich wollte ich nochmal das interpolieren ansprechen: angenommen player1 bewegt sich von position1 auf position 2. er schickt dem server also, dass er auf position 2 schon IST!. der server schickt diese bewegung an alle anderen spieler weiter. diese interpolieren jetzt den weg von position1 zu position2 obwohl player1 schon längst angekommen ist. mist oder?


Log in to reply