Portal SAMP
[Ajuda] Sistema de Registro/Login MySQL - Versão de Impressão

+- Portal SAMP (https://portalsamp.com)
+-- Fórum: SA-MP (https://portalsamp.com/forumdisplay.php?fid=5)
+--- Fórum: Área de suporte (https://portalsamp.com/forumdisplay.php?fid=6)
+--- Tópico: [Ajuda] Sistema de Registro/Login MySQL (/showthread.php?tid=4920)



Sistema de Registro/Login MySQL - GuiLopeS - 18/11/2024

Olá a todos, bom preciso da ajuda de vocês em um sistema de registro/login em MySQL, eu procurei em vários lugares um sistema simples e funcional mas não achei nenhum, todos tinham ou algum erro ou informações demais, então peguei partes de alguns e juntei para ficar de uma forma simples, pois preciso criar um sistema de loja e preciso apenas de um sistema básico de registro em MySQL. Bom sem me alongar muito, o que eu preciso é que alguém de uma olhada no codigo e me diga se tem alguma coisa errada ou se tem algo para aprimorar.

Código PHP:
#include <a_samp>
#include <a_mysql>
#include <sscanf2>
#include <zcmd>

#define function%0(%1) forward %0(%1); public %0(%1)
#define    MYSQL_HOST        "localhost"
#define    MYSQL_USER        "root"
#define    MYSQL_DATABASE    "samptestes"
#define    MYSQL_PASSWORD    "" 

#define Dialog_Login    9998
#define Dialog_Register 9999

new MySQL:DBConn;

enum TPlayerData
{
    
IDp,
    
PlayerLevel,
    
PlayerMoney
    
PlayerScore,
    
PlayerCash,
    
PlayerName[MAX_PLAYER_NAME],
    
PlayerPass[24],
    
pAttempsLogin,
    
pAttempsRegister,
    
bool:pLogged,
}
new 
APlayerData[MAX_PLAYERS][TPlayerData];

main()
{
    print("\n|======================================|");
    print("|Registro e Login em MySQL para testes.|");
    print("|======================================|\n");
    return 1;
}

public 
OnGameModeInit()
{
    
SetGameModeText("GMTESTS");
    
DataBaseInit();
    return 
1;
}

public 
OnGameModeExit()
{
    
mysql_close(DBConn);
    return 
1;
}

public 
OnPlayerRequestClass(playeridclassid)
{
    
SetPlayerPos(playerid1958.37831343.157215.3746);
    
SetPlayerCameraPos(playerid1958.37831343.157215.3746);
    
SetPlayerCameraLookAt(playerid1958.37831343.157215.3746);
    return 
1;
}

public 
OnPlayerConnect(playerid)
{
    new 
Query[80];
    TogglePlayerSpectating(playerid1);
    mysql_format(DBConnQuerysizeof(Query), "SELECT `password`, `id` FROM `Players` WHERE `name`='%e'"GetPlayerNameEx(playerid));
    mysql_tquery(DBConnQuery"CheckAccount""i"playerid);
    return 
1;
}

public 
OnPlayerDisconnect(playeridreason)
{
    if(
APlayerData[playerid][pLogged] == true && reason >= 0
    {
        SaveAccount(playerid);
    }
    return 
1;
}

public 
OnDialogResponse(playeriddialogidresponselistiteminputtext[])
{
    new 
Query[125];

    switch(dialogid)
    {
        case Dialog_Register
        {
            if(!response)
                return Kick(playerid);

            if(strlen(inputtext) < || strlen(inputtext) > 24
            {
                SendClientMessage(playerid0xFF0000AA"[SERVER] Escolha uma senha entre 4 a 24 caracteres.");
                TogglePlayerSpectating(playerid1);

                ShowPlayerDialog(playeridDialog_RegisterDIALOG_STYLE_INPUT"Registro""Digite uma senha para se registrar em nosso servidor""Registrar""Sair"); 
                APlayerData[playerid][pAttempsRegister]++; 

            } else { 
                TogglePlayerSpectating(playerid0); 
                mysql_format(DBConnQuerysizeof(Query), "INSERT INTO `Players`(`name`,`password`) VALUES ('%e', '%e')"GetPlayerNameEx(playerid), inputtext);
                mysql_tquery(DBConnQuery"EnterData""i"playerid);
            }
            if(APlayerData[playerid][pAttempsRegister] == 3
            {
                    SendClientMessage(playerid0xFF0000AA"[SERVER] Limite de tentativas de registro excedida.");
                    APlayerData[playerid][pAttempsRegister] = 0
                    SetTimerEx("KickPlayerinTime"200false"i"playerid); 

            }
        }
        case Dialog_Login:
        {
            if(!response
                return Kick(playerid);

            if(!strcmp(APlayerData[playerid][PlayerPass], inputtexttrue24)) 
            
                TogglePlayerSpectating(playerid0); 
                mysql_format(DBConnQuerysizeof(Query), "SELECT * FROM Players WHERE name='%e'"GetPlayerNameEx(playerid)); 
                mysql_tquery(DBConnQuery"LoadAccount""i"playerid); 

                SendClientMessage(playerid0x80FF00AA"[Server] Logado com sucesso.");
            } else { 
                TogglePlayerSpectating(playerid1);
                SendClientMessage(playerid0xFF0000AA"[SERVER] Senha errada, tente novamente.");
                APlayerData[playerid][pAttempsLogin]++;
                ShowPlayerDialog(playeridDialog_LoginDIALOG_STYLE_PASSWORD"Login""Digite sua senha para entrar em nosso servidor.""Confirmar""Sair");
            }
            if(APlayerData[playerid][pAttempsLogin] == 3
            {
                SendClientMessage(playerid0xFF0000AA"[SERVER] Limite de tentativas de login excedida."); 
                APlayerData[playerid][pAttempsLogin] = 0;
                SetTimerEx("KickPlayerinTime"200false"i"playerid);
            }
        }
    }
    return 
1;
}

function 
SaveAccount(playerid)
{
    if(APlayerData[playerid][pLogged] == false
        return 0;

    new Query[200];

    APlayerData[playerid][PlayerMoney] = GetPlayerMoney(playerid); 
    APlayerData[playerid][PlayerScore] = GetPlayerScore(playerid);

    mysql_format(DBConnQuerysizeof(Query), "UPDATE Players SET \
    name='%e',\
    password='%e',\
    admin='%d',\
    score='%d',\
    money='%d', \
    cash='%d' WHERE id='%d'"
APlayerData[playerid][PlayerName],
                                    
APlayerData[playerid][PlayerPass],
                                    APlayerData[playerid][PlayerLevel], 
                                    APlayerData[playerid][PlayerScore],
                                    APlayerData[playerid][PlayerMoney],
                                    APlayerData[playerid][PlayerCash],                               
                                    APlayerData
[playerid][IDp]);
    mysql_query(DBConnQuery); 

    printf("[MYSQL] Dados do Jogador %s ID %d salvo com sucesso"GetPlayerNameEx(playerid), APlayerData[playerid][IDp]);

    return 1;


function 
LoadAccount(playerid)
{
    APlayerData[playerid][pLogged] = true

    cache_get_value_int(0"id"APlayerData[playerid][IDp]); 
    cache_get_value_name(0"name"APlayerData[playerid][PlayerName]); 
    cache_get_value_name(0"password"APlayerData[playerid][PlayerPass]); 
    cache_get_value_int(0"admin"APlayerData[playerid][PlayerLevel]);
    cache_get_value_int(0"score"APlayerData[playerid][PlayerScore]);
    cache_get_value_int(0"money"APlayerData[playerid][PlayerMoney]);
    cache_get_value_int(0"cash"APlayerData[playerid][PlayerCash]);

    SetPlayerScore(playeridAPlayerData[playerid][PlayerScore]); 
    GivePlayerMoney(playeridAPlayerData[playerid][PlayerMoney]);
    
SetSpawnInfo(playerid01221958.37831343.157215.3746269.1425000000);
    
SpawnPlayer(playerid);
    return 1;


function 
EnterData(playerid)
{
    new Query[50];

    APlayerData[playerid][IDp] = cache_insert_id();
    printf("[MYSQL] Jogador %s registrado como ID %d"GetPlayerNameEx(playerid), APlayerData[playerid][IDp]);

    mysql_format(DBConnQuerysizeof(Query), "SELECT * FROM Players WHERE id='%i'"APlayerData[playerid][IDp]); 
    mysql_query(DBConn,Query); 

    LoadAccount(playerid); 
    return 1;


function 
CheckAccount(playerid)
{
    if(cache_num_rows() > 0
    {
        cache_get_value_name(0"password"APlayerData[playerid][PlayerPass], 24);
        ShowPlayerDialog(playeridDialog_LoginDIALOG_STYLE_PASSWORD"Login""Digite sua senha para entrar em nosso servidor.""Confirmar""Sair");
    }else{ 
        ShowPlayerDialog(playeridDialog_RegisterDIALOG_STYLE_INPUT"Registro""Digite uma senha para se registrar em nosso servidor""Registrar""Sair");
    }
    return 1;


function 
DataBaseInit()
{
    DBConn mysql_connect(MYSQL_HOSTMYSQL_USERMYSQL_PASSWORDMYSQL_DATABASE);
    if(mysql_errno() == 0)
    {
        printf("[MySQL] Database '%s' conectada com sucesso!"MYSQL_DATABASE);
        print("[MySQL] Verificando tabelas...");
 
        mysql_query(DBConn"CREATE TABLE IF NOT EXISTS Players (\
        id int NOT NULL AUTO_INCREMENT,\
        name varchar(25) NOT NULL,\
        password varchar(255) NOT NULL,\
        admin int DEFAULT 0,\
        score int DEFAULT 500,\
        money int DEFAULT 1000,\
        cash int DEFAULT 0,\
        PRIMARY KEY(id));"
false);

        print("[MySQL] Tabela 'Players' verificada com sucesso!");
    }
    else
    {
        printf("[MySQL] ERRO: Não foi possível se conectar a database '%s'!"MYSQL_DATABASE);
        SendRconCommand("exit");
    }
    return 1;
}

function 
KickPlayerinTime(playerid) return Kick(playerid);

stock GetPlayerNameEx(playerid)
{
    new 
PlayerName2[MAX_PLAYER_NAME];
    
GetPlayerName(playeridPlayerName2sizeof(PlayerName2));
    return 
PlayerName2;


Só para salientar, fiz alguns testes e a principio está tudo funcionando, e não consta nenhum erro nos logs, mas sou novo em MySQL então pode ter algo de errado que não tenha percebido por isso peço essa ajuda.

Desde já agradeço pela atenção!


RE: Sistema de Registro/Login MySQL - xbruno1000x - 18/11/2024

Eu acredito que poderia melhorar o armazenamento das senhas, está sendo armazenando sem nenhuma criptografia pelo que vi. Usar hashing nas senhas em um servidor SA-MP (ou qualquer aplicação) é essencial para garantir a segurança dos dados dos jogadores. Mesmo em servidores "simples" ou de uso fechado, a prática de armazenar senhas de forma segura é uma precaução fundamental para evitar riscos que podem impactar o servidor.

Bibliotecas que podem ser usadas:

bcrypt:
https://github.com/Sreyas-Sreelal/samp-bcrypt

SHA256_PassHash(nativo porém deprecated):
https://www.open.mp/docs/scripting/functions/SHA256_PassHash