15/01/2023 23:10
Muito obrigado por da uma noçao do mysql
aqui um exemplo do codigo acima com bug fixado da senha e algumas modificaçoes.
aqui um exemplo do codigo acima com bug fixado da senha e algumas modificaçoes.
Código PHP:
#include <a_samp>
#include <a_mysql>
#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 "gta"
//O nome do banco de dados que você criou no inicio.
#define PASS ""
//Hospedado no computador não tem senha.
#define Dialog_Login 1
#define Dialog_Registro 2
//Dialog do Login e Registro, não é necessário, mas fica melhor.
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.
}
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.
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.
main()
{
print("\n----------------------------------");
print(" Basic gamemode mysql\n");
print("----------------------------------\n");
}
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;
}
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;
}
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;
}
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;
}
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(strlen(inputtext) > 1 && !strcmp(Player[playerid][pSenha], inputtext) ) // Compara a senha do player com o que ele digitou
{ // caso esteja certo
printf("Digitou %s a senha atual %s",inputtext, Player[playerid][pSenha]);
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
Player[playerid][pTentativasLogin]++; // Contabilizar +1 erro
new string[64];
format(string,sizeof(string),"[SERVER] Senha errada, tente novamente. (%d/3)", Player[playerid][pTentativasLogin]);
TogglePlayerSpectating(playerid, 1);
SendClientMessage(playerid, 0xFF0000AA, string); // Vai avisa
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;
}
public OnGameModeInit()
{
SetGameModeText("Basic gamemode mysql");
ConexaoSQL = mysql_connect(HOST,USER,PASS,DTBS);
if(mysql_errno(ConexaoSQL) != 0)
{
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;
}
public OnGameModeExit()
{
return 1;
}
// public OnPlayerRequestClass(playerid, classid)
// {
// SetPlayerPos(playerid, 1958.3783, 1343.1572, 15.3746);
// SetPlayerCameraPos(playerid, 1958.3783, 1343.1572, 15.3746);
// SetPlayerCameraLookAt(playerid, 1958.3783, 1343.1572, 15.3746);
// return 1;
// }
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;
}
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;
}
public OnPlayerSpawn(playerid)
{
return 1;
}
public OnPlayerDeath(playerid, killerid, reason)
{
return 1;
}
public OnVehicleSpawn(vehicleid)
{
return 1;
}
public OnVehicleDeath(vehicleid, killerid)
{
return 1;
}
public OnPlayerText(playerid, text[])
{
return 1;
}
public OnPlayerCommandText(playerid, cmdtext[])
{
if (strcmp("/mycommand", cmdtext, true, 10) == 0)
{
// Do something here
return 1;
}
return 0;
}
public OnPlayerEnterVehicle(playerid, vehicleid, ispassenger)
{
return 1;
}
public OnPlayerExitVehicle(playerid, vehicleid)
{
return 1;
}
public OnPlayerStateChange(playerid, newstate, oldstate)
{
return 1;
}
public OnPlayerEnterCheckpoint(playerid)
{
return 1;
}
public OnPlayerLeaveCheckpoint(playerid)
{
return 1;
}
public OnPlayerEnterRaceCheckpoint(playerid)
{
return 1;
}
public OnPlayerLeaveRaceCheckpoint(playerid)
{
return 1;
}
public OnRconCommand(cmd[])
{
return 1;
}
public OnPlayerRequestSpawn(playerid)
{
return 1;
}
public OnObjectMoved(objectid)
{
return 1;
}
public OnPlayerObjectMoved(playerid, objectid)
{
return 1;
}
public OnPlayerPickUpPickup(playerid, pickupid)
{
return 1;
}
public OnVehicleMod(playerid, vehicleid, componentid)
{
return 1;
}
public OnVehiclePaintjob(playerid, vehicleid, paintjobid)
{
return 1;
}
public OnVehicleRespray(playerid, vehicleid, color1, color2)
{
return 1;
}
public OnPlayerSelectedMenuRow(playerid, row)
{
return 1;
}
public OnPlayerExitedMenu(playerid)
{
return 1;
}
public OnPlayerInteriorChange(playerid, newinteriorid, oldinteriorid)
{
return 1;
}
public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
return 1;
}
public OnRconLoginAttempt(ip[], password[], success)
{
return 1;
}
public OnPlayerUpdate(playerid)
{
return 1;
}
public OnPlayerStreamIn(playerid, forplayerid)
{
return 1;
}
public OnPlayerStreamOut(playerid, forplayerid)
{
return 1;
}
public OnVehicleStreamIn(vehicleid, forplayerid)
{
return 1;
}
public OnVehicleStreamOut(vehicleid, forplayerid)
{
return 1;
}
public OnPlayerClickPlayer(playerid, clickedplayerid, source)
{
return 1;
}
// 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;
}
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;
}