Beiträge von Jeffry

    Du hast es mit den Variablen etwas übertrieben.
    Mache es so:
    if (strcmp(cmd, "/leader", true) == 0)
    {
    new string[512];
    format(string, sizeof(string), "L.S.P.D. : %s\n", dini_Get("Info.ini","LSPD"));
    format(string, sizeof(string), "%sF.B.I. : %s\n", string, dini_Get("Info.ini","FBI"));
    format(string, sizeof(string), "%sArmy : %s\n", string, dini_Get("Info.ini","ARMY"));
    format(string, sizeof(string), "%sMedic : %s\n", string, dini_Get("Info.ini","MEDIC"));
    format(string, sizeof(string), "%sL.C.N. : %s\n", string, dini_Get("Info.ini","LCN"));
    format(string, sizeof(string), "%sYakuzza : %s\n", string, dini_Get("Info.ini","YAK"));
    format(string, sizeof(string), "%sPräsident : %s\n", string, dini_Get("Info.ini","PRÄSI"));
    format(string, sizeof(string), "%sHitman : %s\n", string, dini_Get("Info.ini","HITMAN"));
    format(string, sizeof(string), "%sSan News : %s\n", string, dini_Get("Info.ini","NEWS"));
    format(string, sizeof(string), "%sO-Amt : %s\n", string, dini_Get("Info.ini","OAMT"));
    format(string, sizeof(string), "%sFahrlehrer : %s\n", string, dini_Get("Info.ini","LEHRER"));
    format(string, sizeof(string), "%sTriaden : %s\n", string, dini_Get("Info.ini","TRIADEN"));
    format(string, sizeof(string), "%sGrove-Street : %s\n", string, dini_Get("Info.ini","GROVE"));
    format(string, sizeof(string), "%sBallas : %s\n", string, dini_Get("Info.ini","BALLAS"));
    format(string, sizeof(string), "%sBiker : %s\n", string, dini_Get("Info.ini","BIKER"));
    format(string, sizeof(string), "%sVagos : %s\n", string, dini_Get("Info.ini","VAGOS"));
    format(string, sizeof(string), "%sAztecas : %s\n", string, dini_Get("Info.ini","AZTECAS"));
    format(string, sizeof(string), "%sRifa : %s\n", string, dini_Get("Info.ini","RIFA"));
    format(string, sizeof(string), "%sRed-Soldiers : %s\n", string, dini_Get("Info.ini","REDS"));
    format(string, sizeof(string), "%sTerror : %s\n", string, dini_Get("Info.ini","TERROR"));
    format(string, sizeof(string), "%sWheelman : %s\n", string, dini_Get("Info.ini","WHEEL"));
    ShowPlayerDialog(playerid,30,DIALOG_STYLE_MSGBOX,"Leader-Liste",lstring,"Beenden","");
    return 1;
    }

    3x?
    Versuche es so:
    ocmd:n(playerid,params[])
    {

    if(pInfo[playerid][pLevel] > 3 && pInfo[playerid][pAdmin] == 0)return SendClientMessage(playerid,GRAU,"Du bist kein Neuling mehr!");
    if(pInfo[playerid][pNeulingChat] != 1)return SendClientMessage(playerid,GRAU,"Der Neulingschat ist derzeit {FF3C00}offline");
    new string[145];
    if(sscanf(params,"s[128]",string))return SendClientMessage(playerid, WEIß,"{FFD200}Benutzung:{FEFEFE} /n [Nachricht]");
    if(pInfo[playerid][pAdmin] > 0)
    {
    format(string, sizeof(string), "[%s{00E1FF}] %s: %s",GetAdminName(playerid),GetName(playerid),string);
    }
    else
    {
    format(string, sizeof(string), "{00E1FF}[Neuling{00E1FF}] %s: %s",GetName(playerid),string);
    }
    for(new i=0; i<MAX_PLAYERS; i++)
    {
    if(GetPlayerScore(i)<=3 || pInfo[i][pAdmin] >= 1)
    {
    SendClientMessage(i,HELLBLAU,string);
    }
    }
    return 1;
    }

    new File:BLACKLISTFILE = fopen("/M_Bot/M_Black.cfg", io_read);
    if(BLACKLISTFILE)
    {
    while(fread(BLACKLISTFILE,read))
    {
    for(new x=0; x<strlen(read); x++)
    {
    if(read[x] == '\n')
    {
    read[x] = '\0';
    }
    }
    if(!strcmp(read,playerip,false,TwoNumbersLength) || !strcmp(read,playerip,false))
    {
    fclose(BLACKLISTFILE);
    return 1;
    }
    }
    }
    fclose(BLACKLISTFILE);


    zu:
    new File:BLACKLISTFILE = fopen("/M_Bot/M_Black.cfg", io_read);
    if(BLACKLISTFILE)
    {
    while(fread(BLACKLISTFILE,read))
    {
    for(new x=0; x<strlen(read); x++)
    {
    if(read[x] == '\n')
    {
    read[x] = '\0';
    }
    }
    if(!strcmp(read,playerip,false,TwoNumbersLength) || !strcmp(read,playerip,false))
    {
    fclose(BLACKLISTFILE);
    return 1;
    }
    }
    fclose(BLACKLISTFILE);
    }


    Oder diese Datei erstellen:
    "/M_Bot/M_Black.cfg"

    Beim Auszahlen:
    if(GetPlayerMoney(playerid) == 0)
    {
    SendClientMessage(playerid, COLOR_GRAD1, "Ungültig!");
    return 1;
    }
    Das weg machen. Wenn du kein Geld auf der Hand hast, dann solltest du dir ja was auszahlen können.


    Übrigens:
    Solche Zahlen 999999999999999 sind in SA-MP auf Grund des 32-Bit Limits nicht möglich. Maximal geht 2^31-1 (2147483647), danach wird die Zahl wieder negativ, durch den Überlauf.

    Speichert es denn anderen Statistiken, wenn du das Tutorial gemacht hast?
    Möglicherweise wird einfach SpielerSpeichern nicht aufgerufen, wenn das Tutorial gemacht wurde. Setze da mal einen print hin und schau ob das von Anfang bis Ende durch kommt. Nicht dass "Eingeloggt" durch das Tutorial irgendwo auf 0 gesetzt wird.

    [jTuT] MySQL R41-4
    Installation, XAMPP, Verwendung, Bedienung & Registrations-System





    Hallo Zusammen,


    dieses Tutorial beschreibt die Installation sowie die Anwendung des aktuellsten MySQL Plugins für SA-MP (R41-4 / Stand 10/2017). 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 R41-4 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

      Code
      password=D5H)12DAI?4XST21/&DL1
      level=1
      money=1000
      kills=14
      deaths=3



      ->Datei: /users/Horst.sav

      Code
      password=ZIJ(/5SGJ!$96T6SD§F43
      level=5
      money=99
      kills=19
      deaths=96



      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.
    • Sammlung aller MySQL-Befehle
      Ich verweise hier auf die Sammlung aller SQL-Statements, die von MySQL unterstützt werden. In dieser Sammlung befinden sich auch Erklärungen und Beispiele zu den jeweiligen Befehlen.
      http://dev.mysql.com/doc/refman/5.7/en/sql-syntax.html
      Diese Liste musst Du natürlich nicht auswendig können. Es reicht zu wissen, dass diese Liste existiert, falls Du irgendwann etwas spezielles nachschauen möchtest.
      Ebenso verweise ich hier noch auf den aktuellen Wiki Eintrag für das MySQL Plugin: http://wiki.sa-mp.com/wiki/MySQL/R40
    • Verstehen der SQL Syntax
      Falls Du Probleme damit hast, die SQL Syntax zu verstehen, oder vor diesem Tutorial die SQL-Grundkenntnisse anhand von einfachen Beispielen lernen möchtest, empfehlen ich Dir diese Seite:
      http://www.w3schools.com/sql/default.asp
      Dort sind die wichtigsten Dinge, bis hin zu etwas komplexeren Themen, sehr gut und verständlich erklärt. Außerdem können die erklärten Funktionen direkt im Browser von Dir selbst ausprobiert werden.
      Ich kann in diesem Tutorial nicht die komplette SQL Syntax erklären, daher der Verweis auf diese wirklich gute Seite. Falls Du Fragen dazu hast, darfst Du diese natürlich trotzdem gerne hier stellen.




    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:




    • 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:

      Code
      id - 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.







    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 vier Dateien benötigt, diese sind: a_mysql.inc, mysql.dll, libmariadb.dll und log-core.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. Die libmariadb.dll sowie die log-core.dll legst Du bitte in den Hauptordner Deines Servers.
      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:

      C
      #include <a_mysql>



      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 Hoster 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:

      C
      new MySQL:handle; //Die Connection-Handle, über die wir später auf die Tabellen der Datenbank zugreifen



      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:

      C
      MySQL_SetupConnection();



      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:



      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:

      C
      mysql_close(handle);



      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:



      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:



      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:



      Außerdem benötigen wir nun das Callback OnUserCheck, welches Du am besten ganz unten in Deinem Gamemode/Filterscript einfügst.



      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.


      Auch hier benötigst Du die beiden neuen Callbacks, die Du wieder ganz unten in Deinem Gamemode/Filterscript einfügst:

      C
      forward OnUserRegister(playerid);
      public OnUserRegister(playerid)
      {
      	//Der Spieler wurde in die Datenbank eingetragen, es wird die id ausgelesen
      	PlayerInfo[playerid][p_id] = cache_insert_id();
      	PlayerInfo[playerid][pLoggedIn]  = true;
      	SendClientMessage(playerid, 0x00FF00FF, "[Konto] Registration erfolgreich.");
      	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.

      C
      public 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:



      Damit wären wir so gut wie durch. Um die Funktionen auch testen zu können schreiben wir noch etwas bei OnPlayerDeath rein:



      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:

      C
      mysql_log();


      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 )


    • Plugin wird nicht geladen
      In manchen Fällen kann es vorkommen, dass das Plugin nicht gestartet wird. Es gibt unterschiedliche Gründe dafür, diese sind häufig auf fehlende Installationen im Betriebssystem zurückzuführen. Folgende Lösungsansätze helfen in den meisten Fällen:

      • Windows: Download und Installation der All-In-One Runtimes (Download von chip.de)
      • Linux: Nutzung der mysql_static.so anstelle der mysql.so.



    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.



    • Zusätzlich verlinke ich hier noch auf folgende Include von JustMe.77: [INCLUDE] Einzigartige Login/Register TextDraws
      In den dortigen Downloads findet sich ein fertiger Filterscript, der den Code dieses Tutorials beinhaltet.




    Ä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.
    • 14.09.2016: Aktualisierung des Tutorials auf R40 und Verweise auf die SQL-Syntaxliste, das Wiki sowie W3Schools in Abschnitt 3 hinzugefügt.
    • 03.10.2016: Aktualisierung des Tutorials auf R41.
    • 21.05.2017: Aktualisierung des Tutorials auf R41-2 und beheben eines Login Fehlers nach der Registration, vielen Dank an JustMe.77.
    • 02.09.2017: Aktualisierung des Tutorials auf R41-3. Verlinkung Login/Register Textdraw System, vielen Dank an JustMe.77.
    • 01.10.2017: Aktualisierung des Tutorials auf R41-4.




    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 8)

    Zeig mal, wie du dem Spieler die 2000$ gibst, wie du ihm die 40$ abziehst und wie du den Spieler speicherst und einloggst (Daten speichern & laden).

    wer hat Schleifen im Skript für mehr als 10.000 Durchläufe


    Wobei das ja nichts an der Tatsache ändert, dass die Laufzeitperformance besser ist. Dass sie - im kleinen Bereich - unwesentlich ist, ist mir klar. Besser ist sie trotzdem.


    Man hat 1x die Makros...dann ist es einfach nur noch hinzufügen


    Natürlich. Das ändert aber auch nichts daran, dass die Schreibweise von Bit-Berechnungen komplizierter ist. Du argumentierst am Thema vorbei.


    Somit hält das halt die amx schön klein


    400 Bytes Unterschied, mein MAX_PLAYERS steht auf 150. Das ist ebenso unwesentlich wie die eingesparte Laufzeit, nur habe ich persönlich lieber eine größere AMX als Lags.
    Aber das wird doch lächerlich. Weder 1MB Festplattenplatz noch 1ms Laufzeit stören jemand - in SA-MP zumindest.


    Allerdings will mit Sicherheit jemand mal mehr als 32 Items haben, und dann ist er froh drum.