Harry Slice
2nd June 2014, 05:49 AM
Hi,
First off I would highly recommend you to read James' tutorial: Click here (http://www.gta-sarp.com/forums/showthread.php?103437-Scripting-guide), his tutorial is great to start to understand the basics of Pawn.
I'll be talking on my tutorial about commands which are made with both ZCMD and SSCANF.
Link to ZCMD: Click here! (http://forum.sa-mp.com/showthread.php?t=91354)
Link to SSCANF: Click here! (http://forum.sa-mp.com/showthread.php?t=120356)
Contents:
1.0 - What are ZCMD and SSCANF?
1.1 - What is ZCMD?
1.2 - What is SSCANF?
2.0 - First commands!
2.1 - Ban command!
2.2 - Suggestion!
2.3 - Advanced /report command
1.1: What is ZCMD? ZCMD is a command processor in a include which has been created by Zeex, it is one of the fastest command processors out there.
1.2: What is SSCANF? SSCANF is a plugin that takes a string and extracts different types of data from it., I'do highly recommend to read this: Click here! (https://github.com/Y-Less/sscanf/wiki), it will make you understand it easier.
2.1: To make a /ban command you need one include and one plugin: ZCMD & SSCANF.
Okay let's go to the code, this is going to be the base where we work from:
Needed functions for this command:
stock PlayerRPName(playerid)
{
new name[MAX_PLAYER_NAME];
strmid(name, str_replace('_', ' ', ReturnPlayerName(playerid)), 0, MAX_PLAYER_NAME); // Removes the underscore between the player's forename and surname
return name; // Returns the new name without the '_'
}
stock ReturnPlayerName(playerid)
{
new name[MAX_PLAYER_NAME+1]; // Making a new string
GetPlayerName(playerid, name, sizeof(name)); // Get's the player's name.
return name; // Returns it
}
Due to a security update from 0.3x they have decided that when there is being called that a player is kicked/banned, he will get kicked/banned before any other functions, therefore you have to delay the kick/ban with a delay of 1 second so he can recieves the clientmessage about him being kicked/banned.
Therefore you need this(This is what the timer does when it's being called):
forward BanTimer(playerid);
public BanTimer(playerid)
{
return Ban(playerid);
}
It'll become something like this:
CMD:ban(playerid, params[])
{
if(IsPlayerAdmin(playerid)) // Checks if the player who wrote the command is admin if so, continue!
{
new userid, reason[128], string[128]; // userid = the target's playerid, reason = his ban reason, string = we will format our clientmessages into that!
if (sscanf(params, "us[128]", userid, reason)) // This will check wether the /ban command contains a player & string.
return SendClientMessage(playerid, 0xFFFFFFFF, "/ban [playerid] [reason]"); // If not, it will send the synthaxmessage!
format(string, sizeof(string), "AdmCmd: %s was banned by %s, reason: %s", PlayerRPName(userid), PlayerRPName(playerid), reason); // Formats the string!
SendClientMessageToAll(0xFF6347AA, string); // Send a global message to every player that the player has been banned.
SetTimerEx("BanTimer", 1000, false, "i", userid); // Sets a timer on the userid, banning him when 1 sec passed to he is able to see his ban reason.
}
return 1; // Just to know that the command has been recieved.
}
Image:
http://i58.tinypic.com/apiiw1.png
2.2: Suggest on this thread where you would like to see a tutorial about, I'll take everything, I can better spend my time by making the things the people want instead of taking random commands that most people can make from theirselves.
2.3: Okay, thanks for the suggestion in the first place, we will use the functions we used last time again, to get the player's name ect, we will be using the foreach include by Y_Less, it's a better loop than the regular one.
We will be using an enumerator to save the player's report text! Here is the code to make a new enumerator!
enum _AccountData
{
pReportText[128]
};
new AccountData[MAX_PLAYERS][_AccountData];
We will have to reset the string at, under OnPlayerConnect add:
format(AccountData[playerid][pReportText], 5, "None"); // Clears it!
The command will look like this:
IMAGE:
http://i59.tinypic.com/331owlx.png
Text:
CMD:report(playerid, params[])
{
new string[128], reason[128]; // string = string to format for the clientmessage, reason = /report [text]!
if (sscanf(params, "s[128]", reason)) // This will check wether the /report command contains a string.
return SendClientMessage(playerid, 0xFFFFFFFF, "USAGE: /report [text]"); // If not, it will send the synthaxmessage!
if(AccountData[playerid][pReportText]) return SendClientMessage(playerid, 0xFFFFFFF, "You already got a pending report!"); // Checking if the player got a report
SendClientMessage(playerid, "Your report message has been sent to online administrators."); // Sends the client the the player who wrote the comamnd!
format(string, sizeof(string), "Report from [%d]%s: %s", playerid, PlayerRPName(playerid), reason); // Make the message correctly to send it to the admins
format(AccountData[playerid][pReportText], 128, "%s", reason); // Adds the reason to his reporttext variable!
foreach(Player, i)
{
if (IsPlayerAdmin(i)) // Check if the player is rcon admin, if so continue!
SendClientMessage(i, 0xF5DEB3FF, string); // Sends the message to them!
}
return 1; // Just to know that the command has been recieved.
}
Okay, now the /acceptreport & /denyreport commands.
We will start off with the /acceptreport command:
Image:
http://i62.tinypic.com/rk0n0m.png
Code:
CMD:acceptreport(playerid, params[])
{
if (IsPlayerAdmin(playerid)) // Checks if the player is RCON admin
{
new target, string[128]; // new variable, and a new string for our messages!
if (sscanf(params, "u", target)) // This will check wether the /report command contains a playerid.
return SendClientMessage(playerid, 0xFFFFFFF, "USAGE: /acceptreport [playerid]"); // If not, it will send the synthaxmessage!
if(!strcmp(AccountData[target][pReportText], "None", true, 5)) // Compares the reportext to the basic, if it's the same the player didn't /report!
return SendClientMessage(playerid, 0xFFFFFFF, "This player doens't got a pending report!"); // Checks if the player got a report, if not send the message!
format(string, sizeof(string), "Admin %s accepted your report", PlayerRPName(playerid)); // Message that goes to the player with an active report!
SendClientMessage(target, 0xFFFFFFF, string); // Send the message to the person who did /report!
format(string, sizeof(string), "You have accepted %s's report", PlayerRPName(target)); // Message that goes to the admin who accepted the /report!
SendClientMessage(playerid, 0xFFFFFFF, string); // Send the message to the person who did /report!
format(AccountData[playerid][pReportText], 5, "None"); // Clears it!
}
return 1;
}
/denyreport!
IMAGE:
http://i62.tinypic.com/sws6sg.png
CODE:
CMD:denyreport(playerid, params[])
{
if (IsPlayerAdmin(playerid)) // Checks if the player is RCON admin
{
new target, reason[128], string[128]; // new variable, and a new string for our messages, reason for denial!
if (sscanf(params, "us[128]", target, reason)) // This will check wether the /report command contains a playerid & a string.
return SendClientMessage(playerid, 0xFFFFFFF, "USAGE: /denyreport [playerid] [reason]"); // If not, it will send the synthaxmessage!
if(!strcmp(AccountData[target][pReportText], "None", true, 5)) // Compares the reportext to the basic, if it's the same the player didn't /report!
return SendClientMessage(playerid, 0xFFFFFFF, "This player doens't got a pending report!"); // Checks if the player got a report, if not send the message!
format(string, sizeof(string), "Admin %s declined your report reason: %s", PlayerRPName(playerid), reason); // Message that goes to the player with an active report!
SendClientMessage(target, 0xFFFFFFF, string); // Send the message to the person who did /report!
format(string, sizeof(string), "You have declined %s's report, reason: %s", PlayerRPName(target), reason); // Message that goes to the admin who accepted the /report!
SendClientMessage(playerid, 0xFFFFFFF, string); // Send the message to the person who did /report!
format(AccountData[playerid][pReportText], 5, "None"); // Clears it!
}
return 1;
}
First off I would highly recommend you to read James' tutorial: Click here (http://www.gta-sarp.com/forums/showthread.php?103437-Scripting-guide), his tutorial is great to start to understand the basics of Pawn.
I'll be talking on my tutorial about commands which are made with both ZCMD and SSCANF.
Link to ZCMD: Click here! (http://forum.sa-mp.com/showthread.php?t=91354)
Link to SSCANF: Click here! (http://forum.sa-mp.com/showthread.php?t=120356)
Contents:
1.0 - What are ZCMD and SSCANF?
1.1 - What is ZCMD?
1.2 - What is SSCANF?
2.0 - First commands!
2.1 - Ban command!
2.2 - Suggestion!
2.3 - Advanced /report command
1.1: What is ZCMD? ZCMD is a command processor in a include which has been created by Zeex, it is one of the fastest command processors out there.
1.2: What is SSCANF? SSCANF is a plugin that takes a string and extracts different types of data from it., I'do highly recommend to read this: Click here! (https://github.com/Y-Less/sscanf/wiki), it will make you understand it easier.
2.1: To make a /ban command you need one include and one plugin: ZCMD & SSCANF.
Okay let's go to the code, this is going to be the base where we work from:
Needed functions for this command:
stock PlayerRPName(playerid)
{
new name[MAX_PLAYER_NAME];
strmid(name, str_replace('_', ' ', ReturnPlayerName(playerid)), 0, MAX_PLAYER_NAME); // Removes the underscore between the player's forename and surname
return name; // Returns the new name without the '_'
}
stock ReturnPlayerName(playerid)
{
new name[MAX_PLAYER_NAME+1]; // Making a new string
GetPlayerName(playerid, name, sizeof(name)); // Get's the player's name.
return name; // Returns it
}
Due to a security update from 0.3x they have decided that when there is being called that a player is kicked/banned, he will get kicked/banned before any other functions, therefore you have to delay the kick/ban with a delay of 1 second so he can recieves the clientmessage about him being kicked/banned.
Therefore you need this(This is what the timer does when it's being called):
forward BanTimer(playerid);
public BanTimer(playerid)
{
return Ban(playerid);
}
It'll become something like this:
CMD:ban(playerid, params[])
{
if(IsPlayerAdmin(playerid)) // Checks if the player who wrote the command is admin if so, continue!
{
new userid, reason[128], string[128]; // userid = the target's playerid, reason = his ban reason, string = we will format our clientmessages into that!
if (sscanf(params, "us[128]", userid, reason)) // This will check wether the /ban command contains a player & string.
return SendClientMessage(playerid, 0xFFFFFFFF, "/ban [playerid] [reason]"); // If not, it will send the synthaxmessage!
format(string, sizeof(string), "AdmCmd: %s was banned by %s, reason: %s", PlayerRPName(userid), PlayerRPName(playerid), reason); // Formats the string!
SendClientMessageToAll(0xFF6347AA, string); // Send a global message to every player that the player has been banned.
SetTimerEx("BanTimer", 1000, false, "i", userid); // Sets a timer on the userid, banning him when 1 sec passed to he is able to see his ban reason.
}
return 1; // Just to know that the command has been recieved.
}
Image:
http://i58.tinypic.com/apiiw1.png
2.2: Suggest on this thread where you would like to see a tutorial about, I'll take everything, I can better spend my time by making the things the people want instead of taking random commands that most people can make from theirselves.
2.3: Okay, thanks for the suggestion in the first place, we will use the functions we used last time again, to get the player's name ect, we will be using the foreach include by Y_Less, it's a better loop than the regular one.
We will be using an enumerator to save the player's report text! Here is the code to make a new enumerator!
enum _AccountData
{
pReportText[128]
};
new AccountData[MAX_PLAYERS][_AccountData];
We will have to reset the string at, under OnPlayerConnect add:
format(AccountData[playerid][pReportText], 5, "None"); // Clears it!
The command will look like this:
IMAGE:
http://i59.tinypic.com/331owlx.png
Text:
CMD:report(playerid, params[])
{
new string[128], reason[128]; // string = string to format for the clientmessage, reason = /report [text]!
if (sscanf(params, "s[128]", reason)) // This will check wether the /report command contains a string.
return SendClientMessage(playerid, 0xFFFFFFFF, "USAGE: /report [text]"); // If not, it will send the synthaxmessage!
if(AccountData[playerid][pReportText]) return SendClientMessage(playerid, 0xFFFFFFF, "You already got a pending report!"); // Checking if the player got a report
SendClientMessage(playerid, "Your report message has been sent to online administrators."); // Sends the client the the player who wrote the comamnd!
format(string, sizeof(string), "Report from [%d]%s: %s", playerid, PlayerRPName(playerid), reason); // Make the message correctly to send it to the admins
format(AccountData[playerid][pReportText], 128, "%s", reason); // Adds the reason to his reporttext variable!
foreach(Player, i)
{
if (IsPlayerAdmin(i)) // Check if the player is rcon admin, if so continue!
SendClientMessage(i, 0xF5DEB3FF, string); // Sends the message to them!
}
return 1; // Just to know that the command has been recieved.
}
Okay, now the /acceptreport & /denyreport commands.
We will start off with the /acceptreport command:
Image:
http://i62.tinypic.com/rk0n0m.png
Code:
CMD:acceptreport(playerid, params[])
{
if (IsPlayerAdmin(playerid)) // Checks if the player is RCON admin
{
new target, string[128]; // new variable, and a new string for our messages!
if (sscanf(params, "u", target)) // This will check wether the /report command contains a playerid.
return SendClientMessage(playerid, 0xFFFFFFF, "USAGE: /acceptreport [playerid]"); // If not, it will send the synthaxmessage!
if(!strcmp(AccountData[target][pReportText], "None", true, 5)) // Compares the reportext to the basic, if it's the same the player didn't /report!
return SendClientMessage(playerid, 0xFFFFFFF, "This player doens't got a pending report!"); // Checks if the player got a report, if not send the message!
format(string, sizeof(string), "Admin %s accepted your report", PlayerRPName(playerid)); // Message that goes to the player with an active report!
SendClientMessage(target, 0xFFFFFFF, string); // Send the message to the person who did /report!
format(string, sizeof(string), "You have accepted %s's report", PlayerRPName(target)); // Message that goes to the admin who accepted the /report!
SendClientMessage(playerid, 0xFFFFFFF, string); // Send the message to the person who did /report!
format(AccountData[playerid][pReportText], 5, "None"); // Clears it!
}
return 1;
}
/denyreport!
IMAGE:
http://i62.tinypic.com/sws6sg.png
CODE:
CMD:denyreport(playerid, params[])
{
if (IsPlayerAdmin(playerid)) // Checks if the player is RCON admin
{
new target, reason[128], string[128]; // new variable, and a new string for our messages, reason for denial!
if (sscanf(params, "us[128]", target, reason)) // This will check wether the /report command contains a playerid & a string.
return SendClientMessage(playerid, 0xFFFFFFF, "USAGE: /denyreport [playerid] [reason]"); // If not, it will send the synthaxmessage!
if(!strcmp(AccountData[target][pReportText], "None", true, 5)) // Compares the reportext to the basic, if it's the same the player didn't /report!
return SendClientMessage(playerid, 0xFFFFFFF, "This player doens't got a pending report!"); // Checks if the player got a report, if not send the message!
format(string, sizeof(string), "Admin %s declined your report reason: %s", PlayerRPName(playerid), reason); // Message that goes to the player with an active report!
SendClientMessage(target, 0xFFFFFFF, string); // Send the message to the person who did /report!
format(string, sizeof(string), "You have declined %s's report, reason: %s", PlayerRPName(target), reason); // Message that goes to the admin who accepted the /report!
SendClientMessage(playerid, 0xFFFFFFF, string); // Send the message to the person who did /report!
format(AccountData[playerid][pReportText], 5, "None"); // Clears it!
}
return 1;
}