From 1d338bfdf9828bb28953f01d77002f65f2dfcbc1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 2 Sep 2017 19:28:51 +0100 Subject: [PATCH 01/14] Fixed uncaught exceptions during Task->onCancel() causing all kinds of nasty behaviour including crashing the server on shutdown, preventing self-cancellation, and causing memory leaks --- src/pocketmine/scheduler/TaskHandler.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/scheduler/TaskHandler.php b/src/pocketmine/scheduler/TaskHandler.php index 8e04778b70..bb1f5212d4 100644 --- a/src/pocketmine/scheduler/TaskHandler.php +++ b/src/pocketmine/scheduler/TaskHandler.php @@ -25,6 +25,7 @@ namespace pocketmine\scheduler; use pocketmine\event\Timings; use pocketmine\event\TimingsHandler; +use pocketmine\utils\MainLogger; class TaskHandler{ @@ -136,10 +137,15 @@ class TaskHandler{ * Changes to this function won't be recorded on the version. */ public function cancel(){ - if(!$this->isCancelled()){ - $this->task->onCancel(); + try{ + if(!$this->isCancelled()){ + $this->task->onCancel(); + } + }catch(\Throwable $e){ + MainLogger::getLogger()->logException($e); + }finally{ + $this->remove(); } - $this->remove(); } public function remove(){ From 0b83c61494d4d73808f751aea63ee686de81c646 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Sep 2017 11:24:34 +0100 Subject: [PATCH 02/14] Fixed cyclic reference with chest tiles and DoubleChestInventory --- src/pocketmine/inventory/DoubleChestInventory.php | 5 +++++ src/pocketmine/tile/Chest.php | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/inventory/DoubleChestInventory.php b/src/pocketmine/inventory/DoubleChestInventory.php index 3b68ef8899..e588de9dc6 100644 --- a/src/pocketmine/inventory/DoubleChestInventory.php +++ b/src/pocketmine/inventory/DoubleChestInventory.php @@ -139,4 +139,9 @@ class DoubleChestInventory extends ChestInventory implements InventoryHolder{ public function getRightSide() : ChestInventory{ return $this->right; } + + public function invalidate(){ + $this->left = null; + $this->right = null; + } } diff --git a/src/pocketmine/tile/Chest.php b/src/pocketmine/tile/Chest.php index fc3e472f3f..edce48f0a8 100644 --- a/src/pocketmine/tile/Chest.php +++ b/src/pocketmine/tile/Chest.php @@ -67,8 +67,12 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{ $player->removeWindow($this->getRealInventory()); } + if($this->doubleInventory !== null){ + $this->doubleInventory->invalidate(); + $this->doubleInventory = null; + } + $this->inventory = null; - $this->doubleInventory = null; parent::close(); } From 41780fd19529c1e955f0182e3aaf3242cc6bb13d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Sep 2017 11:50:15 +0100 Subject: [PATCH 03/14] Made entity collision checks for block placement more logical and less wasteful We don't care how many entities collide, only that a non-zero number collided. --- src/pocketmine/level/Level.php | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index f8607c6cc2..2019662f78 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1743,26 +1743,22 @@ class Level implements ChunkManager, Metadatable{ if($hand->isSolid() === true and $hand->getBoundingBox() !== null){ $entities = $this->getCollidingEntities($hand->getBoundingBox()); - $realCount = 0; foreach($entities as $e){ if($e instanceof Arrow or $e instanceof DroppedItem){ continue; } - ++$realCount; + + return false; //Entity in block } if($player !== null){ if(($diff = $player->getNextPosition()->subtract($player->getPosition())) and $diff->lengthSquared() > 0.00001){ $bb = $player->getBoundingBox()->getOffsetBoundingBox($diff->x, $diff->y, $diff->z); if($hand->getBoundingBox()->intersectsWith($bb)){ - ++$realCount; + return false; //Inside player BB } } } - - if($realCount > 0){ - return false; //Entity in block - } } From 4df261b75a41be3c317403ea1344dde2e77c72bd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Sep 2017 12:00:24 +0100 Subject: [PATCH 04/14] Made some variable names in Bucket less confusing --- src/pocketmine/item/Bucket.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/pocketmine/item/Bucket.php b/src/pocketmine/item/Bucket.php index 489c6d1c25..9b44144420 100644 --- a/src/pocketmine/item/Bucket.php +++ b/src/pocketmine/item/Bucket.php @@ -51,13 +51,13 @@ class Bucket extends Item{ } public function onActivate(Level $level, Player $player, Block $block, Block $target, int $face, Vector3 $facePos) : bool{ - $targetBlock = BlockFactory::get($this->meta); + $resultBlock = BlockFactory::get($this->meta); - if($targetBlock instanceof Air){ + if($resultBlock instanceof Air){ if($target instanceof Liquid and $target->getDamage() === 0){ - $result = clone $this; - $result->setDamage($target->getId()); - $player->getServer()->getPluginManager()->callEvent($ev = new PlayerBucketFillEvent($player, $block, $face, $this, $result)); + $resultItem = clone $this; + $resultItem->setDamage($target->getId()); + $player->getServer()->getPluginManager()->callEvent($ev = new PlayerBucketFillEvent($player, $block, $face, $this, $resultItem)); if(!$ev->isCancelled()){ $player->getLevel()->setBlock($target, BlockFactory::get(Block::AIR), true, true); if($player->isSurvival()){ @@ -68,12 +68,12 @@ class Bucket extends Item{ $player->getInventory()->sendContents($player); } } - }elseif($targetBlock instanceof Liquid){ - $result = clone $this; - $result->setDamage(0); - $player->getServer()->getPluginManager()->callEvent($ev = new PlayerBucketEmptyEvent($player, $block, $face, $this, $result)); + }elseif($resultBlock instanceof Liquid){ + $resultItem = clone $this; + $resultItem->setDamage(0); + $player->getServer()->getPluginManager()->callEvent($ev = new PlayerBucketEmptyEvent($player, $block, $face, $this, $resultItem)); if(!$ev->isCancelled()){ - $player->getLevel()->setBlock($block, $targetBlock, true, true); + $player->getLevel()->setBlock($block, $resultBlock, true, true); if($player->isSurvival()){ $player->getInventory()->setItemInHand($ev->getItem()); } From 89f55674765ab134d0e68bdb95eb7233b03e18fe Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Sep 2017 12:08:40 +0100 Subject: [PATCH 05/14] Use Entity->getDirectionVector() more --- src/pocketmine/Player.php | 6 +----- src/pocketmine/item/Bow.php | 8 +++++--- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 5cb528a028..3e07ebaea7 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2376,11 +2376,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->level->sendBlocks([$this], [$target, $block], UpdateBlockPacket::FLAG_ALL_PRIORITY); return true; }elseif($packet->face === -1){ - $directionVector = new Vector3( - -sin($this->yaw / 180 * M_PI) * cos($this->pitch / 180 * M_PI), - -sin($this->pitch / 180 * M_PI), - cos($this->yaw / 180 * M_PI) * cos($this->pitch / 180 * M_PI) - ); + $directionVector = $this->getDirectionVector(); if($this->isCreative()){ $item = $this->inventory->getItemInHand(); diff --git a/src/pocketmine/item/Bow.php b/src/pocketmine/item/Bow.php index 08313b9c2c..5ff357c7f3 100644 --- a/src/pocketmine/item/Bow.php +++ b/src/pocketmine/item/Bow.php @@ -54,6 +54,8 @@ class Bow extends Tool{ return false; } + $directionVector = $player->getDirectionVector(); + $nbt = new CompoundTag("", [ new ListTag("Pos", [ new DoubleTag("", $player->x), @@ -61,9 +63,9 @@ class Bow extends Tool{ new DoubleTag("", $player->z) ]), new ListTag("Motion", [ - new DoubleTag("", -sin($player->yaw / 180 * M_PI) * cos($player->pitch / 180 * M_PI)), - new DoubleTag("", -sin($player->pitch / 180 * M_PI)), - new DoubleTag("", cos($player->yaw / 180 * M_PI) * cos($player->pitch / 180 * M_PI)) + new DoubleTag("", $directionVector->x), + new DoubleTag("", $directionVector->y), + new DoubleTag("", $directionVector->z) ]), new ListTag("Rotation", [ //yaw/pitch for arrows taken crosswise, not along the arrow shaft. From 7483f22e8b470ff8ebab890897dc1747ddb565d1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Sep 2017 12:10:56 +0100 Subject: [PATCH 06/14] Fixed a PhpStorm inspection --- src/pocketmine/entity/Entity.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index dae3ed5c62..b8d13fb7a1 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -205,6 +205,7 @@ abstract class Entity extends Location implements Metadatable{ public static $entityCount = 1; /** @var Entity[] */ private static $knownEntities = []; + /** @var string[] */ private static $shortNames = []; public static function init(){ From aa9fd1b4f95c1bc8b4d3b174f63b058d57963205 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Sep 2017 12:22:37 +0100 Subject: [PATCH 07/14] Remove redundant gamemode checks The caller will check the player's gamemode, so there is no use for these checks. --- src/pocketmine/block/Sapling.php | 5 ++--- src/pocketmine/block/Sugarcane.php | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/block/Sapling.php b/src/pocketmine/block/Sapling.php index 9597a6d966..e29faebbbe 100644 --- a/src/pocketmine/block/Sapling.php +++ b/src/pocketmine/block/Sapling.php @@ -76,9 +76,8 @@ class Sapling extends Flowable{ if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal //TODO: change log type Tree::growTree($this->getLevel(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->meta & 0x07); - if(($player->gamemode & 0x01) === 0){ - $item->count--; - } + + $item->count--; return true; } diff --git a/src/pocketmine/block/Sugarcane.php b/src/pocketmine/block/Sugarcane.php index 6512fbd4a8..09280ce3cc 100644 --- a/src/pocketmine/block/Sugarcane.php +++ b/src/pocketmine/block/Sugarcane.php @@ -64,9 +64,8 @@ class Sugarcane extends Flowable{ $this->meta = 0; $this->getLevel()->setBlock($this, $this, true); } - if(($player->gamemode & 0x01) === 0){ - $item->count--; - } + + $item->count--; return true; } From cb7911ee9c5f1ed305583d996c28ad21b1f63ce2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 30 Apr 2017 19:29:10 +0100 Subject: [PATCH 08/14] Improved Absorption, now only applies to living entities, now controllable by plugins --- src/pocketmine/entity/Entity.php | 24 +------------------ src/pocketmine/entity/Living.php | 6 ++++- .../event/entity/EntityDamageEvent.php | 1 + 3 files changed, 7 insertions(+), 24 deletions(-) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index b8d13fb7a1..1f71de95f8 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -892,21 +892,7 @@ abstract class Entity extends Location implements Metadatable{ $this->setLastDamageCause($source); - $damage = $source->getFinalDamage(); - - $absorption = $this->getAbsorption(); - if($absorption > 0){ - if($absorption > $damage){ - //Use absorption health before normal health. - $this->setAbsorption($absorption - $damage); - $damage = 0; - }else{ - $this->setAbsorption(0); - $damage -= $absorption; - } - } - - $this->setHealth($this->getHealth() - $damage); + $this->setHealth($this->getHealth() - $source->getFinalDamage()); } /** @@ -953,14 +939,6 @@ abstract class Entity extends Location implements Metadatable{ } } - public function getAbsorption() : float{ - return 0; - } - - public function setAbsorption(float $absorption){ - - } - /** * @param EntityDamageEvent $type */ diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 8c4d01b19a..3cde9874e1 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -342,8 +342,10 @@ abstract class Living extends Entity implements Damageable{ $source->setCancelled(); } + $source->setDamage(-min($this->getAbsorption(), $source->getFinalDamage()), EntityDamageEvent::MODIFIER_ABSORPTION); + if($this->hasEffect(Effect::DAMAGE_RESISTANCE)){ - $source->setDamage(-($source->getDamage(EntityDamageEvent::MODIFIER_BASE) * 0.20 * $this->getEffect(Effect::DAMAGE_RESISTANCE)->getEffectLevel()), EntityDamageEvent::MODIFIER_RESISTANCE); + $source->setDamage(-($source->getFinalDamage() * 0.20 * $this->getEffect(Effect::DAMAGE_RESISTANCE)->getEffectLevel()), EntityDamageEvent::MODIFIER_RESISTANCE); } parent::attack($source); @@ -369,6 +371,8 @@ abstract class Living extends Entity implements Damageable{ } } + $this->setAbsorption(max(0, $this->getAbsorption() + $source->getDamage(EntityDamageEvent::MODIFIER_ABSORPTION))); + $pk = new EntityEventPacket(); $pk->entityRuntimeId = $this->getId(); $pk->event = $this->getHealth() <= 0 ? EntityEventPacket::DEATH_ANIMATION : EntityEventPacket::HURT_ANIMATION; //Ouch! diff --git a/src/pocketmine/event/entity/EntityDamageEvent.php b/src/pocketmine/event/entity/EntityDamageEvent.php index 836ed2feca..4194f425e4 100644 --- a/src/pocketmine/event/entity/EntityDamageEvent.php +++ b/src/pocketmine/event/entity/EntityDamageEvent.php @@ -37,6 +37,7 @@ class EntityDamageEvent extends EntityEvent implements Cancellable{ const MODIFIER_STRENGTH = 2; const MODIFIER_WEAKNESS = 3; const MODIFIER_RESISTANCE = 4; + const MODIFIER_ABSORPTION = 5; const CAUSE_CONTACT = 0; const CAUSE_ENTITY_ATTACK = 1; From 58bf5d6679a2ce53c455e7ebb31de9402668190e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Sep 2017 12:48:57 +0100 Subject: [PATCH 09/14] Use null coalesce in EntityDamageEvent --- src/pocketmine/event/entity/EntityDamageEvent.php | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/pocketmine/event/entity/EntityDamageEvent.php b/src/pocketmine/event/entity/EntityDamageEvent.php index 4194f425e4..0be966f2c5 100644 --- a/src/pocketmine/event/entity/EntityDamageEvent.php +++ b/src/pocketmine/event/entity/EntityDamageEvent.php @@ -100,11 +100,7 @@ class EntityDamageEvent extends EntityEvent implements Cancellable{ * @return float */ public function getOriginalDamage(int $type = self::MODIFIER_BASE) : float{ - if(isset($this->originals[$type])){ - return $this->originals[$type]; - } - - return 0.0; + return $this->originals[$type] ?? 0.0; } /** @@ -113,11 +109,7 @@ class EntityDamageEvent extends EntityEvent implements Cancellable{ * @return float */ public function getDamage(int $type = self::MODIFIER_BASE) : float{ - if(isset($this->modifiers[$type])){ - return $this->modifiers[$type]; - } - - return 0.0; + return $this->modifiers[$type] ?? 0.0; } /** From bb9299070de34255e75806cfb681b0cbbea9f5c5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Sep 2017 13:08:27 +0100 Subject: [PATCH 10/14] Fixed several Cake bugs fixed cake flat-out doesn't work fixed last slice of cake vanishing (NOOOOO) fixed EntityEatBlockEvent not getting called made AABB calculation less confusing --- src/pocketmine/block/Cake.php | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/pocketmine/block/Cake.php b/src/pocketmine/block/Cake.php index 65ef590400..0cce711f19 100644 --- a/src/pocketmine/block/Cake.php +++ b/src/pocketmine/block/Cake.php @@ -50,10 +50,10 @@ class Cake extends Transparent implements FoodSource{ protected function recalculateBoundingBox(){ - $f = (1 + $this->getDamage() * 2) / 16; + $f = $this->getDamage() * 0.125; //1 slice width return new AxisAlignedBB( - $this->x + $f, + $this->x + 0.0625 + $f, $this->y, $this->z + 0.0625, $this->x + 1 - 0.0625, @@ -90,10 +90,17 @@ class Cake extends Transparent implements FoodSource{ } public function onActivate(Item $item, Player $player = null) : bool{ - if($player instanceof Player and $player->getHealth() < $player->getMaxHealth()){ - $ev = new EntityEatBlockEvent($player, $this); + //TODO: refactor this into generic food handling + if($player instanceof Player and $player->getFood() < $player->getMaxFood()){ + $player->getServer()->getPluginManager()->callEvent($ev = new EntityEatBlockEvent($player, $this)); if(!$ev->isCancelled()){ + $player->addFood($ev->getFoodRestore()); + $player->addSaturation($ev->getSaturationRestore()); + foreach($ev->getAdditionalEffects() as $effect){ + $player->addEffect($effect); + } + $this->getLevel()->setBlock($this, $ev->getResidue()); return true; } @@ -113,7 +120,7 @@ class Cake extends Transparent implements FoodSource{ public function getResidue(){ $clone = clone $this; $clone->meta++; - if($clone->meta >= 0x06){ + if($clone->meta > 0x06){ $clone = BlockFactory::get(Block::AIR); } return $clone; From 2398e2450ab45749b4c21de9de877c0464cecc9d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Sep 2017 13:47:44 +0100 Subject: [PATCH 11/14] Allow building inside spectators This check is pretty ugly, it'll need cleaning up later. For now, this will suffice. --- src/pocketmine/level/Level.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 2019662f78..781c568e94 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1744,7 +1744,7 @@ class Level implements ChunkManager, Metadatable{ if($hand->isSolid() === true and $hand->getBoundingBox() !== null){ $entities = $this->getCollidingEntities($hand->getBoundingBox()); foreach($entities as $e){ - if($e instanceof Arrow or $e instanceof DroppedItem){ + if($e instanceof Arrow or $e instanceof DroppedItem or ($e instanceof Player and $e->isSpectator())){ continue; } From 90cb3c010f848874524cf4f4db6dc29bf31bd8aa Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Sep 2017 14:24:21 +0100 Subject: [PATCH 12/14] Added some new items (the basic ones) --- src/pocketmine/item/BlazeRod.php | 36 +++++++++++++++++++++++++++++ src/pocketmine/item/ItemFactory.php | 12 +++++----- 2 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 src/pocketmine/item/BlazeRod.php diff --git a/src/pocketmine/item/BlazeRod.php b/src/pocketmine/item/BlazeRod.php new file mode 100644 index 0000000000..ae7298c4be --- /dev/null +++ b/src/pocketmine/item/BlazeRod.php @@ -0,0 +1,36 @@ + Date: Sun, 3 Sep 2017 14:27:17 +0100 Subject: [PATCH 13/14] fuel time should be ticks here, not seconds --- src/pocketmine/item/BlazeRod.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/item/BlazeRod.php b/src/pocketmine/item/BlazeRod.php index ae7298c4be..d4fa6e0ba7 100644 --- a/src/pocketmine/item/BlazeRod.php +++ b/src/pocketmine/item/BlazeRod.php @@ -30,7 +30,7 @@ class BlazeRod extends Item{ } public function getFuelTime() : int{ - return 120; + return 2400; } } \ No newline at end of file From 815c697767595048e8d1368ae9519c913ad7fc7d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Sep 2017 14:59:04 +0100 Subject: [PATCH 14/14] Fixed sticks being useless as furnace fuel --- src/pocketmine/item/Stick.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/item/Stick.php b/src/pocketmine/item/Stick.php index a3ff64e950..f5a2163267 100644 --- a/src/pocketmine/item/Stick.php +++ b/src/pocketmine/item/Stick.php @@ -30,7 +30,7 @@ class Stick extends Item{ } public function getFuelTime() : int{ - return 5; + return 100; } } \ No newline at end of file