[Tutorial] Funзхes get (Pawn.RakNet)
#1

Funзхes get
(com o uso de Pawn.RakNet)
Bom, estou um certo tempo sem trazer contribuiзхes para a board, entгo, vim trazer um pouco do meu conhecimento sobre Pawn.RakNet, por aqui, jб existem diversos tуpicos sobre Pawn.RakNet construнdos pelo BrunoBM23 e pela Jelly23. Mas vou trazer um simples tуpico sobre como funcionam as funзхes Get com o uso de Pawn.RakNet, e mostrarei como fiz um conserto de uma funзгo nativa.

Vamos comeзar...

Para vocк entender o que eu irei fazer, й necessбrio vocк ler os tуpicos sobre RPCs, Pacotes e Leitura/escritura de Offsets.

Vou explicar tudo o que eu fiz na minha correзгo da funзгo nativa, a GetPlayerVehicleSeat.
"Qual o problema da funзгo nativa?"
A funзгo nativa nгo retorna exatamente os valores dos assentos, algumas vezes ela retorna com valores aleatуrios. Mas com a minha correзгo, a funзгo vai retornar exatamente aonde o jogador estб sentado, pois com a minha funзгo, os dados extraнdos diretamente do pacote em que й transmito via IncomingPackets.
Primeiro temos que criar uma definiзгo em prй-processamento para a nossa correзгo. (Lembrando, estou retratando tudo que fiz na correзгo, pois a correзгo й uma include)

Vamos comeзar verificando se existe alguma definiзгo com a nomenclatura que vamos fazer.:
PHP Code:
#if defined _GPVS_included
    #endinput
#endif
#define _GPVS_included 
Eu fiz uma simples condicional, caso jб esteja definida/inserida a include com a nomenclatura carregada como "_GPVS_included", nгo inserir ("#endinput").
Apуs a condicional, foi inserida a nomenclatura em prй-processamento da minha include. (Que й "_GPVS_included")

Agora, vamos fazer outra condicional, que й para verificar se a include do plugin RakNet estб inserida.
PHP Code:
#if !defined PAWNRAKNET_INC_
    #error Pawn.RakNet is necessary.
#endif 
O que foi feito acima, foi para retornar com uma mensagem de erro caso a include do Pawn.RakNet nгo esteja inserida/definida.

Agora, vamos criar uma definiзгo, para identificar o valor de um assento invбlido.
PHP Code:
#define     INVALID_SEAT_ID        (-1) 
Apуs, iremos criar uma variбvel estбtica com a matriz MAX_PLAYERS em char.
PHP Code:
static GPVS_PlayerSeat[MAX_PLAYERS char]; 
Agora, vamos para onde й o nosso "X" da questгo, que й aonde tudo vai acontecer.

Primeiro temos que procurar saber aonde que ocorre a passagem desses dados.
Logicamente, dados sobre o assento do jogador, sгo passados pelos pacotes ID_DRIVER_SYNC(ID: 200) e ID_PASSENGER_SYNC (ID: 211). Que os mesmos sгo responsбveis por questхes relacionados ao veнculo e ao passageiro.

Agora, para nуs iniciarmos, й necessбrio saber em qual tipo de pacote nуs vamos comeзar a usar a callback. No caso, se iremos usar Incoming ou Outgoing Packet.

Neste caso, nуs iremos utilizar o IncomingPacket, pois o valor de cada assento sгo dados criados pelo cliente e enviados ao servidor.

Entгo, iremos utilizar a callback OnIncomingPacket.
Sim, nуs usaremos Hook, nуs vamos utilizar o ALS Hook Method 7.

PHP Code:
public OnIncomingPacket(playeridpacketidBitStream:bs)
{
    
#if defined GPVS_OnIncomingPacket
        
return GPVS_OnIncomingPacket(playeridpacketidbs);
    
#else
        
return true;
    
#endif

Para comeзar, vamos fazer uma condicional sobre o assento do motorista, logo, o mesmo deverб ser setado para 0. Entгo, vamos setar a array estбtica que fizemos.
PHP Code:
public OnIncomingPacket(playeridpacketidBitStream:bs)
{
    if(
packetid == 200)
        
GPVS_PlayerSeat{playerid} = 0;
    
#if defined GPVS_OnIncomingPacket
        
return GPVS_OnIncomingPacket(playeridpacketidbs);
    
#else
        
return true;
    
#endif

Apуs nуs setarmos o valor da variбvel para 0, quando o jogador estiver no assento do motorista, a variбvel serб setada para 0, logo, a funзгo tambйm retornarб 0.

Agora, vamos tratar sobre o pacote responsбvel pelo passageiro do veнculo, que й aonde vamos comeзar os processos.
PHP Code:
public OnIncomingPacket(playeridpacketidBitStream:bs)
{
    if(
packetid == 200
        
GPVS_PlayerSeat{playerid} = 0;
    else if(
packetid == 211)
    {
        
BS_SetReadOffset(bs26);
        
BS_ReadValue\
        (\
            
bs,
            
PR_BITSGPVS_PlayerSeat{playerid}, 6
        
);
        
BS_ResetReadPointer(bs);
    }
    
#if defined GPVS_OnIncomingPacket
        
return GPVS_OnIncomingPacket(playeridpacketidbs);
    
#else
        
return true;
    
#endif

Agora, vamos entender o que foi feito na condicional sobre o pacote dos passageiros.
No caso abaixo:
PHP Code:
BS_SetReadOffset(bs26); 
Й necessбrio entender que:
Code:
stock BS_ReadPassengerSync(BitStream:bs, data[PR_PassengerSync])
{
    BS_ReadValue\
    (\
        bs,
        PR_UINT16, data[PR_vehicleId],
        PR_BITS, data[PR_driveBy], 2,
        PR_BITS, data[PR_seatId], 6,
        PR_BITS, data[PR_additionalKey], 2,
        PR_BITS, data[PR_weaponId], 6,
        PR_UINT8, data[PR_playerHealth],
        PR_UINT8, data[PR_playerArmour],
        PR_UINT16, data[PR_lrKey],
        PR_UINT16, data[PR_udKey],
        PR_UINT16, data[PR_keys],
        PR_FLOAT, data[PR_position][0],
        PR_FLOAT, data[PR_position][1],
        PR_FLOAT, data[PR_position][2]
    );
}
A linhagem acima, estб o que percorre todo o pacote, e o que consegue ser lido pelo mesmo.

Nуs queremos interceptar o assento do jogador, que no caso, й o seatId, й uma variбvel com o tipo de dados em BITS, que possui 6 bits.
Agora, que nуs iremos aplicar o que foi dado no tуpico do BrunoBM23 sobre escritura/leitura das offsets.

O parвmetro que queremos chegar, й o terceiro, logo, nуs devemos obrigatoriamente inserir os primeiros 8bits do bitStream junto а soma.
O que й pra se fazer й apenas somar os valores.

Code:
Primeiros oito bits = 8
PR_UINT16 = 16
PR_BITS = 2 (O valor de PR_BITS й variado com o valor dado ao lado, apуs passar a variбvel, mas nesse caso, й 2)

8 + 16 + 2 = 26
Nota: Nгo insira o valor do parвmetro que vocк quer chegar, sempre insira um antes dele mesmo, como foi feito acima.:
Eu quero chegar no seatId, entгo eu tenho que somar atй o driveBy. E nгo atй o seatId.
Apуs entendermos o que foi feito na contagem e inserзгo da quantidade bits a serem lidos, vamos ler os valores. (Que foi o caso abaixo)
PHP Code:
BS_ReadValue\
(\
    
bs,
    
PR_BITSGPVS_PlayerSeat{playerid}, 6
); 
O valor foi lido e consequentemente, devemos colocar a nossa variбvel estбtica como referкncia para que os valores sejam lidos, ou seja, eles estгo passando os valores que foram lidos para a nossa variбvel estбtica.

Claro, quando finalizarmos, vamos fechar/deletar todos os pontos de leitura de qualquer bitStream, para nгo entrar em conflito com nenhum outro que jб esteja com a soma inserida.(Como foi feito no caso abaixo)
PHP Code:
BS_ResetReadPointer(bs); 
Finalizado a parte mais "complexa". Agora, vamos desenvolver a correзгo da funзгo.
PHP Code:
stock GetPlayerVehicleSeat(playerid)
{
    if(!
IsPlayerConnected(playerid) || !IsPlayerInAnyVehicle(playerid))
        return 
INVALID_SEAT_ID;
    else 
        return 
GPVS_PlayerSeat{playerid};

Criamos a nomenclatura da funзгo, logo apуs, foi feita a condicional, se o jogador nгo estiver conectado ou se ele nгo estiver em nenhum veнculo, obviamente, irб retornar o valor invбlido de assento(-1), que foi definido no topo da include. Caso contrбrio, irб retornar o valor que estб dentro da nossa variбvel estбtica.

Pronto, quase tudo estб pronto, agora, sу falta finalizar a ъltima parte do Hook.:

PHP Code:
/*----------------------------------------------*/
#if defined _ALS_OnIncomingPacket
    #undef OnIncomingPacket
#else
    #define _ALS_OnIncomingPacket
#endif
#define OnIncomingPacket GPVS_OnIncomingPacket
#if defined GPVS_OnIncomingPacket
    
forward GPVS_OnIncomingPacket(playeridpacketidBitStream:bs);
#endif
/*----------------------------------------------*/
#if defined _ALS_GetPlayerVehicleSeat
    #undef GetPlayerVehicleSeat
#else
    #define _ALS_GetPlayerVehicleSeat
#endif
#define GetPlayerVehicleSeat GPVS_GetPlayerVehicleSeat 
Finalizando, toda a include ficou da seguinte forma:
PHP Code:
#if defined _GPVS_included
    #endinput
#endif
#define _GPVS_included
#if !defined PAWNRAKNET_INC_
    #error Pawn.RakNet is necessary.
#endif
#define     INVALID_SEAT_ID     (-1)
/* Variable */
static GPVS_PlayerSeat[MAX_PLAYERS char];
/* Function */
stock GetPlayerVehicleSeat(playerid)
{
    if(!
IsPlayerConnected(playerid) || !IsPlayerInAnyVehicle(playerid))
        return 
INVALID_SEAT_ID;
    else 
        return 
GPVS_PlayerSeat{playerid};
}
/* Callback */
public OnIncomingPacket(playeridpacketidBitStream:bs)
{
    if(
packetid == 0xC8
        
GPVS_PlayerSeat{playerid} = 0;
    else if(
packetid == 0xD3)
    {
        
BS_SetReadOffset(bs26);
        
BS_ReadValue\
        (\
            
bs,
            
PR_BITSGPVS_PlayerSeat{playerid}, 6
        
);
        
BS_ResetReadPointer(bs);
    }
    
#if defined GPVS_OnIncomingPacket
        
return GPVS_OnIncomingPacket(playeridpacketidbs);
    
#else
        
return true;
    
#endif
}
/* Hook */
/*----------------------------------------------*/
#if defined _ALS_OnIncomingPacket
    #undef OnIncomingPacket
#else
    #define _ALS_OnIncomingPacket
#endif
#define OnIncomingPacket GPVS_OnIncomingPacket
#if defined GPVS_OnIncomingPacket
    
forward GPVS_OnIncomingPacket(playeridpacketidBitStream:bs);
#endif
/*----------------------------------------------*/
#if defined _ALS_GetPlayerVehicleSeat
    #undef GetPlayerVehicleSeat
#else
    #define _ALS_GetPlayerVehicleSeat
#endif
#define GetPlayerVehicleSeat GPVS_GetPlayerVehicleSeat 
Obrigado, nгo й algo tгo longo, mas que acredito que possa contribuir e ajudar em algo para os demais da board.
+Informations:

Outro exemplo, й esta reproduзгo da funзгo GetPlayerWeapon.:
PHP Code:
static GPW_RakNet[MAX_PLAYERS char];
stock GetPlayerWeapon(playerid)
{
    if(
playerid || playerid MAX_PLAYERS)
        return 
false;
    return 
GPW_RakNet{playerid};
}
public 
OnIncomingPacket(playeridpacketidBitStream:bs)
{
    if(
packetid == 207)
    {
        
BS_SetReadOffset(bs234);
        
BS_ReadValue\
        (\
            
bs,
            
PR_BITSGPW_RakNet{playerid}, 6
        
);
        
BS_ResetReadPointer(bs);
    }
    
#if defined GPW_RakNet_OnIncomingPacket
        
return GPW_RakNet_OnIncomingPacket(playeridpacketidBitStream:bs);
    
#else
        
return true;
    
#endif
}
#if defined _ALS_OnIncomingPacket
    #undef OnIncomingPacket
#else
    #define _ALS_OnIncomingPacket
#endif
#define OnIncomingPacket _ALS_OnIncomingPacket
#if defined GPW_RakNet_OnIncomingPacket
    
forward GPW_RakNet_OnIncomingPacket(playeridpacketidBitStream:bs);
#endif
// --------------------
#if defined _ALS_GetPlayerWeapon
    #undef GetPlayerWeapon
#else
    #define _ALS_GetPlayerWeapon
#endif
#define GetPlayerWeapon GPW_GetPlayerWeapon 
Reply
#2

Parabйns pelo tutorial.
Ensinou de uma matйria didбtica e tudo bem 'mastigadinho'.
Reply
#3

Muito bom
Reply
#4

Parabens Bem Util +rep

Mapas fale comigo

__________________________________________________ ______




Reply
#5

Bem explicado!
Reply
#6

Bom tutorial, bem util
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)