29.10.2012, 17:44
(
Last edited by gtakillerIV; 19/04/2014 at 05:04 PM.
Reason: Fixed mistake.
)
Hey guys today I'm gonna show you how to ban an offline(not connected) player from your server, this is very easy to do so I wanted to share it with you guys
Let's get started.
Requirments:
* ZCMD (Zeex)
* y_ini (******)
* Sscanf2 (******)
* Kush (For his tutorial) <==== You have to follow his tutorial first before you continue with me.
Now let me tell you what is ZCMD and y_ini.
ZCMD: ZCMD is a fast and simple command processor.
y_ini: y_ini is a fast and modern .ini file reading and writing system.
First of all add this at the top of your GameMode/FilterScript BUT under "#include <a_samp>":
Sscanf Specifiers(Thanks to ******):
Now let's get in to the real thing!
First we are going to look at our Enum that we just did with Kush's tutorial.
It should look like this:
What we are going to do is add another one variable and one string called "pBanned"(variable) and "BannedIP"(string) which is a string with the size of 22, like this:
Go back to your OnPlayerDialog and find a line that looks like this:
We wanna add the player's IP for futher use. It should look like this:
Now after we got that out off of our way, we will make the command. Which will look like this:
Now let me break that up for ya:
Here we are creating a new string called "targetname" with the size of 24 which is the max characters a SA-MP name can have, and creating another string called "filestring" with the size of 79.
Here we are checking if the player entered the correct parameters of our command which is "/banofflineplayer [Player's Name]", if he didin't enter the correct parameters it will give him an error.
Here we are formatting our "filestring" to the directory of our User Files, and you can see that I have typed in %s which means a string and if you look more to the right you will see that I typed in "targetname" what this basicly means is that our %s(String) will get replaced with our "targetname" string which we just typed in. "/banofflineplayer [Player's Name]", our parameter "targetname" will get replaced with our text which is something like this: "/banofflineplayer gta" , "gta" will be inserted to our string "targetname". So our %s will get replaced with "gta".
Now here we are checking if our string "filestring" exists, remember when we formated it to "/Users/%s.ini"? Well now we can call "filestring" a directory for our "targetname". So we are basicly checking to see if the directory in "filestring" exists, if not it will return an error.
This means that if all of the errors above are false or don't apply to you then you can continue with the rest of the command.
Here we are opening our "filestring" (The directory of "/Users/%s.ini"). In other words we're opening the .ini file of the player. Which containts all of his status.
Setting the tag of the .ini file. Setting tags in Y_Ini is very important!
More explanation on that in the /unban command below!
Now here we are writing a new entry with the name of "Banned" and it has an integer with the value of 1 which means true.
Closing our .ini file.
Creating a new string with the name of "done" and its size is 128.
formatting our "done" string. You noticed that I used %s in there? I'll tell you why, if you look above you will see that we have "new targetname[24]" which means that we created a new string called "targetname" with the size of 24. So what will happen is that our %s will get replaced with our "targetname" string. For example: /banofflineplayer Gta ."Gta" will be inserted to our "targetname" string, so now it should send our formated "done" string like this: "You have banned Gta" with no quotient marks.
Sending our formated "done" string to ourself(playerid).
Returning 1 for the command to work.
Now let's make something that checks to see if the player's User Account.ini contains "Banned = 1".
Add this at the top of your OnPlayerRequestClass:
Now remember in Kush's tutorial you made a stock with the name of "LoadUser_data" that loads the user? Well I want you to locate it and add the following line:
So your stock "LoadUser_data" should now look like this:
Now for the /unbanofflineplayer Command!
It will look like this:
Explanation:
Creating a new string called "string" and another called "tname". What Are Strings?
Here we're checking if the parameters of the command contains the Player Name. If not, it'll return us this error: "Correct Usage: /unbanofflineplayer [Player Name]".
So if I use "/unbanofflineplayer" only, it'll give me an error. Now away from the error side. If I enter "/unbanofflineplayer gtakillerIV", our tname will be assigned to gtakillerIV. That means if I use tname in anything for example like: printf("%s", tname); It will print in the console "gtakillerIV".
You're probably wondering what "s[24]" means, it means that our 1st parameter after the command "," which is tname is a string with the size of 24(maximum charactes in a SA-MP name).
We are creating a new string called "filestring" with the size of 79. Means it can only take 79 charactes. We will use this later on for our User's directory.
Now here we're formatting our string "filetsring" with our User's Directory which is "/Users/%s.ini". %s stands for String. Alright so now, if I go ingame and type in "/unbanofflineplayer gtakillerIV" the "filestring" string will be formated as: "/Users/gtakillerIV.ini".
This is pretty much it, thanks for reading I hope I have did a good job in explaining.
In the last line we formated our string "filestring" to be a directory of our "tname"'s string, so now "filestring" is our directory location of our Accounts folder. So here we're checking to see if the directory "filestring" exists, if not it'll return an error. Ex: If I go ingame and type in "/unbanofflineplayer gtakillerIV" our string "tname" will be set to "gtakillerIV" after that our directory string aka "filestring" will be formated as "/Users/%s.ini" if our account doesn't exist, we'll get an error.
If all of the above is FALSE in other words doesn't correspond to our situation we will continue with the next block of codes.
Here we are opening our .ini file using our directory "filestring"(/Users/%s.ini). If I go ingame and type in "/unbanofflineplayer gtakillerIV", our "filestring" will be formated as "/Users/gtakillerIV" and this line here will open our .ini file("/Users/gtakillerIV.ini")
Here we're setting the tag of the .ini file which will look like [data] inside the .ini file. It's very important to set a tag, else it won't replace the current value of "Banned". Remember that Tags have to be the same, so for example if I set the tag to "test123" it will create a new tag which will look like [test123] and above it our [data] tag which has the "Banned" value. .ini file will look like:
As you can see instead of replacing the "Banned = 1" it created a new line with a new tag"[test123]".
Here we are writing or if it's currently in the .ini file we will replace it with the "0". So the .ini file should look like:
Here we are closing our .ini and saving it.
Alright now add this anywhere in your script:
Here we are loading the Public Function "LoadIP_data". We're also passing an extra variable called "playerid". What will happen is that our "BannedIP" string will be assigned to the target name's IP address. So if "gtakillerIV"'s IP was "127.0.0.1" our BannedIP string will be set to "127.0.0.1".
Here we are creating a new String called "cmdstring" with the maximum length of 44.
Here we are formatting our "cmdstring" that we created earlier with the data "unbanip %s" again %s stands for string. %s will be replaced with our string data of BannedIP[playerid]. So if "gtakillerIV"'s IP is "127.0.0.1" our BannedIP[playerid] string will be set to "127.0.0.1" and our "cmdstring" string will be formated as "unbanip 127.0.0.1".
Here we are sending a RCON command which is the data of our string "cmdstring". If "gtakillerIV"'s IP was "127.0.0.1" then our "cmdstring" will be "unbanip 127.0.0.1" so it will be like doing "SendRconCommand("unbanip 127.0.0.1");".
Reloading our samp.ban file. In other words we're reloading our bans.
Creating a new string called "done" with the maximum characters of 128, which is the maximum length of a message in SA-MP.
Here we are formatting our "done" string to "You have successfully unbanned %s". If I entered "/unbanofflineplayer gtakillerIV" our "done" string will be formated as "You have successfully unbanned gtakillerIV".
Sending our string "done" to ourself.
My second Tutorial, first one sucked, so I hope this one is good.
Thank you.
Let's get started.
Requirments:
* ZCMD (Zeex)
* y_ini (******)
* Sscanf2 (******)
* Kush (For his tutorial) <==== You have to follow his tutorial first before you continue with me.
Now let me tell you what is ZCMD and y_ini.
ZCMD: ZCMD is a fast and simple command processor.
y_ini: y_ini is a fast and modern .ini file reading and writing system.
First of all add this at the top of your GameMode/FilterScript BUT under "#include <a_samp>":
pawn Code:
#include <zcmd>
#include <sscanf2>
#include <YSI\y_ini>
Sscanf Specifiers(Thanks to ******):
Code:
Specifier(s) Name Example values i, d Integer 1, 42, -10 c Character a, o, * l Logical true, false b Binary 01001, 0b1100 h, x Hex 1A, 0x23 o Octal 045 12 n Number 42, 0b010, 0xAC, 045 f Float 0.7, -99.5 g IEEE Float 0.7, -99.5, INFINITY, -INFINITY, NAN, NAN_E u User name/id (bots and players) ******, 0 q Bot name/id ShopBot, 27 r Player name/id ******, 42
First we are going to look at our Enum that we just did with Kush's tutorial.
It should look like this:
pawn Code:
enum pInfo
{
pPass,
pCash,
pAdmin,
pKills,
pDeaths
}
new PlayerInfo[MAX_PLAYERS][pInfo];
pawn Code:
enum pInfo
{
pPass,
pCash,
pAdmin,
pKills,
pDeaths,
pBanned, //Here!
BannedIP[22] //This one too :P
}
new PlayerInfo[MAX_PLAYERS][pInfo];
pawn Code:
case DIALOG_REGISTER:
{
if (!response) return Kick(playerid);
if(response)
{
if(!strlen(inputtext)) return ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_INPUT, ""COL_WHITE"Registering...",""COL_RED"You have entered an invalid password.\n"COL_WHITE"Type your password below to register a new account.","Register","Quit");
new INI:File = INI_Open(UserPath(playerid));
INI_SetTag(File,"data");
INI_WriteInt(File,"Password",udb_hash(inputtext));
INI_WriteInt(File,"Cash",0);
INI_WriteInt(File,"Admin",0);
INI_WriteInt(File,"Kills",0);
INI_WriteInt(File,"Deaths",0);
INI_Close(File);
SetSpawnInfo(playerid, 0, 0, 1958.33, 1343.12, 15.36, 269.15, 0, 0, 0, 0, 0, 0);
SpawnPlayer(playerid);
ShowPlayerDialog(playerid, DIALOG_SUCCESS_1, DIALOG_STYLE_MSGBOX,""COL_WHITE"Success!",""COL_GREEN"Great! Your Y_INI system works perfectly. Relog to save your stats!","Ok","");
}
}
pawn Code:
case DIALOG_REGISTER:
{
if (!response) return Kick(playerid);
if(response)
{
if(!strlen(inputtext)) return ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_INPUT, ""COL_WHITE"Registering...",""COL_RED"You have entered an invalid password.\n"COL_WHITE"Type your password below to register a new account.","Register","Quit");
new IP[22]; // Creating a new string called IP with the maximum length of 22.
GetPlayerIp(playerid, IP, sizeof(IP)); // Here we are getting the Player's IP and storing it in our string "IP" with the maximum length of 22.
new INI:File = INI_Open(UserPath(playerid));
INI_SetTag(File,"data");
INI_WriteInt(File,"Password",udb_hash(inputtext));
INI_WriteInt(File,"Cash",0);
INI_WriteString(File, "Ip", IP); // We're writing in the .ini file of the player a new line which will contain our string "IP", so it'll look like "Ip = IP String here". If my IP was for example "127.0.0.1" then it'll be "Ip = 127.0.0.1".
INI_WriteInt(File,"Admin",0);
INI_WriteInt(File,"Kills",0);
INI_WriteInt(File,"Deaths",0);
INI_Close(File);
SetSpawnInfo(playerid, 0, 0, 1958.33, 1343.12, 15.36, 269.15, 0, 0, 0, 0, 0, 0);
SpawnPlayer(playerid);
ShowPlayerDialog(playerid, DIALOG_SUCCESS_1, DIALOG_STYLE_MSGBOX,""COL_WHITE"Success!",""COL_GREEN"Great! Your Y_INI system works perfectly. Relog to save your stats!","Ok","");
}
}
pawn Code:
CMD:banofflineplayer(playerid, params[])
{
new targetname[24], filestring[79];
if(sscanf(params, "s[24]", targetname)) return SendClientMessage(playerid, -1, "Correct Usage: /banofflineplayer [Player's Name]");
format(filestring, sizeof(filestring), "/Users/%s.ini", targetname);
if(!fexist(filestring)) return SendClientMessage(playerid, -1, "Error: The player name you have chosen was not found in our system.");
else
{
new INI:File = INI_Open(filestring);
INI_SetTag(File, "data");
INI_WriteInt(File, "Banned", 1);
INI_Close(File);
new done[128];
format(done, sizeof(done), "You have banned %s", targetname);
SendClientMessage(playerid,-1 , done);
}
return 1;
}
pawn Code:
new targetname[24], filestring[79];
pawn Code:
if(sscanf(params, "s[24]", targetname)) return SendClientMessage(playerid, -1, "Correct Usage: /banofflineplayer [Player's Name]");
pawn Code:
format(filestring, sizeof(filestring), "/Users/%s.ini", targetname);
pawn Code:
if(!fexist(filestring)) return SendClientMessage(playerid, -1, "Error: The player name you have chosen was not found in our system.");
pawn Code:
else
pawn Code:
new INI:File = INI_Open(filestring);
pawn Code:
INI_SetTag(File, "data");
More explanation on that in the /unban command below!
pawn Code:
INI_WriteInt(File, "Banned", 1);
pawn Code:
INI_Close(File);
pawn Code:
new done[128];
pawn Code:
format(done, sizeof(done), "You have banned %s", targetname);
pawn Code:
SendClientMessage(playerid,-1, done);
pawn Code:
return 1;
Now let's make something that checks to see if the player's User Account.ini contains "Banned = 1".
Add this at the top of your OnPlayerRequestClass:
pawn Code:
if(PlayerInfo[playerid][pBanned] == 1)//Checking if the user's file contains "Banned = 1", if that's true we continue if not we die :D
{
Ban(playerid); //Banning the player. I like to not send a Message saying that you have been banned..etc so the hacker doesn't know why it said "Server closed the connection" and changes his IP and the same thing happens and his new IP gets banned, stealthy shit :p
}
pawn Code:
INI_Int("Banned", PlayerInfo[playerid][pBanned]);
pawn Code:
public LoadUser_data(playerid,name[],value[])
{
INI_Int("Password",PlayerInfo[playerid][pPass]);
INI_Int("Cash",PlayerInfo[playerid][pCash]);
INI_Int("Banned", PlayerInfo[playerid][pBanned]);//Well basicly we are getting the entry "Banned" from the user's .ini file and storing it in "PlayerInfo[playerid][pBanned]" variable.
INI_Int("Admin",PlayerInfo[playerid][pAdmin]);
INI_Int("Kills",PlayerInfo[playerid][pKills]);
INI_Int("Deaths",PlayerInfo[playerid][pDeaths]);
return 1;
}
It will look like this:
pawn Code:
CMD:unbanofflineplayer(playerid, params[])
{
new string[128],tname[24];
if(sscanf(params, "s[24]", tname)) return SendClientMessage(playerid,-1,"Correct Usage: /unbanofflineplayer [Player Name] ");
new filestring[79];
format(filestring, sizeof(filestring), "/Users/%s.ini", tname);
if(!fexist(filestring)) return SendClientMessage(playerid,Lime, "The name you've chosen was not found in our database ");
else
{
new INI:File = INI_Open(filestring);
INI_SetTag(File, "data");
INI_WriteInt(File, "Banned",0);
INI_Close(File);
INI_ParseFile(filestring, "LoadIP_%s", .bExtra = true , .extra = playerid);
new cmdstring[44];
format(cmdstring, sizeof(cmdstring), "unbanip %s", PlayerInfo[playerid][BannedIP]);
SendRconCommand(cmdstring);
SendRconCommand("reloadbans");
new done[128];
format(done, sizeof(done),"You have successfully unbanned %s", tname);
SendClientMessage(playerid, -1,done);
}
return 1;
}
pawn Code:
new string[128],tname[24];
pawn Code:
if(sscanf(params, "s[24]", tname)) return SendClientMessage(playerid,-1,"Correct Usage: /unbanofflineplayer [Player Name]");
So if I use "/unbanofflineplayer" only, it'll give me an error. Now away from the error side. If I enter "/unbanofflineplayer gtakillerIV", our tname will be assigned to gtakillerIV. That means if I use tname in anything for example like: printf("%s", tname); It will print in the console "gtakillerIV".
You're probably wondering what "s[24]" means, it means that our 1st parameter after the command "," which is tname is a string with the size of 24(maximum charactes in a SA-MP name).
pawn Code:
new filestring[79];
pawn Code:
format(filestring, sizeof(filestring), "/Users/%s.ini", tname);
This is pretty much it, thanks for reading I hope I have did a good job in explaining.
pawn Code:
if(!fexist(filestring)) return SendClientMessage(playerid,Lime, "The name you've chosen was not found in our database ");
pawn Code:
else
pawn Code:
new INI:File = INI_Open(filestring);
pawn Code:
INI_SetTag(File, "data");
pawn Code:
[data]
Banned = 1;
[test123]
Banned = 0;
pawn Code:
INI_WriteInt(File, "Banned",0);
pawn Code:
[data]
Banned = 0;
pawn Code:
INI_Close(File);
Alright now add this anywhere in your script:
pawn Code:
public LoadIP_data(playerid, name[], value[]) //Creating a new Public function for use later.
{
INI_String("Ip", PlayerInfo[ playerid ][ BannedIP ], 33); //Loading the string "Ip", and assigning it to our string "BannedIP", with the maximum size of 33.
return 1; //Returning 1 for it to work.
}
pawn Code:
INI_ParseFile(filestring, "LoadIP_%s", .bExtra = true , .extra = playerid);
pawn Code:
new cmdstring[44];
pawn Code:
format(cmdstring, sizeof(cmdstring), "unbanip %s", BannedIP[playerid]);
pawn Code:
SendRconCommand(cmdstring);
pawn Code:
SendRconCommand("reloadbans");
pawn Code:
new done[128];
pawn Code:
format(done, sizeof(done),"You have successfully unbanned %s", tname);
pawn Code:
SendClientMessage(playerid, -1,done);
My second Tutorial, first one sucked, so I hope this one is good.
Thank you.