[Tutorial] Sistema de Login/Registro MySQL R41-4
#1

Login e Registro em MySQL R41-4
Feito por: Cauezin

Este tutorial foi feito por um programador novato para programadores novatos com a funзгo de tentar explicar como funciona e como fazer um sistema de Login/Registro em MySQL R41-4 do jeito mais fбcil de entender possнvel.

LEMBRE-SE FOI FEITO PRA SER UM SISTEMA SIMPLES, SУ PRA ENTENDER O BБSICO.

Primeiro de tudo, o que й MySQL?

O MySQL й um sistema de gerenciamento de banco de dados, que utiliza a linguagem SQL como interface.

O que й um banco de dados?

Bancos de dados ou bases de dados sгo conjuntos de arquivos relacionados entre si com registros sobre pessoas, lugares ou coisas.

Agora a grande pergunta, como utilizar ele para fazer um sistema de login e registro no SA-MP?

Isso por incrнvel que parece й atй bastante simples, provavelmente vocк pulando os passos, vai achar que й algo extremamente difнcil, um bicho de 7 cabeзas.
Mas seguindo os passos um a um, corretamente, vocк vai descobrir que й extremamente simples mexer com esse tipo de gerenciamento de banco de dados.

Agora chega de falaзгo e vamos ao trabalho.

[ 1 ] -> Instalaзгo do servidor

No caso desse tutorial utilizaremos o XAMPP, vocк pode baixar gratuitamente no link abaixo.
Caso tenha problemas na instalaзгo procure no ******* como instalar corretamente, mas nгo tem mistйrio.

XAMPP

[ 2 ] -> Utilizando o servidor e criando o banco de dados e a tabela

Quando vocк abrir o XAMPP vai se deparar com isso, agora faзa a mesma coisa que й feito nessa sequencia de imagens.









[ * ] Agora vamos entender o que vocк fez

Vocк executou o XAMPP.
Iniciou os servidores.
Entrou no servidor e criou o banco de dados.
Criou a tabela, dentro do banco de dados.

[ * ] Agora vamos entender a tabela

PHP Code:

CREATE TABLE 
`jogadores`(`pIDint AUTO_INCREMENT PRIMARY KEY,
                        `
pNomevarchar(24),
                        `
pSenhavarchar(24),
                        `
pDinheiroint(12) DEFAULT 500,
                        `
pScoreint(6),
                        `
pSkinint(4) DEFAULT 60,
                        `
pPosXfloat DEFAULT -2240.9197,
                        `
pPosYfloat DEFAULT 252.0263,
                        `
pPosZfloat DEFAULT 35.3203,
                        `
pPosAfloat DEFAULT 91.2125
Vocк criou a tabela "jogadores" com a coluna do "ID" da conta do player, o "nome" do player, a "senha" do player, o "dinheiro" do player, o "score" do player, a "skin" do player, a coordenada "X" do player, a coordenada "Y" do player, a coordenada "Z" do player, a coordenada "A" do player.

Mas temos coisas diferentes em algumas colunas.

Temos 3 tipos de valores armazenados na nossa tabela
Vou explicar de um jeito leigo, porйm й facilmente entendido.

varchar -> nъmeros e letras;
int -> nъmeros;
float -> nъmeros com virgula;

Mas tambйm sгo de outro tipo

Default -> Sгo colunas com valores padrгo, quando vocк criar uma nova linha, eles vгo ter sempre aquele valor.

Ali no caso eu botei o dinheiro do player com default 500, assim quando ele iniciar no servidor, jб vai ter $500, a skin default 60, ele jб vai comeзar com a skin id 60 e o mesmo se aplica nas coordenadas, ele vai nascer naquelas coordenadas.


[ 2 ] -> Criaзгo da GM

Vocк primeiro precisa da include, que pode ser encontrada no link abaixo.

Include

Vamos seguir a linha de raciocнnio que o player seguiria ao entrar no servidor pela primeira vez.

Entrar no server -> Se Registrar -> Sair -> Entrar no server -> Logar

Vamos preparar a бrea.

Primeiro adicionaremos a include na GM.

PHP Code:

#include <a_samp>
#include <a_mysql> 
Definiremos algumas coisas.

PHP Code:

#define HOST "localhost"
o IP do servidorno caso й hospedado no nosso computadorentгo localhost ou 127.0.0.1
#define USER "root"
Como estamos hospedando em nosso computador й root.
#define DTBS "samp"
O nome do banco de dados que vocк criou no inicio
#define PASS ""
Hospedado no computador nгo tem senha
PHP Code:

#define Dialog_Login 1
#define Dialog_Registro 2
Dialog do Login e Registronгo й necessбriomas fica melhor
Teremos que criar a ENUM com as variбveis que utilizaremos no player.

PHP Code:

enum PlayerInfos
{
    
pID,
    
pSenha[24],
    
pDinheiro,
    
pScore,
    
pSkin,
    
Float:pPosX,
    
Float:pPosY,
    
Float:pPosZ,
    
Float:pPosA,
Abaixo utilizaremosporйm nгo sera salvo na tabela.
    
pTentativasLogin
// Caso ele erre a senha, sera contabilizado.
    
pTentativasRegistro,
// Caso ele nгo cumpra o necessбrio para o registro, sera contabilizado.
    
bool:pLogado
// Utilizaremos para saber se o player estб logado ou nгo no servidor.
}
new 
Player[MAX_PLAYERS][PlayerInfos];
//Criaremos uma variбvel do Player, para utilizar com a ENUM.
new MySQL:ConexaoSQL;
//Essa й para utilizar na parte do MySQL. 
As forwards serгo criadas adiantadas.

PHP Code:

forward VerificarContaSQL
(playerid);
// Verifica se ele tem conta registrada
forward InserirDadosSQL(playerid);
// Insere os dados na tabela e cria a conta do player
forward CarregarContaSQL(playerid);
// Carrega a conta do player
forward SalvarContaSQL(playerid);
// Salva a conta do player
forward KickPlayerinTime(playerid);
// Utilizaremos com um timer, pra antes de ser kickado ele saiba o motivo. 
Crie a public do KickPlayerinTime e a stock GetPlayerNameEx, serгo necessбrias logo no inнcio.
Coloque elas no fim da sua GM.

PHP Code:

// Ela sу tem a funзгo de kickar o player quando acionado.
public KickPlayerinTime(playerid)
{
    return 
Kick(playerid);
}
// Pega o nome do player acionado.
stock GetPlayerNameEx(playerid)
{
    static 
pname[MAX_PLAYER_NAME];
    
GetPlayerName(playeridpnameMAX_PLAYER_NAME);
    return 
pname;

Primeira coisa que o server precisa й conectar no servidor do banco de dados.

PHP Code:

public OnGameModeInit()
{
    
ConexaoSQL mysql_connect(HOST,USER,PASS,DTBS);
// Define a variбvel MySQL como mysql_connect e conecta no servidor do banco de dados.
     
if(mysql_errno(ConexaoSQL) != 0
     { 
// Caso o servidor esteja desligado, vocк nгo ter criado o banco de dados ou algum erro, ele nгo se conecta e te avisa.
        
print("[MySQL] Falha ao tentar estabelecer conexгo com o banco de dados.");
    } else {
// Caso de tudo certo, ele tambйm te avisa.
        
print("[MySQL] Sucesso ao conectar com o banco de dados.");
    }
    return 
1;

Agora vamos ao quando player entrar no servidor, precisamos verificar se ele tem conta ou nгo.

PHP Code:

public OnPlayerConnect(playerid)
{
    new 
Query[90];
    
TogglePlayerSpectating(playerid1);// Isso daqui й sу pra sumir o botгo de spawn, tem vбrios dele espalhado pelo code.
    
mysql_format(ConexaoSQLQuerysizeof(Query), "SELECT `pSenha`, `pID` FROM `Jogadores` WHERE `pNome`='%e'"GetPlayerNameEx(playerid));
// Ele seleciona as colunas "pSenha" e "pID" da tabela jogadores AONDE o nome й igual do player.
    
mysql_tquery(ConexaoSQLQuery"VerificarContaSQL""i"playerid);
// Logo depois de selecionar ele aciona a funзгo para Verificar se ele tem conta ou nгo.
    
return 1;

PHP Code:

public VerificarContaSQL(playerid)
{
    if(
cache_num_rows() > 0// Se for > 0 , existe uma linha com o nome do player, entгo ele tem conta.
    
{
        
cache_get_value_name(0"pSenha"Player[playerid][pSenha], 24); // Jб puxa a senha pra comparar se й igual a que ele vai digitar no dialog.
        
ShowPlayerDialog(playeridDialog_LoginDIALOG_STYLE_PASSWORD"Login""Digite sua senha para entrar em nosso servidor.""Confirmar""Sair");
// Abre o dialog pra logar
    
}else{ // Se nгo for > 0 , nгo existe, ele nгo estб registrado.
        
ShowPlayerDialog(playeridDialog_RegistroDIALOG_STYLE_INPUT"Registro""Digite uma senha para se registrar em nosso servidor""Registrar""Sair");
// Abre o dialog pra se registrar
    
}
    return 
1;

Vamos comeзar pelo registro, utilizaremos um sistema de switch, algo bбsico.

PHP Code:

public OnDialogResponse(playeriddialogidresponselistiteminputtext[])
{
    new 
Query[125];
    switch(
dialogid)
    {
        case 
Dialog_Registro
        {
            if(!
response// Se ele apertar esc ou na segunda opзгo, vai ser kickado
                
return Kick(playerid);
            if(
strlen(inputtext) < || strlen(inputtext) > 24// Se o que ele digitou for menor 4 e maior que 24, a senha nгo sera aceita
            
{
                
SendClientMessage(playerid0xFF0000AA"[SERVER] Escolha uma senha entre 4 a 24 caracteres.");
                
TogglePlayerSpectating(playerid1);
                
ShowPlayerDialog(playeridDialog_RegistroDIALOG_STYLE_INPUT"Registro""Digite uma senha para se registrar em nosso servidor""Registrar""Sair"); // Mostra o dialog para ele tentar de novo.
                
Player[playerid][pTentativasRegistro]++; // Adiciona +1 ao erro.
            
} else { // Se a senha for aceitavel, no caso entre 4 a 24 caracteres
                
TogglePlayerSpectating(playerid0); // Tira ele de espectador, agora ele vai entrar no server
                
mysql_format(ConexaoSQLQuerysizeof(Query), "INSERT INTO `jogadores`(`pNome`,`pSenha`) VALUES ('%e', '%e')"GetPlayerNameEx(playerid), inputtext);
// Vai inserir na tabela jogares, nas colunas pNome e pSenha os seguintes valores, o nome do player que ele puxou com a stock e o que ele digitou, o inputtext.
                
mysql_tquery(ConexaoSQLQuery"InserirDadosSQL""i"playerid);
// Ele vai executar o comando acima e vai acionar a funзгo de inserir o ID e criar a conta do player
            
}
            if(
Player[playerid][pTentativasRegistro] == 3// Se ele errar mais de 3 vezes vai ser kickado
            
{
                    
SendClientMessage(playerid0xFF0000AA"[SERVER] Limite de tentativas de registro excedida.");
                    
Player[playerid][pTentativasRegistro] = 0// Zerar a variбvel pra caso um outro jogador entre, nгo comeзe com 3 na variбvel
                    
SetTimerEx("KickPlayerinTime"200false"i"playerid); // ele й kickado 200 milisegundos apos isso acontecer, tempo suficiente pra ver a mensagem e ser kickado.
            
}
        }
}
return 
1;

Vamos agora inserir todos os dados na conta e carregar ela.

PHP Code:

public InserirDadosSQL(playerid)
{
    new 
Query[90];
    
Player[playerid][pID] = cache_insert_id(); // Adiciona o id no player
    
printf("[MYSQL] Jogador %s registrado como ID %d"GetPlayerNameEx(playerid), Player[playerid][pID]); // Apenas um debug, pra saber se deu tudo certo.
    
mysql_format(ConexaoSQLQuerysizeof(Query), "SELECT * FROM jogadores WHERE pID='%i'"Player[playerid][pID]); // Seleciona todas as informaзхes desse player AONDE o id dele й o id dele
    
mysql_query(ConexaoSQL,Query); // Executa o comando acima
    
CarregarContaSQL(playerid); // Ele carrega a conta.
    
return 1;

Vamos agora carregar a conta.

PHP Code:

public CarregarContaSQL(playerid)
{
    
Player[playerid][pLogado] = true// Seta a variбvel bool, como true, no caso fala como se vocк tivesse logado.
    
cache_get_value_int(0"pID"Player[playerid][pID]); // Carrega o id e armazena nessa variбvel "Player[playerid][pID]"
    
cache_get_value_int(0"pDinheiro"Player[playerid][pDinheiro]); // A mesma coisa nesse e nas outras sу que com outra variбvel
    
cache_get_value_int(0"pScore"Player[playerid][pScore]); 
    
cache_get_value_int(0"pSkin"Player[playerid][pSkin]);
    
cache_get_value_float(0"pPosX"Player[playerid][pPosX]);
    
cache_get_value_float(0"pPosY"Player[playerid][pPosY]);
    
cache_get_value_float(0"pPosZ"Player[playerid][pPosZ]);
    
cache_get_value_float(0"pPosA"Player[playerid][pPosA]);
// Ele aplica as informaзхes igame
    
SetPlayerScore(playeridPlayer[playerid][pScore]);  // seta o score com a variavel do score
    
GivePlayerMoney(playeridPlayer[playerid][pDinheiro]); // seta o dinheiro com a variavel do dinheiro
// Etc....
    
SetSpawnInfo(playerid0Player[playerid][pSkin], Player[playerid][pPosX], Player[playerid][pPosY], Player[playerid][pPosZ], Player[playerid][pPosA], 000,00);
    
SpawnPlayer(playerid); //Spawna o player
    
SetPlayerSkin(playeridPlayer[playerid][pSkin]);
// Seta a skin dele, porquк as vezes pode bugar no SetSpawnInfo e aparecer a skin do CJ
    
return 1;

Basicamente essa й a parte de registro, caso vocк tenha feito tudo certo, quando ligar no seu servidor vocк vai conseguir se registrar normalmente e jogar normalmente, sу que quando sair do servidor, nгo vai conseguir logar, porque ainda nгo existe a dialog de login.

Entгo vamos lб.

Vamos voltar em OnDialogResponse

PHP Code:
public OnDialogResponse(playeriddialogidresponselistiteminputtext[])
{
    new 
Query[125];
    switch(
dialogid)
    {
        case 
Dialog_Registro
        {
            if(!
response// Se ele apertar esc ou na segunda opзгo, vai ser kickado
                
return Kick(playerid);
            if(
strlen(inputtext) < || strlen(inputtext) > 24// Se o que ele digitou for menor 4 e maior que 24, a senha nгo sera aceita
            
{
                
SendClientMessage(playerid0xFF0000AA"[SERVER] Escolha uma senha entre 4 a 24 caracteres.");
                
TogglePlayerSpectating(playerid1);
                
ShowPlayerDialog(playeridDialog_RegistroDIALOG_STYLE_INPUT"Registro""Digite uma senha para se registrar em nosso servidor""Registrar""Sair"); // Mostra o dialog para ele tentar de novo.
                
Player[playerid][pTentativasRegistro]++; // Adiciona +1 ao erro.
            
} else { // Se a senha for aceitavel, no caso entre 4 a 24 caracteres
                
TogglePlayerSpectating(playerid0);
                
mysql_format(ConexaoSQLQuerysizeof(Query), "INSERT INTO `jogadores`(`pNome`,`pSenha`) VALUES ('%e', '%e')"GetPlayerNameEx(playerid), inputtext);
// Vai inserir na tabela jogares, nas colunas pNome e pSenha os seguintes valores, o nome do player que ele puxou com a stock e o que ele digitou, o inputtext.
                
mysql_tquery(ConexaoSQLQuery"InserirDadosSQL""i"playerid);
// Ele vai executar o comando acima e vai acionar a funзгo de inserir o ID e criar a conta do player
            
}
            if(
Player[playerid][pTentativasRegistro] == 3// Se ele errar mais de 3 vezes vai ser kickado
            
{
                    
SendClientMessage(playerid0xFF0000AA"[SERVER] Limite de tentativas de registro excedida.");
                    
Player[playerid][pTentativasRegistro] = 0// Zerar a variбvel pra caso um outro jogador entre, nгo comeзe com 3 na variбvel
                    
SetTimerEx("KickPlayerinTime"200false"i"playerid); // ele й kickado 200 milisegundos apos isso acontecer, tempo suficiente pra ver a mensagem e ser kickado.
            
}
        }
        case 
Dialog_Login:
        {
            if(!
response// Se responder a segunda opзгo ou apertar esc, sera kickado
                
return Kick(playerid);
            if(!
strcmp(Player[playerid][pSenha], inputtexttrue24)) // Compara a senha do player com o que ele digitou
            
// caso esteja certo
                
TogglePlayerSpectating(playerid0); // tira ele de espectador
                
mysql_format(ConexaoSQLQuerysizeof(Query), "SELECT * FROM jogadores WHERE pNome='%e'"GetPlayerNameEx(playerid)); // Seleciona tudo aonde o nome dele estб
                
mysql_tquery(ConexaoSQLQuery"CarregarContaSQL""i"playerid); // Executa o carregamento de conta
                
SendClientMessage(playerid0x80FF00AA"[Server] Logado com sucesso."); // E manda uma mensagem falando que ele logou
            
} else { // Se nгo for igual
                
TogglePlayerSpectating(playerid1);
                
SendClientMessage(playerid0xFF0000AA"[SERVER] Senha errada, tente novamente."); // Vai avisar
                
Player[playerid][pTentativasLogin]++; // Contabilizar +1 erro
                
ShowPlayerDialog(playeridDialog_LoginDIALOG_STYLE_PASSWORD"Login""Digite sua senha para entrar em nosso servidor.""Confirmar""Sair"); // Mostra a dialog pra ele tentar dnvo
            
}
            if(
Player[playerid][pTentativasLogin] == 3// Caso ele erre 3 vezes
            
{
                
SendClientMessage(playerid0xFF0000AA"[SERVER] Limite de tentativas de login excedida."); // Avisa que ele exedeu o limite
                
Player[playerid][pTentativasLogin] = 0// Zera a variбvel pra nгo gerar conflito
                
SetTimerEx("KickPlayerinTime"200false"i"playerid); // E kicka ele depois de 200 milisegundos, dando tempo de ver a mensagem
            
}
        }
    }
    return 
1;

Agora nуs precisamos salvar tudo quando o player deslogar.

PHP Code:

public SalvarContaSQL(playerid)
{
    if(
Player[playerid][pLogado] == false// Se ele nгo estiver logado, para ali mesmo
        
return 0;
    new 
Query[250];
// Usa as variбveis pra pegar os valores in game
    
Player[playerid][pDinheiro] = GetPlayerMoney(playerid); 
    
Player[playerid][pScore] = GetPlayerScore(playerid);
    
Player[playerid][pSkin] = GetPlayerSkin(playerid);
    
GetPlayerPos(playeridPlayer[playerid][pPosX], Player[playerid][pPosY], Player[playerid][pPosZ]);
    
GetPlayerFacingAngle(playeridPlayer[playerid][pPosA]);
// Atualiza a tabela jogadores na fila do jogador SETANDO aquelas colunas como %i - interior, nъmero e %f float , nъmero com virgula AONDE estб o ID do jogador
    
mysql_format(ConexaoSQLQuerysizeof(Query), "UPDATE `jogadores` SET \
    `pDinheiro`='%i', \
    `pScore`='%i', \
    `pSkin`='%i', \
    `pPosX`='%f', \
    `pPosY`='%f', \
    `pPosZ`='%f', \
    `pPosA`='%f' WHERE `pID`='%i'"
Player[playerid][pDinheiro],
                                    
Player[playerid][pScore],
                                    
Player[playerid][pSkin],
                                    
Player[playerid][pPosX],
                                    
Player[playerid][pPosY],
                                    
Player[playerid][pPosZ],
                                    
Player[playerid][pPosA],
                                    
Player[playerid][pID]);
    
mysql_query(ConexaoSQLQuery); // Executa o comando
    
printf("[MYSQL] Dados do Jogador %s ID %d salvo com sucesso"GetPlayerNameEx(playerid), Player[playerid][pID]); // Apenas um debug
    
return 1;

Agora temos que aplicar o salvamento.

PHP Code:

public OnPlayerDisconnect(playeridreason)
{
// Se o player estiver logado E a razгo do disconnect for 0 ou 1 ou 2, salva a conta e zera os dados para nгo entrar em conflito com a conta de outro jogador.
    
if(Player[playerid][pLogado] == true && reason >= 0
    {
        
SalvarContaSQL(playerid);
        
ZerarDadosSQL(playerid);
    }
    return 
1;

Como zerar

PHP Code:

stock ZerarDadosSQL
(playerid)
{
    
Player[playerid][pID] = 0;
    
Player[playerid][pSenha] = 0;
    
Player[playerid][pDinheiro] = 0;
    
Player[playerid][pScore] = 0;
    
Player[playerid][pSkin] = 0;
    
Player[playerid][pLogado] = false;
    
Player[playerid][pTentativasLogin] = 0;
    
Player[playerid][pTentativasRegistro] = 0;
    
Player[playerid][pPosX] = 0;
    
Player[playerid][pPosA] = 0;
    
Player[playerid][pPosY] = 0;
    
Player[playerid][pPosA] = 0;
}
//Zere tudo possнvel, nгo sabe se precisa ou nгo? Zera, caso algum outro jogador entre no mesmo momento que ele sair, pode causar um conflito e esse jogador que entrou pegar as informaзхes que vocк nгo zerou do player que tinha deslogado. 
Basicamente й isso, um tutorial um pouco extenso, de um jeito que eu considero fбcil de entender, caso vocк tenha se confundi em alguma parte desse tutorial, comente pra mim tirar suas duvidas.
Caso algo no tutorial esteja errado, me avise pra mim consertar.
Reply
#2

Espaзo destinado a alguma alteraзгo ou duvida recente.
Reply
#3

Й sem dъvida um bom tutorial.
Mas o fуrum estб cheio de tutoriais como esse.
Reply
#4

Entгo mais um num tem problema :v

Mas obrigado pelo elogio
Reply
#5

Cara, уtimo tutorial, vai ajudar muitos, continue assim. +REP
Reply
#6

Quote:
Originally Posted by zF3lKy3
View Post
Cara, уtimo tutorial, vai ajudar muitos, continue assim. +REP
Obrigado men, espero que ajude de verdade
Reply
#7

Ficou muito bom !

PHP Code:
//Tira esses reason
if(Player[playerid][pLogado] == true && reason == || reason == || reason == 2
Reply
#8

Quote:
Originally Posted by Marllun
View Post
Ficou muito bom !

PHP Code:
//Tira esses reason
if(Player[playerid][pLogado] == true && reason == || reason == || reason == 2
Botei o reason pra independentemente se ele foi expulso, banido, caiu, explodiu o computador dele, salve as informaзхes dele.
Reply
#9

Nгo precisa..
Reply
#10

Bom tutorial, parabйns.
Reply
#11

O mundo vai acabar e os cara ainda lanзando sistema de registro no fуrum samp
Reply
#12

Quote:
Originally Posted by TheBob
View Post
O mundo vai acabar e os cara ainda lanзando sistema de registro no fуrum samp
Estou simplesmente tentando ajudar quem precisa.
Reply
#13

Quote:
Originally Posted by IlanZ
View Post
Bom tutorial, parabйns.
Obrigado
Reply
#14

Quote:
Originally Posted by Cauezin
View Post
Botei o reason pra independentemente se ele foi expulso, banido, caiu, explodiu o computador dele, salve as informaзхes dele.
if(reason >= 0)
Reply
#15

Quote:
Originally Posted by ipsLuan
View Post
if(reason >= 0)
Nгo tinha pensando nisso... Obrigado.
Reply
#16

Tutorial lixo n me ajudou em nada

Ficou top man kakakakak, +rep
Tava mexendo com dof2 ainda :v
Reply
#17

Quote:
Originally Posted by TheBob
O mundo vai acabar e os cara ainda lanзando sistema de registro no fуrum samp
Pelomenos n e de DOF2 e dini

Reply
#18

Quote:
Originally Posted by MituhBR
View Post
Tutorial lixo n me ajudou em nada

Ficou top man kakakakak, +rep
Tava mexendo com dof2 ainda :v
EsterEgg.
Reply
#19

Quote:
Originally Posted by AutoMatic2
View Post
Pelomenos n e de DOF2 e dini

Neh :v
Reply
#20

O Tutorial й bom, ajuda bastante, mas se vocк jб estiver registrado e logar sem colocar nenhuma senha, ele loga sem problemas... =\
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)