Compare commits

..

88 Commits

Author SHA1 Message Date
13f28d8454 Release 3.11.4 2020-01-20 18:06:46 +00:00
5a97c378fc phpstan: green on level 6, minus iterable types
iterable types are a big pain in the ass because of pthreads' awful architecture, and there's nothing I can do about that without BC-breaking changes to pthreads.
2020-01-20 17:54:55 +00:00
e5d62ec901 phpstan 0.12.6 2020-01-20 17:26:48 +00:00
cfd975009e Leaves: fix decay performance issue
this code was written with references in mind, but it looks like someone forgot the reference.
2020-01-20 11:52:11 +00:00
73257ffde7 updated pocketmine/spl dependency 2020-01-19 19:50:20 +00:00
8252bea699 phpstan: enable MissingMethodReturnTypehintRule
this was a bitch of a job, but it's one step closer to bypassing level 6.
2020-01-19 19:43:52 +00:00
ea935a1af5 pocketmine root: sweep missing return type information 2020-01-19 19:40:01 +00:00
e8a5fa8a37 updater: populate missing return type information 2020-01-19 19:38:41 +00:00
db734675d8 level: populate missing interface return types 2020-01-19 19:38:09 +00:00
6ede56015d level/biome: populate missing return type information 2020-01-19 19:37:08 +00:00
5334099fbf level/format: populate missing return type information 2020-01-19 19:36:34 +00:00
82e9072223 level/format/io: populate missing return type information 2020-01-19 19:35:45 +00:00
2c11742f9e Player: populate missing type information 2020-01-19 19:16:38 +00:00
bd4a63b668 Server: populate missing return type information 2020-01-19 19:09:08 +00:00
cd36af46bf Level: populate missing type information 2020-01-19 18:44:41 +00:00
aa7d55e21d level/generator: populate missing return type information 2020-01-19 18:07:54 +00:00
31e8efa6d1 level/light: populate missing return type information 2020-01-19 18:06:31 +00:00
facca13139 permission: populate missing return type information
PermissibleBase has some redundant phpdoc removed so that the Permissible interface can provide return types.
2020-01-19 17:23:52 +00:00
fffeeddca6 DataPacket: add magic method return types to keep phpstan happy
this really shouldn't be necessary, but it is what it is.
2020-01-19 17:14:34 +00:00
e6ba3ce8a6 item: populate missing return type information 2020-01-19 17:13:33 +00:00
11cae2f0c0 timings: populate missing return type information 2020-01-19 17:12:13 +00:00
f5a18df835 scheduler: populate missing return type information 2020-01-19 17:11:12 +00:00
1cc7027f92 plugin: populate missing return type information 2020-01-19 17:09:33 +00:00
8776b71d63 tile: populate missing return type information 2020-01-19 17:08:40 +00:00
0b9d0f3cdc utils: populate missing return type information 2020-01-19 17:07:48 +00:00
e419d76367 metadata: populate missing return type information 2020-01-19 17:06:48 +00:00
36cde9f352 inventory: populate missing return type information 2020-01-19 17:05:31 +00:00
05c602a044 event: populate missing return type information 2020-01-19 17:05:01 +00:00
0db7e57a15 lang: populate missing return type information 2020-01-19 17:04:25 +00:00
205e47c0c4 entity: populate missing return type information 2020-01-19 17:03:54 +00:00
e328d00cca command: populate missing return type info 2020-01-19 17:02:55 +00:00
ccbcc14600 Block: populate missing return type info 2020-01-19 17:02:03 +00:00
e544bc0d4b Item: added missing return type info for clearCustomBlockData() 2020-01-18 20:11:47 +00:00
fd27227cc7 Item: fix @return annotations for fluent methods (needed for correct auto complete) 2020-01-18 20:10:46 +00:00
b42966f61b network: explicitly specify @return void 2020-01-18 19:35:01 +00:00
ca86ec2ec2 Network: added missing return type information for getUpload() and getDownload() 2020-01-18 19:33:27 +00:00
97b6183404 PermissionManager: add native return types to private functions 2020-01-18 17:59:10 +00:00
0587d03c03 PluginDescription: add native return types to private functions 2020-01-18 17:57:24 +00:00
c7f1b605f2 PluginBase: remove useless duplicate doc comment from onLoad() stub 2020-01-18 17:56:44 +00:00
f069df65a8 PermissibleBase: added native returm types to private functions 2020-01-18 17:54:13 +00:00
1e624e7bb9 Attribute: add missing @return $this annotations 2020-01-18 17:50:58 +00:00
f16a530849 MainLogger: add native return types to private functions 2020-01-18 17:47:38 +00:00
7137b8a8a4 Config: added native void return types to private functions 2020-01-18 17:46:25 +00:00
ab57914322 CraftingDataPacket: added native return typehints to private methods 2020-01-18 17:45:15 +00:00
260869c0d5 Position: populate missing return type information for fromObject() 2020-01-18 17:44:14 +00:00
9135877da1 SetupWizard: add native void typehints to private methods 2020-01-18 17:39:06 +00:00
07cb603231 Liquid: add missing return type to getFluidHeightPercent() 2020-01-17 13:58:54 +00:00
f59094e6d6 Fence: add missing return type to canConnect() 2020-01-17 13:58:29 +00:00
d8acae5495 Door: add missing return type to getFullDamage() 2020-01-17 13:57:56 +00:00
239fe909be CobblestoneWall: add missing return type for canConnect() 2020-01-17 13:57:29 +00:00
c22576a266 CrashDump: add void native return types to private methods 2020-01-17 13:55:38 +00:00
bac788fd00 Timezone: add missing return type for detectSystemTimezone() 2020-01-15 20:18:35 +00:00
f6d96c5827 DataPacket: clean() returns $this, not void 2020-01-14 17:30:48 +00:00
b1458db47b Revert "CraftingDataPacket: fixed trying to return void result of parent function"
This reverts commit e12ecaf629.
2020-01-14 17:16:17 +00:00
2d2c9379cd DataPacket: apply @return void annotations to make phpstan happy
this eliminates 250+ errors on level 6.
2020-01-14 15:39:07 +00:00
3400771770 DataPacket: add missing return type info for pid() 2020-01-14 15:38:24 +00:00
e12ecaf629 CraftingDataPacket: fixed trying to return void result of parent function 2020-01-14 15:37:06 +00:00
1303cbfe02 UUID: add some missing return type annotations 2020-01-14 15:35:46 +00:00
ad4a211cba Color: add missing return type annotation for fromABGR() 2020-01-14 15:35:14 +00:00
d1e56c4611 Location: add missing return types for getYaw() and getPitch() 2020-01-14 15:34:40 +00:00
d9bbab54f4 Entity: fixing position and velocity sync on start/stop movement, closes #3133
the delta for velocity sync is WAYYYYYY too big, but that's a task for another commit.
2020-01-14 13:08:38 +00:00
07cf4eb7a9 Revert "Create .sonarcloud.properties"
This reverts commit 50a7663369.
2020-01-13 21:46:38 -06:00
50a7663369 Create .sonarcloud.properties 2020-01-13 21:31:36 -06:00
651ef500a3 Make pocketmine\PATH and pocketmine\RESOURCE_PATH always available
these are non-dependent on environment, so they can be determined with no external input.
    This fixes 2 PHPStan issues, fixes some code that couldn't run outside of PM, and makes it easier to write code that depends on PM.
2020-01-13 10:55:54 +00:00
30f2e75278 phpstan 0.12.5 2020-01-12 16:57:43 +00:00
2cfc25b4f8 phpstan: enable checkGenericClassInNonGenericObjectType 2020-01-11 23:04:16 +00:00
5bded9cff8 AttributeMap: add phpstan generic parameters for ArrayAccess 2020-01-11 23:03:21 +00:00
5816ff85ba don't depend on phpstan 0.12.4 phpdoc inheriting
this causes build failure because the parameter names are different to
the base class.
2020-01-11 22:08:16 +00:00
8f7d8347ee update pocketmine/spl dependency 2020-01-11 22:05:37 +00:00
3614d9a78d phpstan: enable MissingMethodParameterTypehintRule 2020-01-11 21:54:42 +00:00
818d0e19ab RCONInstance: remove always-false branch (readPacket() never returns null) 2020-01-11 21:54:03 +00:00
17720041a3 phpdoc: populate missing parameter typeinfo 2020-01-11 21:53:24 +00:00
c329ff7d4f SubChunk: remove nonsensical reference from internal function 2020-01-11 21:49:33 +00:00
8794292788 remove &$var reference notations in phpdoc
this isn't required by the spec and PHPStan chokes on it. I was previously having it ignore these errors, but it turns out that PHPStan is not making use of extended typeinfo provided if it can't parse the tag, which is problematic on level 6 and also a problem for array-of-type. Therefore, we are going to have to take the hit.
2020-01-11 21:20:55 +00:00
0a39e580e9 MainLogger: log exception chains in logException(), closes #2447
this method is simpler than #2447 and easier to apply to stable.
2020-01-09 21:01:12 +00:00
c4580dd56d MainLogger: extract a printErrorMessage() function from logException() 2020-01-09 20:51:13 +00:00
fab81d28bc MainLogger: always log exceptions with CRITICAL level
if we reached this point, it's almost always due to a general exception handler which doesn't know what else to do with the error.
2020-01-09 20:44:21 +00:00
039478223e phpstan: enable MissingFunctionReturnTypehintRule 2020-01-09 20:14:15 +00:00
64b5db4bf2 bootstrap: add some @return annotations for phpstan 2020-01-09 20:13:53 +00:00
c85f4256c7 phpstan: enable MissingFunctionParameterTypehintRule 2020-01-09 20:10:15 +00:00
1192b8bdf1 bootstrap: add PhpDoc to critical_error to make phpstan happy
it wants phpdoc or typehints, and we can't provide typehints because bootstrap needs to be compatible with old PHP versions.
2020-01-09 20:09:33 +00:00
6dcd2a4ece phpstan: start phasing in some level 6 checks 2020-01-09 19:56:04 +00:00
3fff0a0656 BigTree: evict unmaintained dead code
phpstan whines about all this stuff, and everything left is private, so we can get rid of it. Sadly we can't ditch the class without breaking BC, so that sticks with 4.0.
2020-01-09 14:26:46 +00:00
e1e1bfa5e3 CompressBatchedTask: remove useless code causing build failure
assuming that pthreads does not have leak issues, this code is pointless, and if pthreads does have leak issues, this may not prevent them anyway.
2020-01-09 14:19:35 +00:00
1eedac87b2 added missing @var property types (reported by phpstan) 2020-01-09 14:13:54 +00:00
cda3e6f4dc PluginDescription: clean up type information for extensions field 2020-01-09 11:20:01 +00:00
e6a58e2690 format/leveldb: fix crash on truncated level.dat file 2020-01-08 09:55:03 +00:00
27350c4673 3.11.4 is next 2020-01-04 16:46:55 +00:00
184 changed files with 2218 additions and 293 deletions

View File

@ -42,4 +42,14 @@ Plugin developers should **only** update their required API to this version if y
- Timings chains now work correctly.
- Fixed some minor timing errors in chained timings.
- Forcing resource packs no longer causes removal of client-sided resource packs. If this behaviour is desired, use a vanilla resource pack at the bottom of your resource stack (as was necessary for non-forced packs).
- Added documentation to the API to clarify that effect durations are in ticks.
- Added documentation to the API to clarify that effect durations are in ticks.
# 3.11.4
- Fixed performance issue in leaf decay.
- Fixed entity position desync when entities stop moving, but still have velocity on the client.
- Fixed a crash when encountering truncated `level.dat` files in LevelDB worlds.
- Core code is now analyzed using PHPStan level 6.
- The core constants `pocketmine\PATH` and `pocketmine\RESOURCE_PATH` are now unconditionally available when including the Composer autoloader.
- Populate type information in lots of places where it was previously missing; this will improve the quality of static analysis for plugins.
- `MainLogger::logException()` now logs previous exceptions recursively.
- `MainLogger::logException()` now always logs exceptions as `critical`.

View File

@ -25,7 +25,7 @@
"ext-zip": "*",
"ext-zlib": ">=1.2.11",
"pocketmine/raklib": "^0.12.5",
"pocketmine/spl": "^0.3.0",
"pocketmine/spl": "^0.3.5",
"pocketmine/binaryutils": "^0.1.9",
"pocketmine/nbt": "^0.2.10",
"pocketmine/math": "^0.2.0",
@ -38,6 +38,7 @@
"": ["src"]
},
"files": [
"src/pocketmine/CoreConstants.php",
"src/pocketmine/GlobalConstants.php",
"src/pocketmine/VersionInfo.php"
]

14
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": "377d9e0ab5f1a9a4ef9b664706d26f5b",
"content-hash": "f693f278b3bb9c1d266079fa17644dcb",
"packages": [
{
"name": "adhocore/json-comment",
@ -276,16 +276,16 @@
},
{
"name": "pocketmine/spl",
"version": "0.3.3",
"version": "0.3.5",
"source": {
"type": "git",
"url": "https://github.com/pmmp/SPL.git",
"reference": "94d4df142fe837ba836e9348dd00209e4bdcc307"
"reference": "88052c67d3df2cc2dc2d99ebeae3d7ede3fc64ab"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/SPL/zipball/94d4df142fe837ba836e9348dd00209e4bdcc307",
"reference": "94d4df142fe837ba836e9348dd00209e4bdcc307",
"url": "https://api.github.com/repos/pmmp/SPL/zipball/88052c67d3df2cc2dc2d99ebeae3d7ede3fc64ab",
"reference": "88052c67d3df2cc2dc2d99ebeae3d7ede3fc64ab",
"shasum": ""
},
"type": "library",
@ -299,10 +299,10 @@
],
"description": "Standard library files required by PocketMine-MP and related projects",
"support": {
"source": "https://github.com/pmmp/SPL/tree/0.3.3",
"source": "https://github.com/pmmp/SPL/tree/0.3",
"issues": "https://github.com/pmmp/SPL/issues"
},
"time": "2019-10-28T11:41:20+00:00"
"time": "2020-01-14T16:23:26+00:00"
}
],
"packages-dev": [],

View File

@ -1,13 +1,13 @@
includes:
- tests/phpstan/configs/com-dotnet-magic.neon
- tests/phpstan/configs/custom-leveldb.neon
- tests/phpstan/configs/gc-hacks.neon
- tests/phpstan/configs/optional-com-dotnet.neon
- tests/phpstan/configs/optional-leveldb.neon
- tests/phpstan/configs/phpstan-bugs.neon
- tests/phpstan/configs/pthreads-bugs.neon
- tests/phpstan/configs/runtime-type-checks.neon
parameters:
level: 5
level: 6
autoload_files:
- tests/phpstan/bootstrap.php
- src/pocketmine/PocketMine.php
@ -19,6 +19,7 @@ parameters:
- pocketmine\IS_DEVELOPMENT_BUILD
- pocketmine\DEBUG
reportUnmatchedIgnoredErrors: false #no other way to silence platform-specific non-warnings
checkMissingIterableValueType: false #TODO: pthreads Threaded base for too many things, fix this later
ignoreErrors:
-
message: "#^Cannot instantiate interface pocketmine\\\\level\\\\format\\\\io\\\\LevelProvider\\.$#"
@ -86,11 +87,6 @@ parameters:
count: 1
path: src/pocketmine/level/generator/normal/Normal.php
-
message: "#^Used constant pocketmine\\\\RESOURCE_PATH not found\\.$#"
count: 1
path: src/pocketmine/network/mcpe/protocol/StartGamePacket.php
-
message: "#^Constructor of class pocketmine\\\\scheduler\\\\TaskScheduler has an unused parameter \\$logger\\.$#"
count: 1
@ -108,18 +104,10 @@ parameters:
message: "#^Constant pocketmine\\\\GIT_COMMIT not found\\.$#"
path: src
-
message: "#^Constant pocketmine\\\\PATH not found\\.$#"
path: src
-
message: "#^Constant pocketmine\\\\PLUGIN_PATH not found\\.$#"
path: src
-
message: "#^Constant pocketmine\\\\RESOURCE_PATH not found\\.$#"
path: src
-
message: "#^Constant pocketmine\\\\START_TIME not found\\.$#"
path: src

View File

@ -25,12 +25,16 @@ namespace pocketmine;
abstract class Collectable extends \Threaded{
/** @var bool */
private $isGarbage = false;
public function isGarbage() : bool{
return $this->isGarbage;
}
/**
* @return void
*/
public function setGarbage(){
$this->isGarbage = true;
}

View File

@ -0,0 +1,33 @@
<?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;
// composer autoload doesn't use require_once and also pthreads can inherit things
if(defined('pocketmine\_CORE_CONSTANTS_INCLUDED')){
return;
}
define('pocketmine\_CORE_CONSTANTS_INCLUDED', true);
define('pocketmine\PATH', dirname(__DIR__, 2) . '/');
define('pocketmine\RESOURCE_PATH', __DIR__ . '/resources/');

View File

@ -96,8 +96,11 @@ class CrashDump{
/** @var Server */
private $server;
/** @var resource */
private $fp;
/** @var int */
private $time;
/** @var mixed[] */
private $data = [];
/** @var string */
private $encodedData = "";
@ -134,6 +137,9 @@ class CrashDump{
return $this->path;
}
/**
* @return string
*/
public function getEncodedData(){
return $this->encodedData;
}
@ -142,7 +148,7 @@ class CrashDump{
return $this->data;
}
private function encodeData(){
private function encodeData() : void{
$this->addLine();
$this->addLine("----------------------REPORT THE DATA BELOW THIS LINE-----------------------");
$this->addLine();
@ -158,7 +164,7 @@ class CrashDump{
$this->addLine("===END CRASH DUMP===");
}
private function pluginsData(){
private function pluginsData() : void{
if($this->server->getPluginManager() instanceof PluginManager){
$this->addLine();
$this->addLine("Loaded plugins:");
@ -182,7 +188,7 @@ class CrashDump{
}
}
private function extraData(){
private function extraData() : void{
global $argv;
if($this->server->getProperty("auto-report.send-settings", true) !== false){
@ -209,7 +215,7 @@ class CrashDump{
}
}
private function baseCrash(){
private function baseCrash() : void{
global $lastExceptionError, $lastError;
if(isset($lastExceptionError)){
@ -317,7 +323,7 @@ class CrashDump{
return false;
}
private function generalData(){
private function generalData() : void{
$version = new VersionString(\pocketmine\BASE_VERSION, \pocketmine\IS_DEVELOPMENT_BUILD, \pocketmine\BUILD_NUMBER);
$this->data["general"] = [];
$this->data["general"]["name"] = $this->server->getName();
@ -340,10 +346,20 @@ class CrashDump{
$this->addLine("OS : " . PHP_OS . ", " . Utils::getOS());
}
/**
* @param string $line
*
* @return void
*/
public function addLine($line = ""){
fwrite($this->fp, $line . PHP_EOL);
}
/**
* @param string $str
*
* @return void
*/
public function add($str){
fwrite($this->fp, $str);
}

View File

@ -44,6 +44,8 @@ interface IPlayer extends ServerOperator{
/**
* @param bool $banned
*
* @return void
*/
public function setBanned(bool $banned);
@ -54,6 +56,8 @@ interface IPlayer extends ServerOperator{
/**
* @param bool $value
*
* @return void
*/
public function setWhitelisted(bool $value);

View File

@ -115,7 +115,7 @@ class MemoryManager{
$this->init();
}
private function init(){
private function init() : void{
$this->memoryLimit = ((int) $this->server->getProperty("memory.main-limit", 0)) * 1024 * 1024;
$defaultMemory = 1024;
@ -201,6 +201,8 @@ class MemoryManager{
* @param int $limit
* @param bool $global
* @param int $triggerCount
*
* @return void
*/
public function trigger(int $memory, int $limit, bool $global = false, int $triggerCount = 0){
$this->server->getLogger()->debug(sprintf("[Memory Manager] %sLow memory triggered, limit %gMB, using %gMB",
@ -230,6 +232,8 @@ class MemoryManager{
/**
* Called every tick to update the memory manager state.
*
* @return void
*/
public function check(){
Timings::$memoryManagerTimer->startTiming();
@ -297,6 +301,8 @@ class MemoryManager{
* @param string $outputFolder
* @param int $maxNesting
* @param int $maxStringSize
*
* @return void
*/
public function dumpServerMemory(string $outputFolder, int $maxNesting, int $maxStringSize){
$this->server->getLogger()->notice("[Dump] After the memory dump is done, the server might crash");
@ -319,6 +325,7 @@ class MemoryManager{
* @param int $maxStringSize
* @param \Logger $logger
*
* @return void
* @throws \ReflectionException
*/
public static function dumpMemory($startingObject, string $outputFolder, int $maxNesting, int $maxStringSize, \Logger $logger){
@ -472,14 +479,14 @@ class MemoryManager{
/**
* @param mixed $from
* @param mixed &$data
* @param object[] &$objects
* @param int[] &$refCounts
* @param mixed $data reference parameter
* @param object[] $objects reference parameter
* @param int[] $refCounts reference parameter
* @param int $recursion
* @param int $maxNesting
* @param int $maxStringSize
*/
private static function continueDump($from, &$data, array &$objects, array &$refCounts, int $recursion, int $maxNesting, int $maxStringSize){
private static function continueDump($from, &$data, array &$objects, array &$refCounts, int $recursion, int $maxNesting, int $maxStringSize) : void{
if($maxNesting <= 0){
$data = "(error) NESTING LIMIT REACHED";
return;

View File

@ -57,6 +57,9 @@ class OfflinePlayer implements IPlayer, Metadatable{
return $this->name;
}
/**
* @return Server
*/
public function getServer(){
return $this->server;
}

View File

@ -282,6 +282,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** @var string */
protected $xuid = "";
/** @var int */
protected $windowCnt = 2;
/** @var int[] */
protected $windows = [];
@ -475,6 +476,11 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return $this->playedBefore;
}
/**
* @param bool $value
*
* @return void
*/
public function setAllowFlight(bool $value){
$this->allowFlight = $value;
$this->sendSettings();
@ -484,6 +490,11 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return $this->allowFlight;
}
/**
* @param bool $value
*
* @return void
*/
public function setFlying(bool $value){
if($this->flying !== $value){
$this->flying = $value;
@ -496,6 +507,11 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return $this->flying;
}
/**
* @param bool $value
*
* @return void
*/
public function setAutoJump(bool $value){
$this->autoJump = $value;
$this->sendSettings();
@ -509,6 +525,11 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return $this->allowMovementCheats;
}
/**
* @param bool $value
*
* @return void
*/
public function setAllowMovementCheats(bool $value = true){
$this->allowMovementCheats = $value;
}
@ -538,6 +559,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/**
* @param bool $remove
*
* @return void
*/
public function setRemoveFormat(bool $remove = true){
$this->removeFormat = $remove;
@ -565,6 +588,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/**
* @param Player $player
*
* @return void
*/
public function hidePlayer(Player $player){
if($player === $this){
@ -576,6 +601,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/**
* @param Player $player
*
* @return void
*/
public function showPlayer(Player $player){
if($player === $this){
@ -604,6 +631,11 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return $this->viewDistance;
}
/**
* @param int $distance
*
* @return void
*/
public function setViewDistance(int $distance){
$this->viewDistance = $this->server->getAllowedViewDistance($distance);
@ -634,6 +666,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/**
* @param bool $value
*
* @return void
*/
public function setOp(bool $value){
if($value === $this->isOp()){
@ -685,6 +719,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/**
* @param PermissionAttachment $attachment
*
* @return void
*/
public function removeAttachment(PermissionAttachment $attachment){
$this->perm->removeAttachment($attachment);
@ -720,6 +756,9 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return $this->perm->getEffectivePermissions();
}
/**
* @return void
*/
public function sendCommandData(){
$pk = new AvailableCommandsPacket();
foreach($this->server->getCommandMap()->getCommands() as $name => $command){
@ -817,6 +856,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/**
* @param string $name
*
* @return void
*/
public function setDisplayName(string $name){
$this->displayName = $name;
@ -902,6 +943,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
* @internal Plugins should not use this method.
*
* @param int $pingMS
*
* @return void
*/
public function updatePing(int $pingMS){
$this->lastPingMeasure = $pingMS;
@ -926,6 +969,11 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return $this->getGenericFlag(self::DATA_FLAG_ACTION) and $this->startAction > -1;
}
/**
* @param bool $value
*
* @return void
*/
public function setUsingItem(bool $value){
$this->startAction = $value ? $this->server->getTick() : -1;
$this->setGenericFlag(self::DATA_FLAG_ACTION, $value);
@ -995,6 +1043,13 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return false;
}
/**
* @param int $x
* @param int $z
* @param Level|null $level
*
* @return void
*/
protected function unloadChunk(int $x, int $z, Level $level = null){
$level = $level ?? $this->level;
$index = Level::chunkHash($x, $z);
@ -1011,6 +1066,13 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
unset($this->loadQueue[$index]);
}
/**
* @param int $x
* @param int $z
* @param BatchPacket $payload
*
* @return void
*/
public function sendChunk(int $x, int $z, BatchPacket $payload){
if(!$this->isConnected()){
return;
@ -1033,6 +1095,9 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
}
}
/**
* @return void
*/
protected function sendNextChunk(){
if(!$this->isConnected()){
return;
@ -1067,6 +1132,9 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
Timings::$playerChunkSendTimer->stopTiming();
}
/**
* @return void
*/
public function doFirstSpawn(){
if($this->spawned){
return; //avoid player spawning twice (this can only happen on 3.x with a custom malicious client)
@ -1116,6 +1184,12 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
}
}
/**
* @param Vector3 $pos
* @param int $respawnState
*
* @return void
*/
protected function sendRespawnPacket(Vector3 $pos, int $respawnState = RespawnPacket::SEARCHING_FOR_SPAWN){
$pk = new RespawnPacket();
$pk->position = $pos->add(0, $this->baseOffset, 0);
@ -1245,6 +1319,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
* Position object
*
* @param Vector3|Position $pos
*
* @return void
*/
public function setSpawn(Vector3 $pos){
if(!($pos instanceof Position)){
@ -1304,6 +1380,9 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return true;
}
/**
* @return void
*/
public function stopSleep(){
if($this->sleeping instanceof Vector3){
$b = $this->level->getBlock($this->sleeping);
@ -1367,6 +1446,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/**
* @param string $achievementId
*
* @return void
*/
public function removeAchievement(string $achievementId){
if($this->hasAchievement($achievementId)){
@ -1455,6 +1536,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/**
* @internal
* Sends the player's gamemode to the client.
*
* @return void
*/
public function sendGamemode(){
$pk = new SetPlayerGameTypePacket();
@ -1464,6 +1547,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/**
* Sends all the option flags
*
* @return void
*/
public function sendSettings(){
$pk = new AdventureSettingsPacket();
@ -1569,6 +1654,9 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return false; //currently has no server-side movement
}
/**
* @return void
*/
protected function checkNearEntities(){
foreach($this->level->getNearbyEntities($this->boundingBox->expandedCopy(1, 0.5, 1), $this) as $entity){
$entity->scheduleUpdate();
@ -1581,6 +1669,11 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
}
}
/**
* @param int $tickDiff
*
* @return void
*/
protected function processMovement(int $tickDiff){
if(!$this->isAlive() or !$this->spawned or $this->newPosition === null or $this->isSleeping()){
return;
@ -1723,6 +1816,11 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
}
/**
* @param bool $sendAll
*
* @return void
*/
public function sendAttributes(bool $sendAll = false){
$entries = $sendAll ? $this->attributeMap->getAll() : $this->attributeMap->needSend();
if(count($entries) > 0){
@ -1828,6 +1926,9 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$this->dataPacket($pk);
}
/**
* @return void
*/
public function checkNetwork(){
if(!$this->isOnline()){
return;
@ -1976,6 +2077,12 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return true;
}
/**
* @param int $status
* @param bool $immediate
*
* @return void
*/
public function sendPlayStatus(int $status, bool $immediate = false){
$pk = new PlayStatusPacket();
$pk->status = $status;
@ -2019,6 +2126,9 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$this->processLogin();
}
/**
* @return void
*/
protected function processLogin(){
foreach($this->server->getLoggedInPlayers() as $p){
if($p !== $this and ($p->iusername === $this->iusername or $this->getUniqueId()->equals($p->getUniqueId()))){
@ -2135,6 +2245,9 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return true;
}
/**
* @return void
*/
protected function completeLoginSequence(){
/** @var float[] $pos */
$pos = $this->namedtag->getListTag("Pos")->getAllValues();
@ -3155,6 +3268,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
* Called when a packet is received from the client. This method will call DataPacketReceiveEvent.
*
* @param DataPacket $packet
*
* @return void
*/
public function handleDataPacket(DataPacket $packet){
if($this->sessionAdapter !== null){
@ -3312,6 +3427,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
* @param int $fadeIn Duration in ticks for fade-in. If -1 is given, client-sided defaults will be used.
* @param int $stay Duration in ticks to stay on screen for
* @param int $fadeOut Duration in ticks for fade-out.
*
* @return void
*/
public function addTitle(string $title, string $subtitle = "", int $fadeIn = -1, int $stay = -1, int $fadeOut = -1){
$this->setTitleDuration($fadeIn, $stay, $fadeOut);
@ -3325,6 +3442,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
* Sets the subtitle message, without sending a title.
*
* @param string $subtitle
*
* @return void
*/
public function addSubTitle(string $subtitle){
$this->sendTitleText($subtitle, SetTitlePacket::TYPE_SET_SUBTITLE);
@ -3334,6 +3453,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
* Adds small text to the user's screen.
*
* @param string $message
*
* @return void
*/
public function addActionBarMessage(string $message){
$this->sendTitleText($message, SetTitlePacket::TYPE_SET_ACTIONBAR_MESSAGE);
@ -3341,6 +3462,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/**
* Removes the title from the client's screen.
*
* @return void
*/
public function removeTitles(){
$pk = new SetTitlePacket();
@ -3350,6 +3473,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/**
* Resets the title duration settings to defaults and removes any existing titles.
*
* @return void
*/
public function resetTitles(){
$pk = new SetTitlePacket();
@ -3363,6 +3488,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
* @param int $fadeIn Title fade-in time in ticks.
* @param int $stay Title stay time in ticks.
* @param int $fadeOut Title fade-out time in ticks.
*
* @return void
*/
public function setTitleDuration(int $fadeIn, int $stay, int $fadeOut){
if($fadeIn >= 0 and $stay >= 0 and $fadeOut >= 0){
@ -3380,6 +3507,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
*
* @param string $title
* @param int $type
*
* @return void
*/
protected function sendTitleText(string $title, int $type){
$pk = new SetTitlePacket();
@ -3392,6 +3521,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
* Sends a direct chat message to a player
*
* @param TextContainer|string $message
*
* @return void
*/
public function sendMessage($message){
if($message instanceof TextContainer){
@ -3411,6 +3542,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/**
* @param string $message
* @param string[] $parameters
*
* @return void
*/
public function sendTranslation(string $message, array $parameters = []){
$pk = new TextPacket();
@ -3436,6 +3569,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
*
* @param string $message
* @param string $subtitle @deprecated
*
* @return void
*/
public function sendPopup(string $message, string $subtitle = ""){
$pk = new TextPacket();
@ -3444,6 +3579,11 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$this->dataPacket($pk);
}
/**
* @param string $message
*
* @return void
*/
public function sendTip(string $message){
$pk = new TextPacket();
$pk->type = TextPacket::TYPE_TIP;
@ -3454,6 +3594,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/**
* @param string $sender
* @param string $message
*
* @return void
*/
public function sendWhisper(string $sender, string $message){
$pk = new TextPacket();
@ -3595,6 +3737,9 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
}
}
/**
* @return mixed[]
*/
public function __debugInfo(){
return [];
}
@ -3611,6 +3756,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
* Handles player data saving
*
* @throws \InvalidStateException if the player is closed
*
* @return void
*/
public function save(){
if($this->closed){
@ -3773,6 +3920,15 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return $result;
}
/**
* @param Vector3 $pos
* @param float|null $yaw
* @param float|null $pitch
* @param int $mode
* @param Player[]|null $targets
*
* @return void
*/
public function sendPosition(Vector3 $pos, float $yaw = null, float $pitch = null, int $mode = MovePlayerPacket::MODE_NORMAL, array $targets = null){
$yaw = $yaw ?? $this->yaw;
$pitch = $pitch ?? $this->pitch;
@ -3824,6 +3980,9 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return false;
}
/**
* @return void
*/
protected function addDefaultWindows(){
$this->addWindow($this->getInventory(), ContainerIds::INVENTORY, true);
@ -3949,6 +4108,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
* @param Inventory $inventory
* @param bool $force Forces removal of permanent windows such as normal inventory, cursor
*
* @return void
* @throws \InvalidArgumentException if trying to remove a fixed inventory window without the `force` parameter as true
*/
public function removeWindow(Inventory $inventory, bool $force = false){
@ -3968,6 +4128,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
* Removes all inventory windows from the player. By default this WILL NOT remove permanent windows.
*
* @param bool $removePermanentWindows Whether to remove permanent windows.
*
* @return void
*/
public function removeAllWindows(bool $removePermanentWindows = false){
foreach($this->windowIndex as $id => $window){
@ -3979,6 +4141,9 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
}
}
/**
* @return void
*/
protected function sendAllInventories(){
foreach($this->windowIndex as $id => $inventory){
$inventory->sendContents($this);

View File

@ -36,6 +36,10 @@ namespace pocketmine {
const MIN_PHP_VERSION = "7.2.0";
/**
* @param string $message
* @return void
*/
function critical_error($message){
echo "[ERROR] $message" . PHP_EOL;
}
@ -117,6 +121,10 @@ namespace pocketmine {
return $messages;
}
/**
* @param \Logger $logger
* @return void
*/
function emit_performance_warnings(\Logger $logger){
if(extension_loaded("xdebug")){
$logger->warning("Xdebug extension is enabled. This has a major impact on performance.");
@ -132,6 +140,9 @@ namespace pocketmine {
}
}
/**
* @return void
*/
function set_ini_entries(){
ini_set("allow_url_fopen", '1');
ini_set("display_errors", '1');
@ -140,6 +151,9 @@ namespace pocketmine {
ini_set('assert.exception', '1');
}
/**
* @return void
*/
function server(){
if(count($messages = check_platform_dependencies()) > 0){
echo PHP_EOL;
@ -157,17 +171,11 @@ namespace pocketmine {
error_reporting(-1);
set_ini_entries();
if(\Phar::running(true) !== ""){
define('pocketmine\PATH', \Phar::running(true) . "/");
}else{
define('pocketmine\PATH', dirname(__FILE__, 3) . DIRECTORY_SEPARATOR);
}
$opts = getopt("", ["bootstrap:"]);
if(isset($opts["bootstrap"])){
$bootstrap = realpath($opts["bootstrap"]) ?: $opts["bootstrap"];
}else{
$bootstrap = \pocketmine\PATH . 'vendor/autoload.php';
$bootstrap = dirname(__FILE__, 3) . '/vendor/autoload.php';
}
define('pocketmine\COMPOSER_AUTOLOADER_PATH', $bootstrap);
@ -198,8 +206,6 @@ namespace pocketmine {
define('pocketmine\GIT_COMMIT', $gitHash);
define('pocketmine\RESOURCE_PATH', \pocketmine\PATH . 'src' . DIRECTORY_SEPARATOR . 'pocketmine' . DIRECTORY_SEPARATOR . 'resources' . DIRECTORY_SEPARATOR);
$opts = getopt("", ["data:", "plugins:", "no-wizard", "enable-ansi", "disable-ansi"]);
define('pocketmine\DATA', isset($opts["data"]) ? $opts["data"] . DIRECTORY_SEPARATOR : realpath(getcwd()) . DIRECTORY_SEPARATOR);

View File

@ -483,6 +483,8 @@ class Server{
/**
* @param bool $value
*
* @return void
*/
public function setAutoSave(bool $value){
$this->autoSave = $value;
@ -874,6 +876,8 @@ class Server{
/**
* @param string $name
* @param CompoundTag $nbtTag
*
* @return void
*/
public function saveOfflinePlayerData(string $name, CompoundTag $nbtTag){
$ev = new PlayerDataSaveEvent($nbtTag, $name);
@ -1277,6 +1281,8 @@ class Server{
/**
* @param string $variable
* @param string $value
*
* @return void
*/
public function setConfigString(string $variable, string $value){
$this->properties->set($variable, $value);
@ -1300,6 +1306,8 @@ class Server{
/**
* @param string $variable
* @param int $value
*
* @return void
*/
public function setConfigInt(string $variable, int $value){
$this->properties->set($variable, $value);
@ -1336,6 +1344,8 @@ class Server{
/**
* @param string $variable
* @param bool $value
*
* @return void
*/
public function setConfigBool(string $variable, bool $value){
$this->properties->set($variable, $value ? "1" : "0");
@ -1370,6 +1380,8 @@ class Server{
/**
* @param string $name
*
* @return void
*/
public function addOp(string $name){
$this->operators->set(strtolower($name), true);
@ -1382,6 +1394,8 @@ class Server{
/**
* @param string $name
*
* @return void
*/
public function removeOp(string $name){
$this->operators->remove(strtolower($name));
@ -1394,6 +1408,8 @@ class Server{
/**
* @param string $name
*
* @return void
*/
public function addWhitelist(string $name){
$this->whitelist->set(strtolower($name), true);
@ -1402,6 +1418,8 @@ class Server{
/**
* @param string $name
*
* @return void
*/
public function removeWhitelist(string $name){
$this->whitelist->remove(strtolower($name));
@ -1440,6 +1458,9 @@ class Server{
return $this->operators;
}
/**
* @return void
*/
public function reloadWhitelist(){
$this->whitelist->reload();
}
@ -1476,6 +1497,11 @@ class Server{
return self::$instance;
}
/**
* @param int $microseconds
*
* @return void
*/
public static function microSleep(int $microseconds){
Server::$sleeper->synchronized(function(int $ms){
Server::$sleeper->wait($ms);
@ -1913,6 +1939,8 @@ class Server{
*
* @param Player[] $players
* @param DataPacket $packet
*
* @return void
*/
public function broadcastPacket(array $players, DataPacket $packet){
$packet->encode();
@ -1926,6 +1954,8 @@ class Server{
* @param DataPacket[] $packets
* @param bool $forceSync
* @param bool $immediate
*
* @return void
*/
public function batchPackets(array $players, array $packets, bool $forceSync = false, bool $immediate = false){
if(count($packets) === 0){
@ -1964,6 +1994,8 @@ class Server{
* @param BatchPacket $pk
* @param Player[] $players
* @param bool $immediate
*
* @return void
*/
public function broadcastPacketsCallback(BatchPacket $pk, array $players, bool $immediate = false){
if(!$pk->isEncoded){
@ -1978,6 +2010,8 @@ class Server{
/**
* @param int $type
*
* @return void
*/
public function enablePlugins(int $type){
foreach($this->pluginManager->getPlugins() as $plugin){
@ -1994,11 +2028,16 @@ class Server{
/**
* @param Plugin $plugin
*
* @return void
*/
public function enablePlugin(Plugin $plugin){
$this->pluginManager->enablePlugin($plugin);
}
/**
* @return void
*/
public function disablePlugins(){
$this->pluginManager->disablePlugins();
}
@ -2033,6 +2072,9 @@ class Server{
return false;
}
/**
* @return void
*/
public function reload(){
$this->logger->info("Saving worlds...");
@ -2072,11 +2114,16 @@ class Server{
/**
* Shuts the server down correctly
*
* @return void
*/
public function shutdown(){
$this->isRunning = false;
}
/**
* @return void
*/
public function forceShutdown(){
if($this->hasStopped){
return;
@ -2162,7 +2209,7 @@ class Server{
/**
* Starts the PocketMine-MP server and starts processing ticks and packets
*/
private function start(){
private function start() : void{
if($this->getConfigBool("enable-query", true)){
$this->queryHandler = new QueryHandler();
}
@ -2204,6 +2251,11 @@ class Server{
$this->forceShutdown();
}
/**
* @param int $signo
*
* @return void
*/
public function handleSignal($signo){
if($signo === SIGTERM or $signo === SIGINT or $signo === SIGHUP){
$this->shutdown();
@ -2213,6 +2265,8 @@ class Server{
/**
* @param \Throwable $e
* @param array|null $trace
*
* @return void
*/
public function exceptionHandler(\Throwable $e, $trace = null){
while(@ob_end_flush()){}
@ -2331,6 +2385,9 @@ class Server{
exit(1);
}
/**
* @return mixed[]
*/
public function __debugInfo(){
return [];
}
@ -2339,7 +2396,7 @@ class Server{
return $this->tickSleeper;
}
private function tickProcessor(){
private function tickProcessor() : void{
$this->nextTick = microtime(true);
while($this->isRunning){
@ -2350,6 +2407,11 @@ class Server{
}
}
/**
* @param Player $player
*
* @return void
*/
public function onPlayerLogin(Player $player){
if($this->sendUsageTicker > 0){
$this->uniquePlayers[$player->getRawUniqueId()] = $player->getRawUniqueId();
@ -2358,27 +2420,49 @@ class Server{
$this->loggedInPlayers[$player->getRawUniqueId()] = $player;
}
/**
* @param Player $player
*
* @return void
*/
public function onPlayerLogout(Player $player){
unset($this->loggedInPlayers[$player->getRawUniqueId()]);
}
/**
* @param Player $player
*
* @return void
*/
public function addPlayer(Player $player){
$this->players[spl_object_hash($player)] = $player;
}
/**
* @param Player $player
*
* @return void
*/
public function removePlayer(Player $player){
unset($this->players[spl_object_hash($player)]);
}
/**
* @param Player $player
*
* @return void
*/
public function addOnlinePlayer(Player $player){
$this->updatePlayerListData($player->getUniqueId(), $player->getId(), $player->getDisplayName(), $player->getSkin(), $player->getXuid());
$this->playerList[$player->getRawUniqueId()] = $player;
}
/**
* @param Player $player
*
* @return void
*/
public function removeOnlinePlayer(Player $player){
if(isset($this->playerList[$player->getRawUniqueId()])){
unset($this->playerList[$player->getRawUniqueId()]);
@ -2394,6 +2478,8 @@ class Server{
* @param Skin $skin
* @param string $xboxUserId
* @param Player[]|null $players
*
* @return void
*/
public function updatePlayerListData(UUID $uuid, int $entityId, string $name, Skin $skin, string $xboxUserId = "", array $players = null){
$pk = new PlayerListPacket();
@ -2407,6 +2493,8 @@ class Server{
/**
* @param UUID $uuid
* @param Player[]|null $players
*
* @return void
*/
public function removePlayerListData(UUID $uuid, array $players = null){
$pk = new PlayerListPacket();
@ -2417,6 +2505,8 @@ class Server{
/**
* @param Player $p
*
* @return void
*/
public function sendFullPlayerListData(Player $p){
$pk = new PlayerListPacket();
@ -2452,6 +2542,9 @@ class Server{
}
}
/**
* @return void
*/
public function doAutoSave(){
if($this->getAutoSave()){
Timings::$worldSaveTimer->startTiming();
@ -2470,6 +2563,11 @@ class Server{
}
}
/**
* @param int $type
*
* @return void
*/
public function sendUsage($type = SendUsageTask::TYPE_STATUS){
if((bool) $this->getProperty("anonymous-statistics.enabled", true)){
$this->asyncPool->submitTask(new SendUsageTask($this, $type, $this->uniquePlayers));
@ -2506,7 +2604,7 @@ class Server{
return $this->memoryManager;
}
private function titleTick(){
private function titleTick() : void{
Timings::$titleTickTimer->startTiming();
$d = Utils::getRealMemoryUsage();
@ -2531,6 +2629,8 @@ class Server{
* @param int $port
* @param string $payload
*
* @return void
*
* TODO: move this to Network
*/
public function handlePacket(AdvancedSourceInterface $interface, string $address, int $port, string $payload){

View File

@ -33,12 +33,21 @@ abstract class Thread extends \Thread{
/** @var string|null */
protected $composerAutoloaderPath;
/** @var bool */
protected $isKilled = false;
/**
* @return \ClassLoader|null
*/
public function getClassLoader(){
return $this->classLoader;
}
/**
* @param \ClassLoader|null $loader
*
* @return void
*/
public function setClassLoader(\ClassLoader $loader = null){
$this->composerAutoloaderPath = \pocketmine\COMPOSER_AUTOLOADER_PATH;
@ -54,6 +63,8 @@ abstract class Thread extends \Thread{
* WARNING: This method MUST be called from any descendent threads' run() method to make autoloading usable.
* If you do not do this, you will not be able to use new classes that were not loaded when the thread was started
* (unless you are using a custom autoloader).
*
* @return void
*/
public function registerClassLoader(){
if($this->composerAutoloaderPath !== null){
@ -64,6 +75,11 @@ abstract class Thread extends \Thread{
}
}
/**
* @param int|null $options TODO: pthreads bug
*
* @return bool
*/
public function start(?int $options = \PTHREADS_INHERIT_ALL){
ThreadManager::getInstance()->add($this);
@ -75,6 +91,8 @@ abstract class Thread extends \Thread{
/**
* Stops the thread using the best way possible. Try to stop it yourself before calling this.
*
* @return void
*/
public function quit(){
$this->isKilled = true;

View File

@ -31,6 +31,9 @@ class ThreadManager extends \Volatile{
/** @var ThreadManager */
private static $instance = null;
/**
* @return void
*/
public static function init(){
self::$instance = new ThreadManager();
}
@ -44,6 +47,8 @@ class ThreadManager extends \Volatile{
/**
* @param Worker|Thread $thread
*
* @return void
*/
public function add($thread){
if($thread instanceof Thread or $thread instanceof Worker){
@ -53,6 +58,8 @@ class ThreadManager extends \Volatile{
/**
* @param Worker|Thread $thread
*
* @return void
*/
public function remove($thread){
if($thread instanceof Thread or $thread instanceof Worker){

View File

@ -32,6 +32,6 @@ const _VERSION_INFO_INCLUDED = true;
const NAME = "PocketMine-MP";
const BASE_VERSION = "3.11.3";
const BASE_VERSION = "3.11.4";
const IS_DEVELOPMENT_BUILD = false;
const BUILD_NUMBER = 0;

View File

@ -33,12 +33,21 @@ abstract class Worker extends \Worker{
/** @var string|null */
protected $composerAutoloaderPath;
/** @var bool */
protected $isKilled = false;
/**
* @return \ClassLoader|null
*/
public function getClassLoader(){
return $this->classLoader;
}
/**
* @param \ClassLoader|null $loader
*
* @return void
*/
public function setClassLoader(\ClassLoader $loader = null){
$this->composerAutoloaderPath = \pocketmine\COMPOSER_AUTOLOADER_PATH;
@ -54,6 +63,8 @@ abstract class Worker extends \Worker{
* WARNING: This method MUST be called from any descendent threads' run() method to make autoloading usable.
* If you do not do this, you will not be able to use new classes that were not loaded when the thread was started
* (unless you are using a custom autoloader).
*
* @return void
*/
public function registerClassLoader(){
if($this->composerAutoloaderPath !== null){
@ -64,6 +75,11 @@ abstract class Worker extends \Worker{
}
}
/**
* @param int|null $options TODO: pthreads bug
*
* @return bool
*/
public function start(?int $options = \PTHREADS_INHERIT_ALL){
ThreadManager::getInstance()->add($this);
@ -75,6 +91,8 @@ abstract class Worker extends \Worker{
/**
* Stops the thread using the best way possible. Try to stop it yourself before calling this.
*
* @return void
*/
public function quit(){
$this->isKilled = true;

View File

@ -76,6 +76,11 @@ class Bed extends Transparent{
return ($this->meta & self::BITFLAG_OCCUPIED) !== 0;
}
/**
* @param bool $occupied
*
* @return void
*/
public function setOccupied(bool $occupied = true){
if($occupied){
$this->meta |= self::BITFLAG_OCCUPIED;

View File

@ -111,6 +111,11 @@ class CobblestoneWall extends Transparent{
);
}
/**
* @param Block $block
*
* @return bool
*/
public function canConnect(Block $block){
return $block instanceof static or $block instanceof FenceGate or ($block->isSolid() and !$block->isTransparent());
}

View File

@ -36,7 +36,7 @@ abstract class Door extends Transparent{
return false;
}
private function getFullDamage(){
private function getFullDamage() : int{
$damage = $this->getDamage();
$isUp = ($damage & 0x08) > 0;

View File

@ -103,6 +103,11 @@ abstract class Fence extends Transparent{
return $bbs;
}
/**
* @param Block $block
*
* @return bool
*/
public function canConnect(Block $block){
return $block instanceof static or $block instanceof FenceGate or ($block->isSolid() and !$block->isTransparent());
}

View File

@ -39,6 +39,7 @@ class Leaves extends Transparent{
public const DARK_OAK = 1;
protected $id = self::LEAVES;
/** @var int */
protected $woodType = self::WOOD;
public function __construct(int $meta = 0){
@ -68,7 +69,7 @@ class Leaves extends Transparent{
}
protected function findLog(Block $pos, array $visited, int $distance, ?int $fromSide = null) : bool{
protected function findLog(Block $pos, array &$visited, int $distance, ?int $fromSide = null) : bool{
$index = $pos->x . "." . $pos->y . "." . $pos->z;
if(isset($visited[$index])){
return false;

View File

@ -29,6 +29,7 @@ use pocketmine\item\ItemFactory;
class Leaves2 extends Leaves{
protected $id = self::LEAVES2;
/** @var int */
protected $woodType = self::WOOD2;
public function getName() : string{

View File

@ -38,6 +38,7 @@ use function min;
abstract class Liquid extends Transparent{
/** @var int */
public $adjacentSources = 0;
/** @var Vector3|null */
@ -90,6 +91,9 @@ abstract class Liquid extends Transparent{
abstract public function getBucketEmptySound() : int;
/**
* @return float
*/
public function getFluidHeightPercent(){
$d = $this->meta;
if($d >= 8){
@ -430,6 +434,9 @@ abstract class Liquid extends Transparent{
return ($decay >= 0 && $blockDecay >= $decay) ? $decay : $blockDecay;
}
/**
* @return void
*/
protected function checkForHarden(){
}

View File

@ -74,6 +74,11 @@ class TNT extends Solid{
}
}
/**
* @param int $fuse
*
* @return void
*/
public function ignite(int $fuse = 80){
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true);

View File

@ -114,6 +114,8 @@ abstract class Command{
/**
* @param string|null $permission
*
* @return void
*/
public function setPermission(string $permission = null){
$this->permission = $permission;
@ -259,6 +261,8 @@ abstract class Command{
/**
* @param string[] $aliases
*
* @return void
*/
public function setAliases(array $aliases){
$this->aliases = $aliases;
@ -269,6 +273,8 @@ abstract class Command{
/**
* @param string $description
*
* @return void
*/
public function setDescription(string $description){
$this->description = $description;
@ -276,6 +282,8 @@ abstract class Command{
/**
* @param string $permissionMessage
*
* @return void
*/
public function setPermissionMessage(string $permissionMessage){
$this->permissionMessage = $permissionMessage;
@ -283,6 +291,8 @@ abstract class Command{
/**
* @param string $usage
*
* @return void
*/
public function setUsage(string $usage){
$this->usageMessage = $usage;
@ -292,6 +302,8 @@ abstract class Command{
* @param CommandSender $source
* @param TextContainer|string $message
* @param bool $sendToSource
*
* @return void
*/
public static function broadcastCommandMessage(CommandSender $source, $message, bool $sendToSource = true){
if($message instanceof TextContainer){

View File

@ -29,6 +29,8 @@ interface CommandMap{
/**
* @param string $fallbackPrefix
* @param Command[] $commands
*
* @return void
*/
public function registerAll(string $fallbackPrefix, array $commands);

View File

@ -54,7 +54,9 @@ class CommandReader extends Thread{
/** @var \Threaded */
protected $buffer;
/** @var bool */
private $shutdown = false;
/** @var int */
private $type = self::TYPE_STREAM;
/** @var SleeperNotifier|null */
@ -71,6 +73,9 @@ class CommandReader extends Thread{
}
}
/**
* @return void
*/
public function shutdown(){
$this->shutdown = true;
}
@ -94,7 +99,7 @@ class CommandReader extends Thread{
throw new \ThreadException($message);
}
private function initStdin(){
private function initStdin() : void{
if(is_resource(self::$stdin)){
fclose(self::$stdin);
}
@ -185,6 +190,9 @@ class CommandReader extends Thread{
return null;
}
/**
* @return void
*/
public function run(){
$this->registerClassLoader();

View File

@ -31,6 +31,8 @@ interface CommandSender extends Permissible{
/**
* @param TextContainer|string $message
*
* @return void
*/
public function sendMessage($message);
@ -56,6 +58,8 @@ interface CommandSender extends Permissible{
* Sets the line height used for command output pagination for this command sender. `null` will reset it to default.
*
* @param int|null $height
*
* @return void
*/
public function setScreenLineHeight(int $height = null);
}

View File

@ -37,6 +37,7 @@ use const PHP_INT_MAX;
class ConsoleCommandSender implements CommandSender{
/** @var PermissibleBase */
private $perm;
/** @var int|null */
@ -104,6 +105,8 @@ class ConsoleCommandSender implements CommandSender{
/**
* @param TextContainer|string $message
*
* @return void
*/
public function sendMessage($message){
if($message instanceof TextContainer){
@ -133,6 +136,8 @@ class ConsoleCommandSender implements CommandSender{
/**
* @param bool $value
*
* @return void
*/
public function setOp(bool $value){

View File

@ -32,6 +32,7 @@ use function strpos;
use function substr;
class FormattedCommandAlias extends Command{
/** @var string[] */
private $formatStrings = [];
/**

View File

@ -70,6 +70,8 @@ class PluginCommand extends Command implements PluginIdentifiableCommand{
/**
* @param CommandExecutor $executor
*
* @return void
*/
public function setExecutor(CommandExecutor $executor){
$this->executor = $executor;

View File

@ -41,6 +41,9 @@ class RemoteConsoleCommandSender extends ConsoleCommandSender{
$this->messages .= trim($message, "\r\n") . "\n";
}
/**
* @return string
*/
public function getMessage(){
return $this->messages;
}

View File

@ -92,7 +92,7 @@ class SimpleCommandMap implements CommandMap{
$this->setDefaultCommands();
}
private function setDefaultCommands(){
private function setDefaultCommands() : void{
$this->registerAll("pocketmine", [
new BanCommand("ban"),
new BanIpCommand("ban-ip"),
@ -226,8 +226,8 @@ class SimpleCommandMap implements CommandMap{
* This method is intended to provide capability for handling commands with spaces in their name.
* The referenced parameters will be modified accordingly depending on the resulting matched command.
*
* @param string &$commandName
* @param string[] &$args
* @param string $commandName reference parameter
* @param string[] $args reference parameter
*
* @return Command|null
*/

View File

@ -75,7 +75,7 @@ class BanIpCommand extends VanillaCommand{
return true;
}
private function processIPBan(string $ip, CommandSender $sender, string $reason){
private function processIPBan(string $ip, CommandSender $sender, string $reason) : void{
$sender->getServer()->getIPBans()->addBan($ip, $reason, null, $sender->getName());
foreach($sender->getServer()->getOnlinePlayers() as $player){

View File

@ -84,7 +84,7 @@ class VersionCommand extends VanillaCommand{
return true;
}
private function describeToSender(Plugin $plugin, CommandSender $sender){
private function describeToSender(Plugin $plugin, CommandSender $sender) : void{
$desc = $plugin->getDescription();
$sender->sendMessage(TextFormat::DARK_GREEN . $desc->getName() . TextFormat::WHITE . " version " . TextFormat::DARK_GREEN . $desc->getVersion());

View File

@ -46,14 +46,22 @@ class Attribute{
public const HORSE_JUMP_STRENGTH = 14;
public const ZOMBIE_SPAWN_REINFORCEMENTS = 15;
/** @var int */
private $id;
/** @var float */
protected $minValue;
/** @var float */
protected $maxValue;
/** @var float */
protected $defaultValue;
/** @var float */
protected $currentValue;
/** @var string */
protected $name;
/** @var bool */
protected $shouldSend;
/** @var bool */
protected $desynchronized = true;
/** @var Attribute[] */
@ -137,6 +145,11 @@ class Attribute{
return $this->minValue;
}
/**
* @param float $minValue
*
* @return $this
*/
public function setMinValue(float $minValue){
if($minValue > ($max = $this->getMaxValue())){
throw new \InvalidArgumentException("Minimum $minValue is greater than the maximum $max");
@ -153,6 +166,11 @@ class Attribute{
return $this->maxValue;
}
/**
* @param float $maxValue
*
* @return $this
*/
public function setMaxValue(float $maxValue){
if($maxValue < ($min = $this->getMinValue())){
throw new \InvalidArgumentException("Maximum $maxValue is less than the minimum $min");
@ -169,6 +187,11 @@ class Attribute{
return $this->defaultValue;
}
/**
* @param float $defaultValue
*
* @return $this
*/
public function setDefaultValue(float $defaultValue){
if($defaultValue > $this->getMaxValue() or $defaultValue < $this->getMinValue()){
throw new \InvalidArgumentException("Default $defaultValue is outside the range " . $this->getMinValue() . " - " . $this->getMaxValue());

View File

@ -25,6 +25,9 @@ namespace pocketmine\entity;
use function array_filter;
/**
* @phpstan-implements \ArrayAccess<int, float>
*/
class AttributeMap implements \ArrayAccess{
/** @var Attribute[] */
private $attributes = [];
@ -58,6 +61,11 @@ class AttributeMap implements \ArrayAccess{
});
}
/**
* @param int $offset
*
* @return bool
*/
public function offsetExists($offset) : bool{
return isset($this->attributes[$offset]);
}
@ -79,6 +87,9 @@ class AttributeMap implements \ArrayAccess{
$this->attributes[$offset]->setValue($value);
}
/**
* @param int $offset
*/
public function offsetUnset($offset) : void{
throw new \RuntimeException("Could not unset an attribute from an attribute map");
}

View File

@ -32,8 +32,10 @@ use function is_string;
class DataPropertyManager{
/** @var mixed[][] */
private $properties = [];
/** @var mixed[][] */
private $dirtyProperties = [];
public function __construct(){

View File

@ -317,6 +317,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
public const DATA_PLAYER_FLAG_SLEEP = 1;
public const DATA_PLAYER_FLAG_DEAD = 2; //TODO: CHECK
/** @var int */
public static $entityCount = 1;
/** @var string[] */
private static $knownEntities = [];
@ -504,6 +505,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
/** @var float */
private $health = 20.0;
/** @var int */
private $maxHealth = 20;
/** @var float */
@ -1210,15 +1212,19 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
}
protected function updateMovement(bool $teleport = false) : void{
//TODO: hack for client-side AI interference: prevent client sided movement when motion is 0
$this->setImmobile($this->motion->x == 0 and $this->motion->y == 0 and $this->motion->z == 0);
$diffPosition = ($this->x - $this->lastX) ** 2 + ($this->y - $this->lastY) ** 2 + ($this->z - $this->lastZ) ** 2;
$diffRotation = ($this->yaw - $this->lastYaw) ** 2 + ($this->pitch - $this->lastPitch) ** 2;
$diffMotion = $this->motion->subtract($this->lastMotion)->lengthSquared();
if($teleport or $diffPosition > 0.0001 or $diffRotation > 1.0){
$still = $this->motion->lengthSquared() == 0.0;
$wasStill = $this->lastMotion->lengthSquared() == 0.0;
if($wasStill !== $still){
//TODO: hack for client-side AI interference: prevent client sided movement when motion is 0
$this->setImmobile($still);
}
if($teleport or $diffPosition > 0.0001 or $diffRotation > 1.0 or (!$wasStill and $still)){
$this->lastX = $this->x;
$this->lastY = $this->y;
$this->lastZ = $this->z;
@ -1229,7 +1235,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
$this->broadcastMovement($teleport);
}
if($diffMotion > 0.0025 or ($diffMotion > 0.0001 and $this->motion->lengthSquared() <= 0.0001)){ //0.05 ** 2
if($diffMotion > 0.0025 or $wasStill !== $still){ //0.05 ** 2
$this->lastMotion = clone $this->motion;
$this->broadcastMotion();
@ -2279,6 +2285,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
* @param string $name
* @param mixed $value
*
* @return void
* @throws \ErrorException
* @throws \InvalidArgumentException
*/

View File

@ -26,5 +26,8 @@ namespace pocketmine\entity;
interface Explosive{
/**
* @return void
*/
public function explode();
}

View File

@ -81,6 +81,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
/** @var UUID */
protected $uuid;
/** @var string */
protected $rawUUID;
public $width = 0.6;
@ -90,10 +91,14 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
/** @var Skin */
protected $skin;
/** @var int */
protected $foodTickTimer = 0;
/** @var int */
protected $totalXp = 0;
/** @var int */
protected $xpSeed;
/** @var int */
protected $xpCooldown = 0;
protected $baseOffset = 1.62;

View File

@ -70,6 +70,7 @@ abstract class Living extends Entity implements Damageable{
protected $gravity = 0.08;
protected $drag = 0.02;
/** @var int */
protected $attackTime = 0;
/** @var int */
@ -77,6 +78,7 @@ abstract class Living extends Entity implements Damageable{
/** @var int */
protected $maxDeadTicks = 25;
/** @var float */
protected $jumpVelocity = 0.42;
/** @var EffectInstance[] */

View File

@ -42,8 +42,10 @@ class Squid extends WaterAnimal{
/** @var Vector3|null */
public $swimDirection = null;
/** @var float */
public $swimSpeed = 0.1;
/** @var int */
private $switchDirectionTicker = 0;
public function initEntity() : void{

View File

@ -43,6 +43,7 @@ class PrimedTNT extends Entity implements Explosive{
protected $gravity = 0.04;
protected $drag = 0.02;
/** @var int */
protected $fuse;
public $canCollide = false;

View File

@ -35,6 +35,8 @@ interface Cancellable{
/**
* @param bool $value
*
* @return void
*/
public function setCancelled(bool $value = true);
}

View File

@ -27,6 +27,7 @@ use pocketmine\entity\Entity;
use pocketmine\event\Cancellable;
class EntityCombustEvent extends EntityEvent implements Cancellable{
/** @var int */
protected $duration;
/**

View File

@ -99,6 +99,8 @@ class PlayerCreationEvent extends Event{
/**
* @param string $class
*
* @return void
*/
public function setBaseClass($class){
if(!is_a($class, $this->baseClass, true)){
@ -117,6 +119,8 @@ class PlayerCreationEvent extends Event{
/**
* @param string $class
*
* @return void
*/
public function setPlayerClass($class){
if(!is_a($class, $this->baseClass, true)){

View File

@ -40,6 +40,7 @@ class PlayerDeathEvent extends EntityDeathEvent{
/** @var TextContainer|string */
private $deathMessage;
/** @var bool */
private $keepInventory = false;
/**

View File

@ -84,6 +84,8 @@ abstract class BaseInventory implements Inventory{
* WARNING: If the size is smaller, any items past the new size will be lost.
*
* @param int $size
*
* @return void
*/
public function setSize(int $size){
$this->slots->setSize($size);

View File

@ -142,6 +142,9 @@ class DoubleChestInventory extends ChestInventory implements InventoryHolder{
return $this->right;
}
/**
* @return void
*/
public function invalidate(){
$this->left = null;
$this->right = null;

View File

@ -53,6 +53,8 @@ class EnderChestInventory extends ChestInventory{
* Set the holder's position to that of a tile
*
* @param EnderChest $enderChest
*
* @return void
*/
public function setHolderPosition(EnderChest $enderChest){
$this->holder->setComponents($enderChest->getFloorX(), $enderChest->getFloorY(), $enderChest->getFloorZ());

View File

@ -44,6 +44,8 @@ class FurnaceRecipe implements Recipe{
/**
* @param Item $item
*
* @return void
*/
public function setInput(Item $item){
$this->ingredient = clone $item;

View File

@ -39,6 +39,7 @@ class MultiRecipe{
public const TYPE_FIREWORKS = "00000000-0000-0000-0000-000000000002";
public const TYPE_MAP_LOCKING_CARTOGRAPHY = "602234E4-CAC1-4353-8BB7-B1EBFF70024B";
/** @var UUID */
private $uuid;
public function __construct(UUID $uuid){

View File

@ -97,7 +97,7 @@ class PlayerInventory extends BaseInventory{
*
* @throws \InvalidArgumentException
*/
private function throwIfNotHotbarSlot(int $slot){
private function throwIfNotHotbarSlot(int $slot) : void{
if(!$this->isHotbarSlot($slot)){
throw new \InvalidArgumentException("$slot is not a valid hotbar slot index (expected 0 - " . ($this->getHotbarSize() - 1) . ")");
}
@ -132,6 +132,7 @@ class PlayerInventory extends BaseInventory{
* @param bool $send Whether to send updates back to the inventory holder. This should usually be true for plugin calls.
* It should only be false to prevent feedback loops of equipment packets between client and server.
*
* @return void
* @throws \InvalidArgumentException if the hotbar slot is out of range
*/
public function setHeldItemIndex(int $hotbarSlot, bool $send = true){
@ -170,6 +171,8 @@ class PlayerInventory extends BaseInventory{
* Sends the currently-held item to specified targets.
*
* @param Player|Player[] $target
*
* @return void
*/
public function sendHeldItem($target){
$item = $this->getItemInHand();
@ -201,6 +204,9 @@ class PlayerInventory extends BaseInventory{
return 9;
}
/**
* @return void
*/
public function sendCreativeContents(){
//TODO: this mess shouldn't be in here
$holder = $this->getHolder();

View File

@ -53,6 +53,7 @@ use function spl_object_hash;
* @see InventoryAction
*/
class InventoryTransaction{
/** @var bool */
protected $hasExecuted = false;
/** @var Player */
protected $source;

View File

@ -37,6 +37,7 @@ class CreativeInventoryAction extends InventoryAction{
*/
public const TYPE_CREATE_ITEM = 1;
/** @var int */
protected $actionType;
public function __construct(Item $sourceItem, Item $targetItem, int $actionType){

View File

@ -49,6 +49,8 @@ interface Consumable{
* Called when this Consumable is consumed by mob, after standard resulting effects have been applied.
*
* @param Living $consumer
*
* @return void
*/
public function onConsume(Living $consumer);
}

View File

@ -42,6 +42,8 @@ abstract class Durable extends Item{
* Sets whether the item will take damage when used.
*
* @param bool $value
*
* @return void
*/
public function setUnbreakable(bool $value = true){
$this->setNamedTagEntry(new ByteTag("Unbreakable", $value ? 1 : 0));

View File

@ -123,6 +123,9 @@ class Item implements ItemIds, \JsonSerializable{
/** @var Item[] */
private static $creative = [];
/**
* @return void
*/
public static function initCreativeItems(){
self::clearCreativeItems();
@ -140,6 +143,8 @@ class Item implements ItemIds, \JsonSerializable{
/**
* Removes all previously added items from the creative menu.
* Note: Players who are already online when this is called will not see this change.
*
* @return void
*/
public static function clearCreativeItems(){
Item::$creative = [];
@ -154,6 +159,8 @@ class Item implements ItemIds, \JsonSerializable{
* Note: Players who are already online when this is called will not see this change.
*
* @param Item $item
*
* @return void
*/
public static function addCreativeItem(Item $item){
Item::$creative[] = clone $item;
@ -164,6 +171,8 @@ class Item implements ItemIds, \JsonSerializable{
* Note: Players who are already online when this is called will not see this change.
*
* @param Item $item
*
* @return void
*/
public static function removeCreativeItem(Item $item){
$index = self::getCreativeItemIndex($item);
@ -233,7 +242,7 @@ class Item implements ItemIds, \JsonSerializable{
*
* @param CompoundTag|string|null $tags
*
* @return Item
* @return $this
*/
public function setCompoundTag($tags) : Item{
if($tags instanceof CompoundTag){
@ -272,6 +281,9 @@ class Item implements ItemIds, \JsonSerializable{
return $this->getNamedTagEntry(self::TAG_BLOCK_ENTITY_TAG) instanceof CompoundTag;
}
/**
* @return $this
*/
public function clearCustomBlockData(){
$this->removeNamedTagEntry(self::TAG_BLOCK_ENTITY_TAG);
return $this;
@ -280,7 +292,7 @@ class Item implements ItemIds, \JsonSerializable{
/**
* @param CompoundTag $compound
*
* @return Item
* @return $this
*/
public function setCustomBlockData(CompoundTag $compound) : Item{
$tags = clone $compound;
@ -479,7 +491,7 @@ class Item implements ItemIds, \JsonSerializable{
/**
* @param string $name
*
* @return Item
* @return $this
*/
public function setCustomName(string $name) : Item{
if($name === ""){
@ -499,7 +511,7 @@ class Item implements ItemIds, \JsonSerializable{
}
/**
* @return Item
* @return $this
*/
public function clearCustomName() : Item{
$display = $this->getNamedTagEntry(self::TAG_DISPLAY);
@ -531,7 +543,7 @@ class Item implements ItemIds, \JsonSerializable{
/**
* @param string[] $lines
*
* @return Item
* @return $this
*/
public function setLore(array $lines) : Item{
$display = $this->getNamedTagEntry(self::TAG_DISPLAY);
@ -588,7 +600,7 @@ class Item implements ItemIds, \JsonSerializable{
*
* @param CompoundTag $tag
*
* @return Item
* @return $this
*/
public function setNamedTag(CompoundTag $tag) : Item{
if($tag->getCount() === 0){
@ -603,7 +615,7 @@ class Item implements ItemIds, \JsonSerializable{
/**
* Removes the Item's NBT.
* @return Item
* @return $this
*/
public function clearNamedTag() : Item{
return $this->setCompoundTag("");
@ -619,7 +631,7 @@ class Item implements ItemIds, \JsonSerializable{
/**
* @param int $count
*
* @return Item
* @return $this
*/
public function setCount(int $count) : Item{
$this->count = $count;
@ -632,7 +644,7 @@ class Item implements ItemIds, \JsonSerializable{
*
* @param int $count
*
* @return Item
* @return $this
* @throws \InvalidArgumentException if trying to pop more items than are on the stack
*/
public function pop(int $count = 1) : Item{
@ -700,7 +712,7 @@ class Item implements ItemIds, \JsonSerializable{
/**
* @param int $meta
*
* @return Item
* @return $this
*/
public function setDamage(int $meta) : Item{
$this->meta = $meta !== -1 ? $meta & 0x7FFF : -1;

View File

@ -46,6 +46,9 @@ class ItemFactory{
/** @var \SplFixedArray */
private static $list = null;
/**
* @return void
*/
public static function init(){
self::$list = new \SplFixedArray(65536);
@ -285,6 +288,7 @@ class ItemFactory{
* @param Item $item
* @param bool $override
*
* @return void
* @throws \RuntimeException if something attempted to override an already-registered item without specifying the
* $override parameter.
*/

View File

@ -105,6 +105,12 @@ class BaseLang{
return $this->langName;
}
/**
* @param string $path
* @param string[] $d reference parameter
*
* @return bool
*/
protected static function loadLang(string $path, array &$d){
if(file_exists($path)){
$d = array_map('\stripcslashes', parse_ini_file($path, false, INI_SCANNER_RAW));
@ -132,6 +138,11 @@ class BaseLang{
return $baseText;
}
/**
* @param TextContainer $c
*
* @return string
*/
public function translate(TextContainer $c){
if($c instanceof TranslationContainer){
$baseText = $this->internalGet($c->getText());

View File

@ -37,6 +37,8 @@ class TextContainer{
/**
* @param string $text
*
* @return void
*/
public function setText(string $text){
$this->text = $text;

View File

@ -59,6 +59,8 @@ class TranslationContainer extends TextContainer{
/**
* @param int $i
* @param string $str
*
* @return void
*/
public function setParameter(int $i, string $str){
if($i < 0 or $i > count($this->params)){ //Intended, allow to set the last
@ -70,6 +72,8 @@ class TranslationContainer extends TextContainer{
/**
* @param string[] $params
*
* @return void
*/
public function setParameters(array $params){
$i = 0;

View File

@ -78,6 +78,8 @@ interface ChunkLoader{
* This method will be called when a Chunk is replaced by a new one
*
* @param Chunk $chunk
*
* @return void
*/
public function onChunkChanged(Chunk $chunk);
@ -85,6 +87,8 @@ interface ChunkLoader{
* This method will be called when a registered chunk is loaded
*
* @param Chunk $chunk
*
* @return void
*/
public function onChunkLoaded(Chunk $chunk);
@ -93,6 +97,8 @@ interface ChunkLoader{
* This method will be called when a registered chunk is unloaded
*
* @param Chunk $chunk
*
* @return void
*/
public function onChunkUnloaded(Chunk $chunk);
@ -101,6 +107,8 @@ interface ChunkLoader{
* Usually it'll be sent with another call to onChunkChanged()
*
* @param Chunk $chunk
*
* @return void
*/
public function onChunkPopulated(Chunk $chunk);
@ -108,6 +116,8 @@ interface ChunkLoader{
* This method will be called when a block changes in a registered chunk
*
* @param Block|Vector3 $block
*
* @return void
*/
public function onBlockChanged(Vector3 $block);

View File

@ -44,6 +44,8 @@ interface ChunkManager{
* @param int $y
* @param int $z
* @param int $id 0-255
*
* @return void
*/
public function setBlockIdAt(int $x, int $y, int $z, int $id);
@ -65,6 +67,8 @@ interface ChunkManager{
* @param int $y
* @param int $z
* @param int $data 0-15
*
* @return void
*/
public function setBlockDataAt(int $x, int $y, int $z, int $data);
@ -86,6 +90,8 @@ interface ChunkManager{
* @param int $y
* @param int $z
* @param int $level
*
* @return void
*/
public function setBlockLightAt(int $x, int $y, int $z, int $level);
@ -107,6 +113,8 @@ interface ChunkManager{
* @param int $y
* @param int $z
* @param int $level
*
* @return void
*/
public function setBlockSkyLightAt(int $x, int $y, int $z, int $level);
@ -122,6 +130,8 @@ interface ChunkManager{
* @param int $chunkX
* @param int $chunkZ
* @param Chunk|null $chunk
*
* @return void
*/
public function setChunk(int $chunkX, int $chunkZ, Chunk $chunk = null);

View File

@ -120,7 +120,9 @@ use const PHP_INT_MIN;
class Level implements ChunkManager, Metadatable{
/** @var int */
private static $levelIdCounter = 1;
/** @var int */
private static $chunkLoaderCounter = 1;
public const Y_MASK = 0xFF;
@ -433,6 +435,8 @@ class Level implements ChunkManager, Metadatable{
/**
* @deprecated does nothing
* @param int $tickRate
*
* @return void
*/
public function setTickRate(int $tickRate){
@ -443,6 +447,9 @@ class Level implements ChunkManager, Metadatable{
$this->server->getAsyncPool()->submitTaskToWorker(new GeneratorRegisterTask($this, $this->generator, $this->provider->getGeneratorOptions()), $worker);
}
/**
* @return void
*/
public function unregisterGenerator(){
$pool = $this->server->getAsyncPool();
foreach($pool->getRunningWorkers() as $i){
@ -476,6 +483,9 @@ class Level implements ChunkManager, Metadatable{
return $this->closed;
}
/**
* @return void
*/
public function close(){
if($this->closed){
throw new \InvalidStateException("Tried to close a world which is already closed");
@ -498,6 +508,12 @@ class Level implements ChunkManager, Metadatable{
$this->closed = true;
}
/**
* @param Sound $sound
* @param Player[]|null $players
*
* @return void
*/
public function addSound(Sound $sound, array $players = null){
$pk = $sound->encode();
if(!is_array($pk)){
@ -514,6 +530,12 @@ class Level implements ChunkManager, Metadatable{
}
}
/**
* @param Particle $particle
* @param Player[]|null $players
*
* @return void
*/
public function addParticle(Particle $particle, array $players = null){
$pk = $particle->encode();
if(!is_array($pk)){
@ -536,6 +558,8 @@ class Level implements ChunkManager, Metadatable{
* @param Vector3|null $pos If null, broadcasts to every player in the Level
* @param int $evid
* @param int $data
*
* @return void
*/
public function broadcastLevelEvent(?Vector3 $pos, int $evid, int $data = 0){
$pk = new LevelEventPacket();
@ -559,6 +583,8 @@ class Level implements ChunkManager, Metadatable{
* @param int $entityTypeId
* @param bool $isBabyMob
* @param bool $disableRelativeVolume If true, all players receiving this sound-event will hear the sound at full volume regardless of distance
*
* @return void
*/
public function broadcastLevelSoundEvent(Vector3 $pos, int $soundId, int $extraData = -1, int $entityTypeId = -1, bool $isBabyMob = false, bool $disableRelativeVolume = false){
$pk = new LevelSoundEventPacket();
@ -575,6 +601,11 @@ class Level implements ChunkManager, Metadatable{
return $this->autoSave;
}
/**
* @param bool $value
*
* @return void
*/
public function setAutoSave(bool $value){
$this->autoSave = $value;
}
@ -672,6 +703,8 @@ class Level implements ChunkManager, Metadatable{
* @param int $chunkX
* @param int $chunkZ
* @param DataPacket $packet
*
* @return void
*/
public function addChunkPacket(int $chunkX, int $chunkZ, DataPacket $packet){
if(!isset($this->chunkPackets[$index = Level::chunkHash($chunkX, $chunkZ)])){
@ -710,6 +743,14 @@ class Level implements ChunkManager, Metadatable{
$this->globalPackets[] = $packet;
}
/**
* @param ChunkLoader $loader
* @param int $chunkX
* @param int $chunkZ
* @param bool $autoLoad
*
* @return void
*/
public function registerChunkLoader(ChunkLoader $loader, int $chunkX, int $chunkZ, bool $autoLoad = true){
$loaderId = $loader->getLoaderId();
@ -739,6 +780,13 @@ class Level implements ChunkManager, Metadatable{
}
}
/**
* @param ChunkLoader $loader
* @param int $chunkX
* @param int $chunkZ
*
* @return void
*/
public function unregisterChunkLoader(ChunkLoader $loader, int $chunkX, int $chunkZ){
$chunkHash = Level::chunkHash($chunkX, $chunkZ);
$loaderId = $loader->getLoaderId();
@ -762,6 +810,8 @@ class Level implements ChunkManager, Metadatable{
* @internal
*
* @param Player ...$targets If empty, will send to all players in the level.
*
* @return void
*/
public function sendTime(Player ...$targets){
$pk = new SetTimePacket();
@ -775,6 +825,7 @@ class Level implements ChunkManager, Metadatable{
*
* @param int $currentTick
*
* @return void
*/
public function doTick(int $currentTick){
if($this->closed){
@ -927,6 +978,9 @@ class Level implements ChunkManager, Metadatable{
$this->chunkPackets = [];
}
/**
* @return void
*/
public function checkSleep(){
if(count($this->players) === 0){
return;
@ -962,6 +1016,8 @@ class Level implements ChunkManager, Metadatable{
* @param Vector3[] $blocks
* @param int $flags
* @param bool $optimizeRebuilds
*
* @return void
*/
public function sendBlocks(array $target, array $blocks, int $flags = UpdateBlockPacket::FLAG_NONE, bool $optimizeRebuilds = false){
$packets = [];
@ -1021,6 +1077,11 @@ class Level implements ChunkManager, Metadatable{
$this->server->batchPackets($target, $packets, false, false);
}
/**
* @param bool $force
*
* @return void
*/
public function clearCache(bool $force = false){
if($force){
$this->chunkCache = [];
@ -1037,6 +1098,12 @@ class Level implements ChunkManager, Metadatable{
}
}
/**
* @param int $chunkX
* @param int $chunkZ
*
* @return void
*/
public function clearChunkCache(int $chunkX, int $chunkZ){
unset($this->chunkCache[Level::chunkHash($chunkX, $chunkZ)]);
}
@ -1045,15 +1112,25 @@ class Level implements ChunkManager, Metadatable{
return $this->randomTickBlocks;
}
/**
* @param int $id
*
* @return void
*/
public function addRandomTickedBlock(int $id){
$this->randomTickBlocks[$id] = BlockFactory::get($id);
}
/**
* @param int $id
*
* @return void
*/
public function removeRandomTickedBlock(int $id){
$this->randomTickBlocks[$id] = null;
}
private function tickChunks(){
private function tickChunks() : void{
if($this->chunksPerTick <= 0 or count($this->loaders) === 0){
$this->chunkTickList = [];
return;
@ -1161,6 +1238,9 @@ class Level implements ChunkManager, Metadatable{
return true;
}
/**
* @return void
*/
public function saveChunks(){
$this->timings->syncChunkSaveTimer->startTiming();
try{
@ -1181,6 +1261,8 @@ class Level implements ChunkManager, Metadatable{
*
* @param Vector3 $pos
* @param int $delay
*
* @return void
*/
public function scheduleDelayedBlockUpdate(Vector3 $pos, int $delay){
if(
@ -1198,6 +1280,8 @@ class Level implements ChunkManager, Metadatable{
* Blocks will be updated with the normal update type.
*
* @param Vector3 $pos
*
* @return void
*/
public function scheduleNeighbourBlockUpdates(Vector3 $pos){
$pos = $pos->floor();
@ -1489,6 +1573,11 @@ class Level implements ChunkManager, Metadatable{
return $block;
}
/**
* @param Vector3 $pos
*
* @return void
*/
public function updateAllLight(Vector3 $pos){
$this->updateBlockSkyLight($pos->x, $pos->y, $pos->z);
$this->updateBlockLight($pos->x, $pos->y, $pos->z);
@ -1514,6 +1603,13 @@ class Level implements ChunkManager, Metadatable{
]);
}
/**
* @param int $x
* @param int $y
* @param int $z
*
* @return void
*/
public function updateBlockSkyLight(int $x, int $y, int $z){
$this->timings->doBlockSkyLightUpdates->startTiming();
@ -1574,6 +1670,13 @@ class Level implements ChunkManager, Metadatable{
]);
}
/**
* @param int $x
* @param int $y
* @param int $z
*
* @return void
*/
public function updateBlockLight(int $x, int $y, int $z){
$this->timings->doBlockLightUpdates->startTiming();
@ -1776,7 +1879,7 @@ class Level implements ChunkManager, Metadatable{
* It'll try to lower the durability if Item is a tool, and set it to Air if broken.
*
* @param Vector3 $vector
* @param Item &$item (if null, can break anything)
* @param Item $item reference parameter (if null, can break anything)
* @param Player $player
* @param bool $createParticles
*
@ -2240,6 +2343,8 @@ class Level implements ChunkManager, Metadatable{
* @param int $y
* @param int $z
* @param int $id 0-255
*
* @return void
*/
public function setBlockIdAt(int $x, int $y, int $z, int $id){
if(!$this->isInWorld($x, $y, $z)){ //TODO: bad hack but fixing this requires BC breaks to do properly :(
@ -2279,6 +2384,8 @@ class Level implements ChunkManager, Metadatable{
* @param int $y
* @param int $z
* @param int $data 0-15
*
* @return void
*/
public function setBlockDataAt(int $x, int $y, int $z, int $data){
if(!$this->isInWorld($x, $y, $z)){ //TODO: bad hack but fixing this requires BC breaks to do properly :(
@ -2319,6 +2426,8 @@ class Level implements ChunkManager, Metadatable{
* @param int $y
* @param int $z
* @param int $level 0-15
*
* @return void
*/
public function setBlockSkyLightAt(int $x, int $y, int $z, int $level){
$this->getChunk($x >> 4, $z >> 4, true)->setBlockSkyLight($x & 0x0f, $y, $z & 0x0f, $level & 0x0f);
@ -2344,6 +2453,8 @@ class Level implements ChunkManager, Metadatable{
* @param int $y
* @param int $z
* @param int $level 0-15
*
* @return void
*/
public function setBlockLightAt(int $x, int $y, int $z, int $level){
$this->getChunk($x >> 4, $z >> 4, true)->setBlockLight($x & 0x0f, $y, $z & 0x0f, $level & 0x0f);
@ -2373,6 +2484,8 @@ class Level implements ChunkManager, Metadatable{
* @param int $x
* @param int $z
* @param int $biomeId
*
* @return void
*/
public function setBiomeId(int $x, int $z, int $biomeId){
$this->getChunk($x >> 4, $z >> 4, true)->setBiomeId($x & 0x0f, $z & 0x0f, $biomeId);
@ -2392,6 +2505,8 @@ class Level implements ChunkManager, Metadatable{
* @param int $x
* @param int $z
* @param int $value
*
* @return void
*/
public function setHeightMap(int $x, int $z, int $value){
$this->getChunk($x >> 4, $z >> 4, true)->setHeightMap($x & 0x0f, $z & 0x0f, $value);
@ -2459,6 +2574,13 @@ class Level implements ChunkManager, Metadatable{
return $result;
}
/**
* @param int $x
* @param int $z
* @param Chunk|null $chunk
*
* @return void
*/
public function generateChunkCallback(int $x, int $z, ?Chunk $chunk){
Timings::$generationCallbackTimer->startTiming();
if(isset($this->chunkPopulationQueue[$index = Level::chunkHash($x, $z)])){
@ -2496,6 +2618,8 @@ class Level implements ChunkManager, Metadatable{
* @param int $chunkZ
* @param Chunk|null $chunk
* @param bool $deleteEntitiesAndTiles Whether to delete entities and tiles on the old chunk, or transfer them to the new one
*
* @return void
*/
public function setChunk(int $chunkX, int $chunkZ, Chunk $chunk = null, bool $deleteEntitiesAndTiles = true){
if($chunk === null){
@ -2621,6 +2745,8 @@ class Level implements ChunkManager, Metadatable{
* Sets the level spawn location
*
* @param Vector3 $pos
*
* @return void
*/
public function setSpawnLocation(Vector3 $pos){
$previousSpawn = $this->getSpawnLocation();
@ -2628,6 +2754,13 @@ class Level implements ChunkManager, Metadatable{
(new SpawnChangeEvent($this, $previousSpawn))->call();
}
/**
* @param int $x
* @param int $z
* @param Player $player
*
* @return void
*/
public function requestChunk(int $x, int $z, Player $player){
$index = Level::chunkHash($x, $z);
if(!isset($this->chunkSendQueue[$index])){
@ -2637,7 +2770,7 @@ class Level implements ChunkManager, Metadatable{
$this->chunkSendQueue[$index][$player->getLoaderId()] = $player;
}
private function sendChunkFromCache(int $x, int $z){
private function sendChunkFromCache(int $x, int $z) : void{
if(isset($this->chunkSendQueue[$index = Level::chunkHash($x, $z)])){
foreach($this->chunkSendQueue[$index] as $player){
/** @var Player $player */
@ -2649,7 +2782,7 @@ class Level implements ChunkManager, Metadatable{
}
}
private function processChunkRequest(){
private function processChunkRequest() : void{
if(count($this->chunkSendQueue) > 0){
$this->timings->syncChunkSendTimer->startTiming();
@ -2687,6 +2820,13 @@ class Level implements ChunkManager, Metadatable{
}
}
/**
* @param int $x
* @param int $z
* @param BatchPacket $payload
*
* @return void
*/
public function chunkRequestCallback(int $x, int $z, BatchPacket $payload){
$this->timings->syncChunkSendTimer->startTiming();
@ -2705,6 +2845,7 @@ class Level implements ChunkManager, Metadatable{
/**
* @param Entity $entity
*
* @return void
* @throws LevelException
*/
public function addEntity(Entity $entity){
@ -2726,6 +2867,7 @@ class Level implements ChunkManager, Metadatable{
*
* @param Entity $entity
*
* @return void
* @throws LevelException
*/
public function removeEntity(Entity $entity){
@ -2745,6 +2887,7 @@ class Level implements ChunkManager, Metadatable{
/**
* @param Tile $tile
*
* @return void
* @throws LevelException
*/
public function addTile(Tile $tile){
@ -2771,6 +2914,7 @@ class Level implements ChunkManager, Metadatable{
/**
* @param Tile $tile
*
* @return void
* @throws LevelException
*/
public function removeTile(Tile $tile){
@ -2866,11 +3010,18 @@ class Level implements ChunkManager, Metadatable{
return true;
}
private function queueUnloadChunk(int $x, int $z){
private function queueUnloadChunk(int $x, int $z) : void{
$this->unloadQueue[$index = Level::chunkHash($x, $z)] = microtime(true);
unset($this->chunkTickList[$index]);
}
/**
* @param int $x
* @param int $z
* @param bool $safe
*
* @return bool
*/
public function unloadChunkRequest(int $x, int $z, bool $safe = true){
if(($safe and $this->isChunkInUse($x, $z)) or $this->isSpawnChunk($x, $z)){
return false;
@ -2881,6 +3032,12 @@ class Level implements ChunkManager, Metadatable{
return true;
}
/**
* @param int $x
* @param int $z
*
* @return void
*/
public function cancelUnloadChunkRequest(int $x, int $z){
unset($this->unloadQueue[Level::chunkHash($x, $z)]);
}
@ -3032,6 +3189,8 @@ class Level implements ChunkManager, Metadatable{
* Sets the current time on the level
*
* @param int $time
*
* @return void
*/
public function setTime(int $time){
$this->time = $time;
@ -3040,6 +3199,8 @@ class Level implements ChunkManager, Metadatable{
/**
* Stops the time for the level, will not save the lock state to disk
*
* @return void
*/
public function stopTime(){
$this->stopTime = true;
@ -3048,6 +3209,8 @@ class Level implements ChunkManager, Metadatable{
/**
* Start the time again, if it was stopped
*
* @return void
*/
public function startTime(){
$this->stopTime = false;
@ -3067,6 +3230,8 @@ class Level implements ChunkManager, Metadatable{
* Sets the seed for the level
*
* @param int $seed
*
* @return void
*/
public function setSeed(int $seed){
$this->provider->setSeed($seed);
@ -3085,6 +3250,8 @@ class Level implements ChunkManager, Metadatable{
/**
* @param int $difficulty
*
* @return void
*/
public function setDifficulty(int $difficulty){
if($difficulty < 0 or $difficulty > 3){
@ -3097,6 +3264,8 @@ class Level implements ChunkManager, Metadatable{
/**
* @param Player ...$targets
*
* @return void
*/
public function sendDifficulty(Player ...$targets){
if(count($targets) === 0){
@ -3145,6 +3314,9 @@ class Level implements ChunkManager, Metadatable{
return true;
}
/**
* @return void
*/
public function doChunkGarbageCollection(){
$this->timings->doChunkGC->startTiming();
@ -3163,6 +3335,11 @@ class Level implements ChunkManager, Metadatable{
$this->timings->doChunkGC->stopTiming();
}
/**
* @param bool $force
*
* @return void
*/
public function unloadChunks(bool $force = false){
if(count($this->unloadQueue) > 0){
$maxUnload = 96;

View File

@ -67,10 +67,16 @@ class Location extends Position{
return new Location($this->x, $this->y, $this->z, $this->yaw, $this->pitch, $this->level);
}
/**
* @return float
*/
public function getYaw(){
return $this->yaw;
}
/**
* @return float
*/
public function getPitch(){
return $this->pitch;
}

View File

@ -43,6 +43,12 @@ class Position extends Vector3{
$this->setLevel($level);
}
/**
* @param Vector3 $pos
* @param Level|null $level
*
* @return Position
*/
public static function fromObject(Vector3 $pos, Level $level = null){
return new Position($pos->x, $pos->y, $pos->z, $level);
}

View File

@ -32,7 +32,9 @@ class SimpleChunkManager implements ChunkManager{
/** @var Chunk[] */
protected $chunks = [];
/** @var int */
protected $seed;
/** @var int */
protected $worldHeight;
/**
@ -69,6 +71,8 @@ class SimpleChunkManager implements ChunkManager{
* @param int $y
* @param int $z
* @param int $id 0-255
*
* @return void
*/
public function setBlockIdAt(int $x, int $y, int $z, int $id){
if($chunk = $this->getChunk($x >> 4, $z >> 4)){
@ -99,6 +103,8 @@ class SimpleChunkManager implements ChunkManager{
* @param int $y
* @param int $z
* @param int $data 0-15
*
* @return void
*/
public function setBlockDataAt(int $x, int $y, int $z, int $data){
if($chunk = $this->getChunk($x >> 4, $z >> 4)){
@ -148,6 +154,8 @@ class SimpleChunkManager implements ChunkManager{
* @param int $chunkX
* @param int $chunkZ
* @param Chunk|null $chunk
*
* @return void
*/
public function setChunk(int $chunkX, int $chunkZ, Chunk $chunk = null){
if($chunk === null){
@ -157,6 +165,9 @@ class SimpleChunkManager implements ChunkManager{
$this->chunks[Level::chunkHash($chunkX, $chunkZ)] = $chunk;
}
/**
* @return void
*/
public function cleanChunks(){
$this->chunks = [];
}

View File

@ -76,11 +76,20 @@ abstract class Biome{
/** @var float */
protected $temperature = 0.5;
/**
* @param int $id
* @param Biome $biome
*
* @return void
*/
protected static function register(int $id, Biome $biome){
self::$biomes[$id] = $biome;
$biome->setId($id);
}
/**
* @return void
*/
public static function init(){
self::$biomes = new \SplFixedArray(self::MAX_BIOMES);
@ -113,10 +122,18 @@ abstract class Biome{
return self::$biomes[$id];
}
/**
* @return void
*/
public function clearPopulators(){
$this->populators = [];
}
/**
* @param Populator $populator
*
* @return void
*/
public function addPopulator(Populator $populator){
$this->populators[] = $populator;
}
@ -126,6 +143,8 @@ abstract class Biome{
* @param int $chunkX
* @param int $chunkZ
* @param Random $random
*
* @return void
*/
public function populateChunk(ChunkManager $level, int $chunkX, int $chunkZ, Random $random){
foreach($this->populators as $populator){
@ -140,6 +159,11 @@ abstract class Biome{
return $this->populators;
}
/**
* @param int $id
*
* @return void
*/
public function setId(int $id){
if(!$this->registered){
$this->registered = true;
@ -161,6 +185,12 @@ abstract class Biome{
return $this->maxElevation;
}
/**
* @param int $min
* @param int $max
*
* @return void
*/
public function setElevation(int $min, int $max){
$this->minElevation = $min;
$this->maxElevation = $max;
@ -175,6 +205,8 @@ abstract class Biome{
/**
* @param Block[] $covers
*
* @return void
*/
public function setGroundCover(array $covers){
$this->groundCover = $covers;

View File

@ -32,6 +32,7 @@ class ForestBiome extends GrassyBiome{
public const TYPE_NORMAL = 0;
public const TYPE_BIRCH = 1;
/** @var int */
public $type;
public function __construct(int $type = self::TYPE_NORMAL){

View File

@ -153,12 +153,19 @@ class Chunk{
return $this->z;
}
/**
* @param int $x
*
* @return void
*/
public function setX(int $x){
$this->x = $x;
}
/**
* @param int $z
*
* @return void
*/
public function setZ(int $z){
$this->z = $z;
@ -225,6 +232,8 @@ class Chunk{
* @param int $y
* @param int $z 0-15
* @param int $id 0-255
*
* @return void
*/
public function setBlockId(int $x, int $y, int $z, int $id){
if($this->getSubChunk($y >> 4, true)->setBlockId($x, $y & 0x0f, $z, $id)){
@ -252,6 +261,8 @@ class Chunk{
* @param int $y
* @param int $z 0-15
* @param int $data 0-15
*
* @return void
*/
public function setBlockData(int $x, int $y, int $z, int $data){
if($this->getSubChunk($y >> 4, true)->setBlockData($x, $y & 0x0f, $z, $data)){
@ -279,6 +290,8 @@ class Chunk{
* @param int $y
* @param int $z 0-15
* @param int $level 0-15
*
* @return void
*/
public function setBlockSkyLight(int $x, int $y, int $z, int $level){
if($this->getSubChunk($y >> 4, true)->setBlockSkyLight($x, $y & 0x0f, $z, $level)){
@ -288,6 +301,8 @@ class Chunk{
/**
* @param int $level
*
* @return void
*/
public function setAllBlockSkyLight(int $level){
$char = chr(($level & 0x0f) | ($level << 4));
@ -317,6 +332,8 @@ class Chunk{
* @param int $y 0-15
* @param int $z 0-15
* @param int $level 0-15
*
* @return void
*/
public function setBlockLight(int $x, int $y, int $z, int $level){
if($this->getSubChunk($y >> 4, true)->setBlockLight($x, $y & 0x0f, $z, $level)){
@ -326,6 +343,8 @@ class Chunk{
/**
* @param int $level
*
* @return void
*/
public function setAllBlockLight(int $level){
$char = chr(($level & 0x0f) | ($level << 4));
@ -381,6 +400,8 @@ class Chunk{
* @param int $x 0-15
* @param int $z 0-15
* @param int $value
*
* @return void
*/
public function setHeightMap(int $x, int $z, int $value){
$this->heightMap[($z << 4) | $x] = $value;
@ -388,6 +409,8 @@ class Chunk{
/**
* Recalculates the heightmap for the whole chunk.
*
* @return void
*/
public function recalculateHeightMap(){
for($z = 0; $z < 16; ++$z){
@ -423,6 +446,8 @@ class Chunk{
* if the chunk is light-populated after being terrain-populated.
*
* TODO: fast adjacent light spread
*
* @return void
*/
public function populateSkyLight(){
$maxY = $this->getMaxY();
@ -469,6 +494,8 @@ class Chunk{
* @param int $x 0-15
* @param int $z 0-15
* @param int $biomeId 0-255
*
* @return void
*/
public function setBiomeId(int $x, int $z, int $biomeId){
$this->hasChanged = true;
@ -549,6 +576,8 @@ class Chunk{
/**
* @param bool $value
*
* @return void
*/
public function setLightPopulated(bool $value = true){
$this->lightPopulated = $value;
@ -563,6 +592,8 @@ class Chunk{
/**
* @param bool $value
*
* @return void
*/
public function setPopulated(bool $value = true){
$this->terrainPopulated = $value;
@ -577,6 +608,8 @@ class Chunk{
/**
* @param bool $value
*
* @return void
*/
public function setGenerated(bool $value = true){
$this->terrainGenerated = $value;
@ -584,6 +617,8 @@ class Chunk{
/**
* @param Entity $entity
*
* @return void
*/
public function addEntity(Entity $entity){
if($entity->isClosed()){
@ -597,6 +632,8 @@ class Chunk{
/**
* @param Entity $entity
*
* @return void
*/
public function removeEntity(Entity $entity){
unset($this->entities[$entity->getId()]);
@ -607,6 +644,8 @@ class Chunk{
/**
* @param Tile $tile
*
* @return void
*/
public function addTile(Tile $tile){
if($tile->isClosed()){
@ -624,6 +663,8 @@ class Chunk{
/**
* @param Tile $tile
*
* @return void
*/
public function removeTile(Tile $tile){
unset($this->tiles[$tile->getId()]);
@ -690,6 +731,8 @@ class Chunk{
* Deserializes tiles and entities from NBT
*
* @param Level $level
*
* @return void
*/
public function initChunk(Level $level){
if(!$this->isInit){
@ -766,6 +809,8 @@ class Chunk{
/**
* @param bool $value
*
* @return void
*/
public function setChanged(bool $value = true){
$this->hasChanged = $value;

View File

@ -38,25 +38,28 @@ if(!defined(__NAMESPACE__ . '\ZERO_NIBBLE_ARRAY')){
}
class SubChunk implements SubChunkInterface{
/** @var string */
protected $ids;
/** @var string */
protected $data;
/** @var string */
protected $blockLight;
/** @var string */
protected $skyLight;
private static function assignData(&$target, string $data, int $length, string $value = "\x00"){
private static function assignData(string $data, int $length, string $value = "\x00") : string{
if(strlen($data) !== $length){
assert($data === "", "Invalid non-zero length given, expected $length, got " . strlen($data));
$target = str_repeat($value, $length);
}else{
$target = $data;
return str_repeat($value, $length);
}
return $data;
}
public function __construct(string $ids = "", string $data = "", string $skyLight = "", string $blockLight = ""){
self::assignData($this->ids, $ids, 4096);
self::assignData($this->data, $data, 2048);
self::assignData($this->skyLight, $skyLight, 2048, "\xff");
self::assignData($this->blockLight, $blockLight, 2048);
$this->ids = self::assignData($ids, 4096);
$this->data = self::assignData($data, 2048);
$this->skyLight = self::assignData($skyLight, 2048, "\xff");
$this->blockLight = self::assignData($blockLight, 2048);
$this->collectGarbage();
}
@ -214,6 +217,9 @@ class SubChunk implements SubChunkInterface{
return "\x00" . $this->ids . $this->data;
}
/**
* @return mixed[]
*/
public function __debugInfo(){
return [];
}

View File

@ -185,6 +185,8 @@ interface SubChunkInterface{
/**
* @param string $data
*
* @return void
*/
public function setBlockSkyLightArray(string $data);
@ -195,6 +197,8 @@ interface SubChunkInterface{
/**
* @param string $data
*
* @return void
*/
public function setBlockLightArray(string $data);

View File

@ -150,6 +150,9 @@ abstract class BaseLevelProvider implements LevelProvider{
return $this->levelData;
}
/**
* @return void
*/
public function saveLevelData(){
$nbt = new BigEndianNBTStream();
$buffer = $nbt->writeCompressed(new CompoundTag("", [

View File

@ -34,12 +34,17 @@ use function strlen;
class ChunkRequestTask extends AsyncTask{
/** @var int */
protected $levelId;
/** @var string */
protected $chunk;
/** @var int */
protected $chunkX;
/** @var int */
protected $chunkZ;
/** @var int */
protected $compressionLevel;
/** @var int */

View File

@ -72,6 +72,8 @@ interface LevelProvider{
* @param int $seed
* @param string $generator
* @param array $options
*
* @return void
*/
public static function generate(string $path, string $name, int $seed, string $generator, array $options = []);
@ -119,6 +121,8 @@ interface LevelProvider{
/**
* @param int $value
*
* @return void
*/
public function setTime(int $value);
@ -129,6 +133,8 @@ interface LevelProvider{
/**
* @param int $value
*
* @return void
*/
public function setSeed(int $value);
@ -139,6 +145,8 @@ interface LevelProvider{
/**
* @param Vector3 $pos
*
* @return void
*/
public function setSpawn(Vector3 $pos);
@ -152,16 +160,22 @@ interface LevelProvider{
* Sets the world difficulty.
*
* @param int $difficulty
*
* @return void
*/
public function setDifficulty(int $difficulty);
/**
* Performs garbage collection in the level provider, such as cleaning up regions in Region-based worlds.
*
* @return void
*/
public function doGarbageCollection();
/**
* Performs cleanups necessary when the level provider is closed and no longer needed.
*
* @return void
*/
public function close();

View File

@ -31,6 +31,7 @@ use function strtolower;
use function trim;
abstract class LevelProviderManager{
/** @var string[] */
protected static $providers = [];
public static function init() : void{
@ -43,6 +44,7 @@ abstract class LevelProviderManager{
/**
* @param string $class
*
* @return void
* @throws \InvalidArgumentException
*/
public static function addProvider(string $class){

View File

@ -102,7 +102,7 @@ class LevelDB extends BaseLevelProvider{
/** @var \LevelDB */
protected $db;
private static function checkForLevelDBExtension(){
private static function checkForLevelDBExtension() : void{
if(!extension_loaded('leveldb')){
throw new LevelException("The leveldb PHP extension is required to use this world format");
}
@ -126,8 +126,12 @@ class LevelDB extends BaseLevelProvider{
}
protected function loadLevelData() : void{
$rawLevelData = file_get_contents($this->getPath() . "level.dat");
if($rawLevelData === false or strlen($rawLevelData) <= 8){
throw new LevelException("Truncated level.dat");
}
$nbt = new LittleEndianNBTStream();
$levelData = $nbt->read(substr(file_get_contents($this->getPath() . "level.dat"), 8));
$levelData = $nbt->read(substr($rawLevelData, 8));
if($levelData instanceof CompoundTag){
$this->levelData = $levelData;
}else{
@ -519,7 +523,7 @@ class LevelDB extends BaseLevelProvider{
* @param CompoundTag[] $targets
* @param string $index
*/
private function writeTags(array $targets, string $index){
private function writeTags(array $targets, string $index) : void{
if(count($targets) > 0){
$nbt = new LittleEndianNBTStream();
$this->db->put($index, $nbt->write($targets));

View File

@ -331,8 +331,10 @@ class McRegion extends BaseLevelProvider{
/**
* @param int $chunkX
* @param int $chunkZ
* @param int &$regionX
* @param int &$regionZ
* @param int $regionX reference parameter
* @param int $regionZ reference parameter
*
* @return void
*/
public static function getRegionIndex(int $chunkX, int $chunkZ, &$regionX, &$regionZ){
$regionX = $chunkX >> 5;
@ -364,6 +366,8 @@ class McRegion extends BaseLevelProvider{
/**
* @param int $regionX
* @param int $regionZ
*
* @return void
*/
protected function loadRegion(int $regionX, int $regionZ){
if(!isset($this->regions[$index = Level::chunkHash($regionX, $regionZ)])){

View File

@ -62,6 +62,7 @@ class RegionLoader{
private const FIRST_SECTOR = 2; //location table occupies 0 and 1
/** @var int */
public static $COMPRESSION_LEVEL = 7;
/** @var int */
@ -86,6 +87,7 @@ class RegionLoader{
}
/**
* @return void
* @throws CorruptedRegionException
*/
public function open(){
@ -187,6 +189,7 @@ class RegionLoader{
* @param int $z
* @param string $chunkData
*
* @return void
* @throws ChunkException
* @throws \InvalidArgumentException
*/
@ -219,6 +222,7 @@ class RegionLoader{
* @param int $x
* @param int $z
*
* @return void
* @throws \InvalidArgumentException
*/
public function removeChunk(int $x, int $z){
@ -243,8 +247,8 @@ class RegionLoader{
/**
* @param int $offset
* @param int &$x
* @param int &$z
* @param int $x reference parameter
* @param int $z reference parameter
*/
protected static function getChunkCoords(int $offset, ?int &$x, ?int &$z) : void{
$x = $offset & 0x1f;
@ -255,6 +259,8 @@ class RegionLoader{
* Writes the region header and closes the file
*
* @param bool $writeHeader
*
* @return void
*/
public function close(bool $writeHeader = true){
if(is_resource($this->filePointer)){
@ -267,6 +273,7 @@ class RegionLoader{
}
/**
* @return void
* @throws CorruptedRegionException
*/
protected function loadLocationTable(){
@ -328,7 +335,7 @@ class RegionLoader{
}
}
private function writeLocationTable(){
private function writeLocationTable() : void{
$write = [];
for($i = 0; $i < 1024; ++$i){
@ -341,6 +348,11 @@ class RegionLoader{
fwrite($this->filePointer, pack("N*", ...$write), 4096 * 2);
}
/**
* @param int $index
*
* @return void
*/
protected function writeLocationIndex($index){
fseek($this->filePointer, $index << 2);
fwrite($this->filePointer, Binary::writeInt(($this->locationTable[$index]->getFirstSector() << 8) | $this->locationTable[$index]->getSectorCount()), 4);
@ -348,6 +360,9 @@ class RegionLoader{
fwrite($this->filePointer, Binary::writeInt($this->locationTable[$index]->getTimestamp()), 4);
}
/**
* @return void
*/
protected function createBlank(){
fseek($this->filePointer, 0);
ftruncate($this->filePointer, 8192); // this fills the file with the null byte

View File

@ -34,10 +34,15 @@ use function unserialize;
class GeneratorRegisterTask extends AsyncTask{
/** @var string */
public $generatorClass;
/** @var string */
public $settings;
/** @var int */
public $seed;
/** @var int */
public $levelId;
/** @var int */
public $worldHeight = Level::Y_MAX;
public function __construct(Level $level, string $generatorClass, array $generatorSettings = []){

View File

@ -28,6 +28,7 @@ use pocketmine\scheduler\AsyncTask;
class GeneratorUnregisterTask extends AsyncTask{
/** @var int */
public $levelId;
public function __construct(Level $level){

View File

@ -31,18 +31,31 @@ use pocketmine\Server;
class PopulationTask extends AsyncTask{
/** @var bool */
public $state;
/** @var int */
public $levelId;
/** @var string */
public $chunk;
/** @var string */
public $chunk0;
/** @var string */
public $chunk1;
/** @var string */
public $chunk2;
/** @var string */
public $chunk3;
//center chunk
/** @var string */
public $chunk5;
/** @var string */
public $chunk6;
/** @var string */
public $chunk7;
/** @var string */
public $chunk8;
public function __construct(Level $level, Chunk $chunk){

View File

@ -52,6 +52,9 @@ abstract class BiomeSelector{
*/
abstract protected function lookup(float $temperature, float $rainfall) : int;
/**
* @return void
*/
public function recalculate(){
$this->map = new \SplFixedArray(64 * 64);
@ -66,18 +69,29 @@ abstract class BiomeSelector{
}
}
/**
* @param float $x
* @param float $z
*
* @return float
*/
public function getTemperature($x, $z){
return ($this->temperature->noise2D($x, $z, true) + 1) / 2;
}
/**
* @param float $x
* @param float $z
*
* @return float
*/
public function getRainfall($x, $z){
return ($this->rainfall->noise2D($x, $z, true) + 1) / 2;
}
/**
* TODO: not sure on types here
* @param int|float $x
* @param int|float $z
* @param int $x
* @param int $z
*
* @return Biome
*/

View File

@ -31,30 +31,77 @@ use function array_fill;
use function assert;
abstract class Noise{
/** @var int[] */
protected $perm = [];
/** @var float */
protected $offsetX = 0;
/** @var float */
protected $offsetY = 0;
/** @var float */
protected $offsetZ = 0;
/** @var int */
protected $octaves = 8;
/** @var float */
protected $persistence;
/** @var float */
protected $expansion;
/**
* @param float $x
*
* @return int
*/
public static function floor($x) : int{
return $x >= 0 ? (int) $x : (int) ($x - 1);
}
/**
* @param float $x
*
* @return float
*/
public static function fade($x){
return $x * $x * $x * ($x * ($x * 6 - 15) + 10);
}
/**
* @param float $x
* @param float $y
* @param float $z
*
* @return float
*/
public static function lerp($x, $y, $z){
return $y + $x * ($z - $y);
}
/**
* @param float $x
* @param float $x1
* @param float $x2
* @param float $q0
* @param float $q1
*
* @return float
*/
public static function linearLerp($x, $x1, $x2, $q0, $q1){
return (($x2 - $x) / ($x2 - $x1)) * $q0 + (($x - $x1) / ($x2 - $x1)) * $q1;
}
/**
* @param float $x
* @param float $y
* @param float $q00
* @param float $q01
* @param float $q10
* @param float $q11
* @param float $x1
* @param float $x2
* @param float $y1
* @param float $y2
*
* @return float
*/
public static function bilinearLerp($x, $y, $q00, $q01, $q10, $q11, $x1, $x2, $y1, $y2){
$dx1 = (($x2 - $x) / ($x2 - $x1));
$dx2 = (($x - $x1) / ($x2 - $x1));
@ -66,6 +113,27 @@ abstract class Noise{
);
}
/**
* @param float $x
* @param float $y
* @param float $z
* @param float $q000
* @param float $q001
* @param float $q010
* @param float $q011
* @param float $q100
* @param float $q101
* @param float $q110
* @param float $q111
* @param float $x1
* @param float $x2
* @param float $y1
* @param float $y2
* @param float $z1
* @param float $z2
*
* @return float
*/
public static function trilinearLerp($x, $y, $z, $q000, $q001, $q010, $q011, $q100, $q101, $q110, $q111, $x1, $x2, $y1, $y2, $z1, $z2){
$dx1 = (($x2 - $x) / ($x2 - $x1));
$dx2 = (($x - $x1) / ($x2 - $x1));
@ -87,6 +155,14 @@ abstract class Noise{
);
}
/**
* @param int $hash
* @param float $x
* @param float $y
* @param float $z
*
* @return float
*/
public static function grad($hash, $x, $y, $z){
$hash &= 15;
$u = $hash < 8 ? $x : $y;
@ -95,10 +171,30 @@ abstract class Noise{
return (($hash & 1) === 0 ? $u : -$u) + (($hash & 2) === 0 ? $v : -$v);
}
/**
* @param float $x
* @param float $z
*
* @return float
*/
abstract public function getNoise2D($x, $z);
/**
* @param float $x
* @param float $y
* @param float $z
*
* @return float
*/
abstract public function getNoise3D($x, $y, $z);
/**
* @param float $x
* @param float $z
* @param bool $normalized
*
* @return float
*/
public function noise2D($x, $z, $normalized = false){
$result = 0;
$amp = 1;
@ -122,6 +218,14 @@ abstract class Noise{
return $result;
}
/**
* @param float $x
* @param float $y
* @param float $z
* @param bool $normalized
*
* @return float
*/
public function noise3D($x, $y, $z, $normalized = false){
$result = 0;
$amp = 1;
@ -297,6 +401,13 @@ abstract class Noise{
return $noiseArray;
}
/**
* @param float $x
* @param float $y
* @param float $z
*
* @return void
*/
public function setOffset($x, $y, $z){
$this->offsetX = $x;
$this->offsetY = $y;

View File

@ -26,6 +26,7 @@ namespace pocketmine\level\generator\noise;
use pocketmine\utils\Random;
class Perlin extends Noise{
/** @var int[][] */
public static $grad3 = [
[1, 1, 0], [-1, 1, 0], [1, -1, 0], [-1, -1, 0],
[1, 0, 1], [-1, 0, 1], [1, 0, -1], [-1, 0, -1],
@ -33,6 +34,12 @@ class Perlin extends Noise{
];
/**
* @param Random $random
* @param int $octaves
* @param float $persistence
* @param float $expansion
*/
public function __construct(Random $random, $octaves, $persistence, $expansion = 1){
$this->octaves = $octaves;
$this->persistence = $persistence;
@ -144,6 +151,12 @@ class Perlin extends Noise{
*/
}
/**
* @param float $x
* @param float $y
*
* @return float
*/
public function getNoise2D($x, $y){
return $this->getNoise3D($x, $y, 0);
}

View File

@ -34,18 +34,31 @@ use function sqrt;
* http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf
*/
class Simplex extends Perlin{
/** @var float */
protected static $SQRT_3;
/** @var float */
protected static $SQRT_5;
/** @var float */
protected static $F2;
/** @var float */
protected static $G2;
/** @var float */
protected static $G22;
/** @var float */
protected static $F3;
/** @var float */
protected static $G3;
/** @var float */
protected static $F4;
/** @var float */
protected static $G4;
/** @var float */
protected static $G42;
/** @var float */
protected static $G43;
/** @var float */
protected static $G44;
/** @var int[][] */
protected static $grad4 = [[0, 1, 1, 1], [0, 1, 1, -1], [0, 1, -1, 1], [0, 1, -1, -1],
[0, -1, 1, 1], [0, -1, 1, -1], [0, -1, -1, 1], [0, -1, -1, -1],
[1, 0, 1, 1], [1, 0, 1, -1], [1, 0, -1, 1], [1, 0, -1, -1],
@ -54,6 +67,8 @@ class Simplex extends Perlin{
[-1, 1, 0, 1], [-1, 1, 0, -1], [-1, -1, 0, 1], [-1, -1, 0, -1],
[1, 1, 1, 0], [1, 1, -1, 0], [1, -1, 1, 0], [1, -1, -1, 0],
[-1, 1, 1, 0], [-1, 1, -1, 0], [-1, -1, 1, 0], [-1, -1, -1, 0]];
/** @var int[][] */
protected static $simplex = [
[0, 1, 2, 3], [0, 1, 3, 2], [0, 0, 0, 0], [0, 2, 3, 1], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [1, 2, 3, 0],
[0, 2, 1, 3], [0, 0, 0, 0], [0, 3, 1, 2], [0, 3, 2, 1], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [1, 3, 2, 0],
@ -63,9 +78,17 @@ class Simplex extends Perlin{
[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0],
[2, 0, 1, 3], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [3, 0, 1, 2], [3, 0, 2, 1], [0, 0, 0, 0], [3, 1, 2, 0],
[2, 1, 0, 3], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [3, 1, 0, 2], [0, 0, 0, 0], [3, 2, 0, 1], [3, 2, 1, 0]];
/** @var float */
protected $offsetW;
/**
* @param Random $random
* @param int $octaves
* @param float $persistence
* @param float $expansion
*/
public function __construct(Random $random, $octaves, $persistence, $expansion = 1){
parent::__construct($random, $octaves, $persistence, $expansion);
$this->offsetW = $random->nextFloat() * 256;
@ -83,14 +106,38 @@ class Simplex extends Perlin{
self::$G44 = self::$G4 * 4.0 - 1.0;
}
/**
* @param int[] $g
* @param float $x
* @param float $y
*
* @return float
*/
protected static function dot2D($g, $x, $y){
return $g[0] * $x + $g[1] * $y;
}
/**
* @param int[] $g
* @param float $x
* @param float $y
* @param float $z
*
* @return float
*/
protected static function dot3D($g, $x, $y, $z){
return $g[0] * $x + $g[1] * $y + $g[2] * $z;
}
/**
* @param int[] $g
* @param float $x
* @param float $y
* @param float $z
* @param float $w
*
* @return float
*/
protected static function dot4D($g, $x, $y, $z, $w){
return $g[0] * $x + $g[1] * $y + $g[2] * $z + $g[3] * $w;
}
@ -219,6 +266,12 @@ class Simplex extends Perlin{
return 32.0 * $n;
}
/**
* @param float $x
* @param float $y
*
* @return float
*/
public function getNoise2D($x, $y){
$x += $this->offsetX;
$y += $this->offsetY;

View File

@ -55,7 +55,9 @@ class Normal extends Generator{
/** @var BiomeSelector */
private $selector;
/** @var float[][]|null */
private static $GAUSSIAN_KERNEL = null;
/** @var int */
private static $SMOOTH_SIZE = 2;
/**

View File

@ -26,60 +26,25 @@ namespace pocketmine\level\generator\object;
use pocketmine\level\ChunkManager;
use pocketmine\utils\Random;
/**
* @deprecated
*/
class BigTree extends Tree{
private $trunkHeightMultiplier = 0.618;
private $trunkHeight;
private $leafAmount = 1;
private $leafDistanceLimit = 5;
private $widthScale = 1;
private $branchSlope = 0.381;
private $totalHeight = 6;
private $leavesHeight = 3;
protected $radiusIncrease = 0;
private $addLeavesVines = false;
private $addLogVines = false;
private $addCocoaPlants = false;
public function canPlaceObject(ChunkManager $level, int $x, int $y, int $z, Random $random) : bool{
return false;
}
/**
* @param ChunkManager $level
* @param int $x
* @param int $y
* @param int $z
* @param Random $random
*
* @return void
*/
public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random){
/*$this->trunkHeight = (int) ($this->totalHeight * $this->trunkHeightMultiplier);
$leaves = $this->getLeafGroupPoints($level, $pos);
foreach($leaves as $leafGroup){
$groupX = $leafGroup->getBlockX();
$groupY = $leafGroup->getBlockY();
$groupZ = $leafGroup->getBlockZ();
for($yy = $groupY; $yy < $groupY + $this->leafDistanceLimit; ++$yy){
$this->generateGroupLayer($level, $groupX, $yy, $groupZ, $this->getLeafGroupLayerSize($yy - $groupY));
}
}
final BlockIterator trunk = new BlockIterator(new Point(w, x, y - 1, z), new Point(w, x, y + trunkHeight, z));
while (trunk.hasNext()) {
trunk.next().setMaterial(VanillaMaterials.LOG, logMetadata);
}
generateBranches(w, x, y, z, leaves);
$level->setBlock($x, $pos->y - 1, $z, 3, 0);
$this->totalHeight += $random->nextRange(0, 2);
$this->leavesHeight += mt_rand(0, 1);
for($yy = ($this->totalHeight - $this->leavesHeight); $yy < ($this->totalHeight + 1); ++$yy){
$yRadius = ($yy - $this->totalHeight);
$xzRadius = (int) (($this->radiusIncrease + 1) - $yRadius / 2);
for($xx = -$xzRadius; $xx < ($xzRadius + 1); ++$xx){
for($zz = -$xzRadius; $zz < ($xzRadius + 1); ++$zz){
if((abs($xx) != $xzRadius or abs($zz) != $xzRadius) and $yRadius != 0){
$level->setBlock($pos->x + $xx, $pos->y + $yy, $pos->z + $zz, 18, $this->type);
}
}
}
}
for($yy = 0; $yy < ($this->totalHeight - 1); ++$yy){
$level->setBlock($x, $pos->y + $yy, $z, 17, $this->type);
}
*/
}
}

View File

@ -30,6 +30,7 @@ use pocketmine\utils\Random;
class BirchTree extends Tree{
/** @var bool */
protected $superBirch = false;
public function __construct(bool $superBirch = false){
@ -39,6 +40,15 @@ class BirchTree extends Tree{
$this->superBirch = $superBirch;
}
/**
* @param ChunkManager $level
* @param int $x
* @param int $y
* @param int $z
* @param Random $random
*
* @return void
*/
public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random){
$this->treeHeight = $random->nextBoundedInt(3) + 5;
if($this->superBirch){

View File

@ -36,6 +36,15 @@ class OakTree extends Tree{
$this->type = Wood::OAK;
}
/**
* @param ChunkManager $level
* @param int $x
* @param int $y
* @param int $z
* @param Random $random
*
* @return void
*/
public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random){
$this->treeHeight = $random->nextBoundedInt(3) + 4;
parent::placeObject($level, $x, $y, $z, $random);

View File

@ -49,6 +49,14 @@ class Ore{
return $level->getBlockIdAt($x, $y, $z) === Block::STONE;
}
/**
* @param ChunkManager $level
* @param int $x
* @param int $y
* @param int $z
*
* @return void
*/
public function placeObject(ChunkManager $level, int $x, int $y, int $z){
$clusterSize = $this->type->clusterSize;
$angle = $this->random->nextFloat() * M_PI;

View File

@ -29,7 +29,9 @@ use pocketmine\math\Vector3;
use pocketmine\utils\Random;
class Pond{
/** @var Random */
private $random;
/** @var Block */
public $type;
public function __construct(Random $random, Block $type){
@ -41,6 +43,12 @@ class Pond{
return false;
}
/**
* @param ChunkManager $level
* @param Vector3 $pos
*
* @return void
*/
public function placeObject(ChunkManager $level, Vector3 $pos){
}

View File

@ -39,6 +39,15 @@ class SpruceTree extends Tree{
$this->treeHeight = 10;
}
/**
* @param ChunkManager $level
* @param int $x
* @param int $y
* @param int $z
* @param Random $random
*
* @return void
*/
public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random){
$this->treeHeight = $random->nextBoundedInt(4) + 6;

View File

@ -31,6 +31,15 @@ use function count;
class TallGrass{
/**
* @param ChunkManager $level
* @param Vector3 $pos
* @param Random $random
* @param int $count
* @param int $radius
*
* @return void
*/
public static function growGrass(ChunkManager $level, Vector3 $pos, Random $random, int $count = 15, int $radius = 10){
$arr = [
[Block::DANDELION, 0],

View File

@ -31,6 +31,7 @@ use pocketmine\utils\Random;
use function abs;
abstract class Tree{
/** @var bool[] */
public $overridable = [
Block::AIR => true,
Block::SAPLING => true,
@ -39,11 +40,25 @@ abstract class Tree{
Block::LEAVES2 => true
];
/** @var int */
public $type = 0;
/** @var int */
public $trunkBlock = Block::LOG;
/** @var int */
public $leafBlock = Block::LEAVES;
/** @var int */
public $treeHeight = 7;
/**
* @param ChunkManager $level
* @param int $x
* @param int $y
* @param int $z
* @param Random $random
* @param int $type
*
* @return void
*/
public static function growTree(ChunkManager $level, int $x, int $y, int $z, Random $random, int $type = 0){
switch($type){
case Sapling::SPRUCE:
@ -95,6 +110,15 @@ abstract class Tree{
return true;
}
/**
* @param ChunkManager $level
* @param int $x
* @param int $y
* @param int $z
* @param Random $random
*
* @return void
*/
public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random){
$this->placeTrunk($level, $x, $y, $z, $random, $this->treeHeight - 1);
@ -118,6 +142,16 @@ abstract class Tree{
}
}
/**
* @param ChunkManager $level
* @param int $x
* @param int $y
* @param int $z
* @param Random $random
* @param int $trunkHeight
*
* @return void
*/
protected function placeTrunk(ChunkManager $level, int $x, int $y, int $z, Random $random, int $trunkHeight){
// The base dirt block
$level->setBlockIdAt($x, $y - 1, $z, Block::DIRT);

View File

@ -48,6 +48,8 @@ class Ore extends Populator{
/**
* @param OreType[] $types
*
* @return void
*/
public function setOreTypes(array $types){
$this->oreTypes = $types;

View File

@ -30,8 +30,11 @@ use pocketmine\math\Vector3;
use pocketmine\utils\Random;
class Pond extends Populator{
/** @var int */
private $waterOdd = 4;
/** @var int */
private $lavaOdd = 4;
/** @var int */
private $lavaSurfaceOdd = 4;
public function populate(ChunkManager $level, int $chunkX, int $chunkZ, Random $random){
@ -46,14 +49,29 @@ class Pond extends Populator{
}
}
/**
* @param int $waterOdd
*
* @return void
*/
public function setWaterOdd(int $waterOdd){
$this->waterOdd = $waterOdd;
}
/**
* @param int $lavaOdd
*
* @return void
*/
public function setLavaOdd(int $lavaOdd){
$this->lavaOdd = $lavaOdd;
}
/**
* @param int $lavaSurfaceOdd
*
* @return void
*/
public function setLavaSurfaceOdd(int $lavaSurfaceOdd){
$this->lavaSurfaceOdd = $lavaSurfaceOdd;
}

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