Merge branch 'minor-next' into hot-events-optimisation

This commit is contained in:
Dylan K. Taylor
2023-08-01 17:01:52 +01:00
818 changed files with 38074 additions and 70531 deletions

View File

@ -35,8 +35,7 @@ abstract class Event{
private static int $eventCallDepth = 1;
/** @var string|null */
protected $eventName = null;
protected ?string $eventName = null;
final public function getEventName() : string{
return $this->eventName ?? get_class($this);

View File

@ -73,10 +73,7 @@ class HandlerList{
$this->invalidateAffectedCaches();
}
/**
* @param RegisteredListener|Listener|Plugin $object
*/
public function unregister($object) : void{
public function unregister(RegisteredListener|Plugin|Listener $object) : void{
if($object instanceof Plugin || $object instanceof Listener){
foreach($this->handlerSlots as $priority => $list){
foreach($list as $hash => $listener){
@ -87,7 +84,7 @@ class HandlerList{
}
}
}
}elseif($object instanceof RegisteredListener){
}else{
unset($this->handlerSlots[$object->getPriority()][spl_object_id($object)]);
}
$this->invalidateAffectedCaches();
@ -102,7 +99,7 @@ class HandlerList{
* @return RegisteredListener[]
*/
public function getListenersByPriority(int $priority) : array{
return $this->handlerSlots[$priority];
return $this->handlerSlots[$priority] ?? [];
}
public function getParent() : ?HandlerList{

View File

@ -40,10 +40,8 @@ class HandlerListManager{
/**
* Unregisters all the listeners
* If a Plugin or Listener is passed, all the listeners with that object will be removed
*
* @param Plugin|Listener|RegisteredListener|null $object
*/
public function unregisterAll($object = null) : void{
public function unregisterAll(RegisteredListener|Plugin|Listener|null $object = null) : void{
if($object instanceof Listener || $object instanceof Plugin || $object instanceof RegisteredListener){
foreach($this->allLists as $h){
$h->unregister($object);

View File

@ -57,8 +57,11 @@ class RegisteredListener{
return;
}
$this->timings->startTiming();
($this->handler)($event);
$this->timings->stopTiming();
try{
($this->handler)($event);
}finally{
$this->timings->stopTiming();
}
}
public function isHandlingCancelled() : bool{

View File

@ -35,30 +35,22 @@ use pocketmine\player\Player;
class BlockBreakEvent extends BlockEvent implements Cancellable{
use CancellableTrait;
/** @var Player */
protected $player;
/** @var Item */
protected $item;
/** @var bool */
protected $instaBreak = false;
/** @var Item[] */
protected $blockDrops = [];
/** @var int */
protected $xpDrops;
protected array $blockDrops = [];
/**
* @param Item[] $drops
*/
public function __construct(Player $player, Block $block, Item $item, bool $instaBreak = false, array $drops = [], int $xpDrops = 0){
public function __construct(
protected Player $player,
Block $block,
protected Item $item,
protected bool $instaBreak = false,
array $drops = [],
protected int $xpDrops = 0
){
parent::__construct($block);
$this->item = $item;
$this->player = $player;
$this->instaBreak = $instaBreak;
$this->setDrops($drops);
$this->xpDrops = $xpDrops;
}
/**

View File

@ -30,12 +30,9 @@ use pocketmine\block\Block;
use pocketmine\event\Event;
abstract class BlockEvent extends Event{
/** @var Block */
protected $block;
public function __construct(Block $block){
$this->block = $block;
}
public function __construct(
protected Block $block
){}
public function getBlock() : Block{
return $this->block;

View File

@ -23,10 +23,26 @@ declare(strict_types=1);
namespace pocketmine\event\block;
use pocketmine\block\Block;
/**
* Called when a new block forms, usually as the result of some action.
* This could be things like obsidian forming due to collision of lava and water.
*/
class BlockFormEvent extends BaseBlockChangeEvent{
public function __construct(
Block $block,
Block $newState,
private Block $causingBlock
){
parent::__construct($block, $newState);
}
/**
* Returns the block which caused the target block to form into a new state.
*/
public function getCausingBlock() : Block{
return $this->causingBlock;
}
}

View File

@ -23,9 +23,27 @@ declare(strict_types=1);
namespace pocketmine\event\block;
use pocketmine\block\Block;
use pocketmine\player\Player;
/**
* Called when plants or crops grow.
*/
class BlockGrowEvent extends BaseBlockChangeEvent{
public function __construct(
Block $block,
Block $newState,
private ?Player $player = null,
){
parent::__construct($block, $newState);
}
/**
* It returns the player which grows the crop.
* It returns null when the crop grows by itself.
*/
public function getPlayer() : ?Player{
return $this->player;
}
}

View File

@ -26,32 +26,28 @@ namespace pocketmine\event\block;
use pocketmine\block\Block;
use pocketmine\event\Cancellable;
use pocketmine\event\CancellableTrait;
use pocketmine\event\Event;
use pocketmine\item\Item;
use pocketmine\player\Player;
use pocketmine\world\BlockTransaction;
/**
* Called when a player places a block
* Called when a player initiates a block placement action.
* More than one block may be changed by a single placement action, for example when placing a door.
*/
class BlockPlaceEvent extends BlockEvent implements Cancellable{
class BlockPlaceEvent extends Event implements Cancellable{
use CancellableTrait;
/** @var Player */
protected $player;
/** @var Item */
protected $item;
/** @var Block */
protected $blockReplace;
/** @var Block */
protected $blockAgainst;
public function __construct(Player $player, Block $blockPlace, Block $blockReplace, Block $blockAgainst, Item $item){
parent::__construct($blockPlace);
$this->blockReplace = $blockReplace;
$this->blockAgainst = $blockAgainst;
$this->item = $item;
$this->player = $player;
public function __construct(
protected Player $player,
protected BlockTransaction $transaction,
protected Block $blockAgainst,
protected Item $item
){
$world = $this->blockAgainst->getPosition()->getWorld();
foreach($this->transaction->getBlocks() as [$x, $y, $z, $block]){
$block->position($world, $x, $y, $z);
}
}
/**
@ -68,8 +64,15 @@ class BlockPlaceEvent extends BlockEvent implements Cancellable{
return clone $this->item;
}
public function getBlockReplaced() : Block{
return $this->blockReplace;
/**
* Returns a BlockTransaction object containing all the block positions that will be changed by this event, and the
* states they will be changed to.
*
* This will usually contain only one block, but may contain more if the block being placed is a multi-block
* structure such as a door or bed.
*/
public function getTransaction() : BlockTransaction{
return $this->transaction;
}
public function getBlockAgainst() : Block{

View File

@ -30,6 +30,11 @@ use pocketmine\block\Block;
*/
class BlockSpreadEvent extends BaseBlockChangeEvent{
/**
* @param Block $block Block being replaced (TODO: rename this)
* @param Block $source Origin of the spread
* @param Block $newState Replacement block
*/
public function __construct(
Block $block,
private Block $source,

View File

@ -27,8 +27,7 @@ use pocketmine\block\Block;
use pocketmine\entity\Entity;
class EntityCombustByBlockEvent extends EntityCombustEvent{
/** @var Block */
protected $combuster;
protected Block $combuster;
public function __construct(Block $combuster, Entity $combustee, int $duration){
parent::__construct($combustee, $duration);

View File

@ -26,8 +26,7 @@ namespace pocketmine\event\entity;
use pocketmine\entity\Entity;
class EntityCombustByEntityEvent extends EntityCombustEvent{
/** @var Entity */
protected $combuster;
protected Entity $combuster;
public function __construct(Entity $combuster, Entity $combustee, int $duration){
parent::__construct($combustee, $duration);

View File

@ -33,8 +33,7 @@ use pocketmine\event\CancellableTrait;
class EntityCombustEvent extends EntityEvent implements Cancellable{
use CancellableTrait;
/** @var int */
protected $duration;
protected int $duration;
public function __construct(Entity $combustee, int $duration){
$this->entity = $combustee;

View File

@ -36,7 +36,15 @@ class EntityDamageByEntityEvent extends EntityDamageEvent{
/**
* @param float[] $modifiers
*/
public function __construct(Entity $damager, Entity $entity, int $cause, float $damage, array $modifiers = [], private float $knockBack = 0.4){
public function __construct(
Entity $damager,
Entity $entity,
int $cause,
float $damage,
array $modifiers = [],
private float $knockBack = Living::DEFAULT_KNOCKBACK_FORCE,
private float $verticalKnockBackLimit = Living::DEFAULT_KNOCKBACK_VERTICAL_LIMIT
){
$this->damagerEntityId = $damager->getId();
parent::__construct($entity, $cause, $damage, $modifiers);
$this->addAttackerModifiers($damager);
@ -62,11 +70,39 @@ class EntityDamageByEntityEvent extends EntityDamageEvent{
return $this->getEntity()->getWorld()->getServer()->getWorldManager()->findEntity($this->damagerEntityId);
}
/**
* Returns the force with which the victim will be knocked back from the attacking entity.
*
* @see Living::DEFAULT_KNOCKBACK_FORCE
*/
public function getKnockBack() : float{
return $this->knockBack;
}
/**
* Sets the force with which the victim will be knocked back from the attacking entity.
* Larger values will knock the victim back further.
* Negative values will pull the victim towards the attacker.
*/
public function setKnockBack(float $knockBack) : void{
$this->knockBack = $knockBack;
}
/**
* Returns the maximum upwards velocity the victim may have after being knocked back.
* This ensures that the victim doesn't fly up into the sky when high levels of knockback are applied.
*
* @see Living::DEFAULT_KNOCKBACK_VERTICAL_LIMIT
*/
public function getVerticalKnockBackLimit() : float{
return $this->verticalKnockBackLimit;
}
/**
* Sets the maximum upwards velocity the victim may have after being knocked back.
* Larger values will allow the victim to fly higher if the knockback force is also large.
*/
public function setVerticalKnockBackLimit(float $verticalKnockBackLimit) : void{
$this->verticalKnockBackLimit = $verticalKnockBackLimit;
}
}

View File

@ -46,6 +46,7 @@ class EntityDamageEvent extends EntityEvent implements Cancellable{
public const MODIFIER_TOTEM = 8;
public const MODIFIER_WEAPON_ENCHANTMENTS = 9;
public const MODIFIER_PREVIOUS_DAMAGE_COOLDOWN = 10;
public const MODIFIER_ARMOR_HELMET = 11;
public const CAUSE_CONTACT = 0;
public const CAUSE_ENTITY_ATTACK = 1;
@ -63,6 +64,7 @@ class EntityDamageEvent extends EntityEvent implements Cancellable{
public const CAUSE_MAGIC = 13;
public const CAUSE_CUSTOM = 14;
public const CAUSE_STARVATION = 15;
public const CAUSE_FALLING_BLOCK = 16;
private float $baseDamage;
private float $originalBase;

View File

@ -33,11 +33,8 @@ use pocketmine\event\Event;
* @phpstan-template TEntity of Entity
*/
abstract class EntityEvent extends Event{
/**
* @var Entity
* @phpstan-var TEntity
*/
protected $entity;
/** @phpstan-var TEntity */
protected Entity $entity;
/**
* @return Entity

View File

@ -34,34 +34,27 @@ use pocketmine\world\Position;
* Called when an entity explodes, after the explosion's impact has been calculated.
* No changes have been made to the world at this stage.
*
* @see ExplosionPrimeEvent
* @see EntityPreExplodeEvent
*
* @phpstan-extends EntityEvent<Entity>
*/
class EntityExplodeEvent extends EntityEvent implements Cancellable{
use CancellableTrait;
/** @var Position */
protected $position;
/** @var Block[] */
protected $blocks;
/** @var float */
protected $yield;
/**
* @param Block[] $blocks
* @param float $yield 0-100
*/
public function __construct(Entity $entity, Position $position, array $blocks, float $yield){
public function __construct(
Entity $entity,
protected Position $position,
protected array $blocks,
protected float $yield
){
$this->entity = $entity;
$this->position = $position;
$this->blocks = $blocks;
if($yield < 0.0 || $yield > 100.0){
throw new \InvalidArgumentException("Yield must be in range 0.0 - 100.0");
}
$this->yield = $yield;
}
public function getPosition() : Position{

View File

@ -35,30 +35,30 @@ use pocketmine\event\CancellableTrait;
*
* @phpstan-extends EntityEvent<Entity>
*/
class ExplosionPrimeEvent extends EntityEvent implements Cancellable{
class EntityPreExplodeEvent extends EntityEvent implements Cancellable{
use CancellableTrait;
/** @var float */
protected $force;
private bool $blockBreaking = true;
public function __construct(Entity $entity, float $force){
if($force <= 0){
public function __construct(
Entity $entity,
protected float $radius
){
if($radius <= 0){
throw new \InvalidArgumentException("Explosion radius must be positive");
}
$this->entity = $entity;
$this->force = $force;
}
public function getForce() : float{
return $this->force;
public function getRadius() : float{
return $this->radius;
}
public function setForce(float $force) : void{
if($force <= 0){
public function setRadius(float $radius) : void{
if($radius <= 0){
throw new \InvalidArgumentException("Explosion radius must be positive");
}
$this->force = $force;
$this->radius = $radius;
}
public function isBlockBreaking() : bool{

View File

@ -31,12 +31,9 @@ use pocketmine\inventory\Inventory;
use pocketmine\player\Player;
abstract class InventoryEvent extends Event{
/** @var Inventory */
protected $inventory;
public function __construct(Inventory $inventory){
$this->inventory = $inventory;
}
public function __construct(
protected Inventory $inventory
){}
public function getInventory() : Inventory{
return $this->inventory;

View File

@ -26,7 +26,7 @@ namespace pocketmine\event\player;
use pocketmine\command\CommandSender;
use pocketmine\event\Cancellable;
use pocketmine\event\CancellableTrait;
use pocketmine\lang\KnownTranslationKeys;
use pocketmine\player\chat\ChatFormatter;
use pocketmine\player\Player;
use pocketmine\utils\Utils;
@ -36,25 +36,16 @@ use pocketmine\utils\Utils;
class PlayerChatEvent extends PlayerEvent implements Cancellable{
use CancellableTrait;
/** @var string */
protected $message;
/** @var string */
protected $format;
/** @var CommandSender[] */
protected $recipients = [];
/**
* @param CommandSender[] $recipients
*/
public function __construct(Player $player, string $message, array $recipients, string $format = KnownTranslationKeys::CHAT_TYPE_TEXT){
public function __construct(
Player $player,
protected string $message,
protected array $recipients,
protected ChatFormatter $formatter
){
$this->player = $player;
$this->message = $message;
$this->format = $format;
$this->recipients = $recipients;
}
public function getMessage() : string{
@ -72,12 +63,12 @@ class PlayerChatEvent extends PlayerEvent implements Cancellable{
$this->player = $player;
}
public function getFormat() : string{
return $this->format;
public function getFormatter() : ChatFormatter{
return $this->formatter;
}
public function setFormat(string $format) : void{
$this->format = $format;
public function setFormatter(ChatFormatter $formatter) : void{
$this->formatter = $formatter;
}
/**

View File

@ -69,10 +69,9 @@ class PlayerCreationEvent extends Event{
/**
* Returns the base class that the final player class must extend.
*
* @return string
* @phpstan-return class-string<Player>
*/
public function getBaseClass(){
public function getBaseClass() : string{
return $this->baseClass;
}
@ -81,10 +80,9 @@ class PlayerCreationEvent extends Event{
* The new base class must be a subclass of the current base class.
* This can (perhaps) be used to limit the options for custom player classes provided by other plugins.
*
* @param string $class
* @phpstan-param class-string<Player> $class
*/
public function setBaseClass($class) : void{
public function setBaseClass(string $class) : void{
if(!is_a($class, $this->baseClass, true)){
throw new \RuntimeException("Base class $class must extend " . $this->baseClass);
}
@ -95,10 +93,9 @@ class PlayerCreationEvent extends Event{
/**
* Returns the class that will be instantiated to create the player after the event.
*
* @return string
* @phpstan-return class-string<Player>
*/
public function getPlayerClass(){
public function getPlayerClass() : string{
return $this->playerClass;
}
@ -106,10 +103,9 @@ class PlayerCreationEvent extends Event{
* Sets the class that will be instantiated to create the player after the event. The class must not be abstract,
* and must be an instance of the base class.
*
* @param string $class
* @phpstan-param class-string<Player> $class
*/
public function setPlayerClass($class) : void{
public function setPlayerClass(string $class) : void{
Utils::testValidInstance($class, $this->baseClass);
$this->playerClass = $class;
}

View File

@ -35,19 +35,11 @@ use pocketmine\player\Player;
class PlayerDataSaveEvent extends Event implements Cancellable{
use CancellableTrait;
/** @var CompoundTag */
protected $data;
/** @var string */
protected $playerName;
public function __construct(
CompoundTag $nbt,
string $playerName,
protected CompoundTag $data,
protected string $playerName,
private ?Player $player
){
$this->data = $nbt;
$this->playerName = $playerName;
}
){}
/**
* Returns the data to be written to disk as a CompoundTag

View File

@ -23,8 +23,9 @@ declare(strict_types=1);
namespace pocketmine\event\player;
use pocketmine\block\BlockLegacyIds;
use pocketmine\block\BlockTypeIds;
use pocketmine\entity\Living;
use pocketmine\entity\object\FallingBlock;
use pocketmine\event\entity\EntityDamageByBlockEvent;
use pocketmine\event\entity\EntityDamageByEntityEvent;
use pocketmine\event\entity\EntityDamageEvent;
@ -35,10 +36,10 @@ use pocketmine\lang\Translatable;
use pocketmine\player\Player;
class PlayerDeathEvent extends EntityDeathEvent{
/** @var Player */
protected $player;
protected Player $player;
private Translatable|string $deathMessage;
private Translatable|string $deathScreenMessage;
private bool $keepInventory = false;
private bool $keepXp = false;
@ -50,6 +51,7 @@ class PlayerDeathEvent extends EntityDeathEvent{
parent::__construct($entity, $drops, $xp);
$this->player = $entity;
$this->deathMessage = $deathMessage ?? self::deriveMessage($entity->getDisplayName(), $entity->getLastDamageCause());
$this->deathScreenMessage = $this->deathMessage;
}
/**
@ -71,6 +73,14 @@ class PlayerDeathEvent extends EntityDeathEvent{
$this->deathMessage = $deathMessage;
}
public function getDeathScreenMessage() : Translatable|string{
return $this->deathScreenMessage;
}
public function setDeathScreenMessage(Translatable|string $deathScreenMessage) : void{
$this->deathScreenMessage = $deathScreenMessage;
}
public function getKeepInventory() : bool{
return $this->keepInventory;
}
@ -137,7 +147,7 @@ class PlayerDeathEvent extends EntityDeathEvent{
case EntityDamageEvent::CAUSE_CONTACT:
if($deathCause instanceof EntityDamageByBlockEvent){
if($deathCause->getDamager()->getId() === BlockLegacyIds::CACTUS){
if($deathCause->getDamager()->getTypeId() === BlockTypeIds::CACTUS){
return KnownTranslationFactory::death_attack_cactus($name);
}
}
@ -156,6 +166,19 @@ class PlayerDeathEvent extends EntityDeathEvent{
case EntityDamageEvent::CAUSE_MAGIC:
return KnownTranslationFactory::death_attack_magic($name);
case EntityDamageEvent::CAUSE_FALLING_BLOCK:
if($deathCause instanceof EntityDamageByEntityEvent){
$e = $deathCause->getDamager();
if($e instanceof FallingBlock){
if($e->getBlock()->getTypeId() === BlockTypeIds::ANVIL){
return KnownTranslationFactory::death_attack_anvil($name);
}else{
return KnownTranslationFactory::death_attack_fallingBlock($name);
}
}
}
break;
case EntityDamageEvent::CAUSE_CUSTOM:
break;

View File

@ -0,0 +1,62 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\event\player;
use pocketmine\lang\Translatable;
trait PlayerDisconnectEventTrait{
/**
* Sets the kick reason shown in the server log and on the console.
*
* This should be a **short, simple, single-line** message.
* Do not use long or multi-line messages here - they will spam the log and server console with useless information.
*/
public function setDisconnectReason(Translatable|string $disconnectReason) : void{
$this->disconnectReason = $disconnectReason;
}
/**
* Returns the kick reason shown in the server log and on the console.
* When kicked by the /kick command, the default is something like "Kicked by admin.".
*/
public function getDisconnectReason() : Translatable|string{
return $this->disconnectReason;
}
/**
* Sets the message shown on the player's disconnection screen.
* This can be as long as you like, and may contain formatting and newlines.
* If this is set to null, the kick reason will be used as the disconnect screen message directly.
*/
public function setDisconnectScreenMessage(Translatable|string|null $disconnectScreenMessage) : void{
$this->disconnectScreenMessage = $disconnectScreenMessage;
}
/**
* Returns the message shown on the player's disconnection screen.
* When kicked by the /kick command, the default is something like "Kicked by admin.".
* If this is null, the kick reason will be used as the disconnect screen message directly.
*/
public function getDisconnectScreenMessage() : Translatable|string|null{ return $this->disconnectScreenMessage ?? $this->disconnectReason; }
}

View File

@ -26,6 +26,7 @@ namespace pocketmine\event\player;
use pocketmine\event\Cancellable;
use pocketmine\event\CancellableTrait;
use pocketmine\event\Event;
use pocketmine\lang\Translatable;
use pocketmine\network\mcpe\NetworkSession;
/**
@ -34,12 +35,13 @@ use pocketmine\network\mcpe\NetworkSession;
*/
class PlayerDuplicateLoginEvent extends Event implements Cancellable{
use CancellableTrait;
private string $disconnectMessage = "Logged in from another location";
use PlayerDisconnectEventTrait;
public function __construct(
private NetworkSession $connectingSession,
private NetworkSession $existingSession
private NetworkSession $existingSession,
private Translatable|string $disconnectReason,
private Translatable|string|null $disconnectScreenMessage
){}
public function getConnectingSession() : NetworkSession{
@ -49,15 +51,4 @@ class PlayerDuplicateLoginEvent extends Event implements Cancellable{
public function getExistingSession() : NetworkSession{
return $this->existingSession;
}
/**
* Returns the message shown to the session which gets disconnected.
*/
public function getDisconnectMessage() : string{
return $this->disconnectMessage;
}
public function setDisconnectMessage(string $message) : void{
$this->disconnectMessage = $message;
}
}

View File

@ -30,8 +30,7 @@ use pocketmine\event\Event;
use pocketmine\player\Player;
abstract class PlayerEvent extends Event{
/** @var Player */
protected $player;
protected Player $player;
public function getPlayer() : Player{
return $this->player;

View File

@ -46,23 +46,19 @@ class PlayerExhaustEvent extends EntityEvent implements Cancellable{
public const CAUSE_SPRINT_JUMPING = 10;
public const CAUSE_CUSTOM = 11;
/** @var Human */
protected $player;
public function __construct(
Human $human,
protected Human $human,
private float $amount,
private int $cause
){
$this->entity = $human;
$this->player = $human;
}
/**
* @return Human
*/
public function getPlayer(){
return $this->player;
return $this->human;
}
public function getAmount() : float{

View File

@ -35,9 +35,6 @@ use pocketmine\event\entity\EntityEvent;
class PlayerExperienceChangeEvent extends EntityEvent implements Cancellable{
use CancellableTrait;
/** @var Human */
protected $entity;
public function __construct(
Human $player,
private int $oldLevel,

View File

@ -34,15 +34,14 @@ use pocketmine\player\Player;
class PlayerGameModeChangeEvent extends PlayerEvent implements Cancellable{
use CancellableTrait;
/** @var GameMode */
protected $gamemode;
public function __construct(Player $player, GameMode $newGamemode){
public function __construct(
Player $player,
protected GameMode $newGamemode
){
$this->player = $player;
$this->gamemode = $newGamemode;
}
public function getNewGamemode() : GameMode{
return $this->gamemode;
return $this->newGamemode;
}
}

View File

@ -40,28 +40,18 @@ class PlayerInteractEvent extends PlayerEvent implements Cancellable{
public const LEFT_CLICK_BLOCK = 0;
public const RIGHT_CLICK_BLOCK = 1;
/** @var Block */
protected $blockTouched;
protected Vector3 $touchVector;
/** @var Vector3 */
protected $touchVector;
/** @var int */
protected $blockFace;
/** @var Item */
protected $item;
/** @var int */
protected $action;
public function __construct(Player $player, Item $item, Block $block, ?Vector3 $touchVector, int $face, int $action = PlayerInteractEvent::RIGHT_CLICK_BLOCK){
public function __construct(
Player $player,
protected Item $item,
protected Block $blockTouched,
?Vector3 $touchVector,
protected int $blockFace,
protected int $action = PlayerInteractEvent::RIGHT_CLICK_BLOCK
){
$this->player = $player;
$this->item = $item;
$this->blockTouched = $block;
$this->touchVector = $touchVector ?? Vector3::zero();
$this->blockFace = $face;
$this->action = $action;
}
public function getAction() : int{

View File

@ -34,12 +34,11 @@ use pocketmine\player\Player;
* @see PlayerLoginEvent
*/
class PlayerJoinEvent extends PlayerEvent{
/** @var string|Translatable */
protected $joinMessage;
public function __construct(Player $player, Translatable|string $joinMessage){
public function __construct(
Player $player,
protected Translatable|string $joinMessage
){
$this->player = $player;
$this->joinMessage = $joinMessage;
}
public function setJoinMessage(Translatable|string $joinMessage) : void{

View File

@ -33,34 +33,15 @@ use pocketmine\player\Player;
*/
class PlayerKickEvent extends PlayerEvent implements Cancellable{
use CancellableTrait;
use PlayerDisconnectEventTrait;
/** @var Translatable|string */
protected $quitMessage;
/** @var string */
protected $reason;
public function __construct(Player $player, string $reason, Translatable|string $quitMessage){
public function __construct(
Player $player,
protected Translatable|string $disconnectReason,
protected Translatable|string $quitMessage,
protected Translatable|string|null $disconnectScreenMessage
){
$this->player = $player;
$this->quitMessage = $quitMessage;
$this->reason = $reason;
}
/**
* Sets the message shown on the kicked player's disconnection screen.
* This message is also displayed in the console and server log.
*/
public function setReason(string $reason) : void{
$this->reason = $reason;
}
/**
* Returns the message shown on the kicked player's disconnection screen.
* This message is also displayed in the console and server log.
* When kicked by the /kick command, the default is something like "Kicked by admin.".
*/
public function getReason() : string{
return $this->reason;
}
/**

View File

@ -25,6 +25,7 @@ namespace pocketmine\event\player;
use pocketmine\event\Cancellable;
use pocketmine\event\CancellableTrait;
use pocketmine\lang\Translatable;
use pocketmine\player\Player;
/**
@ -35,19 +36,18 @@ use pocketmine\player\Player;
class PlayerLoginEvent extends PlayerEvent implements Cancellable{
use CancellableTrait;
/** @var string */
protected $kickMessage;
public function __construct(Player $player, string $kickMessage){
public function __construct(
Player $player,
protected Translatable|string $kickMessage
){
$this->player = $player;
}
public function setKickMessage(Translatable|string $kickMessage) : void{
$this->kickMessage = $kickMessage;
}
public function setKickMessage(string $kickMessage) : void{
$this->kickMessage = $kickMessage;
}
public function getKickMessage() : string{
public function getKickMessage() : Translatable|string{
return $this->kickMessage;
}
}

View File

@ -25,39 +25,15 @@ namespace pocketmine\event\player;
use pocketmine\event\Cancellable;
use pocketmine\event\CancellableTrait;
use pocketmine\event\server\CommandEvent;
use pocketmine\player\Player;
/**
* Called when a player runs a command or chats, before it is processed.
*
* If the message is prefixed with a / (forward slash), it will be interpreted as a command.
* Otherwise, it will be broadcasted as a chat message.
*
* @deprecated
* @see PlayerChatEvent to handle chat messages
* @see CommandEvent to intercept commands
* Called when a player attempts to perform the attack action (left-click) without a target entity.
*/
class PlayerCommandPreprocessEvent extends PlayerEvent implements Cancellable{
class PlayerMissSwingEvent extends PlayerEvent implements Cancellable{
use CancellableTrait;
/** @var string */
protected $message;
public function __construct(Player $player, string $message){
$this->player = $player;
$this->message = $message;
}
public function getMessage() : string{
return $this->message;
}
public function setMessage(string $message) : void{
$this->message = $message;
}
public function setPlayer(Player $player) : void{
public function __construct(Player $player){
$this->player = $player;
}
}

View File

@ -23,8 +23,8 @@ declare(strict_types=1);
namespace pocketmine\event\player;
use pocketmine\event\Cancellable;
use pocketmine\event\Event;
use pocketmine\lang\Translatable;
use pocketmine\player\PlayerInfo;
use function array_keys;
use function count;
@ -39,33 +39,30 @@ use function count;
* WARNING: Any information about the player CANNOT be trusted at this stage, because they are not authenticated and
* could be a hacker posing as another player.
*/
class PlayerPreLoginEvent extends Event implements Cancellable{
public const KICK_REASON_PLUGIN = 0;
public const KICK_REASON_SERVER_FULL = 1;
public const KICK_REASON_SERVER_WHITELISTED = 2;
public const KICK_REASON_BANNED = 3;
class PlayerPreLoginEvent extends Event{
public const KICK_FLAG_PLUGIN = 0;
public const KICK_FLAG_SERVER_FULL = 1;
public const KICK_FLAG_SERVER_WHITELISTED = 2;
public const KICK_FLAG_BANNED = 3;
public const KICK_REASON_PRIORITY = [
self::KICK_REASON_PLUGIN, //Plugin reason should always take priority over anything else
self::KICK_REASON_SERVER_FULL,
self::KICK_REASON_SERVER_WHITELISTED,
self::KICK_REASON_BANNED
public const KICK_FLAG_PRIORITY = [
self::KICK_FLAG_PLUGIN, //Plugin reason should always take priority over anything else
self::KICK_FLAG_SERVER_FULL,
self::KICK_FLAG_SERVER_WHITELISTED,
self::KICK_FLAG_BANNED
];
/** @var bool */
protected $authRequired;
/** @var string[] reason const => associated message */
protected $kickReasons = [];
/** @var Translatable[]|string[] reason const => associated message */
protected array $disconnectReasons = [];
/** @var Translatable[]|string[] */
protected array $disconnectScreenMessages = [];
public function __construct(
private PlayerInfo $playerInfo,
private string $ip,
private int $port,
bool $authRequired
){
$this->authRequired = $authRequired;
}
protected bool $authRequired
){}
/**
* Returns an object containing self-proclaimed information about the connecting player.
@ -93,27 +90,31 @@ class PlayerPreLoginEvent extends Event implements Cancellable{
}
/**
* Returns an array of kick reasons currently assigned.
* Returns an array of kick flags currently assigned.
*
* @return int[]
*/
public function getKickReasons() : array{
return array_keys($this->kickReasons);
public function getKickFlags() : array{
return array_keys($this->disconnectReasons);
}
/**
* Returns whether the given kick reason is set for this event.
* Returns whether the given kick flag is set for this event.
*/
public function isKickReasonSet(int $flag) : bool{
return isset($this->kickReasons[$flag]);
public function isKickFlagSet(int $flag) : bool{
return isset($this->disconnectReasons[$flag]);
}
/**
* Sets a reason to disallow the player to continue authenticating, with a message.
* This can also be used to change kick messages for already-set flags.
*
* @param Translatable|string $disconnectReason Shown in the server log - this should be a short one-line message
* @param Translatable|string|null $disconnectScreenMessage Shown on the player's disconnection screen (null will use the reason)
*/
public function setKickReason(int $flag, string $message) : void{
$this->kickReasons[$flag] = $message;
public function setKickFlag(int $flag, Translatable|string $disconnectReason, Translatable|string|null $disconnectScreenMessage = null) : void{
$this->disconnectReasons[$flag] = $disconnectReason;
$this->disconnectScreenMessages[$flag] = $disconnectScreenMessage ?? $disconnectReason;
}
/**
@ -122,50 +123,72 @@ class PlayerPreLoginEvent extends Event implements Cancellable{
*
* @param int $flag Specific flag to clear.
*/
public function clearKickReason(int $flag) : void{
unset($this->kickReasons[$flag]);
public function clearKickFlag(int $flag) : void{
unset($this->disconnectReasons[$flag], $this->disconnectScreenMessages[$flag]);
}
/**
* Clears all pre-assigned kick reasons, allowing the player to continue logging in.
*/
public function clearAllKickReasons() : void{
$this->kickReasons = [];
public function clearAllKickFlags() : void{
$this->disconnectReasons = [];
$this->disconnectScreenMessages = [];
}
/**
* Returns whether the player is allowed to continue logging in.
*/
public function isAllowed() : bool{
return count($this->kickReasons) === 0;
return count($this->disconnectReasons) === 0;
}
/**
* Returns the kick message provided for the given kick flag, or null if not set.
* Returns the disconnect reason provided for the given kick flag, or null if not set.
* This is the message which will be shown in the server log and on the console.
*/
public function getKickMessage(int $flag) : ?string{
return $this->kickReasons[$flag] ?? null;
public function getDisconnectReason(int $flag) : Translatable|string|null{
return $this->disconnectReasons[$flag] ?? null;
}
/**
* Returns the final kick message which will be shown on the disconnect screen.
*
* Note: Only one message (the highest priority one) will be shown. See priority order to decide how to set your
* Returns the disconnect screen message provided for the given kick flag, or null if not set.
* This is the message shown to the player on the disconnect screen.
*/
public function getDisconnectScreenMessage(int $flag) : Translatable|string|null{
return $this->disconnectScreenMessages[$flag] ?? null;
}
/**
* Resolves the message that will be shown in the server log if the player is kicked.
* Only one message (the highest priority one) will be shown. See priority order to decide how to set your
* messages.
*
* @see PlayerPreLoginEvent::KICK_REASON_PRIORITY
* @see PlayerPreLoginEvent::KICK_FLAG_PRIORITY
*/
public function getFinalKickMessage() : string{
foreach(self::KICK_REASON_PRIORITY as $p){
if(isset($this->kickReasons[$p])){
return $this->kickReasons[$p];
public function getFinalDisconnectReason() : Translatable|string{
foreach(self::KICK_FLAG_PRIORITY as $p){
if(isset($this->disconnectReasons[$p])){
return $this->disconnectReasons[$p];
}
}
return "";
}
public function isCancelled() : bool{
return !$this->isAllowed();
/**
* Resolves the message that will be shown on the player's disconnect screen if they are kicked.
* Only one message (the highest priority one) will be shown. See priority order to decide how to set your
* messages.
*
* @see PlayerPreLoginEvent::KICK_FLAG_PRIORITY
*/
public function getFinalDisconnectScreenMessage() : Translatable|string{
foreach(self::KICK_FLAG_PRIORITY as $p){
if(isset($this->disconnectScreenMessages[$p])){
return $this->disconnectScreenMessages[$p];
}
}
return "";
}
}

View File

@ -37,16 +37,12 @@ use pocketmine\player\Player;
* @see PlayerKickEvent
*/
class PlayerQuitEvent extends PlayerEvent{
/** @var Translatable|string */
protected $quitMessage;
/** @var string */
protected $quitReason;
public function __construct(Player $player, Translatable|string $quitMessage, string $quitReason){
public function __construct(
Player $player,
protected Translatable|string $quitMessage,
protected Translatable|string $quitReason
){
$this->player = $player;
$this->quitMessage = $quitMessage;
$this->quitReason = $quitReason;
}
/**
@ -66,7 +62,7 @@ class PlayerQuitEvent extends PlayerEvent{
/**
* Returns the disconnect reason shown in the server log and on the console.
*/
public function getQuitReason() : string{
public function getQuitReason() : Translatable|string{
return $this->quitReason;
}
}

View File

@ -31,12 +31,11 @@ use pocketmine\world\Position;
* Called when a player is respawned
*/
class PlayerRespawnEvent extends PlayerEvent{
/** @var Position */
protected $position;
public function __construct(Player $player, Position $position){
public function __construct(
Player $player,
protected Position $position
){
$this->player = $player;
$this->position = $position;
}
public function getRespawnPosition() : Position{

View File

@ -30,12 +30,11 @@ use pocketmine\player\Player;
class PlayerToggleFlightEvent extends PlayerEvent implements Cancellable{
use CancellableTrait;
/** @var bool */
protected $isFlying;
public function __construct(Player $player, bool $isFlying){
public function __construct(
Player $player,
protected bool $isFlying
){
$this->player = $player;
$this->isFlying = $isFlying;
}
public function isFlying() : bool{

View File

@ -30,12 +30,11 @@ use pocketmine\player\Player;
class PlayerToggleSneakEvent extends PlayerEvent implements Cancellable{
use CancellableTrait;
/** @var bool */
protected $isSneaking;
public function __construct(Player $player, bool $isSneaking){
public function __construct(
Player $player,
protected bool $isSneaking
){
$this->player = $player;
$this->isSneaking = $isSneaking;
}
public function isSneaking() : bool{

View File

@ -30,12 +30,11 @@ use pocketmine\player\Player;
class PlayerToggleSprintEvent extends PlayerEvent implements Cancellable{
use CancellableTrait;
/** @var bool */
protected $isSprinting;
public function __construct(Player $player, bool $isSprinting){
public function __construct(
Player $player,
protected bool $isSprinting
){
$this->player = $player;
$this->isSprinting = $isSprinting;
}
public function isSprinting() : bool{

View File

@ -25,6 +25,7 @@ namespace pocketmine\event\player;
use pocketmine\event\Cancellable;
use pocketmine\event\CancellableTrait;
use pocketmine\lang\Translatable;
use pocketmine\player\Player;
/**
@ -33,18 +34,13 @@ use pocketmine\player\Player;
class PlayerTransferEvent extends PlayerEvent implements Cancellable{
use CancellableTrait;
/** @var string */
protected $address;
/** @var int */
protected $port = 19132;
/** @var string */
protected $message;
public function __construct(Player $player, string $address, int $port, string $message){
public function __construct(
Player $player,
protected string $address,
protected int $port,
protected Translatable|string $message
){
$this->player = $player;
$this->address = $address;
$this->port = $port;
$this->message = $message;
}
/**
@ -78,14 +74,14 @@ class PlayerTransferEvent extends PlayerEvent implements Cancellable{
/**
* Returns the disconnect reason shown in the server log and on the console.
*/
public function getMessage() : string{
public function getMessage() : Translatable|string{
return $this->message;
}
/**
* Sets the disconnect reason shown in the server log and on the console.
*/
public function setMessage(string $message) : void{
public function setMessage(Translatable|string $message) : void{
$this->message = $message;
}
}

View File

@ -44,16 +44,10 @@ use pocketmine\event\CancellableTrait;
class CommandEvent extends ServerEvent implements Cancellable{
use CancellableTrait;
/** @var string */
protected $command;
/** @var CommandSender */
protected $sender;
public function __construct(CommandSender $sender, string $command){
$this->sender = $sender;
$this->command = $command;
}
public function __construct(
protected CommandSender $sender,
protected string $command
){}
public function getSender() : CommandSender{
return $this->sender;

View File

@ -27,6 +27,7 @@ use pocketmine\event\Cancellable;
use pocketmine\event\CancellableTrait;
use pocketmine\network\mcpe\NetworkSession;
use pocketmine\network\mcpe\protocol\ClientboundPacket;
use pocketmine\utils\Utils;
/**
* Called when packets are sent to network sessions.
@ -56,4 +57,12 @@ class DataPacketSendEvent extends ServerEvent implements Cancellable{
public function getPackets() : array{
return $this->packets;
}
/**
* @param ClientboundPacket[] $packets
*/
public function setPackets(array $packets) : void{
Utils::validateArrayValueType($packets, function(ClientboundPacket $_) : void{});
$this->packets = $packets;
}
}

View File

@ -26,12 +26,9 @@ namespace pocketmine\event\server;
use pocketmine\network\NetworkInterface;
class NetworkInterfaceEvent extends ServerEvent{
/** @var NetworkInterface */
protected $interface;
public function __construct(NetworkInterface $interface){
$this->interface = $interface;
}
public function __construct(
protected NetworkInterface $interface
){}
public function getInterface() : NetworkInterface{
return $this->interface;

View File

@ -0,0 +1,48 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\event\world;
use pocketmine\world\World;
/**
* Called when a world's display name is changed.
*/
final class WorldDisplayNameChangeEvent extends WorldEvent{
public function __construct(
World $world,
private string $oldName,
private string $newName
){
parent::__construct($world);
}
public function getOldName() : string{
return $this->oldName;
}
public function getNewName() : string{
return $this->newName;
}
}