07.03.2014, 19:04
(
Последний раз редактировалось Locky_; 21.03.2015 в 13:41.
)
Como muitos sabem, para usar MySQL no SA-MP, й necessбrio o Plugin MySQL.
Hб vбrias versхes atualizadas do MySQL Plugin. Iremos usar, uma das versхes mais atuais do MySQL, e esse tutorial serб funcional em versхes R33 ou superiores.
Versхes R33 ou Superiores, hб sistema de cache e orm.
Bбsicamente, com o sistema de cache, vocк pode efetuar Querys, e armazena-las em variaveis. Assim, podendo ser chamadas/deletadas de acordo com sua necessidade.
Os "ORM"s sгo uma forma mais fбcil de usar o MySQL, evitando variaveis para efetuar Querys. Assim, funcionando de forma atй mais simples e prбtica. Caso queira saber mais sobre ORMs, acesse esse link.
Tуpico do Plugin MySQL by BlueG
Atualmente, estб na versгo R39-2. Vocк pode efetuar o download ou saber versхes em desenvolvimento neste link.
MYSQL
As funзхes do Plugin:
Callback:
As nativas principais do Plugin! Sem elas, vocк nгo pode usar nenhuma das citadas abaixo.
Primeiramente, conectar ao banco de dados.
mysql_connect
O valor mysql serб o id da conexгo. Vocк tambйm pode conectar em mais de um hosting, porйm vocк deve separar os ids das conexхes '-'
Em uso de funзхes, deve especificar qual conexгo, ou sempre irб ser a primeira.
mysql_close
No caso, isso й para fechar uma conexгo do MySQL. Й mais ъtil usar quando o servidor for desligado/reniciado.
mysql_escape_string
Isso servirб para retornar um string, sem problemas.
Isso por que, um string onde pode receber quaisquer caractere pode ser prejudicial ao prуprio mysql, ocorrendo o chamado sql-injection. Entгo, usando o mysql_escape_string ele irб corrigir os caracteres que podem atrapalhar uma query.
Exemplo de uso:
inputtext > Valor que serб convertido.
APlayerData[playerid][Senha] > O valor jб convertido.
mysql[1] > Seria no caso a conexгo do MySQL, dos exemplos acima.
mysql_format
mysql_format basicamente seria o format padrгo do SA-MP, sу que com funзгo extra.
Entгo, posso formatar uma query com mysql_format, sem necessitar usar o mysql_escape_string.
mysql_query || mysql_tquery || mysql_pquery
Aparentemente, mysql_tquery e mysql_pquery sгo semelhantes o uso.
Mas, BlueG diz:
Deu pra entender um pouco o que ele quis dizer.. (****** Tradutor)
mysql_query
Esta funзгo, pode servir para adicionar, atualizar ou selecionar dados!
(Para selecionar dados, deve se usar cache)
Por padrгo o cache й ativo, mas vocк pode desativa-lo, conforme o desejado.
Exemplo 1 (Usando Cache para exibir dados, veja mais a baixo):
Exemplo 2 (Atualizando dados):
Exemplo 3: (Inserindo dados):
mysql_tquery & mysql_pquery
Estas funзхes necessitam de uma callback de resultado.
Elas nгo usam cache, como a callback mysql_query.
Alguma query que ocorrer erro, serб retornado em OnQueryError.
ORM
Acima expliquei basicamente o que й o ORM no MySQL Plugin.
Funзхes:
orm_create*
Cria um novo orm, e irб retornar no id do orm.
Necessбrio especificar a tabela, e a conexгo usada.
orm_destroy*
Destroy um orm criado, atravйs do seu ID.
orm_errno*
Retorna um resultado/erro.
orm_addvar_int*
Aqui adiciona uma variavel (int), e sua respectiva coluna tabela.
Necessбrio adicionar uma variavel global, em casos de adicionar variavel local, deve ocorrer warnings/erros.
orm_addvar_float*
Adiciona uma variavel (float) e sua respectiva coluna na tabela.
Necessбrio adicionar uma variavel global, em casos de adicionar variavel local, deve ocorrer warnings/erros.
orm_addvar_string*
Adiciona uma variavel (string) e sua respectiva coluna na tabela.
Necessбrio adicionar uma variavel global, em casos de adicionar variavel local, deve ocorrer warnings/erros.
orm_setkey*
Seta a condiзгo para atualizaзгo/inserзгo/selecionar dados. (Como se funcionasse "WHERE Nome='meunome'")
orm_update*
Atualiza os dados de um orm criado. Todas as variaveis especificadas, serгo atualizadas na tabela.
orm_select*
Seleciona os dados da tabela, resultando os valores sem suas respectivas variaveis.
Assim, irб resultar se foi com sucesso ou nгo em uma callback, que serб necessбrio especifica-la. (exemplos abaixo)
orm_insert*
Insere os dados na tabela. Nгo й tгo necessбrio especificar a callback onde serб retornado, apenas irб retornar se foi com sucesso ou nгo.
* Hб exemplos.
Exemplos
Necessбrio entender, que usando por exemplo.
Seria o mesmo, se usasse
Sу que vocк, usando ORM, vocк decide o que fazer, usando as nativas
Usando ORM
Usando os ORM's, й possнvel fazer sistemas de registro/login por exemplo!
Entendendo
Vamos entender agora de forma mais explicada, pois acima sгo apenas cуdigos.
Em OnPlayerConnect, crio um novo ORM. Assim, esse ORM й respectivo com os dados do jogador que acabou de se conectar.
Ponho as variaveis que sempre receberгo e terгo dados a atualizar.
Seto a condiзгo, que irб pegar a conta que tem o nome do player que conectou. (como se fosse WHERE Nome='%s')
E vai dizer se estб registrado ou nгo, com o tal nome, em OnPlayerLogin.
Em OnPlayerLogin, irб serar a condiзгo, que antes era o Nome, para ID. Assim, o jogador pode atй alterar seu nome, que os dados ainda receberгo atualizaзхes normalmente.
OBS: ERROR_OK = Hб algo. | ERROR_NO_DATA = Nгo hб resultado.
Em OnPlayerDisconnect, irб checar se estб logado ou nгo, e aн, irб atualizar os dados. E nisso, irб deletar o ORM do player, e zerando os dados de todas as variбveis.
CACHE
Usando cache, como o explicado de forma resumida acima, vocк necessita primeiro do uso de funзхes do MySQL mesmo. ORM's nгo sгo necessбrios cache.
Funзхes:
Vendo essas nativas, parece que tudo й difнcil. Porйm, tudo й bem fбcil.
cache_get_data
Retorna o nъmero de resultados, e colunas, da conexгo feita (no caso, de uma query).
cache_get_row_count*
Retorna apenas o nъmero de resultados de uma query, da conexгo indicada.
cache_save
Salva uma query em cache.
cache_delete*
Deleta um cache salvo.
cache_is_valid
Detecta ver se o cache й vбlido.
cache_set_active*
Deixa um cache em modo ativo.
Pode ser usado, para pegar resultados nгo necessбrios em tais momentos.
Por exemplo, para dados que sгo atualizados de tempos em tempos.
cache_get_field_content*
Pega o resultado de uma query, assim vocк especifica o id do resultado (inicial do 0) atй o valor mбximo (que nгo pode ser igual a rows).
Se uma query, retorna 10 rows (10 resultados) as informaзхes dos resultados serгo de 0 atй 9. 10 serб NULL.
cache_get_field_content_int
Semelhante ao cache_get_field_content porйm, o valor serб logo retornado.
cache_get_field_content_float
Semelhante ao cache_get_field_content porйm o valor serб logo retornado.
* Hб exemplos
Exemplos
Vamos supor, que eu quero que pegue o log de banidos de 15 em 15 minutos, uma query serб feita e o resultado serб sempre exibido se eu usar /banidos.
Bбsicamente, eu teria que usar um cache, e um settimer.
Cуdigo de exemplo acima. Que tal agora, um sistema de ranking, que seja atualizado de 10 em 10 minutos?
Lembrando que o plugin pode receber atualizaзхes, e algumas callbacks podem ser sim removidas ou alteradas. Sempre dк uma olhada nas nativas.
Caso nгo tenha entendido algo do tуpico, por favor, diga e eu tentarei tirar sua dъvida.
Muitas callbacks nгo foram utilizadas neste tutorial, por nгo serem necessбrias atй certo ponto.
A Wiki explica basicamente o funcionamento de cada nativa do Plugin. (Link)
Espero que tenha entendido, e lhe ajudado!
Tutoriais semelhantes ao uso do MySQL:
[Tutorial] Criando um sistema em MySQL
[Tutorial] Usando MySQL
Vocк deve entender como й o MySQL!
Tenha um conhecimento em SQL, pesquise, estude! Este tutorial destaca funзхes do MySQL Plugin (para versхes R33 e superiores).
* Caso tenha dъvidas, comente no tуpico que tentarei lhe explicar..
Hб vбrias versхes atualizadas do MySQL Plugin. Iremos usar, uma das versхes mais atuais do MySQL, e esse tutorial serб funcional em versхes R33 ou superiores.
Versхes R33 ou Superiores, hб sistema de cache e orm.
Bбsicamente, com o sistema de cache, vocк pode efetuar Querys, e armazena-las em variaveis. Assim, podendo ser chamadas/deletadas de acordo com sua necessidade.
Os "ORM"s sгo uma forma mais fбcil de usar o MySQL, evitando variaveis para efetuar Querys. Assim, funcionando de forma atй mais simples e prбtica. Caso queira saber mais sobre ORMs, acesse esse link.
Tуpico do Plugin MySQL by BlueG
Atualmente, estб na versгo R39-2. Vocк pode efetuar o download ou saber versхes em desenvolvimento neste link.
MYSQL
As funзхes do Plugin:
pawn Код:
native mysql_log(E_LOGLEVEL:loglevel = LOG_ERROR | LOG_WARNING, E_LOGTYPE:logtype = LOG_TYPE_TEXT);
native mysql_connect(const host[], const user[], const database[], const password[], port = 3306, bool:autoreconnect = true, pool_size = 2);
native mysql_close(connectionHandle = 1);
native mysql_reconnect(connectionHandle = 1);
native mysql_unprocessed_queries(connectionHandle = 1);
native mysql_current_handle();
native mysql_option(E_MYSQL_OPTION:type, value);
native mysql_errno(connectionHandle = 1);
native mysql_escape_string(const source[], destination[], connectionHandle = 1, max_len = sizeof(destination));
native mysql_format(connectionHandle, output[], len, format[], {Float,_}:...);
native mysql_pquery(connectionHandle, query[], callback[] = "", format[] = "", {Float,_}:...);
native mysql_tquery(connectionHandle, query[], callback[] = "", format[] = "", {Float,_}:...);
native Cache:mysql_query(conhandle, query[], bool:use_cache = true);
native mysql_stat(destination[], connectionHandle = 1, max_len = sizeof(destination));
native mysql_get_charset(destination[], connectionHandle = 1, max_len = sizeof(destination));
native mysql_set_charset(charset[], connectionHandle = 1);
pawn Код:
forward OnQueryError(errorid, error[], callback[], query[], connectionHandle);
Primeiramente, conectar ao banco de dados.
mysql_connect
pawn Код:
new mysql = mysql_connect("host", "usuario", "database", "senha"); //Obrigado Schocc
pawn Код:
new mysql[3];
public OnGameModeInit() {
mysql[0] = mysql_connect("localhost", "root", "forum_samp", "");
mysql[1] = mysql_connect("localhost", "root", "servidor", "");
mysql[2] = mysql_connect("www.meuserver.com", "NicK", "servidor", "uimeututorial");
return 1;
}
mysql_close
No caso, isso й para fechar uma conexгo do MySQL. Й mais ъtil usar quando o servidor for desligado/reniciado.
pawn Код:
public OnGameModeExit()
{
for(new i; i < sizeof(mysql); i++)
mysql_close(mysql[i]); // Fechando as conexхes do exemplo anterior
return 1;
}
Isso servirб para retornar um string, sem problemas.
Isso por que, um string onde pode receber quaisquer caractere pode ser prejudicial ao prуprio mysql, ocorrendo o chamado sql-injection. Entгo, usando o mysql_escape_string ele irб corrigir os caracteres que podem atrapalhar uma query.
Exemplo de uso:
pawn Код:
mysql_escape_string(inputtext, APlayerData[playerid][Senha],mysql[1]);
APlayerData[playerid][Senha] > O valor jб convertido.
mysql[1] > Seria no caso a conexгo do MySQL, dos exemplos acima.
mysql_format
mysql_format basicamente seria o format padrгo do SA-MP, sу que com funзгo extra.
pawn Код:
%e > escapa um string, nгo necessitando do mysql_escape_string
%s > insere um string
%d / %i > insere um valor inteiro
%f > insere um valor float
%X > insere um valor hexadecimal em maiъsculo.
%x > insere um valor hexadecimal em minъsculo.
%b > insere um nъmero binбrio.
pawn Код:
mysql_format(mysql[1], Query, sizeof(Query), "UPDATE usuarios SET Senha='%e' WHERE ID=%i", APlayerData[playerid][Senha], APlayerData[playerid][MySQL_ID]); //Demostraзгo
mysql_query || mysql_tquery || mysql_pquery
Aparentemente, mysql_tquery e mysql_pquery sгo semelhantes o uso.
Mas, BlueG diz:
Quote:
A diferenзa entre este nativo e mysql_tquery () й que este tipo de consulta usa multi-threading, portanto, й mais rбpido, dependendo de quantas conexхes sгo usadas. O nъmero de conexхes podem ser especificados no mysql_connect () atravйs do parвmetro POOL_SIZE. Cada conexгo se assemelha a um fio. Esse tipo de consulta nгo suporta transaзхes. |
mysql_query
Esta funзгo, pode servir para adicionar, atualizar ou selecionar dados!
(Para selecionar dados, deve se usar cache)
Por padrгo o cache й ativo, mas vocк pode desativa-lo, conforme o desejado.
Exemplo 1 (Usando Cache para exibir dados, veja mais a baixo):
pawn Код:
CMD:primeiroregistrado(playerid) {
new Cache:Temp = mysql_query(mysql[1], "SELECT Nome FROM usuarios ORDER BY ID DESC WHERE LIMIT 1", true); //Cache local
if(cache_get_row_count(mysql[1]) > 0) //Se houver um resultado
{
new Nome[24], Msg[144];
cache_get_field_content(0, "Nome", Nome, mysql[1]);
format(Msg, 144, "{ffff00}O jogador %s й o primeiro registrado do servidor!", Nome);
SendClientMessage(playerid, -1, Msg);
}
else
SendClientMessage(playerid, -1, "{ff0000}Nгo foi possнvel pegar o primeiro registrado!"); //Coisa que seria meio dificil nй '-'
cache_delete(Temp, mysql[1]); //Deletar o cache
return 1;
}
pawn Код:
CMD:mudarsenha(playerid, params[]) {
if(strlen(params) < 3) return SendClientMessage(playerid, -1, "{ff0000}Sua senha estб pequena!");
new Query[150], Nome[24];
GetPlayerName(playerid, Nome, 24);
mysql_format(mysql[1], Query, 150, "UPDATE usuarios SET Senha='%e' WHERE Nome='%s'", params, Nome);
mysql_query(mysql[1], Query, false);
return 1;
}
pawn Код:
CMD:registrarplayer(playerid, params[]) {
new Nome[24], Senha[128]; //Vou usar a sscanf aqui
if(sscanf(params, "s[24]s[128]", Nome,Senha)) return SendClientMessage(playerid, -1, "{ff0000}Use: /registrarplayer [nome do jogador] [senha do jogdor]");
new Query[190], Msg[144];
mysql_format(mysql[1], Query, sizeof(Query), "INSERT INTO usuarios (Nome,Senha) VALUES ('%e','%e')", Nome, Senha);
mysql_query(mysql[1], Query, false);
format(Msg, 144, "{ffff00}Vocк inseriu uma nova conta! Usuбrio: %s, Senha: %s", Nome, Senha);
SendClientMessage(playerid, -1, Msg);
return 1;
}
Estas funзхes necessitam de uma callback de resultado.
Elas nгo usam cache, como a callback mysql_query.
pawn Код:
public OnPlayerConnect(playerid) {
new Nome[24], Query[128];
GetPlayerName(playerid, Nome, 24);
mysql_format(mysql[1], Query, 128, "SELECT * FROM usuarios WHERE Nome='%s'", Nome);
mysql_tquery(mysql[1], Query, "OnPlayerLogin", "d", playerid);
return 1;
}
forward OnPlayerLogin(playerid);
public OnPlayerLogin(playerid) {
if(cache_get_row_count(mysql[1]) == 0) //Nгo registrado
else // Registrado
return 1;
}
pawn Код:
public OnPlayerConnect(playerid) {
new Nome[24], Query[128];
GetPlayerName(playerid, Nome, 24);
mysql_format(mysql[1], Query, 128, "SELECT * FROM usuarios WHERE Nome='%s'", Nome);
mysql_pquery(mysql[1], Query, "OnPlayerLogin", "d", playerid);
return 1;
}
forward OnPlayerLogin(playerid);
public OnPlayerLogin(playerid) {
if(cache_get_row_count(mysql[1]) == 0) //Nгo registrado
else // Registrado
return 1;
}
Alguma query que ocorrer erro, serб retornado em OnQueryError.
ORM
Acima expliquei basicamente o que й o ORM no MySQL Plugin.
Funзхes:
pawn Код:
native ORM:orm_create(const table[], connectionHandle = 1); //Cria um orm em uma tabela, e sua conexгo do MySQL
native orm_destroy(ORM:id); //Destroi um ORM criado pelo ID
native ORM_Error:orm_errno(ORM:id); // Retorna o erro de um orm pelo id
native orm_apply_cache(ORM:id, row); //Aplica cache em um orm
native orm_select(ORM:id, callback[] = "", format[] = "", {Float, _}:...); //Seleciona e Retorna dados de um ORM
native orm_update(ORM:id); //Atualiza os dados do ORM
native orm_insert(ORM:id, callback[] = "", format[] = "", {Float, _}:...); //Insere dados de um ORM
native orm_delete(ORM:id, bool:clearvars=true); //Deleta um ORM, opcional zerar variaveis usadas
native orm_load(ORM:id, callback[] = "", format[] = "", {Float, _}:...) = orm_select; //Ler um ORM
native orm_save(ORM:id, callback[] = "", format[] = "", {Float, _}:...); //Salva um ORM
native orm_addvar_int(ORM:id, &var, varname[]); //Adiciona uma variavel a um ORM
native orm_addvar_float(ORM:id, &Float:var, varname[]); //Adiciona uma variavel float a um ORM
native orm_addvar_string(ORM:id, var[], var_maxlen, varname[]); //Adiciona uma variavel string a um ORM
native orm_delvar(ORM:id, varname[]); //Deleta uma variavel de um ORM
native orm_setkey(ORM:id, varname[]); //Seta a condiзгo de atualizaзгo/selecionar em ORMs
Cria um novo orm, e irб retornar no id do orm.
Necessбrio especificar a tabela, e a conexгo usada.
orm_destroy*
Destroy um orm criado, atravйs do seu ID.
orm_errno*
Retorna um resultado/erro.
orm_addvar_int*
Aqui adiciona uma variavel (int), e sua respectiva coluna tabela.
Necessбrio adicionar uma variavel global, em casos de adicionar variavel local, deve ocorrer warnings/erros.
orm_addvar_float*
Adiciona uma variavel (float) e sua respectiva coluna na tabela.
Necessбrio adicionar uma variavel global, em casos de adicionar variavel local, deve ocorrer warnings/erros.
orm_addvar_string*
Adiciona uma variavel (string) e sua respectiva coluna na tabela.
Necessбrio adicionar uma variavel global, em casos de adicionar variavel local, deve ocorrer warnings/erros.
orm_setkey*
Seta a condiзгo para atualizaзгo/inserзгo/selecionar dados. (Como se funcionasse "WHERE Nome='meunome'")
orm_update*
Atualiza os dados de um orm criado. Todas as variaveis especificadas, serгo atualizadas na tabela.
orm_select*
Seleciona os dados da tabela, resultando os valores sem suas respectivas variaveis.
Assim, irб resultar se foi com sucesso ou nгo em uma callback, que serб necessбrio especifica-la. (exemplos abaixo)
orm_insert*
Insere os dados na tabela. Nгo й tгo necessбrio especificar a callback onde serб retornado, apenas irб retornar se foi com sucesso ou nгo.
* Hб exemplos.
Exemplos
Necessбrio entender, que usando por exemplo.
pawn Код:
//Exemplo
orm_addvar_string(ormdid, APlayerData[playerid][Name], 24, "Nome");
orm_addvar_string(ormdid, APlayerData[playerid][Senha], 128, "Senha");
orm_addvar_string(ormdid, APlayerData[playerid][Email], 128, "Email");
orm_addvar_int(ormdid, APlayerData[playerid][Dinheiro], "Dinheiro");
orm_addvar_int(ormdid, APlayerData[playerid][Scores], "Scores");
orm_addvar_int(ormdid, APlayerData[playerid][Mortes], "Mortes");
orm_addvar_int(ormdid, APlayerData[playerid][Matou], "Matou");
orm_addvar_string(ormdid, APlayerData[playerid][pIP], 16, "IP");
orm_addvar_string(ormdid, APlayerData[playerid][DataRegistro], 50, "DataRegistro");
orm_addvar_int(ormdid, APlayerData[playerid][ID], "ID");
orm_setkey(ormdid, "Nome");
pawn Код:
new Query[800];
// Selecionar Dados
format(Query, sizeof(Query), "SELECT Nome,Senha,Email,Dinheiro,Scores,Mortes,Matou,IP,DataRegistro,ID FROM usuarios WHERE Nome='%s'", APlayerData[playerid][Name]);
//Ou atualizar dados
format(Query, sizeof(Query), "UPDATE contas SET Nome='%s',Senha='%s',Email='%s',Dinheiro=%i,Scores=%i,Mortes=%i,Matou=%i,IP='%s',DataRegistro='%s',ID=%i WHERE Nome='%s'", ....);
//Ou inserir dados
format(Query, sizeof(Query), "INSERT INTO usuarios (Nome,Senha,Email,Dinheiro,Scores,Mortes,Matou,IP,DataRegistro,ID) VALUES ('%s','%s','%s',%i,%i,%i,%i,'%s','%s',%i)", ...);
pawn Код:
orm_select
orm_update
orm_insert
Usando os ORM's, й possнvel fazer sistemas de registro/login por exemplo!
pawn Код:
#define DialogLogin 1
#define DialogRegistro 2
new mysql;
enum pInfo //Variaveis do Player
{
bool:Logado,
Name[24],
Senha[128],
Email[128],
pIP[16],
DataRegistro[50],
Scores,
Dinheiro,
Matou,
Mortes,
ID, // ID do MySQL
ORM:OrmID // Teste
};
new APlayerData[MAX_PLAYERS][pInfo]; //Variavel do Player
public OnGameModeInit() //Ao ligar o gamemode
{
mysql = mysql_connect("localhost", "root", "test", ""); //Conexгo do MySQL, isso й necessбrio
return 1;
}
public OnGameModeExit() // gamemode desligar
{
mysql_close(mysql); //Fechar conexгo do MySQL, й necessбrio, em caso de nгo fechar conexгo do MySQL, em um GMX o servidor pode crashar.
return 1;
}
public OnPlayerConnect(playerid) //Ao jogador se conectar
{
GetPlayerName(playerid, APlayerData[playerid][Name], 24); //Pegar o nome do player..
new ORM:ormdid = APlayerData[playerid][OrmID] = orm_create("usuarios", mysql); //Crio um novo ORM, na tabela "Usuarios" e na conexгo "mysql"
orm_addvar_string(ormdid, APlayerData[playerid][Name], 24, "Nome"); //Adiciono o string 'Nome' juntamente a variavel Name
orm_addvar_string(ormdid, APlayerData[playerid][Senha], 128, "Senha"); //Adiciono o string 'Senha' juntamente a variavel Senha..
orm_addvar_string(ormdid, APlayerData[playerid][Email], 128, "Email"); //merma coisa
orm_addvar_int(ormdid, APlayerData[playerid][Dinheiro], "Dinheiro"); //Adiciono o inteiro 'Dinheiro' a variavel Dinheiro '-'
orm_addvar_int(ormdid, APlayerData[playerid][Scores], "Scores"); //merma coisa
orm_addvar_int(ormdid, APlayerData[playerid][Mortes], "Mortes"); //merma coisa
orm_addvar_int(ormdid, APlayerData[playerid][Matou], "Matou"); //merma coisa
orm_addvar_string(ormdid, APlayerData[playerid][pIP], 16, "IP"); //merma coisa '-'
orm_addvar_string(ormdid, APlayerData[playerid][DataRegistro], 50, "DataRegistro"); //й a mesma
orm_addvar_int(ormdid, APlayerData[playerid][ID], "ID"); //Isso iremos usar mais a frente
orm_setkey(ormdid, "Nome"); //Seto a condiзгo, como se usasse "WHERE Nome='nomedocara'"
orm_select(ormdid, "OnPlayerLogin", "d", playerid); //Seleciona os dados e diz o resultado na callback OnPlayerLogin
return 1;
}
forward OnPlayerLogin(playerid);
public OnPlayerLogin(playerid) {
if(orm_errno(APlayerData[playerid][OrmID]) == ERROR_OK) //Se houver dados, sinal que o jogador estб registrado
ShowPlayerDialog(playerid, DialogLogin, DIALOG_STYLE_PASSWORD, "{ff0000} # {ffffff}Login", "Digite sua senha para logar!", "Login", "Cancelar");
else //Se nгo estiver dados, o jogador nгo estб registrado!
ShowPlayerDialog(playerid, DialogRegistro, DIALOG_STYLE_INPUT, "{00ff00} # {ffffff}Seja bem vindo novato!", "Digite uma senha para se registrar", "Registrar", "Cancelar");
orm_setkey(APlayerData[playerid][OrmID], "ID"); //Seta a condiзгo, mesmo nгo havendo registro, ele irб inserir, e o ID serб automaticamente dado ;)
return 1;
}
public OnPlayerDisconnect(playerid, reason) //Ao sair
{
if(APlayerData[playerid][Logado] == true) { //Caso esteja logado
orm_update(APlayerData[playerid][OrmID]); //Atualizar informaзхes
}
orm_destroy(APlayerData[playerid][OrmID]); //Destruir ORM, e isso nгo irб zerar as informaзхes
for(new pInfo:i; i < pInfo; i++)
APlayerData[playerid][i] = 0; //dados zerados.
return 1;
}
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[]) //Dialogs
{
switch(dialogid) {
case DialogLogin: { //Para efetuar login
if(!response || strlen(inputtext) == 0) return Kick(playerid);
if(strcmp(APlayerData[playerid][Senha], inputtext, false) != 0) return Kick(playerid);
APlayerData[playerid][Logado] = true; //Efetuar Login
GetPlayerIp(playerid, APlayerData[playerid][pIP], 16); //Novo IP
orm_update(APlayerData[playerid][OrmID]); //Atualizar informaзхes, e incluindo o novo Ip que acabou de se conectar.
return SendClientMessage(playerid, -1, "{ffff00}Conectado com sucesso ao gamemode de estudos!");
}
case DialogRegistro: { //Para efetuar registro
if(!response || strlen(inputtext) == 0) return Kick(playerid);
format(APlayerData[playerid][Senha], 128, inputtext); //Senha inserida
APlayerData[playerid][Logado] = true; //Logado
new d, m, a;
GetPlayerIp(playerid, APlayerData[playerid][pIP], 16); //novo ip
getdate(a, m, d);
format(APlayerData[playerid][DataRegistro], 50, "%02d/%02d/%d", d, m, a); //Data de registro
orm_insert(APlayerData[playerid][OrmID], "", ""); //Insere as informaзхes, nгo usei nenhuma callback para inserir, mas poderia atй ter colocado, porйm nгo й tгo necessбrio.
return SendClientMessage(playerid, -1, "{ffff00}Registrado com sucesso ao gamemode de estudos!");
}
}
return 1;
}
Vamos entender agora de forma mais explicada, pois acima sгo apenas cуdigos.
Em OnPlayerConnect, crio um novo ORM. Assim, esse ORM й respectivo com os dados do jogador que acabou de se conectar.
Ponho as variaveis que sempre receberгo e terгo dados a atualizar.
Seto a condiзгo, que irб pegar a conta que tem o nome do player que conectou. (como se fosse WHERE Nome='%s')
E vai dizer se estб registrado ou nгo, com o tal nome, em OnPlayerLogin.
Em OnPlayerLogin, irб serar a condiзгo, que antes era o Nome, para ID. Assim, o jogador pode atй alterar seu nome, que os dados ainda receberгo atualizaзхes normalmente.
OBS: ERROR_OK = Hб algo. | ERROR_NO_DATA = Nгo hб resultado.
Em OnPlayerDisconnect, irб checar se estб logado ou nгo, e aн, irб atualizar os dados. E nisso, irб deletar o ORM do player, e zerando os dados de todas as variбveis.
CACHE
Usando cache, como o explicado de forma resumida acima, vocк necessita primeiro do uso de funзхes do MySQL mesmo. ORM's nгo sгo necessбrios cache.
Funзхes:
pawn Код:
native cache_get_data(&num_rows, &num_fields, connectionHandle = 1);
native cache_get_row_count(connectionHandle = 1);
native cache_get_field_count(connectionHandle = 1);
native cache_get_field_name(field_index, destination[], connectionHandle = 1, max_len = sizeof(destination));
native cache_get_row(row, field_idx, destination[], connectionHandle = 1, max_len = sizeof(destination));
native cache_get_row_int(row, field_idx, connectionHandle = 1);
native Float:cache_get_row_float(row, field_idx, connectionHandle = 1);
native cache_get_field_content(row, const field_name[], destination[], connectionHandle = 1, max_len = sizeof(destination));
native cache_get_field_content_int(row, const field_name[], connectionHandle = 1);
native Float:cache_get_field_content_float(row, const field_name[], connectionHandle = 1);
native Cache:cache_save(connectionHandle = 1);
native cache_delete(Cache:cache_id, connectionHandle = 1);
native cache_set_active(Cache:cache_id, connectionHandle = 1);
native cache_is_valid(Cache:cache_id, connectionHandle = 1);
native cache_affected_rows(connectionHandle = 1);
native cache_insert_id(connectionHandle = 1);
native cache_warning_count(connectionHandle = 1);
native cache_get_query_exec_time(E_EXECTIME_UNIT:unit = UNIT_MICROSECONDS);
native cache_get_query_string(destination[], max_len = sizeof(destination));
cache_get_data
Retorna o nъmero de resultados, e colunas, da conexгo feita (no caso, de uma query).
cache_get_row_count*
Retorna apenas o nъmero de resultados de uma query, da conexгo indicada.
cache_save
Salva uma query em cache.
cache_delete*
Deleta um cache salvo.
cache_is_valid
Detecta ver se o cache й vбlido.
cache_set_active*
Deixa um cache em modo ativo.
Pode ser usado, para pegar resultados nгo necessбrios em tais momentos.
Por exemplo, para dados que sгo atualizados de tempos em tempos.
cache_get_field_content*
Pega o resultado de uma query, assim vocк especifica o id do resultado (inicial do 0) atй o valor mбximo (que nгo pode ser igual a rows).
Se uma query, retorna 10 rows (10 resultados) as informaзхes dos resultados serгo de 0 atй 9. 10 serб NULL.
cache_get_field_content_int
Semelhante ao cache_get_field_content porйm, o valor serб logo retornado.
pawn Код:
new Scores = cache_get_field_content_int(0, "Scores", mysql);
Semelhante ao cache_get_field_content porйm o valor serб logo retornado.
pawn Код:
new Float:pPos[3];
pPos[0] = cache_get_field_content_float(0, "PosX", mysql);
pPos[1] = cache_get_field_content_float(0, "PosY", mysql);
pPos[2] = cache_get_field_content_float(0, "PosZ", mysql);
Exemplos
Vamos supor, que eu quero que pegue o log de banidos de 15 em 15 minutos, uma query serб feita e o resultado serб sempre exibido se eu usar /banidos.
Bбsicamente, eu teria que usar um cache, e um settimer.
pawn Код:
new mysql, Cache:Banidos; //Variavel da conexгo, e do Cache
public OnGameModeInit() {
mysql = mysql_connect("localhost", "root", "test", ""); //Conexгo do MySQL
SetTimer("AtualizarListaBanidos", 1000 * 60 * 15, true); // 15 minutos
return 1;
}
forward AtualizarListaBanidos();
public AtualziarListaBanidos() {
Banidos = mysql_query(mysql, "SELECT * FROM banidos ORDER BY ID DESC LIMIT 30", true); //Resultados armazenados em "Banidos"
return 1;
}
CMD:banidos(playerid) {
cache_set_active(Banidos, mysql); //Seta o cache como ativo.
if(cache_get_row_count(mysql) == 0) return SendClientMessage(playerid, -1, "{ff0000}Nгo hб pessoas banidas!"); //Caso nгo tenha resultados
new Lista[1000];
for(new i; i < cache_get_row_count(mysql); i++) { // Um loop, atй chegar o mбximo de resultados.
new Nome[24], BanPor[24]; //Variaveis
cache_get_field_content(i, "Nome", Nome, mysql); //Pega o valor que estava no banco de dados na tabela 'Nome' e pхe na variavel Nome
cache_get_field_content(i, "BanAdmin", BanPor, mysql); //Pega o valor que estava tambйm no banco de dados na tabela 'BanAdmin' e pхe na variavel BanPor
format(Lista, sizeof(Lista), "%s%s banido por %s\n", Nome, BanPor);
}
format(Lista, sizeof(Lista), "Mostrando %i banidos\n\n%s", cache_get_row_count(mysql), Lista); //"Mostrando 30 banidos, e logo abaixo todos os resultados
ShowPlayerDialog(playerid, 25000, DIALOG_STYLE_MSGBOX, "{ff0000}# {ffffff}Banidos", Lista, "Fechar", "");
return 1;
}
pawn Код:
new mysql, Cache:RankDemo;
public OnGameModeInit() {
mysql = mysql_connect("localhost", "root", "test", "");
SetTimer("AtualizarRanking", 1000 * 60 * 10, true); //10 minutos
return 1;
}
forward AtualizarRanking();
public AtualizarRanking() {
RankDemo = mysql_query(mysql, "SELECT Nome,Scores FROM usuarios ORDER BY Scores DESC LIMIT 10", true);
/*
Irб ordenar o resultado dos que tem mais scores para os que tem menos.
Irб limitar o resultado em 10, ou seja, os 10 que tem maior quantidade de scores.
*/
return 1;
}
CMD:rank(playerid) {
cache_set_active(RankDemo, mysql);
if(cache_get_row_count(mysql) == 0) return SendClientMessage(playerid, -1, "{ff0000}Nada encontrado!");
new Lista[800];
for(new i; i < cache_get_row_count(mysql); i++) {
new Nome[24], Score;
cache_get_field_content(i, "Nome", Nome, mysql);
Score = cache_get_field_content_int(i, "Scores", mysql);
format(Lista, sizeof(Lista), "%s%iє - %s - Scores: %i", i+1, Nome, Score);
}
ShowPlayerDialog(playerid, 25000, DIALOG_STYLE_MSGBOX, "{ff0000}# {ffffff}Exibindo ranking!", Lista, "Ok", "");
return 1;
}
Caso nгo tenha entendido algo do tуpico, por favor, diga e eu tentarei tirar sua dъvida.
Muitas callbacks nгo foram utilizadas neste tutorial, por nгo serem necessбrias atй certo ponto.
A Wiki explica basicamente o funcionamento de cada nativa do Plugin. (Link)
Espero que tenha entendido, e lhe ajudado!
Tutoriais semelhantes ao uso do MySQL:
[Tutorial] Criando um sistema em MySQL
[Tutorial] Usando MySQL
Vocк deve entender como й o MySQL!
Tenha um conhecimento em SQL, pesquise, estude! Este tutorial destaca funзхes do MySQL Plugin (para versхes R33 e superiores).
* Caso tenha dъvidas, comente no tуpico que tentarei lhe explicar..