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
  • Hallo Liebe Community,
    da ich inmoment etwas langeweile habe,
    werde ich nun ein Mysql Tutorial machen,
    das meistens geupdatet wird.
    Nun fangen wir mal an.


    1.Installation


    Für die installation benötigt ihr natürlich erstmal die Mysql Dateien, dieses findet ihr Hier
    In dem Forum wählt ihr aus, was für ein Betriebssyste ihr habt.
    Desweiteren müsst ihr euch das Pawn-kit herunterladen, damit ihr das Include besitzt.
    Das Include wisst ihr wohl wo es hinkommt.


    Wenn ihr die Mysqldatei entpackt habt,bekommt ihr auch einen Sourceordner, diesen benötigt ihr nicht.
    Ihr braucht lediglich die sampmysql.dll.
    Ihr erstellt in eurem Serverordner einen neuen ordner namens Plugins,
    in der ihr das Plugin sampmysql.dll einfügt.
    Natürlich müsst ihr dieses Plugin auch als Plugin in eurer Serverconfig reinschreiben.
    Dies passiert mit:

    Code
    Plugins sampmysql


    Um die Mysqlfunktionen in eurem Script anwenden zu können,
    müsst ihr in eurem script natürlich das Include hinzufügen:
    #include <a_sampmysql>


    2.Funktionen

    • samp_mysql_connect()
    • samp_mysql_select_db()
    • samp_mysql_query()
    • samp_mysql_store_result()
    • samp_mysql_fetch_row()
    • samp_mysql_get_field()
    • samp_mysql_num_rows()
    • samp_mysql_num_fields()
    • samp_mysql_strtok()
    • samp_mysql_ping()
    • samp_mysql_real_escape_string()
    • samp_mysql_free_result() => DON'T USE IT, IT WILL CRASH YOUR SERVER !!!
    • samp_mysql_close()

    (Von SA-MP.com kopiert)


    3.Verbindung zu MYSQL


    Vorab braucht ihr XAMPP auf eurem Computer, damit ihr überhaupt eine MYSQL auf eurem Computer habt.
    Hier Weiter Infos dazu + INSTALLATION von XAMPP
    Nun fehlt uns nurnoch ein Mysql Programm,
    ich benutze Navicat ist sehr leicht und praktisch.
    Download
    Dann Connectet ihr auf eure Mysql und erstellt eine neue Datenbank mit dem Name samp.


    Nun zum Script.
    Nun gehen wir zu OnGameModeInit,
    dort fügen wir dies hinzu

    stock MySQLConnect(sqlhost[], sqluser[], sqlpass[], sqldb[])
    {
    samp_mysql_connect(sqlhost, sqluser, sqlpass);//Connected auf die Mysql
    samp_mysql_select_db(sqldb);//Wählt die Datenbank
    if(samp_mysql_ping() == 0) return 1;//Überprüft die Connection
    else
    {
    samp_mysql_connect(sqlhost, sqluser, sqlpass);//Wieder alles von vorn
    samp_mysql_select_db(sqldb);
    if(samp_mysql_ping() == 0) return 1;
    else
    {
    SendRconCommand("exit");
    return 0;
    }
    }
    }
    Variante von Nachoman:
    stock MySQLConnect()
    {
    new arrCoords[19][64];
    new strFromFile2[256];
    new sqlhost[56], sqluser[56], sqlpass[64], sqldb[56];
    new File: file = fopen("config/mysql.cfg", io_read);
    if (file)
    {
    fread(file, strFromFile2);
    split(strFromFile2, arrCoords, '|');


    strmid(sqlhost, arrCoords[0], 0, strlen(arrCoords[0]), 255);
    strmid(sqluser, arrCoords[1], 0, strlen(arrCoords[1]), 255);
    strmid(sqlpass, arrCoords[2], 0, strlen(arrCoords[2]), 255);
    strmid(sqldb, arrCoords[3], 0, strlen(arrCoords[3]), 255);
    fclose(file);
    }


    samp_mysql_connect(sqlhost, sqluser, sqlpass);//Connected auf die Mysql
    samp_mysql_select_db(sqldb);//Wählt die Datenbank


    if(samp_mysql_ping() == 0) return 1;//Überprüft die Connection
    samp_mysql_connect(sqlhost, sqluser, sqlpass);//Wieder alles von vorn
    samp_mysql_select_db(sqldb);


    if(samp_mysql_ping() == 0) return 1;
    SendRconCommand("exit");
    return 0;


    }

    So nun seid ihr mit der Mysql verbunden, nun könntet ihr Sachen aus dieser Laden und so weiter, dies kommt aber erst im Nächsten Tutorial das in den nächsten Stunden erscheinen wird.
    Also freut euch auf v0.2.


    mfg Kavkus
    P.S Ich hoffe es ist wenigstens ein bisschen verständlich


    EDIT://Public in Stock geändert.

    4 Mal editiert, zuletzt von Kavkus ()

  • Ich hab noch ein paar Sachen zu bemängeln.
    Warum public?
    Ist viel zu langsam da bis zu 50Native Operations zum Aufruf gebraucht werden, da sind normale Funktionen viel besser geeignet.


    Du brauchst ein else bei einer if, die schon durch return; abgeschlossen wird. (Der PAWNCC optimiert dies NICHT weg)


    Das würde ich ganz klar in Tutorial v0.2 ändern.

  • 4.Grunderklärungen der 2Arten zum Lesen aus der Tabelle


    Es gibt insgesamt 2Arten vom auslesen aus den Tabellen
    die 1Art ist per split, split definiert ihr so in eurem Script:
    stock split(const strsrc[], strdest[][], delimiter)
    {
    new
    i,
    li,
    aNum,
    len;
    while(i <= strlen(strsrc))
    {
    if(strsrc[i]==delimiter || i==strlen(strsrc))
    {
    len = strmid(strdest[aNum], strsrc, li, i, 128);
    strdest[aNum][len] = 0;
    li = i+1;
    aNum++;
    }
    i++;
    }
    return 1;
    }
    Split ist dazu da, um aus den einzelnen Zeilen der Reihe der Tabelle sachen herauszulesen.
    Dies kann zwar die 2Art auch, aber ihr werdet nachher den Unterscheid merken.
    So, die 2Art ist per strtok, diese ist im Aufbau etwas leichter.
    strtok definiert ihr im Script so:
    strtok(const string[], &index)
    {
    new length = strlen(string);
    while ((index < length) && (string[index] <= ' '))
    {
    index++;
    }


    new offset = index;
    new result[20];
    while ((index < length) && (string[index] > ' ') && ((index - offset) < (sizeof(result) - 1)))
    {
    result[index - offset] = string[index];
    index++;
    }
    result[index - offset] = EOS;
    return result;
    }
    So dies sind die 2Arten des auslesen.


    5. Erstellen einer Tabelle
    So, um im Script etwas zu Laden brauchen wir nun erstmal eine Tabelle,
    (Ich erkläre euch jetzt per Schritte wie es im Navicat Lite geht).
    Als erstes öffnet ihr euer Navicat und wählt eure Datenbank.
    Und erstellt dort eine neue Tabelle, dann geht ihr in diese Tabelle.
    Wie ihr seht, steht nichts drinnen,jetzt befindet ihr euch gerade im Designbereich für eure Tabelle,
    dies bedeutet dort könnt ihr neue Einträge einschreiben.
    GANZ Wichtig, am besten immer in Zeile 1 die ID, umso übersichtlicher ist es,als Typ wählen wir INT.
    Nun noch eine Wichtige Sache, ihr müsst bei einer neuen Tabelle,
    die erste Spalte bei den Feldern müsst ihr hinten bei NULL-Werte Erlauben einen hacken hinmachen und in der Letzte spalte einen Key rein.

    So Nehmen wir mal die 2Zeile,
    Nehmen wir an ihr wollt einen Namen speicher/Laden.
    Schreiben wir vorne bei Name pName hin.
    Als Typ wählen wir text, nun ACHTUNG
    bei Länge und Dezimal braucht ihr nichts einzuschreiben,
    da diese beim Speichern Automatisch eingesetzt wird.
    Dann speichert ihr nun unter dem Namen Player ab.Dies ist nun eure erste Tabelle.


    6.Laden aus der Tabelle

    So wir erstellen erstmal eine PlayerInfo da es dann umso leichter ist.
    enum pinfo
    {
    pName
    }
    new PlayerInfo[MAX_PLAYERS][pinfo];
    Das müsste erstmal reichen.
    Nun zum Laden.
    ART 1:

    new Player;


    stock LoadPlayer()
    {
    new
    data[200],
    sql[50],
    line[6][20];
    samp_mysql_query("SELECT COUNT(*) FROM Player");//Wählt die Tabelle aus
    samp_mysql_store_result();
    samp_mysql_fetch_row(data);
    Player = strval(data);
    for(new i;i<Player;i++)
    {
    format(sql, sizeof(sql), "SELECT * FROM Player WHERE id='%d'", i);
    samp_mysql_query(sql);
    samp_mysql_store_result();
    if (samp_mysql_num_rows() > 0)
    {
    samp_mysql_fetch_row(data);
    split(data, line, '|');
    PlayerInfo[i][pName] = strval(line[1]);//strval für einen string/Text, floatstr für ein Float
    }
    }
    }
    Art 2:
    stock LoadPlayer()
    {
    new Data[100];
    new rcnt=1;
    new Field[64];
    new query[128];
    samp_mysql_query("SELECT * from Player"); //Wählt die Tabelle
    samp_mysql_store_result();
    samp_mysql_fetch_row(Data);
    samp_mysql_strtok(Field, "|", Data);

    while (samp_mysql_strtok(Field, "|", "")==1)
    {
    if(rcnt==2)PlayerInfo[playerid][pName]=strval(Field);
    rcnt++;
    }//Nun haben wir auch den Namen geladen, der jetzt wo anderst verwendet werden kann
    return 1;
    }
    Wie ihr seht, gibt es nicht große unterschiede.
    So nun sind die Werte geladen, doch um das Laden überhaupt starten zu lassen, fügen wir bei OnGameModeInit das hier ein,
    LoadPlayer();


    So, nun kommen wir zum Speichern.
    7.Speichern in eine Tabelle

    Speichern ist genauso einfach wie das Laden.
    Fangen wir an mit SavePlayer();
    stock SavePlayer(p)
    {
    if(p == 0)
    new
    sql[384],
    Name[32],
    message[32];
    samp_mysql_real_escape_string(PlayerInfo[p][pName], Name);
    format(sql, sizeof(sql), "UPDATE Player SET pName='%s' WHERE id=%d",PlayerInfo[p][pName],p);
    samp_mysql_query(sql);
    return 1;
    }
    So wird der Name in die Tabelle wieder eingespeichert
    Diese können wir nun bei OnPlayerDisconnect speichern lassen.
    SavePlayer(playerid);


    So, nun wisst ihr wie man lädt und speichert, falls ihr irgendwelche fragen habt, postet sie hier und nicht im ICQ.


    mfg Kevin(Kavkus).
    Verbesserungsvorschläge/Kritik sind sehr gewünscht.

  • zu Punkt 6, art 1, zeile 15: Leider funktioniert das nur so lange bis du ein Spieler in mitten der Tabelle löschst.
    Wenn du ALLE Spieler laden willst, dann benutzt lieber:

    format(sql, sizeof(sql), "SELECT * FROM Player LIMIT %d, 1", i);


    sonst ein super Tutorial, dankeschön!

  • noch nen vorschlag zur verbesserung der sicherheit:


    stock MySQLConnect()
    {
    new arrCoords[19][64];
    new strFromFile2[256];
    new sqlhost[56], sqluser[56], sqlpass[64], sqldb[56];
    new File: file = fopen("config/mysql.cfg", io_read);
    if (file)
    {
    fread(file, strFromFile2);
    split(strFromFile2, arrCoords, '|');

    strmid(sqlhost, arrCoords[0], 0, strlen(arrCoords[0]), 255);
    strmid(sqluser, arrCoords[1], 0, strlen(arrCoords[1]), 255);
    strmid(sqlpass, arrCoords[2], 0, strlen(arrCoords[2]), 255);
    strmid(sqldb, arrCoords[3], 0, strlen(arrCoords[3]), 255);
    fclose(file);
    }


    samp_mysql_connect(sqlhost, sqluser, sqlpass);//Connected auf die Mysql
    samp_mysql_select_db(sqldb);//Wählt die Datenbank


    if(samp_mysql_ping() == 0) return 1;//Überprüft die Connection
    samp_mysql_connect(sqlhost, sqluser, sqlpass);//Wieder alles von vorn
    samp_mysql_select_db(sqldb);


    if(samp_mysql_ping() == 0) return 1;
    SendRconCommand("exit");
    return 0;


    }


    so kann man die sqldaten extern einstellen, brauch bei änderung des passworts nicht neu kompilieren und kann den code weiter geben ohne das pw ändern zu müssen.
    ausserdem kann man bei deiner variante das pw leicht aus der amx auslesen.

  • do.de - Domain-Offensive - Domains für alle und zu super Preisen

  • Habe jetzt


    enum pInfo
    {
    pSkinID
    pAdmin
    pOnline
    pJob
    pFraktion
    pGeld
    pHP
    pKills
    pDeaths
    pLevel
    üRespekt
    pSkillpoints
    pHandy
    pHandy_Guthaben


    }


    Möchte die jetzt alle Laden (Heißen in der Tabelle alle Fast gleich eben nur ohne das p davor also z.b. pKills ist in der tabelle Kills)
    Wie mache ich das am besten ? (Die tabelle heißt users)

  • Anmerkungen:


    1. Wie soll es beim Art 2 beim Laden wissen, welchen Spieler man meint? (playerid is ja net definiert)
    2. Wieso bei OnGameModeInit? Ist ja noch kein Spieler da?
    3. Wieso benutzt man beim Speichern WHERE id=%d? Das heisst ja eigentlich, das der erste Spieler der gespeichert wird, ID 0 hat, wenn dann aber beim nächsten mal einer kommt, der im Spiel dann auch ID 0 hat, wird der erste Spieler überschrieben o_O oder seh ich das falsch? und das speichern ist in demfall nur für einen Spieler? (if p == 0)
    4. Hats noch irgendwo ein anderes Tut, mit mehr Sachen bei LoadPlayer & SavePlayer?


    Also das Tut ist ein bisschen komisch finde ich, dennoch gute arbeit..


    MFG

  • Ich weiß, das hier ist villeicht ein bisschen Outdated, aber ich würde gerne Mysql auf meinem Server benutzen.
    Und das hier ist das einzige Tutorial das ich gefunden habe.


    Wenn ich das jedoch alles so einsetzte und den Server starten möchte, wird er sofort wieder beendet.
    Die Crashinfo schmeißt mir dann folgendes auf den Screen:
    [hide]
    --------------------------
    SA-MP Server: 0.3b R2
    Exception At Address: 0x100035EB


    Registers:
    EAX: 0x00000000 EBX: 0x003527A8 ECX: 0x003527A8 EDX: 0x003527A8
    ESI: 0x609C9040 EDI: 0x0000001B EBP: 0x0013FDB8 ESP: 0x0013FD4C
    EFLAGS: 0x00010246


    Stack:
    +0000: 0x609C9040 0x00000003 0x00000000 0x00000000
    +0010: 0x003527A8 0x0000001B 0x00000001 0x00F85A48
    +0020: 0x609C9040 0x00F871D0 0x10003615 0x609C9040
    +0030: 0x003527A8 0x0000001B 0x003527A9 0x10014665
    +0040: 0x609C9040 0x003527A8 0x0000001B 0x00F85A48
    +0050: 0x609C14A4 0x609C9040 0x003527A8 0x00488100
    +0060: 0x00F85A48 0x003527A8 0x0000000C 0x00F87750
    +0070: 0x00401096 0x00F85A48 0x00F8C9F4 0x00F87CC4
    +0080: 0x00402BB3 0x00F85A48 0x00000006 0x0013FDF0
    +0090: 0x00F8C9F4 0x004EFE50 0x00F85A48 0x00000001
    +00A0: 0x00000000 0x00001180 0x00004D38 0x00004D30
    +00B0: 0x00005330 0x00001334 0x00005318 0x00001334
    +00C0: 0x00F871D0 0x00F87CC4 0x00000000 0x00F86BD0
    +00D0: 0x00000AF4 0x00487D64 0x00F85A48 0x0013FE38
    +00E0: 0x00000002 0x003F7658 0xFFFFFFFF 0x00000002
    +00F0: 0x003F7658 0x004986BF 0x004EFE50 0x004C0651
    +0100: 0x003F5BD9 0xFFFFFFFF 0x00000000 0x00F85A48
    +0110: 0x0013FEDC 0x004B3F28 0xFFFFFFFF 0x00497AFF
    +0120: 0x00000001 0x00000000 0x00000A28 0x0013FFC0
    +0130: 0x7FFDF000 0x00012BA3 0x00010101 0x00000032[/hide]


    Kann damit irgendjemand etwas anfangen?


    Das Script ist ein komplett neues. Abgesehen von diesen hier geschriebenen Mysql dingen steht noch nichts drinn.
    Benutzt habe ich die erste Variante des Ladens/Speicherns und Nachoman´s Verbindungsvariante und Mysql v0.15.


    Vielen dank schon mal im vorraus euer,


    Paddy