Do not call PlayerLoginEvent during the Player constructor

this closes a lot of loopholes in the login sequence that plugins were using to cause crashes.
This commit is contained in:
Dylan K. Taylor 2021-10-04 22:36:50 +01:00
parent 356a49d225
commit bb6ea8cbdc
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
3 changed files with 29 additions and 24 deletions

View File

@ -40,6 +40,7 @@ use pocketmine\entity\Location;
use pocketmine\event\HandlerListManager;
use pocketmine\event\player\PlayerCreationEvent;
use pocketmine\event\player\PlayerDataSaveEvent;
use pocketmine\event\player\PlayerLoginEvent;
use pocketmine\event\server\CommandEvent;
use pocketmine\event\server\DataPacketSendEvent;
use pocketmine\event\server\QueryRegenerateEvent;
@ -1521,7 +1522,28 @@ class Server{
}
}
public function addOnlinePlayer(Player $player) : void{
public function addOnlinePlayer(Player $player) : bool{
$ev = new PlayerLoginEvent($player, "Plugin reason");
$ev->call();
if($ev->isCancelled() or !$player->isConnected()){
$player->disconnect($ev->getKickMessage());
return false;
}
$session = $player->getNetworkSession();
$position = $player->getPosition();
$this->logger->info($this->language->translate(KnownTranslationFactory::pocketmine_player_logIn(
TextFormat::AQUA . $player->getName() . TextFormat::WHITE,
$session->getIp(),
(string) $session->getPort(),
(string) $player->getId(),
$position->getWorld()->getDisplayName(),
(string) round($position->x, 4),
(string) round($position->y, 4),
(string) round($position->z, 4)
)));
foreach($this->playerList as $p){
$p->getNetworkSession()->onPlayerAdded($player);
}
@ -1531,6 +1553,8 @@ class Server{
if($this->sendUsageTicker > 0){
$this->uniquePlayers[$rawUUID] = $rawUUID;
}
return true;
}
public function removeOnlinePlayer(Player $player) : void{

View File

@ -234,6 +234,10 @@ class NetworkSession{
return;
}
$this->player = $player;
if(!$this->server->addOnlinePlayer($player)){
return;
}
$this->invManager = new InventoryManager($this->player, $this);
$effectManager = $this->player->getEffects();

View File

@ -63,7 +63,6 @@ use pocketmine\event\player\PlayerItemUseEvent;
use pocketmine\event\player\PlayerJoinEvent;
use pocketmine\event\player\PlayerJumpEvent;
use pocketmine\event\player\PlayerKickEvent;
use pocketmine\event\player\PlayerLoginEvent;
use pocketmine\event\player\PlayerMoveEvent;
use pocketmine\event\player\PlayerQuitEvent;
use pocketmine\event\player\PlayerRespawnEvent;
@ -133,7 +132,6 @@ use function max;
use function microtime;
use function min;
use function preg_match;
use function round;
use function spl_object_id;
use function sqrt;
use function strlen;
@ -277,27 +275,6 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
$this->usedChunks[World::chunkHash($spawnLocation->getFloorX() >> Chunk::COORD_BIT_SIZE, $spawnLocation->getFloorZ() >> Chunk::COORD_BIT_SIZE)] = UsedChunkStatus::NEEDED();
parent::__construct($spawnLocation, $this->playerInfo->getSkin(), $namedtag);
$ev = new PlayerLoginEvent($this, "Plugin reason");
$ev->call();
if($ev->isCancelled() or !$this->isConnected()){
$this->disconnect($ev->getKickMessage());
return;
}
$this->server->getLogger()->info($this->getServer()->getLanguage()->translate(KnownTranslationFactory::pocketmine_player_logIn(
TextFormat::AQUA . $this->username . TextFormat::WHITE,
$session->getIp(),
(string) $session->getPort(),
(string) $this->id,
$this->getWorld()->getDisplayName(),
(string) round($this->location->x, 4),
(string) round($this->location->y, 4),
(string) round($this->location->z, 4)
)));
$this->server->addOnlinePlayer($this);
}
protected function initHumanData(CompoundTag $nbt) : void{