mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-07-29 22:25:52 +00:00
Merge branch 'minor-next' into major-next
This commit is contained in:
commit
1026811741
@ -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.
|
||||
|
@ -55,7 +55,7 @@
|
||||
"symfony/filesystem": "^5.4"
|
||||
},
|
||||
"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
24
composer.lock
generated
@ -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": "438d391135646f845eed034c362dffe3",
|
||||
"content-hash": "8c74b9fadbf1e7ea0777a1aa05f1ad29",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/json-comment",
|
||||
@ -1775,16 +1775,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": {
|
||||
@ -1833,7 +1833,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-04-04T19:17:42+00:00"
|
||||
"time": "2023-04-12T19:29:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan-phpunit",
|
||||
@ -2256,16 +2256,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": {
|
||||
@ -2339,7 +2339,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": [
|
||||
{
|
||||
@ -2355,7 +2355,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-03-27T11:43:46+00:00"
|
||||
"time": "2023-04-14T08:58:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/cli-parser",
|
||||
|
@ -56,7 +56,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{
|
||||
|
@ -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{
|
||||
|
@ -163,7 +163,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());
|
||||
}
|
||||
}
|
||||
|
@ -896,6 +896,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.
|
||||
@ -932,15 +957,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){
|
||||
|
@ -203,45 +203,57 @@ 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{
|
||||
self::init();
|
||||
$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{
|
||||
self::init();
|
||||
$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{
|
||||
self::init();
|
||||
$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
|
||||
@ -249,8 +261,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
|
||||
@ -258,8 +269,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
|
||||
@ -268,12 +278,11 @@ abstract class Timings{
|
||||
|
||||
public static function getSendDataPacketTimings(ClientboundPacket $pk) : TimingsHandler{
|
||||
self::init();
|
||||
$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 getCommandDispatchTimings(string $commandName) : TimingsHandler{
|
||||
@ -285,12 +294,7 @@ abstract class Timings{
|
||||
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];
|
||||
|
@ -490,7 +490,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.");
|
||||
|
Loading…
x
Reference in New Issue
Block a user