RiptideNetworking / Riptide

Lightweight C# networking solution for multiplayer games.
https://riptide.tomweiland.net
MIT License
1.14k stars 144 forks source link

Feature Request | Restriction to bytes length send separately to server and client #118

Closed DPrison closed 1 year ago

DPrison commented 1 year ago

I'd like to have separately bytes length restriction (to send message) to client and server, because all data sends in bytes (don't ask why), and server sends more data in one message then client

tom-weiland commented 1 year ago

I'm not sure why you want or need a separate "bytes length restriction" for the server and client. If the server sends 10,000 bytes in a message, that means the client needs to have messages with enough capacity to receive 10,000 bytes, so both ends need to have the same message capacity...

You can already increase the Message.MaxPayloadSize if you want to send/receive larger messages, however the default value ensures that messages will fit the MTU and avoid being fragmented by the internet. Sending messages larger than the MTU leads to a higher chance of them being lost (and in the case of reliably sent messages, having to be resent), so I generally wouldn't recommend doing that frequently.

DPrison commented 1 year ago

I mean client and server have own bytes length limits (example Message.MaxServerMessagePayloadSize and Message.MaxClientMessagePayloadSize)

tom-weiland commented 1 year ago

I mean client and server have own bytes length limits

I understood what you meant, but what I don't understand is why you want or need this, and what the benefit of this is.

Like I said before, it doesn't make any sense to give the server and client separate message size limits. If I were to implement this and then you set Message.MaxServerPayloadSize to 5000 and Message.MaxClientPayloadSize to 3000, that will only cause confusion and errors because as soon as your server sends a message that is bigger than the MaxClientPayloadSize—4000 bytes for example—the client won't be able to handle it because it's 1000 bytes too big. What should happen in that scenario?

Even if that wasn't an issue, I don't know why you need separate properties for this as you can essentially already do what you're describing with just the one current Message.MaxPayloadSize property. If you have separate projects for your server and client, just set the MaxPayloadSize in each project how you want it. If you have one combined project for both and build each separately, all it takes is one if statement to set the MaxPayloadSize based on which one you're building/running. Of course as soon as you send a message bigger than what the other side is equipped to handle, you'll have issues.

The only scenario where a single property isn't enough is if you're building a player-hosted game where the host player runs both a Server and Client instance simultaneously. But again, setting separate payload sizes doesn't even really make sense, and I don't see any benefit to being able to do it...feel free to enlighten me :P

DPrison commented 1 year ago

I need it to protect server from spamming packets, because client send small data, max up to 2000 bytes, but server send all objects in the server, data about other players and other, that in my case up message size to 100000 bytes, and if client and server have the same message size limit, then client just can spamming empty packets with 100000 bytes, i cannot kick player immediatly because i need understand spamming client or just send message, why message up's to 100000 bytes? Because i send data not as string, int or float, i send data directly in bytes, i convert all data to bytes because for perfomance and scripting its very simplify just read and deserialize bytes, write too, simplify then write by one int, string or other variable But if you say that client cannot recieve message than bigger own Message.MaxClientPayloadSize, so i close this thread

tom-weiland commented 1 year ago

I need it to protect server from spamming packets, because client send small data, max up to 2000 bytes

Assuming you mean "to protect the server from being spammed with large packets" (otherwise I'm not sure why the payload size is relevant), you could just as easily do this by checking the received message length in a message handler, and kick the client if it's too big.

if client and server have the same message size limit, then client just can spamming empty packets with 100000 bytes

Like I said in my previous response, you could make the message size limits different for the server and client by setting the existing Message.MaxPayloadSize property to a different value on each (but it will cause problems when you receive a message that's bigger than the local max). However, any sort of message size limit you try to impose on the client within the client's own code could be bypassed by a hacker/malicious client with ease, so it wouldn't accomplish what I think you're trying to achieve. The only way to protect the server against large message spam from clients is by checking the received message size on the server.

For what it's worth, these days most server hosting providers offer DDoS protection which might be worth looking into.

i cannot kick player immediatly because i need understand spamming client or just send message

I'm not really sure what you mean by this, or why it prevents you from kicking a client that's spamming large messages 🤔

Because i send data not as string, int or float, i send data directly in bytes

What does this have to do with large message spam and the size of messages? Everyone sends data "directly in bytes" because you can't send a string, int or float in their regular form—they need to be converted to bytes because the only thing you can send over the network is bytes. There's no other way to do it, so I'm not sure what the point is that you're trying to make...