• Includes com Pawn.RakNet
Se vocк estб lendo esse tуpico, vamos assumir que vocк jб sabe utilizar o Pawn.RakNet.
Quando vocк for criar uma include utilizando Pawn.RakNet, talvez vocк precise fazer um hook com as callbacks OnIncomingPacket/RPC ou OnOutcomingPacket/RPC, mas, outras includes com essas callbacks "hookadas" que utilizem o mesmo id de pacote/RPC, podem causar problemas.
Nгo utilizar ResetWritePointer ou ResetReadPointer apуs ler ou escrever dados em um pacote/RPC, resultarб na prуxima include ao utilizar o mesmo pacote/RPC em ler/escrever dados nas offsets invбlidas no BitStream do pacote/RPC.
Abaixo temos dois exemplos de includes problemбticas que utilizam o mesmo pacote:
- Código:
//Include 1
public OnIncomingPacket(playerid, packetid, BitStream:bs)
{
if (packetid == 207)
{
new INC1_OnFootData[PR_OnFootSync];
BS_IgnoreBits(bs, 8);
BS_ReadOnFootSync(bs, INC1_OnFootData);
INC1_OnFootData[PR_weaponId] = 38;
BS_SetWriteOffset(bs, 8);
BS_WriteOnFootSync(bs, INC1_OnFootData);
}
#if defined INC1_OnIncomingPacket
return INC1_OnIncomingPacket(playerid, packetid, bs);
#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(playerid, packetid, BitStream:bs);
#endif
A primeira include nгo terб problemas lendo e escrevendo dados, jб a segunda sim, pois as offsets de escrita e leitura foram alteradas pela primeira. As callbacks OnIncomingPacket/RPC e OnOutcomingPacket/RPC sгo chamadas por RPC/pacote, este problema ocorre por que vocк tem duas ou mais includes usando o mesmo RPC/pacote, entгo, quando a callback for chamada para este especнfico RPC ou pacote, todas as suas includes lendo/escrevendo dados neste mesmo RPC/Pacote vгo ter seu cуdigo em uso. Basicamente, seria como ter vбrias condicionais para o mesmo RPC/pacote.
- Código:
//Include 2
public OnIncomingPacket(playerid, packetid, BitStream:bs)
{
if (packetid == 207)
{
new INC2_OnFootData[PR_OnFootSync];
BS_IgnoreBits(bs, 8);
BS_ReadOnFootSync(bs, INC2_OnFootData);
INC2_OnFootData[PR_specialAction] = 2;
BS_SetWriteOffset(bs, 8);
BS_WriteOnFootSync(bs, INC2_OnFootData);
}
#if defined INC2_OnIncomingPacket
return INC2_OnIncomingPacket(playerid, packetid, bs);
#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(playerid, packetid, BitStream:bs);
#endif
Entгo, toda vez que vocк escrever/ler algum dado de qualquer pacote/RPC nas callbacks "hookadas", й recomendado vocк utilizar ResetWritePointer/ResetReadPointer, assim evitando problemas com outras includes que utilizam o mesmo pacote ou RPC para ler/escrever dados.
Abaixo temos dois exemplos de includes na maneira correta:
- Código:
//Include 1
public OnIncomingPacket(playerid, packetid, BitStream:bs)
{
if (packetid == 207)
{
new INC1_OnFootData[PR_OnFootSync];
BS_IgnoreBits(bs, 8);
BS_ReadOnFootSync(bs, INC1_OnFootData);
BS_ResetReadPointer(bs); //Apуs ler os dados acima, "resetamos" as offsets de leitura.
INC1_OnFootData[PR_weaponId] = 38;
BS_SetWriteOffset(bs, 8);
BS_WriteOnFootSync(bs, INC1_OnFootData);
BS_ResetWritePointer(bs); //Apуs escrever os dados acima, "resetamos" as offsets de escrita.
}
#if defined INC1_OnIncomingPacket
return INC1_OnIncomingPacket(playerid, packetid, bs);
#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(playerid, packetid, BitStream:bs);
#endifOs dois exemplos acima funcionaram sem nenhum problema, pois as offsets de escrita/leitura vгo ser "resetadas" apуs o uso.
- Código:
//Include 2
public OnIncomingPacket(playerid, packetid, BitStream:bs)
{
if (packetid == 207)
{
new INC2_OnFootData[PR_OnFootSync];
BS_IgnoreBits(bs, 8);
BS_ReadOnFootSync(bs, INC2_OnFootData);
BS_ResetReadPointer(bs); //Apуs ler os dados acima, "resetamos" as offsets de leitura.
INC2_OnFootData[PR_specialAction] = 2;
BS_SetWriteOffset(bs, 8);
BS_WriteOnFootSync(bs, INC2_OnFootData);
BS_ResetWritePointer(bs); //Apуs escrever os dados acima, "resetamos" as offsets de escrita.
}
#if defined INC2_OnIncomingPacket
return INC2_OnIncomingPacket(playerid, packetid, bs);
#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(playerid, packetid, BitStream:bs);
#endif
Vocк nгo precisa "resetar" as offsets de escrita e leitura toda vez que ler/escrever dados, faзa isso apenas ao terminar de ler/escrever todos os dados.
Este pode atй ser um tуpico pequeno, mas a informaзгo providenciada й importante.
Creditos: Jelly23