SA-MP Forums

Go Back   SA-MP Forums > SA-MP Scripting and Plugins > Scripting Help > Help Archive

 
 
Thread Tools Display Modes
Old 23/08/2008, 11:12 AM   #1
DracoBlue
Gangsta
 
Join Date: Apr 2006
Posts: 818
Reputation: 49
Default [HowTo] Fast command processor: DCMD (0.3 Ready)

Hello!

jtp10181 showed in a topic that there are still person which use strtok to get a nice looking command processor. But it is slow and it won't work like it should if you have more commands behind each other.

Thatswhy I decided to show a way (dcmd) which also looks gentle but is much faster then strtok only and in my opinion better organized.

How To: [iurl=http://forum.sa-mp.com/index.php?topic=70925.msg461044#msg461044]Add Multiple Parameters[/iurl]

This way, is often used (I am not using params now, because that would decrease strtok-method again) (Remember it hasn't even protection if somebody uses commands like /meso or something like this!)
pawn Code:
public OnPlayerCommandText(playerid,text[])
{
new cmd[MAX_STRING];
new tmp[MAX_STRING];
new idx;
cmd=strtok(text,idx);

if (equal(cmd,"me",true)) {
  /* Ok it was a emote command */
      format(tmp,sizeof(tmp),"%s",text);
  strdel(tmp,0,3);
   // tmp has the message now!
     printf("[%d] /ME %s",playerid,tmp);
      return 1;
    }

if (equal(cmd,"die",true)) {
  /* Ok it was a die command */
      printf("[%d] /DIE",playerid);
      return 1;
    }
 // This command is not supported.
  return 0;
}

Our implementation will look like this (it has protection like /meso is not allowed, but /me hello is.):
pawn Code:
#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

 dcmd_me(const playerid,const params[]) {
   printf("[%d] /ME %s",playerid,params);
   return true;
  }

 dcmd_die(const playerid,const params[]) {
   // following line states, that we won't use params in that command.
   #pragma unused params

   printf("[%d] /DIE",playerid);
   return true;
  }

public OnPlayerCommandText(playerid, const cmdtext[])
{

  dcmd(me,2,cmdtext);
  dcmd(die,3,cmdtext);
 // This command is not supported.
  return 0;
}

I tested (calling 1000000 times) the implementations above, without print-stuff (this would make lag, which isn't called by the function itself!) and had this results:
63 Seconds for first implementation.
18 Seconds for my implementation.

Here is my testcase:
pawn Code:
OnPlayerCommandText(1,"/me looks evil to somebody.");
    OnPlayerCommandText(1,"/me");
    OnPlayerCommandText(1,"/me     ");
    OnPlayerCommandText(1,"/meso askljdaslkjdaslkjdaslkdj"); // is unknown
    OnPlayerCommandText(1,"/die");
    OnPlayerCommandText(1,"/die ");
    OnPlayerCommandText(1,"/die jashdasjk");

If I add two more /commands (for example /give and /me in both implementation) the results where: 19 seconds for mine, and already 70 seconds for the first implementation.

You can see that it is much faster without extra vars and stuff.

Why is it so much faster, even in this small example?
The magic thing is using procedures and good organized if-statement, instead of lots of strtok's.
Our macro:
pawn Code:
#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
With parameter me,2,cmdtext will result into:
pawn Code:
if ((strcmp(cmdtext, "/me", true, 2+1) == 0)&&(((cmdtext[2+1]==0)&&(dcmd_me(playerid,"")))||((cmdtext[2+1]==32)&&(dcmd_me(playerid,cmdtext[2+2]))))) return 1
But how does this work? Lets split it:
#1 (strcmp(cmdtext, "/me", true, 2+1) == 0)
#2.1 ((cmdtext[2+1]==0)&&(dcmd_me(playerid,""))
#2.2 ((cmdtext[2+1]==32)&&(dcmd_me(playerid,cmdtext[2+2]))
If #1 is true, the beginning is /me, but this doesn't filter stuff like /meso yet.
Now #2.1 or #2.2 must be true. The #2.1 is true, if "/me" is the whole string, and dcmd_me returns true. The #2.2 returns true, if "/me " has a space after /me, so its for example "/me hello." and transfers the array beginning from the "hello" (therefor we have cmdtext[2+2]). The cool thing is, that dcmd_me won't be executed if already #1 isn't true, so it doesn't take extra space/speed.

Regards,
Jan (DracoBlue)

[Hint] This topic got lost, when updating/converting the forums, so you may find an archive at webarchive.org
__________________
Auto-Indent Your Code online with TidyPawn

dcmd 1.0 | dini 1.6 | djson 1.6.2 (The offic. Dini²) | DMap 0.4 | DModule 0.13 (Dynamic GM/FS) | DUDB 2.4 | DTest 1.2 | Dutils 1.10

[dracoblue's dev-diary][php + javascript developer][serverside javascript mvc framework]

DracoBlue is offline  
Old 23/08/2008, 11:24 AM   #2
DracoBlue
Gangsta
 
Join Date: Apr 2006
Posts: 818
Reputation: 49
Default Re: [HowTo] Fast command processor: DCMD (0.2 Ready)

Example with multiple parameters:
pawn Code:
dcmd_giveweapon(playerid,params[]) {
 new index=0;
 new nick[255]=strtok(params,index);
 new weapon[255]=strtok(params,index);
 new amount=strval(strtok(params,index));
 // ...
}
Example to get params.

You can additionall also use sscanf to properly parse the params.

- Draco

PS: Sorry for doublepost, but the topic was lost, so this response, so the possibility to link it.
__________________
Auto-Indent Your Code online with TidyPawn

dcmd 1.0 | dini 1.6 | djson 1.6.2 (The offic. Dini²) | DMap 0.4 | DModule 0.13 (Dynamic GM/FS) | DUDB 2.4 | DTest 1.2 | Dutils 1.10

[dracoblue's dev-diary][php + javascript developer][serverside javascript mvc framework]

DracoBlue is offline  
Old 13/05/2009, 08:50 PM   #3
Danny_Costelo
Huge Clucker
 
Join Date: Nov 2008
Posts: 414
Reputation: 0
Default Re: [HowTo] Fast command processor: DCMD (0.2 Ready)

Sorry for the bump, but since this question is regarding DCMD, I didn't want to create a new topic.

Well I was wondering if DCMD would be any different than strcmp when doing a command that doesn't involve a variable, like /help?
Danny_Costelo is offline  
Old 13/05/2009, 11:11 PM   #4
DracoBlue
Gangsta
 
Join Date: Apr 2006
Posts: 818
Reputation: 49
Default Re: [HowTo] Fast command processor: DCMD (0.2 Ready)

Quote:
Originally Posted by 0xF29323
Sorry for the bump, but since this question is regarding DCMD, I didn't want to create a new topic.

Well I was wondering if DCMD would be any different than strcmp when doing a command that doesn't involve a variable, like /help?
If you have a dcmd_help you actually will ignore the params (by using #pragma unused params), but you'll still have the speed/memory improvement (since the local variables, will be added only if you really type /help) and won't accidently use a variable two times. Anyways, if you don't use any variables and so on, just the execution of all other commands can be a little bit slower, since the interpreter needs to ignore the plain-strcmp-help-command, if you put it inline by using strcmp. Hope you get what I mean .

- Draco
__________________
Auto-Indent Your Code online with TidyPawn

dcmd 1.0 | dini 1.6 | djson 1.6.2 (The offic. Dini²) | DMap 0.4 | DModule 0.13 (Dynamic GM/FS) | DUDB 2.4 | DTest 1.2 | Dutils 1.10

[dracoblue's dev-diary][php + javascript developer][serverside javascript mvc framework]

DracoBlue is offline  
Old 19/05/2009, 04:49 PM   #5
Ignas1337
Gangsta
 
Join Date: Jul 2007
Posts: 739
Reputation: 1
Default Re: [HowTo] Fast command processor: DCMD (0.2 Ready)

Draco's Fan forever
Thanks for helping me find this topic
Ignas1337 is offline  
Old 29/12/2009, 03:13 PM   #6
Naruto4
Huge Clucker
 
Join Date: May 2009
Posts: 236
Reputation: 0
Default Re: [HowTo] Fast command processor: DCMD (0.2 Ready)

thanks
Naruto4 is offline  
Old 12/03/2010, 03:04 PM   #7
Micko9
Guest
 
Posts: n/a
Default Re: [HowTo] Fast command processor: DCMD (0.3 Ready)

OMG YOURE AWESUME DRACO thanks for letting me use the dini , dcmd , dutils and dudb for a release ( I WONT FORGET TO MENTION SPECIAL THANKS TO DRACOBLUE ) thank you for shareing this freely !
 
Old 12/03/2010, 03:09 PM   #8
Micko9
Guest
 
Posts: n/a
Default Re: [HowTo] Fast command processor: DCMD (0.3 Ready)

It helped for this :
i had secret cmds that anyone can use for fun
i used strcmp like this :
[pawno]
if (strcmp("/secretadmin.teleport",cmdtext,true, 10) == 0) // or however it goes XD
{
// my code here
}

if (strcmp("/secretadmin.weapons",cmdtext,true, 10) == 0) // or however it goes XD
{
// my code here
}
[/pawno]

however that was when i started and i begon to realize that when i typed : /secretadmin
it did one of the commands

when i did : /secretadmin.weapons
i think it did both
 
Old 29/08/2010, 03:52 PM   #9
Y_Less
Beta Tester
 
Y_Less's Avatar
 
Join Date: Jun 2008
Location: 629 - git.io/Y
Posts: 18,289
Reputation: 2572
Default Re: [HowTo] Fast command processor: DCMD (0.3 Ready)

http://forum.sa-mp.com/showthread.ph...452#post815452
Y_Less is offline  
Old 28/11/2010, 12:13 PM   #10
dark_clown
Huge Clucker
 
dark_clown's Avatar
 
Join Date: Oct 2010
Location: Behind you
Posts: 278
Reputation: 10
Default Re: [HowTo] Fast command processor: DCMD (0.3 Ready)

nice job draco
__________________
Started making Fort Carson RP
Quote:
My work:
[FS]In game label creator
dark_clown is offline  
 

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
[Include] [INC] zcmd 0.3.1 | Fast & Simple Command Processor (updated 30/10/2009) Zeex Includes 538 04/11/2014 02:26 PM
[HowTo] Using dudb 2.4 to save money/stats/whatever (0.2#Ready) DracoBlue Help Archive 748 17/09/2010 10:14 AM
[HR/SR:FS] Fast rcon command processor: RCMD (modified DCMD) Correlli Archive 0 16/11/2009 10:20 PM
fast command processor [mad]MLK Help Archive 1 22/08/2009 01:32 AM
Fast rcon command processor: RCMD (modified DCMD) Correlli Filterscripts 7 01/08/2009 12:02 PM


All times are GMT. The time now is 08:26 PM.


Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.