Dcmd und sscanf Commands

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 mir gerade langweilig ist und öfters nach Commands mit Parametern gefragt wird, dachte ich, ich erstelle mal ein Tutorial in dem so etwas erklärt wird.
    Ich mache das mit Dcmd und Sscanf weil es CPU schonender als der ganze Schnik Schnak da mit strcmp und strtok ist und wie ich finde auch viel einfacher ist.
    Als erstes brauchen Wir mal die Definitionen für dcmd und sscanf.
    Hier die für dcmd:
    #define dcmd(%1,%2,%3) if ((strcmp((%3)[1], #%1, true, (%2)) == 0) && ((((%3)[(%2) + 1] == 0) && (dcmd_%1(playerid, "")))||(((%3)[(%2) + 1] == 32) && (dcmd_%1(playerid, (%3)[(%2) + 2]))))) return 1

    Und hier der Link zu sscanf weil die Definition für sscanf ein bisschen zu lang wäre ;) .
    Klick
    Nun fangen wir mal an. Ich mache hier jetzt ein einfaches /goto [PlayerID] Command [Non-GF!].
    Als erstes machen wir mal bei OnPlayerCommandText folgendes:
    dcmd(goto, 4, cmdtext);
    Erklärung:
    dcmd gehört einfach zum definieren des Befehls.
    goto gibt den Commandnamen an. Ohne '/'.
    Und cmdtext ist einfach der Text von dem Commando, dass man eingibt, also die Quelle.
    Nun ausserhalb eines Publics machen wir dann folgendes:
    dcmd_goto(playerid, params[])
    Erklärung: dcmd_goto heisst erstelle die dcmd funktion goto.
    Das playerid steht für denjenigen der /goto [PlayerID] ausführt.
    Und Params sind einfach die Parameter ( Also hier die PlayerID von dem Spieler zu dem wir uns teleportieren möchten. )
    Jetzt eine geschweifte Klammer auf ( { )
    Und dann der eigentliche Command.
    Als erstes mal die Variablen:
    new pid;
    new Float: PosX, Float: PosY, Float: PosZ;
    Das pid wird dann die PlayerID von dem Spieler beinhalten zu dem wir uns Teleportieren möchten.
    Und Float: PosX, Float: PosY und Float: PosZ das sind die Koordinaten von dem Spieler der in pid gespeichert ist.
    Jetzt zur Verwendung von sscanf.
    Erst der Code, dann die Erklärung:
    if(sscanf(params, "d", pid))
    {
    return SendClientMessage(playerid, COLOR_RED, "Verwendung: /goto [PlayerID]");
    }
    Zur Erklärung:
    sscanf(params, "d", pid):
    Hier werden die Parameter festgelegt, also welcher Variablentyp es sein soll ( "d" d steht für Integer ) und in welcher Variable das nach /goto eingegebene gespeichert werden soll.
    Dort wird geprüft ob ein Parameter mit /goto eingegeben wurde, wieviele Parameter eingegeben wurden. Und ob der Parameter ein Integer ist ( Also eine Zahl ohne Kommastellen ist ).
    Und falls das nicht so ist wird SendClientMessage(playerid, COLOR_RED, "Verwendung: /goto [PlayerID]"); returnt ( zurückgegeben ).
    So nun der Code der ganz normal ist:
    if(pid == INVALID_PLAYER_ID) // Prüfen ob die eingebene PlayerID gültig ist also ob der Spieler online ist
    {
    SendClientMessage(playerid, COLOR_RED, "Ungültige PlayerID");
    }
    else // Wenn es die PlayerID gibt
    {
    GetPlayerPos(pid, PosX, PosY, PosZ);
    SetPlayerPos(playerid, PosX, PosY, PosZ);
    SendClientMessage(playerid, 0x00FF00FF, "Du hast dich teleportiert");
    }

    Nun noch ein "return 1;" und das wars schon. Ziemlich einfach oder?
    Das Ganze sollte nun so aussehen:

    dcmd_goto(playerid, params[])
    {
    new pid;
    new Float: PosX, Float: PosY, Float: PosZ;
    if(sscanf(params, "d", pid))
    {
    return SendClientMessage(playerid, COLOR_RED, "Verwendung: /goto [PlayerID]");
    }
    if(pid == INVALID_PLAYER_ID)
    {
    SendClientMessage(playerid, COLOR_RED, "Ungültige PlayerID");
    }
    else
    {
    GetPlayerPos(pid, PosX, PosY, PosZ);
    SetPlayerPos(playerid, PosX, PosY, PosZ);
    SendClientMessage(playerid, 0x00FF00FF, "Du hast dich teleportiert");
    }
    return 1;
    }

    Man kann bei sscanf(params, "d", pid) statt d auch u nehmen, dass ist extra für PlayerIDs und PlayerNamen gemacht.
    Das war jetzt natürlich ein ganz einfaches Beispiel man sollte da noch prüfen ob der Player Admin oder so ist und ob der Player überhaupt schon eingeloggt ist. Aber das habe ich jetzt mal rausgelassen um es noch mehr zu vereinfachen.
    Ich hoffe ich konnte einigen Leuten mit meinem Tutorial helfen :thumbup:


    LG
    V1rus

    Einmal editiert, zuletzt von v1rus ()

  • Stimmt
    Hab ja nur gesagt dass es schneller als strcmp und strtok ist nicht das schnellste.

    Einmal editiert, zuletzt von v1rus ()

  • Nettes Tut aber ich will nicht pingelich oder so klingen aber das geht auch kürzer :)


    dcmd_goto(playerid, params[])
    {
    new pid, Float: PosX, Float: PosY, Float: PosZ;
    if(sscanf(params, "d", pid)) SendClientMessage(playerid, COLOR_RED, "Verwendung: /goto [PlayerID]");
    if(pid == INVALID_PLAYER_ID) SendClientMessage(playerid, COLOR_RED, "Ungültige PlayerID");
    else
    {
    GetPlayerPos(pid, PosX, PosY, PosZ);
    SetPlayerPos(playerid, PosX, PosY, PosZ);
    SendClientMessage(playerid, 0x00FF00FF, "Du hast dich teleportiert");
    }
    return 1;
    }

  • Stimmt hab ich vergessen. Sry weil hab mit der SuFu unter dcmd und sscanf nix gefunden.

  • kürzer



    dcmd_goto(playerid, params[])
    {
    new pid, Float: PosX, Float: PosY, Float: PosZ;
    if(sscanf(params, "d", pid))return SendClientMessage(playerid, COLOR_RED, "Verwendung: /goto [PlayerID]");
    if(pid == INVALID_PLAYER_ID)return SendClientMessage(playerid, COLOR_RED, "Ungültige PlayerID");
    GetPlayerPos(pid, PosX, PosY, PosZ);
    SetPlayerPos(playerid, PosX, PosY, PosZ);
    SendClientMessage(playerid, 0x00FF00FF, "Du hast dich teleportiert");
    return 1;
    }

    RFT

  • OCMD isn abklatsch von DCMD und das wissen alle, außerdem isses sowas von unnötig, das Leute sagen "OCMD besser als DCMD", "warum?", "man muss nix unter OnPlayerCommandText schreiben", pah !
    Diese "feature" ist in meinen augen sowas von unnötig, und stoppt ihr mal bitte für Opa's sachen rumzuwerben in anderen Threads, ich kann verstehen wie das die Threadersteller sowas von nerven kann.
    Und jetzt BACK TO TOPIC


    @Topic://
    Es gibt ein sehr gutes und besseres Tut von Goldkiller, aber deins ist auch gut und hast dir Mühe gegeben, respekt ;)
    8/10

  • Zitat

    naja gibt schon eines ... und ocmd ist auch schneller, aber dafür braucht man kein Tutorial funktioniert ja gleich wie dcmd


    edit: verbessert


    edit2: hier haste eine Grafik http://www.kleiner-opa.de/pic/test.png und wenn du dieser Grafik nicht glaubst dann teste es selber ..... also mach keine Aussagen die nicht stimmen



    Was mach ich für falsche Aussagen?


    Zitat

    Stimmt
    Hab ja nur gesagt dass es schneller als strcmp und strtok ist nicht das schnellste.


    Das heißt, dass ocmd vielleicht schneller ist, aber dcmd auf jedn schneller ist als strcmp und strtok usw. Mein Gott lern lesen Junge -.-

  • OCMD kann schneller sein, und auch kürzer gescriptet sein, wen kümmerts ?
    Und wen kümmerts dass OCMD 1/100000 Sekunde und DCMD 1/10000 die Sekunde ausgeführt wird ?
    Hauptsache es funzt !
    Und das wichtigste ist immernoch die Stabilität, und auch Userfreundlichkeit :thumbdown:


    @Topic jetzt, bevor wir alle Verwarnungen nehmen wegen Off-Topic!
    Ich habs jetzt nochmal durchgelesen und ich mache eine kleine änderung an deinen Punkten ;)
    7/10

  • Kurz offtopic.


    Habt ihr den schonmal die Codes der beiden verglichen?
    DCMD erscheint mir wesentlich schneller.


    @Threadhersteller


    Die "4" bei deinem CMD ist die Länge des CMDs die bei strcmp mitangegeben werden kann.
    dcmd überprüft halt obcmdtext[1] ("goto") in deinem cmd mit %1 ("goto") und die länge übereinstimmt.