#caching packets into player memory?
1 messages · Page 1 of 1 (latest)
the motivation behind this is that I noticed that at some point, i send so many packets to player that their ping starts jumping and they eventually time out
I'm assuming they don't have time to process every packets yet that already they are sent more packets
Do you have any idea about how I could control the flow?
The amount of packets they may receive can be 0, or 5000 per seconds technically, no real limit, it depends how many stuff get animated around them
Obviously I don't want to exceed their limits
So it's all about delay between each packet basically
afaik this is not possible, it would require client modifications to do this.
you will be still sending packets even if the packet data are "cached" for later use inside client, since there's no way to communicate with server and client, except for packets
to command which cached packet to use, which would probably perform worse since you would need to send more packets than initially before
ah alright thanks for your response buddy, and do you know whether its possible to cancel all the packets that were already sent to a user so if they're flooded and can't keep up (typically if i detect their ping is high af), i can reset their connection or sth?
(leaving and rejoining game would have this effect)
I don't want to time them out of course, on the contrary i want to ensure this will not happen
@shrewd schooner
if its sent already you can't
ofc you can check ping
before sending them in the server
But like how do you explain that when a player was spammed with packets, their ping can still be quite high the following 2.5 minutes after server stopped spamming them with packets
Here's my intuition on it: When they were spammed, they were accumulating more and more delay in their "packets to process" queue (idk if it exists), so when the server stopped spamming, they still had a big queue of packets to process...
But now, instead of waiting 2.5 minutes for ping to get back to normal, they can simply disconnect and reconnect, (i noticed that by testing)
So I'm assuming that disconnecting empties their queue of packets to process, if it exists
Isn't it possible to replicate the same thing, clearing their queue of packets to process, without making/letting them disconnect?
Or is this queue only available & managed client side?
but maybe there'd still be a way to make their clients trigger in such a way without any disconnecting, i'm thinking "sending them a fake disconnect/kick packet" which has max priority on any other packets, or sth could do the trick?
ofc you can check ping
before sending them in the server
yeah so actually the situation i described is not mine, it was easier to explain this
My real situation is: i don't mind if their ping gets high af because its their fault they did add the animated shit themselves, and it only happens on a specific geographic region where they put too much of the animated madness, but when they leave the zone, i already made it that it doesn't send packets anymore, and therefore i would also like to clear their packets list queue so their ping can get back to normal faster after leaving the zone
I don't really know, i haven't digged up minecraft's protocol so far as you do right now, but as far as i am aware, the furthest point you can get with packet handling is via netty channel pipeline queue manipulation
but i do not recommend that, since it could desync client and server, and the functionality would be undefined (timeout kicking, client and server views are different, etc.)
whenever you send a packet via NMS or Protocollib async they'll end up in the server's packet queue (at least on paper). But im not quite sure how that works because i researched this like a year ago and couldnt really tell
public void send(Packet<?> packet, @Nullable GenericFutureListener<? extends Future<? super Void>> callback) {
// Paper start - handle oversized packets better
boolean connected = this.isConnected();
if (!connected && !preparing) {
return; // Do nothing
}
packet.onPacketDispatch(getPlayer());
if (connected && (InnerUtil.canSendImmediate(this, packet) || (
net.minecraft.server.MCUtil.isMainThread() && packet.isReady() && this.queue.isEmpty() &&
(packet.getExtraPackets() == null || packet.getExtraPackets().isEmpty())
))) {
this.writePacket(packet, callback, null); // Paper
return;
}
// write the packets to the queue, then flush - antixray hooks there already
java.util.List<Packet> extraPackets = InnerUtil.buildExtraPackets(packet);
boolean hasExtraPackets = extraPackets != null && !extraPackets.isEmpty();
if (!hasExtraPackets) {
this.queue.add(new Connection.PacketHolder(packet, callback));
} else {
java.util.List<Connection.PacketHolder> packets = new java.util.ArrayList<>(1 + extraPackets.size());
packets.add(new Connection.PacketHolder(packet, null)); // delay the future listener until the end of the extra packets
for (int i = 0, len = extraPackets.size(); i < len;) {
Packet extra = extraPackets.get(i);
boolean end = ++i == len;
packets.add(new Connection.PacketHolder(extra, end ? callback : null)); // append listener to the end
}
this.queue.addAll(packets); // atomic
}
this.flushQueue();
// Paper end
}