Merge branch 'next-major' into modern-world-support

This commit is contained in:
Dylan K. Taylor 2022-05-22 16:21:48 +01:00
commit 03c505aaa7
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
33 changed files with 228 additions and 46 deletions

View File

@ -43,3 +43,35 @@ Released 16th May 2022.
- Fixed server crash when chunks are unloaded during chunk generation callbacks - Fixed server crash when chunks are unloaded during chunk generation callbacks
- Fixed dead coral fan items placing coral fans in the wrong orientation. - Fixed dead coral fan items placing coral fans in the wrong orientation.
- Fixed max stack size of boat items. - Fixed max stack size of boat items.
# 4.3.4
Released 22nd May 2022.
## Fixes
- Fixed `difficulty` in `server.properties` having no effect - it's now applied to newly generated worlds.
- Note: this setting still doesn't behave the same way as vanilla due to potential disruption to existing servers.
- Fixed paintings not working in newly generated worlds and some other cases.
- Fixed inventory window switching breaking the inventory UI in some cases (e.g. pressing E while clicking a chest).
- Fixed minecart items incorrectly stacking.
- Fixed incorrect light levels in translucent blocks at the top of the world.
- Fixed teleporting sleeping players causing broken behaviour on the sleeping player's client.
- Fixed `EntityExplodeEvent->setYield()` accepting values outside the range 0-100.
- Fixed `ExplosionPrimeEvent->setForce()` accepting negative values (later resulting in crashes).
## Documentation
- Updated documentation for the following events:
- `CommandEvent`
- `EntityDespawnEvent`
- `EntityExplodeEvent`
- `EntitySpawnEvent`
- `ExplosionPrimeEvent`
- `InventoryTransactionEvent`
- `ItemDespawnEvent`
- `ItemSpawnEvent`
- `PlayerCommandPreprocessEvent`
- `PlayerDropItemEvent`
- `PlayerItemHeldEvent`
- `PlayerKickEvent`
- `PlayerQuitEvent`
- `PlayerTransferEvent`
- `UpdateNotifyEvent`

View File

@ -1118,6 +1118,7 @@ class Server{
$creationOptions->setGeneratorClass($generatorClass); $creationOptions->setGeneratorClass($generatorClass);
$creationOptions->setGeneratorOptions($generatorOptions); $creationOptions->setGeneratorOptions($generatorOptions);
$creationOptions->setDifficulty($this->getDifficulty());
if(isset($options["difficulty"]) && is_string($options["difficulty"])){ if(isset($options["difficulty"]) && is_string($options["difficulty"])){
$creationOptions->setDifficulty(World::getDifficultyFromString($options["difficulty"])); $creationOptions->setDifficulty(World::getDifficultyFromString($options["difficulty"]));
} }
@ -1161,6 +1162,7 @@ class Server{
if($convertedSeed !== null){ if($convertedSeed !== null){
$creationOptions->setSeed($convertedSeed); $creationOptions->setSeed($convertedSeed);
} }
$creationOptions->setDifficulty($this->getDifficulty());
$this->worldManager->generateWorld($default, $creationOptions); $this->worldManager->generateWorld($default, $creationOptions);
} }

View File

@ -23,9 +23,9 @@ declare(strict_types=1);
namespace pocketmine\block\inventory; namespace pocketmine\block\inventory;
use pocketmine\block\BlockLegacyIds;
use pocketmine\inventory\SimpleInventory; use pocketmine\inventory\SimpleInventory;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\item\ItemIds;
use pocketmine\network\mcpe\protocol\BlockEventPacket; use pocketmine\network\mcpe\protocol\BlockEventPacket;
use pocketmine\network\mcpe\protocol\types\BlockPosition; use pocketmine\network\mcpe\protocol\types\BlockPosition;
use pocketmine\world\Position; use pocketmine\world\Position;
@ -50,7 +50,7 @@ class ShulkerBoxInventory extends SimpleInventory implements BlockInventory{
} }
public function canAddItem(Item $item) : bool{ public function canAddItem(Item $item) : bool{
if($item->getId() === BlockLegacyIds::UNDYED_SHULKER_BOX || $item->getId() === BlockLegacyIds::SHULKER_BOX){ if($item->getId() === ItemIds::UNDYED_SHULKER_BOX || $item->getId() === ItemIds::SHULKER_BOX){
return false; return false;
} }
return parent::canAddItem($item); return parent::canAddItem($item);

View File

@ -99,7 +99,7 @@ class GiveCommand extends VanillaCommand{
$player->getInventory()->addItem($item); $player->getInventory()->addItem($item);
Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_give_success( Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_give_success(
$item->getName() . " (" . $item->getId() . ":" . $item->getMeta() . ")", $item->getName() . " (" . $args[1] . ")",
(string) $item->getCount(), (string) $item->getCount(),
$player->getName() $player->getName()
)); ));

View File

@ -26,7 +26,9 @@ namespace pocketmine\event\entity;
use pocketmine\entity\Entity; use pocketmine\entity\Entity;
/** /**
* Called when a entity is despawned * Called when an entity is removed from the world. This could be for a variety of reasons, including chunks being
* unloaded, entity death, etc.
*
* @phpstan-extends EntityEvent<Entity> * @phpstan-extends EntityEvent<Entity>
*/ */
class EntityDespawnEvent extends EntityEvent{ class EntityDespawnEvent extends EntityEvent{

View File

@ -31,7 +31,11 @@ use pocketmine\utils\Utils;
use pocketmine\world\Position; use pocketmine\world\Position;
/** /**
* Called when a entity explodes * 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
*
* @phpstan-extends EntityEvent<Entity> * @phpstan-extends EntityEvent<Entity>
*/ */
class EntityExplodeEvent extends EntityEvent implements Cancellable{ class EntityExplodeEvent extends EntityEvent implements Cancellable{
@ -48,11 +52,15 @@ class EntityExplodeEvent extends EntityEvent implements Cancellable{
/** /**
* @param Block[] $blocks * @param Block[] $blocks
* @param float $yield 0-100
*/ */
public function __construct(Entity $entity, Position $position, array $blocks, float $yield){ public function __construct(Entity $entity, Position $position, array $blocks, float $yield){
$this->entity = $entity; $this->entity = $entity;
$this->position = $position; $this->position = $position;
$this->blocks = $blocks; $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; $this->yield = $yield;
} }
@ -61,6 +69,8 @@ class EntityExplodeEvent extends EntityEvent implements Cancellable{
} }
/** /**
* Returns a list of blocks destroyed by the explosion.
*
* @return Block[] * @return Block[]
*/ */
public function getBlockList() : array{ public function getBlockList() : array{
@ -68,6 +78,8 @@ class EntityExplodeEvent extends EntityEvent implements Cancellable{
} }
/** /**
* Sets the blocks destroyed by the explosion.
*
* @param Block[] $blocks * @param Block[] $blocks
*/ */
public function setBlockList(array $blocks) : void{ public function setBlockList(array $blocks) : void{
@ -75,11 +87,22 @@ class EntityExplodeEvent extends EntityEvent implements Cancellable{
$this->blocks = $blocks; $this->blocks = $blocks;
} }
/**
* Returns the percentage chance of drops from each block destroyed by the explosion.
* @return float 0-100
*/
public function getYield() : float{ public function getYield() : float{
return $this->yield; return $this->yield;
} }
/**
* Sets the percentage chance of drops from each block destroyed by the explosion.
* @param float $yield 0-100
*/
public function setYield(float $yield) : void{ public function setYield(float $yield) : void{
if($yield < 0.0 || $yield > 100.0){
throw new \InvalidArgumentException("Yield must be in range 0.0 - 100.0");
}
$this->yield = $yield; $this->yield = $yield;
} }
} }

View File

@ -26,7 +26,8 @@ namespace pocketmine\event\entity;
use pocketmine\entity\Entity; use pocketmine\entity\Entity;
/** /**
* Called when a entity is spawned * Called when an entity is added to the world. This might be a new entity or an entity loaded from storage.
*
* @phpstan-extends EntityEvent<Entity> * @phpstan-extends EntityEvent<Entity>
*/ */
class EntitySpawnEvent extends EntityEvent{ class EntitySpawnEvent extends EntityEvent{

View File

@ -28,7 +28,11 @@ use pocketmine\event\Cancellable;
use pocketmine\event\CancellableTrait; use pocketmine\event\CancellableTrait;
/** /**
* Called when a entity decides to explode * Called when an entity decides to explode, before the explosion's impact is calculated.
* This allows changing the force of the explosion and whether it will destroy blocks.
*
* @see EntityExplodeEvent
*
* @phpstan-extends EntityEvent<Entity> * @phpstan-extends EntityEvent<Entity>
*/ */
class ExplosionPrimeEvent extends EntityEvent implements Cancellable{ class ExplosionPrimeEvent extends EntityEvent implements Cancellable{
@ -39,6 +43,9 @@ class ExplosionPrimeEvent extends EntityEvent implements Cancellable{
private bool $blockBreaking = true; private bool $blockBreaking = true;
public function __construct(Entity $entity, float $force){ public function __construct(Entity $entity, float $force){
if($force <= 0){
throw new \InvalidArgumentException("Explosion radius must be positive");
}
$this->entity = $entity; $this->entity = $entity;
$this->force = $force; $this->force = $force;
} }
@ -48,6 +55,9 @@ class ExplosionPrimeEvent extends EntityEvent implements Cancellable{
} }
public function setForce(float $force) : void{ public function setForce(float $force) : void{
if($force <= 0){
throw new \InvalidArgumentException("Explosion radius must be positive");
}
$this->force = $force; $this->force = $force;
} }

View File

@ -28,6 +28,9 @@ use pocketmine\event\Cancellable;
use pocketmine\event\CancellableTrait; use pocketmine\event\CancellableTrait;
/** /**
* Called when a dropped item tries to despawn due to its despawn delay running out.
* Cancelling the event will reset the despawn delay to default (5 minutes).
*
* @phpstan-extends EntityEvent<ItemEntity> * @phpstan-extends EntityEvent<ItemEntity>
*/ */
class ItemDespawnEvent extends EntityEvent implements Cancellable{ class ItemDespawnEvent extends EntityEvent implements Cancellable{

View File

@ -26,6 +26,15 @@ namespace pocketmine\event\entity;
use pocketmine\entity\object\ItemEntity; use pocketmine\entity\object\ItemEntity;
/** /**
* Called when an item is spawned or loaded.
*
* Some possible reasons include:
* - item is loaded from disk
* - player dropping an item
* - block drops
* - loot of a player or entity
*
* @see PlayerDropItemEvent
* @phpstan-extends EntityEvent<ItemEntity> * @phpstan-extends EntityEvent<ItemEntity>
*/ */
class ItemSpawnEvent extends EntityEvent{ class ItemSpawnEvent extends EntityEvent{

View File

@ -29,8 +29,17 @@ use pocketmine\event\Event;
use pocketmine\inventory\transaction\InventoryTransaction; use pocketmine\inventory\transaction\InventoryTransaction;
/** /**
* Called when there is a transaction between two Inventory objects. * Called when a player performs actions involving items in inventories.
* The source of this can be a Player, entities, mobs, or even hoppers in the future! *
* This may involve multiple inventories, and may include actions such as:
* - moving items from one slot to another
* - splitting itemstacks
* - dragging itemstacks across inventory slots (slot painting)
* - dropping an item on the ground
* - taking an item from the creative inventory menu
* - destroying (trashing) an item
*
* @see https://doc.pmmp.io/en/rtfd/developer-reference/inventory-transactions.html for more information on inventory transactions
*/ */
class InventoryTransactionEvent extends Event implements Cancellable{ class InventoryTransactionEvent extends Event implements Cancellable{
use CancellableTrait; use CancellableTrait;

View File

@ -25,15 +25,18 @@ namespace pocketmine\event\player;
use pocketmine\event\Cancellable; use pocketmine\event\Cancellable;
use pocketmine\event\CancellableTrait; use pocketmine\event\CancellableTrait;
use pocketmine\event\server\CommandEvent;
use pocketmine\player\Player; use pocketmine\player\Player;
/** /**
* Called when a player runs a command or chats, early in the process * Called when a player runs a command or chats, before it is processed.
* *
* You don't want to use this except for a few cases like logging commands, * If the message is prefixed with a / (forward slash), it will be interpreted as a command.
* blocking commands on certain places, or applying modifiers. * Otherwise, it will be broadcasted as a chat message.
* *
* The message contains a slash at the start * @deprecated
* @see PlayerChatEvent to handle chat messages
* @see CommandEvent to intercept commands
*/ */
class PlayerCommandPreprocessEvent extends PlayerEvent implements Cancellable{ class PlayerCommandPreprocessEvent extends PlayerEvent implements Cancellable{
use CancellableTrait; use CancellableTrait;

View File

@ -40,6 +40,7 @@ class PlayerDeathEvent extends EntityDeathEvent{
private Translatable|string $deathMessage; private Translatable|string $deathMessage;
private bool $keepInventory = false; private bool $keepInventory = false;
private bool $keepXp = false;
/** /**
* @param Item[] $drops * @param Item[] $drops
@ -78,6 +79,14 @@ class PlayerDeathEvent extends EntityDeathEvent{
$this->keepInventory = $keepInventory; $this->keepInventory = $keepInventory;
} }
public function getKeepXp() : bool{
return $this->keepXp;
}
public function setKeepXp(bool $keepXp) : void{
$this->keepXp = $keepXp;
}
/** /**
* Returns the vanilla death message for the given death cause. * Returns the vanilla death message for the given death cause.
*/ */

View File

@ -29,7 +29,7 @@ use pocketmine\item\Item;
use pocketmine\player\Player; use pocketmine\player\Player;
/** /**
* Called when a player tries to drop an item from its hotbar * Called when a player tries to drop an item
*/ */
class PlayerDropItemEvent extends PlayerEvent implements Cancellable{ class PlayerDropItemEvent extends PlayerEvent implements Cancellable{
use CancellableTrait; use CancellableTrait;

View File

@ -28,6 +28,11 @@ use pocketmine\event\CancellableTrait;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\player\Player; use pocketmine\player\Player;
/**
* Called when a player's held item changes.
* This could be because they selected a different hotbar slot, or because the item in the selected hotbar slot was
* changed.
*/
class PlayerItemHeldEvent extends PlayerEvent implements Cancellable{ class PlayerItemHeldEvent extends PlayerEvent implements Cancellable{
use CancellableTrait; use CancellableTrait;

View File

@ -29,7 +29,7 @@ use pocketmine\lang\Translatable;
use pocketmine\player\Player; use pocketmine\player\Player;
/** /**
* Called when a player leaves the server * Called when a player is kicked (forcibly disconnected) from the server, e.g. if an operator used /kick.
*/ */
class PlayerKickEvent extends PlayerEvent implements Cancellable{ class PlayerKickEvent extends PlayerEvent implements Cancellable{
use CancellableTrait; use CancellableTrait;
@ -46,18 +46,33 @@ class PlayerKickEvent extends PlayerEvent implements Cancellable{
$this->reason = $reason; $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{ public function setReason(string $reason) : void{
$this->reason = $reason; $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{ public function getReason() : string{
return $this->reason; return $this->reason;
} }
/**
* Sets the quit message broadcasted to other players.
*/
public function setQuitMessage(Translatable|string $quitMessage) : void{ public function setQuitMessage(Translatable|string $quitMessage) : void{
$this->quitMessage = $quitMessage; $this->quitMessage = $quitMessage;
} }
/**
* Returns the quit message broadcasted to other players, e.g. "Steve left the game".
*/
public function getQuitMessage() : Translatable|string{ public function getQuitMessage() : Translatable|string{
return $this->quitMessage; return $this->quitMessage;
} }

View File

@ -27,7 +27,14 @@ use pocketmine\lang\Translatable;
use pocketmine\player\Player; use pocketmine\player\Player;
/** /**
* Called when a player leaves the server * Called when a player disconnects from the server for any reason.
*
* Some possible reasons include:
* - being kicked by an operator
* - disconnecting from the game
* - timeout due to network connectivity issues
*
* @see PlayerKickEvent
*/ */
class PlayerQuitEvent extends PlayerEvent{ class PlayerQuitEvent extends PlayerEvent{
@ -42,14 +49,23 @@ class PlayerQuitEvent extends PlayerEvent{
$this->quitReason = $quitReason; $this->quitReason = $quitReason;
} }
/**
* Sets the quit message broadcasted to other players.
*/
public function setQuitMessage(Translatable|string $quitMessage) : void{ public function setQuitMessage(Translatable|string $quitMessage) : void{
$this->quitMessage = $quitMessage; $this->quitMessage = $quitMessage;
} }
/**
* Returns the quit message broadcasted to other players, e.g. "Steve left the game".
*/
public function getQuitMessage() : Translatable|string{ public function getQuitMessage() : Translatable|string{
return $this->quitMessage; return $this->quitMessage;
} }
/**
* Returns the disconnect reason shown in the server log and on the console.
*/
public function getQuitReason() : string{ public function getQuitReason() : string{
return $this->quitReason; return $this->quitReason;
} }

View File

@ -27,6 +27,9 @@ use pocketmine\event\Cancellable;
use pocketmine\event\CancellableTrait; use pocketmine\event\CancellableTrait;
use pocketmine\player\Player; use pocketmine\player\Player;
/**
* Called when a player attempts to be transferred to another server, e.g. by using /transferserver.
*/
class PlayerTransferEvent extends PlayerEvent implements Cancellable{ class PlayerTransferEvent extends PlayerEvent implements Cancellable{
use CancellableTrait; use CancellableTrait;
@ -44,26 +47,44 @@ class PlayerTransferEvent extends PlayerEvent implements Cancellable{
$this->message = $message; $this->message = $message;
} }
/**
* Returns the destination server address. This could be an IP or a domain name.
*/
public function getAddress() : string{ public function getAddress() : string{
return $this->address; return $this->address;
} }
/**
* Sets the destination server address.
*/
public function setAddress(string $address) : void{ public function setAddress(string $address) : void{
$this->address = $address; $this->address = $address;
} }
/**
* Returns the destination server port.
*/
public function getPort() : int{ public function getPort() : int{
return $this->port; return $this->port;
} }
/**
* Sets the destination server port.
*/
public function setPort(int $port) : void{ public function setPort(int $port) : void{
$this->port = $port; $this->port = $port;
} }
/**
* Returns the disconnect reason shown in the server log and on the console.
*/
public function getMessage() : string{ public function getMessage() : string{
return $this->message; 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(string $message) : void{
$this->message = $message; $this->message = $message;
} }

View File

@ -28,12 +28,18 @@ use pocketmine\event\Cancellable;
use pocketmine\event\CancellableTrait; use pocketmine\event\CancellableTrait;
/** /**
* Called when any CommandSender runs a command, early in the process * Called when any CommandSender runs a command, before it is parsed.
* *
* You don't want to use this except for a few cases like logging commands, * This can be used for logging commands, or preprocessing the command string to add custom features (e.g. selectors).
* blocking commands on certain places, or applying modifiers.
* *
* The message DOES NOT contain a slash at the start * WARNING: DO NOT use this to block commands. Many commands have aliases.
* For example, /version can also be invoked using /ver or /about.
* To prevent command senders from using certain commands, deny them permission to use the commands you don't want them
* to have access to.
*
* @see Permissible::addAttachment()
*
* The message DOES NOT begin with a slash.
*/ */
class CommandEvent extends ServerEvent implements Cancellable{ class CommandEvent extends ServerEvent implements Cancellable{
use CancellableTrait; use CancellableTrait;

View File

@ -26,7 +26,7 @@ namespace pocketmine\event\server;
use pocketmine\updater\UpdateChecker; use pocketmine\updater\UpdateChecker;
/** /**
* Called when the AutoUpdater receives notification of an available PocketMine-MP update. * Called when the update checker receives notification of an available PocketMine-MP update.
* Plugins may use this event to perform actions when an update notification is received. * Plugins may use this event to perform actions when an update notification is received.
*/ */
class UpdateNotifyEvent extends ServerEvent{ class UpdateNotifyEvent extends ServerEvent{

View File

@ -27,7 +27,7 @@ use pocketmine\world\format\Chunk;
use pocketmine\world\World; use pocketmine\world\World;
/** /**
* Called when a Chunk is loaded * Called when a Chunk is loaded or newly created by the world generator.
*/ */
class ChunkLoadEvent extends ChunkEvent{ class ChunkLoadEvent extends ChunkEvent{
public function __construct( public function __construct(
@ -40,6 +40,10 @@ class ChunkLoadEvent extends ChunkEvent{
parent::__construct($world, $chunkX, $chunkZ, $chunk); parent::__construct($world, $chunkX, $chunkZ, $chunk);
} }
/**
* Returns whether the chunk is newly generated.
* If false, the chunk was loaded from storage.
*/
public function isNewChunk() : bool{ public function isNewChunk() : bool{
return $this->newChunk; return $this->newChunk;
} }

View File

@ -24,7 +24,8 @@ declare(strict_types=1);
namespace pocketmine\event\world; namespace pocketmine\event\world;
/** /**
* Called when a Chunk is populated (after receiving it on the main thread) * Called when a Chunk is fully populated by the world generator.
* This means that the terrain has been generated, and all artifacts (e.g. trees, grass, ponds, etc.) have been placed.
*/ */
class ChunkPopulateEvent extends ChunkEvent{ class ChunkPopulateEvent extends ChunkEvent{

View File

@ -27,7 +27,7 @@ use pocketmine\event\Cancellable;
use pocketmine\event\CancellableTrait; use pocketmine\event\CancellableTrait;
/** /**
* Called when a Chunk is unloaded * Called when a Chunk is unloaded from memory.
*/ */
class ChunkUnloadEvent extends ChunkEvent implements Cancellable{ class ChunkUnloadEvent extends ChunkEvent implements Cancellable{
use CancellableTrait; use CancellableTrait;

View File

@ -24,7 +24,7 @@ declare(strict_types=1);
namespace pocketmine\event\world; namespace pocketmine\event\world;
/** /**
* Called when a World is initializing * Called when a new world is created/generated.
*/ */
class WorldInitEvent extends WorldEvent{ class WorldInitEvent extends WorldEvent{

View File

@ -24,7 +24,7 @@ declare(strict_types=1);
namespace pocketmine\event\world; namespace pocketmine\event\world;
/** /**
* Called when a World is loaded * Called when a world is loaded or newly created/generated.
*/ */
class WorldLoadEvent extends WorldEvent{ class WorldLoadEvent extends WorldEvent{

View File

@ -24,7 +24,7 @@ declare(strict_types=1);
namespace pocketmine\event\world; namespace pocketmine\event\world;
/** /**
* Called when a World is saved * Called when a world is saved. Saving may be triggered manually (e.g. via commands) or automatically (autosave).
*/ */
class WorldSaveEvent extends WorldEvent{ class WorldSaveEvent extends WorldEvent{

View File

@ -27,7 +27,7 @@ use pocketmine\event\Cancellable;
use pocketmine\event\CancellableTrait; use pocketmine\event\CancellableTrait;
/** /**
* Called when a World is unloaded * Called when a world is unloaded from memory.
*/ */
class WorldUnloadEvent extends WorldEvent implements Cancellable{ class WorldUnloadEvent extends WorldEvent implements Cancellable{
use CancellableTrait; use CancellableTrait;

View File

@ -148,7 +148,7 @@ class InventoryTransaction{
try{ try{
$action->validate($this->source); $action->validate($this->source);
}catch(TransactionValidationException $e){ }catch(TransactionValidationException $e){
throw new TransactionValidationException(get_class($action) . ": " . $e->getMessage(), 0, $e); throw new TransactionValidationException(get_class($action) . "#" . spl_object_id($action) . ": " . $e->getMessage(), 0, $e);
} }
if(!$action->getSourceItem()->isNull()){ if(!$action->getSourceItem()->isNull()){

View File

@ -713,6 +713,7 @@ class NetworkSession{
} }
public function onServerRespawn() : void{ public function onServerRespawn() : void{
$this->syncAttributes($this->player, $this->player->getAttributeMap()->getAll());
$this->player->sendData(null); $this->player->sendData(null);
$this->syncAdventureSettings($this->player); $this->syncAdventureSettings($this->player);

View File

@ -33,6 +33,7 @@ use pocketmine\data\java\GameModeIdMap;
use pocketmine\entity\animation\Animation; use pocketmine\entity\animation\Animation;
use pocketmine\entity\animation\ArmSwingAnimation; use pocketmine\entity\animation\ArmSwingAnimation;
use pocketmine\entity\animation\CriticalHitAnimation; use pocketmine\entity\animation\CriticalHitAnimation;
use pocketmine\entity\Attribute;
use pocketmine\entity\effect\VanillaEffects; use pocketmine\entity\effect\VanillaEffects;
use pocketmine\entity\Entity; use pocketmine\entity\Entity;
use pocketmine\entity\Human; use pocketmine\entity\Human;
@ -2223,8 +2224,10 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
} }
} }
if(!$ev->getKeepXp()){
$this->getWorld()->dropExperience($this->location, $ev->getXpDropAmount()); $this->getWorld()->dropExperience($this->location, $ev->getXpDropAmount());
$this->xpManager->setXpAndProgress(0, 0.0); $this->xpManager->setXpAndProgress(0, 0.0);
}
if($ev->getDeathMessage() != ""){ if($ev->getDeathMessage() != ""){
$this->server->broadcastMessage($ev->getDeathMessage()); $this->server->broadcastMessage($ev->getDeathMessage());
@ -2285,6 +2288,9 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
$this->setHealth($this->getMaxHealth()); $this->setHealth($this->getMaxHealth());
foreach($this->attributeMap->getAll() as $attr){ foreach($this->attributeMap->getAll() as $attr){
if($attr->getId() === Attribute::EXPERIENCE || $attr->getId() === Attribute::EXPERIENCE_LEVEL){ //we have already reset both of those if needed when the player died
continue;
}
$attr->resetToDefault(); $attr->resetToDefault();
} }
@ -2373,6 +2379,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
if(parent::teleport($pos, $yaw, $pitch)){ if(parent::teleport($pos, $yaw, $pitch)){
$this->removeCurrentWindow(); $this->removeCurrentWindow();
$this->stopSleep();
$this->sendPosition($this->location, $this->location->yaw, $this->location->pitch, MovePlayerPacket::MODE_TELEPORT); $this->sendPosition($this->location, $this->location->yaw, $this->location->pitch, MovePlayerPacket::MODE_TELEPORT);
$this->broadcastMovement(true); $this->broadcastMovement(true);
@ -2384,7 +2391,6 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
if($this->spawnChunkLoadCount !== -1){ if($this->spawnChunkLoadCount !== -1){
$this->spawnChunkLoadCount = 0; $this->spawnChunkLoadCount = 0;
} }
$this->stopSleep();
$this->blockBreakHandler = null; $this->blockBreakHandler = null;
//TODO: workaround for player last pos not getting updated //TODO: workaround for player last pos not getting updated
@ -2496,14 +2502,14 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
public function removeCurrentWindow() : void{ public function removeCurrentWindow() : void{
$this->doCloseInventory(); $this->doCloseInventory();
if($this->currentWindow !== null){ if($this->currentWindow !== null){
(new InventoryCloseEvent($this->currentWindow, $this))->call(); $currentWindow = $this->currentWindow;
$this->logger->debug("Closing inventory " . get_class($this->currentWindow) . "#" . spl_object_id($this->currentWindow)); $this->logger->debug("Closing inventory " . get_class($this->currentWindow) . "#" . spl_object_id($this->currentWindow));
$this->currentWindow->onClose($this); $this->currentWindow->onClose($this);
if(($inventoryManager = $this->getNetworkSession()->getInvManager()) !== null){ if(($inventoryManager = $this->getNetworkSession()->getInvManager()) !== null){
$inventoryManager->onCurrentWindowRemove(); $inventoryManager->onCurrentWindowRemove();
} }
$this->currentWindow = null; $this->currentWindow = null;
(new InventoryCloseEvent($currentWindow, $this))->call();
} }
} }

View File

@ -42,6 +42,7 @@ use pocketmine\world\utils\SubChunkExplorer;
use pocketmine\world\utils\SubChunkExplorerStatus; use pocketmine\world\utils\SubChunkExplorerStatus;
use function ceil; use function ceil;
use function floor; use function floor;
use function min;
use function mt_rand; use function mt_rand;
use function sqrt; use function sqrt;
@ -90,9 +91,6 @@ class Explosion{
$blockFactory = BlockFactory::getInstance(); $blockFactory = BlockFactory::getInstance();
$currentChunk = null;
$currentSubChunk = null;
$mRays = $this->rays - 1; $mRays = $this->rays - 1;
for($i = 0; $i < $this->rays; ++$i){ for($i = 0; $i < $this->rays; ++$i){
for($j = 0; $j < $this->rays; ++$j){ for($j = 0; $j < $this->rays; ++$j){
@ -151,10 +149,8 @@ class Explosion{
* and creating sounds and particles. * and creating sounds and particles.
*/ */
public function explodeB() : bool{ public function explodeB() : bool{
$updateBlocks = [];
$source = (new Vector3($this->source->x, $this->source->y, $this->source->z))->floor(); $source = (new Vector3($this->source->x, $this->source->y, $this->source->z))->floor();
$yield = (1 / $this->size) * 100; $yield = min(100, (1 / $this->size) * 100);
if($this->what instanceof Entity){ if($this->what instanceof Entity){
$ev = new EntityExplodeEvent($this->what, $this->source, $this->affectedBlocks, $yield); $ev = new EntityExplodeEvent($this->what, $this->source, $this->affectedBlocks, $yield);

View File

@ -116,6 +116,9 @@ abstract class LightUpdate{
$context->removalQueue->enqueue([$x, $y, $z, $oldLevel]); $context->removalQueue->enqueue([$x, $y, $z, $oldLevel]);
} }
} }
}elseif($this->getEffectiveLight($x, $y, $z) > 0){ //outside the chunk (e.g. virtual sky light from y=256)
$context->spreadVisited[$blockHash] = true;
$context->spreadQueue->enqueue([$x, $y, $z]);
} }
} }
return $context; return $context;

View File

@ -635,6 +635,11 @@ parameters:
count: 1 count: 1
path: ../../../src/network/mcpe/NetworkSession.php path: ../../../src/network/mcpe/NetworkSession.php
-
message: "#^Cannot call method getAttributeMap\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#"
count: 1
path: ../../../src/network/mcpe/NetworkSession.php
- -
message: "#^Cannot call method getLanguage\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#" message: "#^Cannot call method getLanguage\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#"
count: 1 count: 1
@ -690,6 +695,11 @@ parameters:
count: 1 count: 1
path: ../../../src/network/mcpe/NetworkSession.php path: ../../../src/network/mcpe/NetworkSession.php
-
message: "#^Parameter \\#1 \\$entity of method pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\:\\:syncAttributes\\(\\) expects pocketmine\\\\entity\\\\Living, pocketmine\\\\player\\\\Player\\|null given\\.$#"
count: 1
path: ../../../src/network/mcpe/NetworkSession.php
- -
message: "#^Parameter \\#1 \\$for of method pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\:\\:syncAdventureSettings\\(\\) expects pocketmine\\\\player\\\\Player, pocketmine\\\\player\\\\Player\\|null given\\.$#" message: "#^Parameter \\#1 \\$for of method pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\:\\:syncAdventureSettings\\(\\) expects pocketmine\\\\player\\\\Player, pocketmine\\\\player\\\\Player\\|null given\\.$#"
count: 2 count: 2
@ -970,11 +980,6 @@ parameters:
count: 1 count: 1
path: ../../../src/utils/Utils.php path: ../../../src/utils/Utils.php
-
message: "#^Parameter \\#2 \\$array of function array_map expects array, mixed given\\.$#"
count: 1
path: ../../../src/utils/Utils.php
- -
message: "#^Cannot call method getFullBlock\\(\\) on pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" message: "#^Cannot call method getFullBlock\\(\\) on pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#"
count: 1 count: 1