# Datenbank für kleinen Online Highscore



## Koyote (18. August 2014)

*Datenbank für kleinen Online Highscore*

Hallo,
ich bin derzeit dabei in Java ein 2D Spiel zu programmieren. Alles kein Problem, aber leider kenne ich mich bezüglich html, php, mysql überhaupt nicht aus.
Ich habe nämlich vor, den erreichten Score Online in einer MySql DB zu speichern und auch wieder auszulesen. Das sollte alles über das Programm laufen.
Es gibt ja kostenlose Anbieter für kleine MySql DBs und auch für Webseiten. Daher wollte ich nun eine Html Seite schreiben mit Anfragen, die an einen php Skript übergeben werden, der mit einer MySql Datenbank kommuniziert.
Dabei würde ich gerne die SpielerID, das Level und den Score übertragen. 
Dadurch möchte ich erreichen, dass jeder Spieler seinen Score hochladen kann und auch später nochmal verbessern. Dabei soll die ID helfen, die dann einfach die (falls vorhandenen) Werte überschreibt.
Da es verschiedene Level gibt, sollte auch das Level aus der DB auszulesen sein, da ich dann beim auslesen die Highscoreliste in Level unterteilen kann. 

Vorgestellt hatte ich es mir so, dass ich eine MySql Datenbank habe mit den Werten SpielerID, Level, Score.
Dann rufe ich über das Programm eine URL auf, die aus der URL die Werte übernehmen (www.xxx.xxx/SpielerID&Level&Score).
Diese Seite ruft dann einen php Skript auf, der mit die Daten mit der Datenbank abgleicht.
Wenn also Spieler ID schon vorhanden, dann Level == Wert von Level aus der URL; Score == Wert von Score aus der URL.
Wenn Spieler ID noch nicht vorhanden, dann Wert von SpielerID aus der URL = new Spieler(); und dann eben die Werte von Level und Score noch abspeichern.
Und dann beim Abfragen hatte ich mir überlegt mit einer neuen Seite auf die Datenbank zuzugreifen und mir einfach alle Werte sortiert nach Level und Score auslesen zu lassen.
Dann downloade ich mir mit Java den Quelltext und schneide mir das wichtige raus, vielleicht sogar beim Auslesen damit es einfacher ist einzelne Datenblöcken mit Beschriftungen wie "SpielerID = " + Die erste ID usw.

So, von der Logik her alles klar und kann ja auch nicht so schwer sein... Dachte ich mir zumindest 
Nun habe ich nach einigen Stunden rumprobieren und lesen einfach kein Bock mehr. Ich hatte mir zwar nen Webspace und nen Datenbank anbieter herausgesucht, aber mehr kam auch nicht bei rum.
Eine Tabelle zu erzeugen schien ja noch ganz Simpel, diese dann auszulesen machte dann aber schon mehr Probleme, wegen irgendwelchen Zugriffsrechten, die ich garnicht verteilt habe und danach wäre ich wahrscheinlich daran gescheitert, wie ich das ganze in ein Array schreibe oder Zeile für Zeile ausgebe.

Nun die Frage an euch, 
wie schaffe ich es, die Werte ID, Level und Score irgendwie im Netz zu speichern? Meinetwegen alle Werte hintereinander auf einer einzigen Seite die jeder Idiot manipulieren kann... Um die Sicherheit geht es mir erstmal nicht.
Gibt es da schon vorgefertigtes Zeug im Netz oder gibt es eine möglichkeit für jemanden, der sich mit Php usw. überhaupt nicht auskennt, das zu realisieren?

Die komplette programmierung vom Spiel in Java verläuft reibungslos und da ich ein Scoresystem drin habe, hätte ich eben gerne auch eine Möglichkeit, dass sich Spieler mit anderen vergleichen können. Dazu fehlt mir eben das Wissen über das Onlinezeug. Daher würde ich mich freuen, wenn mir hier geholfen wird.

Gruß,
frustrierter Koyote


----------



## BenRo (18. August 2014)

*AW: Datenbank für kleinen Online Highscore*

Hey Koyote,

Nicht frustrieren lassen, dein Ansatz klingt schonmal gut.

Zunächst: Für die Abfrage von der Datenbank brauchst du kein HTML generieren, sondern etwas, was du leicht weiterverarbeiten kannst. So lange es so simpel bleibt, wie du beschreibst reicht CSV. Ansonsten bietet sich JSON an. Etwas komplexer wirds mit XML.

Nun zur Datenbank und deinem Zugriffsrechteproblem: Was für eine Datenbank ist es denn? Wie hast du den Datenbankuser angelegt? Oder war der vom Hoster vorgegeben?


----------



## Koyote (18. August 2014)

Ehrlich gesagt habe ich mir ne MySql Datenbank kostenlos geholt und habe dann die Zugangsdaten bekommen. Anschließend habe ich auf phpmyadmin.com die Daten eingegeben und mir die Tabelle dort erstellt. Dann habe ich mir ne Php Datei geschrieben um darauf zuzugreifen(ich dachte der User den ich da bekommen habe ist sowas wie ein Administrator zugang.)
Als dann irgendwie nichts passierte habe ich versucht in dem Tool das hinzuzufügen über Php code und da stand dann, dass der Zugriff für den User nicht gestattet ist. 

Wie schwer ist es denn, das ganze zu realisieren? 

Gruß


----------



## BenRo (18. August 2014)

*AW: Datenbank für kleinen Online Highscore*

PhpMyAdmin ist eine Software, um die Datenbank, MySQL, leichter administrieren zu können. Auf phpmyadmin.net ist nur eine Demo-Datenbank um diese Software zu präsentieren, es ist nicht dafür gedacht, eigene Projekte umzusetzen.

Erster Schritt muss jetzt erstmal sein: Webhosting mit PHP und Datenbank  (wird meist MySQL sein) organisieren.
Falls du bereits irgendein Webhosting angebot hast: Oft ist eine Datenbank dabei, kannst ja mal nachschauen.

Deine Idee ist nicht sooooo schwer umzusetzen. Du solltest allerdings ein bisschen Ahnung davon haben, wie HTTP funktioniert, was objektrelationale Datenbanken sind, SQL-Syntax verstehen, dir ein sinnvolles Datenbankschema überlegen und die PHP-Syntax verstehen. Okay, klingt jetzt komplizierter als es ist. Die gute Nachricht: HTML brauchst du für dein Vorhaben gar nicht )solange nur dein Java-Spiel mit deiner Datenbank kommuniziert und die Daten nicht auch noch auf einer öffentlichen Webseite ansprechend angezeigt werden sollen).


----------



## Koyote (18. August 2014)

*AW: Datenbank für kleinen Online Highscore*

Bei Hostinger.de habe ich mir jetzt ne MySql Datenbank und Webspace geholt. 
Wollte dann nach diesem tutorial vorgehen: Basic online high scores with XNA / C# and PHP / MYSQL | Brightside Games

Aber irgendwie bekomm ich den Nutzer bzw. die richtigen Rechte nicht korrekt hin und bekomme daher keinen Zugriff.


----------



## BenRo (18. August 2014)

*AW: Datenbank für kleinen Online Highscore*

An welchem Punkt scheiterst du denn? Ich kenne zwar Hostinger nicht, aber üblicherweise bekommt man genau einen Datenbankuser vom Hoster zugewiesen (entweder mit einem zugewiesenen Passwort oder mit einem, dass man selber definieren kann) und der User hat alle Rechte auf die eigene Datenbank.

Edit: Du musst natürlich die jeweiligen SQL-Befehle aus dem Tutorial an deine Situation anpassen, z. B. den Datenbanknamen usw.

Noch ein Edit: Leider enthält das Tutorial ein paar gravierende Mängel.
- Beispielsweise sollte man konsequent <?php als öffnenden Tag verwenden.
- Der letzte schließende Tag ?> in einer Datei sollte jeweils weggelassen werden.
- Die ganzen mysql_-Befehle sind veraltet. Man kann entweder mysqli_ verwenden, oder, wie ich finde besser, PDOs (PHP Data Objects), ist die objektorientierte Variante
- Der im Tutorial verwendete Code ist unsicher und offen für SQL-Injections
- POST für die Top 10 Highscores ist quatsch, hier sollte GET verwendet werden
- Das Datenbankschema ist nicht durchdacht. Warum latin1? Warum die jeweilige Größe der Felder? Warum ist die ID nicht unsigned? usw.
- Es findet kein Escpaing statt. Wenn jemand _COL_ heißt, funktioniert nichts mehr, wie es soll
- Der Beispiel-HTML-Code auf Seite 3 ist ungültiger Quatsch
- md5 ist nicht gerade der beste Hashing-Algorithmus
- ...


----------



## Koyote (18. August 2014)

Ohje....
Gibt es ein aktuelles Tutorial was du mir empfehlen kannst?


----------



## BenRo (18. August 2014)

*AW: Datenbank für kleinen Online Highscore*

Dieses Post ist doppelt. Kann das jemand löschen?


----------



## BenRo (18. August 2014)

*AW: Datenbank für kleinen Online Highscore*

Für genau das Thema was du brauchst, leider nicht.

Hast du für die Datenbank einen phpmyadmin- oder anderen grafischen Clientzugang? Ist für den Einstieg einfacher, als SQL zu lernen.

Für die Datenbank musst du dir erstmal überlegen, welche Felder du brauchst.
Theoretisch reicht ja, wie du sagtest Spieler - Level - Score. Soll für jedes Level für jeden Spieler nur ein Score gespeichert werden, oder mehrere? Welchen Datentyp haben die Felder jeweils? Auch die Größe der Felder sollte man sinnvoll wählen - für Integer zum Beispiel hier die verschiedenen Typen: MySQL :: MySQL 5.1 Referenzhandbuch :: 11.2 Numerische Datentypen

Für den Zugriff auf die Datenbank, hier die Infos zu PDOs:
- Verbindung aufbauen: PHP: Verbindungen und Verbindungsmanagement - Manual
- In die Datenbank schreiben / aus ihr lesen: PHP: Prepared Statements und Stored Procedures - Manual

Für die Verbindung deines Spiels mit dem Skript, evtl sowas in der Art:

```
<?php
// Hier Code einfügen, der die Datenbankverbindung herstellt

switch($_SERVER['REQUEST_METHOD']) {
   case 'GET':
      // Hier Code einfügen, damit ein Eintrag aus der Datenbank gelesen wird
   break;
   case 'POST':
   case 'PUT':
      // Hier Code einfügen, damit ein Eintrag in die Datenbank geschrieben wird
   break;
   default:
      throw new Exception('Ungültige Anfrage');
   break;
}
```
Dann musst du dir ein sinnvolles Format überlegen, mit dem dein Spiel umgehen kann, um die Daten einzulesen. Das kann ganz simpel

```
Spielername,Level,Highscore
Spielername,Level,Highscore
Spielername,Level,Highscore
Spielername,Level,Highscore
```
sein - allerdings musst du dann darauf achten, alle Kommas in Spielername in was anderes umzuwandeln (z. B. \, oder ,,) oder aber "Spielername",Level,Highscore verwenden (und dann alle " in Spielername escapen) oder ähnlich.

Am Besten einfach mal loslegen, ausprobieren, recherchieren, nochmal ausprobieren, Zwischenstand hier reinposten, von mir zerpflückt werden. 

EDIT: SQL gelernt hab ich 2003 mit Can Türkers "SQL: 1999 & SQL: 2003 - Objektrelationales SQL, SQLJ & SQL/XML" und dann hab ich mich je nachdem, welches Datenbanksystem ich verwendet hab anhand der MySQL bzw. PosgreSQL-Webseiten weitergebildet. Ob das Buch allerdings noch halbwegs aktuell ist, weiß ich nicht. Und es war zugegebenermaßen auch schwer zu verstehen. ^^


----------



## Koyote (19. August 2014)

*AW: Datenbank für kleinen Online Highscore*

*EDIT NR Unendlich:*
Hab endlich das richtige Stichwort für das letzte Problem gefunden, und nun läuft alles 
Vielen vielen Dank!


----------



## BenRo (19. August 2014)

Möchtest du deinen aktuellen Code + Datenbankschema mal posten? Dann schau ich noch mal drüber.


----------



## enrager7 (20. August 2014)

*AW: Datenbank für kleinen Online Highscore*

Das Thema würde mich auch mal interessieren. Was genau ist das für ein 2D Spiel?


----------



## Koyote (20. August 2014)

*AW: Datenbank für kleinen Online Highscore*

Also die Datenbank besteht aus
ID, Name, Level, Score.
Die ID wird beim ersten Start des Spiels generiert, ist eine Random Zahl mit 9 Ziffern, also theorethisch könnte da auch eine ID doppelt entstehen, aber  das ist so unwahrscheinlich... Naja vielleicht mach ich am Ende noch ne Abfrage, ob die ID schon  existiert. Den Namen kann man auch eingeben, jedoch ist nur eine bestimmte Anzahl an Zeichen erlaubt und mein Trennzeichen filter ich raus.
Beides wird auf dem jeweiligen PC gespeichert. Noch im Klartext, vielleicht wird das aber noch so geändert, dass man ohne die ID nicht den Name entschlüsseln kann und ohne Name nicht die ID, was dann bedeuten würde, dass wenn man an der Datei was ändert, ein Fehler auftritt. Aber wenn jemand unbedingt öfter in den Highscore will, dann soll es ihm gegönnt sein, Gründe dafür noch etwas später.
Die PHP Dateien, würde ich nur ungern posten, da ich ja sonst das ganze Schema schon offen lege. Habe es nämlich letztendlich doch über die Werte in der URL gelöst. 
Beim schreiben verwende ich eine Abfrage mit mysql_query und SELECT. Da prüfe ich, ob ID und Level schon vorhanden sind. Wenn z.B. die ID vorhanden ist, aber für Level 2 und man grade als Level 3 eingegeben hat, wird für die ID noch ein Eintrag für Level 3 erstellt. Das ganze läuft über mysql_query und INSERT INTO. Danach hole ich mir mit $_GET[xxx] die Werte aus der URL.
Falls der Eintrag, also Level und ID doch schon vorhanden ist, wird mit mysql_query UPDATE durchgeführt.
Beim lesen übergebe ich mit $_GET[xxx] das Level über die URL  und dann lade ich mir in ein Array die Daten von der Tabelle, die das Leve beinhalten und gebe diese dann hintereinander, mit Trennzeichen aus.

Und im Java Programm habe ich eben ein Frame für den Highscore erstellt, mit einer Auswahlmöglichkeit, von welchem Level man den Highscore sehen möchte. Dann lade ich die entsprechende URL und lade mit den Quelltext runter. 
Da ich trennzeichen verwende weiß ich, dass vorne und hinten table steht und daher lade ich alle einträge in ein Array und nehme dann die Größe des Arrays -2. Damit habe ich die Anzahl der Einträge und kann, wenn noch keine 10 Einträge im Highscore vorhanden sind, nur so viele Textfelder erstellen, wie es Einträge gibt. Anschließen lade ich mir die Einträge von vorne nach hinten in die Textfelder, da ich sie schon beim Ausgeben mit ORDER BY sortiert habe.

Nun, beim Schreiben lade ich mir den Name und die ID aus der Datei, dann hole ich mir noch vom anderen Thread den Score und das Level vom Frame. Sobald ich die alle habe, mach ich mir nen neuen StreamReader und Buffered Reader und schicke dann die URL mit den Daten los. Schon ist alles in der Datenbank. 

Im Endeffekt eigentlich auf dem Niveau alles sehr sehr einfach. Wenn man sich mit MySql und PHP etwas auskennt, geht das wahrscheinlich 1000 mal schneller als bei mir, aber ich hatte eben noch keine Ahnung davon. Der Java-Teil ging entsprechend schnell. Achso und die Datenbank habe ich komplett über myPHP Admin gemacht, da ich nichts brauchte, was man dort nicht machen kann. Was ich dann im nachhinein noch geändert habe, waren eben passend für meine Werte die Variablen und beim Score habe ich noch eingestellt, dass wenn der INT zu kurz ist, mit 0 aufgefüllt wird. Habe das einfach gemacht, damit falls mal was schief geht, die Struktur vorhanden bleibt.

Also warum mir bei vielen Sachen die Sicherheit usw. nicht so wichtig ist ist einfach zu erklären. Ich interessiere mich schon lange fürs programmieren und habe "früher" sehr gerne mit VB.net und C# mit XNA Framework gearbeitet. Naja, irgendwann gehen einem dann eben auch die Ideen aus und man ist von der Mathematik noch nicht so weit. Daher habe ich dann erstmal nichtsmehr programmiert. Dann kam ich aber auf die Oberstufe und da lernen wir Java. Eigentlich kann man ja alles grundlegende von anderen Sprachen übernehmen und muss sich nur an die Schreibweise gewöhnen (obwohl man da ja shon was aus C# kennt ). Im prinzip konnte ich nach ner Stunde schon alles machen, was wir in einem Jahr jetzt gelernt haben. Und naja, mit dem Lehrer gab es immer etwas Streit, da ich einige Sachen komplett anders gesehen habe und er meiner Meinung nach auch einiges einfach nicht weiß.
Naja, ich hatte immer 15 Punkte geschrieben und habe dann aufgrund meiner Beiträge 14 Punkte im Zeugnis bekommen. Im Endeffekt ist mir die Note total egal, aber ich will einfach nochmal dem netten Herrn zeigen, was ich kann und da hab ich mir eben gedacht, dass es ein einfaches Java Spiel tut. 1. Wird er niemals auch nur im Ansatz so weit kommen (er muss schon beim bearbeiten von Strings und Arrays googlen ) und 2. sieht er es dann hoffentlich ein, wenn er sich daran versucht es nachzumachen, dass ich nicht nur dummes Zeug geredet habe, sondern es wirklich kann. 
Das mit dem Online Highscore habe ich mir vom Aufbau her sehr einfach vorgestellt (was es ja auch ist) und bin eben daran gescheitert, dass ich noch nie etwas in MySql und PHP gemacht habe. Deshalb brauchte ich einige Denkanstöße und Hilfe, aber der Post #9 von BenRo hat mehr als nur geholfen. Hatte dann noch ein Problem, aber das konnte ich noch im Netz nachlesen. Bezüglich der Sicherheit der Übertragung kann ich, falls ich das wirklich will, noch nachrüsten. 
Das Spiel ist noch nicht fertig, wird jedoch ziemlich vielseitig und verfolgt keine grade Struktur. Mein Ziel ist es einfach nur möglichst viele Mechaniken einzubinden, sonst wäre es ja zu einfach. Des Weiteren ist es auch nochmal eine gute Übung, da es mein erstes Spiel ist und ich danach in die Programmierung mit dem Android SDK einsteigen möchte. Jedoch finde ich bisher das ganze zwar sehr zeitintensiv(am längsten dauert eigentlich sinnvolle Positionen der Objekte festzulegen), aber dafür, dass ich es noch nie gemacht habe, geht es mir leicht von der Hand. Ich  verwende nur Java2D und keine Engine, also ich berechne alles selber für bestimmte Fälle... Eine Engine selbst zu schreiben wäre dann nämlich doch etwas zeitintensiver und für einen 17 Jährigen, der nach den Ferien auf Abitur hinarbeitet, wohl etwas zu stressig 

Gruß Koyote


----------



## DarkMo (21. August 2014)

*AW: Datenbank für kleinen Online Highscore*

hmm, du magst also nur 10 einträge speichern (is ja highscore und keine kompletübersicht), da brauchste glaube nichmal ne id (die haste wohl zum sortieren?). es sollte (wenn ich jetzt keinen denkfehler haben) folgender algorythmus langen:

- spieler hat einen punktestand X erspielt
- schicke namen N, level L und punktestand X ans php script
- frage in der db nach (select...), ob der minimal-wert kleiner als X ist
-> select * from highscore where x > min(punkte);

hmm, hierbei frag ich mich, ob das so schon funzt, wenn nicht, müsstest du es so abfragen:
-> select * from highscore where X > select min(punkte) from highscore;

jut...
- wenn X größer ist, wie der kleinste wert, dann schmeiss den eintrag mit dem kleinsten wert und adde X
-> delete from highscore where punkte = min(punkte); // oder eben wieder diese variante:
-> delete from highscore where punkte = select min(punkte) from highscore;
dann x adden:
-> insert into highscore (name, level punkte) values (N, L, X);


um die highscoretabelle dann auszugeben, brauchste dir nur alles sortiert ausgeben lassen
-> select * from highscore order by punkte asc; // glaube asc un nich desc, notfalls probieren ^^ asc brauchste aber nichmal mit hinschreiben, ist default-wert


----------



## BenRo (22. August 2014)

*AW: Datenbank für kleinen Online Highscore*



Koyote schrieb:


> Also die Datenbank besteht aus
> ID, Name, Level, Score.
> Die ID wird beim ersten Start des Spiels generiert, ist eine Random Zahl mit 9 Ziffern, also theorethisch könnte da auch eine ID doppelt entstehen, aber  das ist so unwahrscheinlich... Naja vielleicht mach ich am Ende noch ne Abfrage, ob die ID schon  existiert.



Schau dir mal Indizes in SQL-Datenbanken an (siehe PRIMARY KEY, UNIQUE, INDEX, ...).
Es ist sinnvoll, die ID als PRIMARY KEY zu definieren. Das hat folgende Auswirkungen:

- Da die Tabelle nach dem Feld ID indiziert wird, ist ein Zugriff (z. B. WHERE `ID`='a432gfd4') deutlich schneller, als ohne Index
- Achtung, es kann nur einen PRIMARY KEY  geben
- Ein PRIMARY KEY ist auch automatisch UNIQUE, das heißt werde dürfen nicht doppelt vorkommen, beim Versuch einen Wert doppelt anzulegen liefert die Datenbank einen Fehler zurück
-> Dieser Fehler sollte sich, wenn du PDOs verwendest als Exception bemerkbar machen, die du abfangen und es einfach nochmal mit einer neuen ID probieren kannst.

Da du ja die Top 10 Einträge pro Level selektierst ist ein weiterer INDEX (hier natürlich nicht Unique) auf die Spalte `level` sinnvoll.



> Die PHP Dateien, würde ich nur ungern posten, da ich ja sonst das ganze Schema schon offen lege. Habe es nämlich letztendlich doch über die Werte in der URL gelöst.


Wenn du möchtest und mir halbwegs vertraust kannst du mir ja per privater Nachricht den Code schicken und ggf. sensitive Daten raus-X-en.



> Beim schreiben verwende ich eine Abfrage mit mysql_query und SELECT. Da prüfe ich, ob ID und Level schon vorhanden sind. Wenn z.B. die ID vorhanden ist, aber für Level 2 und man grade als Level 3 eingegeben hat, wird für die ID noch ein Eintrag für Level 3 erstellt. Das ganze läuft über mysql_query und INSERT INTO. [...]


Bin mir unsicher, ob ichs 100% nachvollzogen habe, aber es klingt, als könne man es einfacher lösen. Es ist allgemein sinnvoll, möglichst viel von der Datenbank machen zu lassen. SQL ist sehr mächtig und normalerweise auch äußerst performant. Wenn du es schaffst das obige in einen einzelnen SQL-Query zu stecken, wird es vermutlich deutlich schneller laufen als SQL-Query -> PHP -> SQL-Query -> ...


Alles andere was du schreibst, klingt sinnvoll. Schön, dass es klappt! 

Nun zu DarkMo, zu dem Meisten was du schreibst will ich gar nichts sagen, aber zum letzten Satz:



> // glaube asc un nich desc, notfalls probieren ^^ asc brauchste aber nichmal mit hinschreiben, ist default-wert


Das hätte man in einer Minute googlen können:

ASC = ASCending = Aufsteigend = wie bei einem Berg von unten nach oben = erst kommen niedrige Werte, dann hohe

DESC = DESCending = Absteigend = wie bei einem Berg von oben nach unten = erst kommen hohe Werte, dann niedrige

Für Highscores also DESC verwenden, da man ja die 10 höchsten Werte haben will:

Beispiel für die TOP-10-Highscores von Level 6:


```
SELECT `name`,`punkte` FROM `highscore` WHERE `level`=5 ORDER BY `punkte` DESC LIMIT 10;
```


----------

