https://github.com/pBlueG/SA-MP-MySQL/releases/tag/R39-3
Habe es von da. Hatte extra die R39-gehlt da das Tutorial ja dafür ausgelegt ist.
Wenn ich z.b. R39-2 nehme kommen diese Fehlermeldungen nicht und das Plugin wird geladen.
Jedoch verhält sich das Script dann so als wäre nie etwas damit gemacht worden.
Sprich die ganzen Dialoge öffnen sich nicht. Es gibt aber auch keine Fehler im Script.
[jTuT] MySQL R41-4 (Installation, XAMPP, Verwendung, Bedienung & Registrations-System)
Wichtiger Hinweis: Bitte ändert nicht manuell die Schriftfarbe auf schwarz sondern belasst es bei der Standardeinstellung. Somit tragt ihr dazu bei dass euer Text auch bei Verwendung unseren dunklen Forenstils noch lesbar ist!
Tipp: Ihr wollt längere Codeausschnitte oder Logfiles bereitstellen? Benutzt unseren eigenen PasteBin-Dienst Link
-
-
Ich hab jetzt genau das selbe Problem
Installiere dir dieses All in One Paket:
http://www.chip.de/downloads/A…ne-Runtimes_37449838.html -
Das PLugin läd jetzt aber Ingame passiert immer noch nichts...
Die Verbindung zur DB wird aber hergestellt -
Das PLugin läd jetzt aber Ingame passiert immer noch nichts...
Kannst du bitte den Code posten, der nicht ausgeführt wird, und den MySQL Log, der erzeugt wird?
-
Es gibt momentan Problem mit dem Server da er nicht mehr hochfahren möchte...
Melde mich sobald es wieder geht.//Edit
Server funktioniert wieder und MySQL komischer weiße auchNaja Trotzdem sehr schönes Tutorial funktioniert alles super
-
Gutes Anfängertutorial.
Allerdings fehlt ein gute Erklärung zur SQL-Syntax, was bei Anfängern, die andere Systeme als Login/Register erstellen wollen, oft zu Problemen führt.
Desweiteren hätte man noch zu eine Seite verweisen können, die sämtliche SQL Befehle enthält.
Dennoch, gute Arbeit. -
Allerdings fehlt ein gute Erklärung zur SQL-Syntax, was bei Anfängern, die andere Systeme als Login/Register erstellen wollen, oft zu Problemen führt.
Desweiteren hätte man noch zu eine Seite verweisen können, die sämtliche SQL Befehle enthält.Danke für den Hinweis, ich werde das in den nächsten Tagen hinzufügen.
-
Wie soll ich die Funktion jetzt schreiben?
if(cache_get_row_count() == 0)
Weil es gibt ja eine neue Funktion und bei mir kommt immer dieser Warning:
Warning 202: number of arguments does not match definition...
-
Wie soll ich die Funktion jetzt schreiben?
if(cache_get_row_count() == 0)
Weil es gibt ja eine neue Funktion und bei mir kommt immer dieser Warning:
Warning 202: number of arguments does not match definition...
Verwende mal das MySQL R40 Include / Plugin.
-
Wie soll ich die Funktion jetzt schreiben?
Das musst du mit dem neuen R40 jetzt so schreiben:
new rows;cache_get_row_count(rows);if(rows == 0)Ich werde im Laufe der nächsten Tage das Tutorial an die R40 Version anpassen.
==================================================================================
Allerdings fehlt ein gute Erklärung zur SQL-Syntax, was bei Anfängern, die andere Systeme als Login/Register erstellen wollen, oft zu Problemen führt.
Desweiteren hätte man noch zu eine Seite verweisen können, die sämtliche SQL Befehle enthält.
Ich habe beides in Form von Verweisen zu Kapitel 3 hinzugefügt. Nochmals Danke für den Hinweis.==================================================================================
==================================================================================
==================================================================================Hallo Zusammen,
ich habe soeben das Tutorial auf die neuste Version (R40) angepasst.
Durch die neue Version des MySQL Plugins haben sich einige Änderungen ergeben.
Für das Upgrade von R39-3 (vorheriger Stand des Tutorials) auf R40 (aktueller Stand des Tutorials) sind folgende Anpassungen am Beispielcode notwendig (im Tutorial und Download bereits angepasst):Der MySQL handle Variable wurde der Tag "MySQL" hinzugefügt. Dies muss bei der Deklaration angepasst werden.
new handle; //Die Connection-Handle, über die wir später auf die Tabellen der Datenbank zugreifen
zu:new MySQL:handle; //Die Connection-Handle, über die wir später auf die Tabellen der Datenbank zugreifenDurch diverse Anpassungen wurde auch cache_get_row_count verändert. Diese gibt nun nicht mehr den Wert direkt zurück, sondern über einen Parameter. Der Code muss entsprechend angepasst werden.
if(cache_get_row_count() == 0)
zu:new rows;
cache_get_row_count(rows);
if(rows == 0)
Die gleiche Änderung hat auch cache_get_field_content_int erfahren und muss daher ebenfalls wie folgt angepasst werden.
PlayerInfo[playerid][p_id] = cache_get_field_content_int(0, "id", handle);
zu:cache_get_value_name_int(0, "id", PlayerInfo[playerid][p_id]);
Bitte beachtet, dass dies natürlich bei allen cache_get_field_content_int's gemacht werden muss, nicht nur bei der "id".
Zudem haben sich auch die anderen Cache-Funktionen in gleicher Weise geändert. Solltet Ihr also diese Funktionen ebenfalls verwenden (siehe Changelog), dann müsst Ihr diese auch anpassen.In mysql_log wurde der Parameter entfernt und muss daher aus dem Code genommen werden.
//mysql_log(LOG_ALL); //<- Kommentar vor mysql_log entfernen um den MySQL Debug-Modus zu aktivieren
zu://mysql_log(); //<- Kommentar vor mysql_log entfernen um den MySQL Debug-Modus zu aktivierenJetzt die wichtigste Änderung! Hier wurde die Datenbank und das Passwort vertauscht. Auf diese Änderung macht Euch auch der Compiler nicht aufmerksam, vergesst dies also bitte nicht, sonst kann der Server keine Verbindung zur Datenbank herstellen.
handle = mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_DBSE, MYSQL_PASS);
zu:handle = mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DBSE);Außerdem muss in dem Informationsprint der handle noch der Tag entfernt werden, um einen Tag-Mismatch zu verhindern.
printf("[MySQL] Die Verbindung zur Datenbank wurde erfolgreich hergestellt! Handle: %d", handle);
zu:printf("[MySQL] Die Verbindung zur Datenbank wurde erfolgreich hergestellt! Handle: %d", _:handle);Außerdem ist es nun zwingend notwendig, die aktuelle libmysql.dll sowie die neue log-core.dll Datei im Hauptordner des Servers zu haben. Ansonsten lädt der Code nicht.
Alle Änderungen findet Ihr hier:
https://github.com/pBlueG/SA-MP-MySQL/releases/tag/R40Ich zähle daher hier nicht nochmal alle Änderungen auf. Falls Ihr Fragen zu den Änderungen habt könnt Ihr gerne wie gewohnt hier nachfragen, ebenso falls es bei der Konvertierung von R39-3 zu R40 Probleme gibt.
Bitte beachtet, dass der in diesem Post angehängte Ordner "Beispiele_R39-3" für das untenstehende alte Tutorial ist. Die neue Version findet sich im Startpost!Viele Grüße,
JeffryPS:
Das Tutorial für MySQL R39-3 habe ich hier nochmal angehängt, falls es noch jemand benötigt. Ich empfehle aber die Nutzung der Version R40.[jTuT] MySQL R39-3
Installation, XAMPP, Verwendung, Bedienung & Registrations-SystemHallo zusammen,
dieses Tutorial beschreibt die Installation sowie die Anwendung des aktuellsten MySQL Plugins für SA-MP (R39-3 / Stand 08/2015). Es baut in den Grundformen auf maddin's MySQL Tutorial auf, welches allerdings nicht mehr aktuell ist. Gerne kann dieser Thread auch für Fragen bezüglich dem Plugin oder den Codes verwendet werden.Inhaltsverzeichnis
- Voraussetzungen
- Kurzer Überblick
- Nützliches Vorwissen
- Aufsetzen der Datenbank in Windows mit XAMPP und phpMyAdmin
- SA-MP Server und MySQL Datenbank verbinden
- Register & Login System
- Hinweise und Fehlerbehebung
- Fußnoten
- Für die Faulen unter uns
1.) Voraussetzungen
- Einzigste Voraussetzung für dieses Tutorial ist ein vorhandener Windows PC mit dem aktuellsten SA-MP Server, beziehungsweise ein SA-MP Server mit MySQL Anbindung bei einem Hoster.
2.) Kurzer Überblick
- Dieses Tutorial beschreibt und erklärt die Installation, Aufsetzung und Anwendung des neusten MySQL Plugins. Außerdem wird der Aufbau der Tabelle in der Datenbank, sowie das Laden und das Speichern von Spielerstatistiken anhand von Beispielen erklärt. Am Ende haben wir ein komplett funktionsfähiges Registrations-System welches auf dem MySQL Plugin Version R39-3 basiert. Falls Du das Plugin noch nicht hast, lade es Dir bitte jetzt herunter und füge es entsprechend in Deinen Server ein.
Es ist zu beachten, dass die Codes ganz bewusst mit englischen Variablennamen versehen worden sind, da dies der Einheitlichkeit und Allgemeinverständlichkeit eines Codes dient. Kommentare habe ich auf deutsch gehalten.
3.) Nützliches Vorwissen
-
Was ist MySQL überhaupt?
MySQL steht als Abkürzung für My Structured Query Language, was soviel wie "strukturierte Abfragesprache" heißt. Das ganze wird strukturiert genannt, weil es, anders als bei Dateisystemen, sehr übersichtlich aufgebaut ist, und alle Daten an einem Punkt sind, nämlich in der Datenbank. Man hat nicht tausende Dateien, die man zu verwalten hat, sondern genau eine Datenbank, in der bestmöglichst alles steht. Diese Datenbanken sind unbegrenzt* groß, es können als so viele Datensätze und Daten wie man will in der Datenbank gespeichert werden. -
Was sind die Vorteile davon? Gibt es auch Nachteile?
Der wohl größte Vorteil liegt in der Geschwindigkeit, in der sehr viele Daten auf einmal ausgewertet werden können. Beim abfragen von einzelnen Daten ist MySQL meist langsamer als Dateisysteme, sobald man aber viele Daten zu verwalten hat, dann lohnt sich MySQL auf jeden Fall.
Außerdem bietet sich mit einer MySQL Datenbank die Möglichkeit, die Daten mit einer Website zu verknüpfen, das geht mit Dateien keineswegs so leicht.
Natürlich gibt es auch Nachteile, dort ist besonders der hervorzuheben, dass es oft schwieriger für Anfänger ist, MySQL zu verstehen. Aber genau um diesem Nachteil entgegen zu wirken gibt es dieses Tutorial, damit wir gemeinsam auf die wichtigsten Dinge eingehen können, damit es anschließend ein Leichtes für Dich ist, MySQL zu verstehen. -
Vergleich zwischen einer Datei (dini) und einer MySQL Tabelle.
In einer Datei sieht es bekanntermaßen oft so aus:
->Datei: /users/Jeffry.sav
->Datei: /users/Horst.sav
Eine MySQL Tabelle sieht dann bei entsprechenden Daten so aus:
Wie Du siehst, besteht eine MySQL Tabelle - wer hätte es gedacht - aus einer Tabelle, in der die Daten stehen. Im Beispiel der Tabelle sind dort alle Benutzer untereinander aufgeführt, es muss nicht für jeden Benutzer eine eigene Datei erstellt werden. Das hat vor allem bei Änderungen oder Server-Umzügen extreme Vorteile und erleichtert die Arbeit ungemein.
-
Externer Zugriff auf MySQL Datenbanken
Ein externer Zugriff auf einer MySQL Datenbank (SA-MP Server auf Maschine A, MySQL Datenbank auf Maschine B) ist möglich, allerdings ist ein solches Vorgehen nicht zu empfehlen. Warum? Ganz einfach: Die Daten können während der Übertragung abgefangen werden. Natürlich sind das meist keine sensiblen Daten, aber dennoch sollte man sich darüber im Klaren sein. Außerdem, und das ist der ausschlaggebendere Punkt, dauert die Übertragung natürlich seine Zeit. Muss der MySQL Server aus den USA die Daten ins Rechenzentrum nach Frankfurt schicken, dann dauert das einen kurzen Moment (Millisekunden / Sekunden). Kommt es nun mal vor, dass der MySQL Server nicht erreichbar ist, dann hat man ein echtes Problem, denn das bedeutet, dass keine Daten mehr gelesen beziehungsweise geschrieben werden können, was oft zu Fehlern oder gar zum Server-Absturz führt.
Daher ist es immer empfohlen, die Datenbank auf dem gleichen Server zu betreiben, auf dem auch der SA-MP Server liegt. Dies ist bei den großen Hostern ohnehin automatisch so geregelt.
4.) Aufsetzen der Datenbank in Windows mit XAMPP und phpMyAdmin
-
Installation von XAMPP
Die Installation von XAMPP ist nur notwendig, wenn Du die MySQL Datenbank auf Deinem Windows-Rechner aufsetzen willst. Liegt der SA-MP Server bei einem Hoster, dann ist dieser Schritt nicht notwendig, da die entsprechenden Mittel in den meisten Fällen bereits gegeben sind. Sollte dies nicht der Fall sein, setze Dich einfach mit Deinem Host in Verbindung, der Support wird Dir bestimmt helfen.
Gehen wir nun also davon aus, dass Du die MySQL Datenbank auf Deinem Rechner installieren willst. Lade hierzu XAMPP herunter. Den Download findet man auf der offiziellen Seite: Download
Nach erfolgreichem Download findest Du in Deinem Download-Verzeichnis ein Installer-Paket um die Installation von XAMPP zu starten. Starte diesen Installer mit einem Doppelklick.In einigen Fällen werden Warnmeldungen wie folgende angezeigt. Diese können einfach übersprungen werden.
Als erstes erscheint das Hauptfenster des Installers. Hier genügt es mit einem Klick auf "Next" fortzufahren.
Im darauf folgenden Schritt kannst Du auswählen, welche Komponenten mit XAMPP auf Deinem Rechner installiert werden. Hier empfiehlt es sich, alle Komponenten auszuwählen und mit "Next" zu bestätigen.
Jetzt musst Du den Pfad angeben, auf dem XAMPP installiert werden soll. Grundsätzlich empfiehlt es sich hier, den Standard-Pfad beizubehalten und mit "Next" zum nächsten Schritt zu springen.
Natürlich will Dich auch dieser Installer freundlicherweise auf andere Programme aufmerksam machen. Darauf verzichtest Du empfehlenswerterweise, indem Du den Haken in der Checbox entfernst und dies mit "Next" bestätigst.
Anschließend startet der Installer den Installationsvorgang. Hier heißt es dann: Warten und Tee trinken.
Nach der Installation siehst Du dann den Control Panel von XAMPP. Wir benötigen hier nur die ersten beiden Teile, den Apache und MySQL.
Klicke nun sowohl bei Apache als auch bei MySQL auf den "Start"-Button. Wenn beide Services korrekt gestartet worden sind, dann siehst Du folgendes:
Sollte hier ein Fehler angezeigt werden, dann ist dies oftmals durch Skype verschuldet, da Skype den gleichen Port wie Apache nutzt.
Klappe, falls Du Probleme mit dem Port hast, folgenden Spoiler auf:
-
XAMPP Port ändern
Um den Port von Apache zu ändern musst Du einige Änderungen in den Einstellungen vornehmen. Klicke dazu bei Apache auf "Config" und wähle die httpd.conf Datei aus.
Suche dort nach:
und ersetze es durch:
Anschließend suche nach:
und ersetze es durch:
Dann speichere und schließe die Datei.
Öffne nun über den "Config"-Button die httpd-ssl.conf Datei.
Suche dort nach:und ersetze es durch:
Anschließend suche nach:
und ersetze es durch:
Dann speichere und schließe die Datei.
Starte nun den Apache wieder. Jetzt siehst Du die neuen Ports 4433 und 8080.
Öffne nun die Config von XAMPP.
Und wähle dort die "Service and Port Settings" aus.Ändere in dem erscheinenden Fenster nun den Main Port von Apache von 80 zu 8080 und den SSL Port von 443 zu 4433. Anschließend klicke auf "Save", ebenso im Config Panel.
Nun kannst Du den MySQL Server auch wieder starten.
Die Änderungen wurden durchgeführt und es sollten keine Port-Probleme mehr auftreten.
Natürlich kannst Du die Port-Nummern 8080 und 4433 auch ändern, wenn Dir diese nicht gefallen, oder diese bereits belegt sind.
-
Anlegen einer Datenbank in phpMyAdmin
Um nun eine Datenbank anzulegen, in der die Daten gespeichert werden, müssen wir mit phpMyAdmin arbeiten. Klicke hierzu auf den "Admin"-Button von MySQL.Es öffnet sich nun in Deinem Standard-Browser die phpMyAdmin Startseite.
Um jetzt eine neue Datenbank anzulegen, klicke bitte auf "Neu" am linken Randmenü.
Gebe dort nun den gewünschten Datenbankname ein. Ich nehme für das Beispiel "samp_db". Wenn Du problemlos durch das Tutorial gehen möchtest ist es zu empfehlen, dass Du auch diesen Namen verwendest. Danach drücke bitte auf "Anlegen".
Die Datenbank wurde nun angelegt. Um sie zu öffnen musst Du die Datenbank am linken Randmenü auswählen.
Da in der neu erstellten Datenbank noch keine Tabelle vorhanden ist gibt uns phpMyAdmin vor eine neue Tabelle anzulegen. Wir legen uns eine Tabelle wie im obigen Beispiel an. Diese Tabelle nennen wir "users" und sie soll 7 Spalten haben.
Anschließend siehst Du die Maske um die Spalten der Tabelle zu pflegen.
Gebe bitte diese Daten ein:Codeid - INT (10) - Keine - Index: PRIMARY - A_I angehakt name - VARCHAR (64) - NULL password - VARCHAR (128) - NULL level - INT (3) - Wie definiert: 0 money - INT (10) - Wie definiert: 0 kills - INT (10) - Wie definiert: 0 deaths - INT (10) - Wie definiert: 0
Das sieht dann so aus:
Klicke dann auf "Speichern" um die Tabelle anzulegen.Die fertig erstellte Tabelle "users" sieht dann in phpMyAdmin so aus:
Nun ist die Tabelle bereit Daten aufzunehmen. Wie das geht werden wir im nächsten Kapitel behandeln.
-
Optionaler Schritt: phpMyAdmin Passwort für root-Benutzer ändern
Dieser Schritt ist optional und muss nicht zwangsläufig durchgeführt werden. Da es aus Sicherheitsgründen von phpMyAdmin vorgeschlagen wird, gehe ich auch auf diesen Punkt ein und erkläre kurz, wie man das root-Passwort ändert, da der root-Benutzer standardmäßig kein Passwort besitzt. Wenn Du diesen Schritt nicht durchführen willst, dann überspringe ihn einfach.Standardmäßig ist der root-Benutzer in phpMyAdmin ohne ein Passwort angelegt. Du wirst von phpMyAdmin auch darauf hingewiesen.
Um das Passwort zu ändern, wähle oben im Menü den Reiter "Benutzer" aus.
Dort siehst Du nun mehrere Benutzer. Du musst das Passwort von allen drei root-Benutzern ändern. Grundsätzlich sind das die gleichen Benutzer, nur mit einer anderen Schreibweise für den localhost. Das Passwort kannst Du über einen Klick auf "Rechte ändern" ändern.
Achte bitte darauf, den root-Benutzer als letztes zu ändern, bei dem Du diese Meldung siehst:
Klicke nun auf "Passwort ändern".
Dort kannst Du nun das neue Passwort eingeben. Es ist zu empfehlen, dass Du allen drei root-Benutzern das gleiche Passwort gibst, damit das nicht zu Problemen führt.
Wenn Du das neue Passwort eingegeben hast und wiederholt hast, dann bestätige die Eingabe mit "Ok" rechts unten am Bildrand.Sobald Du die Änderung für den root-Benutzer gemacht hast, mit dem Du gerade angemeldet bist kann sich phpMyAdmin nicht mehr anmelden, es kommt folgende Meldung:
Schließe nun Deinen Browser beziehungsweise den Tab, in dem phpMyAdmin offen ist. Klicke im XAMPP Control Panel unter Apache auf Config und wähle dort "<Browse> [phpMyAdmin]".
Öffne in dem Verzeichnis nun die config.inc.php Datei mit einem Texteditor.
Suche dort die Zeileund ersetze diese durch
wobei Du natürlich "meinPW" mit dem von Dir vergebenen Passwort ersetzt.
Anschließend speichere und schließe die Datei. Jetzt kannst Du phpMyAdmin wieder über einen Klick auf "Admin" bei MySQL starten. Du wirst nun wieder automatisch korrekt angemeldet.
5.) SA-MP Server und MySQL Datenbank verbinden
-
Benötigte Dateien
Jetzt sind wir an dem Punkt angekommen, an dem es interessant wird. Wir bauen die Verbindung zwischen dem SA-MP Server und der MySQL Datenbank auf. Hierzu benötigen wir einige Dateien. Diese kannst Du hier herunterladen: Download
In diesem Ordner findest Du nun einige Dateien. Für die Verwendung auf einem Windows-System werden nur zwei Dateien benötigt, das ist zum einen die a_mysql.inc und zum anderen die mysql.dll. Füge nun bitte die a_mysql.inc Datei in das Verzeichnis Deines SA-MP Servers unter /pawno/includes/ ein. Die mysql.dll legst Du bitte im /plugins/ Ordner ab. Sollte sich dieser Ordner noch nicht in dem Hauptordner Deines SA-MP Servers befinden, erstelle diesen Ordner zuerst und füge die mysql.dll Datei dann dort ein.
Als nächstes musst Du die server.cfg Datei öffnen, die sich im Hauptordner Deines SA-MP Servers befindet. Trage dort in der Zeile "plugins" das MySQL Plugin ein, indem Du mysql zu der Zeile hinzufügst. Sollte in der server.cfg Datei noch keine plugins-Zeile vorhanden sein, füge am Ende der Datei "plugins mysql" in einer neuen Zeile ein.
-
Verbindungsaufbau
Um nun die Verbindung herzustellen benötigen wir einen PAWN Code. Öffne hierzu bitte die pawno.exe, die sich im Ordner /pawno/ befindet. Wähle dann entweder einen existierenden Code aus oder erstelle eine neue Datei. Es spielt herbei keine Rolle, ob der MySQL Code in einem Filterscript oder einem Gamemode aufgebaut wird, beides funktioniert ohne Probleme.
Als erstes musst Du zu den Includes die MySQL-Include hinzufügen:
Jetzt benötigen wir die Login Daten für die Datenbank. Diese hast Du ja zuvor bereits mit XAMPP und phpMyAdmin aufgesetzt. Die Login Daten sind hierfür standardmäßig der root Benutzer. Das kannst Du auch über phpMyAdmin ändern, indem Du einen neuen Benutzer anlegst, allerdings kommt es häufig zu Problemen mit den Berechtigungen, daher ist es zu empfehlen, dem root Benutzer später nur ein Passwort zu geben, das reicht, vor allem für Tests, völlig aus.
Solltest Du die vorherigen Schritte übersprungen haben, da Du Deinen Server bei einem Hoste r liegen hast, dann musst Du die Login Daten angeben, die in Deinem Control Panel des Servers angezeigt werden. Frage gegebenenfalls bei dem Support Deines Hosters nach, wenn Du nicht weißt, welche Daten das sind, beziehungsweise wo Du diese Daten findest.
Wir geben nun also die Daten in den Code ein, dazu legen wir Konstanten an:C#define MYSQL_HOST "127.0.0.1" //IP Adresse des MySQL Servers #define MYSQL_USER "root" //Benutzername der angemeldet wird #define MYSQL_PASS "" //Passwort des Benutzers #define MYSQL_DBSE "samp_db" //Name der Datenbank
Solltest Du andere Daten haben, nutze bitte Deine Daten. Hier nochmals der Hinweis, wenn Du zuvor das root-Passwort geändert hast, dieses Passwort zu verwenden.
Außerdem benötigen wir noch eine Variable, die uns die Verbindungs-ID speichert. Füge direkt unter den Konstanten folgendes ein:Um jetzt die Verbindung mit diesen Daten herzustellen erstellen wir uns eine kleine Funktion, die das für uns macht, vor allem auch deshalb, damit OnGameModeInit/OnFilterScriptInit nicht zu unübersichtlich wird, da dort oft ziemlich viel drin steht. Dazu musst Du bei OnGameModeInit/OnFilterScriptInit folgenden Funktionsaufruf einfügen:
Es besteht die Möglichkeit, zwischen den Klammern eine Zahl einzufügen, die steht dann für die Anzahl der Verbindungsversuche (TTL = Time To Lift). Standardmäßig ist das 3, wenn Du mehr oder weniger willst, trage die entsprechende Zahl dort ein, ansonsten lasse es leer.
Ganz unten in Deinem Gamemode/Filterscript fügst Du dann diese Funktion ein:
C
Alles anzeigenstock MySQL_SetupConnection(ttl = 3) { print("[MySQL] Verbindungsaufbau..."); //mysql_log(LOG_ALL); //<- Kommentar vor mysql_log entfernen um den MySQL Debug-Modus zu aktivieren handle = mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_DBSE, MYSQL_PASS); //Prüfen und gegebenenfalls wiederholen if(mysql_errno(handle) != 0) { //Fehler im Verbindungsaufbau, prüfe ob ein weiterer Versuch gestartet werden soll if(ttl > 1) { //Versuche erneut eine Verbindung aufzubauen print("[MySQL] Es konnte keine Verbindung zur Datenbank hergestellt werden."); printf("[MySQL] Starte neuen Verbindungsversuch (TTL: %d).", ttl-1); return MySQL_SetupConnection(ttl-1); } else { //Abbrechen und Server schließen print("[MySQL] Es konnte keine Verbindung zur Datenbank hergestellt werden."); print("[MySQL] Bitte prüfen Sie die Verbindungsdaten."); print("[MySQL] Der Server wird heruntergefahren."); return SendRconCommand("exit"); } } printf("[MySQL] Die Verbindung zur Datenbank wurde erfolgreich hergestellt! Handle: %d", handle); return 1; }
Mit diesem Code haben wir uns nun mehrfach abgesichert, damit auch wirklich eine Datenbankverbindung aufgebaut wird.
Um die Verbindung zu Beenden, wenn der Gamemode/Filterscript beendet wird, füge bei OnGameModeExit/OnFilterScriptExit diese Zeile ein:
Kompiliere jetzt Deinen Code und starte zum Test Deinen Server. Im besten Fall siehst Du in der Console folgende Meldung:
Ist dies der Fall, dann kannst Du mit dem nächsten Schritt fortfahren. Sollten Probleme auftauchen, schalte den Debug-Modus an und prüfe Deine Daten. Falls Du Hilfe benötigst kannst Du gerne in diesem Thread nach Hilfe fragen, oder einen neuen Thread in der Scripting Base erstellen.
6.) Register & Login System
-
Coding
Da wir jetzt die Verbindung aufgebaut haben, können wir mit dem eigentlich wichtigen Teil beginnen, nämlich dem Speichersystem für die Benutzer Deines Servers, schließlich sollen deren Daten ja gespeichert werden. Hierzu benötigen wir diverse Code-Teile, die ich im folgenden Abschnitt erkläre. Wir gehen chronologisch vom Betreten des Servers bis zum Verlassen des Servers vor, und beginnen bei der Deklaration der Variablen.Um die Daten zur Laufzeit temporär zu speichern, ohne jedes mal auf die Datenbank zugreifen zu müssen legen wir ein Array mit den Spielerdaten an. Für eine komfortablere Bedienung nutzen wir ein Enum. Füge hierzu unter den Includes - also ganz oben in Deinem Gamemode/Filterscript - diese Deklaration ein:
C
Alles anzeigenenum pDataEnum { p_id, bool:pLoggedIn, pName[MAX_PLAYER_NAME], pLevel, pMoney, pKills, pDeaths } new PlayerInfo[MAX_PLAYERS][pDataEnum];
Anschließend gehst Du zu OnPlayerConnect. Wenn der Spieler den Server betritt, dann soll er initialisiert werden, sprich die Variablen werden sicherheitshalter zurückgesetzt. Dazu benötigst Du diesen Code:
C
Alles anzeigenpublic OnPlayerConnect(playerid) { PlayerInfo[playerid][p_id] = 0; PlayerInfo[playerid][pLoggedIn] = false; PlayerInfo[playerid][pLevel] = 0; PlayerInfo[playerid][pMoney] = 0; PlayerInfo[playerid][pKills] = 0; PlayerInfo[playerid][pDeaths] = 0; GetPlayerName(playerid, PlayerInfo[playerid][pName], MAX_PLAYER_NAME); return 1; }
Als nächstes kommt der Spieler in die Class-Selection. Hier wird OnPlayerRequestClass aufgerufen. Dort fragen wir in der Datenbank ab, ob der Spieler bereits registriert ist. Dies geht so:
C
Alles anzeigenpublic OnPlayerRequestClass(playerid) { //Wenn der Spieler die Class-Selection betritt prüfe, ob er bereits eingeloggt ist if(!PlayerInfo[playerid][pLoggedIn]) { //Wenn nicht, dann prüfe ob der Spieler ein Konto hat //Dazu wird ein Query gesendet und ein neues Callback aufgerufen //%e steht für einen geprüften String (sollte anstatt %s in Queries verwendet werden) new query[128]; mysql_format(handle, query, sizeof(query), "SELECT id FROM users WHERE name = '%e'", PlayerInfo[playerid][pName]); //Das Query wird abgesendet und die playerid an OnUserCheck übergeben mysql_pquery(handle, query, "OnUserCheck", "d", playerid); } return 1; }
Außerdem benötigen wir nun das Callback OnUserCheck, welches Du am besten ganz unten in Deinem Gamemode/Filterscript einfügst.C
Alles anzeigenforward OnUserCheck(playerid); public OnUserCheck(playerid) { //Query wurde ausgeführt und das Ergebnis im Cache gespeichert if(cache_get_row_count() == 0) { //Der Spieler konnte nicht gefunden werden, er muss sich registrieren ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_PASSWORD, "Registration", "Bitte registriere Dich:", "Ok", "Abbrechen"); } else { //Es existiert ein Ergebnis, das heißt der Spieler ist registriert und muss sich einloggen ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "Anmeldung", "Bitte logge Dich ein:", "Ok", "Abbrechen"); } return 1; }
Damit der Code ohne Fehler kompiliert, musst Du unter den Includes die beiden Dialoge definieren:C//Dialog IDs (gegebenenfalls ändern, falls bereits belegt) #define DIALOG_REGISTER 1403 #define DIALOG_LOGIN 2401
Da dem Spieler nun Dialoge angezeigt werden benötigst Du das Callback OnDialogResponse. Dort trägst Du ein, was passiert, wenn der Spieler sich registrieren oder einloggen will, je nach dem welchen Dialog der Spieler angezeigt bekommen hat.
C
Alles anzeigenpublic OnDialogResponse(playerid, dialogid, response, listitem, inputtext[]) { if(dialogid == DIALOG_REGISTER) { //Spieler hat Abbrechen gewählt if(!response) return Kick(playerid); //Wenn der Spieler kein, oder ein zu kurzes, Passwort eingegeben hat if(strlen(inputtext) < 3) return ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_PASSWORD, "Registration", "Bitte registriere Dich:\n{FF0000}Mindestens 3 Zeichen!", "Ok", "Abbrechen"); //Wenn alles passt wird der Spieler in der Datenbank angelegt //Als Verschlüsselung für das Passwort wird MD5 verwendet new query[256]; mysql_format(handle, query, sizeof(query), "INSERT INTO users (name, password) VALUES ('%e', MD5('%e'))", PlayerInfo[playerid][pName], inputtext); //Das Query wird abgesendet und die playerid an OnUserRegister übergeben mysql_pquery(handle, query, "OnUserRegister", "d", playerid); return 1; } if(dialogid == DIALOG_LOGIN) { //Spieler hat Abbrechen gewählt if(!response) return Kick(playerid); //Wenn der Spieler kein, oder ein zu kurzes, Passwort eingegeben hat if(strlen(inputtext) < 3) return ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "Anmeldung", "Bitte logge Dich ein:\n{FF0000}Mindestens 3 Zeichen!", "Ok", "Abbrechen"); //Wenn alles passt wird die Datenbank ausgelesen new query[256]; mysql_format(handle, query, sizeof(query), "SELECT * FROM users WHERE name = '%e' AND password = MD5('%e')", PlayerInfo[playerid][pName], inputtext); //Das Query wird abgesendet und die playerid an OnUserLogin übergeben mysql_pquery(handle, query, "OnUserLogin", "d", playerid); return 1; } return 0; }
Auch hier benötigst Du die beiden neuen Callbacks, die Du wieder ganz unten in Deinem Gamemode/Filterscript einfügst:
Cforward OnUserRegister(playerid); public OnUserRegister(playerid) { //Der Spieler wurde in die Datenbank eingetragen, es wird die id ausgelesen PlayerInfo[playerid][p_id] = cache_insert_id(); SendClientMessage(playerid, 0x00FF00FF, "[Konto] Registration erfolgreich."); return 1; }
C
Alles anzeigenforward OnUserLogin(playerid); public OnUserLogin(playerid) { //Query wurde ausgeführt und das Ergebnis im Cache gespeichert if(cache_get_row_count() == 0) { //Der Spieler hat ein falsches Passwort eingegeben ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "Anmeldung", "Bitte logge Dich ein:\n{FF0000}Falsches Passwort!", "Ok", "Abbrechen"); } else { //Es existiert ein Ergebnis, das heißt der Spieler hat das richtige Passwort eingegeben //Wir lesen nun die erste Zeile des Caches aus (ID 0) PlayerInfo[playerid][p_id] = cache_get_field_content_int(0, "id", handle); PlayerInfo[playerid][pLevel] = cache_get_field_content_int(0, "level", handle); PlayerInfo[playerid][pMoney] = cache_get_field_content_int(0, "money", handle); PlayerInfo[playerid][pKills] = cache_get_field_content_int(0, "kills", handle); PlayerInfo[playerid][pDeaths] = cache_get_field_content_int(0, "deaths", handle); PlayerInfo[playerid][pLoggedIn] = true; SendClientMessage(playerid, 0x00FF00FF, "[Konto] Eingeloggt."); GivePlayerMoney(playerid, PlayerInfo[playerid][pMoney]); } return 1; }
So, jetzt hast Du es fast geschafft. Es fehlt nur noch die Speicherung der Spielerdaten, wenn der Spieler den Server wieder verlässt.
Cpublic OnPlayerDisconnect(playerid, reason) { //Speichere den Spieler wenn er der Server verlässt SaveUserStats(playerid); return 1; }
Für die Speicherung nutzen wir dann diese Funktion:
C
Alles anzeigenstock SaveUserStats(playerid) { //Wenn der Spieler nicht eingeloggt ist, dann speichere seine Statistiken nicht if(!PlayerInfo[playerid][pLoggedIn]) return 1; //Ansonsten speichere sie new query[256]; mysql_format(handle, query, sizeof(query), "UPDATE users SET level = '%d', money = '%d', kills = '%d', deaths = '%d' WHERE id = '%d'", PlayerInfo[playerid][pLevel], PlayerInfo[playerid][pMoney], PlayerInfo[playerid][pKills], PlayerInfo[playerid][pDeaths], PlayerInfo[playerid][p_id]); //Das Query wird abgesendet mysql_pquery(handle, query); return 1; }
Damit wären wir so gut wie durch. Um die Funktionen auch testen zu können schreiben wir noch etwas bei OnPlayerDeath rein:
C
Alles anzeigenpublic OnPlayerDeath(playerid, killerid, reason) { //Beispielcode if(killerid != INVALID_PLAYER_ID) { PlayerInfo[killerid][pKills]++; GivePlayerMoney(killerid, 10); PlayerInfo[killerid][pMoney] += 10; if(PlayerInfo[killerid][pKills] > 3) { PlayerInfo[killerid][pLevel] = 1; } } PlayerInfo[playerid][pDeaths]++; return 1; }
Damit sind wir durch. Kompiliere Deinen Code und starte den Server neu.
Der Spieler kann sich nun registrieren, einloggen und seine Statistiken werden beim Verlassen des Servers gespeichert. Die Statistiken kannst Du gegebenenfalls auch in einem Timer oder in einem Befehl speichern lassen, das bleibt Dir überlassen.Wenn der Spieler nun den Server betritt, dann wird ihm der Register-/Login-Dialog angezeigt.
In der Datenbank sieht ein neuer Spieler nach der Registration so aus:Und nachdem er ein paar Dinge gemacht hat und den Server verlässt, sieht es so aus:
Aktualisiere (F5), falls nötig, die Ansicht, damit die Daten korrekt angezeigt werden.Dieses Register-/Login-System kannst Du nun nach Belieben ausbauen, da es ja noch recht spartanisch ist. Aber Du weißt jetzt wie es geht und kannst Dich ohne Probleme durch die Materie arbeiten.
7.) Hinweise und Fehlerbehebung
-
Der Debug Modus
Mit dem MySQL Plugin kommt ein sehr nützlicher Debug Modus, mit dem Du alles was das Plugin macht überprüfen kannst, denn jeder Schritt wird in einem Log ausgegeben. Sollte es also einmal vorkommen, dass Du einen MySQL Code hast, der aber aus unbekannten Gründen nicht das macht, was er soll, dann kannst Du in dem MySQL Log nachschauen, was denn eigentlich passiert, oder ob möglicherweise Fehler ausgegeben werden.
Um den MySQL Debug Modus einzuschalten musst Du nichts weiter machen, als bei OnGameModeInit/OnFilterScriptInit folgenden Funktionsaufruf hinzuzufügen:
Dies bewirkt, dass alle Aktionen des Plugins geloggt werden. Dieser Log findet sich als mysql_log.txt im Hauptverzeichnis des SA-MP Servers wieder, dort wo auch die server_log.txt liegt. Du musst Dir aber im Klaren darüber sein, dass dieser Debug Modus nicht die ganze Zeit auf dem produktiven System laufen sollte, sondern nur dann, wenn er auch benötigt wird, da durch das ganze Logging die Performance des Plugins eingeschränkt wird.
Eine Liste zu allen Fehler-Ausgaben von MySQL findest Du hier. -
CentOS: Failed ( libz.so.1 & libmysqlclient.so.18 )Diff
Alles anzeigenFailed (libz.so.1: cannot open shared object file: No such file or directory) Lösung : yum install zlib.i686 ---------------------------------------------------- Die fehlenden 32 Bit Bibliotheken für CentOS libmysqlclient.18 bei folgendem Fehler : Failed (libmysqlclient.so.18: cannot open shared object file: No such file or directory) Download : http://www.xup.in/dl,36770503/Libmysqlclient_v18.rar/ Die files nach /usr/lib kopieren / einfügen !
8.) Fußnoten
- * unbegrenzt
MySQL Tabelle sind natürlich nur theoretisch unbegrenzt, alles andere wäre unrealistisch, allerdings ist es kaum möglich, dass Du die existierenden Limits erreichst. Jeder Eintrag in der Datenbank benötigt Speicher, das heißt je mehr Einträge Deine Datenbank hat, desto mehr Speicher wird benötigt. Somit sind die Grenzen vor allem durch das Betriebssystem beziehungsweise die Festplattengröße begrenzt. Genauere Informationen zu den Limits findest Du hier: http://dev.mysql.com/doc/refman/5.6/en/limits.html
9.) Für die Faulen unter uns
- Wie immer habe ich für die Faulen unter uns einen fertigen Filterscript. Im Download befindet sich zudem die Datenbank, falls jemand die importieren möchte.
Änderungen:
- 14.08.2015: Übersetzung korrigiert und Hinweis bei Debugging hinzugefügt, danke an maddin.
- 06.09.2015: Hinweis zu CentOS Problem hinzugefügt, danke an Scene-Sector.
- 08.11.2015: Code-Formatierung an WBB4 angepasst.
- 19.03.2016: Spoiler-Formatierung repariert.
Sollten während oder nach dem Tutorial Fragen oder Probleme auftauchen, dann kannst Du natürlich gerne in diesem Thread oder in der Scripting Base nachfragen.
Viel Spaß damit!Beste Grüße,
Jeffry -
-
cache_get_field_content
Entspricht jetzt
cache_get_value_name
http://wiki.sa-mp.com/wiki/MySQL/R40#cache_get_value_name -
Entspricht jetztcache_get_value_name
http://wiki.sa-mp.com/wiki/MySQL/R40#cache_get_value_name
also von:
zu?
-
zu
Korrekt.
EDIT:
Danke @Tommyx3 für den Hinweis mit der Handle, hatte vergessen, dass die dort komplett entfernt wurde. -
Das 'handle' muss noch weg
-
ich hab kleine Probleme beim umschreiben der MySQL Callbacks...
Mein Compiler spuckt folgende Fehlermeldung aus:
error 035: argument type mismatch (argument 2)In folgenden Zeilen:
Code
Alles anzeigenFunction LoadFactionCars() { if(!cache_num_rows())return 1; for(new i = 0; i < cache_num_rows(); i++) { cache_get_value_index_float(i, "Fv_aX", FactionCars[i][v_X]); // Hier ist angeblich ein fehler cache_get_value_index_float(i, "Fv_aY", FactionCars[i][v_Y]); // Hier ist angeblich ein fehler cache_get_value_index_float(i, "Fv_aZ", FactionCars[i][v_Z]); // Hier ist angeblich ein fehler cache_get_value_index_float(i, "Fv_aA", FactionCars[i][v_A]); // Hier ist angeblich ein fehler } return 1; }
das selbe wie in diesen Zeilen:
Code
Alles anzeigenFunction LoadBlitzerFromData() { new num_rows; cache_get_row_count(num_rows); new bid = 0; if(num_rows) { while(bid < num_rows) { cache_get_value_index_float(bid, "BlitzerX", Blitzer[bid][BlitzerX]); // Hier ist angeblich ein fehler cache_get_value_index_float(bid, "BlitzerY", Blitzer[bid][BlitzerY]); // Hier ist angeblich ein fehler cache_get_value_index_float(bid, "BlitzerZ", Blitzer[bid][BlitzerZ]); // Hier ist angeblich ein fehler cache_get_value_index_float(bid, "BlitzerA", Blitzer[bid][BlitzerA]); // Hier ist angeblich ein fehler cache_get_value_name_int(bid, "BlitzerGeschwindigkeit", Blitzer[bid][Geschwindigkeit]); // Hier ist angeblich ein fehler cache_get_value_name_int(bid, "BlitzerStrafe", Blitzer[bid][Strafe]); // Hier ist angeblich ein fehler cache_get_value_name_int(bid, "BlitzerRadius", Blitzer[bid][Radius]); // Hier ist angeblich ein fehler cache_get_value_name_int(bid, "BlitzerKasse", Blitzer[bid][Kasse]); // Hier ist angeblich ein fehler cache_get_value_name_int(bid, "BlitzerAnzahl", Blitzer[bid][BlitzerAnzahl]); // Hier ist angeblich ein fehler Blitzer[bid][Erstellt] = 1; GesammtBlitzer++; bid++; } }
Habe ich einen Syntax fehler ?
Vergleiche ständig mit dem Eintrag im SA:MP Wiki aber mir fällt jetzt nicht auf was ich da falsch gemacht haben könnte...Kann mir einer weiterhelfen?
-
Nutze anstatt
cache_get_value_index_float
Die Funktion
cache_get_value_name_float -
Wie kann ich den Account nach einem anderen Dialog als den Register Dialog an die Datenbank senden?
Grüße
-
Beitrag von Marschl ()
Dieser Beitrag wurde vom Autor gelöscht (). -
Du speicherst das Kennwort im Register Dialog in einer Spielervariable ab und liest es dann in dem anderen Dialog wieder aus, in dem dann das INSERT Query steht.
==============================
EDIT:
Das Tutorial wurde von der MySQL Plugin Version R40 auf die Version R41 aktualisiert.
Es sind keine Änderungen am Standard-Code des Tutorials notwendig, wenn von R40 auf R41 aktualisiert wird.