[Tutorial] pVars | y_Commands | y_ini | +Reg/Log | _:Simples.
#1

YCMD | PVars | Y_Ini | Basic.

Bom, estes dias ****** lanзou o "y_ini", que podemos chamar de uma versгo bem aprimorada e atual de Dini. A grande diferenзa й que y_ini й 40x(Ou Mais) mais rбpido que Dini. Por que? Simples, Dini faz a leitura completa de um arquivo linha por linha, entretanto ele abre e fecha o arquivo para cada leitura de linha concluнda, o que, CLARO, causa uma queda enorme no tempo e no desempenho de Dini ao ler um arquivo. Y_ini por outro lado, abre o arquivo e lк-o por completo, acredite, com uma velocidade incrнvel. Outro segredo estб na proprias funзхes, aonde em Dini vocк nгo tinha essa liberdade, tudo que devк fazer й basicamente "abrir,salvar,fechar" e especificar o que salvar, em Y_ini as "especificaзхes" jб sгo mais exigidas, e talvez seja por isso que muitas pessoas ainda usam Dini, apesar de terem plena consciкncia de que estam "matando" seu script.

Uma combinaзгo perfeita para montar um script estб na combinaзгo de funзхes que "substituem" outras, que convenhamos, sгo literalmente uma tristeza! Alйm de grandes e complexas fazem um uso enorme de memуria. Um exemplo de uma boa e simples combinaзгo destas funзхes:

YCMD + sscanf + PVar + Forech:
pawn Код:
YCMD:kick(playerid, params[], ajuda)
{
    if (ajuda)
    return SendClientMessage(playerid, COR, "AJUDA: Chuta o jogador especificado.");
   
    if ( GetPVarInt( playerid, "Level" ) <= 2 )
    return SendClientMessage( playerid, COR, "ERRO: Apenas administradores acima do Level 2.");

    if (sscanf( params, "uS", params[0], params[1]))
        return SendClientMessage( playerid, COR, "ERRO: /kick [id] [Motivo]");

    if ( !IsPlayerConnected( params[0] ) )
        return SendClientMessage( playerid, -1, "ERRO: Jogador nгo conectado");

    new String[ 128 ];
   
    format( String, sizeof String, "%s (ID: %i) chutou o jogador '%s'( ID: %i ) Reason: %s",pName( playerid ),playerid,pName( params[0] ),params[0],params[1]);
               
    SendClientMessageToAll(COR, String );
    Kick(params[0]);
    return 1;
}
Agora, uma comparaзгo com explicaзгo em outro comando:
pawn Код:
YCMD:Kicktodos(playerid, params[], ajuda)
/*
Cmd: KickTodos | Player = ID | Params: O que vem apos | Ajuda = Уtimo sistema de YCMD, aonde vocк pode espeficiar
um comando dentro de outro, no caso, no camando ajuda, se digitarmos "/ajuda kicktodos" iria resultar na mensagem:
"AJUDA: Chuta todos os jogadores!", o que й bem mais simples de que adicionar um comando ajuda incluindo todos os
"ajudas" do script dentro!
*/

{
    if (ajuda)
        return SendClientMessage(playerid, COR, "AJUDA: Chuta todos os jogadores!");
    /* Apenas retorna a tal mensagem caso o jogador use o comando /ajuda.*/
   
    if ( GetPVarInt( playerid, "Level" ) <= 2 )
        return SendClientMessage( playerid, COR, "ERRO: Apenas administradores acima do Level 2.");
    /* Aqui vem um bom exemplo de PVar, nгo vou passar o script todo pois nгo hб necessidade, e scripter de verdade
    corre atrбs para tentar fazer seu prуprio. Bom, em outra parte (Exemplo:"/selevel") eu defini para que o level
    setado vб a por-jogador-variavel "Level" (SetPVarInt).
    E aqui, estou apenas pegando o valor da variavel de volta e verificando se й menos que o level requisitado
    para o uso do comando.
    */

    if (sscanf( params, "s",params[0]))
        return SendClientMessage( playerid, COR, "ERRO: /kicktodos [Motivo]");
    /*
    Aqaui й bem simples, apenas espeficiquei ao "espeficiador" de Sscanf que o motivo й uma "string", um "texto"
    com "s" (Encontre outros espeficadores no post oficial do plugin sscanf). No caso, usei outro item que й bem
    aplicado a YCMD, os parametros (Tudo que vem apуs o comando, e separados por espaзos). Caso nгo haja nada
    apуs o comando, irб retornar na mensagem: "ERRO: /kicktodos [Motivo]"
    */
 
    new String[128]; //Mбximo de caracteres permitidos pelo Chat SA-MP.
    format(String, sizeof(String), "%s chutou todos os jogadores. [Motivo: %s ] |-", pName( playerid ),params[0]);
    SendClientMessageToAll(COR, String);
    /*
    Aqui vai imprimir o resultado do comando a todos os jogadores presentes, utilizei " pName( playerid )" para
    pegar o nome do administrador, como й uma funзгo bem conhecida e quase todos possuem em seus scripts,
    o que й bem melhor de que definir uma variavel e aplicб-la a verificaзгo do nome do jogador em todos os comandos.
    Params: vai publicar todo o motivo.
    */

    foreach(Player, i)
    /*
    O melhor script de todos "foreach"! Ele simplesmente substitui os "Loops" convencionais (que sгo uma coisa
    ruim que pelo amor) por outro, que й realmente muito mais rapido! E convenhamos, bem mais simples.
    No post oficial de Foreach existem diversos exemplos e como aplicб-los aos Loops.
    */

    {
        if (i != playerid) /*Verifica se o "administrador" que usou o comando nгo vai ser kickado juntamente
        com todos os outros jogadores.*/

        Kick(i);
        //Bom, vocк sabe.
    }
    return 1;
}
Aparentemente nгo existe "ENORME" diferenзa com um comando normal:
pawn Код:
if(strcmp(cmd, "/kicktodos", true) == 0)
    {
        new reason[128];
        if ( GetPVarInt( playerid, "Level" ) > 2 )
        {
            reason = strtok(cmdtext, idx);
            if(!strlen(reason))
            {
                SendClientMessage( playerid, COR, "ERRO: /kicktodos [Motivo]");
                return 1;
            }
            new String[128];
            format(String, sizeof(String), "%s chutou todos os jogadores. [Motivo: %s ] |-", pName( playerid ),reason);
            SendClientMessageToAll(COR, String);
            for(new i = 0; i < MAX_PLAYERS; i++)
            {
                if (i != playerid)
                {
                    Kick(i);
                }
            }
        }
        else SendClientMessage( playerid, COR, "ERRO: Apenas administradores acima do Level 2.");
        return 1;
    }
Mas a diferenзa existe! E й ENORME. Aparentemente nгo parece ser "TUDO" isso, mas este comando estб, digamos, simplificado. Se fossemos colocar a definiзгo de "cmd" o "strtok"...' ja ficaria bem maior. Sem contar que a diferenзa de tempo e desempenho entre os dois й realmente gigantesca! YCMD ainda й um poquinho complicado de se trabalhar, ja que ele vem com diversas funзхes (como o "Help", veja na pбgina oficial de YCMD), mais realmente vale um esforзo.

Uma observaзгo importante quanto as PVar й que, diferentemente das variaveis normais "(Pinfo[playerid][Level]...)' ela tem a vantagem da memуria, na qual ela se "aloca", permitindo que sua funcionalidade seja praticamente perfeita. Entretanto, sua diferenзa perante as variaveis normais й que, por estar usando a memуria, sua velocidade de execuзгo acaba sendo um pouco menor, mais isso й o MINIMO se compararmos todos os beneficios.

YCMD: Й altamente recomendavel que seja usado APENAS em scripts grandes (como um AdminScript), pois em um script de porte pequeno ele nгo vai ter tamanho resultado, suas funcionalidades ficaram praticamente nulas (Afinal, para que usar a funcionalidade da lista de comandos, quando se tem apenas 4-5 comandos?). (PS: YCMD й mais rбpido que ZCMD).

Bom, agora fica por sua conta. Os comandos acima nгo foram testados (й apenas um exemplo) de como funcionam algumas das funзхes que "aceleram" seu script. Passo a frente, vamos ao Y_Ini.
____________________________________

Um ponto de extrema importancia que vocк deve saber sobre Y_Ini antes de comeзar, й que todas suas funзхes (Seja leitura, ou ediзгo) devem estar sobre callbacks (Diferentemente de DINI).

Vou dar um exemplo SIMPLES de Login/Registro (Apenas um exemplo, se vocк testar, acredito que nгo vai funcionar) que salva o dinheiro e o nome do jogador (+PVars). Lembrando que й apenas um exemplo e Y_Ini possui diversas outras funcionalidades das quais requer um certo conhecimento (Veja no post oficial alguns tutoriais relacionados)

pawn Код:
#include    <YSI/y_ini>
//Faz a leitura do Include.
pawn Код:
public OnPlayerConnect(playerid)
{
    if(!INI_Exist( pName( playerid))) // Verifica se existe um arquivo com o nome do jogador.
    ShowPlayerDialog( playerid, D_REGISTRO, DIALOG_STYLE_INPUT, "Registro", "Coloque uma senha abaixo:", "Ok", "Sair");
    //Caso nгo exista o arquivo abre-se o dialog "STYLE_INPUT" com a mensagem acima.
    else ShowPlayerDialog( playerid, D_LOGIN, DIALOG_STYLE_INPUT, "Login", "Coloque sua senha abaixo:", "Logar", "Sair");
    //Caso o arquivo exista abre-se o dialog "STYLE_INPUT" com a mensagem acima.
    return 1;
}
pawn Код:
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
    switch(dialogid)
    {
        case D_REGISTRO: //Vocк sabe.
        {
            if (!response) //Caso a respota foi "Sair" (Botгo 2) o jogador й kickado.
            return Kick(playerid);
           
            if(response) //Respota "Ok" (Botгo 1). - Procegue a fuзгo.
            {
                if(strlen(inputtext[0]) == 0 ))
                    return ShowPlayerDialog( playerid, D_REGISTRO, DIALOG_STYLE_INPUT, "Senha Invбlida", "Vocк nгo digitou nenhum caractere, tente novamente.","Ok", "Sair");
                //Verifica se existe algum caractere digitado
               
                if(strlen( inputtext[0]) < 3 || strlen( inputtext[ 0 ] ) > 20 )
                    return ShowPlayerDialog( playerid, D_REGISTRO, DIALOG_STYLE_INPUT, "Senha Invбlida", "Minimo 3 caracteres, Mбximo 20 caracteres, tente novamente.","Ok", "Sair");
                //Verifica se a senha possui mais de 3 caracteres e menos de 20.
                   
                new pArquivo[ 10 + MAX_PLAYER_NAME ];
                //Novo arquivo do jogador. Nome Mбximo permitido pela SA-MP(24)+10(Contas/..ini)
                format( pArquivo , sizeof pArquivo, "Contas/%s.ini", Encode(pName(playerid)));
                //Aqui ele verifica se o nome do jogador possui caracteres invalidos (Permitido pelo SA-MP)
                //"encode" ele codifica o nome do jogador para que torne-se possivel a leitura.

                new INI:pConta = INI_Open(pArquivo); //Cria um novo arquivo (Se ja existe, apenas abre).
                INI_WriteString(pConta,"NOME",pName(playerid)); //Edita a String. "Nome" com o nome do jogador
                INI_WriteInt(pConta,"DINHEIRO",1000); //Edita a string "Dinheiro" com 1000 reais.
                INI_Close(pConta); //Fecha o arquivo.
                GivePlayerMoney( playerid, 1000 ); // >_>"
               
                ShowPlayerDialog( playerid, D_LOGIN, DIALOG_STYLE_INPUT, "Login", "Coloque sua senha abaixo:", "Logar", "Sair");
                //Abre o dialog de Login
                //Como eu disse й apenas um exemplo, nгo ha a necessidade de eu criar um login automбtico.
            }
        }
pawn Код:
//=====================================================================
        case D_LOGIN:
        {
            if (!response)//Caso a respota foi "Sair" (Botгo 2) o jogador й kickado.
            return Kick( playerid);
           
            if(response)//Respota "Ok" (Botгo 1). - Procegue a fuзгo.
            {
                if (strlen(inputtext) == 0)
                return ShowPlayerDialog( playerid, D_LOGIN, DIALOG_STYLE_INPUT, "Senha Invбlida","Vocк nгo digitou nada, tente novamente"",Logar", "Sair");

                new pArquivo[10+MAX_PLAYER_NAME],Password[20+1] ;
               
                format( pArquivo , sizeof pArquivo, "Contas/%s.ini",Encode(pName(playerid )));
               
                INI_ParseFile(pArquivo, "PlayerSenha", false, true, playerid); //Verifica a senha do jogador atraves da funзгo ParseFile
                //ela й um tanto complexa, verifique o post principal de y_ini par amais detalhes sobre como usб-la
                GetPVarString(playerid, "pSenha", Password, sizeof Password );
                //Verifica a senha em PVar.

                if(!strcmp (inputtext,Password,false ) ) //Verifica se a senha colocada й igual a senha do arquivo
                {
                    format( pArquivo , sizeof pArquivo, "Contas/%s.ini", Encode( pName( playerid ))); //Ja expliquei em registro.
                    INI_ParseFile( pArquivo, "CarregarJogador", false, true, playerid, true, false);
                    //Outra funзгo ParseFile, apenas leie o post principal de Y_ini e vocк vai entender.
                    GivePlayerMoney(playerid, GetPVarInt( playerid, "Dinheiro" ));
                    //Da o valor atual de dinheiro salvo no arquivo ao jogador, atravйs da variavel!
                }
                    else ShowPlayerDialog( playerid, D_LOGIN, DIALOG_STYLE_INPUT, "Senha Invбlida","Incorreta, tente novamente"",Logar", "Sair");
                    //Caso a senha nгo esteja correta, ele retorna ao dialog novamente.
                }
            }
        }
        return 1;
    }
}
Para as funзхes ParseFile agora!
pawn Код:
forward PlayerSenha( playerid, name[ ], value[ ] );
public PlayerSenha( playerid, name[ ], value[ ] )
{
    if ( !strcmp( name, "SENHA" ) ) //Compara a conta com a senha.
    {
        SetPVarString( playerid, "pSenha", value );
        //Coloca o valor da senha (a senha em si) dentro da variavel.
    }
}
pawn Код:
forward CarregarJogador( playerid, name[ ], value[ ] );
public CarregarJogador( playerid, name[ ], value[ ] )
{
    if(!strcmp(name, "DINHEIRO"))SetPVarInt( playerid,"Dinheiro", strval(value));
    //Bom, й um sistema simples. Apenas salvando o dinheiro vocк ja deve ter uma noзгo
    //do seu funcionamento. Aqui, ele pega o valor atual do dinheiro do jogador e coloca dentro
    //da variavel "Dinheiro"
   
}
Й basico, mais nгo vamos deixar de lado a funзгo de salvar as ultimas informaзхes antes do jogador sair:
pawn Код:
public OnPlayerDisconnect(playerid, reason)
{
    if (INI_Exist(pName(playerid))) //Verifica se exite o arquivo com o nome do jogador que se desconectou
    {
        new pArquivo[10+MAX_PLAYER_NAME +1]; //10+24+1(Nulo).
        format(pArquivo ,sizeof pArquivo, "Contas/%s.ini", Encode(pName( playerid ))); //Ja expliquei.

        new INI:pConta = INI_Open( pArquivo ); //Abre o Arquivo do jogador
        INI_WriteInt( pConta,"DINHEIRO",GetPlayerMoney( playerid ));
        INI_Close( pConta ); //Fecha o arquivo.
    }
    return 1;
}
Perguntas frequentes de preguiзos que nгo gostam de ler:
Y_ini й mais rбpido que DINI?
Sim.
YCMD й mais rapido que ZCMD?
Na maioria dos casos.
Como eu uso foreach em outros casos?
Primeiro leia o post principal do sistema, depois pergunte.
YCMD й muito complicado?
Nгo.
Eu ja sabia de tudo isso, e dai?
Precisa responder?
Nгo tenho a funзгo "pName". Aonde acho?
pawn Код:
stock pName( playerid )
{
    new Name[ MAX_PLAYER_NAME ];
    GetPlayerName( playerid, Name, sizeof( Name ) );
    return Name;
}
pVars realmente podem ser lidas de um script para outro?
Sim. Seus valores podem ser lidos de um FS em um GM (por exemplo)

Eu realmente ODEIO fazer tutoriais (Sу fiz este por que recebei algumas mensagens privadas sobre Y_ini), 90% das vezes й seguido por diversas perguntas que nem ao menos tem relaзгo com o assunto postado, e na maioria dos casos a prуpria resposta da pergunta esta no post. Entгo, leia, tente absorver algo, se nгo, apenas nгo abra o post. Como eu disse no comeзo, й um sistema simples, apenas para informaзгo e nгo para uso. Agora, caso alguem realmente tenha alguma pergunta construtiva, sinta-se livre para perguntar. Espero que tenha dado para adquirir algum conhecimento.
Reply
#2

Hehe eu estava procurando como usar Y_ini a ums trкs dias atrбs, mas consegui usar totalmente ontem, realmente Y_ini й уtimo mas como vocк disse algumas pessoas preferem usar Dini pela "Praticidade" ou as vezes por pura preguiзa mesmo.Foreach eu sempre usei, vou trocar meu ZCMD para YCMD tambйm pois sу tive vantagem com os trabalhos do ******. Ah jб ia me esquecendo, уtimo trabalho LuxurioN.
Reply
#3

Muito legal o tutorial, reforзo muito meu conhecimento de y_ini, jб estou passando meu sistema de salvamento para essa include. Agora vou aprender a usar ycmd...

Vlw pelo tuto Luxurion...
Reply
#4

Quote:
Originally Posted by Strong_ADM
Посмотреть сообщение
Hehe eu estava procurando como usar Y_ini a ums trкs dias atrбs, mas consegui usar totalmente ontem, realmente Y_ini й уtimo mas como vocк disse algumas pessoas preferem usar Dini pela "Praticidade" ou as vezes por pura preguiзa mesmo.Foreach eu sempre usei, vou trocar meu ZCMD para YCMD tambйm pois sу tive vantagem com os trabalhos do ******. Ah jб ia me esquecendo, уtimo trabalho LuxurioN.
Quote:
Originally Posted by leandro123456
Посмотреть сообщение
Muito legal o tutorial, reforзo muito meu conhecimento de y_ini, jб estou passando meu sistema de salvamento para essa include. Agora vou aprender a usar ycmd...

Vlw pelo tuto Luxurion...
Realmente. De uns tempos pra cб estou me dedicando a estudar o YSI (Os sistemas do ******) juntamente com C++, atй parei um pouco de atualizar o AdminScript, para ver como funciona. E, sу atualmente pude perceber o quando perdemos. Alex fez o que, na minha opiniгo, й o melhor conjunto de scripts do SA-MP. YSI й simples e possui cуdigos bem avanзados, alйm de serem perfeitamente estruturados. Sinto por estar comeзando a estudб-lo e ver suas verdadeiras funcionalidades apenas agora. Acredito que os "scripters" estгo dando algum valor somente agora porque conforme os scripts vгo crescendo de tamanho, os verdadeiros problemas "Internos" comeзam a surgir, requerendo algo com mais "desempenho", e funзхes mais inovadoras.

Mas, infelizmente ainda existem aqueles que apenas pegam os scripts prontos, modificam 3-4 linhas e dizem terem sido eles que fizeram. Querem enganar a quem? A si mesmos, й pior apenas para si prуprio. Eu queria ver, quantas pessoas que se dizem "scripters" serem capazes de abrirem o pawno e criarem, do nada, um script considerado avanзado.
Reply
#5

Complicado ._.
Reply
#6

Naao E Tao Complicado ..
E So Ter Paciencia ..
Muito Bom O Tutorial LuxurioN™
Reply
#7

Quote:
Originally Posted by [AF]Junior
Посмотреть сообщение
Complicado ._.
Pessoas limitadas acham coisas complicadas.


@TOPIC:
Bom tutorial
Reply
#8

Higor... "O homem comum fala, o sбbio escuta, o tolo discute."
Reply
#9

Quote:
Originally Posted by LuxurioN™
Посмотреть сообщение
Realmente. De uns tempos pra cб estou me dedicando a estudar o YSI (Os sistemas do ******) juntamente com C++, atй parei um pouco de atualizar o AdminScript, para ver como funciona. E, sу atualmente pude perceber o quando perdemos. Alex fez o que, na minha opiniгo, й o melhor conjunto de scripts do SA-MP. YSI й simples e possui cуdigos bem avanзados, alйm de serem perfeitamente estruturados. Sinto por estar comeзando a estudб-lo e ver suas verdadeiras funcionalidades apenas agora. Acredito que os "scripters" estгo dando algum valor somente agora porque conforme os scripts vгo crescendo de tamanho, os verdadeiros problemas "Internos" comeзam a surgir, requerendo algo com mais "desempenho", e funзхes mais inovadoras.

Mas, infelismente ainda existem aqueles que apenas pegam os scripts prontos, modificam 3-4 linhas e dizem terem sido eles que fizeram. Querem enganar a quem? A si mesmos, й pior apenas para si prуprio. Eu queria ver, quantas pessoas que se dizem "scripters" serem capazes de abrirem o pawno e criarem, do nada, um script considerado avanзado.
boas,

olha obrigado por esse comentario pois so disseste as verdades ai... o YSI й um conjunto de scripts que eu realmente admiro , muito , porem nunca fui capaz o suficiente para pensar em o estudar sempre fui na onda de simplesmente usar apesar de penso que facilmente aprendo ... muitos daqui nem conhecem metade das minhas capacidades , muito poucos sabem o que eu sou realmente capaz de fazer porem tambem ver se comeзo a estudar realmente c++ mas... o tempo n da para tudo e tbm temos que os divertir :P ( para alem de eu ser o maior perguiзoso a face da terra XD )

bem mas de qualquer maneira obrigado pelo tutorial
Reply
#10

Quote:
Originally Posted by Falcon.Sixe
Посмотреть сообщение
Nossa. Ficou muito bom o tutorial. Уtimo trabalho Luxurion..
Jб deixei de usar Y_INI 2 vezes para usar dini porque й realmente mais prбtico..Mas se for parar para pensar.Compensa mesmo entender esse sistema de ponta a ponta e comeзa-lo a usar.
Meus parabйns. em todas as suas ajudas a tуpicos ou com tutoriais, ficam bem explicados..Muito bom mesmo
Y_ini й "mais objetivo", ele nos permite criar coisas nas quais eram literalmente impossiveis com DINI. Nгo й complicado, й como um Photoshop perto do Paint, apenas possui funcionalidades demais, das quais devemos aprender a usб-las.

Quote:
Originally Posted by SlashPT
Посмотреть сообщение
boas,

olha obrigado por esse comentario pois so disseste as verdades ai... o YSI й um conjunto de scripts que eu realmente admiro , muito , porem nunca fui capaz o suficiente para pensar em o estudar sempre fui na onda de simplesmente usar apesar de penso que facilmente aprendo ... muitos daqui nem conhecem metade das minhas capacidades , muito poucos sabem o que eu sou realmente capaz de fazer porem tambem ver se comeзo a estudar realmente c++ mas... o tempo n da para tudo e tbm temos que os divertir :P ( para alem de eu ser o maior perguiзoso a face da terra XD )

bem mas de qualquer maneira obrigado pelo tutorial
Quote:
Originally Posted by H1g0r
Посмотреть сообщение
Eu tambйm jб fiquei horas estudando o Foreach, ate mesmo para fazer um igual, nгo a copia mais sim um sistema complexo que nem o dele, o ****** acredito que ele tenha um grande conhecimento pois ja estou varais бreas fora do sa-mp, concerteza isso deixou ele com o conhecimento melhor estou a fazer o mesmo expandindo meus conhecimentos a outras linguagens.
Fico feliz por ver outras pessoas que realmente se interessam pelo linguagem, Alex (******) tem um conhecimento bem avanзado, afinal й o trabalho dele, tambйm pretendo seguir o mesmo caminho. E como o Higor disse, devemos expandir nossas fronteiras do conhecimento alйm de SA-MP. Quem conhece a linguagem Pawn com perfeiзгo nгo vai ter problema algum em comeзar a estudar C++, Pawn й literalmente a sua base.
Reply


Forum Jump:


Users browsing this thread: 3 Guest(s)