[Tutorial] If you plan on making an include with Pawn.RakNet
#1

• If you plan on making an include with Pawn.RakNet
Other Pawn.RakNet tutorials: RPC - Pawn.RakNet | Packets - Pawn.RakNet | Handlers - Pawn.RakNet

If you are reading this thread, let's assume you already know how to use Pawn.RakNet.

Let's say you are about to make an include using Pawn.RakNet, you might have to hook the callbacks OnIncomingPacket/RPC or OnOutcomingPacket/RPC, but, other includes hooking those callbacks that might use the same packet/RPC id, will cause problems when it comes about reading/writing data.

Not making use of ResetWritePointer or ResetReadPointer after reading/writing data in a packet/RPC's BitStream, will result in the next include making use of that same RPC/Packet in the hooked callback, in reading/writing data in the incorrect offsets of the BitStream.

Below, there is an example of two problematic includes using the same packet id.

PHP Code:
//Include 1
public OnIncomingPacket(playeridpacketidBitStream:bs)
{
    if (
packetid == 207)
    {
        new 
INC1_OnFootData[PR_OnFootSync];
        
BS_IgnoreBits(bs8);
        
BS_ReadOnFootSync(bsINC1_OnFootData);
        
INC1_OnFootData[PR_weaponId] = 38;
        
BS_SetWriteOffset(bs8);
        
BS_WriteOnFootSync(bsINC1_OnFootData);
    }
    
#if defined INC1_OnIncomingPacket
        
return INC1_OnIncomingPacket(playeridpacketidbs);
    
#else
        
return 1;
    
#endif
}
#if defined _ALS_OnIncomingPacket
#undef OnIncomingPacket
#else
#define _ALS_OnIncomingPacket
#endif
#define OnIncomingPacket INC1_OnIncomingPacket
#if defined INC1_OnIncomingPacket
forward INC1_OnIncomingPacket(playeridpacketidBitStream:bs);
#endif 
PHP Code:
//Include 2
public OnIncomingPacket(playeridpacketidBitStream:bs)
{
    if (
packetid == 207)
    {
        new 
INC2_OnFootData[PR_OnFootSync];
        
BS_IgnoreBits(bs8);
        
BS_ReadOnFootSync(bsINC2_OnFootData);
        
INC2_OnFootData[PR_specialAction] = 2;
        
BS_SetWriteOffset(bs8);
        
BS_WriteOnFootSync(bsINC2_OnFootData);
    }
    
#if defined INC2_OnIncomingPacket
        
return INC2_OnIncomingPacket(playeridpacketidbs);
    
#else
        
return 1;
    
#endif
}
#if defined _ALS_OnIncomingPacket
#undef OnIncomingPacket
#else
#define _ALS_OnIncomingPacket
#endif
#define OnIncomingPacket INC2_OnIncomingPacket
#if defined INC2_OnIncomingPacket
forward INC2_OnIncomingPacket(playeridpacketidBitStream:bs);
#endif 
The first include won't really have problems reading and writing data, now the second one will, because the write/read offsets were changed when the first include read/wrote data in the BitStream. The OnIncomingPacket/RPC & OnOutcomingPacket/RPC callbacks are called per RPC/Packet, this issue happens because you have two or more includes using the same Packet/RPC, so, when that callback be called because of that specific RPC or Packet, all your includes reading/writing data on that same Packet/RPC will have their code in use. Basically, it's like having more than one if condition for the same packet/RPC id.

So, after you are done reading/writing all your data in a packet/RPC's BitStream in one of those hooked callbacks in your include, it's recommended to use ResetWritePointer/ResetReadPointer, preventing issues with other includes that might use that same Packet/RPC's BitStream to read/write data.

Below, there is an example of two includes which will work just fine:

PHP Code:
//Include 1
public OnIncomingPacket(playeridpacketidBitStream:bs)
{
    if (
packetid == 207)
    {
        new 
INC1_OnFootData[PR_OnFootSync];
        
BS_IgnoreBits(bs8);
        
BS_ReadOnFootSync(bsINC1_OnFootData);
        
BS_ResetReadPointer(bs); //After we are done reading all our data, we can reset the read offsets.
        
INC1_OnFootData[PR_weaponId] = 38;
        
BS_SetWriteOffset(bs8);
        
BS_WriteOnFootSync(bsINC1_OnFootData);
        
BS_ResetWritePointer(bs); //After we are done writing all our data, we can reset the write offsets.
    
}
    
#if defined INC1_OnIncomingPacket
        
return INC1_OnIncomingPacket(playeridpacketidbs);
    
#else
        
return 1;
    
#endif
}
#if defined _ALS_OnIncomingPacket
#undef OnIncomingPacket
#else
#define _ALS_OnIncomingPacket
#endif
#define OnIncomingPacket INC1_OnIncomingPacket
#if defined INC1_OnIncomingPacket
forward INC1_OnIncomingPacket(playeridpacketidBitStream:bs);
#endif 
PHP Code:
//Include 2
public OnIncomingPacket(playeridpacketidBitStream:bs)
{
    if (
packetid == 207)
    {
        new 
INC2_OnFootData[PR_OnFootSync];
        
BS_IgnoreBits(bs8);
        
BS_ReadOnFootSync(bsINC2_OnFootData);
        
BS_ResetReadPointer(bs); //After we are done reading all our data, we can reset the read offsets.
  
        
INC2_OnFootData[PR_specialAction] = 2;
        
BS_SetWriteOffset(bs8);
        
BS_WriteOnFootSync(bsINC2_OnFootData);
        
BS_ResetWritePointer(bs); //After we are done writing all our data, we can reset the write offsets.
    
}
    
#if defined INC2_OnIncomingPacket
        
return INC2_OnIncomingPacket(playeridpacketidbs);
    
#else
        
return 1;
    
#endif
}
#if defined _ALS_OnIncomingPacket
#undef OnIncomingPacket
#else
#define _ALS_OnIncomingPacket
#endif
#define OnIncomingPacket INC2_OnIncomingPacket
#if defined INC2_OnIncomingPacket
forward INC2_OnIncomingPacket(playeridpacketidBitStream:bs);
#endif 
The two includes example above will work just fine, because the read/write offsets were reset after we were done reading/writing our data to the BitStream.

You don't have to reset the write and read offsets every time you read/write data to the BitStream, only do that after you are done reading/writing ALL the data.

This might be a small thread, but the information provided is actually important.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)