mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-06-07 12:18:46 +00:00
NetworkSession: add support for discarding repeated packets before they're decoded
this dramatically reduces the server workload dealing with spammy packets like right-click interactions trigger. It also solves the problem of players getting kicked for right-clicking for too long.
This commit is contained in:
parent
56da492e48
commit
14b70c04ad
@ -58,6 +58,7 @@ use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket;
|
||||
use pocketmine\network\mcpe\protocol\ClientboundCloseFormPacket;
|
||||
use pocketmine\network\mcpe\protocol\ClientboundPacket;
|
||||
use pocketmine\network\mcpe\protocol\DisconnectPacket;
|
||||
use pocketmine\network\mcpe\protocol\InventoryTransactionPacket;
|
||||
use pocketmine\network\mcpe\protocol\ModalFormRequestPacket;
|
||||
use pocketmine\network\mcpe\protocol\MovePlayerPacket;
|
||||
use pocketmine\network\mcpe\protocol\NetworkChunkPublisherUpdatePacket;
|
||||
@ -109,6 +110,7 @@ use pocketmine\promise\PromiseResolver;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\timings\Timings;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
use pocketmine\utils\Binary;
|
||||
use pocketmine\utils\BinaryDataException;
|
||||
use pocketmine\utils\BinaryStream;
|
||||
use pocketmine\utils\ObjectSet;
|
||||
@ -194,6 +196,17 @@ class NetworkSession{
|
||||
*/
|
||||
private ObjectSet $disposeHooks;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
* @phpstan-var array<int, string>
|
||||
*/
|
||||
private array $repeatedPacketFilters = [];
|
||||
/**
|
||||
* @var int[]
|
||||
* @phpstan-var array<int, int>
|
||||
*/
|
||||
private array $repeatedPacketFilterStats = [];
|
||||
|
||||
public function __construct(
|
||||
private Server $server,
|
||||
private NetworkSessionManager $manager,
|
||||
@ -221,6 +234,8 @@ class NetworkSession{
|
||||
$this->onSessionStartSuccess(...)
|
||||
));
|
||||
|
||||
$this->addRepeatedPacketFilter(InventoryTransactionPacket::NETWORK_ID);
|
||||
|
||||
$this->manager->add($this);
|
||||
$this->logger->info($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_network_session_open()));
|
||||
}
|
||||
@ -350,6 +365,44 @@ class NetworkSession{
|
||||
}
|
||||
}
|
||||
|
||||
public function addRepeatedPacketFilter(int $packetId) : void{
|
||||
$this->repeatedPacketFilters[$packetId] = "";
|
||||
$this->repeatedPacketFilterStats[$packetId] = 0;
|
||||
}
|
||||
|
||||
public function removeRepeatedPacketFilter(int $packetId) : void{
|
||||
unset($this->repeatedPacketFilters[$packetId]);
|
||||
unset($this->repeatedPacketFilterStats[$packetId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the stats for repeated packet filters, indexed by packet ID.
|
||||
* The value is the number of times a packet was dropped due to being repeated.
|
||||
*
|
||||
* @return int[]
|
||||
* @phpstan-return array<int, int>
|
||||
*/
|
||||
public function getRepeatedPacketFilterStats() : array{
|
||||
return $this->repeatedPacketFilterStats;
|
||||
}
|
||||
|
||||
private function checkRepeatedPacketFilter(string $buffer) : bool{
|
||||
//TODO: would be great if we didn't repeat reading the ID inside PacketPool
|
||||
$dummy = 0;
|
||||
$packetId = Binary::readUnsignedVarInt($buffer, $dummy);
|
||||
|
||||
if(isset($this->repeatedPacketFilters[$packetId])){
|
||||
if($buffer === $this->repeatedPacketFilters[$packetId]){
|
||||
$this->repeatedPacketFilterStats[$packetId]++;
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->repeatedPacketFilters[$packetId] = $buffer;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws PacketHandlingException
|
||||
*/
|
||||
@ -403,6 +456,10 @@ class NetworkSession{
|
||||
try{
|
||||
$stream = new BinaryStream($decompressed);
|
||||
foreach(PacketBatch::decodeRaw($stream) as $buffer){
|
||||
if($this->checkRepeatedPacketFilter($buffer)){
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->gamePacketLimiter->decrement();
|
||||
$packet = $this->packetPool->getPacket($buffer);
|
||||
if($packet === null){
|
||||
|
Loading…
x
Reference in New Issue
Block a user