Merge branch 'release/3.3'

This commit is contained in:
Dylan K. Taylor 2018-10-05 18:11:33 +01:00
commit 495a0b1dc2
28 changed files with 182 additions and 139 deletions

View File

@ -185,7 +185,7 @@ class MemoryManager{
} }
$ev = new LowMemoryEvent($memory, $limit, $global, $triggerCount); $ev = new LowMemoryEvent($memory, $limit, $global, $triggerCount);
$this->server->getPluginManager()->callEvent($ev); $ev->call();
$cycles = 0; $cycles = 0;
if($this->garbageCollectionTrigger){ if($this->garbageCollectionTrigger){

View File

@ -745,7 +745,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
$ev = new PlayerChangeSkinEvent($this, $this->getSkin(), $skin); $ev = new PlayerChangeSkinEvent($this, $this->getSkin(), $skin);
$this->server->getPluginManager()->callEvent($ev); $ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->sendSkin([$this]); $this->sendSkin([$this]);
@ -972,11 +972,12 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
PermissionManager::getInstance()->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this); PermissionManager::getInstance()->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this);
} }
$this->server->getPluginManager()->callEvent($ev = new PlayerJoinEvent($this, $ev = new PlayerJoinEvent($this,
new TranslationContainer(TextFormat::YELLOW . "%multiplayer.player.joined", [ new TranslationContainer(TextFormat::YELLOW . "%multiplayer.player.joined", [
$this->getDisplayName() $this->getDisplayName()
]) ])
)); );
$ev->call();
if(strlen(trim((string) $ev->getJoinMessage())) > 0){ if(strlen(trim((string) $ev->getJoinMessage())) > 0){
$this->server->broadcastMessage($ev->getJoinMessage()); $this->server->broadcastMessage($ev->getJoinMessage());
} }
@ -1159,7 +1160,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$pos = $pos->floor(); $pos = $pos->floor();
$b = $this->level->getBlock($pos); $b = $this->level->getBlock($pos);
$this->server->getPluginManager()->callEvent($ev = new PlayerBedEnterEvent($this, $b)); $ev = new PlayerBedEnterEvent($this, $b);
$ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;
} }
@ -1186,7 +1188,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
if($b instanceof Bed){ if($b instanceof Bed){
$b->setOccupied(false); $b->setOccupied(false);
} }
$this->server->getPluginManager()->callEvent($ev = new PlayerBedLeaveEvent($this, $b)); (new PlayerBedLeaveEvent($this, $b))->call();
$this->sleeping = null; $this->sleeping = null;
$this->propertyManager->setBlockPos(self::DATA_PLAYER_BED_POSITION, null); $this->propertyManager->setBlockPos(self::DATA_PLAYER_BED_POSITION, null);
@ -1223,7 +1225,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return false; return false;
} }
} }
$this->server->getPluginManager()->callEvent($ev = new PlayerAchievementAwardedEvent($this, $achievementId)); $ev = new PlayerAchievementAwardedEvent($this, $achievementId);
$ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->achievements[$achievementId] = true; $this->achievements[$achievementId] = true;
Achievement::broadcast($this, $achievementId); Achievement::broadcast($this, $achievementId);
@ -1286,7 +1289,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return false; return false;
} }
$this->server->getPluginManager()->callEvent($ev = new PlayerGameModeChangeEvent($this, $gm)); $ev = new PlayerGameModeChangeEvent($this, $gm);
$ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
if($client){ //gamemode change by client in the GUI if($client){ //gamemode change by client in the GUI
$this->sendGamemode(); $this->sendGamemode();
@ -1502,7 +1506,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$ev = new PlayerIllegalMoveEvent($this, $newPos, $this->lastLocation->asVector3()); $ev = new PlayerIllegalMoveEvent($this, $newPos, $this->lastLocation->asVector3());
$ev->setCancelled($this->allowMovementCheats); $ev->setCancelled($this->allowMovementCheats);
$this->server->getPluginManager()->callEvent($ev); $ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$revert = true; $revert = true;
@ -1527,7 +1531,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$ev = new PlayerMoveEvent($this, $from, $to); $ev = new PlayerMoveEvent($this, $from, $to);
$this->server->getPluginManager()->callEvent($ev); $ev->call();
if(!($revert = $ev->isCancelled())){ //Yes, this is intended if(!($revert = $ev->isCancelled())){ //Yes, this is intended
if($to->distanceSquared($ev->getTo()) > 0.01){ //If plugins modify the destination if($to->distanceSquared($ev->getTo()) > 0.01){ //If plugins modify the destination
@ -1561,7 +1565,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
public function jump() : void{ public function jump() : void{
$this->server->getPluginManager()->callEvent(new PlayerJumpEvent($this)); (new PlayerJumpEvent($this))->call();
parent::jump(); parent::jump();
} }
@ -1722,7 +1726,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$this->setSkin($packet->skin); $this->setSkin($packet->skin);
$this->server->getPluginManager()->callEvent($ev = new PlayerPreLoginEvent($this, "Plugin reason")); $ev = new PlayerPreLoginEvent($this, "Plugin reason");
$ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->close("", $ev->getKickMessage()); $this->close("", $ev->getKickMessage());
@ -1787,7 +1792,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
foreach($this->server->getLoggedInPlayers() as $p){ foreach($this->server->getLoggedInPlayers() as $p){
if($p !== $this and ($p->iusername === $this->iusername or $this->getUniqueId()->equals($p->getUniqueId()))){ if($p !== $this and ($p->iusername === $this->iusername or $this->getUniqueId()->equals($p->getUniqueId()))){
$this->server->getPluginManager()->callEvent($ev = new PlayerDuplicateLoginEvent($this->networkSession, $p->networkSession)); $ev = new PlayerDuplicateLoginEvent($this->networkSession, $p->networkSession);
$ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->networkSession->disconnect($ev->getDisconnectMessage()); $this->networkSession->disconnect($ev->getDisconnectMessage());
return false; return false;
@ -1825,8 +1831,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$level->registerChunkLoader($this, ((int) floor($pos[0])) >> 4, ((int) floor($pos[2])) >> 4, true); $level->registerChunkLoader($this, ((int) floor($pos[0])) >> 4, ((int) floor($pos[2])) >> 4, true);
parent::__construct($level, $namedtag); parent::__construct($level, $namedtag);
$ev = new PlayerLoginEvent($this, "Plugin reason");
$this->server->getPluginManager()->callEvent($ev = new PlayerLoginEvent($this, "Plugin reason")); $ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->close($this->getLeaveMessage(), $ev->getKickMessage()); $this->close($this->getLeaveMessage(), $ev->getKickMessage());
@ -1908,8 +1914,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
$ev = new PlayerCommandPreprocessEvent($this, $messagePart); $ev = new PlayerCommandPreprocessEvent($this, $messagePart);
$ev->call();
$this->server->getPluginManager()->callEvent($ev);
if($ev->isCancelled()){ if($ev->isCancelled()){
break; break;
@ -1920,7 +1925,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$this->server->dispatchCommand($ev->getPlayer(), substr($ev->getMessage(), 1)); $this->server->dispatchCommand($ev->getPlayer(), substr($ev->getMessage(), 1));
Timings::$playerCommandTimer->stopTiming(); Timings::$playerCommandTimer->stopTiming();
}else{ }else{
$this->server->getPluginManager()->callEvent($ev = new PlayerChatEvent($this, $ev->getMessage())); $ev = new PlayerChatEvent($this, $ev->getMessage());
$ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->server->broadcastMessage($this->getServer()->getLanguage()->translateString($ev->getFormat(), [$ev->getPlayer()->getDisplayName(), $ev->getMessage()]), $ev->getRecipients()); $this->server->broadcastMessage($this->getServer()->getLanguage()->translateString($ev->getFormat(), [$ev->getPlayer()->getDisplayName(), $ev->getMessage()]), $ev->getRecipients());
} }
@ -1991,7 +1997,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return false; return false;
} }
$this->server->getPluginManager()->callEvent($ev = new PlayerItemHeldEvent($this, $this->inventory->getItem($hotbarSlot), $hotbarSlot)); $ev = new PlayerItemHeldEvent($this, $this->inventory->getItem($hotbarSlot), $hotbarSlot);
$ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->inventory->sendHeldItem($this); $this->inventory->sendHeldItem($this);
return false; return false;
@ -2017,7 +2024,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$ev->setCancelled(); $ev->setCancelled();
} }
$this->server->getPluginManager()->callEvent($ev); $ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->inventory->sendHeldItem($this); $this->inventory->sendHeldItem($this);
@ -2049,7 +2056,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
if($this->hasItemCooldown($slot)){ if($this->hasItemCooldown($slot)){
$ev->setCancelled(); $ev->setCancelled();
} }
$this->server->getPluginManager()->callEvent($ev); $ev->call();
if($ev->isCancelled() or !$this->consumeObject($slot)){ if($ev->isCancelled() or !$this->consumeObject($slot)){
$this->inventory->sendContents($this); $this->inventory->sendContents($this);
@ -2117,7 +2124,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$ev->setCancelled(); $ev->setCancelled();
} }
$this->server->getPluginManager()->callEvent($ev); $ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->inventory->setItemInHand($item); $this->inventory->setItemInHand($item);
} }
@ -2137,7 +2144,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$ev->setCancelled(); $ev->setCancelled();
} }
$this->getServer()->getPluginManager()->callEvent($ev); $ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->inventory->sendHeldItem($this); $this->inventory->sendHeldItem($this);
return true; return true;
@ -2347,7 +2354,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
public function toggleSprint(bool $sprint) : void{ public function toggleSprint(bool $sprint) : void{
$ev = new PlayerToggleSprintEvent($this, $sprint); $ev = new PlayerToggleSprintEvent($this, $sprint);
$this->server->getPluginManager()->callEvent($ev); $ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->sendData($this); $this->sendData($this);
}else{ }else{
@ -2357,7 +2364,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
public function toggleSneak(bool $sneak) : void{ public function toggleSneak(bool $sneak) : void{
$ev = new PlayerToggleSneakEvent($this, $sneak); $ev = new PlayerToggleSneakEvent($this, $sneak);
$this->server->getPluginManager()->callEvent($ev); $ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->sendData($this); $this->sendData($this);
}else{ }else{
@ -2367,7 +2374,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
public function toggleFlight(bool $fly) : void{ public function toggleFlight(bool $fly) : void{
$ev = new PlayerToggleFlightEvent($this, $fly); $ev = new PlayerToggleFlightEvent($this, $fly);
$this->server->getPluginManager()->callEvent($ev); $ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->sendSettings(); $this->sendSettings();
}else{ }else{
@ -2376,7 +2383,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
public function animate(int $action) : bool{ public function animate(int $action) : bool{
$this->server->getPluginManager()->callEvent($ev = new PlayerAnimationEvent($this, $action)); $ev = new PlayerAnimationEvent($this, $action);
$ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
return true; return true;
} }
@ -2453,7 +2461,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$ev->setCancelled(); $ev->setCancelled();
} }
$this->server->getPluginManager()->callEvent($ev); $ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
$tile->spawnTo($this); $tile->spawnTo($this);
return true; return true;
@ -2507,7 +2515,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return false; return false;
} }
$this->getServer()->getPluginManager()->callEvent($event = new PlayerEditBookEvent($this, $oldBook, $newBook, $packet->type, $modifiedPages)); $event = new PlayerEditBookEvent($this, $oldBook, $newBook, $packet->type, $modifiedPages);
$event->call();
if($event->isCancelled()){ if($event->isCancelled()){
return true; return true;
} }
@ -2558,8 +2567,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
* @return bool if transfer was successful. * @return bool if transfer was successful.
*/ */
public function transfer(string $address, int $port = 19132, string $message = "transfer") : bool{ public function transfer(string $address, int $port = 19132, string $message = "transfer") : bool{
$this->server->getPluginManager()->callEvent($ev = new PlayerTransferEvent($this, $address, $port, $message)); $ev = new PlayerTransferEvent($this, $address, $port, $message);
$ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$pk = new TransferPacket(); $pk = new TransferPacket();
$pk->address = $ev->getAddress(); $pk->address = $ev->getAddress();
@ -2583,7 +2592,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
* @return bool * @return bool
*/ */
public function kick(string $reason = "", bool $isAdmin = true, $quitMessage = null) : bool{ public function kick(string $reason = "", bool $isAdmin = true, $quitMessage = null) : bool{
$this->server->getPluginManager()->callEvent($ev = new PlayerKickEvent($this, $reason, $quitMessage ?? $this->getLeaveMessage())); $ev = new PlayerKickEvent($this, $reason, $quitMessage ?? $this->getLeaveMessage());
$ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$reason = $ev->getReason(); $reason = $ev->getReason();
$message = $reason; $message = $reason;
@ -2825,7 +2835,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$this->stopSleep(); $this->stopSleep();
if($this->spawned){ if($this->spawned){
$this->server->getPluginManager()->callEvent($ev = new PlayerQuitEvent($this, $message, $reason)); $ev = new PlayerQuitEvent($this, $message, $reason);
$ev->call();
if($ev->getQuitMessage() != ""){ if($ev->getQuitMessage() != ""){
$this->server->broadcastMessage($ev->getQuitMessage()); $this->server->broadcastMessage($ev->getQuitMessage());
} }
@ -2974,7 +2985,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
//main inventory and drops the rest on the ground. //main inventory and drops the rest on the ground.
$this->doCloseInventory(); $this->doCloseInventory();
$this->server->getPluginManager()->callEvent($ev = new PlayerDeathEvent($this, $this->getDrops())); $ev = new PlayerDeathEvent($this, $this->getDrops());
$ev->call();
if(!$ev->getKeepInventory()){ if(!$ev->getKeepInventory()){
foreach($ev->getDrops() as $item){ foreach($ev->getDrops() as $item){
@ -3009,7 +3021,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return; return;
} }
$this->server->getPluginManager()->callEvent($ev = new PlayerRespawnEvent($this, $this->getSpawn())); $ev = new PlayerRespawnEvent($this, $this->getSpawn());
$ev->call();
$realSpawn = Position::fromObject($ev->getRespawnPosition()->add(0.5, 0, 0.5), $ev->getRespawnPosition()->getLevel()); $realSpawn = Position::fromObject($ev->getRespawnPosition()->add(0.5, 0, 0.5), $ev->getRespawnPosition()->getLevel());
$this->teleport($realSpawn); $this->teleport($realSpawn);
@ -3204,7 +3217,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$this->doCloseInventory(); $this->doCloseInventory();
if(isset($this->windowIndex[$windowId])){ if(isset($this->windowIndex[$windowId])){
$this->server->getPluginManager()->callEvent(new InventoryCloseEvent($this->windowIndex[$windowId], $this)); (new InventoryCloseEvent($this->windowIndex[$windowId], $this))->call();
$this->removeWindow($this->windowIndex[$windowId]); $this->removeWindow($this->windowIndex[$windowId]);
return true; return true;
} }

View File

@ -826,7 +826,7 @@ class Server{
$ev = new PlayerDataSaveEvent($nbtTag, $name); $ev = new PlayerDataSaveEvent($nbtTag, $name);
$ev->setCancelled(!$this->shouldSavePlayerData()); $ev->setCancelled(!$this->shouldSavePlayerData());
$this->pluginManager->callEvent($ev); $ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$nbt = new BigEndianNBTStream(); $nbt = new BigEndianNBTStream();
@ -1052,7 +1052,7 @@ class Server{
$this->levels[$level->getId()] = $level; $this->levels[$level->getId()] = $level;
$this->getPluginManager()->callEvent(new LevelLoadEvent($level)); (new LevelLoadEvent($level))->call();
$level->setTickRate($this->baseTickRate); $level->setTickRate($this->baseTickRate);
@ -1096,9 +1096,9 @@ class Server{
$level->setTickRate($this->baseTickRate); $level->setTickRate($this->baseTickRate);
$this->getPluginManager()->callEvent(new LevelInitEvent($level)); (new LevelInitEvent($level))->call();
$this->getPluginManager()->callEvent(new LevelLoadEvent($level)); (new LevelLoadEvent($level))->call();
$this->getLogger()->notice($this->getLanguage()->translateString("pocketmine.level.backgroundGeneration", [$name])); $this->getLogger()->notice($this->getLanguage()->translateString("pocketmine.level.backgroundGeneration", [$name]));
@ -1891,7 +1891,8 @@ class Server{
throw new \InvalidArgumentException("Cannot broadcast empty list of packets"); throw new \InvalidArgumentException("Cannot broadcast empty list of packets");
} }
$this->pluginManager->callEvent($ev = new DataPacketBroadcastEvent($players, $packets)); $ev = new DataPacketBroadcastEvent($players, $packets);
$ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;
} }
@ -2006,7 +2007,8 @@ class Server{
*/ */
public function dispatchCommand(CommandSender $sender, string $commandLine, bool $internal = false) : bool{ public function dispatchCommand(CommandSender $sender, string $commandLine, bool $internal = false) : bool{
if(!$internal){ if(!$internal){
$this->pluginManager->callEvent($ev = new CommandEvent($sender, $commandLine)); $ev = new CommandEvent($sender, $commandLine);
$ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;
} }
@ -2583,7 +2585,7 @@ class Server{
} }
if(($this->tickCounter & 0b111111111) === 0){ if(($this->tickCounter & 0b111111111) === 0){
$this->getPluginManager()->callEvent($this->queryRegenerateTask = new QueryRegenerateEvent($this, 5)); ($this->queryRegenerateTask = new QueryRegenerateEvent($this, 5))->call();
if($this->queryHandler !== null){ if($this->queryHandler !== null){
$this->queryHandler->regenerateInfo(); $this->queryHandler->regenerateInfo();
} }

View File

@ -542,7 +542,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
$this->level->addEntity($this); $this->level->addEntity($this);
$this->lastUpdate = $this->server->getTick(); $this->lastUpdate = $this->server->getTick();
$this->server->getPluginManager()->callEvent(new EntitySpawnEvent($this)); (new EntitySpawnEvent($this))->call();
$this->scheduleUpdate(); $this->scheduleUpdate();
@ -882,7 +882,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
* @param EntityDamageEvent $source * @param EntityDamageEvent $source
*/ */
public function attack(EntityDamageEvent $source) : void{ public function attack(EntityDamageEvent $source) : void{
$this->server->getPluginManager()->callEvent($source); $source->call();
if($source->isCancelled()){ if($source->isCancelled()){
return; return;
} }
@ -896,7 +896,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
* @param EntityRegainHealthEvent $source * @param EntityRegainHealthEvent $source
*/ */
public function heal(EntityRegainHealthEvent $source) : void{ public function heal(EntityRegainHealthEvent $source) : void{
$this->server->getPluginManager()->callEvent($source); $source->call();
if($source->isCancelled()){ if($source->isCancelled()){
return; return;
} }
@ -1795,7 +1795,8 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
public function setMotion(Vector3 $motion) : bool{ public function setMotion(Vector3 $motion) : bool{
if(!$this->justCreated){ if(!$this->justCreated){
$this->server->getPluginManager()->callEvent($ev = new EntityMotionEvent($this, $motion)); $ev = new EntityMotionEvent($this, $motion);
$ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;
} }
@ -1828,7 +1829,8 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
} }
$from = Position::fromObject($this, $this->level); $from = Position::fromObject($this, $this->level);
$to = Position::fromObject($pos, $pos instanceof Position ? $pos->getLevel() : $this->level); $to = Position::fromObject($pos, $pos instanceof Position ? $pos->getLevel() : $this->level);
$this->server->getPluginManager()->callEvent($ev = new EntityTeleportEvent($this, $from, $to)); $ev = new EntityTeleportEvent($this, $from, $to);
$ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;
} }
@ -1854,7 +1856,8 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
} }
if($this->isValid()){ if($this->isValid()){
$this->server->getPluginManager()->callEvent($ev = new EntityLevelChangeEvent($this, $this->level, $targetLevel)); $ev = new EntityLevelChangeEvent($this, $this->level, $targetLevel);
$ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;
} }
@ -1980,7 +1983,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
*/ */
public function close() : void{ public function close() : void{
if(!$this->closed){ if(!$this->closed){
$this->server->getPluginManager()->callEvent(new EntityDespawnEvent($this)); (new EntityDespawnEvent($this))->call();
$this->closed = true; $this->closed = true;
$this->despawnFromAll(); $this->despawnFromAll();

View File

@ -269,7 +269,8 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
* @return float the amount of exhaustion level increased * @return float the amount of exhaustion level increased
*/ */
public function exhaust(float $amount, int $cause = PlayerExhaustEvent::CAUSE_CUSTOM) : float{ public function exhaust(float $amount, int $cause = PlayerExhaustEvent::CAUSE_CUSTOM) : float{
$this->server->getPluginManager()->callEvent($ev = new PlayerExhaustEvent($this, $amount, $cause)); $ev = new PlayerExhaustEvent($this, $amount, $cause);
$ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
return 0.0; return 0.0;
} }
@ -466,7 +467,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
protected function setXpAndProgress(?int $level, ?float $progress) : bool{ protected function setXpAndProgress(?int $level, ?float $progress) : bool{
if(!$this->justCreated){ if(!$this->justCreated){
$ev = new PlayerExperienceChangeEvent($this, $this->getXpLevel(), $this->getXpProgress(), $level, $progress); $ev = new PlayerExperienceChangeEvent($this, $this->getXpLevel(), $this->getXpProgress(), $level, $progress);
$this->server->getPluginManager()->callEvent($ev); $ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;

View File

@ -201,7 +201,8 @@ abstract class Living extends Entity implements Damageable{
if(isset($this->effects[$effectId])){ if(isset($this->effects[$effectId])){
$effect = $this->effects[$effectId]; $effect = $this->effects[$effectId];
$hasExpired = $effect->hasExpired(); $hasExpired = $effect->hasExpired();
$this->server->getPluginManager()->callEvent($ev = new EntityEffectRemoveEvent($this, $effect)); $ev = new EntityEffectRemoveEvent($this, $effect);
$ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
if($hasExpired and !$ev->getEffect()->hasExpired()){ //altered duration of an expired effect to make it not get removed if($hasExpired and !$ev->getEffect()->hasExpired()){ //altered duration of an expired effect to make it not get removed
$this->sendEffectAdd($ev->getEffect(), true); $this->sendEffectAdd($ev->getEffect(), true);
@ -274,7 +275,7 @@ abstract class Living extends Entity implements Damageable{
$ev = new EntityEffectAddEvent($this, $effect, $oldEffect); $ev = new EntityEffectAddEvent($this, $effect, $oldEffect);
$ev->setCancelled($cancelled); $ev->setCancelled($cancelled);
$this->server->getPluginManager()->callEvent($ev); $ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;
} }
@ -617,7 +618,8 @@ abstract class Living extends Entity implements Damageable{
} }
protected function onDeath() : void{ protected function onDeath() : void{
$this->server->getPluginManager()->callEvent($ev = new EntityDeathEvent($this, $this->getDrops())); $ev = new EntityDeathEvent($this, $this->getDrops());
$ev->call();
foreach($ev->getDrops() as $item){ foreach($ev->getDrops() as $item){
$this->getLevel()->dropItem($this, $item); $this->getLevel()->dropItem($this, $item);
} }

View File

@ -113,7 +113,8 @@ class FallingBlock extends Entity{
//FIXME: anvils are supposed to destroy torches //FIXME: anvils are supposed to destroy torches
$this->getLevel()->dropItem($this, ItemFactory::get($this->getBlock(), $this->getDamage())); $this->getLevel()->dropItem($this, ItemFactory::get($this->getBlock(), $this->getDamage()));
}else{ }else{
$this->server->getPluginManager()->callEvent($ev = new EntityBlockChangeEvent($this, $block, $blockTarget ?? $this->block)); $ev = new EntityBlockChangeEvent($this, $block, $blockTarget ?? $this->block);
$ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->getLevel()->setBlock($pos, $ev->getTo()); $this->getLevel()->setBlock($pos, $ev->getTo());
} }

View File

@ -79,7 +79,7 @@ class ItemEntity extends Entity{
} }
$this->server->getPluginManager()->callEvent(new ItemSpawnEvent($this)); (new ItemSpawnEvent($this))->call();
} }
public function entityBaseTick(int $tickDiff = 1) : bool{ public function entityBaseTick(int $tickDiff = 1) : bool{
@ -97,7 +97,8 @@ class ItemEntity extends Entity{
$this->age += $tickDiff; $this->age += $tickDiff;
if($this->age > 6000){ if($this->age > 6000){
$this->server->getPluginManager()->callEvent($ev = new ItemDespawnEvent($this)); $ev = new ItemDespawnEvent($this);
$ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->age = 0; $this->age = 0;
}else{ }else{
@ -215,7 +216,8 @@ class ItemEntity extends Entity{
return; return;
} }
$this->server->getPluginManager()->callEvent($ev = new InventoryPickupItemEvent($playerInventory, $this)); $ev = new InventoryPickupItemEvent($playerInventory, $this);
$ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
return; return;
} }

View File

@ -105,8 +105,8 @@ class PrimedTNT extends Entity implements Explosive{
} }
public function explode() : void{ public function explode() : void{
$this->server->getPluginManager()->callEvent($ev = new ExplosionPrimeEvent($this, 4)); $ev = new ExplosionPrimeEvent($this, 4);
$ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$explosion = new Explosion($this, $ev->getForce(), $this); $explosion = new Explosion($this, $ev->getForce(), $this);
if($ev->isBlockBreaking()){ if($ev->isBlockBreaking()){

View File

@ -186,7 +186,7 @@ class Arrow extends Projectile{
$ev->setCancelled(); $ev->setCancelled();
} }
$this->server->getPluginManager()->callEvent($ev); $ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
return; return;
} }

View File

@ -243,7 +243,7 @@ abstract class Projectile extends Entity{
} }
if($ev !== null){ if($ev !== null){
$this->server->getPluginManager()->callEvent($ev); $ev->call();
$this->onHit($ev); $this->onHit($ev);
if($ev instanceof ProjectileHitEntityEvent){ if($ev instanceof ProjectileHitEntityEvent){
@ -317,7 +317,7 @@ abstract class Projectile extends Entity{
if($this->fireTicks > 0){ if($this->fireTicks > 0){
$ev = new EntityCombustByEntityEvent($this, $entityHit, 5); $ev = new EntityCombustByEntityEvent($this, $entityHit, 5);
$this->server->getPluginManager()->callEvent($ev); $ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$entityHit->setOnFire($ev->getDuration()); $entityHit->setOnFire($ev->getDuration());
} }

View File

@ -27,6 +27,9 @@ declare(strict_types=1);
namespace pocketmine\event; namespace pocketmine\event;
abstract class Event{ abstract class Event{
private const MAX_EVENT_CALL_DEPTH = 50;
/** @var int */
private static $eventCallDepth = 1;
/** @var string|null */ /** @var string|null */
protected $eventName = null; protected $eventName = null;
@ -67,4 +70,38 @@ abstract class Event{
/** @var Event $this */ /** @var Event $this */
$this->isCancelled = $value; $this->isCancelled = $value;
} }
/**
* Calls event handlers registered for this event.
*
* @throws \RuntimeException if event call recursion reaches the max depth limit
*
* @throws \ReflectionException
*/
public function call() : void{
if(self::$eventCallDepth >= self::MAX_EVENT_CALL_DEPTH){
//this exception will be caught by the parent event call if all else fails
throw new \RuntimeException("Recursive event call detected (reached max depth of " . self::MAX_EVENT_CALL_DEPTH . " calls)");
}
$handlerList = HandlerList::getHandlerListFor(get_class($this));
assert($handlerList !== null, "Called event should have a valid HandlerList");
++self::$eventCallDepth;
foreach(EventPriority::ALL as $priority){
$currentList = $handlerList;
while($currentList !== null){
foreach($currentList->getListenersByPriority($priority) as $registration){
if(!$registration->getPlugin()->isEnabled()){
continue;
}
$registration->callEvent($this);
}
$currentList = $currentList->getParent();
}
}
--self::$eventCallDepth;
}
} }

View File

@ -26,7 +26,6 @@ namespace pocketmine\inventory;
use pocketmine\entity\Entity; use pocketmine\entity\Entity;
use pocketmine\event\entity\EntityArmorChangeEvent; use pocketmine\event\entity\EntityArmorChangeEvent;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\Server;
class ArmorInventoryEventProcessor implements InventoryEventProcessor{ class ArmorInventoryEventProcessor implements InventoryEventProcessor{
/** @var Entity */ /** @var Entity */
@ -37,7 +36,8 @@ class ArmorInventoryEventProcessor implements InventoryEventProcessor{
} }
public function onSlotChange(Inventory $inventory, int $slot, Item $oldItem, Item $newItem) : ?Item{ public function onSlotChange(Inventory $inventory, int $slot, Item $oldItem, Item $newItem) : ?Item{
Server::getInstance()->getPluginManager()->callEvent($ev = new EntityArmorChangeEvent($this->entity, $oldItem, $newItem, $slot)); $ev = new EntityArmorChangeEvent($this->entity, $oldItem, $newItem, $slot);
$ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
return null; return null;
} }

View File

@ -398,7 +398,8 @@ abstract class BaseInventory implements Inventory{
} }
public function open(Player $who) : bool{ public function open(Player $who) : bool{
$who->getServer()->getPluginManager()->callEvent($ev = new InventoryOpenEvent($this, $who)); $ev = new InventoryOpenEvent($this, $who);
$ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;
} }

View File

@ -26,7 +26,6 @@ namespace pocketmine\inventory;
use pocketmine\entity\Entity; use pocketmine\entity\Entity;
use pocketmine\event\entity\EntityInventoryChangeEvent; use pocketmine\event\entity\EntityInventoryChangeEvent;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\Server;
class EntityInventoryEventProcessor implements InventoryEventProcessor{ class EntityInventoryEventProcessor implements InventoryEventProcessor{
/** @var Entity */ /** @var Entity */
@ -37,7 +36,8 @@ class EntityInventoryEventProcessor implements InventoryEventProcessor{
} }
public function onSlotChange(Inventory $inventory, int $slot, Item $oldItem, Item $newItem) : ?Item{ public function onSlotChange(Inventory $inventory, int $slot, Item $oldItem, Item $newItem) : ?Item{
Server::getInstance()->getPluginManager()->callEvent($ev = new EntityInventoryChangeEvent($this->entity, $oldItem, $newItem, $slot)); $ev = new EntityInventoryChangeEvent($this->entity, $oldItem, $newItem, $slot);
$ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
return null; return null;
} }

View File

@ -134,7 +134,8 @@ class CraftingTransaction extends InventoryTransaction{
} }
protected function callExecuteEvent() : bool{ protected function callExecuteEvent() : bool{
$this->source->getServer()->getPluginManager()->callEvent($ev = new CraftItemEvent($this, $this->recipe, $this->repetitions, $this->inputs, $this->outputs)); $ev = new CraftItemEvent($this, $this->recipe, $this->repetitions, $this->inputs, $this->outputs);
$ev->call();
return !$ev->isCancelled(); return !$ev->isCancelled();
} }

View File

@ -29,7 +29,6 @@ use pocketmine\inventory\transaction\action\InventoryAction;
use pocketmine\inventory\transaction\action\SlotChangeAction; use pocketmine\inventory\transaction\action\SlotChangeAction;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\Server;
/** /**
* This InventoryTransaction only allows doing Transaction between one / two inventories * This InventoryTransaction only allows doing Transaction between one / two inventories
@ -250,7 +249,8 @@ class InventoryTransaction{
} }
protected function callExecuteEvent() : bool{ protected function callExecuteEvent() : bool{
Server::getInstance()->getPluginManager()->callEvent($ev = new InventoryTransactionEvent($this)); $ev = new InventoryTransactionEvent($this);
$ev->call();
return !$ev->isCancelled(); return !$ev->isCancelled();
} }

View File

@ -42,7 +42,8 @@ class DropItemAction extends InventoryAction{
} }
public function onPreExecute(Player $source) : bool{ public function onPreExecute(Player $source) : bool{
$source->getServer()->getPluginManager()->callEvent($ev = new PlayerDropItemEvent($source, $this->targetItem)); $ev = new PlayerDropItemEvent($source, $this->targetItem);
$ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;
} }

View File

@ -87,7 +87,7 @@ class Bow extends Tool{
$ev->setCancelled(); $ev->setCancelled();
} }
$player->getServer()->getPluginManager()->callEvent($ev); $ev->call();
$entity = $ev->getProjectile(); //This might have been changed by plugins $entity = $ev->getProjectile(); //This might have been changed by plugins
@ -104,7 +104,8 @@ class Bow extends Tool{
} }
if($entity instanceof Projectile){ if($entity instanceof Projectile){
$player->getServer()->getPluginManager()->callEvent($projectileEv = new ProjectileLaunchEvent($entity)); $projectileEv = new ProjectileLaunchEvent($entity);
$projectileEv->call();
if($projectileEv->isCancelled()){ if($projectileEv->isCancelled()){
$ev->getProjectile()->flagForDespawn(); $ev->getProjectile()->flagForDespawn();
}else{ }else{

View File

@ -59,7 +59,8 @@ class Bucket extends Item implements Consumable{
$stack->pop(); $stack->pop();
$resultItem = ItemFactory::get(Item::BUCKET, $blockClicked->getFlowingForm()->getId()); $resultItem = ItemFactory::get(Item::BUCKET, $blockClicked->getFlowingForm()->getId());
$player->getServer()->getPluginManager()->callEvent($ev = new PlayerBucketFillEvent($player, $blockReplace, $face, $this, $resultItem)); $ev = new PlayerBucketFillEvent($player, $blockReplace, $face, $this, $resultItem);
$ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$player->getLevel()->setBlock($blockClicked, BlockFactory::get(Block::AIR)); $player->getLevel()->setBlock($blockClicked, BlockFactory::get(Block::AIR));
$player->getLevel()->broadcastLevelSoundEvent($blockClicked->add(0.5, 0.5, 0.5), $blockClicked->getBucketFillSound()); $player->getLevel()->broadcastLevelSoundEvent($blockClicked->add(0.5, 0.5, 0.5), $blockClicked->getBucketFillSound());
@ -80,7 +81,8 @@ class Bucket extends Item implements Consumable{
} }
} }
}elseif($resultBlock instanceof Liquid and $blockReplace->canBeReplaced()){ }elseif($resultBlock instanceof Liquid and $blockReplace->canBeReplaced()){
$player->getServer()->getPluginManager()->callEvent($ev = new PlayerBucketEmptyEvent($player, $blockReplace, $face, $this, ItemFactory::get(Item::BUCKET))); $ev = new PlayerBucketEmptyEvent($player, $blockReplace, $face, $this, ItemFactory::get(Item::BUCKET));
$ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$player->getLevel()->setBlock($blockReplace, $resultBlock->getFlowingForm()); $player->getLevel()->setBlock($blockReplace, $resultBlock->getFlowingForm());
$player->getLevel()->broadcastLevelSoundEvent($blockClicked->add(0.5, 0.5, 0.5), $resultBlock->getBucketEmptySound()); $player->getLevel()->broadcastLevelSoundEvent($blockClicked->add(0.5, 0.5, 0.5), $resultBlock->getBucketEmptySound());

View File

@ -58,7 +58,8 @@ abstract class ProjectileItem extends Item{
$this->count--; $this->count--;
if($projectile instanceof Projectile){ if($projectile instanceof Projectile){
$player->getServer()->getPluginManager()->callEvent($projectileEv = new ProjectileLaunchEvent($projectile)); $projectileEv = new ProjectileLaunchEvent($projectile);
$projectileEv->call();
if($projectileEv->isCancelled()){ if($projectileEv->isCancelled()){
$projectile->flagForDespawn(); $projectile->flagForDespawn();
}else{ }else{

View File

@ -154,7 +154,8 @@ class Explosion{
$yield = (1 / $this->size) * 100; $yield = (1 / $this->size) * 100;
if($this->what instanceof Entity){ if($this->what instanceof Entity){
$this->level->getServer()->getPluginManager()->callEvent($ev = new EntityExplodeEvent($this->what, $this->source, $this->affectedBlocks, $yield)); $ev = new EntityExplodeEvent($this->what, $this->source, $this->affectedBlocks, $yield);
$ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;
}else{ }else{
@ -235,7 +236,8 @@ class Explosion{
continue; continue;
} }
if(!isset($this->affectedBlocks[$index = Level::blockHash($sideBlock->x, $sideBlock->y, $sideBlock->z)]) and !isset($updateBlocks[$index])){ if(!isset($this->affectedBlocks[$index = Level::blockHash($sideBlock->x, $sideBlock->y, $sideBlock->z)]) and !isset($updateBlocks[$index])){
$this->level->getServer()->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->level->getBlockAt($sideBlock->x, $sideBlock->y, $sideBlock->z))); $ev = new BlockUpdateEvent($this->level->getBlockAt($sideBlock->x, $sideBlock->y, $sideBlock->z));
$ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
foreach($this->level->getNearbyEntities(new AxisAlignedBB($sideBlock->x - 1, $sideBlock->y - 1, $sideBlock->z - 1, $sideBlock->x + 2, $sideBlock->y + 2, $sideBlock->z + 2)) as $entity){ foreach($this->level->getNearbyEntities(new AxisAlignedBB($sideBlock->x - 1, $sideBlock->y - 1, $sideBlock->z - 1, $sideBlock->x + 2, $sideBlock->y + 2, $sideBlock->z + 2)) as $entity){
$entity->onNearbyBlockChange(); $entity->onNearbyBlockChange();

View File

@ -547,7 +547,7 @@ class Level implements ChunkManager, Metadatable{
$ev->setCancelled(true); $ev->setCancelled(true);
} }
$this->server->getPluginManager()->callEvent($ev); $ev->call();
if(!$force and $ev->isCancelled()){ if(!$force and $ev->isCancelled()){
return false; return false;
@ -745,7 +745,8 @@ class Level implements ChunkManager, Metadatable{
$block = $this->getBlockAt($x, $y, $z); $block = $this->getBlockAt($x, $y, $z);
$block->clearCaches(); //for blocks like fences, force recalculation of connected AABBs $block->clearCaches(); //for blocks like fences, force recalculation of connected AABBs
$this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($block)); $ev = new BlockUpdateEvent($block);
$ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$block->onNearbyBlockChange(); $block->onNearbyBlockChange();
} }
@ -1020,7 +1021,7 @@ class Level implements ChunkManager, Metadatable{
return false; return false;
} }
$this->server->getPluginManager()->callEvent(new LevelSaveEvent($this)); (new LevelSaveEvent($this))->call();
$this->provider->getLevelData()->setTime($this->time); $this->provider->getLevelData()->setTime($this->time);
$this->saveChunks(); $this->saveChunks();
@ -1516,7 +1517,8 @@ class Level implements ChunkManager, Metadatable{
if($update){ if($update){
$this->updateAllLight($block); $this->updateAllLight($block);
$this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($block)); $ev = new BlockUpdateEvent($block);
$ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
foreach($this->getNearbyEntities(new AxisAlignedBB($block->x - 1, $block->y - 1, $block->z - 1, $block->x + 2, $block->y + 2, $block->z + 2)) as $entity){ foreach($this->getNearbyEntities(new AxisAlignedBB($block->x - 1, $block->y - 1, $block->z - 1, $block->x + 2, $block->y + 2, $block->z + 2)) as $entity){
$entity->onNearbyBlockChange(); $entity->onNearbyBlockChange();
@ -1679,7 +1681,7 @@ class Level implements ChunkManager, Metadatable{
$ev->setCancelled(!$canBreak); $ev->setCancelled(!$canBreak);
} }
$this->server->getPluginManager()->callEvent($ev); $ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;
} }
@ -1769,7 +1771,7 @@ class Level implements ChunkManager, Metadatable{
$ev->setCancelled(); //set it to cancelled so plugins can bypass this $ev->setCancelled(); //set it to cancelled so plugins can bypass this
} }
$this->server->getPluginManager()->callEvent($ev); $ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
if(!$player->isSneaking() and $blockClicked->onActivate($item, $player)){ if(!$player->isSneaking() and $blockClicked->onActivate($item, $player)){
return true; return true;
@ -1841,7 +1843,7 @@ class Level implements ChunkManager, Metadatable{
$ev->setCancelled(!$canPlace); $ev->setCancelled(!$canPlace);
} }
$this->server->getPluginManager()->callEvent($ev); $ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;
} }
@ -2288,7 +2290,7 @@ class Level implements ChunkManager, Metadatable{
$oldChunk = $this->getChunk($x, $z, false); $oldChunk = $this->getChunk($x, $z, false);
$this->setChunk($x, $z, $chunk, false); $this->setChunk($x, $z, $chunk, false);
if(($oldChunk === null or !$oldChunk->isPopulated()) and $chunk->isPopulated()){ if(($oldChunk === null or !$oldChunk->isPopulated()) and $chunk->isPopulated()){
$this->server->getPluginManager()->callEvent(new ChunkPopulateEvent($this, $chunk)); (new ChunkPopulateEvent($this, $chunk))->call();
foreach($this->getChunkLoaders($x, $z) as $loader){ foreach($this->getChunkLoaders($x, $z) as $loader){
$loader->onChunkPopulated($chunk); $loader->onChunkPopulated($chunk);
@ -2416,7 +2418,7 @@ class Level implements ChunkManager, Metadatable{
public function setSpawnLocation(Vector3 $pos){ public function setSpawnLocation(Vector3 $pos){
$previousSpawn = $this->getSpawnLocation(); $previousSpawn = $this->getSpawnLocation();
$this->provider->getLevelData()->setSpawn($pos); $this->provider->getLevelData()->setSpawn($pos);
$this->server->getPluginManager()->callEvent(new SpawnChangeEvent($this, $previousSpawn)); (new SpawnChangeEvent($this, $previousSpawn))->call();
} }
public function requestChunk(int $x, int $z, Player $player){ public function requestChunk(int $x, int $z, Player $player){
@ -2648,7 +2650,7 @@ class Level implements ChunkManager, Metadatable{
$chunk->initChunk($this); $chunk->initChunk($this);
$this->server->getPluginManager()->callEvent(new ChunkLoadEvent($this, $chunk, !$chunk->isGenerated())); (new ChunkLoadEvent($this, $chunk, !$chunk->isGenerated()))->call();
if(!$chunk->isLightPopulated() and $chunk->isPopulated() and $this->getServer()->getProperty("chunk-ticking.light-updates", false)){ if(!$chunk->isLightPopulated() and $chunk->isPopulated() and $this->getServer()->getProperty("chunk-ticking.light-updates", false)){
$this->getServer()->getAsyncPool()->submitTask(new LightPopulationTask($this, $chunk)); $this->getServer()->getAsyncPool()->submitTask(new LightPopulationTask($this, $chunk));
@ -2702,7 +2704,8 @@ class Level implements ChunkManager, Metadatable{
$chunk = $this->chunks[$chunkHash] ?? null; $chunk = $this->chunks[$chunkHash] ?? null;
if($chunk !== null){ if($chunk !== null){
$this->server->getPluginManager()->callEvent($ev = new ChunkUnloadEvent($this, $chunk)); $ev = new ChunkUnloadEvent($this, $chunk);
$ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->timings->doChunkUnload->stopTiming(); $this->timings->doChunkUnload->stopTiming();

View File

@ -41,7 +41,6 @@ use pocketmine\utils\Utils;
* Manages all the plugins * Manages all the plugins
*/ */
class PluginManager{ class PluginManager{
private const MAX_EVENT_CALL_DEPTH = 50;
/** @var Server */ /** @var Server */
private $server; private $server;
@ -64,9 +63,6 @@ class PluginManager{
*/ */
protected $fileAssociations = []; protected $fileAssociations = [];
/** @var int */
private $eventCallDepth = 0;
/** @var string|null */ /** @var string|null */
private $pluginDataDirectory; private $pluginDataDirectory;
@ -420,7 +416,7 @@ class PluginManager{
$this->enabledPlugins[$plugin->getDescription()->getName()] = $plugin; $this->enabledPlugins[$plugin->getDescription()->getName()] = $plugin;
$this->server->getPluginManager()->callEvent(new PluginEnableEvent($plugin)); (new PluginEnableEvent($plugin))->call();
}catch(\Throwable $e){ }catch(\Throwable $e){
$this->server->getLogger()->logException($e); $this->server->getLogger()->logException($e);
$this->disablePlugin($plugin); $this->disablePlugin($plugin);
@ -497,7 +493,7 @@ class PluginManager{
public function disablePlugin(Plugin $plugin){ public function disablePlugin(Plugin $plugin){
if($plugin->isEnabled()){ if($plugin->isEnabled()){
$this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.plugin.disable", [$plugin->getDescription()->getFullName()])); $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.plugin.disable", [$plugin->getDescription()->getFullName()]));
$this->callEvent(new PluginDisableEvent($plugin)); (new PluginDisableEvent($plugin))->call();
unset($this->enabledPlugins[$plugin->getDescription()->getName()]); unset($this->enabledPlugins[$plugin->getDescription()->getName()]);
@ -531,44 +527,13 @@ class PluginManager{
/** /**
* Calls an event * Calls an event
* *
* @deprecated
* @see Event::call()
*
* @param Event $event * @param Event $event
*/ */
public function callEvent(Event $event){ public function callEvent(Event $event){
if($this->eventCallDepth >= self::MAX_EVENT_CALL_DEPTH){ $event->call();
//this exception will be caught by the parent event call if all else fails
throw new \RuntimeException("Recursive event call detected (reached max depth of " . self::MAX_EVENT_CALL_DEPTH . " calls)");
}
$handlerList = HandlerList::getHandlerListFor(get_class($event));
assert($handlerList !== null, "Called event should have a valid HandlerList");
++$this->eventCallDepth;
foreach(EventPriority::ALL as $priority){
$currentList = $handlerList;
while($currentList !== null){
foreach($currentList->getListenersByPriority($priority) as $registration){
if(!$registration->getPlugin()->isEnabled()){
continue;
}
try{
$registration->callEvent($event);
}catch(\Throwable $e){
$this->server->getLogger()->critical(
$this->server->getLanguage()->translateString("pocketmine.plugin.eventError", [
$event->getEventName(),
$registration->getPlugin()->getDescription()->getFullName(),
$e->getMessage(),
get_class($registration->getListener())
]));
$this->server->getLogger()->logException($e);
}
}
$currentList = $currentList->getParent();
}
}
--$this->eventCallDepth;
} }
/** /**

View File

@ -135,8 +135,8 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{
} }
protected function checkFuel(Item $fuel){ protected function checkFuel(Item $fuel){
$this->server->getPluginManager()->callEvent($ev = new FurnaceBurnEvent($this, $fuel, $fuel->getFuelTime())); $ev = new FurnaceBurnEvent($this, $fuel, $fuel->getFuelTime());
$ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
return; return;
} }
@ -190,7 +190,8 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{
if($this->cookTime >= 200){ //10 seconds if($this->cookTime >= 200){ //10 seconds
$product = ItemFactory::get($smelt->getResult()->getId(), $smelt->getResult()->getDamage(), $product->getCount() + 1); $product = ItemFactory::get($smelt->getResult()->getId(), $smelt->getResult()->getDamage(), $product->getCount() + 1);
$this->server->getPluginManager()->callEvent($ev = new FurnaceSmeltEvent($this, $raw, $product)); $ev = new FurnaceSmeltEvent($this, $raw, $product);
$ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->inventory->setResult($ev->getResult()); $this->inventory->setResult($ev->getResult());

View File

@ -143,7 +143,7 @@ class Sign extends Spawnable{
$removeFormat = $player->getRemoveFormat(); $removeFormat = $player->getRemoveFormat();
$ev = new SignChangeEvent($this->getBlock(), $player, array_map(function(string $line) use ($removeFormat){ return TextFormat::clean($line, $removeFormat); }, $lines)); $ev = new SignChangeEvent($this->getBlock(), $player, array_map(function(string $line) use ($removeFormat){ return TextFormat::clean($line, $removeFormat); }, $lines));
$this->level->getServer()->getPluginManager()->callEvent($ev); $ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->setText(...$ev->getLines()); $this->setText(...$ev->getLines());

View File

@ -66,7 +66,7 @@ class AutoUpdater{
$this->updateInfo = $updateInfo; $this->updateInfo = $updateInfo;
$this->checkUpdate(); $this->checkUpdate();
if($this->hasUpdate()){ if($this->hasUpdate()){
$this->server->getPluginManager()->callEvent(new UpdateNotifyEvent($this)); (new UpdateNotifyEvent($this))->call();
if($this->server->getProperty("auto-updater.on-update.warn-console", true)){ if($this->server->getProperty("auto-updater.on-update.warn-console", true)){
$this->showConsoleUpdate(); $this->showConsoleUpdate();
} }

View File

@ -2,8 +2,9 @@
PHP_BINARY="php" PHP_BINARY="php"
DIR="" DIR=""
FIND="find"
while getopts "p:d:" OPTION 2> /dev/null; do while getopts "p:d:f:" OPTION 2> /dev/null; do
case ${OPTION} in case ${OPTION} in
p) p)
PHP_BINARY="$OPTARG" PHP_BINARY="$OPTARG"
@ -11,6 +12,9 @@ while getopts "p:d:" OPTION 2> /dev/null; do
d) d)
DIR="$OPTARG" DIR="$OPTARG"
;; ;;
f)
FIND="$OPTARG"
;;
esac esac
done done
@ -21,7 +25,7 @@ fi
echo Running PHP lint scans on \"$DIR\"... echo Running PHP lint scans on \"$DIR\"...
OUTPUT=`find "$DIR" -name "*.php" -print0 | xargs -0 -n1 -P4 "$PHP_BINARY" -l` OUTPUT=`$FIND "$DIR" -name "*.php" -print0 | xargs -0 -n1 -P4 "$PHP_BINARY" -l`
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo $OUTPUT | grep -v "No syntax errors" echo $OUTPUT | grep -v "No syntax errors"