Beiträge von T4125Gamer

    stock SpielerLaden(playerid)
    {
    new Spieler[64];
    new Sname[MAX_PLAYER_NAME];
    GetPlayerName(playerid,Sname,sizeof(Sname));
    format(Spieler,sizeof(Spieler),"/Spieler/%s.txt",Sname);
    if(dini_Exists(Spieler))
    {
    SetPlayerScore(playerid,dini_Int(Spieler,"Level"));
    sSpieler[playerid][Adminlevel] = dini_Int(Spieler,"Adminlevel");
    sSpieler[playerid][Level] = dini_Int(Spieler,"Level");
    sSpieler[playerid][Fraktion] = dini_Int(Spieler,"Fraktion");
    sSpieler[playerid][Team] = dini_Int(Spieler,"Team");
    }
    return 1;
    }
    So ist es richtig

    Also du beginnst mit einem normale Grundgerüst:
    if(strcmp(cmdtext,"/befehl",true) == 0)
    {
    return 1;
    }
    Wenn du es noch nicht hast, dann machst du new tmp[256], idx; in den Public OnPlayerCommandText


    Wenn das gemacht ist kannst du in den vorherigen Befehl das rein machen tmp = strtok(cmdtext,idx);
    Dann folgt eine Abfrage:
    if(!strlen(tmp))
    {
    SendClientMessage(playerid, FARBE, "BENUTZUNG: /befehl[an/aus]");
    return 1;
    }
    Nun kommen noch die Abfragen mit "an" und "aus"
    if(strcmp(tmp,"an",true) == 0)
    {
    SendClientMessage(playerid,FARBE,"Dein Befehl ist jetzt an");
    }
    else if(strcmp(tmp,"aus",true) == 0)
    {
    SendClientMessage(playerid,FARBE,"Dein Befehl ist jetzt aus");
    }
    Alles in einem sieht das dann so aus:
    public OnPlayerCommandText(playerid,cmdtext[])
    {
    new tmp[256];
    if(strcmp(cmdtext,"/befehl",true) == 0)
    {
    tmp = strtok(cmdtext,idx);
    if(!strlen(tmp))
    {
    SendClientMessage(playerid, FARBE, "BENUTZUNG: /befehl[an/aus]");
    return 1;
    }
    if(strcmp(tmp,"an",true) == 0)
    {
    SendClientMessage(playerid,FARBE,"Dein Befehl ist jetzt an");
    }
    else if(strcmp(tmp,"aus",true) == 0)
    {
    SendClientMessage(playerid,FARBE,"Dein Befehl ist jetzt aus");
    }
    return 1;
    }
    return 0;
    }


    Falls kommt: Undefined Symbol strtok, machst du dann das hier ins Script:
    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;
    }

    Login/Register System
    Da du es ja mit Dialog machen willst, werden zuerst die Dialoge definiert, das sollte ja nicht schwer sein.
    #define Register 0
    #define Login 1
    Nun kann man mit Register und Login arbeiten, da diese ja definiert sind. Doch was nehmen wir zum
    erstellen der Accounts? Da du auf dini Basis arbeiten möchtest, werde ich dir das mit dini jetzt weiter
    erläutern. Zuerst wird das Include dini Includiert, das geht so:
    #include <dini>
    ist das gemacht, kann man jetzt auf Befehle (z. B. dini_Create) die im Include sind zugreifen.
    Jetzt ist das Include da, und die Dialoge sind bereit. Jetzt stellt sich die Frage wo der Dialoge angezeigt
    werden soll, das kann unter OnPlayerRequestClass oder OnPlayerConnect geschehen, das ist relativ egal.
    Ich entscheide mich jetzt für OnPlayerConnect.
    public OnPlayerConnect(playerid)
    {
    ShowPlayerDialog(playerid,Register,DIALOG_STYLE_PASSWORD,"Register","Tippe nun das gewünschte Passwort ein.","OK","Abbrechen");
    return 1;
    }
    1. Jetzt wird der Dialog angezeigt, wenn der Spieler Connectet, aber groß passieren wird da noch nichts.
    2. Wird das dann immer angezeigt obwohl der Spieler dann schon einen Account besitzt. Das sollte nicht sein,
    und deswegen wird nun das erstellt.
    new Spielerdatei[128]; //128 steht für .ini dateien, 64 für .txt dateien
    new sName[MAX_PLAYER_NAME];
    GetPlayerName(playerid,sName,sizeof(sName));
    format(Spielerdatei,sizeof(Spielerdatei),"/Accounts/%s",sName);
    Nun haben wir zugriff auf die Datei, wenn diese Existiert. Nun kann man auch die Abfrage bilden, ob die
    Datei schon vorhanden ist.
    if(dini_Exists(Spielerdatei))
    {


    }
    Wenn die Datei existiert soll ja der Login Dialog angezeigt werden. Deswegen diese Abfrage.
    if(dini_Exists(Spielerdatei))
    {
    ShowPlayerDialog(playerid,Login,DIALOG_STYLE_PASSWORD,"Login","Tippe nun das Passwort ein.","OK","Abbrechen");
    }
    else
    {
    ShowPlayerDialog(playerid,Register,DIALOG_STYLE_PASSWORD,"Register","Tippe nun das gewünschte Passwort ein.","OK","Abbrechen");
    }
    nun ist schonmal gegeben das die Datei nicht zweimal angelegt wird. Zusammen sieht das dann so aus:
    public OnPlayerConnec(playerid)
    {
    new Spielerdatei[128];
    new sName[MAX_PLAYER_NAME];
    GetPlayerName(playerid,sName,sizeof(sName));
    format(Spielerdatei,sizeof(Spielerdatei),"/Accounts/%s",sName);
    if(!dini_Exists(Spielerdatei))
    {
    ShowPlayerDialog(playerid,Login,DIALOG_STYLE_PASSWORD,"Login","Tippe nun das Passwort ein.","OK","Abbrechen");
    }
    else
    {
    ShowPlayerDialog(playerid,Register,DIALOG_STYLE_PASSWORD,"Register","Tippe nun das gewünschte Passwort ein.","OK","Abbrechen");
    }
    return 1;
    }
    Der Anfang ist somit geschaft. Nun kann man weiter mit den Dialogen machen. Das macht man unter OnDialogResponse
    if(dialogid == Register)
    {
    if(response == 0) //Wenn der Spieler auf Abbrechen geklickt hat
    {
    SendClientMessage(playerid,FARBE,"Sie haben den Register Vorgang abgebrochen");
    Kick(playerid);
    }
    if(response == 1) //Wenn der Spieler auf OK geklickt hat
    {
    if(!strlen(inputtext)) //Wenn nichts im Input Feld steht kommt eine Message und der Dialog erneut.
    {
    SendClientMessage(playerid,WEISS,"Sie müssen etwas eingeben");
    ShowPlayerDialog(playerid,Register,DIALOG_STYLE_PASSWORD,"Register","Tippe nun das gewünschte Passwort ein.","OK","Abbrechen");
    }
    else //Wenn ein Passwort angegeben wurde wird der Spieler registriert, der Stock folgt gleich
    {
    Registrieren(playerid,MD5_Hash(inputtext)); //Das Passwort immer (muss aber nicht) mit MD5 Hashen, das sorgt für mehr Sicherheit. Das Include ist im Anhang und wird auch mit #include includiert.
    return 1;
    }
    }
    }
    Nun ist der Register Dialog fertig. Der Stock Register wird etwas später noch erklärt. Nun folgt der Login Dialog
    if(dialogid == Login)
    {
    if(response == 0)
    {
    SendClientMessage(playerid,FARBE,"Sie haben den Login Vorgang abgebrochen"); //Wenn der Spieler auf Abbrechen geklickt hat
    Kick(playerid);
    }
    if(response == 1)
    {
    if(!strlen(inputtext))
    {
    SendClientMessage(playerid,FARBE,"Sie müssen etwas eingeben");
    ShowPlayerDialog(playerid,Login,DIALOG_STYLE_PASSWORD,"Login","Tippe nun das Passwort ein.","OK","Abbrechen");
    }
    else
    {
    SpielerLogin(playerid,MD5_Hash(inputtext));
    }
    }
    }


    So der Login Dialog ist jetzt auch fertig. Wenn man jetzt Compilet würden die Errors kommen das SpielerLogin und Registrieren nicht definiert sind.
    Um das zu beheben werden nun SpielerLogin und Registrieren mit einem stock erstellt.
    stock Registrieren(playerid,passwort[])
    {
    return 1;
    }
    Der Grundbau ist nun fertig, jetzt fragt sich was darin alles geschen soll. Zunächst soll ja der Account in einem
    Ordner erstellt werden. Ich habe dafür den Ordner /Accounts mir ausgesucht. Doch wie lassen wir die Datei erstellen?
    Das geht mit dini_Create, aber ganz alleine geht das auch nicht, da dini_Create einen Pfad braucht wo die
    Datei erstellt werden soll. Das geht wieder mit format.
    new Spielerdatei[128], sName[MAX_PLAYER_NAME];
    GetPlayerName(playerid,sName,sizeof(sName));
    format(Spielerdatei,sizeof(Spielerdatei),"/Accounts/%s.ini",sName);
    Jetzt kann man ein Account erstellen.
    dini_Create(Spielerdatei);
    Jetzt ist der Account erstellt, aber es steht nocht nichts in dieser Datei drinnen.
    Wenn nichts drinnen steht, dann kann man auch nicht bei Login das Passwort herauslesen.
    Deswegen ist im stock noch passwort[] drinnen, damit kann man jetzt folgendes machen:
    dini_Set(Spielerdatei,"Passwort",passwort);
    Jetzt ist in der Account Datei eine Zeile mit Passwort. Das Passwort könnte so aussehen: 9E01C8E41FE64C602F29FDC45BE384F9 da es ja mit MD5 gehasht wird.
    Man kann jetzt auch noch andere Werte setzten lassen, z. B. Adminlevel oder Geld, Level etc.
    Das ist aber jetzt nicht so wichtig. Der Stock sieht dann so aus:
    stock Registrieren(playerid,passwort[])
    {
    new Spielerdatei[128], sName[MAX_PLAYER_NAME];
    GetPlayerName(playerid,sName,sizeof(sName));
    format(Spielerdatei,sizeof(Spielerdatei),"/Accounts/%s.ini",sName);
    dini_Create(Spielerdatei);
    dini_Set(Spielerdatei,"Passwort",passwort);
    return 1;
    }


    Der Stock ist nun fertig. Jetzt kommt der stock SpielerLogin.
    stock SpielerLogin(playerid,password[])
    {
    return 1;
    }
    Was genau geschieht jetzt in diesem Stock? In diesem Stock wird der Spieler eingeloggt, also das Passwort wird ermittelt.
    Wenn es falsch ist wird dem Spieler eine Message geschrieben, dass das Passwort falsch ist. Zuerst müssen wir wieder mittels
    format an die Accountdatei herankommen.
    new Spielerdatei[128], sName[MAX_PLAYER_NAME];
    GetPlayerName(playerid,sName,sizeof(sName));
    format(Spielerdatei,sizeof(Spielerdatei),"/Accounts/%s.ini",sName);
    Nun kann aus der Datei etwas herausgelesen werden. Da es sich hier um den Login vorgang handelt wird das Passwort herausgelsen
    und auf seine richtigkeit überprüft, das geht so:
    if(!strcmp(passwort,dini_Get(Spielerdatei,"Passwort"),true))
    {


    }
    Nun wird ermittelt ob das Passwort falsch oder richtig ist. Wenn es richtig ist lassen wir die eingetragenen
    Daten von der Account Datei laden, wenn es falsch ist bekommt der Spieler eine Message das es falsch ist. Das ganze sieht dann so aus:
    if(!strcmp(passwort,dini_Get(Spielerdatei,"Passwort"),true))
    {
    SpielerLaden(playerid);
    }
    else
    {
    SendClientMessage(playerid,FARBE,"Das Passwort ist leider nicht richtig");
    ShowPlayerDialog(playerid,Login,DIALOG_STYLE_PASSWORD,"Login","Tippe nun das Passwort ein.","OK","Abbrechen");
    }
    Jetzt steht die Passwort überprüfung. Der stock sieht dann so aus:
    stock SpielerLogin(playerid,password[])
    {
    new Spielerdatei[128], sName[MAX_PLAYER_NAME];
    GetPlayerName(playerid,sName,sizeof(sName));
    format(Spielerdatei,sizeof(Spielerdatei),"/Accounts/%s.ini",sName);
    if(!strcmp(passwort,dini_Get(Spielerdatei,"Passwort"),true))
    {
    SpielerLaden(playerid);
    }
    else
    {
    SendClientMessage(playerid,FARBE,"Das Passwort ist leider nicht richtig");
    ShowPlayerDialog(playerid,Login,DIALOG_STYLE_PASSWORD,"Login","Tippe nun das Passwort ein.","OK","Abbrechen");
    }
    return 1;
    }

    Dieser Stock ist nun auch fertig.
    Man möchte ja gerne die Daten auch aus der Datei herausholen, und dem Spieler "übergeben", also wenn jemand Leader eine Fraktion ist soll er ja auch dort Spawnen.
    Das geht mit einem Stock der SpielerLaden heißt (kann auch anders heißen).
    stock SpielerLaden(playerid)
    {
    return 1;
    }
    Nun wieder das bekannte mit dem format.
    new Spielerdatei[128], sName[MAX_PLAYER_NAME];
    GetPlayerName(playerid,sName,sizeof(sName));
    format(Spielerdatei,sizeof(Spielerdatei),"/Accounts/%s.ini",sName);
    Jetzt fragt sich ob man mit PVar oder einen enum Arbeitet. Ich nehme ein enum, da ich es besser finde.
    Dazu wird jetzt ganz oben bei den Defines folgendes erstellt.
    enum sDaten
    {
    Level,
    Geld,
    Adminlevel
    }
    new SpielerInfo[MAX_PLAYERS][sDaten];
    Die Spielerdaten können auch bei bedarf erweitert werden. Ist das erstellt kann man nun über SpielerInfo
    verschiedene Daten abfragen, z. B.:
    if(SpielerInfo[playerid][Adminlevel] == Zahl)
    {


    }
    Das geht auch bei allen anderen Daten so. Nun kann man auch den Stock SpielerLaden ergänzen.
    GivePlayerMoney(playerid,dini_Int(Spielerdatei,"Geld")); //Hier wird das Geld verteilt
    SetPlayerScore(playerid,dini_Int(Spielerdatei,"Level")); //Hier wird der Score verteilt
    SpielerInfo[playerid][Adminlevel] = dini_Int(Spielerdatei,"Adminlevel"); //Hier wird dem Spieler das Adminlevel zugeteilt
    so kann man das mit jeder Information machen. Der Stock sieht dann so aus:
    stock SpielerLaden(playerid)
    {
    new Spielerdatei[128], sName[MAX_PLAYER_NAME];
    GetPlayerName(playerid,sName,sizeof(sName));
    format(Spielerdatei,sizeof(Spielerdatei),"/Accounts/%s.ini",sName);
    GivePlayerMoney(playerid,dini_Int(Spielerdatei,"Geld");
    SetPlayerScore(playerid,dini_Int(Spielerdatei,"Level");
    SpielerInfo[playerid][Adminlevel] = dini_Int(Spielerdatei,"Adminlevel");
    return 1;
    }
    Jetzt werden dem Spieler die Sachen die in der Account Datei stehen gegeben.
    Wenn man jetzt aber etwas daran verändert, muss man das auch irgendwie in die Datei bekommen.
    Das geht mit einem neuen Stock, der SpielerSpeichern heißt. (Kann auch anders heißen)
    stock SpielerSpeichern(playerid)
    {
    return 1;
    }
    Nun wieder das mit format:
    new Spielerdatei[128], sName[MAX_PLAYER_NAME];
    GetPlayerName(playerid,sName,sizeof(sName));
    format(Spielerdatei,sizeof(Spielerdatei),"/Accounts/%s.ini",sName);
    Da wir ja etwas in die Datei speichern wollen, und nicht herauslesen, wird hierbei dini_IntSet benutzt.
    dini_IntSet(Spielerdatei,"Level",GetPlayerScore(playerid)); //Level wird gespeichert
    dini_IntSet(Spielerdatei,"Geld",GetPlayerMoney(playerid)); //Geld wird gespeichert
    dini_IntSet(Spielerdatei,"Adminlevel",SpielerInfo[playerid][Adminlevel]); //Adminlevel wird gespeichert.
    Nun werden die Daten in der Datei gespeichert. Der Stock sieht dann so aus:
    stock SpielerSpeichern(playerid)
    {
    new Spielerdatei[128], sName[MAX_PLAYER_NAME];
    GetPlayerName(playerid,sName,sizeof(sName));
    format(Spielerdatei,sizeof(Spielerdatei),"/Accounts/%s.ini",sName);
    dini_IntSet(Spielerdatei,"Level",GetPlayerScore(playerid)); //Level wird gespeichert
    dini_IntSet(Spielerdatei,"Geld",GetPlayerMoney(playerid)); //Geld wird gespeichert
    dini_IntSet(Spielerdatei,"Adminlevel",SpielerInfo[playerid][Adminlevel]); //Adminlevel wird gespeichert.
    return 1;
    }
    Das kann man jetzt bei OnPlayerDisconnect benutzen, damit der Spieler beim Verlassen des Servers gespeichert wird.
    SpielerSpeichern(playerid);
    Man kann die Spieler auch beim Neustart speichern lassen, damit nicht alles weg ist wenn mal der
    Server neustartet. Dazu wird eine Schleife benötigt, die durch alle Spieler geht, das machst du unter OnGameModExit.
    for(new i = 0; i<MAX_PLAYERS; i++)
    {
    SpielerSpeichern(i);
    }
    Jetzt werden alle Spieler gespeichert.
    Man kann das Login/Register System auch mit einem Alters System bestücken, damit man eine angabe hat wie alt
    der Spieler ist. Aber das ist etwas komplizierter, und meine Verfügbaren zeichen reichen dafür nicht aus.
    MfG: T4125Gamer