09.03.2011, 16:24
(
Последний раз редактировалось LuxurioN™; 15.03.2011 в 03:44.
Причина: Correзгo (Sintaxe Ortogrбfica).
)
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:
Agora, uma comparaзгo com explicaзгo em outro comando:
Aparentemente nгo existe "ENORME" diferenзa com um comando normal:
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)
Para as funзхes ParseFile agora!
Й basico, mais nгo vamos deixar de lado a funзгo de salvar as ultimas informaзхes antes do jogador sair:
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?
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.
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;
}
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;
}
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;
}
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;
}
}
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"
}
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;
}
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;
}
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.