01.09.2011, 11:37
(
Последний раз редактировалось Jafet_Macario; 05.09.2011 в 08:55.
)
How to create commands with ZCMD & sscanf.
Introduction(This is my first tutorial ^^)
ZCMD is a fast and simple command processor made by Zeex so I will teach you guys who don't know to work with.
Sscanf is string splitting routine made by ******.
What do we need?
First, we will need the ZCMD include that you can download from HERE and the
sscanf include and plugin that can be downloaded from HERE.
Steps
Copy zcmd.inc and paste it into your pawno\includes folder.
Copy sscanf2.inc and paste it into your pawno\includes folder.
If you're using windows, copy sscanf.dll in the plugins folder.(If you don't
have one, create it).Open up server.cfg and add "sscanf" in the plugins line:
Код:
plugins sscanf
one, create it).Open up server.cfg and add "sscanf.so" in the plugins line:
Код:
plugins sscanf.so
Usage
Open up your gamemode, at the top of the script include sscanf2 and zcmd:
pawn Код:
#include <sscanf2>
#include <zcmd>
into your gamemode so you can use everything it has.(The files that you just copied)
REMEMBER: ZCMD commands should not be inside any callback.Callbacks are the ones already inside of your gamemode, for example:
pawn Код:
public OnPlayerSpawn(playerid)
{
return 1;
}
Every command must start with:
pawn Код:
CMD:your_command(playerid, params[])
pawn Код:
COMMAND:your_command(playerid, params[])
pawn Код:
command(mycommand, playerid, params[])// or cmd(mycommand, playerid, params[])
pawn Код:
CMD:your_command(playerid, params[])
So, the params are the parameters string while playerid is an ID of the player
who execute this command.(Sends)
NOTE: You can also use "o" instead of "params", example:
pawn Код:
CMD:your_command(playerid, o[])
{
// Here will be our code.
return 1;
}
pawn Код:
CMD:helpme(playerid, params[])
{
// Here will be our code.
return 1;
}
pawn Код:
CMD:helpme(playerid, params[])
{
SendClientMessage(playerid, 0xFFFFFFF, "My first command ^^ ");
return 1;
}
Код:
My first command ^^
Note: I added the color " 0xFFFFFFF " as default, you add there what color you want(not hex).
Now, let's also use sscanf, let's start by creating a /heal [PlayerID] command.
pawn Код:
CMD:heal(playerid, params[])
{
new targetid; //Here we declare the target id.The one on which the command will be executed.
if(sscanf(params,"u", targetid)) return SendClientMessage(playerid, 0xFFFFFFF,"Syntax error.Correct usage: /heal [PlayerID]");
/*We need to split the parameters, "u" is the specifier that stands for Player Name/ID,also
sscanf will check if the sender uses the correct usage of the command, if they use something wrong
like: " /heal " will return the message above.(Syntax error...)*/
if(!IsPlayerConnected(targetid)) return SendClientMessage(playerid, 0xFFFFFFF,"That player is not connected to the server!");
//This actually will check if the player on which you try to execute the command is connected to the server, if not you will recieve the message above.(That player...)
// Notice, before IsPlayerConnected I've put a " ! " this means " NOT ", so if(Not player connected(targetid))... return message, more control structures can be found a little bit more down.
SetPlayerHealth(targetid, 100); //Here is the action, this will heal the targeted player, for example:Dave has 30 health, you execute /heal Dave and he will be healed to 100.
return 1;
}
So when we use sscanf in a command we always must use this formula:
pawn Код:
if(sscanf(params,
pawn Код:
" specifier_here "
pawn Код:
"specifier_here", targetid))
All the specifiers:
Quote:
Код:
Format Use L(true/false) Optional logical truthity l Logical truthity B(binary) Optional binary number b Binary number N(any format number) Optional number n Number C(character) Optional character c Character I(integer) Optional integer i Integer D(integer) Optional integer d Integer H(hex value) Optional hex number h Hex number O(octal value) Optional octal value o Octal value F(float) Optional floating point number f Floating point number G(float/INFINITY/-INFINITY/NAN/NAN_E) Optional float with IEEE definitions g Float with IEEE definitions { Open quiet section } Close quiet section P<delimiter> Invalid delimiter change p<delimiter> Delimiter change Z(string)[length] Invalid optional string z(string)[length] Deprecated optional string S(string)[length] Optional string s[length] String U(name/id) Optional user (bot/player) u User (bot/player) Q(name/id) Optional bot (bot) q Bot (bot) R(name/id) Optional player (player) r Player (player) A<type>(default)[length] Optional array of given type a<type>[length] Array of given type E<specification>(default) Optional enumeration of given layout e<specification> Enumeration of given layout 'string' Search string % Deprecated optional specifier prefix |
pawn Код:
CMD:heal(playerid, params[])
{
new targetid;
if(sscanf(params,"u", targetid)) return SendClientMessage(playerid, 0xFFFFFFF,"Syntax error.Correct usage: /heal [PlayerID]");
if(!IsPlayerConnected(targetid)) return SendClientMessage(playerid, 0xFFFFFFF,"That player is not connected to the server!");
SetPlayerHealth(targetid, 100);
return 1;
}
pawn Код:
CMD:healplayer(playerid, params[])
{
return cmd_heal(playerid, params);
}
Now, let's create a command with more parameters, for example, /givemoney.So we will start with this:
pawn Код:
CMD:givemoney(playerid, params[])
{
//Here will be our codes
return 1;
}
pawn Код:
CMD:givemoney(playerid, params[])
{
new targetid;
new ammount;
return 1;
}
pawn Код:
CMD:givemoney(playerid, params[])
{
new targetid, ammount;
return 1;
}
pawn Код:
CMD:givemoney(playerid, params[])
{
new targetid, ammount;
if(sscanf(params,"ui", targetid, ammount)) return SendClientMessage(playerid, 0xFFFFFFF,"Syntax error.Correct usage: /givemoney [PlayerID] [Ammount]");
return 1;
}
As you see, when you use multiple specifiers, you don't need space between them, you just put them inside the inveted commas,
pawn Код:
" specifier_here_specifier_here "
Let's make this command only for RCON Admins.For that you gotta check if the player is logged into rcon with:
pawn Код:
IsPlayerAdmin
pawn Код:
CMD:givemoney(playerid, params[])
{
new targetid, ammount;
if(sscanf(params,"ui", targetid, ammount)) return SendClientMessage(playerid, 0xFFFFFFF,"Syntax error.Correct usage: /givemoney [PlayerID] [Ammount]");
if(!IsPlayerAdmin(playerid)) return SendClientMessage(playerid, 0xFFFFFFF,"Error: This command is only for RCON Admins");
return 1;
}
Now, let's check if the player who we want to give money(targetid) is online on your server, so we do it like we did in the /heal command.
pawn Код:
CMD:givemoney(playerid, params[])
{
new targetid, ammount;
if(sscanf(params,"ui", targetid, ammount)) return SendClientMessage(playerid, 0xFFFFFFF,"Syntax error.Correct usage: /givemoney [PlayerID] [Ammount]");
if(!IsPlayerAdmin(playerid)) return SendClientMessage(playerid, 0xFFFFFFF,"Error: This command is only for RCON Admins");
if(!IsPlayerConnected(targetid)) return SendClientMessage(playerid, 0xFFFFFFF,"That player is not connected to your server!");
return 1;
}
pawn Код:
GivePlayerMoney
pawn Код:
CMD:givemoney(playerid, params[])
{
new targetid, ammount;
if(sscanf(params,"ui", targetid, ammount)) return SendClientMessage(playerid, 0xFFFFFFF,"Syntax error.Correct usage: /givemoney [PlayerID] [Ammount]");
if(!IsPlayerAdmin(playerid)) return SendClientMessage(playerid, 0xFFFFFFF,"Error: This command is only for RCON Admins");
if(!IsPlayerConnected(targetid)) return SendClientMessage(playerid, 0xFFFFFFF,"That player is not connected to your server!");
GivePlayerMoney(targetid, ammount); // So it will give the targetid the ammount you want.
return 1;
}
pawn Код:
CMD:ooc(playerid, params[])
{
return 1;
}
You don't know what's a string? You can find out more here:https://sampwiki.blast.hk/wiki/Scripting_Basics#Strings
pawn Код:
CMD:ooc(playerid, params[])
{
new sendername[MAX_PLAYER_NAME], string[56];
return 1;
}
pawn Код:
string[56]
The variable called "sendername[MAX_PLAYER_NAME]" will hold the name of the player. The variable has an array ([MAX_PLAYER_NAME]). MAX_PLAYER_NAME it's 24.24 is the maximum name lenght in SA-MP.
An array is lots of variables (where you store data to read and write) clumped together to store lots of data at once.
Now we have to get the sender's name with the function
pawn Код:
GetPlayerName
pawn Код:
CMD:ooc(playerid, params[])
{
new sendername[MAX_PLAYER_NAME], string[56];
GetPlayerName(playerid, sendername, sizeof(sendername));
return 1;
}
The "sizeof(sendername)" it gets the size of the array in the variable called "sendername" which in this case is MAX_PLAYER_NAME.(24)
Now, let's check if the params are null.
pawn Код:
CMD:ooc(playerid, params[])
{
new sendername[MAX_PLAYER_NAME], string[56];
GetPlayerName(playerid, sendername, sizeof(sendername));
if(isnull(params)) return SendClientMessage(playerid, 0xFFFFFFF,"Syntax error.Correct usage: /ooc [text]"); // This will check if the player types just: "/ooc" he will get the following syntax message.
return 1;
}
pawn Код:
CMD:ooc(playerid, params[])
{
new sendername[MAX_PLAYER_NAME], string[56];
GetPlayerName(playerid, sendername, sizeof(sendername));
if(isnull(params)) return SendClientMessage(playerid, 0xFFFFFFF,"Syntax error.Correct usage: /ooc [text]");
format(string, sizeof(string), "(( %s: %s ))", sendername, params);
return 1;
}
"sizeof(string)" will get the size of the string, in this case we declared it 56.
"%s" is a placeholder for the player's name and the second will be the result.
In the end we added "sendername", this is the variable containing the player's name and "params" for the result.
So, it will tell the script that "%s" is a placeholder for player's name, and the second will be the result, let's now send the message to all online players with the fuction:
pawn Код:
SendClientMessageToAll
pawn Код:
CMD:ooc(playerid, params[])
{
new sendername[MAX_PLAYER_NAME], string[56];
GetPlayerName(playerid, sendername, sizeof(sendername));
if(isnull(params)) return SendClientMessage(playerid, 0xFFFFFFF,"Syntax error.Correct usage: /ooc [text]");
format(string, sizeof(string), "(( %s: %s ))", sendername, params);
SendClientMessageToAll(0xFFFFFFF, string);
return 1;
}
pawn Код:
SendClientMessageToAll(color, "message");
Done, the command it's finished, what about typing "/o [text]" instead of "/ooc [text]" ? As I showed above:
pawn Код:
CMD:o(playerid, params[])
{
return cmd_ooc(playerid, params);
}
Код:
(( Dave: Hello ))
Many people use 256 in their arrays,but the maximum length of client messages is 128.Also, don't use 128 if you want the format to be shorter.
Another placeholders:
Код:
%b Inserts a number at this position in binary radix %c Inserts a single character. %d Inserts an integer (whole) number %f Inserts a floating point number. %i Inserts an integer. %s Inserts a string. ( We used this ) %x Inserts a number in hexadecimal notation. %% Inserts the literal '%'
pawn Код:
CMD:setskin(playerid, params[])
{
//Here will be our codes
return 1;
}
pawn Код:
CMD:setskin(playerid, params[])
{
new targetid, skin, sendername[MAX_PLAYER_NAME], receivername[MAX_PLAYER_NAME], string[128];
return 1;
}
pawn Код:
CMD:setskin(playerid, params[])
{
new targetid, skin, sendername[MAX_PLAYER_NAME], receivername[MAX_PLAYER_NAME], string[128];
if(sscanf(params,"ui", targetid, skin)) return SendClientMessage(playerid, 0xFFFFFFF,"Syntax error.Correct usage: /setskin [PlayerID] [Skinmodel]");
if(!IsPlayerAdmin(playerid)) return SendClientMessage(playerid, 0xFFFFFFF,"This command is only for RCON Admins.");
return 1;
}
pawn Код:
CMD:setskin(playerid, params[])
{
new targetid, skin, sendername[MAX_PLAYER_NAME], receivername[MAX_PLAYER_NAME], string[128];
if(sscanf(params,"ui", targetid, skin)) return SendClientMessage(playerid, 0xFFFFFFF,"Syntax error.Correct usage: /setskin [PlayerID] [Skinmodel]");
if(!IsPlayerAdmin(playerid)) return SendClientMessage(playerid, 0xFFFFFFF,"This command is only for RCON Admins.");
if(skin > 299 || skin < 1) return SendClientMessage(playerid, 0xFFFFFFF,"Wrong Skin ID! Available ID's: 1-299");
return 1;
}
Lets now also check if the targetid(the one on which the command will be executed) is on your server.
pawn Код:
CMD:setskin(playerid, params[])
{
new targetid, skin, sendername[MAX_PLAYER_NAME], receivername[MAX_PLAYER_NAME], string[128];
if(sscanf(params,"ui", targetid, skin)) return SendClientMessage(playerid, 0xFFFFFFF,"Syntax error.Correct usage: /setskin [PlayerID] [Skinmodel]");
if(!IsPlayerAdmin(playerid)) return SendClientMessage(playerid, 0xFFFFFFF,"This command is only for RCON Admins.");
if(skin > 299 || skin < 1) return SendClientMessage(playerid, 0xFFFFFFF,"Wrong Skin ID! Available ID's: 1-299");
if(!IsPlayerConnected(targetid)) return SendClientMessage(playerid, 0xFFFFFFF,"That player is not connected to your server");
return 1;
}
pawn Код:
CMD:setskin(playerid, params[])
{
new targetid, skin, sendername[MAX_PLAYER_NAME], receivername[MAX_PLAYER_NAME], string[128];
if(sscanf(params,"ui", targetid, skin)) return SendClientMessage(playerid, 0xFFFFFFF,"Syntax error.Correct usage: /setskin [PlayerID] [Skinmodel]");
if(!IsPlayerAdmin(playerid)) return SendClientMessage(playerid, 0xFFFFFFF,"This command is only for RCON Admins.");
if(skin > 299 || skin < 1) return SendClientMessage(playerid, 0xFFFFFFF,"Wrong Skin ID! Available ID's: 1-299");
if(!IsPlayerConnected(targetid)) return SendClientMessage(playerid, 0xFFFFFFF,"That player is not connected to your server");
GetPlayerName(playerid, sendernamename, sizeof(sendername));
GetPlayerName(targetid, receivername,sizeof(receivername));
return 1;
}
pawn Код:
CMD:setskin(playerid, params[])
{
new targetid, skin, sendername[MAX_PLAYER_NAME], receiver[MAX_PLAYER_NAME], string[128];
if(sscanf(params,"ui", targetid, skin)) return SendClientMessage(playerid, 0xFFFFFFF,"Syntax error.Correct usage: /setskin [PlayerID] [Skinmodel]");
if(!IsPlayerAdmin(playerid)) return SendClientMessage(playerid, 0xFFFFFFF,"This command is only for RCON Admins.");
if(skin > 299 || skin < 1) return SendClientMessage(playerid, 0xFFFFFFF,"Wrong Skin ID! Available ID's: 1-299");
if(!IsPlayerConnected(targetid)) return SendClientMessage(playerid, 0xFFFFFFF,"That player is not connected to your server");
GetPlayerName(playerid, sendernamename, sizeof(sendername));
GetPlayerName(targetid, receivername,sizeof(receivername));
format(string, sizeof(string),"Your skin have been set to model %d by admin %s", skin, sendername);
SeneClientMessage(targetid, 0xFFFFFF, string); // Note, this message will be send to the targetid
format(string, sizeof(string),"You have set %s skin to model %d", receivername, skin);
SendClientMessage(playerid, 0xFFFFFF, string); // This will be send to the one who execute the command
return 1;
}
The only thing is new here, it's the operator "||" and the thing to forbidden another numbers, the rest you know.
Last thing we gotta do, it is to set the target the skin ID the sender want to, so we use the function
pawn Код:
SetPlayerSkin
pawn Код:
CMD:setskin(playerid, params[])
{
new targetid, skin, sendername[MAX_PLAYER_NAME], receiver[MAX_PLAYER_NAME], string[128];
if(sscanf(params,"ui", targetid, skin)) return SendClientMessage(playerid, 0xFFFFFFF,"Syntax error.Correct usage: /setskin [PlayerID] [Skinmodel]");
if(!IsPlayerAdmin(playerid)) return SendClientMessage(playerid, 0xFFFFFFF,"This command is only for RCON Admins.");
if(skin > 299 || skin < 1) return SendClientMessage(playerid, 0xFFFFFFF,"Wrong Skin ID! Available ID's: 1-299");
if(!IsPlayerConnected(targetid)) return SendClientMessage(playerid, 0xFFFFFFF,"That player is not connected to your server");
GetPlayerName(playerid, sendernamename, sizeof(sendername));
GetPlayerName(targetid, receivername,sizeof(receivername));
format(string, sizeof(string),"Your skin have been set to model %d by admin %s", skin, sendername);
SeneClientMessage(targetid, 0xFFFFFF, string);
format(string, sizeof(string),"You have set %s skin to model %d", receivername, skin);
SendClientMessage(playerid, 0xFFFFFF, string);
SetPlayerSkin(targetid, skin); // This will set the target the skin ID the sender want to
return 1;
}
pawn Код:
CMD:givemoney(playerid, params[])
{
new targetid, ammount;
if(sscanf(params,"ui", targetid, ammount)) return SendClientMessage(playerid, 0xFFFFFFF,"Syntax error.Correct usage: /givemoney [PlayerID] [Ammount]");
if(!IsPlayerAdmin(playerid)) return SendClientMessage(playerid, 0xFFFFFFF,"Error: This command is only for RCON Admins");
if(!IsPlayerConnected(targetid)) return SendClientMessage(playerid, 0xFFFFFFF,"That player is not connected to your server!");
GivePlayerMoney(targetid, ammount);
return 1;
}
CMD:ooc(playerid, params[])
{
new sendername[MAX_PLAYER_NAME], string[56];
GetPlayerName(playerid, sendername, sizeof(sendername));
if(isnull(params)) return SendClientMessage(playerid, 0xFFFFFFF,"Syntax error.Correct usage: /ooc [text]");
format(string, sizeof(string), "(( %s: %s ))", sendername, params);
SendClientMessageToAll(0xFFFFFFF, string);
return 1;
}
CMD:heal(playerid, params[])
{
new targetid;
if(sscanf(params,"u", targetid)) return SendClientMessage(playerid, 0xFFFFFFF,"Syntax error.Correct usage: /heal [PlayerID]");
if(!IsPlayerConnected(targetid)) return SendClientMessage(playerid, 0xFFFFFFF,"That player is not connected to the server!");
SetPlayerHealth(targetid, 100);
return 1;
}
CMD:healplayer(playerid, params[])
{
return cmd_heal(playerid, params);
}
CMD:o(playerid, params[])
{
return cmd_ooc(playerid, params);
}
CMD:setskin(playerid, params[])
{
new targetid, skin, sendername[MAX_PLAYER_NAME], receiver[MAX_PLAYER_NAME], string[128];
if(sscanf(params,"ui", targetid, skin)) return SendClientMessage(playerid, 0xFFFFFFF,"Syntax error.Correct usage: /setskin [PlayerID] [Skinmodel]");
if(!IsPlayerAdmin(playerid)) return SendClientMessage(playerid, 0xFFFFFFF,"This command is only for RCON Admins.");
if(skin > 299 || skin < 1) return SendClientMessage(playerid, 0xFFFFFFF,"Wrong Skin ID! Available ID's: 1-299");
if(!IsPlayerConnected(targetid)) return SendClientMessage(playerid, 0xFFFFFFF,"That player is not connected to your server");
GetPlayerName(playerid, sendernamename, sizeof(sendername));
GetPlayerName(targetid, receivername,sizeof(receivername));
format(string, sizeof(string),"Your skin have been set to model %d by admin %s", skin, sendername);
SeneClientMessage(targetid, 0xFFFFFF, string);
format(string, sizeof(string),"You have set %s skin to model %d", receivername, skin);
SendClientMessage(playerid, 0xFFFFFF, string);
SetPlayerSkin(targetid, skin);
return 1;
}
Looked a bit on wiki at some stuff.
Special thanks to:
****** for his sscanf.
Zeex for his zcmd.
End
Hope this is usefull for newbies.If you didn't understand something, or I missed anything please reply.