Timeban 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
  • Heyho Com :)


    Ich habe bemerkt dass es hier kein Tutorial zum schreiben eines Tban Systems gibt,
    daher habe ich mir gedacht schreibe ich doch mal eins.


    Was benötigst du?

    Du benötigst Opas Commandprozessor (ocmd ), sscanf , ein Accountsystem und etwas Grundwissen.


    Was ist ein Timeban System?


    Mit einem Timeban System lässt sich ein User für eine beliebige Zeit
    vom Server verbannen. Die Zeit läuft auch ab wenn der Server ausgeschaltet ist.


    Schritt 1:


    Als erstes benötigen wir eine Funktion, mit der wir den Timeban ausführen.

    stock TBan(playerid,const string[],dauer,bannerid) //playerid = ID des zu bannenden, const string[] = der Grund, dauer = zeit, bannerid = die ID des Admins
    {
    return 1;
    }


    Diesen Stock füllen wir nun.


    Wir nehmen erst einmal den aktuellen UNIX-Timestamp (= Zeit in Sekunden seit dem 1.1.1970)
    new timestamp;
    timestamp = gettime(); //gettime() returnt (wenn man keine Parameter angibt) die genaue Zeit in Sekunden seit dem 1. Januar 1970




    Dann nehmen wir die Variable "dauer", multiplizieren sie mit 60 (= die Dauer des Timebans in Sekunden)
    und rechnen ihn auf den UNIX-Timestamp drauf. Dies ist nun logischerweise der Timestamp, bis wann der Timeban
    laufen wird.
    new sekunden = dauer * 60; //Die Minuten die der Admin angibt werden hier mit 60 multipliziert. Man erhält so die Sekunden, wie lange der Spieler gebannt wird.
    timestamp += sekunden; //Hier rechnen wir die Sekunden auf den vorher genommenen UNIX Timestamp auf, das ergibt dann das Datum bis wann der Spieler gebannt wird (in Sekunden)
    Nun geben wir an die Spieler auf dem Server eine hübsche Nachricht aus und kicken den zu Timebannenden.
    new name[MAX_PLAYER_NAME],bannername[MAX_PLAYER_NAME]; //2 Strings für die beiden Namen vom zu bannenden User und vom Admin werden deklariert
    GetPlayerName(playerid,name,sizeof(name)); //wir nehmen den Namen des zu bannenden und speichern den Namen in "name"
    GetPlayerName(bannerid,bannername,sizeof(bannername)); //das selbe passiert mit dem Namen des Admins
    format(str,sizeof(str),"AdmMsg: %s wurde von %s für %d Minuten gebannt",name,bannername,dauer); //mit format formatieren wir einen String in dem alle Infos stehen.
    SendClientMessageToAll(ROT,str); //und hier wird der gerade formatierte String an alle User auf dem Server ausgegeben.
    format(str,sizeof(str),"Grund: %s",string);//Da eine ClientMessage maximal 128 Zeichen haben kann geben wir den Grund seperat aus.
    SendClientMessageToAll(ROT,str);
    Kick(playerid); //Der Spieler wird gekickt.


    Als letztes kommt der Speicherteil. Wir speichern das "Datum" bis wann er gebannt ist ab um es beim Connecten wieder abzufragen, aber dazu später. Ich weiß leider nicht welches Dateisystem ihr benutzt. Ich nenne hier einfach mal
    jeweils ein Beispiel für MySQL & Dini.

    Mysql:

    mysql_SetInt("accounts", "TBan", timestamp, "Name", name);


    Dini:

    new pfad[MAX_PLAYER_NAME+16]; //wir deklarieren einen neuen String mit der Größe MAX_PLAYER_NAME (maximale Anzahl an Zeichen in einem Namen) + 16
    format(pfad,sizeof(pfad),"/accounts/%s.ini",name); //hier wird dann der Name in den String formatiert.
    dini_IntSet(pfad, "tban", timestamp); //Die Speicherung des Datums bis wann der Spieler gebannt wird erfolgt.
    Und fertig ist unser Timeban-Stock. Er sollte nun z.B. so aussehen:
    stock TBan(playerid,const string[],dauer,bannerid)
    {
    new timestamp;
    timestamp = gettime();
    new sekunden = dauer * 60;
    timestamp += sekunden;
    new name[MAX_PLAYER_NAME],bannername[MAX_PLAYER_NAME];
    GetPlayerName(playerid,name,sizeof(name));
    GetPlayerName(bannerid,bannername,sizeof(bannername));
    format(str,sizeof(str),"AdmMsg: %s wurde von %s für %d Minuten gebannt",name,bannername,dauer);
    SendClientMessageToAll(ROT,str);
    format(str,sizeof(str),"Grund: %s",string);
    SendClientMessageToAll(ROT,str);
    Kick(playerid);
    mysql_SetInt("accounts", "TBan", timestamp, "Name", name);
    return 1;
    }


    Dieser Stock würde also folgendes tun: er berechnet die Zeit bis wann der Spieler gebannt sein soll, und speichert diese Zeit im Account ab. Außerdem gibt er eine Nachricht aus und kickt den Spieler natürlich.


    Schritt 2:


    Der Stock nützt rein gar nichts wenn er nicht auch irgendwo aufgerufen wird. Die einfachste Methode ist nun ocmd in Verbindung mit sscanf, ihr könnt natürlich auch
    einen anderen Cmdprozessor verwenden, ich erkläre es hier aber nur mit ocmd & sscanf.


    Wir schreiben erst einmal das blanke Command wofür wir ocmd benötigen.
    ocmd:tban(playerid,params[])
    {
    return 1;
    }


    Dann machen wir die hinter dem Befehl eingegeben Parameter für uns verwendbar. Dazu benutzen wir sscanf.
    new pID,grund[64],dauer;
    if(sscanf(params, "usi", pID, grund,dauer))return SendClientMessage(playerid, 0xFF004BFF, "/tban [ID] [Grund] [Dauer (in Minuten)]"); //wir speichern die 3 hinter dem Command angegeben Parameter in Variablen. Wenn nicht genau 3 Parameter angegeben wurden, wird eine ClientMessage returnt, in der der Admin angezeigt bekommt was genau er einzugeben hat


    Mit den gerade gewonnen Werten können wir nun unseren Tban-Stock ausführen:
    TBan(pID,grund,dauer,playerid);


    Der Befehl sollte also in etwa so aussehen:
    ocmd:tban(playerid,params[])
    {
    new pID,grund[64],dauer;
    if(sscanf(params, "usi", pID, grund,dauer))return SendClientMessage(playerid, 0xFF004BFF, "/tban [ID] [Grund] [Dauer]");
    TBan(pID,grund,dauer,playerid);
    return 1;
    }


    Schritt 3:


    Wir haben es fast geschafft. Jetzt müssen wir nur noch beim Connecten bzw beim Login des Spielers überprüfen ob er noch gebannt ist.


    Erst nehmen wir den aktuellen UNIX-Timestamp
    new timestamp = gettime(); //Wieder das selbe wie beim Tban-stock....


    Dann lesen wir aus dem Account das Datum aus, bis wann der User noch gebannt ist. Beispiel mit MySQL:
    new bisgebannt = mysql_GetInt("accounts", "TBan", "Name", SpielerName(playerid)); //das Datum wird ausgelesen und in der gerade neu deklarierten Variable "bisgebannt" gespeichert.

    Wir vergleichen nun den aktuellen Timestamp mit dem, bis wann er noch gebannt ist. Ist der aktuelle TS kleiner als der
    TS bis wann er noch gebannt ist, so liegt das Banndatum noch in der Zukunft. Somit ist er noch gebannt und
    der Spieler wird gekickt.
    if(timestamp < bisgebannt) //wenn der gerade genommene Timestamp kleiner als bisgebannt ist, liegt das entbannungsdatum in der Zukunft.
    {
    SendClientMessage(playerid,0xFF3200FF,"Du bist noch gebannt! Komm später wieder!"); //Ist dies der Fall wird der Spieler gekickt.
    Kick(playerid);//Kick erfolgt
    }
    //Hier eine kompliziertere, aber "bessere" Methode:
    if(timestamp < bisgebannt) //wenn der gerade genommene Timestamp kleiner als bisgebannt ist, liegt das entbannungsdatum in der Zukunft.
    {
    new differenz = bisgebannt - timestamp; //wir subtrahieren bisgebannt von timestamp, wir erhalten also die Zeit in Sekunden wie lange der Spieler noch gebannt ist.
    new minuten = differenz / 60; //wir machen aus den Sekunden Minuten....
    new str[64]; //neuer String wird deklariert....
    format(str,sizeof(str),"Du bist noch %i Minuten gebannt!",minuten); //So bekommt der Spieler sogar noch angezeigt, wie langer er noch genau gebannt ist.
    SendClientMessage(playerid,0xFAFAFAFF,str); //String wird dem Spieler ausgegeben
    Kick(playerid);//Kick erfolgt
    }


    Diese Zeilen sollten beim Laden des Accounts ausgeführt werden, am besten als erstes.


    So sollten die Zeilen in etwa aussehen:
    new timestamp = gettime();
    new bisgebannt = mysql_GetInt("accounts", "TBan", "Name", SpielerName(playerid));
    if(timestamp < bisgebannt)
    {
    SendClientMessage(playerid,0xFF3200FF,"Du bist noch gebannt! Komm später wieder!");
    Kick(playerid);
    }







    Damit verabschiede ich mich. Falls Fragen oder Unklarheiten aufkommen helfe ich gerne. Meldet euch dann am besten per PN :)
    Feedback ist natürlich strengstes erwünscht :D


    MfG,

    Keks.


    /e: Schrechtreibfehler
    /e2: Schrechtreibfehler²

    /e3: Kleiner Fehler....

  • cool für anfänger die gerne wissen wie es geht aber ,
    aber dsa tutorial für ein timeban gibt es ja mind. 300mal hier auf forum.sa-mp.de!


    7/10 für die bemühung :)


    mfg m0nkey :thumbup:

    Wirklich? Naja ich hatte die Suchfunktion bevor ich das Tut geschrieben hatte nach "timeban tutorial" durchsucht.
    Ich fand überwiegend User die einen Thread aufmachten mit Titeln wie "Wie schreibt man ein Tban System?" und auch
    in der Liste der Tuts fand ich nichts über Tbans... Das bewegte mich ja dazu das Tut zu schreiben :D


    Ich schreib doch kein Tut wenns das schon ca. 100mal gibt :D


    Danke trotzdem :)

  • Guten Morgen erstmal gut gelungendes Tutorial für Anfänger sicher nützlich aber ein fehler sehe ich da undzwar:


    SendClientMessageToAll(ROT,str);
    Kick(playerid);
    mysql_SetInt("accounts", "TBan", timestamp, "Name", SpielerName(playerid));
    er wird gekickt und wenn er schon garnichtmehr auf dem Server ist wird es in die Tabelle geschrieben was ja nichtmehr gehen kann ^^
    also zu:
    SendClientMessageToAll(ROT,str);
    mysql_SetInt("accounts", "TBan", timestamp, "Name", SpielerName(playerid));
    Kick(playerid);

  • Danke ^^


    Ist mir selbst nicht aufgefallen 8|


    Das Problem ist/war: Es ist ja nur ein Beispiel, gerade diese Zeilen SOLL ja niemand kopieren. Deswegen habe ich mir auch nicht die Mühe gemacht und "SpielerName(playerid)" ausgetauscht.
    Normalerweise hätte ich den Namen mit GetPlayerName() vor dem Kick genommen und dann später in der Tabelle verarbeitet. Naja ich ändere es besser mal um ^^

  • Gutes Tut, soweit aber ohne die angreifen zu wollen, würde ich dir empfehlen alles was die sachen machen zu beschreiben ...
    Das anfänger mehr lernen als zu kopieren ..
    Und noch was zu den new pfad[64];
    Du kannst einfach die Zeichen zählen abzgl dem "%s".
    Das hier sind jetzt 14, dann nimmse einfach MAX_PLAYER_NAME und machst MAX_PLAYER_NAME+15, +1 für einen freien Byte...
    Somit bist du dir auch sicher falls SA:MP mal die Maximallänge der namen ändern sollte, und machst nicht immer so große Strings :D