mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-08-20 10:00:31 +00:00
NetworkSession: Improved packet budgeting
this fixes players getting kicked during server lag spikes. closes #5532
This commit is contained in:
parent
69155015c9
commit
2fd6e769e6
@ -361,12 +361,9 @@ class NetworkSession{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if($this->incomingPacketBatchBudget <= 0){
|
if($this->incomingPacketBatchBudget <= 0){
|
||||||
if(!function_exists('xdebug_is_debugger_active') || !xdebug_is_debugger_active()){
|
$this->updatePacketBudget();
|
||||||
|
if($this->incomingPacketBatchBudget <= 0){
|
||||||
throw new PacketHandlingException("Receiving packets too fast");
|
throw new PacketHandlingException("Receiving packets too fast");
|
||||||
}else{
|
|
||||||
//when a debugging session is active, the server may halt at any point for an indefinite length of time,
|
|
||||||
//in which time the client will continue to send packets
|
|
||||||
$this->incomingPacketBatchBudget = self::INCOMING_PACKET_BATCH_MAX_BUDGET;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->incomingPacketBatchBudget--;
|
$this->incomingPacketBatchBudget--;
|
||||||
@ -1143,6 +1140,23 @@ class NetworkSession{
|
|||||||
$this->sendDataPacket(ToastRequestPacket::create($title, $body));
|
$this->sendDataPacket(ToastRequestPacket::create($title, $body));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function updatePacketBudget() : void{
|
||||||
|
$nowNs = hrtime(true);
|
||||||
|
$timeSinceLastUpdateNs = $nowNs - $this->lastPacketBudgetUpdateTimeNs;
|
||||||
|
if($timeSinceLastUpdateNs > 50_000_000){
|
||||||
|
$ticksSinceLastUpdate = intdiv($timeSinceLastUpdateNs, 50_000_000);
|
||||||
|
/*
|
||||||
|
* If the server takes an abnormally long time to process a tick, add the budget for time difference to
|
||||||
|
* compensate. This extra budget may be very large, but it will disappear the next time a normal update
|
||||||
|
* occurs. This ensures that backlogs during a large lag spike don't cause everyone to get kicked.
|
||||||
|
* As long as all the backlogged packets are processed before the next tick, everything should be OK for
|
||||||
|
* clients behaving normally.
|
||||||
|
*/
|
||||||
|
$this->incomingPacketBatchBudget = min($this->incomingPacketBatchBudget, self::INCOMING_PACKET_BATCH_MAX_BUDGET) + (self::INCOMING_PACKET_BATCH_PER_TICK * 2 * $ticksSinceLastUpdate);
|
||||||
|
$this->lastPacketBudgetUpdateTimeNs = $nowNs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function tick() : void{
|
public function tick() : void{
|
||||||
if(!$this->isConnected()){
|
if(!$this->isConnected()){
|
||||||
$this->dispose();
|
$this->dispose();
|
||||||
@ -1170,16 +1184,5 @@ class NetworkSession{
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->flushSendBuffer();
|
$this->flushSendBuffer();
|
||||||
|
|
||||||
$nowNs = hrtime(true);
|
|
||||||
$timeSinceLastUpdateNs = $nowNs - $this->lastPacketBudgetUpdateTimeNs;
|
|
||||||
if($timeSinceLastUpdateNs > 50_000_000){
|
|
||||||
$ticksSinceLastUpdate = intdiv($timeSinceLastUpdateNs, 50_000_000);
|
|
||||||
$this->incomingPacketBatchBudget = min(
|
|
||||||
$this->incomingPacketBatchBudget + (self::INCOMING_PACKET_BATCH_PER_TICK * 2 * $ticksSinceLastUpdate),
|
|
||||||
self::INCOMING_PACKET_BATCH_MAX_BUDGET
|
|
||||||
);
|
|
||||||
$this->lastPacketBudgetUpdateTimeNs = $nowNs;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user