Beiträge von Bluewall

    Welche MySQL Version verwendest du denn?
    Die neuste? https://github.com/pBlueG/SA-MP-MySQL/releases


    Falls ja, dann solltest du dich mit dem Support von Nitrado in Verbindung setzen, damit die dir das installieren.
    http://forum.sa-mp.com/showthread.php?t=570569


    Am besten du gibst denen die Fehlermeldung, meistens wissen so Anbieter schon um was es da geht, die machen das ja normalerweise nicht zum ersten mal.


    Ich nutze das MySQL-Plugin R39-3
    Das dauert mir viel zu lange, bis man eine Antwort von Nitrado bekommt. Gibts da noch andere Lösungen?

    Kann es sein das du 2 verschiedene Mysql Versionen ladest?
    Fehlt dir eventuell das Whirpool.inc?


    echo Executing Server Config...
    lanmode 0
    rcon_password Zensiert.
    passwort Zensiert.
    hostname SAMP-Server
    gamemode0 Gamemode 1
    filterscripts
    announce 0
    query 1
    chatlogging 0
    weburl
    onfoot_rate 40
    incar_rate 40
    weapon_rate 40
    stream_distance 300.0
    stream_rate 1000
    maxnpc 0
    logtimeformat [%H:%M:%S]
    language German | Deutsch
    plugins mysql_static.so sscanf.so Whirlpool.so
    maxplayers 40
    bind Zensiert
    bindip Zensiert
    port 7777


    Seit wann gibt es eine Whirlpool.inc? Ich hatte bisher nur eine .dll das außerdem wird die auch Geladen. hier der Log:


    SA-MP Dedicated Server
    ----------------------
    v0.3.7-RC6-3, (C)2005-2015 SA-MP Team


    [20:29:20] filterscripts = "" (string)
    [20:29:20] weburl = "www.sa-mp.com" (string)
    [20:29:20]
    [20:29:20] Server Plugins
    [20:29:20] --------------
    [20:29:20] Loading plugin: mysql_static.so
    [20:29:20] Failed (/usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by plugins/mysql_static.so))
    [20:29:20] Loading plugin: sscanf.so
    [20:29:20]


    [20:29:20] ===============================


    [20:29:20] sscanf plugin loaded.


    [20:29:20] Version: 2.8.1


    [20:29:20] (c) 2012 Alex "Y_Less" Cole


    [20:29:20] ===============================


    [20:29:20] Loaded.
    [20:29:20] Loading plugin: Whirlpool.so
    [20:29:20]
    [20:29:20] ==================
    [20:29:20]
    [20:29:20] Whirlpool loaded
    [20:29:20]
    [20:29:20] ==================
    [20:29:20]
    [20:29:20] Loaded.
    [20:29:20] Loaded 2 plugins.


    [20:29:20]
    [20:29:20] Filterscripts
    [20:29:20] ---------------
    [20:29:20] Loaded 0 filterscripts.


    [20:29:20] Script[gamemodes/M_Gamemode.amx]: Run time error 19: "File or function is not found"
    [20:29:20] Number of vehicle models: 0


    Hilfe wäre ganz Nützlich, bin am Verzweifeln. :/
    Jeffry: | Jeffry

    Nitrado macht mir das Leben mal wieder richtig Schwer. Ich hab die mysql_static.so genutzt, und nun kommt Folgendes:


    Failed (/usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by plugins/mysql_static.so))


    Bitte um Hilfe. :D

    Teste dein Tutorial bitte zur Sicherheit. Ohne es zu testen habe ich schon zwei Fehler gefunden.


    1.)
    Zeile 18 in OnAccountCheck macht keinen Sinn:
    (!strlen(IP[playerid]) || strcmp(IP[playerid], NewIP, true));


    2.)
    Das Query in SpielerSpeichern ist viel zu kurz. Schon ohne die ausgefüllten Platzhalter hat es 113 Zeichen, sprich die restlichen Zeichen werden abgeschnitten, somit kommt immer ein Syntax Error.


    Ich habs getestet, bisher hatte ich keine Probleme. Mhh

    Guten Abend.


    Mein Name lautet MiX(eP).
    Ich zeig euch wie man mit MySQL R39-3 ein Register/Login System baut!
    Nun, fangen wir mal damit an.


    Was benötigen wir? :



    Ihr fügt alles in dem Script ordner Rein (Plugins, Includes.) und fügt dann auch die Namen der Plugins in die Server.cfg ein.



    Der Scripting-Part:


    Als erstes erstellen wir uns ein Static, das sollte so aussehen:


    static
    Handle,
    Name[MAX_PLAYERS][24],
    IP[MAX_PLAYERS][16]
    ;


    Dann müssen wir ja noch unsere Daten angeben. Das machen wir so:



    #define M_HOST "Host"
    #define M_USER "Benutzer"
    #define M_DATA "Datenbank"
    #define M_PASS "Passwort"


    Wie kann man nun sein Script mit der Datenbank verbinden? Dazu nutzen wir mysql_connect:
    http://wiki.sa-mp.com/wiki/MySQL/R33#mysql_connect
    Handle = mysql_connect(M_HOST, M_USER, M_DATA, M_PASS);


    So aber am besten sollte man sich 2 Sachen vergewissern, 1. Das die Verbindung steht, 2. Das der Verlauf geloggt wird.
    Um zu wissen, das die Verbindung steht müssen wir mit der Funktion mysql_errno Arbeiten.
    http://wiki.sa-mp.com/wiki/MySQL/R33#mysql_errno


    Beispiel:


    if(mysql_errno(Handle) != 0)
    {
    print("[M_CONNECTION] >> Die Verbindung zur Datenbank ist Fehlgeschlagen! << [M_CONNECTION]");
    }
    else
    {
    printf("[M_CONNECTION] >> Die Verbindung zur Datenbank %s wurde Erfolgreich Hergestellt! << [M_CONNECTION]",M_DATA);
    }


    Jetzt gucken wir mal, wie wir die Datei "mysql_log" erstellen, dazu nutzen wir mysql_log :
    http://wiki.sa-mp.com/wiki/MySQL/R33#mysql_log


    mysql_log(LOG_ERROR | LOG_WARNING | LOG_DEBUG);


    OnGamemodeInit sollte nun so aussehen:


    public OnGameModeInit()
    {
    //===[ M_Connection ]===//
    mysql_log(LOG_ERROR | LOG_WARNING | LOG_DEBUG);
    Handle = mysql_connect(M_HOST, M_USER, M_DATA, M_PASS);
    if(mysql_errno(Handle) != 0)
    {
    print("[M_CONNECTION] >> Die Verbindung zur Datenbank ist Fehlgeschlagen! << [M_CONNECTION]");
    }
    else
    {
    printf("[M_CONNECTION] >> Die Verbindung zur Datenbank %s wurde Erfolgreich Hergestellt! << [M_CONNECTION]",M_DATA);
    }
    return 1;
    }


    So nun gehen wir zu OnPlayerConnect, das haben wir nun auch, nun kommt der Richtige Scripting-Teil:
    als erstes machen wir eine Schleife die, die Spieler durchgeht. Das sieht dann so aus:


    for(new i; SpielerDaten:i < SpielerDaten; i++)
    {
    SpielerInfo[playerid][SpielerDaten:i] = 0;
    }


    Gut. nun setzen wir den Spieler auf Unregistriert, das machen wir so:


    IstRegistriert[playerid] = 0;


    Jetzt erstellen wir einen Query, der Abfragt ob ein Eintrag
    in der Datenbank existiert, vorher Fragen wir aber noch den Namen und die IP des Spielers ab. Das geht so:


    GetPlayerName(playerid, Name[playerid], 24);
    GetPlayerIp(playerid, IP[playerid], 16);


    Nun zu den Querys, erstellt eine Variable die so aussieht:


    new Query[128];


    nun Formatieren wir etwas das sieht dann so aus ( Beispiel! wird noch befüllt :(


    format(query, sizeof(query), "..", ..);


    nun der Format, wie er aussehen Sollte:


    mysql_format(Handle, Query, sizeof(Query), "SELECT * FROM `Spieler` WHERE `Spielername` = '%e' LIMIT 1", Name[playerid]);
    mysql_tquery(Handle, Query, "OnAccountCheck", "i", playerid);


    Nun das ist fertig, jetzt gehen wir zu OnPlayerDisconnect und schreiben folgendes:


    if(IstRegistriert[playerid] != 0)
    {
    SpielerSpeichern(playerid);
    }


    Nun erstellen wir unser Public "OnAccountCheck", dazu schreiben wir oben erst noch:


    forward OnAccountCheck(playerid);
    forward OnAccountLoad(playerid);
    forward OnAccountRegister(playerid);


    und:


    #define D_REGISTER 1
    #define D_LOGIN 2


    Jetzt legen wir mit OnAccountCheck los. Wir arbeiten mit cache_get_data, das soll nun so aussehen:
    http://wiki.sa-mp.com/wiki/MySQL/R33#cache_get_data


    public OnAccountCheck(playerid)
    {
    new Rows, Fields;
    cache_get_data(Rows, Fields, Handle);
    if(Rows)
    {


    Jetzt arbeiten wir weiter mit cache_get_field_content:
    http://wiki.sa-mp.com/wiki/MySQL/R33#cache_get_field_content



    new oldIP[16];
    cache_get_field_content(0, "IP", oldIP, Handle, 16);
    GetPlayerIp(playerid, oldIP, 16);
    IstRegistriert[playerid] = 1;
    if(strlen(IP[playerid]) != 0 && !strcmp(IP[playerid], oldIP, true))
    {
    OnAccountLoad(playerid);
    }
    else
    {
    cache_get_field_content(0, "Passwort", SpielerInfo[playerid][Passwort], Handle, 129);
    SpielerInfo[playerid][ID] = cache_get_field_content_int(0, "ID");
    printf("%s", SpielerInfo[playerid][Passwort]);
    ShowPlayerDialog(playerid, D_LOGIN, DIALOG_STYLE_INPUT, "Login", "Dein Account wurde gefunden. Bitte gib nun dein Passwort ein:","Einloggen","Abbrechen");
    }
    }
    else
    {
    ShowPlayerDialog(playerid, D_REGISTER, DIALOG_STYLE_INPUT, "Registrieren","Dein Account wurde nicht gefunden! Bitte gib nun dein gewünschtes Passwort ein:","Registrieren","Abbrechen");
    }
    return 1;
    }


    Nun sollte unser Public so aussehen:


    public OnAccountCheck(playerid)
    {
    new Rows, Fields;
    cache_get_data(Rows, Fields, Handle);
    if(Rows)
    {
    new oldIP[16];
    cache_get_field_content(0, "IP", oldIP, Handle, 16);
    GetPlayerIp(playerid, oldIP, 16);
    IstRegistriert[playerid] = 1;
    if(strlen(IP[playerid]) != 0 && !strcmp(IP[playerid], oldIP, true))
    {
    OnAccountLoad(playerid);
    }
    else
    {
    (!strlen(IP[playerid]) || strcmp(IP[playerid], NewIP, true));
    cache_get_field_content(0, "Passwort", SpielerInfo[playerid][Passwort], Handle, 129);
    SpielerInfo[playerid][ID] = cache_get_field_content_int(0, "ID");
    printf("%s", SpielerInfo[playerid][Passwort]);
    ShowPlayerDialog(playerid, D_LOGIN, DIALOG_STYLE_INPUT, "Login", "Dein Account wurde gefunden. Bitte gib nun dein Passwort ein:","Einloggen","Abbrechen");
    }
    }
    else
    {
    ShowPlayerDialog(playerid, D_REGISTER, DIALOG_STYLE_INPUT, "Registrieren","Dein Account wurde nicht gefunden! Bitte gib nun dein gewünschtes Passwort ein:","Registrieren","Abbrechen");
    }
    return 1;
    }


    So nun müssen wir zum dem Callback was für die Antwort, es eines Buttons von einem Dialog ist. Eine sogenannte Response.
    Das Callback nennt sich OnDialogResponse, Dazu fragen wir die jeweilige Dialog-ID ab, das erledigen wir so:


    public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
    {
    switch(dialogid)
    {
    case D_LOGIN:
    {
    if(!response) Kick(playerid);
    new H_Pass[129];
    new Query[100];
    WP_Hash(H_Pass, 129, inputtext);
    if(strlen(H_Pass) && !strcmp(H_Pass, SpielerInfo[playerid][Passwort]))
    {
    mysql_format(Handle, Query, sizeof(Query), "SELECT * FROM `Spieler` WHERE `Spielername` = '%e' LIMIT 1", Name[playerid]);
    mysql_tquery(Handle, Query, "OnAccountLoad", "i", playerid);
    }
    else
    {
    ShowPlayerDialog(playerid, D_LOGIN, DIALOG_STYLE_INPUT, "Login", "Dein Account wurde gefunden. Bitte gib nun dein Passwort ein\nFalsches Passwort!", "Einloggen", "Abbrechen");
    }
    }


    Nun fangen wir weiter an mit dem Dialog: D_REGISTER:


    case D_REGISTER:
    {
    if(!response) return Kick(playerid);
    if(strlen(inputtext) < 6) return ShowPlayerDialog(playerid, D_REGISTER, DIALOG_STYLE_INPUT, "Register", "Dein Account wurde nicht gefunden! Bitte gib nun dein gewünschtes Passwort ein.\nDein Passwort muss länger als 6 Zeichen sein!", "Registrieren", "Abbrechen");
    new Query[300];
    WP_Hash(SpielerInfo[playerid][Passwort], 129, inputtext);
    mysql_format(Handle, Query, sizeof(Query), "INSERT INTO `Spieler` (`Spielername`, `Passwort`, `IP`, `Admin`, `VIP`,`Morde`,`Tode`,`Level`, `Geld`) VALUES ('%e', '%s', '%s', 0, 0, 0, 0, 0, 10000)", Name[playerid], SpielerInfo[playerid][Passwort], IP[playerid]);
    mysql_tquery(Handle, Query, "OnAccountRegister", "i", playerid);
    }
    }
    return 1;
    }


    Nun sollte auch dieses Public so aussehen:


    public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
    {
    switch(dialogid)
    {
    case D_LOGIN:
    {
    if(!response) Kick(playerid);
    new H_Pass[129];
    new Query[100];
    WP_Hash(H_Pass, 129, inputtext);
    if(!strcmp(H_Pass, SpielerInfo[playerid][Passwort]))
    {
    mysql_format(Handle, Query, sizeof(Query), "SELECT * FROM `Spieler` WHERE `Spielername` = '%e' LIMIT 1", Name[playerid]);
    mysql_tquery(Handle, Query, "OnAccountLoad", "i", playerid);
    }
    else
    {
    ShowPlayerDialog(playerid, D_LOGIN, DIALOG_STYLE_INPUT, "Login", "Dein Account wurde gefunden. Bitte gib nun dein Passwort ein\nFalsches Passwort!", "Einloggen", "Abbrechen");
    }
    }
    case D_REGISTER:
    {
    if(!response) return Kick(playerid);
    if(strlen(inputtext) < 6) return ShowPlayerDialog(playerid, D_REGISTER, DIALOG_STYLE_INPUT, "Register", "Dein Account wurde nicht gefunden! Bitte gib nun dein gewünschtes Passwort ein.\nDein Passwort muss länger als 6 Zeichen sein!", "Registrieren", "Abbrechen");
    new Query[300];
    WP_Hash(SpielerInfo[playerid][Passwort], 129, inputtext);
    mysql_format(Handle, Query, sizeof(Query), "INSERT INTO `Spieler` (`Spielername`, `Passwort`, `IP`, `Admin`, `VIP`,`Morde`,`Tode`,`Level`, `Geld`) VALUES ('%e', '%s', '%s', 0, 0, 0, 0, 0, 50000)", Name[playerid], SpielerInfo[playerid][Passwort], IP[playerid]);
    mysql_tquery(Handle, Query, "OnAccountRegister", "i", playerid);
    }
    }
    return 1;
    }


    So, nun braucht ihr noch ein Native, und zwar dieses:


    native WP_Hash(buffer[], len, const str[]);


    Nun brauchen wir noch das Public "OnAccountLoad" und "OnAccountRegister".
    Die erstellen wir so:


    OnAccountLoad:
    public OnAccountLoad(playerid)
    {
    new Score;
    SpielerInfo[playerid][Admin] = cache_get_field_content_int(0, "Admin");
    SpielerInfo[playerid][VIP] = cache_get_field_content_int(0, "VIP");
    SpielerInfo[playerid][Geld] = cache_get_field_content_int(0, "Geld");
    SpielerInfo[playerid][Morde] = cache_get_field_content_int(0,"Morde");
    SpielerInfo[playerid][Tode] = cache_get_field_content_int(0, "Tode");
    Score = cache_get_field_content_int(0, "Level");
    SetPlayerScore(playerid, Score);
    GivePlayerMoney(playerid, SpielerInfo[playerid][Geld]);
    SendClientMessage(playerid, -1, "Du hast dich Erfolgreich Eingeloggt!");
    return 1;
    }


    OnAccountRegister:


    public OnAccountRegister(playerid)
    {
    SpielerInfo[playerid][ID] = cache_insert_id();
    printf("Neuer Account Registriert | ID: %d", SpielerInfo[playerid][ID]);
    SpielerInfo[playerid][Geld] = 10000;
    GivePlayerMoney(playerid, 10000);
    IstRegistriert[playerid] = 1;
    return 1;
    }


    Wie können wir nun den Spieler Speichern? Wir machen das per Stock! Hier ein Beispiel das funktionsfähig ist. :


    stock SpielerSpeichern(playerid)
    {
    new Query[256];
    mysql_format(Handle, Query, sizeof(Query), "UPDATE `Spieler` SET `IP`='%s', `Admin`=%d, `VIP`=%d, `Morde`=%d, `Tode`=%d, `Level`=%d, `Geld`=%d WHERE `ID`=%d",\
    IP[playerid], SpielerInfo[playerid][Admin], SpielerInfo[playerid][VIP], SpielerInfo[playerid][Morde], SpielerInfo[playerid][Tode], GetPlayerScore(playerid), SpielerInfo[playerid][Geld], SpielerInfo[playerid][ID]);
    mysql_tquery(Handle, Query, "", "");
    }


    Jetzt fehlen uns noch Folgende Sachen:


    new IstRegistriert[MAX_PLAYERS];


    enum SpielerDaten
    {
    ID,
    Passwort[129],
    Admin,
    VIP,
    Morde,
    Tode,
    Level,
    Geld
    }


    new SpielerInfo[MAX_PLAYERS][SpielerDaten];


    So das war es auch schon! Hoffe es hat euch gefallen
    Hier ist die Datenbank fürs ganze!
    Datenbank: http://www.file-upload.net/dow…10580092/Spieler.sql.html


    Hinweis! : Durch kopieren lernt ihr kein Scripten, deswegen lest es euch durch! Und versucht es mal. Scripten kann Jeder wenn er es nur Möchte!

    error 021: symbol already defined: "GivePlayerMoney"


    Bedeutet:


    error 021: Symbol bereits definiert: "GivePlayerMoney"


    Hast du die Variable irgendwo definiert? such mal nach "GivePlayerMoney" und guck ob irgendwo ein #define davorsteht.

    GivePlayerMoney hat nur 2 Reiter, das sind einmal "playerid"' und "money". ich weiß ja nicht was das soll:


    GivePlayerMoney(playerid,killerid, -100,100);


    Probiers mal so:


    GivePlayerMoney(playerid,100);


    Oder was willst du da probieren?

    Wenn du es mit Stock hast, so siehts bei mir aus:


    stock SpielerLaden(playerid)
    {
    new Spieler[64],Name[MAX_PLAYER_NAME];
    GetPlayerName(playerid,Name,sizeof(Name));
    format(Spieler,sizeof(Spieler),"/Spieler/%s.ini",Name);
    if(dini_Exists(Spieler))
    {
    GivePlayerMoney(playerid,dini_Int(Spieler,"Geld"));
    SetPlayerScore(playerid,dini_Int(Spieler,"Score"));
    SpawnPlayer(playerid);
    }
    return 1;
    }

    Ich hab mit Bluetooth-Headset nur Schlechte Erfahrungen gemacht.
    Eins zu Weihnachten gewünscht und nach dem 1 Tag von Weihnachten war das Headset defekt durch irgendeinen Kommunikations-Fehler, zwischen Stick und Headset.
    Klappte auch ganz gut, aber nach dem 1x Tag wars dann vorbei.