SSGamers - 12 Anos online por você.

#SSGamers - A Comunidade que mais crescer no brasil!

Participe do fórum, é rápido e fácil

SSGamers - 12 Anos online por você.

#SSGamers - A Comunidade que mais crescer no brasil!

SSGamers - 12 Anos online por você.

Gostaria de reagir a esta mensagem? Crie uma conta em poucos cliques ou inicie sessão para continuar.
Chegou o novo tema 6.5.5 - SSGamers - Servidores online de qualidade - Aproveite e entre para nossa comunidade, inscreva-se já! - Ouça nossa web radio - Veja nossas novidades - Participe dos nossos setores de jogos online - Parcerias aberta fale já com um administrador.

    [Tutorial] Usando MySQL + Cache + ORM

    Weslley_Script
    Weslley_Script
    SS - Fundador
    SS - Fundador


    Steam Steam : WeslleySSGames
    Zello : WeslleySSGames
    Mensagens : 11378
    Moedas : 1031967
    Data de inscrição : 06/10/2011
    Idade : 28
    Localização : Brasil

    [Tutorial] Usando MySQL + Cache + ORM Empty [Tutorial] Usando MySQL + Cache + ORM

    Mensagem por Weslley_Script Dom 30 Abr 2023 - 5:42

    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.
    Basicamente, com o sistema de cache, você pode controlar consultas, e armazená-las em variáveis. 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 variáveis ​​para simulações de consultas. Assim, funcionando de forma atÃ:copyright: mais simples e prática. Caso queira saber mais sobre ORMs, 


    Atualmente, está na versão R39-2. Você pode transmitir o download ou saber versões em desenvolvimento.

    MYSQL
    As funções do Plugin:
    peão Код:


    Código:
    mysql_log nativo ( E_LOGLEVEL : loglevel = LOG_ERROR | LOG_WARNING, E_LOGTYPE : logtype = LOG_TYPE_TEXT ) ; mysql_connect
    nativo ( const host [ ] , const user [ ] , const database [ ] , const password [ ] , porta =  3306 , bool : autoreconnect = true, pool_size =  2) ;
    nativo mysql_close ( connectionHandle =  1 ) ;
    nativo mysql_reconnect ( connectionHandle =  1 ) ;

    nativo mysql_unprocessed_queries ( connectionHandle =  1 ) ;
    nativo mysql_current_handle ( ) ; mysql_option
    nativo ( E_MYSQL_OPTION : tipo, valor ) ;

    nativo mysql_errno ( connectionHandle =  1 );
    nativo mysql_escape_string ( const origem [ ] , destino [ ] , connectionHandle =  1 , max_len =  sizeof ( destino ) ) ; mysql_format
    nativo ( connectionHandle, output [ ] , len, format [ ] , { Float,_ } : ... ) ; mysql_pquery
    nativo ( connectionHandle, consulta [ ] , retorno de chamada[ ]  =  "" , formato [ ]  =  "" , { Float,_ } : ... ) ; mysql_tquery

    nativo ( connectionHandle, query [ ] , callback [ ]  =  "" , format [ ]  =  "" , { Float,_ } : ... ) ; Cache

    nativo  : mysql_query ( conhandle, query [ ] ,bool : use_cache = true ) ;

    nativo mysql_stat ( destino [ ] , connectionHandle =  1 , max_len =  sizeof ( destino ) ) ;
    nativo mysql_get_charset ( destino [ ] , connectionHandle =  1 , max_len =  sizeof ( destino ) ) ;
    nativo mysql_set_charset ( conjunto de caracteres [ ], connectionHandle =  1 ) ;

    Chamada de retorno :
    peão Код:


    Código:
    encaminhar OnQueryError ( errorid, error [ ] , callback [ ] , query [ ] , connectionHandle ) ;

    As nativas principais do Plugin! Sem elas, você não pode usar nenhuma das citações abaixo.
    Primeiro, conecte ao banco de dados.

    mysql_connect
    peão Код:


    Código:
    new mysql = mysql_connect ( "host" , "usuário" , "banco de dados" , "senha" ) ; //Obrigado Schocc

    O valor mysql será o id da conexão. Você também pode se conectar em mais de uma hospedagem, porém você deve separar os ids das conexões '-'
    peão Код:


    Código:
    novo mysql [ 3 ] ;
    public OnGameModeInit ( )  {
         mysql [ 0 ]  = mysql_connect ( "localhost" , "root" , "forum_samp" , "" ) ;
        mysql [ 1 ]  = mysql_connect ( "localhost" , "root" , "servidor" , "" ) ;
     "www.meuserver.com" , "NicK" , "servidor" , "uimeututorial" ) ;
        retornar  1 ;
    }

    Em uso de funções, deve especificar qual conexão, ou sempre irá ser a primeira.

    mysql_close
    No caso, é para fechar uma conexão do MySQL. É mais útil usar quando o servidor estiver desligado/reniciado.
    peão Код:


    Código:
    public OnGameModeExit ( )  
    {
        for ( new i; i <  sizeof ( mysql ) ; i ++ )
             mysql_close ( mysql [ i ] ) ; // Fechando as conexões do exemplo anterior
        return  1 ;
    }

    mysql_escape_string
    Isso servirá para retornar uma string, sem problemas.
    Isso por que, uma string onde pode receber qualquer 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 consulta.

    Exemplo de uso:
    peão Код:


    Código:
    mysql_escape_string ( inputtext, APlayerData [ playerid ] [ Senha ] , mysql [ 1 ] ) ;

    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 formato padrão do SA-MP, então com função extra.
    peão Код:


    Código:
    % e    > escapa uma string, nгo necessitando do mysql_escape_string
    % s    > inserir uma string
    % d /  % i   > inserir um valor inteiro
    % f    > inserir um valor float
    % X    > inserir um valor hexadecimal em maiъsculo.
    % x    > insira um valor hexadecimal em min úsculo.
    % b    > insira um número binário.

    Então, posso formatar uma consulta com mysql_format, sem precisar usar o mysql_escape_string.
    peão Код:


    Código:
    mysql_format ( mysql [ 1 ] , Query, sizeof ( Query ) , "UPDATE usuarios SET Senha='%e' WHERE ID=%i" , APlayerData [ playerid ] [ Senha ] , APlayerData [ playerid ] [ MySQL_ID ] ) ; //Demonstração


    mysql_query || mysql_tquery || mysql_pquery
    aparentemente, mysql_tquery e mysql_pquery são semelhantes ou de uso.
    Mas, BlueG diz:
    Citar:



    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 pode ser especificado 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.
    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):
    peão Код:


    Código:
    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 difícil né '-'
        cache_delete ( Temp, mysql [ 1 ] ) ; //Deletar o cache
        return  1 ;
    }

    Exemplo 2 (Atualizando dados):
    peão Код:


    Código:
    CMD : mudarsenha ( playerid, params [ ] )  {
        if ( strlen ( params )  <  3 )  return SendClientMessage ( playerid, - 1 , "{ff0000}Sua senha está pequena!" ) ;
        nova Consulta [ 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 ] , Consulta, false ) ;
        retornar  1 ;
    }

    Exemplo 3: (Inserindo dados):
    peão Код:


    Código:
    CMD : registrarplayer ( playerid, params [ ] )  {
        novo 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 corredor]" ) ;
        nova Consulta [ 190 ] , Msg[ 144 ] ;
        mysql_format ( mysql [ 1 ] , Query, sizeof ( Query ) , "INSERT INTO usuarios (Nome,Senha) VALUES ('%e','%e')" , Nome, Senha ) ;
        mysql_query ( mysql [ 1 ] , Consulta, false ) ;
        format ( Msg, 144 , "{ffff00}Vocк inseriu uma nova conta! Usuário: %s, Senha: %s" , Nome, Senha ) ;
        SendClientMessage ( id do jogador, - 1, Mensagem ) ;
        retornar  1 ;
    }

    mysql_tquery & mysql_pquery
    Estas funções passam por um callback de resultado.
    Eles não usam cache, como um callback mysql_query.
    peão Код:


    Código:
    public OnPlayerConnect ( playerid )  {
        novo Nome [ 24 ] , Consulta [ 128 ] ;
        GetPlayerName ( playerid, Nome, 24 ) ;
        mysql_format ( mysql [ 1 ] , Query, 128 , "SELECT * FROM usuarios WHERE Nome='%s'" , Nome ) ;
        mysql_tquery ( mysql [ 1 ] , Consulta, "OnPlayerLogin" , "d" , playerid );
        retornar  1 ;
    }
    encaminhar OnPlayerLogin ( playerid ) ;
    public OnPlayerLogin ( playerid )  {
        if ( cache_get_row_count ( mysql [ 1 ] )  ==  0 )  //Não registrado
        else  // Registrado
        return  1 ;
    }

    peão Код:

    Código:
    [center][left]public OnPlayerConnect ( playerid )  {
        novo Nome [ 24 ] , Consulta [ 128 ] ;
        GetPlayerName ( playerid, Nome, 24 ) ;
        mysql_format ( mysql [ 1 ] , Query, 128 , "SELECT * FROM usuarios WHERE Nome='%s'" , Nome ) ;
        mysql_pquery ( mysql [ 1 ] , Consulta, "OnPlayerLogin" , "d" , playerid );
        retornar  1 ;
    }
    encaminhar OnPlayerLogin ( playerid ) ;
    public OnPlayerLogin ( playerid )  {
        if ( cache_get_row_count ( mysql [ 1 ] )  ==  0 )  //Não registrado
        else  // Registrado
        return  1 ;
    }[/left][/center]
    [center][color=Red][size=14]
    [/size][/color][/center]

    Alguma consulta que ocorra erro, será retornado em OnQueryError .

    ORM
    Acima expliquei basicamente o que é o ORM no MySQL Plugin.
    Funções:
    peão Код:


    Código:
    ORM nativo : orm_create ( tabela const [ ] , connectionHandle =  1 ) ; //Cria um orm em uma tabela, e sua conexão do MySQL
    nativo orm_destroy ( ORM : id ) ; //Destroi um ORM criado pelo ID

    nativo  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
    nativo 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

    nativo orm_delete ( ORM : id, bool : clearvars = true ) ; //Deleta um ORM, opcionalmente zerar variáveis ​​usadas

    nativo orm_load ( ORM : id, callback [ ]  =  "" , format [ ]  =  "" , { Float, _ } : ... ) = orm_selecionar; //Ler um ORM
    nativo orm_save ( ORM : id, callback [ ]  =  "" , format [ ]  =  "" , { Float, _ } : ... ) ; //Salva um ORM

    nativo orm_addvar_int ( ORM : id, & var, varname [ ] ) ; //Adiciona uma variável a um ORM
    nativo orm_addvar_float ( ORM : id, &Float : var, nomedavar [ ] ) ; //Adiciona uma variável float para um ORM
    nativo orm_addvar_string ( ORM : id, var [ ] , var_maxlen, varname [ ] ) ; //Adiciona uma variável string para um ORM

    nativo orm_delvar ( ORM : id, varname [ ] ) ; //Deleta uma variável de um ORM
    nativo orm_setkey ( ORM : id, varname [ ] ) ;//Definir a condição de atualização/selecionar em ORMs

    orm_create *
    Cria um novo orm, e irá retornar no id do orm.
    Necessário especificar uma tabela, e a conexão usada.

    orm_destroy *
    Destrói um orm criado, através do seu ID.

    orm_errno *
    Retorna um resultado/erro.

    orm_addvar_int *
    Aqui adiciona uma variável (int), e sua respectiva coluna tabela.
    Necessário adicionar uma variável global, em casos de adicionar variável local, deve ocorrer warnings/erros.

    orm_addvar_float *
    Adiciona uma variável (float) e sua respectiva coluna na tabela.
    Necessário adicionar uma variável global, em casos de adicionar variável local, deve ocorrer warnings/erros.

    orm_addvar_string *
    Adiciona uma variável (string) e sua respectiva coluna na tabela.
    Necessário adicionar uma variável global, em casos de adicionar variável local, deve ocorrer warnings/erros.

    orm_setkey *
    Define a condição para atualizar/inserir/selecionar dados. (Como se funcionasse "WHERE Nome='meunome'")

    orm_update *
    Atualiza os dados de um orm criado. Todas as variáveis ​​especificadas, serão atualizadas na tabela.

    orm_select *
    Selecionados os dados da tabela, gerados os valores sem suas respectivas variáveis.
    Assim, irá resultar se foi com sucesso ou não em um callback, que será necessário especificar-la. (exemplos abaixo)

    orm_insert *
    Insira os dados na tabela. Nгo й tгo necessбrio especificar um callback onde serб retornado, apenas irб retornar se foi com sucesso ou nгo.

    * Há exemplos.


    Exemplos
    Necessário entender, que usando por exemplo.
    peão Код:


    Código:
    //Exemplo
         orm_addvar_string ( ormdid, APlayerData [ playerid ] [ Nome ] , 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 ] [ Pontuações ] , "Pontuações" ) ;
        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" ) ;

    Seria o mesmo, se usasse
    peão Код:


    Código:
    nova consulta [ 800 ] ;
    // seleciona
    o formato dos dados ( Query, sizeof ( Query ) , "SELECT Nome,Senha,Email,Dinheiro,Scores,Mortes,Matou,IP,DataRegistro,ID FROM usuarios WHERE Nome='%s'" , APlayerData [ playerid ] [ Nome ] ) ;
    //Ou atualizar
    o formato dos dados ( 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=', .... ) ;
    //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)" , ... ) ;

    Só que você, usando ORM, você decide o que fazer, usando como nativos
    peão Код:


    Código:
    orm_select
    orm_update
    orm_insert

    Usando ORM
    Usando os ORM's, é possível fazer sistemas de registro/login por exemplo!
    peão Код:

    Código:
    [center][left]#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
    } ;
    novo 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 ( )  // modo de jogo desligado
    {
         mysql_close ( mysql) ; //Fechar conexão do MySQL, é necessário, em caso de não fechar conexão do MySQL, em um GMX ou servidor pode travar.
        retornar  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 ( "usuários" , mysql ) ; //Crio um novo ORM, na tabela "Usuarios" e na conexao "mysql"
         orm_addvar_string ( ormdid, APlayerData [ playerid ] [ Name ] , 24 , "Nome" ) ; //Adição da string 'Nome' juntamente com a variável Name
         orm_addvar_string ( ormdid, APlayerData [ playerid ] [ Senha ] , 128 , "Senha" ) ; //adiciona o string 'Senha'
        orm_addvar_string ( ormdid, APlayerData [ playerid ] [ Email ] , 128 , "Email" ) ; //merma coisa
         orm_addvar_int ( ormdid, APlayerData [ playerid ] [ Dinheiro ] , "Dinheiro" ) ; //Adicione 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 vamos usar mais a frente
       
         orm_setkey ( ormdid, "Nome" ) ; //Defina uma condição, como se usasse "WHERE Nome='nomedocara'"
         orm_select ( ormdid, "OnPlayerLogin", "d" , id do jogador ) ; //Seleciona os dados e diz o resultado na callback OnPlayerLogin
        return  1 ;
    }
    encaminhar 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!" , "Entrar" , "Cancelar" ) ;
        else  //Se não houver dados, o jogador não está registrado!
            ShowPlayerDialog ( playerid, DialogRegistro, DIALOG_STYLE_INPUT, "{00ff00} # {ffffff}Seja bem vindo novo!" , "Digite uma senha para se registrar" , "Registrar" , "Cancelar" ) ;
    "ID" ) ; //Define 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.
        retornar  1 ;
    }
    public OnDialogResponse ( playerid, dialogid, resposta, listitem, inputtext [ ] ) //Dialogs
    {
        switch ( dialogid )  {
            case DialogLogin :  {  //Para login redirecionado
                if ( ! resposta || 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 incluir o novo Ip que acabou de se conectar.
                return SendClientMessage ( id do jogador, -1 , "{ffff00}Conectado com sucesso ao gamemode de estudos!" ) ;
            }
            case DialogRegistro :  {  //Para registrado registro
                if ( ! response || strlen ( inputtext )  ==  0 )  return Kick ( playerid ) ;
                formato ( APlayerData [ playerid ] [ Senha ] , 128 , inputtext ) ; //Senha inserido
                 APlayerData [id do jogador ] [ Logado ]  = true; //Logado
                new d, m, a;
                GetPlayerIp ( playerid, APlayerData [ playerid ] [ pIP ] , 16 ) ; //novo ip
                getdate ( a, m, d ) ;
                formato ( APlayerData [ playerid ] [ DataRegistro ] , 50 , "%02d/%02d/%d" , d, m, a ) ; //Dados de registro
                orm_insert ( APlayerData [ playerid ] [ OrmID ] , "" , "" ) ; //Insere as informaзхes, nгo usei nenhum 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!" ) ;
            }
        }
        retorna  1 ;
    }[/left][/center]
    [center][/center]

    Entendendo
    Vamos entender agora de forma mais explicada, pois acima são apenas cуdigos.
    Em OnPlayerConnect , criou um novo ORM . Assim, esse ORM é respectivamente com os dados do jogador que acabou de se conectar .
    Ponho as variaveis que sempre recebem e terao 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 recebem 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 isso, irá deletar o ORM do player, e zerando os dados de todas as variáveis. [Tutorial] Usando MySQL + Cache + ORM Wink

    CACHE
    Usando cache, como o explicado de forma resumida acima, você precisa primeiro do uso de funções do MySQL mesmo. Cache nгo sгo necessбrios do ORM.
    Funções:
    peão Код:


    Código:
    cache_get_data nativo ( & num_rows, & num_fields, connectionHandle =  1 ) ; cache_get_row_count
    nativo ( connectionHandle =  1 ) ; cache_get_field_count
    nativo ( connectionHandle =  1 ) ; cache_get_field_name
    nativo ( field_index, destino [ ] , connectionHandle =  1 , max_len =  sizeof ( destino ) ) ;

    cache_get_row nativo ( linha, field_idx, destino [ ] , connectionHandle =  1 , max_len =  sizeof ( destino ) ) ; cache_get_row_int
    nativo ( linha, field_idx, connectionHandle =  1 ) ; Float
    nativo  : cache_get_row_float ( row, field_idx, connectionHandle = 1 ) ; cache_get_field_content nativo ( linha, const field_name [ ]

    , destino [ ] , connectionHandle =  1 , max_len =  sizeof ( destino ) ) ; cache_get_field_content_int
    nativo ( linha, const field_name [ ] , connectionHandle =  1 ) ; Float
    nativo  : cache_get_field_content_float ( linha, const field_name [ ] , connectionHandle = 1 ) ; Cache nativo : cache_save

     ( connectionHandle =  1 ) ; cache_delete
    nativo ( Cache : cache_id, connectionHandle =  1 ) ; cache_set_active
    nativo ( Cache : cache_id, connectionHandle =  1 ) ; cache_is_valid
    nativo ( Cache : cache_id, connectionHandle =  1 ) ; cache_affected_rows

    nativo ( connectionHandle =  1 ) ;
    nativocache_insert_id ( connectionHandle =  1 ) ; cache_warning_count
    nativo ( connectionHandle =  1 ) ; cache_get_query_exec_time

    nativo ( E_EXECTIME_UNIT : unidade = UNIT_MICROSECONDS ) ; cache_get_query_string
    nativo ( destino [ ] , max_len =  sizeof ( destino ) ) ;

    Vendo esses nativos, 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 consulta).

    cache_get_row_count *
    Retorna apenas o número de resultados de uma consulta, da conexão indicada.

    cache_save
    Salva uma query em cache.

    cache_delete *
    Exclui um salva de cache.

    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 consulta, assim você especifica o id do resultado (inicial do 0) até o valor máximo (que não pode ser igual a linhas).
    Se uma consulta, retorna 10 linhas (10 resultados) como 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.
    peão Код:

    new Scores = cache_get_field_content_int ( 0 , "Scores" , mysql ) ;
    cache_get_field_content_float
    semelhante ao cache_get_field_content porйm o valor serб logo retornado.
    peão Код:


    Código:
    novo  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 ) ;

    * Há exemplos

    Exemplos
    Vamos supor, que eu quero que pegue o log de banidos de 15 em 15 minutos, uma consulta será feita eo resultado será sempre exibido se eu usar /banidos.

    Basicamente, eu teria que usar um cache, e um settimer.
    peão Код:


    Código:
    novo 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 ;
    }
    encaminhar 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 ) ; //Define 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.
            novo Nome [ 24 ] , BanPor [ 24 ] ; //Variáveis
             ​​cache_get_field_content (i, "Nome" , Nome, mysql ) ; //Pega o valor que estava no banco de dados na tabela 'Nome' e pхe na variável 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 variável BanPor
            format ( Lista, sizeof ( Lista ) , "%s%s banido por %s \n " , Nome, BanPor ) ;
        }
        formato ( 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 ;
    }

    Código do exemplo acima. Que tal agora, um sistema de ranking, que seja atualizado de 10 em 10 minutos?
    peão Код:


    Código:
    novo mysql, Cache : RankDemo;
    public OnGameModeInit ( )  {
         mysql = mysql_connect ( "localhost" , "root" , "teste" , "" ) ;
        SetTimer ( "AtualizarRanking" , 1000  *  60  *  10 , verdadeiro ) ; //10 minutos
        return  1 ;
    }
    encaminhar AtualizarRanking ( ) ;
    Public AtualizarRanking ()  {
         RankDemo = mysql_query ( mysql, "SELECT Name,Scores FROM usuarios ORDER BY Scores DESC LIMIT 10" , true ) ;
        /*
        Irá ordenar o resultado dos que tem mais escores para os que tem menos.
        Irá limitar o resultado em 10, ou seja, os 10 que tem maior quantidade de escores.
        */
        retorna  1 ;
    }
    CMD : classificação ( playerid )  {
         cache_set_active ( RankingDemo, mysql ) ;
        if ( cache_get_row_count ( mysql ) ==  0 )  return SendClientMessage ( playerid, - 1 , "{ff0000}Nada encontrado!" ) ;
        nova Lista [ 800 ] ;
        for ( new i; i < cache_get_row_count ( mysql ) ; i ++ )  {
            new Nome [ 24 ] , Pontuação;
            cache_get_field_content ( i, "Nome" , Nome, mysql ) ;
            Pontuação =cache_get_field_content_int ( i, "Pontuações" , mysql ) ;
            format ( Lista, sizeof ( Lista ) , "%s%iє - %s - Pontuações: %i" , i + 1 , Nome, Pontuação ) ;
        }
         ShowPlayerDialog ( playerid, 25000 , DIALOG_STYLE_MSGBOX, "{ff0000}# {ffffff}Exibindo ranking!" , Lista, "Ok" , "" ) ;
        retornar  1 ;
    }

    Lembrando que o plugin pode receber atualizações, e alguns callbacks podem ser sim removidos ou alterados. Sempre dê uma sensação nas nativas.
    Caso nгo tenha entendido algo do tуpico, por favor, diga e eu tentarei tirar sua dъvida.

    Muitos callbacks não foram utilizados neste tutorial, por não serem necessários até certo ponto.
    A Wiki explica basicamente o funcionamento de cada plug-in nativo. 


    Espero que tenha entendido, e lhe ajudado!


    Você deve entender como é o MySQL!
    Tenha um conhecimento em SQL, pesquise, estude! Este tutorial destaca as funções do MySQL Plugin (para versões R33 e superiores) .

    * Caso tenha dъvidas, comente no tуpico que tentarei lhe explicar..
    Creditos: @Locky_



    [Tutorial] Usando MySQL + Cache + ORM D07Xwqb
    [Tutorial] Usando MySQL + Cache + ORM Yjab9HN

      Data/hora atual: Dom 28 Abr 2024 - 9:54