[Ayuda] SQLite login/registro
#3

pawn Код:
// ** INCLUDES

#include <a_samp>

// ** NATIVES

// *** WHIRLPOOL

native WP_Hash(buffer[], len, const str[]);

// ** DEFINES

// *** GENERAL

#define MAX_LOGIN_ATTEMPTS 3

// *** FUNCTIONS

#define isnull(%1) ((!(%1[0])) || (((%1[0]) == '\1') && (!(%1[1]))))
#define strcat_format(%0,%1,%2) format(%0[strlen(%0)], %1 - strlen(%0), %2)

// *** DIALOGS

#define DIALOG_REGISTER 0
#define DIALOG_CONFIRM_REGISTER 1
#define DIALOG_LOGIN 2

// *** PLAYER RESET TYPES

#define PLAYER_RESET_CONNECT 0
#define PLAYER_RESET_DISCONNECT 1

// *** DATABASE

// **** PATHS

#define DATABASE_PATH "database.db"

// **** TABLES

// ***** USERS

// ****** GENERAL

#define TABLE_USERS "USERS"

// ****** CONTENT

#define USER_SQL_ID "sql_id"
#define USER_NAME "name"
#define USER_PASSWORD "password"
#define USER_IP_ADDRESS "ip_address"
#define USER_SCORE "score"
#define USER_CASH "cash"
#define USER_ADMIN_LEVEL "admin_level"

// ** COLORS

// *** GENERAL

#define COLOR_WHITE 0xFFFFFFFF
#define COL_WHITE "{FFFFFF}"

#define COLOR_RED 0xFF0000FF
#define COL_RED "{FF0000}"

// *** CUSTOM

#define COLOR_ACCOUNT 0x37E9A0FF
#define COL_ACCOUNT "{37E9A0}"

// ** ARRAYS AND ENUMERATORS
   
enum eUserInfo
{
    user_info_sql_id,
    user_info_score,
    user_info_cash,
    user_info_admin_level
}

new aUserInfo[MAX_PLAYERS][eUserInfo];

// ** VARIABLES

// *** GLOBAL VARIABLES

// **** DATABASE

new DB:database;

// *** PER-PLAYER VARIABLES

// **** GENERAL

new pPasswordHash[MAX_PLAYERS][129],
pLoginAttempts[MAX_PLAYERS];

// **** PLAYER STATES

new bool:psSignedIn[MAX_PLAYERS] = false;

// ** HOOKS

stock Hook_SetPlayerScore(playerid, score)
{
    aUserInfo[playerid][user_info_score] = score;
    return SetPlayerScore(playerid, score);
}

#if defined _ALS_SetPlayerScore
    #undef SetPlayerScore
#else
    #define _ALS_SetPlayerScore
#endif
#define SetPlayerScore Hook_SetPlayerScore

// ** MAIN

main()
{
    print("Loaded \"sqlite_login_system.amx\".");
}

// ** CALLBACKS

public OnGameModeInit()
{  
    LoadDatabase();
    return 1;
}

public OnGameModeExit()
{
    db_close(database);
    return 1;
}

public OnPlayerConnect(playerid)
{  
    TogglePlayerSpectating(playerid, true);

    ResetPlayerVariables(playerid, PLAYER_RESET_CONNECT);

    new query[300], DBResult:result;
    strcat(query, "SELECT `"#USER_SQL_ID"`");
    strcat(query, " FROM `"#TABLE_USERS"`");
    strcat_format(query, sizeof(query), " WHERE `"#USER_NAME"` = '%q' COLLATE NOCASE LIMIT 1", ReturnPlayerName(playerid));
    result = db_query(database, query);

    if(db_num_rows(result))
    {
        aUserInfo[playerid][user_info_sql_id] = db_get_field_assoc_int(result, USER_SQL_ID);

        ShowLoginDialog(playerid);
    }
    else
    {
        ShowRegisterDialog(playerid);
    }

    db_free_result(result);
    return 1;
}

public OnPlayerDisconnect(playerid, reason)
{
    if(IsPlayerSignedIn(playerid))
    {
        new query[400];
        strcat(query, "UPDATE `"#TABLE_USERS"` SET ");
        strcat_format(query, sizeof(query), "`"#USER_SCORE"` = '%d',", aUserInfo[playerid][user_info_score]);
        strcat_format(query, sizeof(query), "`"#USER_CASH"` = '%d',", aUserInfo[playerid][user_info_cash]);
        strcat_format(query, sizeof(query), "`"#USER_ADMIN_LEVEL"` = '%d'", aUserInfo[playerid][user_info_admin_level]);
        strcat_format(query, sizeof(query), " WHERE `"#USER_SQL_ID"` = '%d'", aUserInfo[playerid][user_info_sql_id]);
        db_query(database, query);
    }

    ResetPlayerVariables(playerid, PLAYER_RESET_DISCONNECT);
    return 1;
}

public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
    switch(dialogid)
    {
        case DIALOG_REGISTER:
        {
            if(!response)
            {
                KickPlayer(playerid);
            }
            else if(response)
            {
                if(isnull(inputtext))
                {
                    ShowRegisterDialog(playerid);
                }
                else if(strlen(inputtext) < 3)
                {
                    ShowRegisterDialog(playerid);

                    SendClientMessage(playerid, COLOR_RED, "Your password is too short, please try again.");
                }
                else if(strlen(inputtext) > 20)
                {
                    ShowRegisterDialog(playerid);

                    SendClientMessage(playerid, COLOR_RED, "Your password is too long, please try again.");
                }
                else
                {
                    WP_Hash(pPasswordHash[playerid], 129, inputtext);

                    ShowConfirmPasswordDialog(playerid);
                }
            }
        }
        case DIALOG_CONFIRM_REGISTER:
        {
            if(!response)
            {
                ShowRegisterDialog(playerid);
            }
            else if(response)
            {
                new hash[129];
                WP_Hash(hash, sizeof(hash), inputtext);

                if(isnull(inputtext))
                {
                    ShowConfirmPasswordDialog(playerid);
                }
                else if(!strcmp(pPasswordHash[playerid], hash, true))
                {
                    new name[MAX_PLAYER_NAME];
                    GetPlayerName(playerid, name, MAX_PLAYER_NAME);

                    new query_1[500];
                    strcat(query_1, "INSERT INTO `"#TABLE_USERS"` (");
                    strcat(query_1, "`"#USER_NAME"`,");
                    strcat(query_1, "`"#USER_PASSWORD"`,");
                    strcat(query_1, "`"#USER_IP_ADDRESS"`,");
                    strcat(query_1, "`"#USER_SCORE"`,");
                    strcat(query_1, "`"#USER_CASH"`,");
                    strcat(query_1, "`"#USER_ADMIN_LEVEL"`");
                    strcat(query_1, ") VALUES (");

                    strcat_format(query_1, sizeof(query_1), "'%q',", name); // USER_NAME
                    strcat_format(query_1, sizeof(query_1), "'%q',", hash); // USER_PASSWORD
                    strcat_format(query_1, sizeof(query_1), "'%q',", GetPlayerIP(playerid)); // USER_IP_ADDRESS
                    strcat(query_1, "'0',"); // USER_SCORE
                    strcat(query_1, "'0',"); // USER_CASH
                    strcat(query_1, "'0')"); // USER_ADMIN_LEVEL
                    db_query(database, query_1);

                    new query_2[300], DBResult:result;
                    strcat(query_2, "SELECT `"#USER_SQL_ID"`");
                    strcat(query_2, " FROM `"#TABLE_USERS"`");
                    strcat_format(query_2, sizeof(query_2), " WHERE `"#USER_NAME"` = '%q' COLLATE NOCASE LIMIT 1", name);
                    result = db_query(database, query_2);

                    aUserInfo[playerid][user_info_sql_id] = db_get_field_assoc_int(result, USER_SQL_ID);

                    db_free_result(result);

                    TogglePlayerSpectating(playerid, false);

                    psSignedIn[playerid] = true;

                    SendClientMessage(playerid, COLOR_ACCOUNT, "You have successfully registered your account.");
                }
                else
                {
                    ShowConfirmPasswordDialog(playerid);

                    SendClientMessage(playerid, COLOR_RED, "That's not the same password as the first one.");
                }
            }
        }
        case DIALOG_LOGIN:
        {
            if(!response)
            {
                KickPlayer(playerid);
            }
            else if(response)
            {
                if(isnull(inputtext))
                {
                    ShowLoginDialog(playerid);
                }
                else
                {
                    new hash[129];
                    WP_Hash(hash, sizeof(hash), inputtext);

                    new query_1[500], DBResult:result;
                    strcat(query_1, "SELECT `"#USER_PASSWORD"`,");
                    strcat(query_1, "`"#USER_IP_ADDRESS"`,");
                    strcat(query_1, "`"#USER_SCORE"`,");
                    strcat(query_1, "`"#USER_CASH"`,");
                    strcat(query_1, "`"#USER_ADMIN_LEVEL"`");
                    strcat(query_1, " FROM `"#TABLE_USERS"`");
                    strcat(query_1, " WHERE `"#USER_SQL_ID"` = '%d' COLLATE NOCASE LIMIT 1", aUserInfo[playerid][user_info_sql_id]);
                    result = db_query(database, query_1);

                    if(db_num_rows(result))
                    {
                        new real_hash[129];
                        db_get_field_assoc(result, USER_PASSWORD, real_hash, sizeof(real_hash));

                        if(!isnull(real_hash) && !strcmp(real_hash, hash, true))
                        {
                            new ip_address[16], current_ip_address[16];
                            GetPlayerIp(playerid, ip_address, sizeof(ip_address));

                            db_get_field_assoc(result, USER_IP_ADDRESS, current_ip_address, sizeof(current_ip_address));

                            if(strcmp(ip_address, current_ip_address, true))
                            {
                                new query_2[128];
                                strcat(query_2, "UPDATE `"#TABLE_USERS"` SET ");
                                strcat_format(query_2, sizeof(query_2), "`"#USER_IP_ADDRESS"` = '%q'", ip_address);
                                strcat_format(query_2, sizeof(query_2), " WHERE `"#USER_SQL_ID"` = '%d'", aUserInfo[playerid][user_info_sql_id]);
                                db_query(database, query_2);
                            }

                            TogglePlayerSpectating(playerid, false);

                            SetPlayerScore(playerid, db_get_field_assoc_int(result, USER_SCORE));
                            SetPlayerMoney(playerid, db_get_field_assoc_int(result, USER_CASH));

                            aUserInfo[playerid][user_info_admin_level] = db_get_field_assoc_int(result, USER_ADMIN_LEVEL);

                            psSignedIn[playerid] = true;

                            SendClientMessage(playerid, COLOR_ACCOUNT, "You have successfully logged into your account.");
                        }
                        else
                        {
                            new string[144];
                            pLoginAttempts[playerid] ++;

                            format(string, sizeof(string), "Incorrect password. Attempts left: %d.", (MAX_LOGIN_ATTEMPTS - pLoginAttempts[playerid]));
                            SendClientMessage(playerid, COLOR_RED, string);

                            if(pLoginAttempts[playerid] == MAX_LOGIN_ATTEMPTS)
                            {
                                KickPlayer(playerid);
                            }
                            else
                            {
                                ShowLoginDialog(playerid);
                            }
                        }
                    }

                    db_free_result(result);
                }
            }
        }
    }
    return 1;
}

// ** FUNCTIONS

// *** LOAD COMPONENTS

stock LoadDatabase()
{
    database = db_open(DATABASE_PATH);

    new query_1[400];
    strcat(query_1, "CREATE TABLE IF NOT EXISTS `"#TABLE_USERS"` (");
    strcat(query_1, "`"#USER_SQL_ID"` INTEGER PRIMARY KEY AUTOINCREMENT,");
    strcat(query_1, "`"#USER_NAME"` TEXT,");
    strcat(query_1, "`"#USER_PASSWORD"` TEXT,");
    strcat(query_1, "`"#USER_IP_ADDRESS"` TEXT,");
    strcat(query_1, "`"#USER_SCORE"` INTEGER,");
    strcat(query_1, "`"#USER_CASH"` INTEGER,");
    strcat(query_1, "`"#USER_ADMIN_LEVEL"` INTEGER)");
    db_query(database, query_1);
    return 1;
}

// *** LOAD PER-PLAYER VARIABLES

stock ResetPlayerVariables(playerid, reset_type)
{
    switch(reset_type)
    {
        case PLAYER_RESET_CONNECT:
        {
            // ** ARRAYS AND ENUMERATORS

            aUserInfo[playerid][user_info_sql_id] = 0;
            aUserInfo[playerid][user_info_score] = 0;
            aUserInfo[playerid][user_info_cash] = 0;
            aUserInfo[playerid][user_info_admin_level] = 0;
        }
        case PLAYER_RESET_DISCONNECT:
        {
            // ** GENERAL

            pLoginAttempts[playerid] = 0;

            // ** PLAYER STATES

            psSignedIn[playerid] = false;
        }
    }
    return 1;
}

// *** GENERAL

stock GetPlayerIP(playerid)
{
    new ip_address[16];
    GetPlayerIp(playerid, ip_address, sizeof(ip_address));
    return ip_address;
}

stock ShowRegisterDialog(playerid)
{
    new string[256];
    strcat_format(string, sizeof(string), "{FFFFFF}Welcome, %s!\n\n", ReturnPlayerName(playerid));
    strcat(string, "You must register to play here.");
    ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_PASSWORD, "Register", string, "Next", "Close");
    return 1;
}

stock ShowConfirmPasswordDialog(playerid)
{
    new string[256];
    strcat_format(string, sizeof(string), "{FFFFFF}Welcome, %s!\n\n", ReturnPlayerName(playerid));
    strcat(string, "You must confirm your registration to play here.");
    ShowPlayerDialog(playerid, DIALOG_CONFIRM_REGISTER, DIALOG_STYLE_PASSWORD, "Confirm Registration", string, "Register", "Back");
    return 1;
}

stock ShowLoginDialog(playerid)
{
    new string[256];
    strcat_format(string, sizeof(string), "{FFFFFF}Welcome back, %s!\n\n", ReturnPlayerName(playerid));
    strcat(string, "You must log into play here.");
    ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "Log In", string, "Log In", "Close");
    return 1;
}

stock ReturnPlayerName(playerid)
{
    new name[MAX_PLAYER_NAME];
    GetPlayerName(playerid, name, MAX_PLAYER_NAME);
    return name;
}

stock SetPlayerMoney(playerid, cash)
{
    aUserInfo[playerid][user_info_cash] = cash;

    ResetPlayerMoney(playerid);
    return GivePlayerMoney(playerid, cash);
}

stock KickPlayer(playerid)
{
    SetTimerEx("KickPlayerAction", 100, false, "i", playerid);
    return 1;
}

forward KickPlayerAction(playerid);
public KickPlayerAction(playerid)
{
    return Kick(playerid);
}

forward bool:IsPlayerSignedIn(playerid);
public bool:IsPlayerSignedIn(playerid)
{
    return psSignedIn[playerid];
}
Reply


Messages In This Thread
[Ayuda] SQLite login/registro - by lucas95akd - 07.03.2016, 22:11
Re: [Ayuda] SQLite login/registro - by F1N4L - 07.03.2016, 23:32
Re: [Ayuda] SQLite login/registro - by SickAttack - 08.03.2016, 01:54

Forum Jump:


Users browsing this thread: 1 Guest(s)