[Tutorial] Blazing User Database, login and register system with dialogs.
#1

After some trial and error with SQLITE, I decided to give Slices' blazing user database a try, I liked it due to its simplicity, and since nobody else did it, I decided to make a tutorial on it.
Credits to Slice for making BUD
First thing we are going to need to do is download the BUD includes.
https://sampforum.blast.hk/showthread.php?tid=187720

Alright next open up Pawno and click on "new" .

We are going to erase all of the code inside there and begin our own.

We need to include all of SA-MP's default functions, and callbacks. While we are doing this we will also incude BUD
put this at the top of your script.

pawn Code:
#include <a_samp>
#include <Bud>
Alright next we are going to define some colors and some dialogs put this somewhere above any callback and below your includes.

pawn Code:
#define DIALOG_LOGIN 1
#define DIALOG_REGISTER 2
#define COLOR_WHITE 0xFFFFFFAA
With that finished next we are going to need, to create some variables to store the players information. Put this under the defines and above any callbacks.
pawn Code:
new
    iMoney,
    iKills,
    iDeaths,
    iAdmin,
    iRespect
;
We are going to define some more variables, these will be used for getting and holding onto a players stats until he logs out then it will be saved to the database
pawn Code:
new pMoney[MAX_PLAYERS];
new pKills[MAX_PLAYERS];
new pDeaths[MAX_PLAYERS];
new pAdmin[MAX_PLAYERS];
new pRespect[MAX_PLAYERS];
Ok next we need to add main to our game mode, I am not exactly sure why it has to be there but if it is not there when you start your server you will see " Run Time Error Bad entry point"
pawn Code:
main()
{
    print("\n----------------------------------");
    print("You Game Mode Name");
    print("----------------------------------\n");
}
Ok add this under OnGameModeInit() read the comments to see what is being done.
pawn Code:
public OnGameModeInit()
{

    BUD::Setting( opt.Database, "server.db" ); // The name of the database to create/use.
    BUD::Setting( opt.Asynchronous, true );      // true - faster, but if your computer gets stuck by ligntning when it's doing something with the database it could end up corrupted! :D
    BUD::Setting( opt.KeepAliveTime, 3000 );     // The database will be kept open for 3000ms each time it's being used; this is to save performance.
    BUD::Setting( opt.CheckForUpdates, true );   // Check for BUD updates! This is set to true by default.

    BUD::Initialize( ); // Initialize the system; this has to be called before using any functions besides BUD::Setting.

    BUD::VerifyColumn(  "Money", BUD::TYPE_NUMBER );
    BUD::VerifyColumn(   "Kills", BUD::TYPE_NUMBER ); // By using these functions, the script will make sure the columns exist if the database; if not, it create them.
    BUD::VerifyColumn(  "Deaths", BUD::TYPE_NUMBER );
    BUD::VerifyColumn(  "Admin", BUD::TYPE_NUMBER  );
    BUD::VerifyColumn(  "Respect", BUD::TYPE_NUMBER );
    AddPlayerClass(179,-357.3307,1727.1892,42.7340,145.5829,0,0,0,0,0,0);
     // The last argument is the default value; it's optional. If no default value is specified, numbers will be set to 0, and strings empty.
    return 1;
}
Alright now under OnGameModeExit we are going to want to close the database. To do this just add this.
pawn Code:
public OnGameModeExit()
{
    BUD::Exit( );
    return 1;
}
Ok now this is pretty much the heart of the login and register system, what this code does is checks if the user is registerd, if he his it directs them to the login dialog, if not he gets shown the register dialog.
pawn Code:
public OnPlayerConnect(playerid)
{
    new name[24];
    GetPlayerName(playerid, name, sizeof(name));
        SetPVarInt(playerid, "Logged", 0);
    if(BUD::IsNameRegistered( name) == true)
    {
        ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "Login", " You are registered please login to continue", "Ok", "Cancel");
    }
    else
    {
        ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_PASSWORD, "Login", " You are not registered\r\n Please type a password below", "Ok", "Cancel");
    }
    return 1;
}
Alright now we are going to make it so when the player types in a password it either registers them or logs them into the server.
pawn Code:
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
    switch(dialogid)
    {
        case DIALOG_LOGIN:
        {
            if(response) // Checks if the player selected "Ok"
            {
                new name[24], userid;//creates a variable to store the players name and unique userid.
                GetPlayerName(playerid, name, sizeof(name)); //gets name
                if(BUD::CheckAuth( name, inputtext) == false)// if the player enters a wrong password
                {
                    SendClientMessage(playerid, COLOR_WHITE, " You have entered a wrong password!");
                    ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "Login", " You are registered please login to continue", "Ok", "Cancel");

                }
                else
                {
                    userid = BUD::GetNameUID(name);
                    BUD::MultiGet(userid, "iiiii", "Money", iMoney, "Kills", iKills,"Deaths", iDeaths,"Admin", iAdmin,"Respect", iRespect);
                    printf( "   BUD::MultiGet returned:\n    money: %d\n    kills: %d\n    deaths: %d\n    res: %i",iMoney, iKills, iDeaths, iRespect );
                    GivePlayerMoney(playerid, iMoney);
                    SetPVarInt(playerid, "Logged", 1);
                    pMoney[playerid] = iMoney;
                    pKills[playerid] = iKills;
                    pDeaths[playerid] = iDeaths;
                    pAdmin[playerid] = iAdmin;
                    pRespect[playerid] = iRespect;
                }
            }
            else return Kick(playerid); // Kick the player if he selected 'Cancel'
        }
        case DIALOG_REGISTER:
        {
            new name[24], userid;//creates a variable to store the players name and unique userid.
            GetPlayerName(playerid, name, sizeof(name)); //gets name
            if(response)//checks if the player selected "ok"
            {
                BUD::RegisterName( name, inputtext );//registers the user
                userid = BUD::GetNameUID( name);
                BUD::MultiSet( userid, "iiiii", // integer, integer, integer, integer, integer.
                "Money", 5000, // gives the player who just registered 5000 dollars.
                "Kills", 0,//sets the players kills to 0
                "Deaths", 0,
                "Admin", 0,
                "Respect", 0

            );
                pMoney[playerid] = iMoney;
                pKills[playerid] = iKills;
                pDeaths[playerid] = iDeaths;
                pAdmin[playerid] = iAdmin;
                pRespect[playerid] = iRespect;
           
            }
        }
    }
    return 1;
}
Now we are going to save the users data when he disconnects
pawn Code:
public OnPlayerDisconnect(playerid, reason)
{
    if(GetPVarInt(playerid, "Logged") == 1)
    {
        new name[24], userid;
        GetPlayerName(playerid, name,sizeof(name));
        userid = BUD::GetNameUID(name);
        BUD::MultiSet(userid, "iiiii", "Money", GetPlayerMoney(playerid), "Kills", pKills[playerid],"Deaths", pDeaths[playerid],"Admin", pAdmin[playerid],"Respect", pRespect[playerid]);
       
    }
    return 1;
}
Here is an example on how to use MultiGet with floats, integers and a string. Credits to slice for this one as I just copied it from the BUD forums so people can see examples on how to save strings floats and integers.
So what this does is gets multiple data from the database.
pawn Code:
BUD::MultiSet( userid, "s[32]iiif", // string, integer, integer, integer, float
        "CarName", "pCar",// saves the persons car name to a string to the database
        "money"GetPlayerMoney(playerid),
        "kills", pKills,
        "deaths",pDeaths,
        "exp", pExp,
    );
[pawn]
Alright if you have any questions on how to do something, or suggestions to make this system better please reply in this topic. Thanks. Also here is a list of all the available BUD functions.

pawn Code:
BUD::Setting( setting[], value )
bool    BUD::Initialize( )
bool    BUD::Exit( )
        BUD::VerifyColumn( column[], type[, default value ] )
bool    BUD::IsNameRegistered( name[] )
bool    BUD::RegisterName( name[], password[] )
        BUD::UnregisterName( name[] )
bool    BUD::CheckAuth( name[], password[] )
        BUD::GetNameUID( name[] )
Float   BUD::GetFloatEntry( uid, entry[] )
        BUD::GetIntEntry( uid, entry[] )
        BUD::GetStringEntry( uid, entry[], &value[][, size ] )
bool    BUD::MultiGet( uid, type definitions, ( entry, &variable )... )
bool    BUD::MultiSet( uid, type definitions, ( entry, value )... )
bool    BUD::SetIntEntry( uid, entry[], value )
bool    BUD::SetFloatEntry( uid, entry[], Float:value )
bool    BUD::SetStringEntry( uid, entry[], value[][, size ] )

Credits to Slice for the list.
Reply
#2

Compare it to Yini. Go.
Reply
#3

How about savings strings when player disconnects? Can you give us an example? Also, for floats, booleans too.

Anyway, not very well explained, but enough for a average scripter. Good work anyhow.
Reply
#4

Quote:
Originally Posted by antonio112
View Post
How about savings strings when player disconnects? Can you give us an example? Also, for floats, booleans too.

Anyway, not very well explained, but enough for a average scripter. Good work anyhow.
What do you feel is not explained enough?Take a look at the first post I added an example on using MultiSet with
floats and integers
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)