From ec5598dbb179d3e3eea303c650772206f369b565 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 12 Oct 2018 16:35:51 +0100 Subject: [PATCH 1/5] Deprecate things removed in acb794e72 and 97c836f19 --- src/pocketmine/event/entity/EntityDespawnEvent.php | 6 ++++++ src/pocketmine/event/entity/EntitySpawnEvent.php | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/src/pocketmine/event/entity/EntityDespawnEvent.php b/src/pocketmine/event/entity/EntityDespawnEvent.php index 0f456e360..e5d239c39 100644 --- a/src/pocketmine/event/entity/EntityDespawnEvent.php +++ b/src/pocketmine/event/entity/EntityDespawnEvent.php @@ -46,6 +46,7 @@ class EntityDespawnEvent extends EntityEvent{ } /** + * @deprecated * @return int */ public function getType() : int{ @@ -53,6 +54,7 @@ class EntityDespawnEvent extends EntityEvent{ } /** + * @deprecated * @return bool */ public function isCreature() : bool{ @@ -60,6 +62,7 @@ class EntityDespawnEvent extends EntityEvent{ } /** + * @deprecated * @return bool */ public function isHuman() : bool{ @@ -67,6 +70,7 @@ class EntityDespawnEvent extends EntityEvent{ } /** + * @deprecated * @return bool */ public function isProjectile() : bool{ @@ -74,6 +78,7 @@ class EntityDespawnEvent extends EntityEvent{ } /** + * @deprecated * @return bool */ public function isVehicle() : bool{ @@ -81,6 +86,7 @@ class EntityDespawnEvent extends EntityEvent{ } /** + * @deprecated * @return bool */ public function isItem() : bool{ diff --git a/src/pocketmine/event/entity/EntitySpawnEvent.php b/src/pocketmine/event/entity/EntitySpawnEvent.php index 20a068b87..fe1f800ae 100644 --- a/src/pocketmine/event/entity/EntitySpawnEvent.php +++ b/src/pocketmine/event/entity/EntitySpawnEvent.php @@ -47,6 +47,7 @@ class EntitySpawnEvent extends EntityEvent{ } /** + * @deprecated * @return Position */ public function getPosition() : Position{ @@ -54,6 +55,7 @@ class EntitySpawnEvent extends EntityEvent{ } /** + * @deprecated * @return int */ public function getType() : int{ @@ -61,6 +63,7 @@ class EntitySpawnEvent extends EntityEvent{ } /** + * @deprecated * @return bool */ public function isCreature() : bool{ @@ -68,6 +71,7 @@ class EntitySpawnEvent extends EntityEvent{ } /** + * @deprecated * @return bool */ public function isHuman() : bool{ @@ -75,6 +79,7 @@ class EntitySpawnEvent extends EntityEvent{ } /** + * @deprecated * @return bool */ public function isProjectile() : bool{ @@ -82,6 +87,7 @@ class EntitySpawnEvent extends EntityEvent{ } /** + * @deprecated * @return bool */ public function isVehicle() : bool{ @@ -89,6 +95,7 @@ class EntitySpawnEvent extends EntityEvent{ } /** + * @deprecated * @return bool */ public function isItem() : bool{ From 60b183b0d925e91aa6ab8bdc5c3d9904242bf95c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 Mar 2019 17:42:41 +0000 Subject: [PATCH 2/5] backport a753c1342: Clean up Query cache handling, remove useless timeouts the timeout was entirely useless, because: - when shorter than 25.6 seconds (512 ticks) it would cause caches to be needlessly destroyed and regenerated - when longer than 25.6 seconds, just made outdated caches persist for longer, even after the query info was regenerated. This now uses a mark-dirty model to deal with caches, which means that plugin modifications to the query data will be reflected immediately, regardless of when they are made. Previously, modifying the result of Server->getQueryInformation() would have inconsistent results. --- src/pocketmine/Server.php | 7 +--- .../event/server/QueryRegenerateEvent.php | 38 ++++++++++++++----- src/pocketmine/network/query/QueryHandler.php | 24 +++--------- 3 files changed, 36 insertions(+), 33 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 0d2d56cdf..851da3290 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1719,7 +1719,7 @@ class Server{ register_shutdown_function([$this, "crashDump"]); - $this->queryRegenerateTask = new QueryRegenerateEvent($this, 5); + $this->queryRegenerateTask = new QueryRegenerateEvent($this); $this->pluginManager->loadPlugins($this->pluginPath); @@ -2591,10 +2591,7 @@ class Server{ } if(($this->tickCounter & 0b111111111) === 0){ - ($this->queryRegenerateTask = new QueryRegenerateEvent($this, 5))->call(); - if($this->queryHandler !== null){ - $this->queryHandler->regenerateInfo(); - } + ($this->queryRegenerateTask = new QueryRegenerateEvent($this))->call(); } if($this->autoSave and ++$this->autoSaveTicker >= $this->autoSaveTicks){ diff --git a/src/pocketmine/event/server/QueryRegenerateEvent.php b/src/pocketmine/event/server/QueryRegenerateEvent.php index beef6b987..811622af0 100644 --- a/src/pocketmine/event/server/QueryRegenerateEvent.php +++ b/src/pocketmine/event/server/QueryRegenerateEvent.php @@ -35,8 +35,6 @@ use function substr; class QueryRegenerateEvent extends ServerEvent{ public const GAME_ID = "MINECRAFTPE"; - /** @var int */ - private $timeout; /** @var string */ private $serverName; /** @var bool */ @@ -68,13 +66,16 @@ class QueryRegenerateEvent extends ServerEvent{ /** @var array */ private $extraData = []; + /** @var string|null */ + private $longQueryCache = null; + /** @var string|null */ + private $shortQueryCache = null; + /** * @param Server $server - * @param int $timeout */ - public function __construct(Server $server, int $timeout = 5){ - $this->timeout = $timeout; + public function __construct(Server $server){ $this->serverName = $server->getMotd(); $this->listPlugins = $server->getProperty("settings.query-plugins", true); $this->plugins = $server->getPluginManager()->getPlugins(); @@ -98,19 +99,25 @@ class QueryRegenerateEvent extends ServerEvent{ } /** - * Gets the min. timeout for Query Regeneration + * @deprecated * * @return int */ public function getTimeout() : int{ - return $this->timeout; + return 0; } /** + * @deprecated * @param int $timeout */ public function setTimeout(int $timeout) : void{ - $this->timeout = $timeout; + + } + + private function destroyCache() : void{ + $this->longQueryCache = null; + $this->shortQueryCache = null; } /** @@ -125,6 +132,7 @@ class QueryRegenerateEvent extends ServerEvent{ */ public function setServerName(string $serverName) : void{ $this->serverName = $serverName; + $this->destroyCache(); } /** @@ -139,6 +147,7 @@ class QueryRegenerateEvent extends ServerEvent{ */ public function setListPlugins(bool $value) : void{ $this->listPlugins = $value; + $this->destroyCache(); } /** @@ -153,6 +162,7 @@ class QueryRegenerateEvent extends ServerEvent{ */ public function setPlugins(array $plugins) : void{ $this->plugins = $plugins; + $this->destroyCache(); } /** @@ -167,6 +177,7 @@ class QueryRegenerateEvent extends ServerEvent{ */ public function setPlayerList(array $players) : void{ $this->players = $players; + $this->destroyCache(); } /** @@ -181,6 +192,7 @@ class QueryRegenerateEvent extends ServerEvent{ */ public function setPlayerCount(int $count) : void{ $this->numPlayers = $count; + $this->destroyCache(); } /** @@ -195,6 +207,7 @@ class QueryRegenerateEvent extends ServerEvent{ */ public function setMaxPlayerCount(int $count) : void{ $this->maxPlayers = $count; + $this->destroyCache(); } /** @@ -209,6 +222,7 @@ class QueryRegenerateEvent extends ServerEvent{ */ public function setWorld(string $world) : void{ $this->map = $world; + $this->destroyCache(); } /** @@ -225,12 +239,16 @@ class QueryRegenerateEvent extends ServerEvent{ */ public function setExtraData(array $extraData) : void{ $this->extraData = $extraData; + $this->destroyCache(); } /** * @return string */ public function getLongQuery() : string{ + if($this->longQueryCache !== null){ + return $this->longQueryCache; + } $query = ""; $plist = $this->server_engine; @@ -273,13 +291,13 @@ class QueryRegenerateEvent extends ServerEvent{ } $query .= "\x00"; - return $query; + return $this->longQueryCache = $query; } /** * @return string */ public function getShortQuery() : string{ - return $this->serverName . "\x00" . $this->gametype . "\x00" . $this->map . "\x00" . $this->numPlayers . "\x00" . $this->maxPlayers . "\x00" . Binary::writeLShort($this->port) . $this->ip . "\x00"; + return $this->shortQueryCache ?? ($this->shortQueryCache = $this->serverName . "\x00" . $this->gametype . "\x00" . $this->map . "\x00" . $this->numPlayers . "\x00" . $this->maxPlayers . "\x00" . Binary::writeLShort($this->port) . $this->ip . "\x00"); } } diff --git a/src/pocketmine/network/query/QueryHandler.php b/src/pocketmine/network/query/QueryHandler.php index 2788d7907..73125866b 100644 --- a/src/pocketmine/network/query/QueryHandler.php +++ b/src/pocketmine/network/query/QueryHandler.php @@ -33,7 +33,6 @@ use pocketmine\utils\Binary; use function base64_encode; use function chr; use function hash; -use function microtime; use function ord; use function random_bytes; use function strlen; @@ -46,12 +45,6 @@ class QueryHandler{ private $lastToken; /** @var string */ private $token; - /** @var string */ - private $longData; - /** @var string */ - private $shortData; - /** @var float */ - private $timeout; public const HANDSHAKE = 9; public const STATISTICS = 0; @@ -73,7 +66,6 @@ class QueryHandler{ $this->regenerateToken(); $this->lastToken = $this->token; - $this->regenerateInfo(); $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.server.query.running", [$addr, $port])); } @@ -82,11 +74,11 @@ class QueryHandler{ $this->server->getLogger()->debug("[Query] $message"); } + /** + * @deprecated + */ public function regenerateInfo(){ - $ev = $this->server->getQueryInformation(); - $this->longData = $ev->getLongQuery(); - $this->shortData = $ev->getShortQuery(); - $this->timeout = microtime(true) + $ev->getTimeout(); + } public function regenerateToken(){ @@ -122,14 +114,10 @@ class QueryHandler{ $reply = chr(self::STATISTICS); $reply .= Binary::writeInt($sessionID); - if($this->timeout < microtime(true)){ - $this->regenerateInfo(); - } - if(strlen($payload) === 8){ - $reply .= $this->longData; + $reply .= $this->server->getQueryInformation()->getLongQuery(); }else{ - $reply .= $this->shortData; + $reply .= $this->server->getQueryInformation()->getShortQuery(); } $interface->sendRawPacket($address, $port, $reply); break; From 0ca07ad0755980d51c186ec4b3873ebecf9bd250 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 16 Jun 2019 16:17:06 +0100 Subject: [PATCH 3/5] Fire QueryRegenerateEvent every 1 second instead of every 25, fixes #2670 --- src/pocketmine/Server.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 851da3290..06497fde0 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -2586,14 +2586,12 @@ class Server{ $this->currentTPS = 20; $this->currentUse = 0; + ($this->queryRegenerateTask = new QueryRegenerateEvent($this))->call(); + $this->network->updateName(); $this->network->resetStatistics(); } - if(($this->tickCounter & 0b111111111) === 0){ - ($this->queryRegenerateTask = new QueryRegenerateEvent($this))->call(); - } - if($this->autoSave and ++$this->autoSaveTicker >= $this->autoSaveTicks){ $this->autoSaveTicker = 0; $this->getLogger()->debug("[Auto Save] Saving worlds..."); From 0fabc0c1990f1b7cd9718a96c9594db4d953dd5a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 Mar 2019 19:53:14 +0000 Subject: [PATCH 4/5] backport b8d1eb20b: EntityDeathEvent: add XP amount API, closes #2690 --- src/pocketmine/Player.php | 5 ++-- src/pocketmine/entity/Living.php | 5 ++-- .../event/entity/EntityDeathEvent.php | 26 ++++++++++++++++++- .../event/player/PlayerDeathEvent.php | 5 ++-- 4 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 8aeb09f79..c722aba87 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -3665,7 +3665,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ //main inventory and drops the rest on the ground. $this->doCloseInventory(); - $ev = new PlayerDeathEvent($this, $this->getDrops()); + $ev = new PlayerDeathEvent($this, $this->getDrops(), null, $this->getXpDropAmount()); $ev->call(); if(!$ev->getKeepInventory()){ @@ -3682,8 +3682,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } } - //TODO: allow this number to be manipulated during PlayerDeathEvent - $this->level->dropExperience($this, $this->getXpDropAmount()); + $this->level->dropExperience($this, $ev->getXpDropAmount()); $this->setXpAndProgress(0, 0); if($ev->getDeathMessage() != ""){ diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index c9030152f..9e0b428af 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -639,15 +639,14 @@ abstract class Living extends Entity implements Damageable{ } protected function onDeath() : void{ - $ev = new EntityDeathEvent($this, $this->getDrops()); + $ev = new EntityDeathEvent($this, $this->getDrops(), $this->getXpDropAmount()); $ev->call(); foreach($ev->getDrops() as $item){ $this->getLevel()->dropItem($this, $item); } //TODO: check death conditions (must have been damaged by player < 5 seconds from death) - //TODO: allow this number to be manipulated during EntityDeathEvent - $this->level->dropExperience($this, $this->getXpDropAmount()); + $this->level->dropExperience($this, $ev->getXpDropAmount()); } protected function onDeathUpdate(int $tickDiff) : bool{ diff --git a/src/pocketmine/event/entity/EntityDeathEvent.php b/src/pocketmine/event/entity/EntityDeathEvent.php index c4ca6111d..aeb7e5574 100644 --- a/src/pocketmine/event/entity/EntityDeathEvent.php +++ b/src/pocketmine/event/entity/EntityDeathEvent.php @@ -29,14 +29,18 @@ use pocketmine\item\Item; class EntityDeathEvent extends EntityEvent{ /** @var Item[] */ private $drops = []; + /** @var int */ + private $xp; /** * @param Living $entity * @param Item[] $drops + * @param int $xp */ - public function __construct(Living $entity, array $drops = []){ + public function __construct(Living $entity, array $drops = [], int $xp = 0){ $this->entity = $entity; $this->drops = $drops; + $this->xp = $xp; } /** @@ -59,4 +63,24 @@ class EntityDeathEvent extends EntityEvent{ public function setDrops(array $drops) : void{ $this->drops = $drops; } + + /** + * Returns how much experience is dropped due to this entity's death. + * @return int + */ + public function getXpDropAmount() : int{ + return $this->xp; + } + + /** + * @param int $xp + * + * @throws \InvalidArgumentException + */ + public function setXpDropAmount(int $xp) : void{ + if($xp < 0){ + throw new \InvalidArgumentException("XP drop amount must not be negative"); + } + $this->xp = $xp; + } } diff --git a/src/pocketmine/event/player/PlayerDeathEvent.php b/src/pocketmine/event/player/PlayerDeathEvent.php index fa93a8ae2..25e8d12ca 100644 --- a/src/pocketmine/event/player/PlayerDeathEvent.php +++ b/src/pocketmine/event/player/PlayerDeathEvent.php @@ -46,9 +46,10 @@ class PlayerDeathEvent extends EntityDeathEvent{ * @param Player $entity * @param Item[] $drops * @param string|TextContainer|null $deathMessage Null will cause the default vanilla message to be used + * @param int $xp */ - public function __construct(Player $entity, array $drops, $deathMessage = null){ - parent::__construct($entity, $drops); + public function __construct(Player $entity, array $drops, $deathMessage = null, int $xp = 0){ + parent::__construct($entity, $drops, $xp); $this->deathMessage = $deathMessage ?? self::deriveMessage($entity->getDisplayName(), $entity->getLastDamageCause()); } From b38c81c96ff3a3b8d5735eb53b9abcb9c9e17ca2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 22 Mar 2019 18:11:32 +0000 Subject: [PATCH 5/5] backport f84a1729c: Inventory: added swap() function --- src/pocketmine/inventory/BaseInventory.php | 7 +++++++ src/pocketmine/inventory/Inventory.php | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index 6f32492fc..bc6f7dcfb 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -378,6 +378,13 @@ abstract class BaseInventory implements Inventory{ } } + public function swap(int $slot1, int $slot2) : void{ + $i1 = $this->getItem($slot1); + $i2 = $this->getItem($slot2); + $this->setItem($slot1, $i2); + $this->setItem($slot2, $i1); + } + /** * @return Player[] */ diff --git a/src/pocketmine/inventory/Inventory.php b/src/pocketmine/inventory/Inventory.php index 94677a75e..1bf84060f 100644 --- a/src/pocketmine/inventory/Inventory.php +++ b/src/pocketmine/inventory/Inventory.php @@ -215,6 +215,14 @@ interface Inventory{ */ public function clearAll(bool $send = true) : void; + /** + * Swaps the specified slots. + * + * @param int $slot1 + * @param int $slot2 + */ + public function swap(int $slot1, int $slot2) : void; + /** * Gets all the Players viewing the inventory * Players will view their inventory at all times, even when not open.