[Tutorial] Login & Register system - dialogs - with y_ini
#1

Hello!

This is my first tutorial. Let's start off.

Requirements:
  • Basic scripting knowledge
  • y_ini by ******
  • dudb & dutils by Dracoblue
Step 1
Including, definining.
Make sure you have these included:
pawn Code:
#include <YSI\y_ini>
#include <dudb>

//Path & options
#define PATH "/Users/%s.ini" //This is the path template

#define REGISTERED_MONEY 5000 //How much money registered users get
#define AUTOLOGIN //Delete this line if you don't want autologin
#define DIALOG_REGISTER 999 //Register dialog ID, feel free to modfiy
#define DIALOG_LOGIN 998 //Login dialog ID, feel free to modfiy

//Additional colors
#define white 0xFFFFFFA
#define red 0xFF0000AA
#define lime 0x00FF00FF
#define yellow 0xFFFF00FF
We'll need these later.

Step 2
Variables, enumerating and a stock function.
pawn Code:
enum iDetails { //Enumerating player data
    Pass,
    Cash,
    Score,
    Banned
};
new pInfo[MAX_PLAYERS][iDetails]; //Player data variable

new pIP[MAX_PLAYERS][16]; //For autologin

new pLogged[MAX_PLAYERS];

stock PlayerPath(playerid) { //This will give us faster access to a player's path
    new iStr[256],name[MAX_PLAYER_NAME];
    GetPlayerName(playerid,name,sizeof(name));
    format(iStr,sizeof(iStr),PATH,name);
    return iStr;
}
//ret_memcpy
#pragma unused ret_memcpy
We need the stock for fast playerfile accessing.

Step 3
OnPlayerConnect
We need to check for the player's file, then load the data if it exists.
<Autologin!>
pawn Code:
public OnPlayerConnect(playerid)
{
    pLogged[playerid] = 0;
    #if defined AUTOLOGIN
        new tmpIP[16];
        GetPlayerIp(playerid,tmpIP,sizeof(tmpIP)); //Getting IP
    #endif
    if(fexist(PlayerPath(playerid))) {
        INI_ParseFile(PlayerPath(playerid), "UserDataLoad_%s", .bExtra = true, .extra = playerid); //Calling loading callback
        #if defined AUTOLOGIN
            if(strcmp(tmpIP,pIP[playerid],true) == 0) { //Checking if the IPs match
                pLogged[playerid] = 1;
                SetPlayerScore(playerid,pInfo[playerid][Score]);
                GivePlayerMoney(playerid,pInfo[playerid][Cash]);
                SendClientMessage(playerid,lime,"You've been auto-logged in. [IP match]");
                return 1;
            }
        #endif
        ShowPlayerDialog(playerid,DIALOG_LOGIN,DIALOG_STYLE_INPUT,"Login","Please enter your password below.","Login","Leave");
    } else {
        ShowPlayerDialog(playerid,DIALOG_REGISTER,DIALOG_STYLE_INPUT,"Register","Please register by entering a password below.","Register","Leave");
    }
    return 1;
}
That includes the autologin part too.

Step 4
UserDataLoad_%s
Used for loading users' data.
pawn Code:
forward UserDataLoad_data(playerid,name[],value[]);

public UserDataLoad_data(playerid,name[],value[]) { //This loads the settings from the INI file
    INI_Int("Pass",pInfo[playerid][Pass]);
    INI_String("IP",pIP[playerid],16);
    INI_Int("Admin",pInfo[playerid][Admin]);
    INI_Int("Cash",pInfo[playerid][Cash]);
    INI_Int("Score",pInfo[playerid][Score]);
    INI_Int("Banned",pInfo[playerid][Banned]);
    return 1;
}
Step 5
Register dialog (under OnDialogResponse)
We need to check for the password, and create a new .ini file.
pawn Code:
if(dialogid == DIALOG_REGISTER) {
        GetPlayerIp(playerid,pIP[playerid],16);
        if(!response) Kick(playerid);
        if(!strlen(inputtext)) return ShowPlayerDialog(playerid,DIALOG_REGISTER,DIALOG_STYLE_INPUT,"Register","Please enter a password.","Register","Leave");
        new INI:iFile = INI_Open(PlayerPath(playerid)); //Making the INI file and writing settings
        INI_SetTag(iFile,"data");
        INI_WriteInt(iFile,"Pass",udb_hash(inputtext));
        #if defined AUTOLOGIN
            INI_WriteString(iFile,"IP",pIP[playerid]);
        #endif
        INI_WriteInt(iFile,"Cash",REGISTERED_MONEY);
        INI_WriteInt(iFile,"Score",0);
        INI_Close(iFile);
        pLogged[playerid] = 1;
        new iStr[128];
        format(iStr,sizeof(iStr),"You've successfully registered with the password \"%s\".",inputtext);
        SendClientMessage(playerid,yellow,iStr);
        return 1;
    }
Step 6
Login dialog (under OnDialogResponse)
Checking for the player's password..
pawn Code:
if(dialogid == DIALOG_LOGIN) {
        if(!response) Kick(playerid);
        new iStr[128],gTries;
        if(gTries == 0) gTries = 1;
        if(gTries == 3) { // 3 tries = kick
            new pName[30];
            GetPlayerName(playerid,pName,sizeof(pName));
            format(iStr,sizeof(iStr),"%s has been kicked for exceeding login tries.",pName);
            SendClientMessageToAll(red,iStr);
            return Kick(playerid);
        }
        if(!strlen(inputtext)) {
            format(iStr,sizeof(iStr),"Please enter your password. Tries: %i/3",gTries);
            return ShowPlayerDialog(playerid,DIALOG_LOGIN,DIALOG_STYLE_INPUT,"Login",iStr,"Login","Leave");
        }
        if(udb_hash(inputtext) == pInfo[playerid][Pass]) {
            pLogged[playerid] = 1;
            SendClientMessage(playerid,lime,"You've successfully logged in.");
            SetPlayerScore(playerid,pInfo[playerid][Score]); //Loading player score
            GivePlayerMoney(playerid,pInfo[playerid][Cash]); //Loading player money
        } else {
            format(iStr,sizeof(iStr),"Incorrect password. Tries: %i/3",gTries);
            ShowPlayerDialog(playerid,DIALOG_REGISTER,DIALOG_STYLE_INPUT,"Register",iStr,"Login","Leave");
            gTries++;
            return 1;
        }
Step 7
Blocking the player from spawning. (because they can spawn by pressing the "Spawn" button in the class selection)
pawn Code:
public OnPlayerRequestSpawn(playerid)
{
    if(pLogged[playerid] == 0) return SendClientMessage(playerid,yellow,"You must register or login before spawning!");
    return 1;
}
Step 8
Disconnection save, this saves user settings in the player's INI file
pawn Code:
public OnPlayerDisconnect(playerid, reason)
{
    if(pLogged[playerid] == 1) {
        new INI:iFile = INI_Open(PlayerPath(playerid));
        INI_SetTag(iFile,"data");
        INI_WriteInt(iFile,"Cash",GetPlayerMoney(playerid));
        INI_WriteInt(iFile,"Score",GetPlayerScore(playerid));
        INI_Close(iFile);
    }
    pLogged[playerid] = 0;
    return 1;
}
Whole code:
PasteBin

Tested, works fine.

Download links:
dutils download link
dudb download link
YSI download link
Reply
#2

Nice tutorial, though you do need to explain several things in the tutorial, otherwise this is basicly a snippet page.

Y_ini ftw.
Reply
#3

Eh

pawn Code:
public OnPlayerDisconnect(playerid, reason)
{
        pLogged[playerid] = 0;
        new INI:iFile = INI_Open(PlayerPath(playerid));
        INI_SetTag(iFile,"data");
        INI_WriteInt(iFile,"Cash",GetPlayerMoney(playerid));
        INI_WriteInt(iFile,"Score",GetPlayerScore(playerid));
        INI_Close(iFile);
        return 1;
}
You should add if the player is logged in tho'

pawn Code:
public OnPlayerDisconnect(playerid, reason)
{
        if ( pLogged[ playerid ] ) {
            new INI:iFile = INI_Open(PlayerPath(playerid));
            INI_SetTag(iFile,"data");
            INI_WriteInt(iFile,"Cash",GetPlayerMoney(playerid));
            INI_WriteInt(iFile,"Score",GetPlayerScore(playerid));
            INI_Close(iFile);
        }

        pLogged[ playerid ] = 0;
        return 1;
}
I think it could be useful.

--

Nice tutorial!
Reply
#4

@Basicz, the player should be logged in because it is a must-register system.
Reply
#5

Great tutorial!
Reply
#6

@ Seven_of_Nine

When you kick the player in the registration dialog, just think..

( It will kick the player, sends OnPlayerDisconnect, the file wouldn't be found xD ).
Reply
#7

Ok, corrected

I think commands are better (/login /register) but yeh.. I made this too
Reply
#8

Still add it because there are many ways of preventing the actual dialog from coming, mostly with some lagg and a command that shows a dialog will clear the dialog
Reply
#9

Uhmm...you can register just by leaving the field blank and pressing 'Register'. Also the account didn't save anywhere :/
Reply
#10

this is too long, I have a smaller code but sometinhg does't work, when I fix it i will post tutorial, anyway, nice tutorial, praise for their efforts, and you should use Whirlpool
Reply
#11

why udb_hash??

how to remove udb_hash from this script and i see pasword of the person?
Reply
#12

pawn Code:
enum iDetails { //Enumerating player data
    Admin,
    Pass,
    Cash,
    Score,
    Banned
};
Reply
#13

Good tutorial! Good work man i really like it.
Reply
#14

Thanks I didn't get any errors when I compiled but for some reason it doesn't save the users in my scriptfiles/Users Directory.
Reply
#15

E:\bestgamemode.pwn(944) : error 017: undefined symbol "pLogged"
E:\bestgamemode.pwn(944) : warning 215: expression has no effect
E:\bestgamemode.pwn(944) : error 001: expected token: ";", but found "]"
E:\bestgamemode.pwn(944) : error 029: invalid expression, assumed zero
E:\bestgamemode.pwn(944) : fatal error 107: too many error messages on one line
Reply
#16

https://sampforum.blast.hk/showthread.php?tid=273088
Reply
#17

Quote:
Originally Posted by Speed
View Post
why udb_hash??

how to remove udb_hash from this script and i see pasword of the person?
'Scuse me, you'd like to exploit the system?
Reply
#18

How to add a new variable(like admin)?
Reply
#19

Quote:
Originally Posted by geerdinho8
View Post
How to add a new variable(like admin)?
Where are the enum of Player data, just add line Admin


I like to report one bug. I did all cool, and system works ok. I can register, it saves all good, good hashing etc etc, but after first fail to login, you'd to skin selection menu, and then u can spawn easy. Second bugis that after u failed login the first time, enter password second time will say U succsessfuly registered with password "password" and it will be new password, and that account is loaded. I use YSI 3.0.


BUG: You made a mistake @ the line when missed a password. it is foring you to DIALOG_REGISTER instead to Login. Also gtriss doesen't works.
Reply
#20

5/5 Tutorial !! And Useful
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)