[Include] y_commands - Most flexible and fastest command processor, now on the YSI wiki
#1

Introduction

This is an update to my old command processing system in YSI. Since then I have steamlined a lot of the code and made it more robust and easier to use. It can also now be used as a drop in replacement for zcmd.
  • Why?
Why do we need another command processing system? ZCMD is already very fast!

y_commands is actually now FASTER than ZCMD and is designed to handle huge numbers of commands. Additionally included in that speed is permission checks (to set exactly who can use the command), a help system, command renaming and removal plus more.
  • Master
This file includes the first preview of my new master system which I will explain in greater detail in a later post - for now don't worry about it beyond what I tell you here.

Download

This library is a part of YSI, which can be found here. Keep your eye on that topic and your server log for updates.

YSI Download Topic

Features
  • Fast commands - This system uses the same CallRemoteFunction used in ZCMD to get good command processing speed.
  • Permissions - The system has in-built support for per-player permissions. No more code like:

    Code:
    CMD:ban(playerid, params[])
    {
        if (gIsAdmin[playerid])
        {
            // Do your code here.
        }
    }
  • Renaming - This system allows you to dynamically rename or remove commands. Imagine a server where English players type "/help", Dutch type "/hulp" and Italian type "/aiuto"!
  • Lists - Using my y_scripting library the command system gathers information about commands in modes. It knows every command you have - you never need to worry about keeping the list in "/commands" updated. Using functions in the system you can list only the commands a single player can use, and if there are multiple language versions of a command it will only list the ones they need:

    Code:
    YCMD:commands(playerid, params[], help)
    {
        if (help)
        {
            SendClientMessage(playerid, 0xFF0000AA, "Lists all the commands a player can use.");
        }
        else
        {
            new
                count = Command_GetPlayerCommandCount(playerid);
            for (new i = 0; i != count; ++i)
            {
                SendClientMessage(playerid, 0xFF0000AA, Command_GetNext(i, playerid));
            }
        }
        return 1;
    }
  • Help - The command system, as shown above, has inbuilt support for a help system. You define the help for a command with that command, making managing your script VASTLY easier. To use this feature from your help command simply do something like:

    Code:
    YCMD:help(playerid, params[], help)
    {
        if (help)
        {
            SendClientMessage(playerid, 0xFF0000AA, "Displays help about your mode.");
        }
        else
        {
            if (isnull(params))
            {
                new
                    str[128];
                SendClientMessage(playerid, 0xFF0000AA, "Welcome to my mode.");
                format(str, sizeof (str), "Type \"/%s [command]\" for more help on a command", Command_GetDisplayNamed("help", playerid));
                SendClientMessage(playerid, 0xFF0000AA, str);
            }
            else
            {
                Command_ReProcess(playerid, params, true);
            }
        }
        return 1;
    }
  • Distribution - Every script on your server which uses this command system is linked. Any script can set who can use any command. If you have a custom admin script as a filterscript this can set the permissions on any command in the main gamemode for example. The "/commands" command above will list all commands on the server, whatever mode they are in.
Use
  • To use the system simply add the following to the top of your mode:

    Code:
    #include <YSI\y_commands>
    #include <YSI\y_master>
    If you already use ZCMD this replaces that line and all commands are already modified (they all also have the "help" parameter added but hidden). The second line allows you to use the commands in multiple scripts. If you do not want this feature DO NOT remove than line, instead add "#define YSI_NO_MASTER" BEFORE the two lines above. There is a reason for doing it this way, but it only applies when using multiple libraries with the master system and will be explained better in the future.
  • To add a command do:

    Code:
    YCMD:me(playerid, params[], help)
    {
        if (help)
        {
            SendClientMessage(playerid, 0xFF0000AA, "Sends an action to other players.");
        }
        else
        {
            new
                str[128];
            if (isnull(params))
            {
                format(str, sizeof (str), "Usage: \"/%s [action]\"", Command_GetDisplayNamed("me", playerid));
                SendClientMessage(playerid, 0xFF0000AA, str);
            }
            else
            {
                GetPlayerName(playerid, str, sizeof (str));
                format(str, sizeof (str), "* %s %s", str, params);
                SendClientMessageToAll(0xFF0000AA, str);
            }
        }
        return 1;
    }
    The syntax for error messages is a little more clumsy as different people can have different names for commands, though if you never use this feature you never need to worry about that.
  • To add an alternate spelling do:

    Code:
    Command_AddAltNamed("help", "aiuto");
    That will add "/aiuto" as a alternate name for "/help", you can then use command permissions to set who can and can't use the command.
  • To set command permissions:

    Code:
    Command_SetPlayerNamed("help", playerid, false);
    That disables the "/help" command for a player - but NOT the "/aiuto" command (if one exists). A language system may look something like:

    Code:
    public OnPlayerLogin(playerid)
    {
        if (gLanguage[playerid] == LANGUAGE_ITALIAN)
        {
            Command_SetPlayerNamed("help", playerid, false);
            Command_SetPlayerNamed("aiuto", playerid, true);
        }
        else
        {
            Command_SetPlayerNamed("help", playerid, true);
            Command_SetPlayerNamed("aiuto", playerid, false);
        }
    }
    That will configure command permissions based on the player's language (assuming an imaginary login system).
Commands

The full list of commands is given below.
  • Command_GetID(funcname[]) - All the examples above used the command's name to set the permissions, if you want you can also use the ID, which this gets.
  • Command_SetPlayer(command, playerid, set) - Enables or disables a player's use of a command by ID.
  • Command_SetPlayerNamed(command[], playerid, set) - Enables or disables a player's use of a command by name.
  • Command_GetPlayer(command, playerid) - Gets a player's use of a command by ID.
  • Command_GetPlayerNamed(command[], playerid) - Gets a player's use of a command by name.
  • Command_AddAlt(oldid, altname[]) - Adds an alternate spelling for a command by ID.
  • Command_AddAltNamed(old[], altname[]) - Adds an alternate spelling for a command by name.
  • Command_ReProcess(playerid, cmdtext[], help) - Call to put text through the command processor, with the help functions enabled or disabled.
  • Command_GetName(id) - Get the name of a command by ID.
  • Command_GetDisplay(command, playerid) - Get the first found command name a player can type to get this functionality.
  • Command_GetDisplayNamed(command[], playerid) - Get the first found command name a player can type to get this functionality by name. For example:

    Code:
    Command_GetDisplayNamed("help", playerid);
    Will return "aiuto" for an Italian player and "help" for an English player.
  • Command_GetPlayerCommandCount(playerid) - Get the number of commands in the system the player can use.
  • Command_GetNext(index, playerid) - Used for looping through all the commands a player can use, not all the commands that exist.
  • Command_SetDeniedReturn(set) - If this is "false" the system will report a command you're not allowed to use as unknown. If it is "true" the system will not run the command but will not send a failure message.
  • Command_GetDeniedReturn() - Get the denied return current status.
Timings

This graph is a comparison between zcmd, y_command and fcmd. Note that strcmp based command processors are excluded for brevity - they are no-where near this speed.

Currently there is no graph displaying the speed comparison. You can make one yourself, or if there is a demand for it I might attempt to make one.

The code for this test can be found here:

http://y-less.pastebin.com/HLgGVynL
http://y-less.pastebin.com/8Cp2p5Pv

The batch command to build the required scripts is:

Code:
FOR /L %%i IN (0, 1, 2703) DO pawncc.exe "..\gamemodes\cmdtest.pwn" -;+ -\ -(+ CMD_NUM=%%i -o..\gamemodes\cmdtest_%%i
Credits
I am reposting this include (made by Y_Less) with the thought of what he said to several members of the community. Everything that could help someone should not be deleted from the forums, which is something I agree with since I learned a lot by reading the tutorials on here. He made a lot of things that are used by lots of servers and that knowledge should not be lost for present and future developers.
Reply
#2

Are you or any of those that are re-posting his threads going to continue the development of such includes? If not, then there should be someone who is whiling to do so.
Reply
#3

Quote:
Originally Posted by SickAttack
View Post
Are you or any of those that are re-posting his threads going to continue the development of such includes? If not, then there should be someone who is whiling to do so.
I can name three people already doing so.
Reply
#4

Quote:
Originally Posted by SickAttack
View Post
Are you or any of those that are re-posting his threads going to continue the development of such includes? If not, then there should be someone who is whiling to do so.
I'm not working on this include. I'm only trying to find and repost information that may be useful to beginners. There are (I believe) three or four other people working on YSI, though.
Reply
#5

How to write unknown command error?
Reply
#6

http://github.com/Misiur/YSI-Includes/issues/18
Reply
#7

Quote:
Originally Posted by eco1999
View Post
How to write unknown command error?
in YSI 3.0 :
PHP Code:
public OnPlayerCommandPerformed(playeridcmdtext[], success)
{
    if (!
success// You can also write it as if (success == 0)
    
{
        
// Your code here 
    
}
    return 
1;

in YSI 4.0 or newer:
PHP Code:
/*
        Error & Return type
    COMMAND_ZERO_RET      = 0 , // The command returned 0.
    COMMAND_OK            = 1 , // Called corectly.
    COMMAND_UNDEFINED     = 2 , // Command doesn't exist.
    COMMAND_DENIED        = 3 , // Can't use the command.
    COMMAND_HIDDEN        = 4 , // Can't use the command don't let them know it exists.
    COMMAND_NO_PLAYER     = 6 , // Used by a player who shouldn't exist.
    COMMAND_DISABLED      = 7 , // All commands are disabled for this player.
    COMMAND_BAD_PREFIX    = 8 , // Used "/" instead of "#", or something similar.
    COMMAND_INVALID_INPUT = 10, // Didn't type "/something".
*/
public e_COMMAND_ERRORS:OnPlayerCommandPerformed(playeridcmdtext[], e_COMMAND_ERRORS:success)
{
    switch (
success)
    {
        case 
COMMAND_UNDEFINED:
        {
             
// Your code here.
        
}
    }
    return 
COMMAND_OK;

Reply
#8

Quote:
Originally Posted by RaeF
View Post
in YSI 3.0 :
PHP Code:
public OnPlayerCommandPerformed(playeridcmdtext[], success)
{
    if (!
success// You can also write it as if (success == 0)
    
{
        
// Your code here 
    
}
    return 
1;

in YSI 4.0 or newer:
PHP Code:
/*
        Error & Return type
    COMMAND_ZERO_RET      = 0 , // The command returned 0.
    COMMAND_OK            = 1 , // Called corectly.
    COMMAND_UNDEFINED     = 2 , // Command doesn't exist.
    COMMAND_DENIED        = 3 , // Can't use the command.
    COMMAND_HIDDEN        = 4 , // Can't use the command don't let them know it exists.
    COMMAND_NO_PLAYER     = 6 , // Used by a player who shouldn't exist.
    COMMAND_DISABLED      = 7 , // All commands are disabled for this player.
    COMMAND_BAD_PREFIX    = 8 , // Used "/" instead of "#", or something similar.
    COMMAND_INVALID_INPUT = 10, // Didn't type "/something".
*/
public e_COMMAND_ERRORS:OnPlayerCommandPerformed(playeridcmdtext[], e_COMMAND_ERRORS:success)
{
    switch (
success)
    {
        case 
COMMAND_UNDEFINED:
        {
             
// Your code here.
        
}
    }
    return 
COMMAND_OK;

It didn't work. I'm using YSI 4.0.

Code:
public e_COMMAND_ERRORS:OnPlayerCommandPerformed(playerid, cmdtext[], e_COMMAND_ERRORS:success)
{
    switch (success)
    {
        case COMMAND_UNDEFINED:
        {
            SendErrorMessage(playerid, "Bu komut mevcut değil. Komut listesini gцrmek iзin /yardim yazın.");
        }
    }
    return COMMAND_OK;
}
Reply
#9

Ohh sorry, change OnPlayerCommandPerformed to OnPlayerCommandReceived, i dont know what make it different, but it should work.


Quote:
Originally Posted by eco1999
View Post
It didn't work. I'm using YSI 4.0.

Code:
public e_COMMAND_ERRORS:OnPlayerCommandPerformed(playerid, cmdtext[], e_COMMAND_ERRORS:success)
{
    switch (success)
    {
        case COMMAND_UNDEFINED:
        {
            SendErrorMessage(playerid, "Bu komut mevcut değil. Komut listesini gцrmek iзin /yardim yazın.");
        }
    }
    return COMMAND_OK;
}
Reply
#10

Hmm.. I decided to use YCMD in my server as a cmd processor. but, it doesn't show anything. I made a cmd like '/shop'
Reply
#11

Quote:
Originally Posted by justice96
Посмотреть сообщение
Hmm.. I decided to use YCMD in my server as a cmd processor. but, it doesn't show anything. I made a cmd like '/shop'
You should probably show us.
Reply
#12

How does the help parameter work? Does that show up if isnull(params)?
Reply
#13

Quote:
Originally Posted by Crayder
Посмотреть сообщение
You should probably show us.
Код:
#include <YSI/y_commands>

YCMD:shop(playerid,params[],help)
{
    new listtext[512],substr[40];
	if(help)
	{
	    SEM(playerid,"CMDINFO: Displays shop to buy special weapons!");
	    return 1;
	}
	forex(i, 13)
	{
	    if(PlayerInfo[playerid][WeaponsPurchased][i])
	    {
	        format(substr,sizeof(substr),"%s - {33AA33}PURCHASED\n",GunNames[SelledGun[i][Weaponid]]);
	    }
	    else
	    {
            format(substr,sizeof(substr),"%s - $%d\n",GunNames[SelledGun[i][Weaponid]],SelledGun[i][Price]);
	    }
	    strcat(listtext,substr,sizeof(listtext));
	}
	ShowPlayerDialog(playerid,DIALOG_BUY_GUN,DIALOG_STYLE_LIST,"Guns Shop",listtext,"Buy","Exit");
	return 1;
}
Reply
#14

Try debug your code maybe like this:
Код:
YCMD:shop(playerid,params[],help)
{
    sendclientmessage(playerid, -1, "Command Called");
    new listtext[512],substr[40];
	if(help)
	{
            sendclientmessage(playerid, -1, "Help Called");
	    SEM(playerid,"CMDINFO: Displays shop to buy special weapons!");
	    return 1;
	}
	forex(i, 13)
	{
	    if(PlayerInfo[playerid][WeaponsPurchased][i])
	    {
	        format(substr,sizeof(substr),"%s - {33AA33}PURCHASED\n",GunNames[SelledGun[i][Weaponid]]);
	    }
	    else
	    {
            format(substr,sizeof(substr),"%s - $%d\n",GunNames[SelledGun[i][Weaponid]],SelledGun[i][Price]);
	    }
	    strcat(listtext,substr,sizeof(listtext));
	}
	ShowPlayerDialog(playerid,DIALOG_BUY_GUN,DIALOG_STYLE_LIST,"Guns Shop",listtext,"Buy","Exit");
	return 1;
}
If you don't get the message, that's the real y_commands problem, do you use OnPlayerCommandPerfomed or OnPlayerCommandReceived??
Reply
#15

Quote:
Originally Posted by RaeF
Посмотреть сообщение
Try debug your code maybe like this:
Код:
YCMD:shop(playerid,params[],help)
{
    sendclientmessage(playerid, -1, "Command Called");
    new listtext[512],substr[40];
	if(help)
	{
            sendclientmessage(playerid, -1, "Help Called");
	    SEM(playerid,"CMDINFO: Displays shop to buy special weapons!");
	    return 1;
	}
	forex(i, 13)
	{
	    if(PlayerInfo[playerid][WeaponsPurchased][i])
	    {
	        format(substr,sizeof(substr),"%s - {33AA33}PURCHASED\n",GunNames[SelledGun[i][Weaponid]]);
	    }
	    else
	    {
            format(substr,sizeof(substr),"%s - $%d\n",GunNames[SelledGun[i][Weaponid]],SelledGun[i][Price]);
	    }
	    strcat(listtext,substr,sizeof(listtext));
	}
	ShowPlayerDialog(playerid,DIALOG_BUY_GUN,DIALOG_STYLE_LIST,"Guns Shop",listtext,"Buy","Exit");
	return 1;
}
If you don't get the message, that's the real y_commands problem, do you use OnPlayerCommandPerfomed or OnPlayerCommandReceived??
Debugged.
Код:
YCMD:testme(playerid, params[], help)
{
    #pragma unused params, help
    SendClientMessage(playerid, -1, "/testme command works");
    return 1;
}
Still the same. I ain't get the message. but, I haven't added OnPlayerCommandPerformed or OnPlayerCommandReceived in my script
Reply
#16

Quote:
Originally Posted by JaydenJason
Посмотреть сообщение
How does the help parameter work? Does that show up if isnull(params)?
The help parameter is like an alternate version of the command.

To use it, do something like this:
pawn Код:
YCMD:help(playerid, params[], help)
{
    if(help)
        return SendClientMessage(playerid, -1, "This is the help command, use it to get extra information on commands.");
   
    if(strlen(params))
        Command_ReProcess(playerid, params, true);
    else
        SendClientMessage(playerid, -1, "Error [SYNTAX]: /help <Command Name>");
   
    return 1;
}
Reply
#17

Is there any way to return commands like in ZCMD?

I mean this:
Код:
CMD:command(playerid, params[])
{
	return cmd_anothercommand(playerid, params);
}
Will Command_ReProcess make the job?
Reply
#18

Quote:
Originally Posted by Kruzz
Посмотреть сообщение
Is there any way to return commands like in ZCMD?

I mean this:
Код:
CMD:command(playerid, params[])
{
	return cmd_anothercommand(playerid, params);
}
Will Command_ReProcess make the job?
Yes, but not on it's own. Also it's better to let YCMD do that itself. The alternative is to do this:
pawn Код:
#define CallCommand(%0,%1) CallLocalFunction("OnPlayerCommandText","is",%0,%1)

#define Y_COMMANDS_NO_IPC
#include <YSI\y_commands>
No it's not the best, and if you don't know what IPC is then you SHOULD look at the source of YCMD (mainly the impl.inc for it). It will work. To use it just do this:
pawn Код:
/*Your Code (and yes YCMD can handle ZCMD syntax):
CMD:command(playerid, params[])
{
    return CallCommand(playerid, params);
}
My Code:*/

CMD:fakecmd(playerid, params[])
{
    new cmd_and_params[136], targetplayer;
    sscanf(params, "us[136]", targetplayer, cmd_and_params);
    return CallCommand(targetplayer, cmd_and_params);
}
Reply
#19

Quote:
Originally Posted by Kruzz
Посмотреть сообщение
Is there any way to return commands like in ZCMD?

I mean this:
Код:
CMD:command(playerid, params[])
{
	return cmd_anothercommand(playerid, params);
}
Will Command_ReProcess make the job?
PHP код:
Command_AddAltNamed("command""anothercommand"); 
Reply
#20

Quote:
Originally Posted by _Zume
Посмотреть сообщение
PHP код:
Command_AddAltNamed("command""anothercommand"); 
Yes there is definitely this. My answer was for anything that alternative names doesn't apply to. Like calling the commands from something remote.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)