[GUIA] Native: register_event
#1
Dedo abajo 
Ya que alardean con el tema de los aportes, les traigo una mini guia que hice en un post, de como se emplea bien la native register_event, de amxmodx.inc, nativa del Core.

register_event registra "Message IDs", "Message Indexes", "msgids", "msgid" (como le quieran llamar) del juego, eventos varios que el servidor envia a los clientes (en forma de paquetes [estos mismos son los que en exceso causan el error Reliable Channel Overflow {solo si se envian en un canal "reliable"}]), register_message hace la misma tarea pero tiene distintos fines.

Código PHP:
native register_event(const event[],const function[],const flags[],const cond[]="", ... ); 

const event[] es el nombre del evento o msgid, pero en su nombre, no en su ID, en el CS existen una serie de eventos, puedes ubicarlos aqui: http://wiki.alliedmods.net/Half-Life_1_Game_Events

const function[] es el nombre de la funcion donde quieres que se llame (funcion callback [asi como set_task, para los que no captaron]) para cuando se realize el evento especifico. El evento tendra un parametro (id) en caso de que el mensaje se le haya enviado a 1 solo player, eso uno lo define en el parametro flags[]

const flags[] aqui ya es especifico:

Cita:* "a" - evento global, se puede deducir cuando es de tipo MSG_ALL, MSG_BROADCAST, y los otros relacionados con predicciones de vision o audicion.
* "b" - evento especifico, cuando se le envia a 1 solo player en 1 ocasion, tipo cuando gastas dinero, el mensaje Money se le envia a 1 solo jugador (el que gasto).
* "c" - evento especifico en cantidad, cuando se le envia un mismo mensaje a varios jugadores pero no es global, ej: cuando hay jugadores que estan specteando un jugador con Nightvision, y este se muere, a todos los Specs que estaban viendo ese player se envia el msg NVGToggle con el primer argumento en 0, lo que hara desactivar el nvg a los specs.
* "d" - evento especifico, para cuando solo el jugador este muerto
* "e" - evento especifico, para cuando solo el jugador este vivo

const cond[]="", ... estas son las condiciones que quieres que se apliquen para que la funcion se llame, esto depende del evento. Las condiciones van en strings, y se usan operadores logicos similares a los de pawn. Entre ellos

Cita:Usado para valores discretos:
>
<
= // 'arg X' igual a
! // 'arg X' distinto a
Especificas para textos:
= // 'arg X' igual a
& // 'arg X' contiene
! // 'arg X' no contiene

A partir del parametro cond[] puedes agregar los que sean (sin exceder el limite de 32 [enfermo sería el que añade más de 32 condiciones]) y un ejemplo sencillo y random sería

Código PHP:
register_event(..., "...""...""1=2""2&Caca""3>0")
// argumento 1 debe ser igual a 2
// argumento 2 debe contener Caca (sabiendo que es un string ese arg)
// argumento 3 debe ser mayor a 0 

Les doy un ejemplo:

"Train" es el evento que muestra el HUD de al medio donde uno ve la velocidad en la que va donde un auto. Las barritas se definen segun el primer argumento del evento (puedes verlos aqui), entonces, si yo quiero hookear cuando el jugador este en la maxima velocidad en un vehiculo (func_vehicle), solo hago:

Código PHP:
public plugin_init()
{
     
register_event("Train""Event_Train""b""1=4")
}
public 
Event_Train(iId// va un index porque el evento esta hookeado para cuando se le llama a 1 solo player
{
     
client_print(iIdprint_chat"Estas en la maxima velocidad con tu vehiculo")

"b" porque quiero hookear cuando se le envia a un solo jugador (o lo deduces, o revisas el SDK). El primer argumento puede ser: 0 (hacerlo desaparecer), 1 (neutro), 2 (velocidad baja), 3 (velocidad media), 4 (velocidad maxima), 5 (reversa)

En el caso del famoso evento HLTV que muchas veces lo vemos hookeado, es un evento especifico enviado a los clientes proxy, Teles, o HLTV. Este evento se envia variadas veces, entre esas, 2 veces en CHalfLifeMultiplay::RestartRound que es donde la ronda empieza, y en estos 2 envios que realiza el Servidor, envia argumentos distintos.

(de una version semidecompilada del CS: )

Cita: // ...
// contenido de la funcion CHalfLifeMultiplay::RestartRound
// ...
g_engfuncs.pfnMessageBegin(9 /* MSG_SPEC */, gmsgHLTV, 0, 0);
g_engfuncs.pfnWriteByte(0);
g_engfuncs.pfnWriteByte(228);

g_engfuncs.pfnMessageEnd();
g_engfuncs.pfnMessageBegin(9 /* MSG_SPEC */, gmsgHLTV, 0, 0);
g_engfuncs.pfnWriteByte(0);
g_engfuncs.pfnWriteByte(0);

g_engfuncs.pfnMessageEnd();


Entonces, para que sea facil deducir, se hookea el evento para cuando el primer argumento sea 0, y el segundo argumento sea 0.
Código PHP:
register_event
(
     
"HLTV"
     
"event_round_start"
     
"a"
     
"1=0"
     
"2=0"

Como te lo dije ahora, a la manera que se puede hacer asi, tambien puedes hacer esto:

Código PHP:
register_event
(
     
"HLTV"
     
"event_round_start"
     
"a"
     
"1=0"
     
"2=228"

O no?

Si le quitas esa deteccion de argumentos, la forward se llamaria 2 veces en inicio de ronda y en otras ocasiones donde tambien se envia el evento HLTV. Es por eso que se hace este tipo de deteccion.

Dudas pregunten, es algo especifico de AMXX, no debe ser muy dificil de entender
Responder
#2
Muy bueno, muy bueno! Algunas/bastantes dudas aclaradas, lo que no entendí del todo es "se hookea el evento para cuando el primer argumento sea 0, y el segundo argumento sea 0.
Believe, be yourself and don't hold on to just one dream ❤

Responder
#3
Lee ésta parte del tema:

Código PHP:
g_engfuncs.pfnMessageBegin(/*
MSG_SPEC */
gmsgHLTV00);
g_engfuncs.pfnWriteByte(0);
g_engfuncs.pfnWriteByte(228);
g_engfuncs.pfnMessageEnd();
g_engfuncs.pfnMessageBegin(/*
MSG_SPEC */
gmsgHLTV00);
g_engfuncs.pfnWriteByte(0);
g_engfuncs.pfnWriteByte(0);
g_engfuncs.pfnMessageEnd(); 

Ni te molestes en enviarme un mensaje privado para pedirme ayuda porque NO lo voy a contestar.
Gracias por su atención.
Responder
#4
Muy bueno Che.
Te ganaste un +1
NUEVO ZOMBIE PLAGUE + LVLS!! UNETE A LA COMUNIDAD
[Imagen: b_350_20_ffad41_e98100_000000_591f11.png]


Responder
#5
(06/09/2014, 02:42 AM)Federicomb escribió: Muy bueno, muy bueno! Algunas/bastantes dudas aclaradas, lo que no entendí del todo es "se hookea el evento para cuando el primer argumento sea 0, y el segundo argumento sea 0.

Que solo se llamara a la funcion cuando el argumento 1 y 2 valgan 0, ejemplo, esto seria lo mismo si no me equivoco
Código PHP:
register_event
(
     
"HLTV"
     
"event_round_start"
     
"a"

public 
event_round_start() {
if(
read_data(1) == && read_data(2) == 0) {
// code 
Para ahorrarte eso cuando registras el evento lo defines
Código PHP:
register_event
(
     
"HLTV"
     
"event_round_start"
     
"a",
     
"1=0",
     
"2=0"

No estoy muy seguro pero creo que a eso se refiere
Todos los MODS VHL totalmente gratuitos  Descarga Aqui

Mis plugins:
STEAM: https://steamcommunity.com/id/Metrikcz/
FB: fb.com/rwoong
Venta plugins a pedido en México mándame MP
Responder
#6
El callback tendra solo 1 argumento y solo sera si el registro contiene el flag b, esta escrito en el tema. Si quieres obtener un argumento del message en el callback, usa read_data()
Responder
#7
Entendido hay edito.
Todos los MODS VHL totalmente gratuitos  Descarga Aqui

Mis plugins:
STEAM: https://steamcommunity.com/id/Metrikcz/
FB: fb.com/rwoong
Venta plugins a pedido en México mándame MP
Responder
#8
Muy buen Aporte Excitedeyes yo no entendia bn el register_event
Te ganastes +1 Rainbow
[Imagen: b_350_20_323957_202743_f19a15_111111.png]

Estudia siempre; el tiempo es oro, lo material se puede recuperar pero el tiempo no se puede recuperar.
(02/10/2016, 05:05 PM)meTaLiCroSS escribió: Siempre me gusta ayudar cuando alguien esta interesado realmente en ver que esta programando.
(08/08/2019, 05:32 PM)meTaLiCroSS escribió: grax x el dato cr4ck


Mis aportes

PLUGINS
MAPAS
Menú LANG [SF] Sistema de Frags
Say System (Admin Prefix)
Responder
#9
algo de esto estuve buscando hace tiempo y no encontré absolutamente.

había algunos register_event que no sabía porque los ponían así.

Gracias por compartir
(17/04/2015, 03:36 PM)Neeeeeeeeeel.- escribió: No se va a volver a conectar a internet en toda su puta vida... nadie sube porno a mi foro y vive para contarlo.
Responder
#10
Esta bueno pero tengo una duda, cuando decis solo si se envian en un canal "reliable" a que te referis? me darias un ejempo..
Responder
#11
(15/01/2015, 08:35 AM)wicho escribió: Esta bueno pero tengo una duda, cuando decis solo si se envian en un canal "reliable" a que te referis? me darias un ejempo..

Reliable = Seguro

Si un mensaje se envia por un canal reliable, te asegura 100% que el mensaje le llegará al cliente (ej. un mensaje importante en la jugabilidad, tipo el screenfade de un flashbang), pero si por razones de enlace este no pudo llegar, se kickea (Reliable Channel Overflowed)

Si un mensaje se envia por un canal unreliable, no te asegura 100% que llegara el mensaje al cliente, pero de ser asi, no hará nada al respecto con la perdida. Solo lo enviará. Esto es más guiado para efectos.
Responder
#12
tengo una pregunta la native client_print usa canal reliable?
Responder
#13
La native client_print llama a la funcion UTIL_ClientPrint
UTIL_ClientPrint hace un llamado dependiendo del receptor, a un mensaje MSG_ONE o MSG_BROADCAST, es decir, que cuando es enviado a 1 es reliable, pero cuando es enviado a todos (parametro 1 en 0) es enviado de manera unreliable.
Responder
#14
Interesante gracias, donde puedo ver como esta echo una native o una forward de amx?
Responder
#15
(25/08/2015, 02:03 PM)wicho escribió: Interesante gracias, donde puedo ver como esta echo una native o una forward de amx?

https://github.com/alliedmodders/amxmodx

El source del AMXX como plugin de Metamod, programado en C++
Responder
#16
No podrias hacer un tutorial de register_message? vos decis q tiene la misma tarea pero diferentes fines, me gustaria saber esos fines y buen tutorial muy util..
Responder


Salto de foro:


Usuarios navegando en este tema: 1 invitado(s)