Telnet in mySQL speichern

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
drakes
User
Beiträge: 2
Registriert: Samstag 21. November 2015, 23:51

Hey Leute,

ich habe bereits mehrere kleine Scripte in Python geschrieben, bin aber dennoch Anfänger...
Und zwar hab ich ein Problem.

Mein Python Script liest über Telnet mit dem Befehl "lp" mehrere Spieler aus.
Die Liste ist wie folgt aufgebaut:
1. SPIELER 1
2. SPIELER 2
3. SPIELER 3
usw.

Diese möchte ich gerne in einer Datenbank speichern.
Ich habs soweit geschafft, dass er mir den ersten in der Liste in der Datenbank speichert, aber keine weiteren.
Habs schon mit ner While Schleife versucht, aber hat auch nicht geklappt.

Hier mal den Code, den ich verwende:

Code: Alles auswählen

while True:
    
        line = tn.write("lp\n")

        line = tn.read_until("\n")
                
        while re.search("^(.*) INF Executing command 'lp' by Telnet from (.*):(.*)",line) is None:
                line = tn.read_until("\n")
                        
                
        line = tn.read_until("\n")
                
        if re.search("^Total of 0 in the game",line) is None:
                data = re.search("(.*). id=(.*), (.*), pos=(.*), rot=(.*), remote=(.*), health=(.*), deaths=(.*), zombies=(.*), players=(.*), score=(.*), level=(.*), steamid=(.*), ip=(.*), ping=(.*)", line)
                
                
                cursor.execute("SELECT * FROM players WHERE entityID = %s",(data.group(2)))
                        
                if cursor.rowcount >= 1:
                        row = cursor.fetchone()
                        #print line   
                        #Zombiekills + Playerkills * 30 + level * 2 - Tote * 10 - ausgegebenes Geld
                        coins = int(row[7]) + (int(row[8]) * 30) + (int(row[4]) * 2) - (int(row[6]) * 10) - int(row[12])
                        cursor.execute("UPDATE players SET username = %s, level = %s, pos = %s, death = %s, zombiekills = %s, playerkills = %s, score = %s, ip = %s, coins = %s WHERE entityID = %s",(data.group(3), data.group(12), data.group(4), data.group(8), data.group(9), data.group(10), data.group(11), data.group(14), coins, data.group(2)))

                        connection.commit()
                        line = tn.read_until("\n")
                        
                else:
                        print line 
                        cursor.execute("""INSERT INTO players (id,entityID,username,steamid,level,pos,death,zombiekills,playerkills,score,ip,coins,ausgegeben,ban) VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, 0, 0, 0)""",(data.group(2), data.group(3), data.group(13), data.group(12), data.group(4), data.group(8), data.group(9), data.group(10), data.group(11), data.group(14)))
                        connection.commit()
                        line = tn.read_until("\n")
        else:
              line = tn.read_until("\n")
Wie bekomm ich das am besten hin? Hat jemand eine Idee? Wäre aufjedenfall sehr dankbar!

Gruß
drakes!
Zuletzt geändert von Anonymous am Sonntag 22. November 2015, 14:14, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Ich habs soweit geschafft, dass er mir den ersten in der Liste in der Datenbank speichert, aber keine weiteren.
Heißt: der `INSERT` Befehl wird ausgeführt, aber kein `UPDATE`?

Im allerersten Schritt solltest du den Code mal dringend entwirren und auf Funktionen aufteilen. Im Moment ist das ja eine wilde Mischung aus Daten von Telnet lesen, Daten verarbeiten und Daten in die DB schreiben. Da ist schwer nachzuvollziehen und noch schwerer zu debuggen.

Und hier macht es IMHO auch sehr viel Sinn, ein ORM zu nutzen. Jeder Mitspieler ist z.B. eine Instanz einer Klasse `Player`, welche die Attribute `zombikills`, `playerkills` etc hat.

Wie viele Daten kommen da eigentlich so rein? Wenn's viel ist macht IMHO der Einsatz eines KV-Stores wie Redis hier mehr Sinn als ein RDBMS. Das oben gesagte gilt aber auch dafür.

Gruß, noisefloor
drakes
User
Beiträge: 2
Registriert: Samstag 21. November 2015, 23:51

Hallo,

erstmal danke für dein Feedback!

Wie gesagt, ich bin ein totaler Neuling in Python. (Hab erst vor 2 Tagen angefangen, damit rumzuspielen) :D
Das Script macht das, was es machen soll, Wenn der Eintrag des Spielers noch nicht existiert, legt der mir einen neuen an.
Wenn der Eintrag existiert, tut der mir diesen Updaten.

Das Problem ist einfach, dass er mir nur den ersten Spieler einträgt, bzw updatet.
d.H. Wenn 9 Spieler auf dem Server derzeit sind, wird nur der 1. bearbeitet. Da evtl eine Schleife fehlt oder so?
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

unabhängig vom verworrenen Code:

* wenn du prüfst, ob ein Spieler existiert, dann solltest du einfach nur `id` abfragen und gegen `None` prüfen. Existiert der Spieler nicht, sollte die DB-Abfrage nämlich `None` zurück liefern.
* `INSERT INTO players (id,entityID,username,steamid,level,pos,death,zombiekills,playerkills,score,ip,coins,ausgegeben,ban) VALUES (NULL, %s, ...` ist als SQL-Befehl IMHO quatsch: weil: wenn die `id` `NULL` sein darf, dann brauchst du ziemlich sicher auch keine ID. Außerdem hast du doch wahrscheinlich beim Anlegen der Tabelle `id` auf `primary key` und `autoincreament` gesetzt?

Gruß, noisefloor
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

@noisefloor: NULL ist der Platzhalter für Felder, die automatisch hochzählen. Also kein Fehler, sondern ein Feature.
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
NULL ist der Platzhalter für Felder, die automatisch hochzählen. Also kein Fehler, sondern ein Feature.
Axo... Wenn ich ein autoincrement-Feld habe, dann lasse ich es im INSERT-Statement immer weg. Funktioniert aber in der Tat auch so wie oben.

Also: bitte meine obigen Aussage streichen :-)

Gruß, noisefloor
Antworten