katursis / Pawn.RakNet

🛡 Plugin for SA:MP 0.3.7 server that allows you to capture and analyze RakNet traffic
https://github.com/katursis/Pawn.RakNet/wiki
MIT License
161 stars 28 forks source link

Few questions #3

Closed IstuntmanI closed 7 years ago

IstuntmanI commented 7 years ago
  1. Why you aren't releasing this on SA:MP forums ? I know that this is a memory hacking plugin, but it is a really useful one, as it can provide access to few unaccesible things from SA:MP, such as player Aim Z, surfing offsets, etc. (I patched invalid values of them by using this plugin). Also, as you said, this plugin is compatible with many SA:MP versions (probably even future ones), as it uses addresses patterns.

  2. About OnPlayerReceivedPacket/RPC. I noticed that these are actually calling when a player is sending a packet/RPC to the server. So if I use a hack for an invalid Aim Z, I have to catch it in OnPlayerReceivedPacket for packet_id ID_PLAYER_SYNC and eventually kick that player. It can be confusing. Wouldn't a name like OnPlayerSendPacket/RPCToServer be better ? I am wrong ? I am not exactly sure about this.

  3. So OnServerSendPacket/RPC is called when a packet/RPC received by the server from OnPlayerReceivedPacket/RPC is sent to a player who needs to receive it. My question is: how can I actually get the playerid this packet is coming from ? Well, I know that this question isn't exactly your business, but it is pretty hard to find things about RakNet.

  4. If a player loses connection to the server (timeout), the server is still sending data to this player, also calling OnServerSendPacket/RPC ? I guess it does, but it would be cool if it didn't (althought I don't think it is really possible), we could track crashes better. (see http://forum.sa-mp.com/showpost.php?p=3819205&postcount=37)

Anyway, great work on this !

ghost commented 7 years ago

"Why you aren't releasing this on SA:MP forums ?"

It was and it has been removed, I remember clearly for that.

spmn commented 7 years ago
  1. Returning 0 in callback would drop the packet, so kick is not necessary. (or even better, you can overwrite the invalid value with a valid one)

  2. I think you didn't understand quite well how those callbacks work. OnServerSendPacket/RPC is called right before server sends a packet or RPC to client(s). OnPlayerReceivedPacket/RPC is called right before server processes a packet or RPC received from a client.

    How can I actually get the playerid this packet is coming from ? Packets and RPCs are not sent from client to client. Here is a brief explanation of how communication works:

    • client sends a packet to the server;
    • server receives it;
    • server validates some data and then updates its internal structures acording to the packet received; And after a while, when current tick = update tick, server broadcasts data read from memory to clients. This broadcasted packet might or might not contain invalid data.
  3. You could check when the last update was received from that player. If time difference between last update and current time is greater than 2000ms, then the player is either experiencing heavy lag, either he crashed.

IstuntmanI commented 7 years ago
  1. @kurta999 I don't see any reason why they would remove something like this. It is only allowing us to handle all packets/RPCs.

  2. @spmn Well, that wasn't what I asked, but you explained me this at the point 3. Anyway, I didn't know that returning 0 in those "Received" callbacks would drop the packet/RPC, thanks. I saw it now.

  3. So:

    • a client sends a packet/RPC to the server;
    • the server receives it and calls OnPlayerReceivedPacket/RPC with sender's player_id;
    • server is sending that BitStream to other clients and it calls OnServerSendPacket/RPC, but callback's player_id parameter will have the value of receiver's player ID, right ? I don't think you understood my question exactly or I didn't understand mostly of what you said (well, I think I did). So, in OnServerSendPacket/RPC player_id will have the value of the RECEIVER, but how I can also get the player_id of the SENDER (the guy that initially sent the packet/RPC to server) ? I think that it is possible, as the receiver client knows to which character to apply that BitStream received from the server (this is what I can't understand about this, the receiver client knows from the server what character/player sent him that information, and the receiver client will apply that information to the sender character/player). Is the sender_id actually placed somewhere in every packet/RPC, so we need to know the structure of each packet/RPC to get the initial sender in OnServerSendPacket/RPC ? This is needed to track those received packets/RPC by clients, from point 4.
  4. This idea is pretty fine I guess, unless there are lots of packets/RPCs sent/received, which I think they are.

About that naming, I think that something like OnServerReceivedPacket/RPC( sender_id, ... ) instead of OnPlayerReceivedPacket would be better now that I think I understood mostly of what spmn explained. Also, OnServerSendPacket/RPC should also contain the sender_id, if possible, see the questions above, at point 3.

This thing needs some proper documentation, it can be really useful if more things would be explained.

spmn commented 7 years ago

@IstuntmanI

  1. It also works at send callbacks.
  2. Almost all SA-MP server->client update packets have the following structure: 1BYTE=packetid + 1WORD=playerid to apply the data to(most likely the initial sender of the packet) + x BYTES=update itself So, the _'senderid' has to be read from bitstream.

Indeed, the callback naming is a bit confusing.

OnServerSendPacket/RPC can't have a sender_id, because the sender, as the callback name implies, is ALWAYS the server. However, some sent packets (update ones) contain data received from other clients.

About documentation, I think it is not the case here. This plugin just enables scripters access to a few raknet functions, and these functions are documented very well on raknet website. For more information about the actual packet structure, you can take a look at RakSAMP, sobeit, YSF, SKY, SA-MP 0.2.5/x leak and VC-MP 0.1. (all these projects got their code available on the internet)

IstuntmanI commented 7 years ago

Aw, so it is like I thought: the sender_id is in bitstream (well, when the case needs it).

OnServerSendPacket/RPC can't have a sender_id, because the sender, as the callback name implies, is ALWAYS the server.

I know, I understood that, sender_id should be the initial packet/RPC sender, which sent it to the server. So the callback can't have that parameter because packets/RPCs don't always contain the sender_id.

I know where I can see things about it, but it is pretty complex, I need to check lots of files only for one of those projects, I tried to check YSF to get some ideas about it, but I didn't understand too much (I remember that I saw something about the sender id written in some packets).

Yeah, you are right, if a documentation would be made, it would need to explain the whole RakNet.

Thanks, @spmn !