SSGamers - 13 Anos online por você.

#SSGamers - A Comunidade que mais crescer no brasil!

Participe do fórum, é rápido e fácil

SSGamers - 13 Anos online por você.

#SSGamers - A Comunidade que mais crescer no brasil!

SSGamers - 13 Anos online por você.

Gostaria de reagir a esta mensagem? Crie uma conta em poucos cliques ou inicie sessão para continuar.
Chegou o novo tema 6.5.5 - SSGamers - Servidores online de qualidade - Aproveite e entre para nossa comunidade, inscreva-se já! - Ouça nossa web radio - Veja nossas novidades - Participe dos nossos setores de jogos online - Parcerias aberta fale já com um administrador.

    [Tutorial] Funções get (Pawn.RakNet)

    Weslley_Script
    Weslley_Script
    SS - Fundador
    SS - Fundador


    Steam Steam : WeslleySSGames
    Zello : WeslleySSGames
    Mensagens : 11638
    Moedas : 1032933
    Data de inscrição : 06/10/2011
    Idade : 29
    Localização : Brasil

    [Tutorial] Funções get (Pawn.RakNet) Empty [Tutorial] Funções get (Pawn.RakNet)

    Mensagem por Weslley_Script Qui 16 Mar 2023 - 7:18

    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 RPCsPacotes 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.:


    Código:
    #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.


    Código:
    #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.


    Código:
    #define     INVALID_SEAT_ID        (-1) 

    Apуs, iremos criar uma variбvel estбtica com a matriz MAX_PLAYERS em char.


    Código:
    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.



    Código:
    public OnIncomingPacket(playerid, packetid, BitStream:bs)
    {
        #if defined GPVS_OnIncomingPacket
            return GPVS_OnIncomingPacket(playerid, packetid, bs);
        #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.


    Código:
    public OnIncomingPacket(playerid, packetid, BitStream:bs)
    {
        if(packetid == 200)
            GPVS_PlayerSeat{playerid} = 0;
        #if defined GPVS_OnIncomingPacket
            return GPVS_OnIncomingPacket(playerid, packetid, bs);
        #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.


    Código:
    public OnIncomingPacket(playerid, packetid, BitStream:bs)
    {
        if(packetid == 200) 
            GPVS_PlayerSeat{playerid} = 0;
        else if(packetid == 211)
        {
            BS_SetReadOffset(bs, 26);
            BS_ReadValue\
            (\
                bs,
                PR_BITS, GPVS_PlayerSeat{playerid}, 6
            );
            BS_ResetReadPointer(bs);
        }
        #if defined GPVS_OnIncomingPacket
            return GPVS_OnIncomingPacket(playerid, packetid, bs);
        #else
            return true;
        #endif


    Agora, vamos entender o que foi feito na condicional sobre o pacote dos passageiros.
    No caso abaixo:

    Código:
    BS_SetReadOffset(bs, 26); 

    Й necessбrio entender que:
    Code:

    Código:
    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:

    Código:
    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)


    Código:
    BS_ReadValue\
    (\
        bs,
        PR_BITS, GPVS_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)


    Código:
    BS_ResetReadPointer(bs); 

    Finalizado a parte mais "complexa". Agora, vamos desenvolver a correзгo da funзгo.


    Código:
    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.:



    Código:
    /*----------------------------------------------*/
    #if defined _ALS_OnIncomingPacket
        #undef OnIncomingPacket
    #else
        #define _ALS_OnIncomingPacket
    #endif
    #define OnIncomingPacket GPVS_OnIncomingPacket
    #if defined GPVS_OnIncomingPacket
        forward GPVS_OnIncomingPacket(playerid, packetid, BitStream: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:


    Código:
    #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(playerid, packetid, BitStream:bs)
    {
        if(packetid == 0xC8) 
            GPVS_PlayerSeat{playerid} = 0;
        else if(packetid == 0xD3)
        {
            BS_SetReadOffset(bs, 26);
            BS_ReadValue\
            (\
                bs,
                PR_BITS, GPVS_PlayerSeat{playerid}, 6
            );
            BS_ResetReadPointer(bs);
        }
        #if defined GPVS_OnIncomingPacket
            return GPVS_OnIncomingPacket(playerid, packetid, bs);
        #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(playerid, packetid, BitStream: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.:

    Código:
    static GPW_RakNet[MAX_PLAYERS char];
    stock GetPlayerWeapon(playerid)
    {
        if(playerid < 0 || playerid > MAX_PLAYERS)
            return false;
        return GPW_RakNet{playerid};
    }
    public OnIncomingPacket(playerid, packetid, BitStream:bs)
    {
        if(packetid == 207)
        {
            BS_SetReadOffset(bs, 234);
            BS_ReadValue\
            (\
                bs,
                PR_BITS, GPW_RakNet{playerid}, 6
            );
            BS_ResetReadPointer(bs);
        }
        #if defined GPW_RakNet_OnIncomingPacket
            return GPW_RakNet_OnIncomingPacket(playerid, packetid, BitStream: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(playerid, packetid, BitStream:bs);
    #endif
    // --------------------
    #if defined _ALS_GetPlayerWeapon
        #undef GetPlayerWeapon
    #else
        #define _ALS_GetPlayerWeapon
    #endif
    #define GetPlayerWeapon GPW_GetPlayerWeapon 

    Creditos: Jelly23



    [Tutorial] Funções get (Pawn.RakNet) D07Xwqb
    [Tutorial] Funções get (Pawn.RakNet) Yjab9HN

      Data/hora atual: Sáb 23 Nov 2024 - 2:43