From f7d0d16eb3b1f4be73535a5674b2da8a2b799a94 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 24 Dec 2022 20:06:00 +0000 Subject: [PATCH] NetworkSession: defer destructive cleanup until the next session tick() call this fixes crashes when kicking players during PlayerJoinEvent and various other events. --- src/network/mcpe/NetworkSession.php | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index ff91aa5b5..a765815f0 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -547,13 +547,18 @@ class NetworkSession{ $this->disposeHooks->clear(); $this->setHandler(null); $this->connected = false; - $this->manager->remove($this); $this->logger->info("Session closed due to $reason"); - - $this->invManager = null; //break cycles - TODO: this really ought to be deferred until it's safe } } + /** + * Performs actions after the session has been disconnected. By this point, nothing should be interacting with the + * session, so it's safe to destroy any cycles and perform destructive cleanup. + */ + private function dispose() : void{ + $this->invManager = null; + } + /** * Disconnects the session, destroying the associated player (if it exists). */ @@ -1114,6 +1119,11 @@ class NetworkSession{ } public function tick() : void{ + if(!$this->isConnected()){ + $this->dispose(); + return; + } + if($this->info === null){ if(time() >= $this->connectTime + 10){ $this->disconnect("Login timeout");