NetworkSession: explicitly unregister effect manager hooks on dispose,

close #3455
This commit is contained in:
Dylan K. Taylor
2020-05-14 10:58:37 +01:00
parent 36c5d9117d
commit 3dafee6aa6
2 changed files with 38 additions and 18 deletions

View File

@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace pocketmine\network\mcpe;
use Ds\Set;
use Mdanter\Ecc\Crypto\Key\PublicKeyInterface;
use pocketmine\entity\Attribute;
use pocketmine\entity\effect\EffectInstance;
@@ -166,6 +167,12 @@ class NetworkSession{
/** @var PacketSender */
private $sender;
/**
* @var \Closure[]|Set
* @phpstan-var Set<\Closure() : void>
*/
private $disposeHooks;
public function __construct(Server $server, NetworkSessionManager $manager, PacketPool $packetPool, PacketSender $sender, Compressor $compressor, string $ip, int $port){
$this->server = $server;
$this->manager = $manager;
@@ -179,6 +186,8 @@ class NetworkSession{
$this->compressor = $compressor;
$this->packetPool = $packetPool;
$this->disposeHooks = new Set();
$this->connectTime = time();
$this->setHandler(new LoginPacketHandler(
@@ -218,12 +227,18 @@ class NetworkSession{
$this->player = new $class($this->server, $this, $this->info, $this->authenticated);
$this->invManager = new InventoryManager($this->player, $this);
$this->player->getEffects()->onEffectAdd(function(EffectInstance $effect, bool $replacesOldEffect) : void{
$effectManager = $this->player->getEffects();
$effectManager->getEffectAddHooks()->add($effectAddHook = function(EffectInstance $effect, bool $replacesOldEffect) : void{
$this->onEntityEffectAdded($this->player, $effect, $replacesOldEffect);
});
$this->player->getEffects()->onEffectRemove(function(EffectInstance $effect) : void{
$effectManager->getEffectRemoveHooks()->add($effectRemoveHook = function(EffectInstance $effect) : void{
$this->onEntityEffectRemoved($this->player, $effect);
});
$this->disposeHooks->add(static function() use ($effectManager, $effectAddHook, $effectRemoveHook) : void{
$effectManager->getEffectAddHooks()->remove($effectAddHook);
$effectManager->getEffectRemoveHooks()->remove($effectRemoveHook);
});
}
public function getPlayer() : ?Player{
@@ -467,6 +482,10 @@ class NetworkSession{
$this->disconnectGuard = true;
$func();
$this->disconnectGuard = false;
foreach($this->disposeHooks as $callback){
$callback();
}
$this->disposeHooks->clear();
$this->setHandler(null);
$this->connected = false;
$this->manager->remove($this);