#1

Hola a todos..

Tenia una Duda:

pawn Код:
#define _ALS_OnFilterScriptInit
Queria saber para que sirve y como se usa el _ALS_ porque lo he visto en muchos INC.
Reply
#2

Seсor Dreyfuz este metodo es utilizado para hacer Hooks de funciones o callbacks para hacer que un cуdigo se ejecute en una funciуn nativa sin tener que alterarla.

Ejemplo:

pawn Код:
enum pInfo
{
  dinero
};
static PlayerInfo[MAX_PLAYERS][pInfo];
stock GivePlayerMoneyEx(playerid, dinero)
{
    GivePlayerMoney(playerid, dinero);
    PlayerInfo[playerid][dinero] += dinero;
    return 1;
}

#if defined _ALS_GivePlayerMoney // Esto sirve para verificar si _ALS_GivePlayerMoney esta definida.
  #undef  GivePlayerMoney // Usamos esto para poder redefinir GivePlayerMoney asi el compilador no lanzara error de redefiniciуn.
#else
#define _ALS_GivePlayerMoney // Definimos el ALS de GivePlayerMoney.
#endif

#define GivePlayerMoney GivePlayerMoneyEx // Esto hace que al ejecutar GivePlayerMoney se ejecute la funci[on creada por nosotros que en este caso es GivePlayerMoneyEx.
Es facil de usar pero hay varias formas de hacer Hooks de funciones y callbacks.

PD: En fнn esto sirve para ejecutar cуdigos creados por el programador para ser ejecutados ensima de una funciуn nativa de SA-MP como por ejemplo el ejemplo que mostre anteriormente, lo que hize fue que al usar GivePlayerMoney este llamase a la funciуn creada por mi GivePlayerMoneyEx sin tener que cambiar todos los GivePlayerMoney a GivePlayerMoneyEx.

Un saludo.

EDIT:

Me olvidй de explicar como hacer un Hook de Callback.

Ejemplo:

pawn Код:
public OnPlayerConnect(playerid)
{
  SendClientMessage(playerid, -1, "Prueba");
  CallLocalFunction("F_OnPlayerConnect", "i", playerid); // Sirve para llamar la callback definidas por nosotros que en este caso es F_OnPlayerConnect.
    return 1;
}

#if defined _ALS_OnPlayerConnect // Esto sirve para verificar si _ALS_OnPlayerConnect esta definida.
  #undef  OnPlayerConnect // Usamos esto para poder redefinir OnPlayerConnect asi el compilador no lanzara error de redefiniciуn.
#else
#define _ALS_OnPlayerConnect // Definimos el ALS de OnPlayerConnect.
#endif

#define OnPlayerConnect F_OnPlayerConnect // Esto hace que al ejecutar OnPlayerConnect se ejecute la funciуn creada por nosotros que en este caso es OnPlayerConnect.

forward F_OnPlayerConnect(playerid);
Recuerde siempre poner las callbacks y funciones por encima del ALS.
Reply
#3

oOFotherOo te estas ekivocando en esto:

el CallLocalFunction no vas dentro del call va en el return para ke retorne.

pawn Код:
public OnPlayerConnect(playerid)
{
  SendClientMessage(playerid, -1, "Prueba");
    return CallLocalFunction("F_OnPlayerConnect", "i", playerid); // Sirve para llamar la callback definidas por nosotros que en este caso es F_OnPlayerConnect.
}
Reply
#4

Completando y simplificando la explicacion de oOFotherOo, este es un metodo utilizado para crear includes y facilitar su uso, para que el include haga el trabajo del scripter por decirlo de alguna forma. Sin este metodo (u otros, ya que no es el unico), lo que deberia hacerse es colocar el callback/funcion dentro de cada codigo.

Para que se entienda mejor un ejemplo.
Supongamos el siguiente include:
pawn Код:
//INCLUDE:
public Health_OnPlayerSpawn(playerid)
{
    SetPlayerHealth(playerid, 100.0);
    return 1;
}
//mas codigo que no nos interesa
El scripter para hacer uso correcto del include, deberia hacer lo siguiente:

pawn Код:
#include <a_samp>
#include <health>//este es el include descripto arriba

public OnPlayerSpawn(playerid)
{
    CallLocalFunction("Health_OnPlayerSpawn", "i", playerid);
    //resto del codigo
    return 1;
}
Ahora bien, si el include 'health' utilizara ALS o algun otro metodo para hookear callbacks, el uso seria diferente.
pawn Код:
//INCLUDE:
new HEALTH_OPS;//En esta variable almacenaremos un valor indicando si se utiliza el callback OnPlayerConnect

#if defined FILTERSCRIPT
public OnFilterScriptInit()
{
    HEALTH_OPS = funcidx("TAG_OnPlayerSpawn");
    return 1;
}

#else

public OnGameModeInit()
{
    HEALTH_OPS = funcidx("TAG_OnPlayerSpawn");
    return 1;
}

public OnPlayerSpawn(playerid)
{
    SetPlayerHealth(playerid, 100.0);
    if(HEALTH_OPS != -1)
        return CallLocalFunction("HEALTH_OnPlayerSpawn", "i", playerid);
    return 1;
}
#if defined _ALS_OnPlayerSpawn
    #undef OnPlayerSpawn
#else
    #define _ALS_OnPlayerSpawn
#endif
#define OnPlayerConnect HEALTH_OnPlayerSpawn
forward public HEALTH_OnPlayerSpawn(playerid);
//mas codigo que no nos interesa
Ahora si el include fuera el anterior, bastaria con incluir el archivo sin necesidad de agregar nada al callback 'OnPlayerSpawn'.

pawn Код:
#include <a_samp>
#include <health>

public OnPlayerSpawn(playerid)
{
    //codigo
    return 1;
}
Nota: La forma correcta para hockear un callback, no es ninguna de las anteriormente mencionadas ya que ambas tienen errores.

pawn Код:
new TAG_OPC;//En esta variable almacenaremos un valor indicando si se utiliza el callback OnPlayerConnect

//Con el siguiente codigo lo que hacemos es optimizar el script para evitar chequear si se utiliza el callback o no cada vez q se llame a OnPlayerConnect (lo chequeamos solo 1 vez al inicio y listo).
#if defined FILTERSCRIPT
public OnFilterScriptInit()
{
    TAG_OPC = funcidx("TAG_OnPlayerConnect");
    return 1;
}

#else

public OnGameModeInit()
{
    TAG_OPC = funcidx("TAG_OnPlayerConnect");
    return 1;
}

#endif

//Este es el callback utilizado por nuestro include
public OnPlayerConnect(playerid)
{
    //Codigo del include.

    if(TAG_OPC != -1)
        return CallLocalFunction("TAG_OnPlayerConnect", "i", playerid);
    return 1;
}
#if defined _ALS_OnPlayerConnect
    #undef OnPlayerConnect
#else
    #define _ALS_OnPlayerConnect
#endif
#define OnPlayerConnect TAG_OnPlayerConnect
forward public TAG_OnPlayerConnect(playerid);
Reply
#5

Quote:
Originally Posted by the_chaoz
Посмотреть сообщение
Completando y simplificando la explicacion de oOFotherOo, este es un metodo utilizado para crear includes y facilitar su uso, para que el include haga el trabajo del scripter por decirlo de alguna forma. Sin este metodo (u otros, ya que no es el unico), lo que deberia hacerse es colocar el callback/funcion dentro de cada codigo.

Para que se entienda mejor un ejemplo.
Supongamos el siguiente include:
pawn Код:
//INCLUDE:
public Health_OnPlayerSpawn(playerid)
{
    SetPlayerHealth(playerid, 100.0);
    return 1;
}
//mas codigo que no nos interesa
El scripter para hacer uso correcto del include, deberia hacer lo siguiente:

pawn Код:
#include <a_samp>
#include <health>//este es el include descripto arriba

public OnPlayerSpawn(playerid)
{
    CallLocalFunction("Health_OnPlayerSpawn", "i", playerid);
    //resto del codigo
    return 1;
}
Ahora bien, si el include 'health' utilizara ALS o algun otro metodo para hookear callbacks, el uso seria diferente.
pawn Код:
//INCLUDE:
new HEALTH_OPS;//En esta variable almacenaremos un valor indicando si se utiliza el callback OnPlayerConnect

#if defined FILTERSCRIPT
public OnFilterScriptInit()
{
    HEALTH_OPS = funcidx("TAG_OnPlayerSpawn");
    return 1;
}

#else

public OnGameModeInit()
{
    HEALTH_OPS = funcidx("TAG_OnPlayerSpawn");
    return 1;
}

public OnPlayerSpawn(playerid)
{
    SetPlayerHealth(playerid, 100.0);
    if(HEALTH_OPS != -1)
        return CallLocalFunction("HEALTH_OnPlayerSpawn", "i", playerid);
    return 1;
}
#if defined _ALS_OnPlayerSpawn
    #undef OnPlayerSpawn
#else
    #define _ALS_OnPlayerSpawn
#endif
#define OnPlayerConnect HEALTH_OnPlayerSpawn
forward public HEALTH_OnPlayerSpawn(playerid);
//mas codigo que no nos interesa
Ahora si el include fuera el anterior, bastaria con incluir el archivo sin necesidad de agregar nada al callback 'OnPlayerSpawn'.

pawn Код:
#include <a_samp>
#include <health>

public OnPlayerSpawn(playerid)
{
    //codigo
    return 1;
}
Nota: La forma correcta para hockear un callback, no es ninguna de las anteriormente mencionadas ya que ambas tienen errores.

pawn Код:
new TAG_OPC;//En esta variable almacenaremos un valor indicando si se utiliza el callback OnPlayerConnect

//Con el siguiente codigo lo que hacemos es optimizar el script para evitar chequear si se utiliza el callback o no cada vez q se llame a OnPlayerConnect (lo chequeamos solo 1 vez al inicio y listo).
#if defined FILTERSCRIPT
public OnFilterScriptInit()
{
    TAG_OPC = funcidx("TAG_OnPlayerConnect");
    return 1;
}

#else

public OnGameModeInit()
{
    TAG_OPC = funcidx("TAG_OnPlayerConnect");
    return 1;
}

#endif

//Este es el callback utilizado por nuestro include
public OnPlayerConnect(playerid)
{
    //Codigo del include.

    if(TAG_OPC != -1)
        return CallLocalFunction("TAG_OnPlayerConnect", "i", playerid);
    return 1;
}
#if defined _ALS_OnPlayerConnect
    #undef OnPlayerConnect
#else
    #define _ALS_OnPlayerConnect
#endif
#define OnPlayerConnect TAG_OnPlayerConnect
forward public TAG_OnPlayerConnect(playerid);
por ke esta mal ?, si funcidx esta haciendo lo mismo ke si oclocaramos el CallLocalFunction en el return .
Reply
#6

Esta mal ya que CallLocalFunction retorna 0 si la funcion llamada no existe.
Reply
#7

Quote:
Originally Posted by the_chaoz
Посмотреть сообщение
Completando y simplificando la explicacion de oOFotherOo, este es un metodo utilizado para crear includes y facilitar su uso, para que el include haga el trabajo del scripter por decirlo de alguna forma. Sin este metodo (u otros, ya que no es el unico), lo que deberia hacerse es colocar el callback/funcion dentro de cada codigo.

Para que se entienda mejor un ejemplo.
Supongamos el siguiente include:
pawn Код:
//INCLUDE:
public Health_OnPlayerSpawn(playerid)
{
    SetPlayerHealth(playerid, 100.0);
    return 1;
}
//mas codigo que no nos interesa
El scripter para hacer uso correcto del include, deberia hacer lo siguiente:

pawn Код:
#include <a_samp>
#include <health>//este es el include descripto arriba

public OnPlayerSpawn(playerid)
{
    CallLocalFunction("Health_OnPlayerSpawn", "i", playerid);
    //resto del codigo
    return 1;
}
Ahora bien, si el include 'health' utilizara ALS o algun otro metodo para hookear callbacks, el uso seria diferente.
pawn Код:
//INCLUDE:
new HEALTH_OPS;//En esta variable almacenaremos un valor indicando si se utiliza el callback OnPlayerConnect

#if defined FILTERSCRIPT
public OnFilterScriptInit()
{
    HEALTH_OPS = funcidx("TAG_OnPlayerSpawn");
    return 1;
}

#else

public OnGameModeInit()
{
    HEALTH_OPS = funcidx("TAG_OnPlayerSpawn");
    return 1;
}

public OnPlayerSpawn(playerid)
{
    SetPlayerHealth(playerid, 100.0);
    if(HEALTH_OPS != -1)
        return CallLocalFunction("HEALTH_OnPlayerSpawn", "i", playerid);
    return 1;
}
#if defined _ALS_OnPlayerSpawn
    #undef OnPlayerSpawn
#else
    #define _ALS_OnPlayerSpawn
#endif
#define OnPlayerConnect HEALTH_OnPlayerSpawn
forward public HEALTH_OnPlayerSpawn(playerid);
//mas codigo que no nos interesa
Ahora si el include fuera el anterior, bastaria con incluir el archivo sin necesidad de agregar nada al callback 'OnPlayerSpawn'.

pawn Код:
#include <a_samp>
#include <health>

public OnPlayerSpawn(playerid)
{
    //codigo
    return 1;
}
Nota: La forma correcta para hockear un callback, no es ninguna de las anteriormente mencionadas ya que ambas tienen errores.

pawn Код:
new TAG_OPC;//En esta variable almacenaremos un valor indicando si se utiliza el callback OnPlayerConnect

//Con el siguiente codigo lo que hacemos es optimizar el script para evitar chequear si se utiliza el callback o no cada vez q se llame a OnPlayerConnect (lo chequeamos solo 1 vez al inicio y listo).
#if defined FILTERSCRIPT
public OnFilterScriptInit()
{
    TAG_OPC = funcidx("TAG_OnPlayerConnect");
    return 1;
}

#else

public OnGameModeInit()
{
    TAG_OPC = funcidx("TAG_OnPlayerConnect");
    return 1;
}

#endif

//Este es el callback utilizado por nuestro include
public OnPlayerConnect(playerid)
{
    //Codigo del include.

    if(TAG_OPC != -1)
        return CallLocalFunction("TAG_OnPlayerConnect", "i", playerid);
    return 1;
}
#if defined _ALS_OnPlayerConnect
    #undef OnPlayerConnect
#else
    #define _ALS_OnPlayerConnect
#endif
#define OnPlayerConnect TAG_OnPlayerConnect
forward public TAG_OnPlayerConnect(playerid);
Muchas gracias por esta gran explicaciуn, aunque el metodo ALS que yo explique es valido, el ъnico error que cometi fue no retornar el CallLocalFunction pero este metodo hace la misma funciуn que la de usted, coo anteriormente usted mencinу "Existen varias formas de hacer ALS".

pawn Код:
public OnPlayerConnect(playerid)
{
  SendClientMessage(playerid, -1, "Prueba");
  return CallLocalFunction("F_OnPlayerConnect", "i", playerid); // Sirve para llamar la callback definidas por nosotros que en este caso es F_OnPlayerConnect.
}

#if defined _ALS_OnPlayerConnect // Esto sirve para verificar si _ALS_OnPlayerConnect esta definida.
  #undef  OnPlayerConnect // Usamos esto para poder redefinir OnPlayerConnect asi el compilador no lanzara error de redefiniciуn.
#else
#define _ALS_OnPlayerConnect // Definimos el ALS de OnPlayerConnect.
#endif

#define OnPlayerConnect F_OnPlayerConnect // Esto hace que al ejecutar OnPlayerConnect se ejecute la funciуn creada por nosotros que en este caso es OnPlayerConnect.

forward F_OnPlayerConnect(playerid);
Su metodo es tambiйn valido, yo prefiero este metodo porque ahorramos varias lineas de script.

PD: Este metodo lo aprendн de un tutorial de ******.

Un saludo.
Reply
#8

La forma correcta es retornar 1 si no existe nuestro callback ya que retornar directamente CallLocalFunction podria generar errores; esta es la unica razon por la cual comente ya que tu explicaste muy bien ALS.
Reply
#9

Ohhh. Muchisimas Gracias a Todos...

No pude contestar antes, pero me saque muchas dudas... Gracias a Todos...
Reply
#10

The Chaoz, me queda una duda, los funcidx se colocan en el incude o en el GM ?

EDIT: nada, ya entendi

RE-EDIT:
No. me queda la duda igual, si estoy hockeando el call OnGameModeInit y OnFilterScriptInit en el include, igual se coloca los funcidx hay mismo, o se colocan en el gm ?
Reply


Forum Jump:


Users browsing this thread: 4 Guest(s)