Merge branch 'stable' into minor-next

This commit is contained in:
Dylan K. Taylor 2023-04-14 20:12:33 +01:00
commit 84cb070d56
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
10 changed files with 101 additions and 58 deletions

View File

@ -75,3 +75,22 @@ It works similarly to the `ChunkLoader` system, in that chunks will be ticked as
- The following API methods have been added:
- `public World->registerTickingChunk(ChunkTicker $ticker, int $chunkX, int $chunkZ) : void` - registers a chunk to be ticked by the given `ChunkTicker`
- `public World->unregisterTickingChunk(ChunkTicker $ticker, int $chunkX, int $chunkZ) : void` - unregisters a chunk from being ticked by the given `ChunkTicker`
# 4.19.1
Released 14th April 2023.
## Fixes
- Fixed inventory rollbacks when spreading items in ender chests.
- Fixed inventory rollbacks when shift-clicking to craft and the outputs would have been split across multiple inventory slots.
- Fixed incorrect spawn terrain generation for newly created worlds.
- Fixed `chunk-ticking.tick-radius` not disabling chunk ticking when set to `0`.
- Fixed chunks not being ticked if they previously left a player's simulation distance without leaving their view distance.
- Fixed height of collision boxes for Grass Path and Farmland blocks.
# 4.19.2
Released 14th April 2023.
## Fixes
- Fixed player timings duplication leading to extremely large timings reports when timings runs for a long time with many players.
- Packet timings are now indexed by class FQN instead of packet ID. This prevents erroneous timer reuse on packet ID reuse (e.g. multi version servers).
- Fixed entity timings being shared by different classes with the same short name. This led to incorrect timings being reported for some entities when custom entities were used.

View File

@ -56,7 +56,7 @@
"webmozart/path-util": "^2.3"
},
"require-dev": {
"phpstan/phpstan": "1.10.11",
"phpstan/phpstan": "1.10.13",
"phpstan/phpstan-phpunit": "^1.1.0",
"phpstan/phpstan-strict-rules": "^1.2.0",
"phpunit/phpunit": "^9.2"

24
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "6cd5185a409af08d842a5e41ba3b877b",
"content-hash": "d819da2b086b38c4dd2a5028084e251c",
"packages": [
{
"name": "adhocore/json-comment",
@ -1884,16 +1884,16 @@
},
{
"name": "phpstan/phpstan",
"version": "1.10.11",
"version": "1.10.13",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan.git",
"reference": "8aa62e6ea8b58ffb650e02940e55a788cbc3fe21"
"reference": "f07bf8c6980b81bf9e49d44bd0caf2e737614a70"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/8aa62e6ea8b58ffb650e02940e55a788cbc3fe21",
"reference": "8aa62e6ea8b58ffb650e02940e55a788cbc3fe21",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/f07bf8c6980b81bf9e49d44bd0caf2e737614a70",
"reference": "f07bf8c6980b81bf9e49d44bd0caf2e737614a70",
"shasum": ""
},
"require": {
@ -1942,7 +1942,7 @@
"type": "tidelift"
}
],
"time": "2023-04-04T19:17:42+00:00"
"time": "2023-04-12T19:29:52+00:00"
},
{
"name": "phpstan/phpstan-phpunit",
@ -2365,16 +2365,16 @@
},
{
"name": "phpunit/phpunit",
"version": "9.6.6",
"version": "9.6.7",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "b65d59a059d3004a040c16a82e07bbdf6cfdd115"
"reference": "c993f0d3b0489ffc42ee2fe0bd645af1538a63b2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b65d59a059d3004a040c16a82e07bbdf6cfdd115",
"reference": "b65d59a059d3004a040c16a82e07bbdf6cfdd115",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c993f0d3b0489ffc42ee2fe0bd645af1538a63b2",
"reference": "c993f0d3b0489ffc42ee2fe0bd645af1538a63b2",
"shasum": ""
},
"require": {
@ -2448,7 +2448,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.6"
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.7"
},
"funding": [
{
@ -2464,7 +2464,7 @@
"type": "tidelift"
}
],
"time": "2023-03-27T11:43:46+00:00"
"time": "2023-04-14T08:58:40+00:00"
},
{
"name": "sebastian/cli-parser",

View File

@ -31,7 +31,7 @@ use function str_repeat;
final class VersionInfo{
public const NAME = "PocketMine-MP";
public const BASE_VERSION = "4.19.1";
public const BASE_VERSION = "4.19.3";
public const IS_DEVELOPMENT_BUILD = true;
public const BUILD_CHANNEL = "stable";

View File

@ -64,7 +64,7 @@ class Farmland extends Transparent{
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
return [AxisAlignedBB::one()]; //TODO: this should be trimmed at the top by 1/16, but MCPE currently treats them as a full block (https://bugs.mojang.com/browse/MCPE-12109)
return [AxisAlignedBB::one()->trim(Facing::UP, 1 / 16)];
}
public function onNearbyBlockChange() : void{

View File

@ -33,7 +33,7 @@ class GrassPath extends Transparent{
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
return [AxisAlignedBB::one()]; //TODO: this should be trimmed at the top by 1/16, but MCPE currently treats them as a full block (https://bugs.mojang.com/browse/MCPE-12109)
return [AxisAlignedBB::one()->trim(Facing::UP, 1 / 16)];
}
public function onNearbyBlockChange() : void{

View File

@ -167,7 +167,7 @@ class TimingsCommand extends VanillaCommand{
Command::broadcastCommandMessage($sender, KnownTranslationFactory::pocketmine_command_timings_timingsRead(
"https://" . $host . "/?id=" . $response["id"]));
}else{
$sender->getServer()->getLogger()->debug("Invalid response from timings server: " . $result->getBody());
$sender->getServer()->getLogger()->debug("Invalid response from timings server (" . $result->getCode() . "): " . $result->getBody());
Command::broadcastCommandMessage($sender, KnownTranslationFactory::pocketmine_command_timings_pasteError());
}
}

View File

@ -894,6 +894,31 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
}
}
/**
* @param true[] $oldTickingChunks
* @param true[] $newTickingChunks
*
* @phpstan-param array<int, true> $oldTickingChunks
* @phpstan-param array<int, true> $newTickingChunks
*/
private function updateTickingChunkRegistrations(array $oldTickingChunks, array $newTickingChunks) : void{
$world = $this->getWorld();
foreach($oldTickingChunks as $hash => $_){
if(!isset($newTickingChunks[$hash]) && !isset($this->loadQueue[$hash])){
//we are (probably) still using this chunk, but it's no longer within ticking range
World::getXZ($hash, $tickingChunkX, $tickingChunkZ);
$world->unregisterTickingChunk($this->chunkTicker, $tickingChunkX, $tickingChunkZ);
}
}
foreach($newTickingChunks as $hash => $_){
if(!isset($oldTickingChunks[$hash]) && !isset($this->loadQueue[$hash])){
//we were already using this chunk, but it is now within ticking range
World::getXZ($hash, $tickingChunkX, $tickingChunkZ);
$world->registerTickingChunk($this->chunkTicker, $tickingChunkX, $tickingChunkZ);
}
}
}
/**
* Calculates which new chunks this player needs to use, and which currently-used chunks it needs to stop using.
* This is based on factors including the player's current render radius and current position.
@ -930,15 +955,10 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
World::getXZ($index, $X, $Z);
$this->unloadChunk($X, $Z);
}
foreach($this->tickingChunks as $hash => $_){
//any chunks we encounter here are still used by the player, but may no longer be within ticking range
if(!isset($tickingChunks[$hash]) && !isset($newOrder[$hash])){
World::getXZ($hash, $tickingChunkX, $tickingChunkZ);
$world->unregisterTickingChunk($this->chunkTicker, $tickingChunkX, $tickingChunkZ);
}
}
$this->loadQueue = $newOrder;
$this->updateTickingChunkRegistrations($this->tickingChunks, $tickingChunks);
$this->tickingChunks = $tickingChunks;
if(count($this->loadQueue) > 0 || count($unloadChunks) > 0){

View File

@ -250,42 +250,54 @@ abstract class Timings{
return self::$pluginTaskTimingMap[$name];
}
/**
* @phpstan-template T of object
* @phpstan-param class-string<T> $class
*/
private static function shortenCoreClassName(string $class, string $prefix) : string{
if(str_starts_with($class, $prefix)){
return (new \ReflectionClass($class))->getShortName();
}
return $class;
}
public static function getEntityTimings(Entity $entity) : TimingsHandler{
$reflect = new \ReflectionClass($entity);
$entityType = $reflect->getShortName();
if(!isset(self::$entityTypeTimingMap[$entityType])){
//the timings viewer calculates average player count by looking at this timer, so we need to ensure it has
//a name it can identify. However, we also want to make it obvious if this is a custom Player class.
if($entity instanceof Player && $reflect->getName() !== Player::class){
$entityType = "Player (" . $reflect->getName() . ")";
if(!isset(self::$entityTypeTimingMap[$entity::class])){
if($entity instanceof Player){
//the timings viewer calculates average player count by looking at this timer, so we need to ensure it has
//a name it can identify. However, we also want to make it obvious if this is a custom Player class.
$displayName = $entity::class !== Player::class ? "Player (" . $entity::class . ")" : "Player";
}else{
$displayName = self::shortenCoreClassName($entity::class, "pocketmine\\entity\\");
}
self::$entityTypeTimingMap[$entityType] = new TimingsHandler("Entity Tick - " . $entityType, self::$tickEntity, group: self::GROUP_BREAKDOWN);
self::$entityTypeTimingMap[$entity::class] = new TimingsHandler("Entity Tick - " . $displayName, self::$tickEntity, group: self::GROUP_BREAKDOWN);
}
return self::$entityTypeTimingMap[$entityType];
return self::$entityTypeTimingMap[$entity::class];
}
public static function getTileEntityTimings(Tile $tile) : TimingsHandler{
$tileType = (new \ReflectionClass($tile))->getShortName();
if(!isset(self::$tileEntityTypeTimingMap[$tileType])){
self::$tileEntityTypeTimingMap[$tileType] = new TimingsHandler("Block Entity Tick - " . $tileType, self::$tickTileEntity, group: self::GROUP_BREAKDOWN);
if(!isset(self::$tileEntityTypeTimingMap[$tile::class])){
self::$tileEntityTypeTimingMap[$tile::class] = new TimingsHandler(
"Block Entity Tick - " . self::shortenCoreClassName($tile::class, "pocketmine\\block\\tile\\"),
self::$tickTileEntity,
group: self::GROUP_BREAKDOWN
);
}
return self::$tileEntityTypeTimingMap[$tileType];
return self::$tileEntityTypeTimingMap[$tile::class];
}
public static function getReceiveDataPacketTimings(ServerboundPacket $pk) : TimingsHandler{
$pid = $pk->pid();
if(!isset(self::$packetReceiveTimingMap[$pid])){
self::$packetReceiveTimingMap[$pid] = new TimingsHandler("Receive - " . $pk->getName(), self::$playerNetworkReceive, group: self::GROUP_BREAKDOWN);
if(!isset(self::$packetReceiveTimingMap[$pk::class])){
self::$packetReceiveTimingMap[$pk::class] = new TimingsHandler("Receive - " . $pk->getName(), self::$playerNetworkReceive, group: self::GROUP_BREAKDOWN);
}
return self::$packetReceiveTimingMap[$pid];
return self::$packetReceiveTimingMap[$pk::class];
}
public static function getDecodeDataPacketTimings(ServerboundPacket $pk) : TimingsHandler{
$pid = $pk->pid();
return self::$packetDecodeTimingMap[$pid] ??= new TimingsHandler(
return self::$packetDecodeTimingMap[$pk::class] ??= new TimingsHandler(
"Decode - " . $pk->getName(),
self::getReceiveDataPacketTimings($pk),
group: self::GROUP_BREAKDOWN
@ -293,8 +305,7 @@ abstract class Timings{
}
public static function getHandleDataPacketTimings(ServerboundPacket $pk) : TimingsHandler{
$pid = $pk->pid();
return self::$packetHandleTimingMap[$pid] ??= new TimingsHandler(
return self::$packetHandleTimingMap[$pk::class] ??= new TimingsHandler(
"Handler - " . $pk->getName(),
self::getReceiveDataPacketTimings($pk),
group: self::GROUP_BREAKDOWN
@ -302,8 +313,7 @@ abstract class Timings{
}
public static function getEncodeDataPacketTimings(ClientboundPacket $pk) : TimingsHandler{
$pid = $pk->pid();
return self::$packetEncodeTimingMap[$pid] ??= new TimingsHandler(
return self::$packetEncodeTimingMap[$pk::class] ??= new TimingsHandler(
"Encode - " . $pk->getName(),
self::getSendDataPacketTimings($pk),
group: self::GROUP_BREAKDOWN
@ -311,23 +321,17 @@ abstract class Timings{
}
public static function getSendDataPacketTimings(ClientboundPacket $pk) : TimingsHandler{
$pid = $pk->pid();
if(!isset(self::$packetSendTimingMap[$pid])){
self::$packetSendTimingMap[$pid] = new TimingsHandler("Send - " . $pk->getName(), self::$playerNetworkSend, group: self::GROUP_BREAKDOWN);
if(!isset(self::$packetSendTimingMap[$pk::class])){
self::$packetSendTimingMap[$pk::class] = new TimingsHandler("Send - " . $pk->getName(), self::$playerNetworkSend, group: self::GROUP_BREAKDOWN);
}
return self::$packetSendTimingMap[$pid];
return self::$packetSendTimingMap[$pk::class];
}
public static function getEventTimings(Event $event) : TimingsHandler{
$eventClass = get_class($event);
if(!isset(self::$events[$eventClass])){
if(str_starts_with($eventClass, "pocketmine\\event\\")){
$name = (new \ReflectionClass($event))->getShortName();
}else{
$name = $eventClass;
}
self::$events[$eventClass] = new TimingsHandler($name, group: "Events");
self::$events[$eventClass] = new TimingsHandler(self::shortenCoreClassName($eventClass, "pocketmine\\event\\"), group: "Events");
}
return self::$events[$eventClass];

View File

@ -507,7 +507,7 @@ class World implements ChunkManager{
$this->time = $this->provider->getWorldData()->getTime();
$cfg = $this->server->getConfigGroup();
$this->chunkTickRadius = min($this->server->getViewDistance(), max(1, $cfg->getPropertyInt("chunk-ticking.tick-radius", 4)));
$this->chunkTickRadius = min($this->server->getViewDistance(), max(0, $cfg->getPropertyInt("chunk-ticking.tick-radius", 4)));
if($cfg->getPropertyInt("chunk-ticking.per-tick", 40) <= 0){
//TODO: this needs l10n
$this->logger->warning("\"chunk-ticking.per-tick\" setting is deprecated, but you've used it to disable chunk ticking. Set \"chunk-ticking.tick-radius\" to 0 in \"pocketmine.yml\" instead.");