SA-MP Forums Archive
[Tutorial] YSeries - Y_INI - Printable Version

+- SA-MP Forums Archive (https://sampforum.blast.hk)
+-- Forum: Non-English (https://sampforum.blast.hk/forumdisplay.php?fid=9)
+--- Forum: Languages (https://sampforum.blast.hk/forumdisplay.php?fid=33)
+---- Forum: Español/Spanish (https://sampforum.blast.hk/forumdisplay.php?fid=29)
+----- Forum: Lanzamientos/Releases (https://sampforum.blast.hk/forumdisplay.php?fid=59)
+----- Thread: [Tutorial] YSeries - Y_INI (/showthread.php?tid=535991)



YSeries - Y_INI - TheChaoz - 06.09.2014

YSI Series - Y_INI



Introducciуn
Bueno, dado que mucha gente me ha preguntado sobre el uso de algunos includes pertenecientes a la librerнa YSI, he decidido comenzar una serie de tutoriales al respecto.
El primero sera este en el cual intentare explicar como utilizar Y_INI correctamente y de una forma simple. Claro esta que si quieren alguna librerнa en particular, pueden decirme e intentare realizar dicho tutorial si asн lo creo conveniente y/o posible.
Les recuerdo como siempre que si ven algun error me avisen para poder corregirlo.

Nota: Si bien es un tutorial sobre Y_INI, no me concentrare concretamente en que hace cada funciуn del mismo, si no, mas bien en como utilizarlas de una forma practica con ejemplos.



Indice

Introducciуn a INI
Si queremos poder utilizar todas las caracterнsticas de Y_INI, primero debemos conocer mejor el formato INI.

їQuй es INI?
El formato INI es un formato (valida la redundancia) utilizado para almacenar mas ordenadamente datos. Estos datos tienen la caracterнstica particular de que poseen una descripciуn similar.

Ejemplo:
Si quisiйramos formar una base de datos sobre personas de nuestra empresa tendrнamos datos personales como por ejemplo su nombre, apellido, direcciуn, edad, nacionalidad y datos laborales como por ejemplo la fecha en la que ingreso a trabajar, su sueldo y el puesto que ocupa. Por lo cual para formar nuestra base de datos necesitarнamos almacenar los mismos, por lo que nuestros archivos INI podrнan ser asн:
Код:
[Personales]
Nombre=Nicolas
Apellido=Rodriguez
Edad=25
Direccion=Av. Espora 672
Nacionalidad=Argentina

[Laborales]
FechaIngreso=27/7/1998
Sueldo=18600
Cargo=Director Finanzas
De esta forma el formato INI no solo nos permite almacenar los datos con una breve descripciуn del mismo, si no que tambiйn nos permite organizarlos por secciones. Explicare mas tйcnicamente esto a continuaciуn.

Secciones y entradas

Secciones
Se llaman secciones a las divisiones creadas por los tags. Los tags se encuentran definidos por palabras encerradas entre corchetes ('[' ']'); estas secciones como se ve en el ejemplo anterior se utilizan para la mejor organizaciуn del documento.
Pero si se utilizan lectores relativamente avanzados, tambiйn brinda una mayor permanecer de lectura ya que si necesitamos un dato en particular buscaremos dentro de la secciуn del mismo y no por todo el documento en si.

Entradas
Las entradas estбn representadas por el conjunto de pares y valores que componen cada entrada.
Las entradas estбn compuertas por una llave o descripciуn (key) seguido de un '=' seguido de un valor (value).

Ejemplo:
[code]key=value[/key]

Una particularidad de las entradas es que no pueden repetirse iguales llaves a diferentes valores dentro de una misma secciуn, pues solo se leerб 1 de ellas (dependiendo del mйtodo de lectura sera la primera o ultima).

Ejemplo:
Код:
[Seccion1]
key1=valor1
key2=valor2
key3=valor3
key1=valor54

[Seccion2]
key1=valor1
key2=valor2
key3=valor3
En este ejemplo es muy posible que el valor obtenido al leer 'key1' de la secciуn1 sea 'valor1', pero tambiйn podrнa ser 'valor54'. Es por este motivo que un archivo INI bien formado no puede tener 2 keys idйnticos dentro de una misma secciуn.

Nota: Notemos que como los textos en formato INI se guardan en texto plano en el ejemplo anterior valorN (siendo N un numero) podrнa ser tanto un valor numйrico como el texto en si mismo; el tipo del valor dependerб de como se lo lea.

Comentarios
En este formato tambiйn podemos realizar comentarios, los cuales se indican colocando un ';' al comienzo del mismo.

Ejemplo:
Код:
key=value ;Esto es un comentario y no forma parte de la entrada

Y_INI Bбsico

Creando un archivo
Para poder trabajar con archivos INI primero necesitamos el archivo en si, por lo que debemos crearlo. Esto se realiza mediante una simple funciуn llamada INI_Open.

Ejemplo:
pawn Код:
new INI:file = INI_Open("ruta/de/nuestro/archivo.ini");
Y asi tan simple como esa linea creamos nuestro archivo, pero debemos comprender que el archivo esta abierto para escritura, por lo cual debemos cerrarlo. Entonces utilizamos la funciуn INI_Close.

Ejemplo:
pawn Код:
INI_Open(file);

Escritura

Ahora que sabemos como crear nuestro archivo podemos escribir datos en el mismo. Esta podrнa considerarse la parte simple.

Ejemplo:
pawn Код:
new
    INI:file = INI_Open("/Usuarios/TheChaoz.ini");

//Guardamos datos personales del usuario
//Seteamos el tag
INI_SetTag(file, "account_data");
//Guardamos datos
INI_WriteString(file, "Password", "12345");
INI_WriteInt(file, "Banned", 0);

//Guardamos informaciуn sobre las estadнsticas del usuario
INI_SetTag(file, "account_stats");
INI_WriteInt(file, "Score", 150);
INI_WriteInt(file, "Kills", 1500);
INI_WriteInt(file, "Deaths", 1500);
INI_WriteInt(file, "Money", 10000);
INI_WriteFloat(file, "SpawnX", 100.0);
INI_WriteFloat(file, "SpawnY", 100.0);
INI_WriteFloat(file, "SpawnZ", 1.0);

INI_Close(file);
El archivo que dicho cуdigo crearнa es el siguiente:
Код:
[account_stats]
SpawnZ = 1.000000
SpawnY = 100.000000
SpawnX = 100.000000
Money = 10000
Deaths = 1500
Kills = 1500
Score = 150
[account_data]
Banned = 0
Password = 12345
Nota: Recomiendo el uso de tags no solo para una mejor organizaciуn en caso de tener que leer el archivo, si no tambiйn por movilizaciуn (luego veremos esto con mas detalle).


Lectura

Y_INI brinda una gran variedad de formas de leer archivos, generalmente aquн es donde muchos usuarios no entienden como funciona el sistema y lo abandonan.

Intentare cubrir algunas de ellas con los aspectos mas bбsicos y simples.

Para leer un archivo utilizaremos la funciуn "INI_Load". Esta funciуn tiene algunos parбmetros opcionales los cuales iremos analizando uno por uno.

pawn Код:
INI_Load(filename[], bool:bExtra = false, extra = 0, bool:bLocal = true);
Veamos algunos ejemplos para comprender mejor el funcionamiento de esta funciуn.


Forma bбsica

Esta forma se suele utilizar con archivos cuyos nombres ya conocemos de ante-mano, por ejemplo archivos de configuraciуn, datos del servidor (no de usuarios), etc.

Ejemplo:
Код:
;este es un archivo utilizado como ejemplo para el siguiente cуdigo
[general]
MustLogin=1
MustRegister=0
[version]
Name=XXX Server
Version=1.4
[other]
DisableChat=0
pawn Код:
new
    gLogin,
    gRegister,
    gName[24],
    Float:gVersion,
    gChat;

public OnFilterScriptInit()
{
    INI_Load("/Config.ini");//Cargamos nuestro archivo

    printf("[general] MustLogin: %i  ||  MustRegister: %i", gLogin, gRegister);
    printf("[versiуn] Name: %s  ||  Version: %.1f", gName, gVersion);
    printf("[other] DisableChat: %i", gChat);

    return 1;
}

/*Aqui es donde hay algo de 'magia' que explicaremos mas adelante, pero por el momento lo que necesitamos saber es que luego de utilizar INI_Load, pawn leerб nuestro archivo
y linea por linea llamara a las siguientes callbacks segъn corresponda, indicando en 'name' el key y en value el valor de cada entrada.*/



//Fuera de cualquier callback y/o funciуn

//Este callback sera llamado ъnicamente con las entradas que estйn dentro del tag 'general'
INI:Config[general](name[], value[])
{
    //Aqui leeremos las entradas del tag 'general'
    INI_Int("MustLogin", gLogin);
    INI_Int("MustRegister", gRegister);

    return 0;//Este return solo es necesario pues utilizamos las macros provistas por Y_INI las cuales tienen en su definiciуn un return.
}

INI:Config[version](name[], value[])
{
    //Aquн leeremos las entradas del tag 'versiуn'
    INI_String("Name", gName, 24);
    INI_Float("Version", gVersion);

    return 0;
}

INI:Config[other](name[], value[])
{
    //Aqui leeremos las entradas del tag 'other'
    INI_Int("DisableChat", gChat);

    return 0;
}
La salida del cуdigo anterior seria:
Код:
[general] MustLogin: 1  ||  MustRegister: 0
[version] Name: XXX Server  ||  Version: 1.3
[other] DisableChat: 0
Ahora bien, dado el ejemplo explicare algunas cosas que tal vez se estйn preguntando.

їPorque utilice variables globales?
Esto se debe a que utilice las macros que nos brinda Y_INI (INI_Int, INI_Float, INI_String). Estas macros incluyen un return dentro, es decir que si el valor es leнdo, ya no se ejecutara cуdigo luego de esa
linea. Esto no quiere decir que estemos obligados a utilizar este mйtodo siempre (aun que a veces puede ser ъtil).

Ejemplo:
pawn Код:
//Las siguientes lineas de cуdigo son anбlogas, solo que la primera no ejecutara cуdigo posterior al leer un dato y la segunda si:
INI_Float("Version", version);
if(!strcmp(name, "Version))
    version = floatstr(value);

Con argumentos extra

Lo que esta forma nos permite es pasar un argumento extra al callback de carga (solo puede ser una variable y no un array).

Ejemplo:
Код:
;este es un archivo utilizado como ejemplo para el siguiente cуdigo
[general]
key1=132
key2=251
key3=512
key4=560
key5=2312
key6=1231
pawn Код:
new
    gValues[10];

public OnFilterScriptInit()
{
    INI_Load("/Numbers.ini", .bExtra=true, .extra=3);//Cargamos nuestro archivo indicando que recibirб un argumento extra y que dicho argumento es el numero 3 (este argumento podrнa ser variable)

    for(new i; i<6; i++)
        printf("key%i: %i", i+1, gValues[i]);

    return 1;
}

//Aquн como podemos observar sera nuestro primer parбmetro el que reciba nuestro parбmetro extra.
INI:Numbers[general](number, name[], value[])
{
    new
        key[5];
    //Lo que este cуdigo realiza es comparar uno por uno los nombres de cada entrada (comprobar sean key1-key6) y multiplicar el valor de dicha entrada por el parбmetro extra
    for(new i; i<6; i++){
        format(key, 5, "key%i", i+1);
        if(!strcmp(name, key)) {
            gValues[i] = strval(value)*number;
            return 1;
        }
    }

    return 0;
}
La salida del cуdigo anterior seria:
Код:
key1: 396
key2: 753
key3: 1536
key4: 1680
key5: 6936
key6: 3693

Y_INI Simplificado

Lectura

Al utilizar Y_INI tenemos muchas formas de leer archivos. El siguiente ejemplo es a mi parecer la forma mas simple de leer un archivo, pero tiene como desventaja la dependencia de otra librerнa (y_inline).


Ejemplo: (El siguiente ejemplo supone la correcta definiciуn de pData, array en la cual se almacenan los datos del jugador)
pawn Код:
stock LoginPlayer(playerid)
{
    new
        file[15 + MAX_PLAYER_NAME],
        pName[MAX_PLAYER_NAME],
        Float:P[3];

    GetPlayerName(playerid, pName, MAX_PLAYER_NAME);

    //Este es el callback inline, el cual es llamado 1 vez por cada entrada del archivo (los tags no estбn incluidos en este ejemplo)
    inline Load(name[], value[])
    {
        //Notemos que las siguientes macros solo funcionan si se definieron los argumentos de nuestra funciуn con los nombres "name[]" y "value[]"
        INI_Float("SpawnX", P[0]);
        INI_Float("SpawnY", P[1]);
        INI_Float("SpawnZ", P[2]);
        INI_Int("Deaths", pData[playerid][Deaths]);
        INI_Int("Kills", pData[playerid][Kills]);

        if(!strcmp(name, "Money"))//Podrнamos usar la macro INI_Int, pero deberнamos crear una variable extra, ademas asi se ejemplifica otra forma de leer los datos
            GivePlayerMoney(playerid, strval(value));
        else if(!strcmp(name, "Score"))
            SetPlayerScore(playerid, strval(value));
        else if(!strcmp(name, "Banned") && strval(value))
            Kick(playerid);
    }
    format(file, sizeof(file), "/Usuarios/%s.ini", pName);

    INI_ParseFile(file, using inline "Load");//Realizamos la lectura del archivo indicando que la funciуn es inline (y se llama "Load") y esta en este bloque de codigo.
    SetPlayerPos(playerid, P[0], P[1], P[2]);

    return 1;//Al igual que antes, es necesario el return por utilizar las macros INI_{Float/Int/...}
}


Y_INI ParseFile

Esto en realidad no es avanzado, pero si no se entiende lo que se hace puede llegar a ser algo confuso, es por esto que mucha gente opta por no utilizar este include.

Comenzemos por analizar el header de la funciуn:
pawn Код:
stock bool:INI_ParseFile(fname[], remoteFormat[], bool:bFileFirst = false, bool:bExtra = false, extra = 0, bool:bLocal = true, bool:bPassTag = false, bool:bFilter = true, filter[] = "")
Nota: El header a partir de YSI 4.0 es otro, pero aun no esta definido y provee una forma diferente de utilizaciуn, la cual no es tan eficiente, por lo que no se explicaran las diferencias aquн.


Final

Espero que les haya servido y si ven algъn error por favor avнsenme asi lo corrijo.


Respuesta: YSeries - Y_INI - ErickPuga234 - 06.09.2014

Muchas gracias buen post!


Respuesta: YSeries - Y_INI - Glimma - 06.09.2014

Quote:
Originally Posted by ErickPuga234
Посмотреть сообщение
Muchas gracias buen post!
їTan rбpido lo leнste?

Lo leн a medias pero se ve que estб completo y le va a servir a varios.

Como veo que pusiste "YSeries", їplaneas hacer tutoriales de la librerнa YSI?


Respuesta: YSeries - Y_INI - aoEXE - 06.09.2014

jojojojojo muchas gracias TheChaoz, desde que me dijiste que lo harнas estuve esperбndolo

Quote:
Originally Posted by Glimma
Посмотреть сообщение
Como veo que pusiste "YSeries", їplaneas hacer tutoriales de la librerнa YSI?
creo que si, eso entendн en la introducciуn. Serнa buenнsimo que haga eso!


Respuesta: YSeries - Y_INI - Glimma - 06.09.2014

Yo creo que a la gente le servirнa tutoriales de y_iterate, y_dialog e y_inline, y_timers, e y_stringhash. Yo podrнa hacer alguno, en teorнa, son fбciles de usar, y son efectivos.


Respuesta: YSeries - Y_INI - !R1Ch@rD! - 06.09.2014

buen aporte amigo yo que quiero aprender un poco de esto :3


Respuesta: YSeries - Y_INI - xGrov3x - 07.09.2014

Gracias por el tutorial habнan unas cosas de "ParseFile" que no me quedaban muy claras.


Respuesta: YSeries - Y_INI - chusothe41 - 07.09.2014

Genialidad. Gracias