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
MfG,
Keks.
/e: Schrechtreibfehler
/e2: Schrechtreibfehler²
/e3: Kleiner Fehler....