PHP-Serverliste
Übersicht

![]() |
StarwarBetreff: PHP-Serverliste |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hallo,
Hier eine kleine PHP-Serverliste für Blitzbasic. Beispiel im Blitz-Code. Kurze Erklärung zur Funktionsweise: 1. Client fragt PHP-Script nach Servern und bekommt eine Liste mit IP, Port und einer ID je Server. 2. Client kontaktiert alle Server (das musst Du einprogrammieren, Funktion serverOnline(...) im BB-Code) 3. Der Client meldet dem Skript welche Server online und welche offline sind. 4. Wenn 3 unterschiedliche Clients gemeldet haben, dass der Server nicht verfügbar ist, wird er aus der Datenbank gelöscht. Wer diese Zahl ändern will guckt mal bei der Funktion couldNotConnect im PHP-Teil) Implementierung: 1. Datenbank anlegen 2. Login- und Ordner-Daten im PHP-Script und Blitz-Code anpassen 3. PHP-Code hochladen 4. Testen 5. serverOnline(...)-Funktion anpassen Quellcodes PHP-Script Code: [AUSKLAPPEN] <?php
$database = ""; //Datenbank (Server ist unten eingetragen) $password=""; //Passwort $table="games"; //Tabelle $action=$_GET['action']; $id=$_GET['id']; $offIDs=$_GET['offids']; $onIDs=$_GET['onids']; $hash=$_GET['hash']; $ip=$_GET['ip']; $port=$_GET['port']; $millisecs=$_GET['millisecs']; echo("[START]\n"); $verbindung=connect("localhost", $database, $password); $action = mysql_real_escape_string($action); $id = mysql_real_escape_string($id); $offIDs = mysql_real_escape_string($offIDs); $onIDs = mysql_real_escape_string($onIDs); $hash = mysql_real_escape_string($hash); $port = mysql_real_escape_string($port); $millisecs = mysql_real_escape_string($millisecs); switch ($action){ case 'get':getGames($table); case 'new':addGame($table,$ip,$port,$millisecs); case 'del':deleteGameHashCheck($id, $table, $hash); case 'sna':couldNotConnect($id, $ip, $table); case 'sce':serverOnline($id,$table); case 'ssr':meldeServer($ip, $onIDs, $offIDs, $table); default:echo("-- Unknown command"); } mysql_close($verbindung); echo("\n[ENDE]"); function getGames($table) { $abfrage = "SELECT * FROM '$table' ORDER BY $table.ID"; $ergebnis = mysql_query($abfrage); $err = mysql_error(); if ($err != "") { echo "-- $err\n"; return; } while($row = mysql_fetch_object($ergebnis)) { // $rem = autoRemove($table, $row); // if ($rem == false) { echo ("+$row->ID|$row->IP|$row->Port\n"); // } } echo ("++\n"); return; } function addGame($table, $ip, $port, $millisecs) { if ($port=="" || $ip == "" || $millisecs=="") { echo("-- Ungültige Argumente\n"); return; } //$stamp=time(); $hash="$ip|$port|$stamp|$millisecs"; $hash=md5($hash,false); $sqlrows="HASH,IP,Port,ErrorCount,ErrorIPs";//,LastPing"; $sqlvals="'$hash','$ip','$port','0',''";//,'$stamp'"; $eintrag ="INSERT INTO $table ($sqlrows) VALUES ($sqlvals)"; mysql_query($eintrag); $err = mysql_error(); if ($err != "") { echo ("-- $err\n"); } else { $gameID=mysql_insert_id(); echo ("+$gameID|$hash\n++\n"); } return; } function meldeServer($meldeIP,$idsOnline,$idsOffline,$table) { //Akzeptiert IDs als Liste (; ist Trennzeichen) if ($idsOnline != "") { $idOn = explode(";",$idsOnline); foreach ($idOn as &$id) { serverOnline($id, $table); } } if ($idsOffline != "") { $idOff = explode(";",$idsOffline); foreach ($idOff as &$id) { couldNotConnect($id, $meldeIP, $table); } } } function serverOnline($id,$table) { $abfrage = "SELECT * FROM '$table' WHERE ID = '$id' "; $ergebnis=mysql_query($abfrage); $err = mysql_error(); if ($err != "") { return; } $count="0"; $ipString = ""; $abfrage2 = "UPDATE '$table' Set ErrorCount = '$count' WHERE ID = '$id' "; $ergebnis2=mysql_query($abfrage2); $err2 = mysql_error(); $abfrage2 = "UPDATE '$table' Set ErrorIPs = '$ipString' WHERE ID = '$id' "; $ergebnis2=mysql_query($abfrage2); $err2 = mysql_error(); } function couldNotConnect($id, $IPdesMelders, $table) { $max=3; $abfrage = "SELECT * FROM '$table' WHERE ID = '$id' "; $ergebnis=mysql_query($abfrage); $err = mysql_error(); if ($err != "") { return; } $row = mysql_fetch_object($ergebnis); $ipString=$row->ErrorIPs; if ($ipString == "") { $ips[]=""; } else { $ips=explode(";",$ipString); } $report=true; foreach ($ips as &$cur) { if ($cur==$IPdesMelders) { $report=false; } } if ($report) { $count=$row->ErrorCount; $count++; if ($count > $max) { deleteGame($id, $table, true); } else { if (empty($ipString)) { $ipString = $IPdesMelders; } else { $ipString = "$ipString;$IPdesMelders"; } $abfrage2 = "UPDATE '$table' Set ErrorCount = '$count' WHERE ID = '$id' "; $ergebnis2=mysql_query($abfrage2); $err2 = mysql_error(); $abfrage2 = "UPDATE '$table' Set ErrorIPs = '$ipString' WHERE ID = '$id' "; $ergebnis2=mysql_query($abfrage2); $err2 = mysql_error(); } } } function connect($serv, $db, $pw) { $verbindung=mysql_connect($serv,$db,$pw) or die ("--\n"); mysql_select_db($db) or die ("--\n"); return $verbindung; } function deleteGameHashCheck($id, $table, $hash) { $abfrage = "SELECT * FROM '$table' WHERE ID = '$id' "; $ergebnis=mysql_query($abfrage); $err = mysql_error(); if ($err != "") { echo ("-- $err\n"); return; } $row = mysql_fetch_object($ergebnis); $h=$row->HASH; if($h == $hash) { deleteGame($id, $table); return; } else { echo ("-- $err\n"); return; } } function deleteGame($id, $table, $noecho) { $abfrage = "DELETE FROM '$table' WHERE ID = '$id' "; $ergebnis=mysql_query($abfrage); $err = mysql_error(); if ($err != "") { if($noecho) { return; } echo ("-- $err\n"); return; } if($noecho) { return; } echo ("++\n"); return; } ?> BlitzBasic Code: [AUSKLAPPEN] ;Informationen zur Serverregistrierung
Global phpserver_reg=False Global phpserver_id%=0 Global phpserver_hash$="" ;Type für die Serverliste Type phpserver_Server ;Diese Felder werden im Code verwendet Field id% Field ip% Field port% ;Diese sind überflüssig und nur für Testzwecke (-> serverOnline(...)) Field name$ Field players% Field maxplayers% Field ping% End Type ;Testinformationen server$="du.server.de" ;entspricht dem Host site$="/ordner/serverliste.php" ;Link zum Script myip%=Rand(10000,990000) myport%=Rand(10,90) ;Server registrieren Test ok = phpserver_registerServer(server$, site$, myip%, myport%) If ok=True Then Print "ID: "+phpserver_id% Print "Hash: "+phpserver_hash$ Print "Adresse: "+myip%+":"+myport% Else Print "Fehler beim erstellen des Servers" EndIf ;Serverlisten-Test ok = phpserver_getServerlist(server$,site$, myip%) If ok = True Then For s.phpserver_Server = Each phpserver_Server Print s\name$+" | "+s\players+"/"+s\maxplayers+" | "+s\id+" | "+s\ping+" | "+s\ip%+":"+s\port%+" Next Else Print "Fehler" EndIf ;Server-löschen Test Print "Löschtest: "+phpserver_unRegisterServer(server$, site$, phpserver_id%, phpserver_hash$) WaitKey End ;Meldet einen Server ab (Host, Link zum Script, serverID, serverHash) ;Liefert true bei Erfolg Function phpserver_unRegisterServer(server$,site$, id%, hash$) answer$ = phpserver_internal_request$(server$, site$+"/?action=del&id="+id%+"&hash="+hash$) If Instr(answer$,"--") Or answer="" Then phpserver_reg=True ;<-- Ist die Frage ob man den Fehlversuch nicht einfach ignorieren soll Return False Else phpserver_reg=False EndIf Return True End Function ;meldet einen Server an (Host, Link zum Script, IP des Servers als Int, Port des Servers) ;Liefert true bei Erfolg Function phpserver_registerServer(server$, site$, myip%, myport%) answer$ = phpserver_internal_request$(server$, site$+"/?action=new&ip="+myip%+"&port="+myport%+"&millisecs="+MilliSecs()) If Instr(answer$,"--") Or answer="" Then phpserver_reg=False Return False Else anz=phpserver_internal_explodeCount(answer$,"@") For i=0 To anz-1 cur$=phpserver_internal_explode(answer$,"@",i) If Left(cur$,1)="+" And Left(cur$,2)<>"++" Then phpserver_reg=True phpserver_id%=Int(Mid(cur$,2,Instr(cur$,"|")-2)) phpserver_hash$=Mid(cur$,Instr(cur$,"|")+1,-1) EndIf Next EndIf Return True End Function ;Lädt die Serverliste in den Type (Host, Link zum Script, IP des Anfragestellers als Int) ;Liefert true bei Erfolg Function phpserver_getServerlist(server$,site$,myip%) Delete Each phpserver_Server answer$ = phpserver_internal_request$(server$, site$+"/?action=get") If Instr(answer$,"--") Or answer="" Then Return False Else anz=phpserver_internal_explodeCount%(answer$,"@") For i=0 To anz-1 cur$=phpserver_internal_explode(answer$,"@",i) If Left(cur$,1)="+" And Left(cur$,2)<>"++" Then ex$=Mid(cur$,2,-1) s.phpserver_Server=New phpserver_Server s\id%=Int(Trim(phpserver_internal_explode$(ex$,"|",0))) s\ip%=Int(Trim(phpserver_internal_explode$(ex$,"|",1))) s\port%=Int(Trim(phpserver_internal_explode$(ex$,"|",2))) If serverOnline(ip%,port%,s) Then onString$=onString$+s\id%+";" Else offString$=offString$+s\id%+";" Delete s EndIf EndIf Next If Right(onString$,1)=";" Then onString$=Left(onString$,Len(onString)-1) If Right(offString$,1)=";" Then onString$=Left(offString$,Len(onString)-1) phpserver_internal_request$(server$,site$+"/?action=ssr&ip="+myip%+"&offids="+offString$+"&onids="+onString$) EndIf Return True End Function ;Kontaktiert den Server über UDP und fragt Spielinformationen ab ;(IP des Servers als Int, Port desd Servers, Object) ;Liefert ob der Server verfügbar ist (True/False) Function serverOnline(ip%,port%,server.phpserver_Server) ;/////////////////////////////////////////////////// ;HIER HAST DU ARBEIT ;) ;Es sollte ein Timeout eingebaut werden ;/////////////////////////////////////////////////// server\name$=Chr(Rand(65,90))+Chr(Rand(65,90))+Chr(Rand(65,90)) server\players=5 server\maxplayers=Rand(5,9) server\ping=Rand(15,99) Return Rand(0,1) ;<- Ist der Server online? End Function ;Allemeine Anfrage an das Script(Host, Link zum Script mit Args) ;Liefert den Text zwischen [START] und [ENDE]. Zeilentrennung durch @ Function phpserver_internal_request$(server$, site$) tcp = OpenTCPStream(server$,80) If Not tcp Then Return "-- No Connection" WriteLine tcp,"GET "+site$+" HTTP/1.1" WriteLine tcp,"Host: "+server$ WriteLine tcp,"User-Agent: Opera/9.80 (Windows NT 6.0; U; de) Presto/2.2.15 Version/10.10" WriteLine tcp,"Connection: close" WriteLine tcp,"Accept: */*" WriteLine tcp, Chr$(10) Local start=False txt$="" lin$ = ReadLine(tcp) If Not Instr(lin$,"200") Then Return "-- "+lin$ Repeat lin$ = ReadLine(tcp) If lin$="[ENDE]" Then start=False If start Then lin$=Replace(lin$,Chr(10),"") lin$=Replace(lin$,Chr(13),"") If lin$ <> "" Then txt$=txt$+lin$+"@" EndIf EndIf If lin$ = "[START]" Then start=True Until Eof(tcp) If Right(txt$,1)="@" Then txt$=Left(txt$,Len(txt$)-1) CloseTCPStream(tcp) Return txt$ End Function Function phpserver_internal_explodeCount%(in$,tz$) pos=Instr(in$,tz$) If pos=0 Then Return 1 EndIf Repeat pos=Instr(in$,tz$,pos+1) If Mid(in$,altpos+1,pos-1-altpos) <> "" Then anz=anz+1 If pos = 0 Then Exit Forever Return anz End Function Function phpserver_internal_explode$(in$,tz$, index%) pos=0 altpos=0 exploded$="" Repeat altpos=pos pos=Instr(in$,tz$,pos+1) If pos = 0 Then pos=-1 If Mid(in$,altpos+1,pos-1-altpos) <> "" Then If index%=i% Then exploded$=Mid(in$,altpos+1,pos-1-altpos) Exit EndIf i%=i%+1 EndIf If pos=-1 Then Exit Forever Return exploded$ End Function Function INT_IP(ip$) p1=Instr(ip$,".") p2=Instr(ip$,".",p1+1) p3=Instr(ip$,".",p2+1) Return (Int(Mid(ip$,1,p1))*16777216)+(Int(Mid(ip$,p1+1,p2-p1))*65536)+(Int(Mid(ip$,p2+1,p3-p2))*256)+Int(Mid(ip$,p3+1,-1)) End Function Und der SQL-Code zum Erzeugen der Datenbank Code: [AUSKLAPPEN] SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
CREATE TABLE IF NOT EXISTS `games` ( `ID` int(11) NOT NULL auto_increment, `HASH` text NOT NULL, `IP` int(11) NOT NULL, `Port` int(11) NOT NULL, `ErrorCount` int(11) NOT NULL default '0', `ErrorIPs` text NOT NULL COMMENT 'Getrennt durch ;', PRIMARY KEY (`ID`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; Ich hab noch manuell Änderungen am Code vorgenommen. Wenn jemand einen (Tipp-)Fehler findet wäre ich ihm/ihr sehr verbunden. MFG EDIT 1.7.2010 - Änderungen am PHP-Code (strlen, switch, '$table') - Änderungen am BB-Code (Name ersetzt) |
||
- Zuletzt bearbeitet von Starwar am Do, Jul 01, 2010 19:43, insgesamt 3-mal bearbeitet
Düsi |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Mal wird eine Variable deutsch benannt, mal gibt man ihr einen englischen Namen. Mal wird eine Variable komplett klein geschrieben, dann werden die Wörter wieder mit _ getrennt und beim nächsten Mal schreibt man wieder jedesWortAmAnfangGross.
Zum PHP Code: -> Wieso verdammt gibst du einen Doctype an?! -> ' ist schneller als " (hier wird geprüft, ob sich Variablen im String befinden), weswegen dies auch verwendet werden sollte. -> In Querys sollten Tabellen- und Spaltennamen immer zwischen zwei ` stehen, da somit Konflikte mit der Syntax von MySQL vermieten werden. Code: [AUSKLAPPEN] if ($action == "get") {
getGames($table); } else if ($action == "new") { addGame($table,$ip,$port,$millisecs); } else if ($action=="del") { deleteGameHashCheck($id, $table, $hash); } else if ($action == "sna") { couldNotConnect($id, $ip, $table); } else if ($action == "sce") { serverOnline($id,$table); } else if ($action=="ssr") { meldeServer($ip, $onIDs, $offIDs, $table); } else { echo("-- Unknown command"); } Wie wärs damit? Code: [AUSKLAPPEN] switch($action) {
case 'get': getGames($table); break; case 'new': addGame($table, $ip, ...); break; ... default: echo '-- Unkown command'; } Code: [AUSKLAPPEN] $abfrage = "SELECT * FROM $table WHERE ID = '$id' ";
$ergebnis=mysql_query($abfrage); $err = mysql_error(); if ($err != "") { return; } 1. Wie oben gesagt, Strings in ', nicht in ". 2. Variablenbezeichner mittels '...'.$var.'...'; bzw. "...{$var}..." einbinden. 3. Wenn das Query fehlerhaft ist, wird FALSE zurück gegeben. Es reicht folglich ein if($ergebnis === FALSE), um zu prüfen, ob das Query fehlerfrei war. Der Aufruf von mysql_error ist an dieser Stelle unnötig. Code: [AUSKLAPPEN] if ($ipString=="") {
besser: Code: [AUSKLAPPEN] if(!strlen($ipString))
oder if(empty($ipString)) |
||
![]() |
Starwar |
![]() Antworten mit Zitat ![]() |
---|---|---|
Danke für deine konstruktive Kritik.
Ich muss zugeben, dass ich die " nur aus Gewohnheit genommen habe. Deshalb auch keine Switch-Blöcke (was in diesem Fall wirklich viel übersichtlicher gewesen wäre). Doctype. Nunja, das gehört für mich eben dazu. Die Sache mit dem mysql_error() habe ich nachher hinzugefügt, da ist deine Lösung wesentlich eleganter. Danke dafür. Öhmm, ja die ' bei $table. Die habe ich einfach vergessen... ![]() Die groß/kleinschreibung Englisch/Deutsch hat durchaus ein System. Damit kann man Zähl/Temp/Langlebige Variablen unterscheiden. die Unterstriche stellen Ebenen dar. Genug der Rechtfertigungen. Ich werde bei Gelegenheit den Code ein wenig säubern. Ich hoffe ich kann trotzdem (auch dir) ein wenig Arbeit abnehmen und einen guten Einstiegspunkt gegen. So weit, MFG. EDIT: Kennst du ein gutes PHP-Tutorial? Also eins in dem man auch ordentliche Verwaltung, casts, etc. erklärt bekommt. Du siehst, ich habe in PHP mehr Halbwissen als Erfahrung. |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group