[Tutorial] Login and Register System - Dialogs - Using SII
#1

Login and Register System - Dialogs - Using SII.

I've seen numerous people, wanting to switch from the older Dini file saving system to a newer one, such as Y_INI, djSON and even Fini. Most of them understand the Dini format, and examples, even tutorials of the newer systems sometimes help, but to some of the newer 'developers' this can be a struggle. I've created this tutorial to help those wishing to upgrade' to a newer system, a better system.

What is this?
This is a simple tutorial on how to make Login and Register system with dialogs using SII.


Step 1
Firstly, your going to need to download the SII include. You can find it here: https://sampforum.blast.hk/showthread.php?tid=58458. Once downloaded, place it into your Pawno > include folder.

Step 2
Add the include at the top of the script.

pawn Code:
#include <SII>
The SII include contains all the needed functions you are going to use to create your Login and Register system.
Step 3
Let's define some dialogs:

pawn Code:
#define DIALOG_REGISTER 2000
#define DIALOG_LOGIN 2001
Step 4
Let's add some colors:

pawn Code:
#define WHITE "{FFFFFF}"
#define RED "{F81414}"
#define GREEN "{00FF22}"
#define LIGHTBLUE "{00CED1}"
Step 5
Create a new variable, somewhere below your defines.

pawn Code:
new gPlayerName[MAX_PLAYERS][MAX_PLAYER_NAME];
Step 6
Next, lets add an enum, also known as an enumeration.

pawn Code:
enum pInfo
{
    pPass,
    pScore,
    pCash,
    pAdmin
}
new PlayerInfo[MAX_PLAYERS][pInfo];
An enumeration stores many things in a variable. This is extremely efficient and effective, instead of creating a set of different variables.


Step 7
Lets create a stock function:

pawn Code:
stock getINI(playerid)
{
  new account[64];
  format(account,30,"Users/%s.ini",gPlayerName[playerid]);
  return account;
}
The stock function is going to load the user file.

Step 8
We'll be using the native 'fexist' function to search for our file. Parameters are set to our stock function which we've created. If the file exists, you will receive a 'Login' dialog. If it doesn't, you will receive a register dialog.


pawn Code:
public OnPlayerConnect(playerid)
{
    GetPlayerName(playerid, gPlayerName[playerid], MAX_PLAYER_NAME);
    if (fexist(getINI(playerid)))
    {
        ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_INPUT,""WHITE"Login",""WHITE"Type your password below to login.","Login","Quit");
    }
    else
    {
        ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_INPUT,""WHITE"Registering...",""WHITE"Type your password below to register a new account.","Register","Quit");
    }
    return 1;
}
Step 9
Go to your OnDialogResponse callback and add this in.


pawn Code:
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
    switch( dialogid )
    {
        case DIALOG_REGISTER:
        {
            if (!response) return Kick(playerid);
            if (response)
            {
                if(!strlen(inputtext)) {
                ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_INPUT, ""WHITE"Registering...",""RED"You have entered an invalid password.\n"WHITE"Type your password below to register a new account.","Register","Quit");
                }

                if(INI_Open(getINI(playerid))) {
                INI_WriteString("Password",inputtext);
                INI_WriteInt("Score",1);
                INI_WriteInt("Cash",5000);
                INI_WriteInt("Admin",0);

                INI_Save();
                INI_Close();

                ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_INPUT,""WHITE"Login",""WHITE"Type your password below to login.","Login","Quit");
            }
        }
    }
        case DIALOG_LOGIN:
        {
            if ( !response ) return Kick ( playerid );
            if( response )
            {
                if(!strlen(inputtext)) {
                ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_INPUT, ""WHITE"Login",""RED"You have entered an invalid password.\n"WHITE"Type your password below to login.","Login","Quit");
                }

                if(INI_Open(getINI(playerid))) {
                INI_ReadString(PlayerInfo[playerid][pPass],"Password",20);

                if(strcmp(inputtext,PlayerInfo[playerid][pPass],false)) {
                ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_INPUT, ""WHITE"Login",""RED"You have entered an incorrect password.\n"WHITE"Type your password below to login.","Login","Quit");
                }

                SetPlayerScore( playerid, INI_ReadInt("Score" ) );
                ResetPlayerMoney( playerid );
                GivePlayerMoney( playerid, INI_ReadInt( "Cash" ) );
                PlayerInfo[playerid][pAdmin] = INI_ReadInt("Admin");
                INI_Close();
                }
            }
        }
    }
    return 1;
}
case DIALOG_REGISTER:

Instead of using the 'if' statement to define my dialogs, I've used cases as they seem to take less space and are supposedly 'faster'. The (!response) is the function if the first Button hasn't been clicked, it will then kick the player.

The if(!strlen(inputtext)) explains if nothing has been entered into the dialog (input), you would then be prompted to another dialog which shows you 'Incorrect Password'.

If all goes well, the function INI_Open is then executed which loads and opens the Userfile. Once open, other functions 'INI_WriteString' 'INI_WriteInt' can be called. It is then finished by the 'INI_Save' function which saves the values which has been set and/or strings which has been entered. Finally, 'INI_Close' closes the Userfile.

Once finished, you will then be prompted to the 'Login' dialog.

case DIALOG_LOGIN:

The only thing which is happening (with the exception of the Userfile being opened and closed) the 'INI_ReadInt' and 'INI_ReadString' function is called. When the player logs in, it loads the players 'stats' or so to say.

Example: If the player had, $1000 dollars before he disconnected, the function 'INI_ReadInt' would read that value, which would be called with GivePlayerMoney to load the player's Money value.

Step 10
Finally, we'll need to save the player stats, when he disconnects.

pawn Code:
public OnPlayerDisconnect(playerid, reason)
{
    if(INI_Open(getINI(playerid))) {
   
    INI_WriteInt("Score",PlayerInfo[playerid][pScore]);
    INI_WriteInt("Cash",GetPlayerMoney(playerid));
    INI_WriteInt("Admin",PlayerInfo[playerid][pAdmin]);

    INI_Save();
    INI_Close();
    }
    return 1;
}
I've chose the OnPlayerDisconnect callback to save player 'stats' because this creates MUCH less lag as opposed to the OnPlayerUpdate.


Downloads:


Pastebin - http://pastebin.com/kgvZGm3e


Credits:
[DRuG]Slick - SII Include
Las Venturas CNR - The man who showed me Dini was shit!
Reply
#2

Nice tutorial, you've done quite a good job of explaining the functions, but you should perhaps consider writing a tutorial on a more modern file-orient include, such as y_files, SII has been out of date for a while - and isn't as fast as it was when the speed tests were taken years ago, plus the last time I used SII, it had trouble saving strings that contained symbols or non-alphanumerical characters.

@ Las Venturas CNR: I'm presuming that's what he meant.
Reply
#3

Thanks for the feedback Calg00n, I'll soon be attempting to write a Tutorial on newer ones such as y_INI and might even attempt to take a look at MySQL a bit or two
Reply
#4

Nice Tutorial.
Reply
#5

Good job. I didn't think someone would of created one for SII. Guess i was wrong.
Reply
#6

Quote:
Originally Posted by Las Venturas CNR
View Post
Nice tutorial, Yes, OnPlayerUpdate isn't too well of a saving method as it's called around 32 times a second.
A simple timer will do it though.
Honestly i never thought of a timer, if i made one for about every 2ish minutes how much lag would it cause for 500 players, or if i set one to loop through players and save. haven't worked much with timers yet.
Reply
#7

Great tutorial! Well explained, reputation ++;

But, did I found a mistake?

pawn Code:
PlayerInfo[playerid][pScore] = INI_ReadInt("Score")
You didn't use SetPlayerScore to set the player's score back, lol

pawn Code:
GivePlayerMoney(playerid, INI_ReadInt("Cash"));
Just an example, before we logged in, we hacked the money to $9999999, then we log in, we got another money too ...

So I think it would be

pawn Code:
GivePlayerMoney( playerid, - GetPlayerMoney( playerid ) + INI_ReadInt( "Cash" ) );

// Or

ResetPlayerMoney( playerid );

GivePlayerMoney( playerid, INI_ReadInt( "Cash" ) );
Reply
#8

Very good tutorial: Good work mate
Reply
#9

Quote:
Originally Posted by Basicz
View Post
Great tutorial! Well explained, reputation ++;

But, did I found a mistake?

pawn Code:
PlayerInfo[playerid][pScore] = INI_ReadInt("Score")
You didn't use SetPlayerScore to set the player's score back, lol

pawn Code:
GivePlayerMoney(playerid, INI_ReadInt("Cash"));
Just an example, before we logged in, we hacked the money to $9999999, then we log in, we got another money too ...

So I think it would be

pawn Code:
GivePlayerMoney( playerid, - GetPlayerMoney( playerid ) + INI_ReadInt( "Cash" ) );

// Or

ResetPlayerMoney( playerid );

GivePlayerMoney( playerid, INI_ReadInt( "Cash" ) );
Your right, I apologize for my inaccuracy. Thanks mate, fixed..
Reply
#10

Will there be y_ini version?
Reply
#11

Yes y_INI version will be posted soon.
Reply
#12

I got 4 errors on this line

GetPlayerName(playerid, gPlayerName[playerid], MAX_PLAYER_NAME);

errors

error 017: undefined symbol "gPlayerName"
warning 215: expression has no effect
error 001: expected token: ";", but found "]"
error 029: invalid expression, assumed zero
fatal error 107: too many error messages on one line

EDIT: I got this fixed
Reply
#13

Quote:
Originally Posted by Kush
View Post
Yes y_INI version will be posted soon.
Actually, which would you suggest me to use for my server's registration system. Y_INI or SII?
Reply
#14

Personally, If you truly are a beginner, SII would be a great start. The tutorial explains almost everything, to get started and the functions are listed so you can actually more.

But in reality, Y_ini is by far the most advanced .ini based system I've seen. Y_Less truly has done a great job in putting it together. Y_Ini is faster, more advanced and has some extra features .
Reply
#15

Duh, I hate dialogs.
I think I'll make a tutorial for command+y_ini
Reply
#16

Quote:
Originally Posted by Seven_of_Nine
View Post
Duh, I hate dialogs.
I think I'll make a tutorial for command+y_ini
How can you hate dialogs?
Reply
#17

Quote:
Originally Posted by Kush
View Post
How can you hate dialogs?
They're annoying I guess..
Reply
#18

Hmmkay, I'm not that much of a beginner but a tutorial like this based on y_ini would indeed help me.

Edit: What if I want to hash the passwords securely?
Reply
#19

Cool man but how to make it save weapons and their ammo?
Reply
#20

Very good =)

This forum requires that you wait 120 seconds between posts. Please try again in 9 seconds.
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)