Hi, recently, I was making an advanced lag cleaner, but on my entity engine, it got error where "$entity->getLevel() returning null" Here is my code, any help is appreciated PHP: <?phpnamespace LagCleaner\engines;use pocketmine\Player;use pocketmine\entity\Entity;use pocketmine\entity\Item;use pocketmine\level\Level;use pocketmine\scheduler\PluginTask;use LagCleaner\Processor;class EntityEngine extends PluginTask{ private $entityData = []; public function __construct(Processor $handler){ parent::__construct($handler); } public function onRun(Int $tick){ $handler = $this->getOwner(); foreach($handler->getServer()->getLevels() as $level){ foreach($level->getEntities() as $entity){ if(!$entity instanceof Player && !$this->canBeSkipped($entity)){ if($entity instanceof Item && $handler->getData("entity.count.item")){ $this->checkEntity($entity); }elseif(!$entity instanceof Item && $handler->getData("entity.count.item") == false){ $this->checkEntity($entity); } } } } foreach($handler->getServer()->getLevels() as $level){ if($this->getTotalEntityCount($level) > $handler->getData("entity.max.count", 50)){ foreach($level->getEntities() as $entity){ if(!$entity instanceof Player){ if($entity instanceof Item && $handler->getData("entity.count.item")){ $entity->close(); $handler->getLogger()->debug("§f[EntityEngine] §7Cleared entity with ID ".$entity->getId()." due to max entity count reached for world: ".$entity->getLevel()->getName()); // Logs "getName() on null on ..... }elseif(!$entity instanceof Item && $handler->getData("entity.count.item") == false && !$this->canBeSkipped($entity)){ $entity->close(); $handler->getLogger()->debug("§f[EntityEngine] §7Cleared entity with ID ".$entity->getId()." due to max entity count reached for world: ".$level->getName()); // This hack worked, but eh, $entity->getLevel() should work } } } } } } public function checkEntity(Entity $entity){ $r = $this->getOwner()->getData("entity.clean.range", 50); $time = $this->getOwner()->getData("entity.clean.time", 50); $canLive = false; foreach($entity->getLevel()->getNearbyEntities($entity->getBoundingBox()->grow($r, $r, $r)) as $ent){ if($ent instanceof Player){ if(isset($this->entityData[$entity->getId()])){ unset($this->entityData[$entity->getId()]); } $canLive = true; break; } } if(!$canLive){ if(!isset($this->entityData[$entity->getId()])){ $this->entityData[$entity->getId()] = 0; } $this->entityData[$entity->getId()]++; if($this->entityData[$entity->getId()] >= $time){ unset($this->entityData[$entity->getId()]); $entity->close(); $this->getOwner()->getLogger()->debug("§f[EntityEngine] §7Cleared entity with ID ".$entity->getId()." due to no player nearby"); } } } public function canBeSkipped(Entity $entity){ $skips = $this->getOwner()->getData("entity.clean.skip", []); $ref = new \ReflectionClass($entity); foreach($skips as $name){ if($ref->getShortName() == $name){ return true; } } return false; } public function getTotalEntityCount(Level $level){ $count = 0; foreach($level->getEntities() as $entity){ if(!$entity instanceof Player){ $count++; } } return $count; }}
PHP: $entity->close(); $handler->getLogger()->debug("§f[EntityEngine] §7Cleared entity with ID ".$entity->getId()." due to max entity count reached for world: ".$entity->getLevel()->getName()); // Logs "getName() on null on ..... PHP: $entity->close(); PHP: $entity->getLevel()
Please let me know if correcting that mistake doesn't fix it because I've been having a similar problem with PureEntitiesX and had to add extra null checks everywhere on getLevel(), even though isClosed() was just checked.
An entity's level is set to null when close() is called. As the documentation warns, entities are unusable after close() is called.