13.03.2010, 04:06
HI, wer mich nicht kennt ich bin Geramy inhaber der Vio-Server
da ich oft gefragt werde wie das mit dem mysql loginsystem geht poste ich einfach mal nen tut:
Nun gut ich mцchte euch heute hier jetzt das Mysql im Samp nдher bringen. Zuvor mцchte ich aber sagen, wenn man noch gar keine Ahnung von Mysql hat oder gerade erst am Anfang des Scriptens steht, lieber die Finger von MySql zu lassen. Dazu muss ich sagen, dass ich in diesem Script Linux verwende und dieses Mysql-Plugin: http://forum.sa-mp.com/index.php?topic=148182.0 das ich nur sehr Empfehlen kann. Die Installation eines MysqlPlugins findet ihr in anderen Tutorials in diesem Forum.
Hier geht es nun drum ein Mysql-Register/Login zu Scripten bestehend aus mehreren Gui's.
Bevor man Anfangen kann zu Scripten muss man sich ersteinmal ьberlegen was man Abspeichern mцchte in der Mysql-Datenbank (im folgenden Nenne ich die Mysqldatenbank nur noch DB). Hier in diesem Tutorial nehme ich als Beispiel fьr die Spielerdaten das Adminlevel. Desweiteren welche Informationen ьber den Spieler interessieren mich beim Registrieren (Hier im Tutorial: Nickname, Passwort, IP, Registrierdatum und E-Mail).
Nach diesen Ьberlegungen gehst du nun in das Verwaltungssystem deiner DB (z.B. PhpMyAdmin) und erstellst eine Datenbank in der die Tabellen des Scriptes gespeichert werden sollen (Hier im Beispiel: BeispielDatenbank). AnschlieЯen erstellst du 2 Tabellen. Eines fьr die Userdaten und eine fьr die Accountdaten. (Man kann alles auch in einem machen, habe mich aber fьr 2 Entschieden um eine schnellere Ьbersicht zu haben wenn ich mal nach Accounts suche oder anderem). In den Tabellen legst du die wьnschenswerten Spalten an. Denk daran das du eine Spalte ID mit autoincrement benцtigen kцnntest und das du die Spalten im Richtigen Format einstellst. (zB eine Spalte Adminleven mit Int(50).
Hier im Scirptbeispiel des Tutorials benцtigst du folgende Tabellen und Spalten:
1. Tabelle "players" mit den Spalten: ID (autoincrement Int(50), Nickname(varchar(255)),Passwort(varchar(255)),IP(v archar(255)),Register(varchar(255)),EMail(varchar( 255))
2. Tabelle "userdata" mit den Spalten: ID(autoincrement Int(50)),Nickname(varchar(255)),Adminlevel(int(50) )
Als nдchstes solltet ihr in wie ganz oben schon gesagt im Samp-Server euer Mysql-Plugin installiert haben.
Hier im Tut: http://forum.sa-mp.com/index.php?topic=148182.0
Nun kцnnen wir beginnen zu Scripten. Beginnen wir erstmal mit der Festlegung unserer Variablen und Definitionen und einbauen des Notwendigen includes.
--> Das Include
Dazu fьgst du ganz oben den Scriptcode ein:
Zunдchst brauchen wir auch 2 Farben. Eine fьr Erfolgreich und eine fьr Fehler. Dafьr nehmen wir Grьn und Rot.
Diese mьsst ihr ebenfals ganz oben einbauen. Am besten gleich unter den #include befehlen:
Um es Spдter zu erleichten das Mysql-Script ein zubauen benцtigen wir 4 weitere Definitionen. Den Mysqluser, dessen Passwort, die datenbank und den Host(IP zur DB):
Desweiteren ist es Ratsam um spдter alles Schnell дndern zu kцnnen ebenfals eine Definition fьr den Timer, der zum Speichern der Userdaten da ist, anzulegen:
Kommen wir nun zu den Variablen. Wir brauchen zuerst eine Variable fьr die Registrationsdaten Hier nennen wir sie RegInfo sie braucht noch einen Index mit der SpielerID und eine InfoIndex (Keine Zahl sondern Text wie der Index rIP) diese InfoIndexe kann man ьber enums anlegen. DIe Zweite ist fьr die Spielerdaten und funktioniert genauso:
Um spдter die Accountdaten alle 10 Minuten (oder wie die Variable update_time eingestellt ist) zu Speichern benцtigen wir einen Timer. Dieser wird unter OnGameModeInit() plaziert. gleich kцnnen wir dort das Script um zur DB zu verbinden einbauen und den Log befehl fьr das Mysql.
Syntax der Funktionen:
--> mysql_connect(Hostadresse, Datenbankuser, Datenbankpasswort, Name der Samp-Datenbank, Automatisches Reconnecten bei Verbindungsverlust(mit einer Boolean-Variable true/false)); ==> Boolean := Wahrheitswert
--> mysql_log(LogType); ==> hat noch weitere Optionale Parameter
Nachlesen kцnnt ihr auch weitere Informationen ьber die Syntax auf der Website des DB-Plugins.
Script:
Baut man eine Verbindung auf muss man diese auch beenden. Daher bauen wir eine Funktion zum schlieЯen der Verbindung in OnGameModeExit ein. Desweiteren muss dort das letzte mal unsere Userdaten aller spieler gespeichert werden.
Jetzt ist schon die ganze Zeit im Script die Sprache von der Public Updater(). Diese mьssen wir natьrlich erst anlegen. Spдter werden die Userdaten in einer Public UserUpdate(playerid); gespeichert. Aber um sie fьr alle auszufьhren mьssen in unserer Updatefunktion alle Spieler durchgegangen werden und gespeichert. D.h. in einer Schleife. Dazu eignet sich besonders gut die for-to-do-Schleife.
Unsere Public mьsste wie folgt aussehen:
Dies sind erstmal alle Funktionen gewesen die soweit ohne Mysql funktioniert haben oder nur wenig enthalten haben. Aber um das eigentliche Script zu schreiben brauchen wir 3 Funktionen fьr unser Script:
1. Eine Zum Laden von Daten aus einer Tabelle
2. Eine Zum Ьberprьfen ob es die Date gibt (eventuell das auslesen einzellner Daten)
3. und das Speichern von Daten in der DB
die 1. und die 2. kann man zusammenfassen zu einer Funktion. Dies habe ich auch im Script getan wie ihr gleich sehen werden. Allerdings wird um Ressourcen zu sparen unser Loginsystem spдter mit einer eigenenstдndigen abfrage funktionieren.
Kommen wir nun zu Abfrage und Ьberprьfung:
Nun zur 3. Funktion der Speicherung der Daten. Da es im Script 3 wichtige Datentypen gibt (String, Integer und Float) muss man beachten das man entweder 3 Funktionen anlegt oder bei unserer Variante beim Ausfьhren der mysqlupdate-Funktion vorher die Variable in einen String umgewandelt hat.
Da wir nun die 2 Funktionen haben kцnnen wir uns an das eigentliche Login System machen:
die Login und die Registerfunktion:
Jetzt haben wir zwar einen Login und eine Registrierung aber die Speicherung der Daten fehlt noch also fьgen wir noch die UserUpdate(playerid) funktion ein:
Fehlt natьrlich auch noch das die Daten gespeichert werden wenn der User den Server verlдsst:
Zu allerletzt mьsst ihr ganz oben noch die forward der Funktionen einbauen:
Es fehlen jetzt nur noch 3 Dinge.
1. OnPlayerConnect
Es muss ein Gui erstellt werden wenn der Spieler drauf kommt:
Die Funktion Disconnect (um Userdaten zu speichern + Spieler nicht mehr eingeloggt zu setzen:
und zu letzt die Antwort auf die Gui's:
Bitte Informiert euch ьber die Guis in anderen Tutorials da es hier mehr um die Mysql-Funktionen geht.
Vielen Dank fьrs Lesen, bei Anregungen Tipps Fragen oder sollte ich Fehler gemacht haben einfach Posten ich lese es gern und antworte auch gerne (bei bedarf kann ich auch eine Scriptdatei hochladen in der die Funktionen gespeichert sind)
da ich oft gefragt werde wie das mit dem mysql loginsystem geht poste ich einfach mal nen tut:
Nun gut ich mцchte euch heute hier jetzt das Mysql im Samp nдher bringen. Zuvor mцchte ich aber sagen, wenn man noch gar keine Ahnung von Mysql hat oder gerade erst am Anfang des Scriptens steht, lieber die Finger von MySql zu lassen. Dazu muss ich sagen, dass ich in diesem Script Linux verwende und dieses Mysql-Plugin: http://forum.sa-mp.com/index.php?topic=148182.0 das ich nur sehr Empfehlen kann. Die Installation eines MysqlPlugins findet ihr in anderen Tutorials in diesem Forum.
Hier geht es nun drum ein Mysql-Register/Login zu Scripten bestehend aus mehreren Gui's.
Bevor man Anfangen kann zu Scripten muss man sich ersteinmal ьberlegen was man Abspeichern mцchte in der Mysql-Datenbank (im folgenden Nenne ich die Mysqldatenbank nur noch DB). Hier in diesem Tutorial nehme ich als Beispiel fьr die Spielerdaten das Adminlevel. Desweiteren welche Informationen ьber den Spieler interessieren mich beim Registrieren (Hier im Tutorial: Nickname, Passwort, IP, Registrierdatum und E-Mail).
Nach diesen Ьberlegungen gehst du nun in das Verwaltungssystem deiner DB (z.B. PhpMyAdmin) und erstellst eine Datenbank in der die Tabellen des Scriptes gespeichert werden sollen (Hier im Beispiel: BeispielDatenbank). AnschlieЯen erstellst du 2 Tabellen. Eines fьr die Userdaten und eine fьr die Accountdaten. (Man kann alles auch in einem machen, habe mich aber fьr 2 Entschieden um eine schnellere Ьbersicht zu haben wenn ich mal nach Accounts suche oder anderem). In den Tabellen legst du die wьnschenswerten Spalten an. Denk daran das du eine Spalte ID mit autoincrement benцtigen kцnntest und das du die Spalten im Richtigen Format einstellst. (zB eine Spalte Adminleven mit Int(50).
Hier im Scirptbeispiel des Tutorials benцtigst du folgende Tabellen und Spalten:
1. Tabelle "players" mit den Spalten: ID (autoincrement Int(50), Nickname(varchar(255)),Passwort(varchar(255)),IP(v archar(255)),Register(varchar(255)),EMail(varchar( 255))
2. Tabelle "userdata" mit den Spalten: ID(autoincrement Int(50)),Nickname(varchar(255)),Adminlevel(int(50) )
Als nдchstes solltet ihr in wie ganz oben schon gesagt im Samp-Server euer Mysql-Plugin installiert haben.
Hier im Tut: http://forum.sa-mp.com/index.php?topic=148182.0
Nun kцnnen wir beginnen zu Scripten. Beginnen wir erstmal mit der Festlegung unserer Variablen und Definitionen und einbauen des Notwendigen includes.
--> Das Include
Dazu fьgst du ganz oben den Scriptcode ein:
Code:
#include <mysql>
Diese mьsst ihr ebenfals ganz oben einbauen. Am besten gleich unter den #include befehlen:
Code:
#define COLOR_ERROR 0xFF0000FF //Fehler #define COLOR_SUCCESSFUL 0x00FF00FF //erfolgreich
Code:
#define datahost "localhost" #define datauser "BeispielUser" #define datapass "BeispielPasswort" #define database "BeispielDatenbank"
Code:
#define update_time 600000 //Zeitintervall des Timers in Millisekunden d.h. um Minuten zu bekommen Minuten *60000 Hier: 10 min
Code:
enum rInfo{ EMail[255], Passwort[255], IP[255], RegisterDatum[255], }; new RegInfo[MAX_PLAYERS][rInfo]; enum pInfo{ pLogged, pAdmin }; new PlayerInfo[MAX_PLAYERS][pInfo];
Syntax der Funktionen:
--> mysql_connect(Hostadresse, Datenbankuser, Datenbankpasswort, Name der Samp-Datenbank, Automatisches Reconnecten bei Verbindungsverlust(mit einer Boolean-Variable true/false)); ==> Boolean := Wahrheitswert
--> mysql_log(LogType); ==> hat noch weitere Optionale Parameter
Nachlesen kцnnt ihr auch weitere Informationen ьber die Syntax auf der Website des DB-Plugins.
Script:
Code:
mysql_log(1); //diesen empfehle ich spдter auf mysql_log(0); zu setzen oder ganz zu lцschen wenn das Script funktioniert mysql_connect(datahost,datauser,datapass,database,true); SetTimer("Updater",update_time,true);
Code:
Updater(); mysql_close();
Unsere Public mьsste wie folgt aussehen:
Code:
public Updater() { for(new i=0;i<MAX_PLAYERS;i++) //solange fьr i um eins erhцht von i=0 aus gilt,dass i kleiner der Maximalen Spielerzahl ist wird durchgefьhrt: { UserUpdate(i);// die Updatefunktion des Spielers } }
1. Eine Zum Laden von Daten aus einer Tabelle
2. Eine Zum Ьberprьfen ob es die Date gibt (eventuell das auslesen einzellner Daten)
3. und das Speichern von Daten in der DB
die 1. und die 2. kann man zusammenfassen zu einer Funktion. Dies habe ich auch im Script getan wie ihr gleich sehen werden. Allerdings wird um Ressourcen zu sparen unser Loginsystem spдter mit einer eigenenstдndigen abfrage funktionieren.
Kommen wir nun zu Abfrage und Ьberprьfung:
Code:
public mysqlget(table[],bedien[],abfrag[],data[]) //Funktion: mysqlget(In welcher Tabelle befindet sich die Datei?, Welche Bedienung gilt? (zB ID des Spielers oder bekannte daten), Welche Spalte soll abgefragt werden?, Variable in der gespeichert wird) { new query[256]; //Query = Abfrage String muss definiert werden format(query,sizeof(query),"SELECT %s FROM %s WHERE %s",abfrag,table,bedien); // entspricht: Frage "abfrag" ab in der Tabelle "table" mit der Bedienung "bedien" mysql_query(query); // sende die Abfrage mysql_store_result(); //Liste die Ergebnisse auf if(mysql_num_rows()) //Wie viele Zeilen hat das Ergebnis (Keine Zeile = Kein Ergebnis) { mysql_fetch_field(abfrag, data); //Frage das Feld "abfrag" ab (Feld entspricht dem Spalte in einer ErgebnisZEILE) und speichere in data mysql_free_result(); //gibt den Speicher fьr weitere Abfragen wieder frei return true; //gibt true=Wahr zurьck wenn die Date existiert und abgefragt werden konnte } else { mysql_free_result(); //siehe oben return false; //gibt false zurьck wenn Date nicht existiert oder nicht Abgefragt werden konnte } }
Code:
public mysqlupdate(table[],bedien[],spalte[],data[]) {//Syntax: mysqlupdate( die Tabelle in der DB, Die Bedienung, Die Spalte, die Variable als String) new query[256]; format(query,sizeof(query),"UPDATE %s SET %s='%s' WHERE %s",table,spalte,data,bedien); //entspricht: Update die Tabelle "table" Setze "Spalte" den Wert "data" wo die Bedienung "bedien" gilt //Es MUSS beachtet werden das zu speichernde Variablen im Query immer mir ' ' umschlossen werden mьssen daher '%s' mysql_query(query); //senden des Querys mysql_free_result(); //Freigabe des Speichers }
die Login und die Registerfunktion:
Code:
public Login(playerid,playername[]) { new query[256]; new data[255]; new bedienung[256]; format(bedienung,sizeof(bedienung),"Nickname='%s'",playername); format(query,sizeof(query),"SELECT * FROM userdata WHERE %s",bedienung); //Nehme ALLE Daten aus userdata bei der die Bedienung "bedienung" gilt --> * steht immer fьr ALLE mysql_query(query); // senden der ABfrage mysql_store_result();//abfragen des ergebnisses if(mysql_num_rows())//auflisten der zeilen { mysql_fetch_field("Adminlevel",data); //abfragen des felden Adminlevel und zwischen speichern in data PlayerInfo[playerid][pAdmin]=strval(data);//umwandeln von data in die Spielervariable (ACHTUNG!! alle abfragten Daten sind erst Strings --> daher strval um es in einen Integer zu wandeln if(PlayerInfo[playerid][pAdmin]>0) { SendClientMessage(playerid,COLOR_SUCCESSFUL,"Willkommen Admin!"); } mysql_free_result();//freigabe des Speichers PlayerInfo[playerid][pLogged]=1;//spieler ist eingeloggt } else { SendClientMessage(playerid,COLOR_ERROR,"Es ist ein Fehler mit deinem Account aufgetretten!"); Kick(playerid); } return 0; } public Register(playerid) { new playername[256]; GetPlayerName(playerid,playername,sizeof(playername)); new query[256]; format(query,sizeof(query),"INSERT INTO players (Nickname,Passwort,EMail,IP,Register) VALUES ('%s','%s','%s','%s','%s')",//Fьge in players ein mit den Spalten Nickname,Passwort,Email,Ip,Register der Werte.... sind (die Reihen folge in den Klammern muss die selbe bleiben) playername, RegInfo[playerid][Passwort], RegInfo[playerid][EMail], RegInfo[playerid][IP], RegInfo[playerid][RegisterDatum]); mysql_query(query); //senden format(query,sizeof(query),"INSERT INTO userdata (Nickname) VALUES ('%s')",playername); mysql_query(query);//einfьgen des Datensatzen in userdata mit Spalte Nickname deren wert der Speilername ist mysql_free_result(); ShowPlayerDialog(playerid,3,1,"Loginsystem","Dein Account wurde erfolgreich angelegt \n Bitte logge dich ein!","Abbrechen","Login!");//anzeigen des Loginguis }
Code:
public UserUpdate(playerid) { if(IsPlayerConnected(playerid))//ist spieler verbunden { if(PlayerInfo[playerid][pLogged]==1)//ist spieler eingeloggt? { new playername[255]; GetPlayerName(playerid,playername,sizeof(playername)); new bedien[256]; new updatestring[256]; format(updatestring,256,"%d",PlayerInfo[playerid][pAdmin]);//Umwandeln der Variable in einen String damit Updatefuntkion geht format(bedien,sizeof(bedien),"Nickname='%s'",playername);//wieder die Bedienung mysqlupdate("userdata",bedien,"Adminlevel",updatestring);//funktion mysqlupdate ausfьhren syntax siehe oben } } }
Code:
public OnPlayerDisconnect(playerid, reason) { UserUpdate(playerid); PlayerInfo[playerid][pLogged]=0; return 1; }
Code:
forward mysqlget(table[],bedien[],abfrag[],data[]); forward Login(playerid,playername[]); forward Register(playerid); forward mysqlupdate(table[],bedien[],spalte[],data[]); forward UserUpdate(playerid); forward Updater();
1. OnPlayerConnect
Es muss ein Gui erstellt werden wenn der Spieler drauf kommt:
Code:
public OnPlayerConnect(playerid) { new bedienung[256]; new playername[256]; GetPlayerName(playerid,playername,sizeof(playername)); format(bedienung,sizeof(bedienung),"Nickname='%s'",playername); new daten[256]; if(mysqlget("players",bedienung,"Passwort",daten))//abfrage es gibt true zurьck oder false variable daten ist unwichtig { SendClientMessage(playerid,COLOR_SUCCESSFUL,"Du hast bereits einen Account"); ShowPlayerDialog(playerid,3,1,"Loginsystem","Du hast bereits einen Account \n Bitte logge dich ein!","Abbrechen","Login!"); } else { SendClientMessage(playerid,COLOR_ERROR,"Du hast noch keinen Account"); ShowPlayerDialog(playerid,1,1,"Loginsystem","Du hast noch keinen Account \n Bitte gebe dein Passwort ein!","Abbrechen","Bestдtigen!"); } return 1; }
Code:
public OnPlayerDisconnect(playerid, reason) { UserUpdate(playerid); PlayerInfo[playerid][pLogged]=0; return 1; }
Code:
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[]) { if(dialogid==1)//registergui 1.Teil { if(response==1){Kick(playerid);} else { format(RegInfo[playerid][Passwort],255,"%s",inputtext); //gewдhltes Passwort zwischenspeichern ShowPlayerDialog(playerid,2,1,"Loginsystem","Um die Registration abzuschlieЯen gebe bitte noch deine Email an!","Abbrechen","Registrieren!"); } } if(dialogid==2)//registergui 2. Teil { if(response==1){Kick(playerid);} else { format(RegInfo[playerid][EMail],255,"%s",inputtext);//zwischenspeichern der eingegeben email GetPlayerIp(playerid,RegInfo[playerid][IP],255);//zwischenspeichern ip new Year, Month, Day; getdate(Year, Month, Day); format(RegInfo[playerid][RegisterDatum],255,"%02d.%02d.%d", Day, Month, Year);//zwischenspeichern registrierungsdatum Register(playerid);//registerfunktion ausfьhren } } if(dialogid==3)//logingui { if(response==1){Kick(playerid);} else { new playername[256]; GetPlayerName(playerid,playername,sizeof(playername)); new string[256]; format(string,sizeof(string),"Nickname='%s'",playername); new data[255]; mysqlget("players",string,"Passwort",data);//abfrage passwort if(!strcmp(data,inputtext,false))//auswertung ob pw's ьbereinsteimmen oder nicht { Login(playerid,playername); } else { ShowPlayerDialog(playerid,3,1,"Loginsystem","Dieses Passwort ist falsch. \n Bitte gib das richtige ein!","Abbrechen","Login!"); } } } return 1; }
Vielen Dank fьrs Lesen, bei Anregungen Tipps Fragen oder sollte ich Fehler gemacht haben einfach Posten ich lese es gern und antworte auch gerne (bei bedarf kann ich auch eine Scriptdatei hochladen in der die Funktionen gespeichert sind)