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

This commit is contained in:
Dylan K. Taylor 2022-05-20 11:21:35 +01:00
commit 68491be847
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
173 changed files with 911 additions and 1294 deletions

View File

@ -11,3 +11,8 @@ updates:
directory: "/"
schedule:
interval: daily
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: daily

View File

@ -12,16 +12,16 @@ jobs:
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v2
- name: Login to DockerHub
uses: docker/login-action@v1
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Clone pmmp/PocketMine-Docker repository
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
repository: pmmp/PocketMine-Docker
fetch-depth: 1
@ -46,7 +46,7 @@ jobs:
run: echo ::set-output name=NAME::$(echo "${GITHUB_REPOSITORY,,}")
- name: Build image for tag
uses: docker/build-push-action@v2.10.0
uses: docker/build-push-action@v3.0.0
with:
push: true
context: ./pocketmine-mp
@ -59,7 +59,7 @@ jobs:
- name: Build image for major tag
if: steps.channel.outputs.CHANNEL == 'stable'
uses: docker/build-push-action@v2.10.0
uses: docker/build-push-action@v3.0.0
with:
push: true
context: ./pocketmine-mp
@ -72,7 +72,7 @@ jobs:
- name: Build image for minor tag
if: steps.channel.outputs.CHANNEL == 'stable'
uses: docker/build-push-action@v2.10.0
uses: docker/build-push-action@v3.0.0
with:
push: true
context: ./pocketmine-mp
@ -85,7 +85,7 @@ jobs:
- name: Build image for latest tag
if: steps.channel.outputs.CHANNEL == 'stable'
uses: docker/build-push-action@v2.10.0
uses: docker/build-push-action@v3.0.0
with:
push: true
context: ./pocketmine-mp

View File

@ -13,17 +13,17 @@ jobs:
fail-fast: false
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
submodules: true
- name: Setup PHP
uses: shivammathur/setup-php@2.12.0
uses: shivammathur/setup-php@2.18.1
with:
php-version: 8.0
- name: Restore Composer package cache
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: |
~/.cache/composer/files
@ -60,7 +60,7 @@ jobs:
run: php build/generate-build-info-json.php ${{ github.sha }} ${{ steps.get-pm-version.outputs.PM_VERSION }} ${{ github.repository }} ${{ steps.build-number.outputs.BUILD_NUMBER }} > build_info.json
- name: Upload release artifacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: release_artifacts
path: |
@ -69,7 +69,7 @@ jobs:
${{ github.workspace }}/build_info.json
- name: Create draft release
uses: ncipollo/release-action@v1.8.6
uses: ncipollo/release-action@v1.10.0
with:
artifacts: ${{ github.workspace }}/PocketMine-MP.phar,${{ github.workspace }}/start.*,${{ github.workspace }}/build_info.json
commit: ${{ github.sha }}

View File

@ -34,7 +34,7 @@ jobs:
php: [8.0.18]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Setup PHP
uses: pmmp/setup-php-action@aa636a4fe0c1c035fd9a3f05e360eadd86e06440
@ -46,7 +46,7 @@ jobs:
run: curl -sS https://getcomposer.org/installer | php
- name: Restore Composer package cache
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: |
~/.cache/composer/files
@ -72,7 +72,7 @@ jobs:
php: [8.0.18]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Setup PHP
uses: pmmp/setup-php-action@aa636a4fe0c1c035fd9a3f05e360eadd86e06440
@ -84,7 +84,7 @@ jobs:
run: curl -sS https://getcomposer.org/installer | php
- name: Restore Composer package cache
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: |
~/.cache/composer/files
@ -110,7 +110,7 @@ jobs:
php: [8.0.18]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
submodules: true
@ -124,7 +124,7 @@ jobs:
run: curl -sS https://getcomposer.org/installer | php
- name: Restore Composer package cache
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: |
~/.cache/composer/files
@ -150,7 +150,7 @@ jobs:
php: [8.0.18]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Setup PHP
uses: pmmp/setup-php-action@aa636a4fe0c1c035fd9a3f05e360eadd86e06440
@ -162,7 +162,7 @@ jobs:
run: curl -sS https://getcomposer.org/installer | php
- name: Restore Composer package cache
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: |
~/.cache/composer/files
@ -192,10 +192,10 @@ jobs:
fail-fast: false
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Setup PHP and tools
uses: shivammathur/setup-php@2.15.0
uses: shivammathur/setup-php@2.18.1
with:
php-version: 8.0
tools: php-cs-fixer:3.2

View File

@ -13,7 +13,7 @@ jobs:
- name: Install jq
run: sudo apt update && sudo apt install jq -y
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
repository: pmmp/update.pmmp.io
ssh-key: ${{ secrets.UPDATE_PMMP_IO_DEPLOY_KEY }}

View File

@ -69,9 +69,6 @@ use const JSON_UNESCAPED_SLASHES;
use const SORT_NUMERIC;
class MemoryManager{
private Server $server;
private int $memoryLimit;
private int $globalMemoryLimit;
private int $checkRate;
@ -98,8 +95,9 @@ class MemoryManager{
private \Logger $logger;
public function __construct(Server $server){
$this->server = $server;
public function __construct(
private Server $server
){
$this->logger = new \PrefixedLogger($server->getLogger(), "Memory Manager");
$this->init($server->getConfigGroup());

View File

@ -223,8 +223,6 @@ class Server{
private int $sendUsageTicker = 0;
private \AttachableThreadedLogger $logger;
private MemoryManager $memoryManager;
private ConsoleReaderThread $console;
@ -249,7 +247,6 @@ class Server{
private UuidInterface $serverID;
private \DynamicClassLoader $autoloader;
private string $dataPath;
private string $pluginPath;
@ -766,7 +763,12 @@ class Server{
return self::$instance;
}
public function __construct(\DynamicClassLoader $autoloader, \AttachableThreadedLogger $logger, string $dataPath, string $pluginPath){
public function __construct(
private \DynamicClassLoader $autoloader,
private \AttachableThreadedLogger $logger,
string $dataPath,
string $pluginPath
){
if(self::$instance !== null){
throw new \LogicException("Only one server instance can exist at once");
}
@ -774,8 +776,6 @@ class Server{
$this->startTime = microtime(true);
$this->tickSleeper = new SleeperHandler();
$this->autoloader = $autoloader;
$this->logger = $logger;
$this->signalHandler = new SignalHandler(function() : void{
$this->logger->info("Received signal interrupt, stopping the server");

View File

@ -32,20 +32,16 @@ use function is_string;
use function strtolower;
final class ServerConfigGroup{
private Config $pocketmineYml;
private Config $serverProperties;
/**
* @var mixed[]
* @phpstan-var array<string, mixed>
*/
private array $propertyCache = [];
public function __construct(Config $pocketmineYml, Config $serverProperties){
$this->pocketmineYml = $pocketmineYml;
$this->serverProperties = $serverProperties;
}
public function __construct(
private Config $pocketmineYml,
private Config $serverProperties
){}
/**
* @param mixed $defaultValue

View File

@ -38,18 +38,17 @@ class BlockBreakInfo{
*/
public const INCOMPATIBLE_TOOL_MULTIPLIER = 5.0;
private float $hardness;
private float $blastResistance;
private int $toolType;
private int $toolHarvestLevel;
/**
* @param float|null $blastResistance default 5x hardness
*/
public function __construct(float $hardness, int $toolType = BlockToolType::NONE, int $toolHarvestLevel = 0, ?float $blastResistance = null){
$this->hardness = $hardness;
$this->toolType = $toolType;
$this->toolHarvestLevel = $toolHarvestLevel;
public function __construct(
private float $hardness,
private int $toolType = BlockToolType::NONE,
private int $toolHarvestLevel = 0,
?float $blastResistance = null
){
$this->blastResistance = $blastResistance ?? $hardness * 5;
}

View File

@ -391,6 +391,7 @@ class BlockFactory{
$this->registerAllMeta(new Stair(new BID(Ids::STONE_BRICK_STAIRS, 0), "Stone Brick Stairs", $stoneBreakInfo));
$this->registerAllMeta(new Stair(new BID(Ids::MOSSY_STONE_BRICK_STAIRS, 0), "Mossy Stone Brick Stairs", $stoneBreakInfo));
$this->registerAllMeta(new StoneButton(new BID(Ids::STONE_BUTTON, 0), "Stone Button", new BlockBreakInfo(0.5, BlockToolType::PICKAXE)));
$this->registerAllMeta(new Stonecutter(new BID(Ids::STONECUTTER_BLOCK, 0, ItemIds::STONECUTTER_BLOCK), "Stonecutter", new BlockBreakInfo(3.5, BlockToolType::PICKAXE)));
$this->registerAllMeta(new StonePressurePlate(new BID(Ids::STONE_PRESSURE_PLATE, 0), "Stone Pressure Plate", new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
//TODO: in the future this won't be the same for all the types
@ -431,7 +432,7 @@ class BlockFactory{
$this->registerSlabWithDoubleHighBitsRemapping($slabType);
}
$this->registerAllMeta(new Opaque(new BID(Ids::STONECUTTER, 0), "Stonecutter", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
$this->registerAllMeta(new Opaque(new BID(Ids::STONECUTTER, 0), "Legacy Stonecutter", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
$this->registerAllMeta(new Sugarcane(new BID(Ids::REEDS_BLOCK, 0, ItemIds::REEDS), "Sugarcane", BlockBreakInfo::instant()));
$this->registerAllMeta(new SweetBerryBush(new BID(Ids::SWEET_BERRY_BUSH, 0, ItemIds::SWEET_BERRIES), "Sweet Berry Bush", BlockBreakInfo::instant()));
$this->registerAllMeta(new TNT(new BID(Ids::TNT, 0), "TNT", BlockBreakInfo::instant()));
@ -641,7 +642,6 @@ class BlockFactory{
//TODO: minecraft:seagrass
//TODO: minecraft:smithing_table
//TODO: minecraft:sticky_piston
//TODO: minecraft:stonecutter_block
//TODO: minecraft:structure_block
//TODO: minecraft:turtle_egg
//endregion

View File

@ -27,31 +27,25 @@ use pocketmine\block\tile\Tile;
use pocketmine\utils\Utils;
class BlockIdentifier{
private int $blockId;
private int $variant;
private ?int $itemId;
/** @phpstan-var class-string<Tile>|null */
private ?string $tileClass;
/**
* @phpstan-param class-string<Tile>|null $tileClass
*/
public function __construct(int $blockId, int $variant, ?int $itemId = null, ?string $tileClass = null){
public function __construct(
private int $blockId,
private int $variant,
private ?int $itemId = null,
private ?string $tileClass = null
){
if($blockId < 0){
throw new \InvalidArgumentException("Block ID may not be negative");
}
if($variant < 0){
throw new \InvalidArgumentException("Block variant may not be negative");
}
$this->blockId = $blockId;
$this->variant = $variant;
$this->itemId = $itemId;
if($tileClass !== null){
Utils::testValidInstance($tileClass, Tile::class);
}
$this->tileClass = $tileClass;
}
public function getBlockId() : int{

View File

@ -24,16 +24,15 @@ declare(strict_types=1);
namespace pocketmine\block;
class Element extends Opaque{
private int $atomicWeight;
private int $group;
private string $symbol;
public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo, string $symbol, int $atomicWeight, int $group){
public function __construct(
BlockIdentifier $idInfo,
string $name,
BlockBreakInfo $breakInfo,
private string $symbol,
private int $atomicWeight,
private int $group
){
parent::__construct($idInfo, $name, $breakInfo);
$this->atomicWeight = $atomicWeight;
$this->group = $group;
$this->symbol = $symbol;
}
public function getAtomicWeight() : int{

View File

@ -138,14 +138,16 @@ class FlowerPot extends Flowable{
$this->setPlant(null);
$this->position->getWorld()->setBlock($this->position, $this);
return true;
}elseif($this->isValidPlant($plant)){
$this->setPlant($plant);
$item->pop();
$this->position->getWorld()->setBlock($this->position, $this);
return true;
}
$this->setPlant($plant);
$item->pop();
$this->position->getWorld()->setBlock($this->position, $this);
return true;
return false;
}
public function getDropsForCompatibleTool(Item $item) : array{

62
src/block/Stonecutter.php Normal file
View File

@ -0,0 +1,62 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\block;
use pocketmine\block\inventory\StonecutterInventory;
use pocketmine\block\utils\BlockDataSerializer;
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
use pocketmine\block\utils\HorizontalFacingTrait;
use pocketmine\item\Item;
use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Facing;
use pocketmine\math\Vector3;
use pocketmine\player\Player;
class Stonecutter extends Transparent{
use FacesOppositePlacingPlayerTrait;
use HorizontalFacingTrait;
public function writeStateToMeta() : int{
return BlockDataSerializer::writeHorizontalFacing($this->facing);
}
public function readStateFromData(int $id, int $stateMeta) : void{
$this->facing = BlockDataSerializer::readHorizontalFacing($stateMeta);
}
public function getStateBitmask() : int{
return 0b111;
}
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
if($player !== null){
$player->setCurrentWindow(new StonecutterInventory($this->position));
}
return true;
}
protected function recalculateCollisionBoxes() : array{
return [AxisAlignedBB::one()->trim(Facing::UP, 7 / 16)];
}
}

View File

@ -529,6 +529,7 @@ use pocketmine\utils\CloningRegistryTrait;
* @method static StainedHardenedGlass STAINED_HARDENED_GLASS()
* @method static StainedHardenedGlassPane STAINED_HARDENED_GLASS_PANE()
* @method static Opaque STONE()
* @method static Stonecutter STONECUTTER()
* @method static Opaque STONE_BRICKS()
* @method static Slab STONE_BRICK_SLAB()
* @method static Stair STONE_BRICK_STAIRS()
@ -1099,6 +1100,7 @@ final class VanillaBlocks{
self::register("stone_pressure_plate", $factory->get(Ids::STONE_PRESSURE_PLATE, 0));
self::register("stone_slab", $factory->get(Ids::STONE_SLAB4, 2));
self::register("stone_stairs", $factory->get(Ids::NORMAL_STONE_STAIRS, 0));
self::register("stonecutter", $factory->get(Ids::STONECUTTER_BLOCK, 2));
self::register("stripped_acacia_log", $factory->get(Ids::STRIPPED_ACACIA_LOG, 0));
self::register("stripped_acacia_wood", $factory->get(Ids::WOOD, 12));
self::register("stripped_birch_log", $factory->get(Ids::STRIPPED_BIRCH_LOG, 0));

View File

@ -33,12 +33,10 @@ use pocketmine\world\sound\Sound;
class DoubleChestInventory extends BaseInventory implements BlockInventory, InventoryHolder{
use AnimatedBlockInventoryTrait;
private ChestInventory $left;
private ChestInventory $right;
public function __construct(ChestInventory $left, ChestInventory $right){
$this->left = $left;
$this->right = $right;
public function __construct(
private ChestInventory $left,
private ChestInventory $right
){
$this->holder = $this->left->getHolder();
parent::__construct();
}

View File

@ -43,12 +43,12 @@ class EnderChestInventory extends DelegateInventory implements BlockInventory{
onClose as animatedBlockInventoryTrait_onClose;
}
private PlayerEnderInventory $inventory;
public function __construct(Position $holder, PlayerEnderInventory $inventory){
public function __construct(
Position $holder,
private PlayerEnderInventory $inventory
){
parent::__construct($inventory);
$this->holder = $holder;
$this->inventory = $inventory;
}
public function getEnderInventory() : PlayerEnderInventory{

View File

@ -35,11 +35,11 @@ class FurnaceInventory extends SimpleInventory implements BlockInventory{
public const SLOT_FUEL = 1;
public const SLOT_RESULT = 2;
private FurnaceType $furnaceType;
public function __construct(Position $holder, FurnaceType $furnaceType){
public function __construct(
Position $holder,
private FurnaceType $furnaceType
){
$this->holder = $holder;
$this->furnaceType = $furnaceType;
parent::__construct(3);
}

View File

@ -0,0 +1,39 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\block\inventory;
use pocketmine\inventory\SimpleInventory;
use pocketmine\inventory\TemporaryInventory;
use pocketmine\world\Position;
class StonecutterInventory extends SimpleInventory implements BlockInventory, TemporaryInventory{
use BlockInventoryTrait;
public const SLOT_INPUT = 0;
public function __construct(Position $holder){
$this->holder = $holder;
parent::__construct(1);
}
}

View File

@ -45,15 +45,14 @@ class FormattedCommandAlias extends Command{
*/
private const FORMAT_STRING_REGEX = '/\G\$(\$)?((?!0)+\d+)(-)?/';
/** @var string[] */
private array $formatStrings = [];
/**
* @param string[] $formatStrings
*/
public function __construct(string $alias, array $formatStrings){
public function __construct(
string $alias,
private array $formatStrings
){
parent::__construct($alias);
$this->formatStrings = $formatStrings;
}
public function execute(CommandSender $sender, string $commandLabel, array $args){

View File

@ -26,23 +26,20 @@ namespace pocketmine\command;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\plugin\Plugin;
use pocketmine\plugin\PluginOwned;
use pocketmine\plugin\PluginOwnedTrait;
final class PluginCommand extends Command implements PluginOwned{
use PluginOwnedTrait;
private CommandExecutor $executor;
public function __construct(string $name, Plugin $owner, CommandExecutor $executor){
public function __construct(
string $name,
private Plugin $owner,
private CommandExecutor $executor
){
parent::__construct($name);
$this->owningPlugin = $owner;
$this->executor = $executor;
$this->usageMessage = "";
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->owningPlugin->isEnabled()){
if(!$this->owner->isEnabled()){
return false;
}
@ -59,6 +56,10 @@ final class PluginCommand extends Command implements PluginOwned{
return $success;
}
public function getOwningPlugin() : Plugin{
return $this->owner;
}
public function getExecutor() : CommandExecutor{
return $this->executor;
}

View File

@ -37,20 +37,17 @@ use const PHP_INT_MAX;
class ConsoleCommandSender implements CommandSender{
use PermissibleDelegateTrait;
/** @var Server */
private $server;
/**
* @var int|null
* @phpstan-var positive-int|null
*/
protected $lineHeight = null;
/** @var Language */
private $language;
public function __construct(Server $server, Language $language){
$this->server = $server;
public function __construct(
private Server $server,
private Language $language
){
$this->perm = new PermissibleBase([DefaultPermissions::ROOT_CONSOLE => true]);
$this->language = $language;
}
public function getServer() : Server{

View File

@ -46,13 +46,10 @@ use const PHP_BINARY;
use const STREAM_SHUT_RDWR;
final class ConsoleReaderThread extends Thread{
private \Threaded $buffer;
private ?SleeperNotifier $notifier;
public function __construct(\Threaded $buffer, ?SleeperNotifier $notifier = null){
$this->buffer = $buffer;
$this->notifier = $notifier;
}
public function __construct(
private \Threaded $buffer,
private ?SleeperNotifier $notifier = null
){}
protected function onRun() : void{
$buffer = $this->buffer;

View File

@ -33,15 +33,14 @@ abstract class CraftingGrid extends SimpleInventory{
public const SIZE_SMALL = 2;
public const SIZE_BIG = 3;
private int $gridWidth;
private ?int $startX = null;
private ?int $xLen = null;
private ?int $startY = null;
private ?int $yLen = null;
public function __construct(int $gridWidth){
$this->gridWidth = $gridWidth;
public function __construct(
private int $gridWidth
){
parent::__construct($this->getGridWidth() ** 2);
}

View File

@ -43,12 +43,19 @@ final class CraftingManagerFromDataHelper{
$itemDeserializerFunc = \Closure::fromCallable([Item::class, 'jsonDeserialize']);
foreach($recipes["shapeless"] as $recipe){
if($recipe["block"] !== "crafting_table"){ //TODO: filter others out for now to avoid breaking economics
$recipeType = match($recipe["block"]){
"crafting_table" => ShapelessRecipeType::CRAFTING(),
"stonecutter" => ShapelessRecipeType::STONECUTTER(),
//TODO: Cartography Table
default => null
};
if($recipeType === null){
continue;
}
$result->registerShapelessRecipe(new ShapelessRecipe(
array_map($itemDeserializerFunc, $recipe["input"]),
array_map($itemDeserializerFunc, $recipe["output"])
array_map($itemDeserializerFunc, $recipe["output"]),
$recipeType
));
}
foreach($recipes["shaped"] as $recipe){

View File

@ -32,12 +32,15 @@ class ShapelessRecipe implements CraftingRecipe{
private array $ingredients = [];
/** @var Item[] */
private array $results;
private ShapelessRecipeType $type;
/**
* @param Item[] $ingredients No more than 9 total. This applies to sum of item stack counts, not count of array.
* @param Item[] $results List of result items created by this recipe.
* TODO: we'll want to make the type parameter mandatory in PM5
*/
public function __construct(array $ingredients, array $results){
public function __construct(array $ingredients, array $results, ?ShapelessRecipeType $type = null){
$this->type = $type ?? ShapelessRecipeType::CRAFTING();
foreach($ingredients as $item){
//Ensure they get split up properly
if(count($this->ingredients) + $item->getCount() > 9){
@ -63,6 +66,10 @@ class ShapelessRecipe implements CraftingRecipe{
return $this->getResults();
}
public function getType() : ShapelessRecipeType{
return $this->type;
}
/**
* @return Item[]
*/

View File

@ -0,0 +1,46 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\crafting;
use pocketmine\utils\EnumTrait;
/**
* This doc-block is generated automatically, do not modify it manually.
* This must be regenerated whenever registry members are added, removed or changed.
* @see build/generate-registry-annotations.php
* @generate-registry-docblock
*
* @method static ShapelessRecipeType CRAFTING()
* @method static ShapelessRecipeType STONECUTTER()
*/
final class ShapelessRecipeType{
use EnumTrait;
protected static function setup() : void{
self::registerAll(
new self("crafting"),
new self("stonecutter")
);
}
}

View File

@ -80,18 +80,14 @@ class CrashDump{
public const PLUGIN_INVOLVEMENT_DIRECT = "direct";
public const PLUGIN_INVOLVEMENT_INDIRECT = "indirect";
/** @var Server */
private $server;
private CrashDumpData $data;
/** @var string */
private $encodedData;
private string $encodedData;
private ?PluginManager $pluginManager;
public function __construct(Server $server, ?PluginManager $pluginManager){
public function __construct(
private Server $server,
private ?PluginManager $pluginManager
){
$now = microtime(true);
$this->server = $server;
$this->pluginManager = $pluginManager;
$this->data = new CrashDumpData();
$this->data->format_version = self::FORMAT_VERSION;

View File

@ -35,12 +35,12 @@ final class CoralTypeIdMap{
* @var CoralType[]
* @phpstan-var array<int, CoralType>
*/
private $idToEnum = [];
private array $idToEnum = [];
/**
* @var int[]
* @phpstan-var array<int, int>
*/
private $enumToId = [];
private array $enumToId = [];
public function __construct(){
$this->register(BlockLegacyMetadata::CORAL_VARIANT_TUBE, CoralType::TUBE());

View File

@ -33,13 +33,13 @@ final class DyeColorIdMap{
* @var DyeColor[]
* @phpstan-var array<int, DyeColor>
*/
private $idToEnum = [];
private array $idToEnum = [];
/**
* @var int[]
* @phpstan-var array<int, int>
*/
private $enumToId = [];
private array $enumToId = [];
private function __construct(){
$this->register(0, DyeColor::WHITE());

View File

@ -36,13 +36,13 @@ final class EffectIdMap{
* @var Effect[]
* @phpstan-var array<int, Effect>
*/
private $idToEffect = [];
private array $idToEffect = [];
/**
* @var int[]
* @phpstan-var array<int, int>
*/
private $effectToId = [];
private array $effectToId = [];
private function __construct(){
$this->register(EffectIds::SPEED, VanillaEffects::SPEED());

View File

@ -39,12 +39,12 @@ final class EnchantmentIdMap{
* @var Enchantment[]
* @phpstan-var array<int, Enchantment>
*/
private $idToEnch = [];
private array $idToEnch = [];
/**
* @var int[]
* @phpstan-var array<int, int>
*/
private $enchToId = [];
private array $enchToId = [];
private function __construct(){
$this->register(EnchantmentIds::PROTECTION, VanillaEnchantments::PROTECTION());

View File

@ -37,12 +37,12 @@ abstract class LegacyToStringBidirectionalIdMap{
* @var string[]
* @phpstan-var array<int, string>
*/
private $legacyToString = [];
private array $legacyToString = [];
/**
* @var int[]
* @phpstan-var array<string, int>
*/
private $stringToLegacy = [];
private array $stringToLegacy = [];
public function __construct(string $file){
$stringToLegacyId = json_decode(Utils::assumeNotFalse(file_get_contents($file), "Missing required resource file"), true);

View File

@ -29,7 +29,7 @@ final class AttributeFactory{
use SingletonTrait;
/** @var Attribute[] */
private $attributes = [];
private array $attributes = [];
public function __construct(){
$this->register(Attribute::ABSORPTION, 0.00, 340282346638528859811704183484516925440.00, 0.00);

View File

@ -27,7 +27,7 @@ use function array_filter;
class AttributeMap{
/** @var Attribute[] */
private $attributes = [];
private array $attributes = [];
public function add(Attribute $attribute) : void{
$this->attributes[$attribute->getId()] = $attribute;

View File

@ -80,8 +80,7 @@ abstract class Entity{
public const MOTION_THRESHOLD = 0.00001;
protected const STEP_CLIP_MULTIPLIER = 0.4;
/** @var int */
private static $entityCount = 1;
private static int $entityCount = 1;
/**
* Returns a new runtime entity ID for a new entity.
@ -96,8 +95,7 @@ abstract class Entity{
/** @var int */
protected $id;
/** @var EntityMetadataCollection */
private $networkProperties;
private EntityMetadataCollection $networkProperties;
/** @var EntityDamageEvent|null */
protected $lastDamageCause = null;
@ -124,10 +122,8 @@ abstract class Entity{
/** @var EntitySizeInfo */
public $size;
/** @var float */
private $health = 20.0;
/** @var int */
private $maxHealth = 20;
private float $health = 20.0;
private int $maxHealth = 20;
/** @var float */
protected $ySize = 0.0;
@ -150,8 +146,7 @@ abstract class Entity{
/** @var bool */
protected $isStatic = false;
/** @var bool */
private $savedWithChunk = true;
private bool $savedWithChunk = true;
/** @var bool */
public $isCollided = false;
@ -181,8 +176,7 @@ abstract class Entity{
/** @var bool */
protected $closed = false;
private bool $closeInFlight = false;
/** @var bool */
private $needsDespawn = false;
private bool $needsDespawn = false;
/** @var TimingsHandler */
protected $timings;

View File

@ -70,12 +70,12 @@ final class EntityFactory{
* @var \Closure[] save ID => creator function
* @phpstan-var array<int|string, \Closure(World, CompoundTag) : Entity>
*/
private $creationFuncs = [];
private array $creationFuncs = [];
/**
* @var string[]
* @phpstan-var array<class-string<Entity>, string>
*/
private $saveNames = [];
private array $saveNames = [];
public function __construct(){
//define legacy save IDs first - use them for saving for maximum compatibility with Minecraft PC
@ -173,8 +173,6 @@ final class EntityFactory{
$this->register(Human::class, function(World $world, CompoundTag $nbt) : Human{
return new Human(Helper::parseLocation($nbt, $world), Human::parseSkinNBT($nbt), $nbt);
}, ['Human']);
PaintingMotive::init();
}
/**

View File

@ -26,16 +26,13 @@ namespace pocketmine\entity;
use function min;
final class EntitySizeInfo{
/** @var float */
private $height;
/** @var float */
private $width;
/** @var float */
private $eyeHeight;
private float $eyeHeight;
public function __construct(float $height, float $width, ?float $eyeHeight = null){
$this->height = $height;
$this->width = $width;
public function __construct(
private float $height,
private float $width,
?float $eyeHeight = null
){
$this->eyeHeight = $eyeHeight ?? min($this->height / 2 + 0.1, $this->height);
}

View File

@ -38,26 +38,18 @@ use function min;
class ExperienceManager{
/** @var Human */
private $entity;
private Attribute $levelAttr;
private Attribute $progressAttr;
/** @var Attribute */
private $levelAttr;
/** @var Attribute */
private $progressAttr;
private int $totalXp = 0;
/** @var int */
private $totalXp = 0;
private bool $canAttractXpOrbs = true;
/** @var bool */
private $canAttractXpOrbs = true;
/** @var int */
private $xpCooldown = 0;
public function __construct(Human $entity){
$this->entity = $entity;
private int $xpCooldown = 0;
public function __construct(
private Human $entity
){
$this->levelAttr = self::fetchAttribute($entity, Attribute::EXPERIENCE_LEVEL);
$this->progressAttr = self::fetchAttribute($entity, Attribute::EXPERIENCE);
}

View File

@ -156,9 +156,9 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
public function jump() : void{
parent::jump();
if($this->isSprinting()){
$this->hungerManager->exhaust(0.8, PlayerExhaustEvent::CAUSE_SPRINT_JUMPING);
$this->hungerManager->exhaust(0.2, PlayerExhaustEvent::CAUSE_SPRINT_JUMPING);
}else{
$this->hungerManager->exhaust(0.2, PlayerExhaustEvent::CAUSE_JUMPING);
$this->hungerManager->exhaust(0.05, PlayerExhaustEvent::CAUSE_JUMPING);
}
}

View File

@ -32,25 +32,17 @@ use function min;
class HungerManager{
/** @var Human */
private $entity;
private Attribute $hungerAttr;
private Attribute $saturationAttr;
private Attribute $exhaustionAttr;
/** @var Attribute */
private $hungerAttr;
/** @var Attribute */
private $saturationAttr;
/** @var Attribute */
private $exhaustionAttr;
private int $foodTickTimer = 0;
/** @var int */
private $foodTickTimer = 0;
/** @var bool */
private $enabled = true;
public function __construct(Human $entity){
$this->entity = $entity;
private bool $enabled = true;
public function __construct(
private Human $entity
){
$this->hungerAttr = self::fetchAttribute($entity, Attribute::HUNGER);
$this->saturationAttr = self::fetchAttribute($entity, Attribute::SATURATION);
$this->exhaustionAttr = self::fetchAttribute($entity, Attribute::EXHAUSTION);
@ -208,7 +200,7 @@ class HungerManager{
if($food >= 18){
if($health < $this->entity->getMaxHealth()){
$this->entity->heal(new EntityRegainHealthEvent($this->entity, 1, EntityRegainHealthEvent::CAUSE_SATURATION));
$this->exhaust(3.0, PlayerExhaustEvent::CAUSE_HEALTH_REGEN);
$this->exhaust(6.0, PlayerExhaustEvent::CAUSE_HEALTH_REGEN);
}
}elseif($food <= 0){
if(($difficulty === World::DIFFICULTY_EASY && $health > 10) || ($difficulty === World::DIFFICULTY_NORMAL && $health > 1) || $difficulty === World::DIFFICULTY_HARD){

View File

@ -39,16 +39,11 @@ final class Skin{
128 * 128 * 4
];
/** @var string */
private $skinId;
/** @var string */
private $skinData;
/** @var string */
private $capeData;
/** @var string */
private $geometryName;
/** @var string */
private $geometryData;
private string $skinId;
private string $skinData;
private string $capeData;
private string $geometryName;
private string $geometryData;
private static function checkLength(string $string, string $name, int $maxLength) : void{
if(strlen($string) > $maxLength){

View File

@ -44,8 +44,7 @@ class Squid extends WaterAnimal{
/** @var float */
public $swimSpeed = 0.1;
/** @var int */
private $switchDirectionTicker = 0;
private int $switchDirectionTicker = 0;
protected function getInitialSizeInfo() : EntitySizeInfo{ return new EntitySizeInfo(0.95, 0.95); }

View File

@ -38,10 +38,8 @@ class Villager extends Living implements Ageable{
public static function getNetworkTypeId() : string{ return EntityIds::VILLAGER; }
/** @var bool */
private $baby = false;
/** @var int */
private $profession = self::PROFESSION_FARMER;
private bool $baby = false;
private int $profession = self::PROFESSION_FARMER;
protected function getInitialSizeInfo() : EntitySizeInfo{
return new EntitySizeInfo(1.8, 0.6); //TODO: eye height??

View File

@ -28,23 +28,12 @@ use pocketmine\utils\Limits;
use function max;
class EffectInstance{
/** @var Effect */
private $effectType;
/** @var int */
private $duration;
/** @var int */
private $amplifier;
/** @var bool */
private $visible;
/** @var bool */
private $ambient;
/** @var Color */
private $color;
private Effect $effectType;
private int $duration;
private int $amplifier;
private bool $visible;
private bool $ambient;
private Color $color;
/**
* @param int|null $duration Passing null will use the effect type's default duration

View File

@ -34,9 +34,6 @@ use function spl_object_id;
class EffectManager{
/** @var Living */
private $entity;
/** @var EffectInstance[] */
protected $effects = [];
@ -56,8 +53,9 @@ class EffectManager{
*/
protected $effectRemoveHooks;
public function __construct(Living $entity){
$this->entity = $entity;
public function __construct(
private Living $entity
){
$this->bubbleColor = new Color(0, 0, 0, 0);
$this->effectAddHooks = new ObjectSet();
$this->effectRemoveHooks = new ObjectSet();

View File

@ -36,7 +36,7 @@ class HungerEffect extends Effect{
public function applyEffect(Living $entity, EffectInstance $instance, float $potency = 1.0, ?Entity $source = null) : void{
if($entity instanceof Human){
$entity->getHungerManager()->exhaust(0.025 * $instance->getEffectLevel(), PlayerExhaustEvent::CAUSE_POTION);
$entity->getHungerManager()->exhaust(0.1 * $instance->getEffectLevel(), PlayerExhaustEvent::CAUSE_POTION);
}
}
}

View File

@ -30,9 +30,7 @@ use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\lang\Translatable;
class PoisonEffect extends Effect{
/** @var bool */
private $fatal;
private bool $fatal;
public function __construct(Translatable|string $name, Color $color, bool $isBad = false, int $defaultDuration = 600, bool $hasBubbles = true, bool $fatal = false){
parent::__construct($name, $color, $isBad, $defaultDuration, $hasBubbles);

View File

@ -24,6 +24,8 @@ declare(strict_types=1);
namespace pocketmine\entity\object;
class PaintingMotive{
private static bool $initialized = false;
/** @var PaintingMotive[] */
protected static $motives = [];
@ -76,6 +78,9 @@ class PaintingMotive{
* @return PaintingMotive[]
*/
public static function getAll() : array{
if(!self::$initialized){
self::init();
}
return self::$motives;
}

View File

@ -30,8 +30,8 @@ use function get_class;
abstract class Event{
private const MAX_EVENT_CALL_DEPTH = 50;
/** @var int */
private static $eventCallDepth = 1;
private static int $eventCallDepth = 1;
/** @var string|null */
protected $eventName = null;

View File

@ -28,18 +28,14 @@ use function array_fill_keys;
use function spl_object_id;
class HandlerList{
/** @var string */
private $class;
/** @var RegisteredListener[][] */
private $handlerSlots = [];
/** @var HandlerList|null */
private $parentList;
private array $handlerSlots = [];
public function __construct(string $class, ?HandlerList $parentList){
$this->class = $class;
public function __construct(
private string $class,
private ?HandlerList $parentList
){
$this->handlerSlots = array_fill_keys(EventPriority::ALL, []);
$this->parentList = $parentList;
}
/**

View File

@ -28,15 +28,14 @@ use pocketmine\utils\Utils;
class HandlerListManager{
/** @var HandlerListManager|null */
private static $globalInstance = null;
private static ?self $globalInstance = null;
public static function global() : self{
return self::$globalInstance ?? (self::$globalInstance = new self);
}
/** @var HandlerList[] classname => HandlerList */
private $allLists = [];
private array $allLists = [];
/**
* Unregisters all the listeners

View File

@ -28,31 +28,16 @@ use pocketmine\timings\TimingsHandler;
use function in_array;
class RegisteredListener{
/** @var \Closure */
private $handler;
/** @var int */
private $priority;
/** @var Plugin */
private $plugin;
/** @var bool */
private $handleCancelled;
/** @var TimingsHandler */
private $timings;
public function __construct(\Closure $handler, int $priority, Plugin $plugin, bool $handleCancelled, TimingsHandler $timings){
public function __construct(
private \Closure $handler,
private int $priority,
private Plugin $plugin,
private bool $handleCancelled,
private TimingsHandler $timings
){
if(!in_array($priority, EventPriority::ALL, true)){
throw new \InvalidArgumentException("Invalid priority number $priority");
}
$this->handler = $handler;
$this->priority = $priority;
$this->plugin = $plugin;
$this->handleCancelled = $handleCancelled;
$this->timings = $timings;
}
public function getHandler() : \Closure{

View File

@ -0,0 +1,44 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\event\player;
use pocketmine\player\Player;
/**
* Called after a player is sent a chunk as part of their view radius.
*/
final class PlayerPostChunkSendEvent extends PlayerEvent{
public function __construct(
Player $player,
private int $chunkX,
private int $chunkZ
){
$this->player = $player;
}
public function getChunkX() : int{ return $this->chunkX; }
public function getChunkZ() : int{ return $this->chunkZ; }
}

View File

@ -29,13 +29,12 @@ use pocketmine\player\Player;
* Called when a player requests a different viewing distance than the current one.
*/
class PlayerViewDistanceChangeEvent extends PlayerEvent{
protected int $newDistance;
protected int $oldDistance;
public function __construct(Player $player, int $oldDistance, int $newDistance){
public function __construct(
Player $player,
protected int $oldDistance,
protected int $newDistance
){
$this->player = $player;
$this->oldDistance = $oldDistance;
$this->newDistance = $newDistance;
}
/**

View File

@ -30,31 +30,20 @@ class CallbackInventoryListener implements InventoryListener{
//TODO: turn the closure signatures into type aliases when PHPStan supports them
/**
* @var \Closure|null
* @phpstan-var (\Closure(Inventory, int, Item) : void)|null
*/
private $onSlotChangeCallback;
/**
* @var \Closure|null
* @phpstan-var (\Closure(Inventory, Item[]) : void)|null
*/
private $onContentChangeCallback;
/**
* @phpstan-param (\Closure(Inventory, int, Item) : void)|null $onSlotChange
* @phpstan-param (\Closure(Inventory, Item[]) : void)|null $onContentChange
*/
public function __construct(?\Closure $onSlotChange, ?\Closure $onContentChange){
public function __construct(
private ?\Closure $onSlotChange,
private ?\Closure $onContentChange
){
if($onSlotChange !== null){
Utils::validateCallableSignature(function(Inventory $inventory, int $slot, Item $oldItem) : void{}, $onSlotChange);
}
if($onContentChange !== null){
Utils::validateCallableSignature(function(Inventory $inventory, array $oldContents) : void{}, $onContentChange);
}
$this->onSlotChangeCallback = $onSlotChange;
$this->onContentChangeCallback = $onContentChange;
}
/**
@ -72,8 +61,8 @@ class CallbackInventoryListener implements InventoryListener{
}
public function onSlotChange(Inventory $inventory, int $slot, Item $oldItem) : void{
if($this->onSlotChangeCallback !== null){
($this->onSlotChangeCallback)($inventory, $slot, $oldItem);
if($this->onSlotChange !== null){
($this->onSlotChange)($inventory, $slot, $oldItem);
}
}
@ -81,8 +70,8 @@ class CallbackInventoryListener implements InventoryListener{
* @param Item[] $oldContents
*/
public function onContentChange(Inventory $inventory, array $oldContents) : void{
if($this->onContentChangeCallback !== null){
($this->onContentChangeCallback)($inventory, $oldContents);
if($this->onContentChange !== null){
($this->onContentChange)($inventory, $oldContents);
}
}
}

View File

@ -34,7 +34,7 @@ final class CreativeInventory{
use SingletonTrait;
/** @var Item[] */
private $creative = [];
private array $creative = [];
private function __construct(){
$creativeItems = json_decode(file_get_contents(Path::join(\pocketmine\BEDROCK_DATA_PATH, "creativeitems.json")), true);

View File

@ -31,13 +31,12 @@ use function count;
* An inventory which is backed by another inventory, and acts as a proxy to that inventory.
*/
class DelegateInventory extends BaseInventory{
private Inventory $backingInventory;
private InventoryListener $inventoryListener;
public function __construct(Inventory $backingInventory){
public function __construct(
private Inventory $backingInventory
){
parent::__construct();
$this->backingInventory = $backingInventory;
$this->backingInventory->getListeners()->add($this->inventoryListener = new CallbackInventoryListener(
function(Inventory $unused, int $slot, Item $oldItem) : void{
$this->onSlotChange($slot, $oldItem);

View File

@ -26,11 +26,10 @@ namespace pocketmine\inventory;
use pocketmine\entity\Human;
final class PlayerEnderInventory extends SimpleInventory{
private Human $holder;
public function __construct(Human $holder, int $size = 27){
$this->holder = $holder;
public function __construct(
private Human $holder,
int $size = 27
){
parent::__construct($size);
}

View File

@ -26,8 +26,7 @@ namespace pocketmine\inventory;
use pocketmine\entity\Human;
final class PlayerOffHandInventory extends SimpleInventory{
/** @var Human */
private $holder;
private Human $holder;
public function __construct(Human $player){
$this->holder = $player;

View File

@ -57,8 +57,8 @@ class CraftingTransaction extends InventoryTransaction{
protected $inputs = [];
/** @var Item[] */
protected $outputs = [];
/** @var CraftingManager */
private $craftingManager;
private CraftingManager $craftingManager;
public function __construct(Player $source, CraftingManager $craftingManager, array $actions = []){
parent::__construct($source, $actions);

View File

@ -36,8 +36,7 @@ class SlotChangeAction extends InventoryAction{
/** @var Inventory */
protected $inventory;
/** @var int */
private $inventorySlot;
private int $inventorySlot;
public function __construct(Inventory $inventory, int $inventorySlot, Item $sourceItem, Item $targetItem){
parent::__construct($sourceItem, $targetItem);

View File

@ -40,8 +40,7 @@ class Armor extends Durable{
public const TAG_CUSTOM_COLOR = "customColor"; //TAG_Int
/** @var ArmorTypeInfo */
private $armorInfo;
private ArmorTypeInfo $armorInfo;
/** @var Color|null */
protected $customColor = null;

View File

@ -24,19 +24,11 @@ declare(strict_types=1);
namespace pocketmine\item;
class ArmorTypeInfo{
/** @var int */
private $defensePoints;
/** @var int */
private $maxDurability;
/** @var int */
private $armorSlot;
public function __construct(int $defensePoints, int $maxDurability, int $armorSlot){
$this->defensePoints = $defensePoints;
$this->maxDurability = $maxDurability;
$this->armorSlot = $armorSlot;
}
public function __construct(
private int $defensePoints,
private int $maxDurability,
private int $armorSlot
){}
public function getDefensePoints() : int{
return $this->defensePoints;

View File

@ -39,14 +39,13 @@ class Banner extends ItemBlockWallOrFloor{
public const TAG_PATTERN_COLOR = TileBanner::TAG_PATTERN_COLOR;
public const TAG_PATTERN_NAME = TileBanner::TAG_PATTERN_NAME;
/** @var DyeColor */
private $color;
private DyeColor $color;
/**
* @var BannerPatternLayer[]
* @phpstan-var list<BannerPatternLayer>
*/
private $patterns = [];
private array $patterns = [];
public function __construct(ItemIdentifier $identifier, Block $floorVariant, Block $wallVariant){
parent::__construct($identifier, $floorVariant, $wallVariant);

View File

@ -28,9 +28,7 @@ use pocketmine\block\utils\DyeColor;
use pocketmine\block\VanillaBlocks;
class Bed extends Item{
/** @var DyeColor */
private $color;
private DyeColor $color;
public function __construct(ItemIdentifier $identifier, string $name, DyeColor $color){
parent::__construct($identifier, $name);

View File

@ -26,8 +26,7 @@ namespace pocketmine\item;
use pocketmine\block\utils\TreeType;
class Boat extends Item{
/** @var TreeType */
private $woodType;
private TreeType $woodType;
public function __construct(ItemIdentifier $identifier, string $name, TreeType $woodType){
parent::__construct($identifier, $name);

View File

@ -32,8 +32,7 @@ abstract class Durable extends Item{
/** @var int */
protected $damage = 0;
/** @var bool */
private $unbreakable = false;
private bool $unbreakable = false;
public function getMeta() : int{
return $this->damage;

View File

@ -26,9 +26,7 @@ namespace pocketmine\item;
use pocketmine\block\utils\DyeColor;
class Dye extends Item{
/** @var DyeColor */
private $color;
private DyeColor $color;
public function __construct(ItemIdentifier $identifier, string $name, DyeColor $color){
parent::__construct($identifier, $name);

View File

@ -65,10 +65,9 @@ class Item implements \JsonSerializable{
public const TAG_DISPLAY_NAME = "Name";
public const TAG_DISPLAY_LORE = "Lore";
/** @var ItemIdentifier */
private $identifier;
/** @var CompoundTag */
private $nbt;
private ItemIdentifier $identifier;
private CompoundTag $nbt;
/** @var int */
protected $count = 1;
/** @var string */

View File

@ -33,8 +33,7 @@ use pocketmine\block\BlockFactory;
* just place wheat crops when used on the ground).
*/
final class ItemBlock extends Item{
/** @var int */
private $blockFullId;
private int $blockFullId;
public function __construct(ItemIdentifier $identifier, Block $block){
parent::__construct($identifier, $block->getName());

View File

@ -29,11 +29,8 @@ use pocketmine\math\Axis;
use pocketmine\math\Facing;
class ItemBlockWallOrFloor extends Item{
/** @var int */
private $floorVariant;
/** @var int */
private $wallVariant;
private int $floorVariant;
private int $wallVariant;
public function __construct(ItemIdentifier $identifier, Block $floorVariant, Block $wallVariant){
parent::__construct($identifier, $floorVariant->getName());

View File

@ -55,7 +55,7 @@ class ItemFactory{
use SingletonTrait;
/** @var Item[] */
private $list = [];
private array $list = [];
public function __construct(){
$this->registerArmorItems();

View File

@ -24,11 +24,8 @@ declare(strict_types=1);
namespace pocketmine\item;
final class ItemIdentifier{
/** @var int */
private $id;
/** @var int */
private $meta;
private int $id;
private int $meta;
public function __construct(int $id, int $meta){
if($id < -0x8000 || $id > 0x7fff){ //signed short range

View File

@ -50,9 +50,6 @@ use function trim;
final class LegacyStringToItemParser{
use SingletonTrait;
/** @var ItemFactory */
private $itemFactory;
private static function make() : self{
$result = new self(ItemFactory::getInstance());
@ -73,11 +70,9 @@ final class LegacyStringToItemParser{
* @var int[]
* @phpstan-var array<string, int>
*/
private $map = [];
private array $map = [];
public function __construct(ItemFactory $itemFactory){
$this->itemFactory = $itemFactory;
}
public function __construct(private ItemFactory $itemFactory){}
public function addMapping(string $alias, int $id) : void{
$this->map[$alias] = $id;

View File

@ -31,9 +31,7 @@ use pocketmine\math\Vector3;
use pocketmine\player\Player;
class LiquidBucket extends Item{
/** @var Liquid */
private $liquid;
private Liquid $liquid;
public function __construct(ItemIdentifier $identifier, string $name, Liquid $liquid){
parent::__construct($identifier, $name);

View File

@ -81,8 +81,6 @@ final class PotionType{
__construct as Enum___construct;
}
private string $displayName;
protected static function setup() : void{
self::registerAll(
new self("water", "Water", fn() => []),
@ -204,16 +202,15 @@ final class PotionType{
);
}
/** @phpstan-var \Closure() : list<EffectInstance> */
private \Closure $effectsGetter;
/**
* @phpstan-param \Closure() : list<EffectInstance> $effectsGetter
*/
private function __construct(string $enumName, string $displayName, \Closure $effectsGetter){
private function __construct(
string $enumName,
private string $displayName,
private \Closure $effectsGetter
){
$this->Enum___construct($enumName);
$this->displayName = $displayName;
$this->effectsGetter = $effectsGetter;
}
public function getDisplayName() : string{ return $this->displayName; }

View File

@ -26,9 +26,9 @@ namespace pocketmine\item;
use pocketmine\block\utils\RecordType;
class Record extends Item{
/** @var RecordType */
private $recordType;
private RecordType $recordType;
//TODO: inconsistent parameter order
public function __construct(ItemIdentifier $identifier, RecordType $recordType, string $name){
$this->recordType = $recordType;
parent::__construct($identifier, $name);

View File

@ -28,9 +28,7 @@ use pocketmine\block\utils\SkullType;
use pocketmine\block\VanillaBlocks;
class Skull extends Item{
/** @var SkullType */
private $skullType;
private SkullType $skullType;
public function __construct(ItemIdentifier $identifier, string $name, SkullType $skullType){
parent::__construct($identifier, $name);

View File

@ -869,7 +869,8 @@ final class StringToItemParser extends StringToTParser{
$result->registerBlock("stone_stairs", fn() => VanillaBlocks::STONE_STAIRS());
$result->registerBlock("stone_wall", fn() => VanillaBlocks::COBBLESTONE_WALL());
$result->registerBlock("stonebrick", fn() => VanillaBlocks::STONE_BRICKS());
$result->registerBlock("stonecutter", fn() => VanillaBlocks::LEGACY_STONECUTTER());
$result->registerBlock("stonecutter", fn() => VanillaBlocks::STONECUTTER());
$result->registerBlock("stonecutter_block", fn() => VanillaBlocks::STONECUTTER());
$result->registerBlock("stripped_acacia_log", fn() => VanillaBlocks::STRIPPED_ACACIA_LOG());
$result->registerBlock("stripped_acacia_wood", fn() => VanillaBlocks::STRIPPED_ACACIA_WOOD());
$result->registerBlock("stripped_birch_log", fn() => VanillaBlocks::STRIPPED_BIRCH_LOG());

View File

@ -52,21 +52,14 @@ final class ToolTier{
);
}
/** @var int */
private $harvestLevel;
/** @var int */
private $maxDurability;
/** @var int */
private $baseAttackPoints;
/** @var int */
private $baseEfficiency;
private function __construct(string $name, int $harvestLevel, int $maxDurability, int $baseAttackPoints, int $baseEfficiency){
private function __construct(
string $name,
private int $harvestLevel,
private int $maxDurability,
private int $baseAttackPoints,
private int $baseEfficiency
){
$this->Enum___construct($name);
$this->harvestLevel = $harvestLevel;
$this->maxDurability = $maxDurability;
$this->baseAttackPoints = $baseAttackPoints;
$this->baseEfficiency = $baseEfficiency;
}
public function getHarvestLevel() : int{

View File

@ -42,7 +42,7 @@ abstract class WritableBookBase extends Item{
* @var WritableBookPage[]
* @phpstan-var list<WritableBookPage>
*/
private $pages = [];
private array $pages = [];
public function __construct(ItemIdentifier $identifier, string $name){
parent::__construct($identifier, $name);

View File

@ -32,10 +32,8 @@ class WritableBookPage{
public const PAGE_LENGTH_HARD_LIMIT_BYTES = Limits::INT16_MAX;
public const PHOTO_NAME_LENGTH_HARD_LIMIT_BYTES = Limits::INT16_MAX;
/** @var string */
private $text;
/** @var string */
private $photoName;
private string $text;
private string $photoName;
/**
* @throws \InvalidArgumentException

View File

@ -40,12 +40,9 @@ class WrittenBook extends WritableBookBase{
public const TAG_AUTHOR = "author"; //TAG_String
public const TAG_TITLE = "title"; //TAG_String
/** @var int */
private $generation = self::GENERATION_ORIGINAL;
/** @var string */
private $author = "";
/** @var string */
private $title = "";
private int $generation = self::GENERATION_ORIGINAL;
private string $author = "";
private string $title = "";
public function getMaxStackSize() : int{
return 16;

View File

@ -29,21 +29,10 @@ namespace pocketmine\item\enchantment;
* Note: This class is assumed to be immutable. Consider this before making alterations.
*/
final class EnchantmentInstance{
/** @var Enchantment */
private $enchantment;
/** @var int */
private $level;
/**
* EnchantmentInstance constructor.
*
* @param Enchantment $enchantment Enchantment type
* @param int $level Level of enchantment
*/
public function __construct(Enchantment $enchantment, int $level = 1){
$this->enchantment = $enchantment;
$this->level = $level;
}
public function __construct(
private Enchantment $enchantment,
private int $level = 1
){}
/**
* Returns the type of this enchantment.

View File

@ -29,15 +29,10 @@ use function count;
final class BandwidthStatsTracker{
/** @var int[] */
private $history;
/** @var int */
private $nextHistoryIndex = 0;
/** @var int */
private $bytesSinceLastRotation = 0;
/** @var int */
private $totalBytes = 0;
private array $history;
private int $nextHistoryIndex = 0;
private int $bytesSinceLastRotation = 0;
private int $totalBytes = 0;
/** @phpstan-param positive-int $historySize */
public function __construct(int $historySize){

View File

@ -24,12 +24,8 @@ declare(strict_types=1);
namespace pocketmine\network;
final class BidirectionalBandwidthStatsTracker{
/** @var BandwidthStatsTracker */
private $send;
/** @var BandwidthStatsTracker */
private $receive;
private BandwidthStatsTracker $send;
private BandwidthStatsTracker $receive;
/** @phpstan-param positive-int $historySize */
public function __construct(int $historySize){

View File

@ -28,6 +28,7 @@ namespace pocketmine\network;
use pocketmine\event\server\NetworkInterfaceRegisterEvent;
use pocketmine\event\server\NetworkInterfaceUnregisterEvent;
use pocketmine\utils\Utils;
use function base64_encode;
use function get_class;
use function preg_match;
@ -37,32 +38,28 @@ use const PHP_INT_MAX;
class Network{
/** @var NetworkInterface[] */
private $interfaces = [];
private array $interfaces = [];
/** @var AdvancedNetworkInterface[] */
private $advancedInterfaces = [];
private array $advancedInterfaces = [];
/** @var RawPacketHandler[] */
private $rawPacketHandlers = [];
private array $rawPacketHandlers = [];
/** @var int[] */
private $bannedIps = [];
/**
* @var int[]
* @phpstan-var array<string, int>
*/
private array $bannedIps = [];
/** @var BidirectionalBandwidthStatsTracker */
private $bandwidthTracker;
private BidirectionalBandwidthStatsTracker $bandwidthTracker;
private string $name;
private NetworkSessionManager$sessionManager;
/** @var string */
private $name;
/** @var NetworkSessionManager */
private $sessionManager;
/** @var \Logger */
private $logger;
public function __construct(\Logger $logger){
public function __construct(
private \Logger $logger
){
$this->sessionManager = new NetworkSessionManager();
$this->logger = $logger;
$this->bandwidthTracker = new BidirectionalBandwidthStatsTracker(5);
}
@ -103,7 +100,7 @@ class Network{
if($interface instanceof AdvancedNetworkInterface){
$this->advancedInterfaces[$hash] = $interface;
$interface->setNetwork($this);
foreach($this->bannedIps as $ip => $until){
foreach(Utils::stringifyKeys($this->bannedIps) as $ip => $until){
$interface->blockAddress($ip);
}
foreach($this->rawPacketHandlers as $handler){

View File

@ -30,7 +30,7 @@ use function spl_object_id;
class NetworkSessionManager{
/** @var NetworkSession[] */
private $sessions = [];
private array $sessions = [];
/**
* Adds a network session to the manager. This should only be called on session creation.

View File

@ -49,8 +49,7 @@ class ChunkRequestTask extends AsyncTask{
/** @var Compressor */
protected $compressor;
/** @var string */
private $tiles = "";
private string $tiles;
/**
* @phpstan-param (\Closure() : void)|null $onError

View File

@ -31,6 +31,7 @@ use pocketmine\block\inventory\EnchantInventory;
use pocketmine\block\inventory\FurnaceInventory;
use pocketmine\block\inventory\HopperInventory;
use pocketmine\block\inventory\LoomInventory;
use pocketmine\block\inventory\StonecutterInventory;
use pocketmine\crafting\FurnaceType;
use pocketmine\inventory\CreativeInventory;
use pocketmine\inventory\Inventory;
@ -74,15 +75,9 @@ class InventoryManager{
private const RESERVED_WINDOW_ID_RANGE_START = ContainerIds::LAST - 10;
private const HARDCODED_INVENTORY_WINDOW_ID = self::RESERVED_WINDOW_ID_RANGE_START + 2;
/** @var Player */
private $player;
/** @var NetworkSession */
private $session;
/** @var Inventory[] */
private $windowMap = [];
/** @var int */
private $lastInventoryNetworkId = ContainerIds::FIRST;
private array $windowMap = [];
private int $lastInventoryNetworkId = ContainerIds::FIRST;
/**
* TODO: HACK! This tracks GUIs for inventories that the server considers "always open" so that the client can't
@ -97,17 +92,16 @@ class InventoryManager{
* @var Item[][]
* @phpstan-var array<int, array<int, Item>>
*/
private $initiatedSlotChanges = [];
/** @var int */
private $clientSelectedHotbarSlot = -1;
private array $initiatedSlotChanges = [];
private int $clientSelectedHotbarSlot = -1;
/** @phpstan-var ObjectSet<ContainerOpenClosure> */
private ObjectSet $containerOpenCallbacks;
public function __construct(Player $player, NetworkSession $session){
$this->player = $player;
$this->session = $session;
public function __construct(
private Player $player,
private NetworkSession $session
){
$this->containerOpenCallbacks = new ObjectSet();
$this->containerOpenCallbacks->add(\Closure::fromCallable([self::class, 'createContainerOpen']));
@ -210,6 +204,7 @@ class InventoryManager{
$inv instanceof AnvilInventory => WindowTypes::ANVIL,
$inv instanceof HopperInventory => WindowTypes::HOPPER,
$inv instanceof CraftingTableInventory => WindowTypes::WORKBENCH,
$inv instanceof StonecutterInventory => WindowTypes::STONECUTTER,
default => WindowTypes::CONTAINER
};
return [ContainerOpenPacket::blockInv($id, $windowType, $blockPosition)];

View File

@ -136,11 +136,7 @@ use const SORT_NUMERIC;
class NetworkSession{
private \PrefixedLogger $logger;
private Server $server;
private ?Player $player = null;
private NetworkSessionManager $manager;
private string $ip;
private int $port;
private ?PlayerInfo $info = null;
private ?int $ping = null;
@ -163,37 +159,31 @@ class NetworkSession{
* @phpstan-var \SplQueue<CompressBatchPromise>
*/
private \SplQueue $compressedQueue;
private Compressor $compressor;
private bool $forceAsyncCompression = true;
private PacketPool $packetPool;
private PacketSerializerContext $packetSerializerContext;
private ?InventoryManager $invManager = null;
private PacketSender $sender;
private PacketBroadcaster $broadcaster;
/**
* @var \Closure[]|ObjectSet
* @phpstan-var ObjectSet<\Closure() : void>
*/
private ObjectSet $disposeHooks;
public function __construct(Server $server, NetworkSessionManager $manager, PacketPool $packetPool, PacketSender $sender, PacketBroadcaster $broadcaster, Compressor $compressor, string $ip, int $port){
$this->server = $server;
$this->manager = $manager;
$this->sender = $sender;
$this->broadcaster = $broadcaster;
$this->ip = $ip;
$this->port = $port;
public function __construct(
private Server $server,
private NetworkSessionManager $manager,
private PacketPool $packetPool,
private PacketSender $sender,
private PacketBroadcaster $broadcaster,
private Compressor $compressor,
private string $ip,
private int $port
){
$this->logger = new \PrefixedLogger($this->server->getLogger(), $this->getLogPrefix());
$this->compressedQueue = new \SplQueue();
$this->compressor = $compressor;
$this->packetPool = $packetPool;
//TODO: allow this to be injected
$this->packetSerializerContext = new PacketSerializerContext(GlobalItemTypeDictionary::getInstance()->getDictionary());

View File

@ -28,13 +28,7 @@ use pocketmine\Server;
use function spl_object_id;
final class StandardPacketBroadcaster implements PacketBroadcaster{
/** @var Server */
private $server;
public function __construct(Server $server){
$this->server = $server;
}
public function __construct(private Server $server){}
public function broadcastPackets(array $recipients, array $packets) : void{
$buffers = [];

View File

@ -42,39 +42,33 @@ class ProcessLoginTask extends AsyncTask{
private const CLOCK_DRIFT_MAX = 60;
/** @var string */
private $chain;
/** @var string */
private $clientDataJwt;
private string $chain;
/**
* @var string|null
* Whether the keychain signatures were validated correctly. This will be set to an error message if any link in the
* keychain is invalid for whatever reason (bad signature, not in nbf-exp window, etc). If this is non-null, the
* keychain might have been tampered with. The player will always be disconnected if this is non-null.
*/
private $error = "Unknown";
private ?string $error = "Unknown";
/**
* @var bool
* Whether the player is logged into Xbox Live. This is true if any link in the keychain is signed with the Mojang
* root public key.
*/
private $authenticated = false;
/** @var bool */
private $authRequired;
/** @var string|null */
private $clientPublicKey = null;
private bool $authenticated = false;
private ?string $clientPublicKey = null;
/**
* @param string[] $chainJwts
* @phpstan-param \Closure(bool $isAuthenticated, bool $authRequired, ?string $error, ?string $clientPublicKey) : void $onCompletion
*/
public function __construct(array $chainJwts, string $clientDataJwt, bool $authRequired, \Closure $onCompletion){
public function __construct(
array $chainJwts,
private string $clientDataJwt,
private bool $authRequired,
\Closure $onCompletion
){
$this->storeLocal(self::TLS_KEY_ON_COMPLETION, $onCompletion);
$this->chain = igbinary_serialize($chainJwts);
$this->clientDataJwt = $clientDataJwt;
$this->authRequired = $authRequired;
}
public function onRun() : void{

View File

@ -39,7 +39,7 @@ use function strlen;
*/
class ChunkCache implements ChunkListener{
/** @var self[][] */
private static $instances = [];
private static array $instances = [];
/**
* Fetches the ChunkCache instance for the given world. This lazily creates cache systems as needed.
@ -79,23 +79,16 @@ class ChunkCache implements ChunkListener{
}
}
/** @var World */
private $world;
/** @var Compressor */
private $compressor;
/** @var CompressBatchPromise[] */
private $caches = [];
private array $caches = [];
/** @var int */
private $hits = 0;
/** @var int */
private $misses = 0;
private int $hits = 0;
private int $misses = 0;
private function __construct(World $world, Compressor $compressor){
$this->world = $world;
$this->compressor = $compressor;
}
private function __construct(
private World $world,
private Compressor $compressor
){}
/**
* Requests asynchronous preparation of the chunk at the given coordinates.

View File

@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe\cache;
use pocketmine\crafting\CraftingManager;
use pocketmine\crafting\FurnaceType;
use pocketmine\crafting\ShapelessRecipeType;
use pocketmine\item\Item;
use pocketmine\network\mcpe\convert\ItemTranslator;
use pocketmine\network\mcpe\convert\TypeConverter;
@ -53,7 +54,7 @@ final class CraftingDataCache{
* @var CraftingDataPacket[]
* @phpstan-var array<int, CraftingDataPacket>
*/
private $caches = [];
private array $caches = [];
public function getCache(CraftingManager $manager) : CraftingDataPacket{
$id = spl_object_id($manager);
@ -81,6 +82,11 @@ final class CraftingDataCache{
$recipesWithTypeIds = [];
foreach($manager->getShapelessRecipes() as $list){
foreach($list as $recipe){
$typeTag = match($recipe->getType()->id()){
ShapelessRecipeType::CRAFTING()->id() => CraftingRecipeBlockName::CRAFTING_TABLE,
ShapelessRecipeType::STONECUTTER()->id() => CraftingRecipeBlockName::STONECUTTER,
default => throw new AssumptionFailedError("Unreachable"),
};
$recipesWithTypeIds[] = new ProtocolShapelessRecipe(
CraftingDataPacket::ENTRY_SHAPELESS,
Binary::writeInt(++$counter),
@ -91,7 +97,7 @@ final class CraftingDataCache{
return $converter->coreItemStackToNet($item);
}, $recipe->getResults()),
$nullUUID,
CraftingRecipeBlockName::CRAFTING_TABLE,
$typeTag,
50,
$counter
);

View File

@ -34,11 +34,6 @@ use function file_get_contents;
class StaticPacketCache{
use SingletonTrait;
/** @var BiomeDefinitionListPacket */
private $biomeDefs;
/** @var AvailableActorIdentifiersPacket */
private $availableActorIdentifiers;
/**
* @phpstan-return CacheableNbt<\pocketmine\nbt\tag\CompoundTag>
*/
@ -55,10 +50,10 @@ class StaticPacketCache{
);
}
public function __construct(BiomeDefinitionListPacket $biomeDefs, AvailableActorIdentifiersPacket $availableActorIdentifiers){
$this->biomeDefs = $biomeDefs;
$this->availableActorIdentifiers = $availableActorIdentifiers;
}
public function __construct(
private BiomeDefinitionListPacket $biomeDefs,
private AvailableActorIdentifiersPacket $availableActorIdentifiers
){}
public function getBiomeDefs() : BiomeDefinitionListPacket{
return $this->biomeDefs;

View File

@ -31,13 +31,11 @@ class CompressBatchPromise{
* @var \Closure[]
* @phpstan-var (\Closure(self) : void)[]
*/
private $callbacks = [];
private array $callbacks = [];
/** @var string|null */
private $result = null;
private ?string $result = null;
/** @var bool */
private $cancelled = false;
private bool $cancelled = false;
/**
* @phpstan-param \Closure(self) : void ...$callbacks

View File

@ -29,14 +29,11 @@ class CompressBatchTask extends AsyncTask{
private const TLS_KEY_PROMISE = "promise";
/** @var string */
private $data;
/** @var Compressor */
private $compressor;
public function __construct(string $data, CompressBatchPromise $promise, Compressor $compressor){
$this->data = $data;
$this->compressor = $compressor;
public function __construct(
private string $data,
CompressBatchPromise $promise,
private Compressor $compressor
){
$this->storeLocal(self::TLS_KEY_PROMISE, $promise);
}

View File

@ -46,21 +46,14 @@ final class ZlibCompressor implements Compressor{
return new self(self::DEFAULT_LEVEL, self::DEFAULT_THRESHOLD, self::DEFAULT_MAX_DECOMPRESSION_SIZE);
}
/** @var int */
private $level;
/** @var int */
private $threshold;
/** @var int */
private $maxDecompressionSize;
public function __construct(int $level, int $minCompressionSize, int $maxDecompressionSize){
$this->level = $level;
$this->threshold = $minCompressionSize;
$this->maxDecompressionSize = $maxDecompressionSize;
}
public function __construct(
private int $level,
private int $minCompressionSize,
private int $maxDecompressionSize
){}
public function willCompress(string $data) : bool{
return $this->threshold > -1 && strlen($data) >= $this->threshold;
return $this->minCompressionSize > -1 && strlen($data) >= $this->minCompressionSize;
}
/**

Some files were not shown because too many files have changed in this diff Show More