25.01.2019, 01:36
(
Last edited by Cauezin; 11/02/2019 at 11:02 PM.
)
Login e Registro em MySQL R41-4
Feito por: Cauezin
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`(`pID` int AUTO_INCREMENT PRIMARY KEY,
`pNome` varchar(24),
`pSenha` varchar(24),
`pDinheiro` int(12) DEFAULT 500,
`pScore` int(6),
`pSkin` int(4) DEFAULT 60,
`pPosX` float DEFAULT -2240.9197,
`pPosY` float DEFAULT 252.0263,
`pPosZ` float DEFAULT 35.3203,
`pPosA` float DEFAULT 91.2125)
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>
PHP Code:
#define HOST "localhost"
o IP do servidor, no caso й hospedado no nosso computador, entг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 Registro, nгo й necessбrio, mas fica melhor.
PHP Code:
enum PlayerInfos{
pID,
pSenha[24],
pDinheiro,
pScore,
pSkin,
Float:pPosX,
Float:pPosY,
Float:pPosZ,
Float:pPosA,
Abaixo utilizaremos, porй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.
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.
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(playerid, pname, MAX_PLAYER_NAME);
return pname;
}
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;
}
PHP Code:
public OnPlayerConnect(playerid)
{
new Query[90];
TogglePlayerSpectating(playerid, 1);// Isso daqui й sу pra sumir o botгo de spawn, tem vбrios dele espalhado pelo code.
mysql_format(ConexaoSQL, Query, sizeof(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(ConexaoSQL, Query, "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(playerid, Dialog_Login, DIALOG_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(playerid, Dialog_Registro, DIALOG_STYLE_INPUT, "Registro", "Digite uma senha para se registrar em nosso servidor", "Registrar", "Sair");
// Abre o dialog pra se registrar
}
return 1;
}
PHP Code:
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
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) < 4 || strlen(inputtext) > 24) // Se o que ele digitou for menor 4 e maior que 24, a senha nгo sera aceita
{
SendClientMessage(playerid, 0xFF0000AA, "[SERVER] Escolha uma senha entre 4 a 24 caracteres.");
TogglePlayerSpectating(playerid, 1);
ShowPlayerDialog(playerid, Dialog_Registro, DIALOG_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(playerid, 0); // Tira ele de espectador, agora ele vai entrar no server
mysql_format(ConexaoSQL, Query, sizeof(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(ConexaoSQL, Query, "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(playerid, 0xFF0000AA, "[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", 200, false, "i", playerid); // ele й kickado 200 milisegundos apos isso acontecer, tempo suficiente pra ver a mensagem e ser kickado.
}
}
}
return 1;
}
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(ConexaoSQL, Query, sizeof(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;
}
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(playerid, Player[playerid][pScore]); // seta o score com a variavel do score
GivePlayerMoney(playerid, Player[playerid][pDinheiro]); // seta o dinheiro com a variavel do dinheiro
// Etc....
SetSpawnInfo(playerid, 0, Player[playerid][pSkin], Player[playerid][pPosX], Player[playerid][pPosY], Player[playerid][pPosZ], Player[playerid][pPosA], 0, 0, 0, 0 ,0, 0);
SpawnPlayer(playerid); //Spawna o player
SetPlayerSkin(playerid, Player[playerid][pSkin]);
// Seta a skin dele, porquк as vezes pode bugar no SetSpawnInfo e aparecer a skin do CJ
return 1;
}
Entгo vamos lб.
Vamos voltar em OnDialogResponse
PHP Code:
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
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) < 4 || strlen(inputtext) > 24) // Se o que ele digitou for menor 4 e maior que 24, a senha nгo sera aceita
{
SendClientMessage(playerid, 0xFF0000AA, "[SERVER] Escolha uma senha entre 4 a 24 caracteres.");
TogglePlayerSpectating(playerid, 1);
ShowPlayerDialog(playerid, Dialog_Registro, DIALOG_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(playerid, 0);
mysql_format(ConexaoSQL, Query, sizeof(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(ConexaoSQL, Query, "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(playerid, 0xFF0000AA, "[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", 200, false, "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], inputtext, true, 24)) // Compara a senha do player com o que ele digitou
{ // caso esteja certo
TogglePlayerSpectating(playerid, 0); // tira ele de espectador
mysql_format(ConexaoSQL, Query, sizeof(Query), "SELECT * FROM jogadores WHERE pNome='%e'", GetPlayerNameEx(playerid)); // Seleciona tudo aonde o nome dele estб
mysql_tquery(ConexaoSQL, Query, "CarregarContaSQL", "i", playerid); // Executa o carregamento de conta
SendClientMessage(playerid, 0x80FF00AA, "[Server] Logado com sucesso."); // E manda uma mensagem falando que ele logou
} else { // Se nгo for igual
TogglePlayerSpectating(playerid, 1);
SendClientMessage(playerid, 0xFF0000AA, "[SERVER] Senha errada, tente novamente."); // Vai avisar
Player[playerid][pTentativasLogin]++; // Contabilizar +1 erro
ShowPlayerDialog(playerid, Dialog_Login, DIALOG_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(playerid, 0xFF0000AA, "[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", 200, false, "i", playerid); // E kicka ele depois de 200 milisegundos, dando tempo de ver a mensagem
}
}
}
return 1;
}
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(playerid, Player[playerid][pPosX], Player[playerid][pPosY], Player[playerid][pPosZ]);
GetPlayerFacingAngle(playerid, Player[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(ConexaoSQL, Query, sizeof(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(ConexaoSQL, Query); // Executa o comando
printf("[MYSQL] Dados do Jogador %s ID %d salvo com sucesso", GetPlayerNameEx(playerid), Player[playerid][pID]); // Apenas um debug
return 1;
}
PHP Code:
public OnPlayerDisconnect(playerid, reason)
{
// 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;
}
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.
Caso algo no tutorial esteja errado, me avise pra mim consertar.