Beiträge von Speedy Consoles

    Naja, es ist ja nicht nur Warcraft, was abstürzt. Eben hatte ich einen BlueScreen, als Firefox aktiv war, aber nicht beim laden einer Seite, sondern aus heiterem Himmel.

    Problemsignatur:
    [INDENT] Problemereignisname: BlueScreen
    Betriebsystemversion: 6.1.7600.2.0.0.256.48
    Gebietsschema-ID: 1031
    [/INDENT]
    Zusatzinformationen zum Problem:
    [INDENT] BCCode: 4e
    BCP1: 0000000000000099
    BCP2: 000000000004A774
    BCP3: 0000000000000000
    BCP4: 000000000004A784
    OS Version: 6_1_7600
    Service Pack: 0_0
    Product: 256_1[/INDENT]

    Gerade kam wieder einer von meinen blauen Freunden:
    Der Computer wurde nach einem schwerwiegenden Fehler neu gestartet. Der Fehlercode war: 0x0000004e (0x0000000000000099, 0x000000000010d191, 0x0000000000000002, 0x000000000010d17e). Ein volles Abbild wurde gespeichert in: C:\Windows\MEMORY.DMP. Berichts-ID: 082810-22620-01.

    EventID: 1001

    Hi!
    Ich bin heute auf verschiedenen Wegen auf folgende Fehlermeldung gestoßen:

    Unteranderem durch ein einfaches PHP-Skript:

    PHP
    <?php
    exec("server.exe");
    ?>

    server.exe läuft bei doppelklick einwandfrei.

    Andere Aktionen bei denen der Fehler ebenfalls auftrat liefen noch kurz zuvor einwandfrei.

    Hat jemand eine Idee, woran das liegen könnte?

    Hi!
    Seit ich ein neues Betriebssystem (Windows 7) auf meinem Rechner installiert habe, habe ich oft bluescreens und Abstürze von Spielen, hauptsächlich Warcraft III, manchmal auch direkt nacheinander, d.h. das Spiel stürzt mit einer Fehlermeldung ab und ich bekomme gleich darauf einen bluescreen.

    Ich habe die neusten Treiber für Mainboard und Grafikkarte installiert.

    Wie kann ich herausfinden, woran das liegt?

    *Skript uptdated*

    Funktioniert soweit, die Tabelle stimmt, allerdings klappt das mit dem Tabellensperren wohl nicht und es dauert mir insgesamt ein bisschen zu lange...

    EDIT:

    *Skript uptdated*
    Habe eine neue Tabelle hinzugefügt, die statt des spielenden Spielers den gespielten Helden als key hat, sonst alles gleich...

    Bis eben gerade gab's noch gar kein Skript...
    Ich habe jetzt angefangen die Sache mit einer Mischung aus SQL und PHP zu lösen:

    Klappt auch soweit. Allerdings konnte ich, als ich das LIMIT noch nicht eingestellt hatte (ist jetzt zu Testzwecken so, sonst gibts n Fatal Error wegen zu langer Skriptausführung) die Tabelle "playerstats" per phpmyadmin einfach mal so leeren... Soviel zum Thema LOCK TABLES :roll:. Warum?

    Die Spalte "read" soll dafür da sein, damit ich nicht jedes mal die neue Tabelle neuschreibe, sondern nur um die neuen Spiele erweitere.

    Hier die Tabellen:
    games:

    dotagames:

    Code
    CREATE TABLE `dotagames` (
      `id` int(11) NOT NULL auto_increment,
      `botid` int(11) NOT NULL,
      `gameid` int(11) NOT NULL,
      `winner` int(11) NOT NULL,
      `min` int(11) NOT NULL,
      `sec` int(11) NOT NULL,
      PRIMARY KEY  (`id`)
      ) ENGINE=InnoDB DEFAULT CHARSET=latin1

    gameplayers:

    dotaplayers:

    Okay, also dieses "LOCK TABLES" scheint das zu sein, was ich brauche. Allerdings habe ich bei der Hälfte der Erklärung nur Bahnhof verstanden, weil ich auch in sachen SQL eigentlich keine Ahnung habe... :roll: Ich denke, ich könnte bei dieser Uptdate-Geschichte ein bisschen Hilfe gebrauchen...

    Ich erkläre das Problem noch mal ein bisschen genauer:
    Es geht um einen Bot, der im Warcraft 3 - Battle.net Spiele hostet und am Ende jedes Spiel die Datenbank aktualisiert. Das umfasst im wesentlichen vier Tabellen:

    games - ein neuer Eintrag
    dotagames - ein neuer Eintrag, wenn das Spiel ein Dotaspiel war (in der Regel immer)
    gameplayers - soviele neue Einträge, wie Spieler im Spiel waren
    dotaplayers - 10 neue Einträge, wenn das Spiel ein Dotaspiel war (in der Regel immer)

    Jeder Eintrag in jeder Tabelle hat natürlich eine fortlaufende Id zur eindeutigen Identifizierung. Jede der Tabellen mit Ausnahme der Tabelle "games" besitzt eine Spalte "gameid", in der die Id des zugehörigen Eintrags in der games-Tabelle steht.
    In der Tabelle "dotaplayers" gibt es eine Spalte "colour". Sie beinhaltet die Farbe des Spielers in Form einer Zahl von 1 bis 11 ohne 6. Da nach jedem Spiel 10 Spieler hinzugefügt werden, gibt es für alle Einträge mit der gleichen "gameid" jede Farbe genau einmal.
    In der Tabelle "gameplayers" gibt es diese Spalte "colour" ebenfalls. Hat ein Eintrag aus der Tabelle "gameplayers" die gleiche "gameid" und "colour", wie ein Eintrag aus der Tabelle "dotaplayers", dann handelt es sich um den selben Spieler in dem selben Spiel. Weil allerdings nicht jedes Spiel ein Dotaspiel ist (könnte ja mal passieren) und nicht jedes Dotaspiel mit 10 Spielern gespielt wird (es gibt also Dummyeinträge), gibt es nicht für jeden "gameplayer" einen "dotaplayer" und andersrum ebenfalls.
    Nun ist es außerdem so, dass der Name, der zur Identifikation des Spielers dient, NUR in der "gameplayers"-Tabelle in der Spalte "name" vorhanden ist. Er ist übrigens auch das einzige Feld, das ich von dieser Tabelle brauche, da die übrigen Statistiken für diese "Update-Geschichte" irrelevant sind.
    In der Tabelle "dotagames" sind drei Spalten wichtig. Die erste nennt sich "winner". Ist der Wert eines Eintrags hier 0, so wurde das Spiel nicht beendet und es gibt keine auswertbaren Statistiken. Ist der Wert 1 oder 2, so hat "Sentinel" oder "Scourge" gewonnen. Die Spalten "min" und "sec" beinhalten die Spieldauer in Minuten und Sekunden.

    Um zur Sache zu kommen:

    Ich möchte eine neue Tabelle erstellen, in der für jeden Spieler aus der "dotaplayers"-Tabelle, der mindestens ein Dotaspiel beendet hat (winner != 0), eine Zeile vorhanden ist. In dieser Zeile sollen einige Statistiken aus den Einträgen der beendeten Spiele in der "dotaplayers"-Tabelle summiert stehen. Außerdem sollen dort die Anzahl der Spiele, die Anzahl der Siege und die gesammte Spielzeit des Spielers stehen.

    Beispiel:
    Ein Spieler mit dem Nicknamen hans hat insgesammt 2 Dotapiele beendet, eins mit der Dauer 40:30, das andere mit der Dauer 29:30, 1 Spiel davon hat er gewonnen. Betrachte ich nur die Spalte "kills" in "dotaplayers" (es gibt noch mehr): Im ersten Spiel hat er 10 Kills bekommen, im zweiten 12.
    Der eintrag in der neuen Tabelle sieht also wie folgt aus:

    name: hans
    games: 2
    wins: 1
    playtime: 4200 (in Sekunden)
    kills: 22
    ...

    Außerdem sollen in die Tabellen noch ein paar Spalten eingetragen werden, die sich aus der Tabelle selbst ergeben, nämlich "winratio" (in diesem Fall 0.5), für alle Statistiken wie "kills" noch eine "-ratio" nach der Formel "kills / playtime * avaragegametime", wobei avaragegametime die durchschnittliche Dauer eines Dotaspiels ist, und noch eine Spalte, die ich "strength" getauft habe und für die ich mir eine komplexere Formel überlegt habe, die von "winratio", "games" und allen ratio-Statistiken wie "killratio" abhängt.

    So weit, so gut, aber wie realisiere ich das?
    Jedes mal, wen sich jemand eine Seite anschaut, die auf dieser Tabelle aufbaut, soll ein Query aufgerufen werden, der die Tabelle aktualisiert und nach einer gewissen Sortierung ausliest. Damit nicht jedesmal jedes Spiel und jeder Spieler ausgelesen wird, möchte ich die bereits gelesenen Spiele markieren, indem ich in der Tabelle "dotagames" eine neue Spalte "read" erstelle, die wahr oder falsch sein kann.
    Im diesem Query müssen zunächsteinmal die beiden Tabellen irgendwie verriegelt werden (irgendwie LOCK TABLES), damit doppelte Aufrufe des Skripts sich nicht in die Quere kommen. Dann werden aus allen vier Tabellen passende 4-Tupel an Einträgen ausgewählt:

    SQL
    SELECT * FROM ´dotaplayers´, ´gameplayers´, ´dotagames´, ´games´ WHERE ´games´.´id´ = ´dotagames´.´gameid´ AND ´games´.´id´ = ´gameplayers´.´gameid´ AND ´games´.´id´ = ´dotaplayers´.´gameid´ AND ´dotagames´.´winner´ != 0 AND ´dotagames´.´read´ = FALSE

    Habe ich das soweit richtig? Vorallem bei dem "!=" und dem "FALSE" bin ich mir nicht wirklich sicher...

    Jetzt muss ich alle obengenannten Daten unter dem entsprechenden Eintrag (Schlüssel "name") in der neuen Tabelle aktualiseren und ab jetzt habe ich keine Ahnung mehr, denke ich. Was ist zum Beispiel, wenn der Eintrag noch nicht existiert, und wie addiere ich etwas zu einem Feld wie "kills".
    Für die zusätzlichen Spalten wie "killratio" brauche ich auch noch die durchschnittliche Spieldauer, die ich aus allen Einträgen der "dotagames"-Tabelle errechnen könnte, aber wie Speichere ich mir soetwas?

    Abschließend muss ich dann noch alle Werte der Spalte "read" der gelesenen Einträge auf true setzen und die Tabellen entriegeln.

    In der Hoffnung, dass irgendjemand, der Ahnung von MySQL hat, bis zum Ende gelesen hat und sich für mein Problem interessiert

    Speedy Consoles

    Hi!
    Ich bastle gerade an einem PHP-Skript zum auslesen von Spielstatistiken aus einer MySQL-Datenbank. Die Statistiken werden von einem Bot geschrieben, auf dessen Art und Weise die Tabelle zu schreiben ich keinen Einfluss habe. In der Datenbank gibt es eine Tabelle, die mit jedem Spiel 10 Zeilen, die den Statistiken der 10 Spieler aus dem Spiel entsprechen bekommt.
    Nun ist es natürlich so, dass es auch Spieler gibt, die mehrere Spiele spielen, also öfter in der Tabelle auftauchen. Ich möchte nun per PHP eine neue Tabelle erzeugen, die jeden Spieler nur einmal und in der entsprechenden Zeile die gesammten Statistiken des Spielers enthält.
    Mit jedem aufruf des Skripts, dass die zweite Tabelle in irgendeiner Art und Weise präsentiert, soll diese auch gleichzeitig aktualisiert werden. Da dies aber bei einer großen Spielzahl eher länger dauert und und ich das nicht bei jedem Seitenaufruf haben möchte, lese ich aus der ersten Tabelle nur bisher ungelesene Einträge aus, indem ich eine weitere Spalte "read" hinzufüge und diese auf nach dem lesen auf 1 setze. Die gelesenen Statistiken werden dann in die zweite Tabelle integriert.
    Und jetzt kommt das Problem:
    Es ist zwar unwahrscheinlich, aber darf nicht außer Acht gelassen werden, dass zwei gleichzeitig ausgeführte Skripte, die beide die ungelesenen Zeilen aus der ersten Tabelle in die zweite Tabelle integrieren wollen sich in die Quere kommen, das heißt sie lesen beide gleichzeitig und integrieren die Zeilen doppelt, was die zweite Tabelle verfälscht.
    Dass das möglich ist, habe ich mit diesem Skript ausprobiert:

    Jetzt zwei fragen:
    1. Wie kann ich das verhindern?
    2. Kann ich wenigstens davon ausgehen, dass der MySQL-Server zwei Queries, die auch nur ansatzweise miteinander zu tun haben, NACHEINANDER ausführt?

    Vielen Dank fürs Durchlesen! ;)