[Tutorial] Making a /renameaccount Command - Using ZCMD + SScanf 2
#1

Hey guys! Today I'm going to tell you how to make a /renameaccount command using ZCMD and SScanf2.

Credits:

SScanf 2 (******)

ZCMD (Zeex)

Note: You have to have a user system for this to work with you.

How can I make one?

There are quite a few tutorials, I'll give you two that I recommend.

1.Newbienoob's Tutorial.

2.Kush's Tutorial.

What is ZCMD?

Zcmd is a fast and simple command processor made by Zeex.

Example of a command in ZCMD:

pawn Code:
CMD:test(playerid, params[]) // Zcmd command format.
{
    SendClientMessage(playerid, -1, "Hey!"); //Sending a message to ourself saying "Hey!".
}
Now take a look at the SScanf Specifiers (Thanks to ******), they will come in handy when you start making advanced commands.

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
Now let's start!

First of all we have to include our downloaded includes which are Zcmd and SScanf 2. At the top of your script but below your defines, add this:

pawn Code:
#include <zcmd>
#include <sscanf2>
Add those anywhere in your script:

pawn Code:
stock frename(oldname[],newname[]) {
    if (!fexist(oldname)) return false;
    fremove(newname);
    if (!fcopy(oldname,newname)) return false;
    fremove(oldname);
    return true;
}
pawn Code:
stock fcopy(oldname[],newname[]) {
    new File:ohnd,File:nhnd;
    if (!fexist(oldname)) return false;
    ohnd=fopen(oldname,io_read);
    nhnd=fopen(newname,io_write);
    new buf2[1];
    new i;
    for (i=flength(ohnd);i>0;i--) {
        fputchar(nhnd, fgetchar(ohnd, buf2[0],false),false);
    }
    fclose(ohnd);
    fclose(nhnd);
    return true;
}

Hit compile if you get no errors, then continue with me, else post a comment here saying the errors you get.

Now for the command, the command will look like this:

pawn Code:
CMD:renameaccount(playerid, params[])
{
    new oldname[24], newname[24];
    if(sscanf(params,"s[24]s[24]", oldname, newname)) return SendClientMessage(playerid, -1 , "Correct Usage: /renameaccount [OldName][New name]");
    new filestring2[128];
    format(filestring2, sizeof(filestring2), "/Users/%s.ini", oldname);
    if(!fexist(filestring2)) return SendClientMessage(playerid, -1 , "That account name doesn't exist!");
    new filestring[128];
    format(filestring, sizeof(filestring), "/Users/%s.ini", newname);
    if(fexist(filestring)) return SendClientMessage(playerid,  -1, "The new name you've chosen is already taken");
    frename(filestring2, filestring);
    new string[128];
    format(string, sizeof(string), "You have successfully renamed %s's account to %s" ,oldname, newname);
    SendClientMessage(playerid, -1, string);
    return 1;
}
I'll explain each line for you now.

pawn Code:
new oldname[24], newname[24];
Here we are creating a new string with the name of "oldname" with the size of 24(Maximum SA-MP Name size, if you use MAX_PLAYER_NAME it's the same as typing in 24) and creating another string called "newname" with the size of 24.



pawn Code:
if(sscanf(params,"s[24]s[24]", oldname, newname)) return SendClientMessage(playerid, -1, "Correct Usage: /renameaccount [OldName][New name]");
Now here we are creating parameters for our command, for example: If I go ingame and type in /renameaccount it will give me an error saying "Correct Usage: /renameaccount [OldName][New name]" and if I type in /renameaccount gtakillerIV it will give me a message with the correct usage
The s[24] means string with the size of 24 now if you look abit more to the right I typed in "oldname" what that means is that when I enter something in the first parameter it will get assigned to my string "oldname" which is the Account's old name, same thing for the string "newname".

If I for example type in /renameaccount gtakillerIV, gtakillerIV will get assigned to our string "oldname", and if I type in /renameaccount gtakillerIV Gta, gtakillerIV will get assigned to our string "oldname" and Gta will get assigned to our string "newname" which is the new name for the account we want to rename.




pawn Code:
new filestring2[128];
Here we are creating a new string called "filestring" with the size of 128, you will know how are going to use it in this Tutorial.


pawn Code:
format(filestring2, sizeof(filestring2), "/Users/%s.ini", oldname);
Here we are formating our string "filestring2" which we have just created, what I mean by formating is like we are assigning/putting in our string "filestring2" what we want, for example if I typed in "/Users/%s.ini" this is the directory which our user accounts are located, %s means a string. Now here is a small example: If I type in /renameaccount gtakillerIV Gta, our string "filestring2" will get formated like this: /Users/gtakillerIV.ini. Why gtakillerIV? Well if you look at our format you will see that I added at the end oldname what that means is that our string(%s) will get replaced with our string oldname which we have just typed in (/renameaccount gtakillerIV Gta).



pawn Code:
if(!fexist(filestring2)) return SendClientMessage(playerid, -1, "That account name doesn't exist!");
Here we are checking to see if our formated string "filestring2" doesn't exist (!), why do we want to do that? Well you can't rename a file that is not there. Example: /renameaccount gtakillerIV Gta, gtakillerIV will get assigned to our string "oldname" from there we format our filestring2 string so it looks like this: /Users/gtakillerIV.ini, so we are checking if there is an account with the name of gtakillerIV, if that is true then we will return an error. This was just an example.


pawn Code:
new filestring[128];
Here we are creating a new string called "filestring" with the size of 128.


pawn Code:
format(filestring, sizeof(filestring), "/Users/%s.ini", newname);
Here we are formating our string "filestring" which we have just created, again why I mean by formating is putting what we want in our string "filestring". For example: If I type in /renameaccount gtakillerIV Gta, our filestring2 will get formated like this: /Users/gtakillerIV.ini , but our filestring will get formated like this: /Users/Gta.ini. If you noticed at the end I added newname instead of oldname what that does is that our %s(string) that we added "/Users/%s.ini" will get replaced with our newname parameter that we have created with SScanf2.



pawn Code:
if(fexist(filestring)) return SendClientMessage(playerid, -1, "The new name you've chosen is already taken");
Here we are checking to see if our filestring that we just formated does exist, why do I want to check if it exists? Because we don't want two user accounts with the same name. For example: If I type in /renameaccount gtakillerIV Gta, gtakillerIV will get assigned to our string "oldname", and Gta will get inserted to our string "newname". Then our filestring2 will get formated like this: /Users/gtakillerIV.ini and our filestring will get formated like this: /Users/Gta.ini. Then we check to see if our filestring exists (Users/Gta.ini), if it does return an error which is: The new name you've chosen is already taken.


pawn Code:
frename(filestring2, filestring);
Here we are using the function frename which just renames our file. We have formated our filestring2 and our filestring, so we are renaming our filestring2 with our filestring. Example: If I type in /renameaccount gtakillerIV Gta, our filestring2 will get formated like this: /Users/gtakillerIV.ini and our filestring will get formated like this: /Users/Gta.ini. Now gtakillerIV will get renamed to Gta.


pawn Code:
new string[128];
Here we are creating a new string with the name of "string" and with the size of 128.


pawn Code:
format(string, sizeof(string), "You have successfully renamed %s's account to %s" ,oldname, newname);
Here we are formating our string "string". Example: If I type in /renameaccount gtakillerIV Gta, our string will get formated like this: You have sucessfully renamed gtakillerIV's account to Gta.


pawn Code:
SendClientMessage(playerid, -1, string);
Here we are sending our formated string to the playerid(us) using the function SendClientMessage.

How does this function work?


Thanks to ****** for telling me how:


Quote:

What level do you want? The "playerid" parameter is used to look up the IP and port (i.e. the socket) of a player, then the colour and text information is packed in to a packet and that is sent via TCP* to the specified socket (i.e. the player). Once there, the client checks the incoming message type and calls the relevant decoding code to extract the the colour and message and uses DirectX text operations to draw to the screen. There is also code to store the current message buffer and manipulate that to add things on to the end.



* Actually, it's sent via a custom UDP protocol, but it is similar to TCP in that is ensures delivery.




pawn Code:
return 1;
Here we are returning 1 for our command to work, if we return 0 we will get an error saying: "SERVER: Unkown Command".



This is pretty much it, I hope you have learned something new. Please learn and don't copy-paste.

Found any typo/mistake? Please tell me here.

Thanks.
Reply
#2

Nice job.
Reply
#3

nice tutorial.
Reply
#4

Quote:
Originally Posted by DaRk_RaiN
View Post
Nice job.
Thanks bro.

Quote:
Originally Posted by Socan
View Post
nice tutorial.
Thank you very much.
Reply
#5

Very nice! +5 reps!
Reply
#6

Nice one, looks like you really put effort into it! +rep.
Reply
#7

Not bad. But i'm not impress..
Reply
#8

Quote:
Originally Posted by XtremeR
View Post
Very nice! +5 reps!
Thanks bro.

Quote:
Originally Posted by Rajat_Pawar
View Post
Nice one, looks like you really put effort into it! +rep.
Thanks.

Quote:
Originally Posted by Romel
View Post
Not bad. But i'm not impress..
Well I don't know what to tell ya, but thanks
Reply
#9

You could explain how does the stocks do perform so it'll be more better and can be considered as a good tutorial. Not bad anyway.
Reply
#10

Quote:
Originally Posted by Lordz™
View Post
You could explain how does the stocks do perform so it'll be more better and can be considered as a good tutorial. Not bad anyway.
But good job ,thanks
Reply
#11

Good Job but there's a problem you havent checked if the player is using his own name as old name.A player can maybe try to change any other acc and it will be done as i see.

Like my ingame name is akkak and i do /renameaccount AdminName hahaichangeyouaccountname so it be changed right ?
Reply
#12

Oh, I got what you mean, I can make a fast check to see if he is doing that, or I can just change his name to the new name and send a message to everyone saying "%s is now known as %s". I'm busy now so I won't edit my Topic, thanks for telling.
Reply
#13

Nice tutorial,but explain the stocks.
Reply
#14

Sure thing just give me time Got exams coming up
Reply
#15

I mean that the oldname player is entering must be same as his own current name then he can begin or it will return a error to him.
Reply
#16

Nice one.
Reply
#17

F:\GTA San Andreas\Rename\pawno\include\zcmd.inc(62) : warning 235: public function lacks forward declaration (symbol "OnGameModeInit")
F:\GTA San Andreas\Rename\pawno\include\zcmd.inc(64) : error 017: undefined symbol "funcidx"
F:\GTA San Andreas\Rename\pawno\include\zcmd.inc(65) : error 017: undefined symbol "funcidx"
F:\GTA San Andreas\Rename\pawno\include\zcmd.inc(66) : error 017: undefined symbol "funcidx"
F:\GTA San Andreas\Rename\pawno\include\zcmd.inc(6 : error 017: undefined symbol "CallLocalFunction"
F:\GTA San Andreas\Rename\pawno\include\zcmd.inc(83) : warning 235: public function lacks forward declaration (symbol "OnPlayerCommandText")
F:\GTA San Andreas\Rename\pawno\include\zcmd.inc(85) : error 017: undefined symbol "CallLocalFunction"
F:\GTA San Andreas\Rename\pawno\include\zcmd.inc(94) : error 017: undefined symbol "tolower"
F:\GTA San Andreas\Rename\pawno\include\zcmd.inc(96) : warning 217: loose indentation
F:\GTA San Andreas\Rename\pawno\include\zcmd.inc(96) : error 017: undefined symbol "format"
F:\GTA San Andreas\Rename\pawno\include\zcmd.inc(96) : warning 202: number of arguments does not match definition
F:\GTA San Andreas\Rename\pawno\include\zcmd.inc(96) : warning 202: number of arguments does not match definition
F:\GTA San Andreas\Rename\pawno\include\zcmd.inc(96) : warning 202: number of arguments does not match definition
F:\GTA San Andreas\Rename\pawno\include\zcmd.inc(97) : warning 217: loose indentation
F:\GTA San Andreas\Rename\pawno\include\zcmd.inc(9 : warning 217: loose indentation
F:\GTA San Andreas\Rename\pawno\include\zcmd.inc(102) : error 017: undefined symbol "CallLocalFunction"
F:\GTA San Andreas\Rename\pawno\include\zcmd.inc(104) : error 017: undefined symbol "CallLocalFunction"
F:\GTA San Andreas\Rename\pawno\include\zcmd.inc(10 : error 017: undefined symbol "CallLocalFunction"
F:\GTA San Andreas\Rename\pawno\include\zcmd.inc(110) : error 017: undefined symbol "CallLocalFunction"
Pawn compiler 3.2.3664 Copyright © 1997-2006, ITB CompuPhase


11 Errors.
Reply
#18

Pretty good. 8/10
Reply
#19

awesome
Reply
#20

Thanks a Lot :X
Very Helped Me...
+REP
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)