Compare commits

..

232 Commits

Author SHA1 Message Date
ded45bddfe Release 3.12.1 2020-05-13 13:10:10 +01:00
b044550475 Player: duct tape for yet another login sequence bug in the shitty net architecture 2020-05-13 12:59:43 +01:00
a70fa15690 phpstan 0.12.25, drop some bug-filtering error patterns 2020-05-13 12:51:52 +01:00
bd1d7b8d75 asserts 👏 are 👏 not 👏 error 👏 checking 2020-05-13 12:39:55 +01:00
1513a0e092 VerifyLoginTask: beware wrong number of parts when splitting JWT 2020-05-13 12:39:53 +01:00
c4150d4520 Bump phpstan/phpstan from 0.12.23 to 0.12.25 (#3486) 2020-05-11 20:19:30 +00:00
2f47597d75 BaseLevelProvider: stop crashing the server on invalid level.dat
broken userdata isn't a core bug, so it shouldn't be flooding our crash archives.
2020-05-11 15:34:53 +01:00
ef97c8f99e Utils: fix parsing of single-line doc comments, closes #3388 (#3469)
* Utils: fix parsing of single-line doc comments, closes #3388

* correctly handle the empty doc-comment case, add another test case

* ignore an extra phpstan bug
2020-05-06 14:17:08 +01:00
84932ce908 Bump phpstan/phpstan from 0.12.22 to 0.12.23 (#3468) 2020-05-05 15:59:22 +00:00
6bfc309a0a phpstan 0.12.22 2020-05-04 22:26:44 +01:00
06e8c6a3ad Entity: new data flags 2020-05-04 21:58:44 +01:00
71271a0e03 Use env to locate bash (#3439)
This change uses env to locate bash, instead of hard-coding it. This is necessary on FreeBSD. Tested on Linux as well.
2020-04-30 17:34:13 +01:00
b63ad032a9 phpstan 0.12.19 2020-04-26 00:08:41 +01:00
d9b0e373bb Populator: fix return type of populate() 2020-04-26 00:04:17 +01:00
32262d9bb5 Merge branch 'stable' of https://github.com/pmmp/pocketmine-mp into stable 2020-04-25 11:59:35 +01:00
4c1b10b24b restructure ignoreErrors to allow regenerating them file by file 2020-04-25 11:59:06 +01:00
61dc9d7f6b phpstan: split up phpstan-bugs and phpstan-bugs-generated configs 2020-04-25 11:26:54 +01:00
da9731ef59 phpstan: add stub defines to improve analysis 2020-04-25 11:07:05 +01:00
e6f64c609e bootstrap: avoid making COMPOSER_AUTOLOADER_PATH having a possible false type 2020-04-25 11:04:09 +01:00
8c7fbf379b Bump irstea/phpunit-shim from 8.5.3 to 8.5.4 (#3435) 2020-04-24 20:45:43 +00:00
34a3e0d8b1 Level: fix sneaking use-item logic (thanks @95CivicSi)
inspired by, but closes #3403
fixes #3401
fixes #2539
fixes #1904
2020-04-19 15:38:12 +01:00
d42217ff57 Bump phpstan/phpstan-phpunit from 0.12.6 to 0.12.8 (#3421) 2020-04-19 14:26:22 +00:00
39d02a67d2 3.12.1 is next 2020-04-17 18:39:20 +01:00
77d45bf116 Release 3.12.0 2020-04-17 18:39:15 +01:00
f79182852b Fixed typo in login handler (wrong variable to store persona pieces) (#3422) 2020-04-17 14:36:51 +01:00
a107ad7404 1.14.60 support (#3407) 2020-04-17 09:18:00 +01:00
7a072931df Merge branch 'stable' of https://github.com/pmmp/pocketmine-mp into stable 2020-04-17 01:58:26 +01:00
f428a9bf52 protocol: rename some useless fields 2020-04-17 01:58:06 +01:00
2e720b48d9 AnimatePacket: added a new constant 2020-04-17 01:57:20 +01:00
a6e79bedf5 ActorEventPacket: plug some gaps 2020-04-17 01:56:56 +01:00
a5ba570fdf StructureBlockUpdatePacket: Added encode/decode (#3148) 2020-04-17 01:11:16 +01:00
0d5164af02 LabTablePacket: updated type field and added constants 2020-04-16 22:03:36 +01:00
534af770f8 InteractPacket: new constant 2020-04-16 22:03:34 +01:00
79ed377c7a Bump pocketmine/nbt from 0.2.13 to 0.2.14 (#3406)
Bumps [pocketmine/nbt](https://github.com/pmmp/NBT) from 0.2.13 to 0.2.14.
- [Release notes](https://github.com/pmmp/NBT/releases)
- [Commits](https://github.com/pmmp/NBT/compare/0.2.13...0.2.14)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-04-15 13:45:52 +01:00
20f3030709 3.11.8 is next 2020-04-14 02:54:41 +01:00
3aa58f54dc Release 3.11.7 2020-04-14 02:54:40 +01:00
5c12a95151 phpstan: force static reflection for COM class
com_dotnet has crap reflection exports and the class name case doesn't match.
2020-04-14 01:43:02 +01:00
5f07c5df1c Bump irstea/phpunit-shim from 8.5.2 to 8.5.3 (#3384) 2020-04-12 03:40:14 +00:00
5f33ef35e3 build: allow providing a git hash 2020-04-09 21:13:54 +01:00
ec949840b2 Do not crash on failure to decompress region chunks
this could happen when a chunk was partially overwritten with one of the same sector size.
2020-04-01 21:30:25 +01:00
e45e84b236 Updated composer dependencies 2020-03-31 18:43:30 +01:00
dfe68c9788 Bump phpstan/phpstan from 0.12.17 to 0.12.18 (#3372)
Bumps [phpstan/phpstan](https://github.com/phpstan/phpstan) from 0.12.17 to 0.12.18.
- [Release notes](https://github.com/phpstan/phpstan/releases)
- [Commits](https://github.com/phpstan/phpstan/compare/0.12.17...0.12.18)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-23 15:21:00 +00:00
35b8f0bf25 Bump phpstan/phpstan from 0.12.15 to 0.12.17 (#3363) 2020-03-18 13:06:14 +00:00
d4dc1c8a0c AttributeMap: be aware of possible NULL offset in ArrayAccess
reported by phpstan 0.12.17
2020-03-18 12:59:01 +00:00
517f9a3c3a Player: fix weapons not taking damage from attacks (bug introduced by #3348) 2020-03-18 12:51:05 +00:00
636c35dcf1 replace daverandom/callback-validator with pocketmine/callback-validator, closes #3359 2020-03-17 12:24:50 +00:00
d22f0da1de Bump phpstan/phpstan from 0.12.14 to 0.12.15 (#3362) 2020-03-17 12:20:55 +00:00
310de5a2b2 RCON: set SO_REUSEADDR to fix RCON start failure after restart (#3357) 2020-03-16 12:00:45 +00:00
f84abcd1fe sync composer.lock with 0dd68e587f 2020-03-14 13:36:35 +00:00
b5dd147ec7 PlayerQuitEvent: fix types of quitMessage 2020-03-14 13:24:40 +00:00
0dd68e587f require phpstan ^0.12.14 (for incremental analysis) 2020-03-13 16:30:35 +00:00
330e93e5e3 Player: do not handle inbound ActorEvents that are not for self 2020-03-13 15:15:20 +00:00
2020fcd18e updated build/php submodule 2020-03-12 11:47:15 +00:00
456d9a722a reduce some doc comments to single line 2020-03-10 12:36:19 +00:00
344c980cff GlobalConstants: add strict_types 2020-03-10 12:35:13 +00:00
167492087f Chunk: specify expected bounds for Y coordinates 2020-03-10 12:33:53 +00:00
db215283a2 Effect: add desc for color parameter 2020-03-10 12:28:44 +00:00
6a507bb149 further CS fixes 2020-03-10 12:18:16 +00:00
a72e6ee706 Player: be aware of held item changing during click-block
this caused bugs if the inventory was cleared while using a hoe.
2020-03-10 12:10:01 +00:00
89ea7f0a76 Player: Stop setting held item post entity attack if changed (#3348)
closes #3340
2020-03-10 10:09:31 +00:00
a6ca37429c Player: do not set held item post block-break if changed (#3345)
this usually happens when a plugin replaces the held item during BlockBreakEvent.
closes #2010
2020-03-09 13:45:58 +00:00
4bf9fb278b Bump phpstan/phpstan from 0.12.11 to 0.12.14 (#3338) 2020-03-09 13:31:23 +00:00
15d81154e6 PluginDescription: drop unenforceable type constraint on array keys
the data that comes through here isn't validated, and there's also no guarantee that all the keys will be strings in spite of our best efforts even if it was validated, because PHP is fucking stupid and casts int-like string keys to int keys.
2020-03-05 19:53:01 +00:00
93e5c80962 MultiplayerSettingsPacket is bothways, close #3331 2020-03-03 12:32:57 +00:00
7aa8bd18d3 Revert "Item: restrict bounds of count to 0-255"
This reverts commit 10317527e4.

this breaks user code which exceeds stack limits in legitimate
circumstances. For example, it should be OK to add 6000x diamond to a
player's inventory without being forced to manually split the count up
for addItem().
2020-02-25 20:42:03 +00:00
53067c26d7 BaseInventory: stop mutating item for no reason in canAddItem() 2020-02-25 20:30:37 +00:00
04581e2700 DataPacket: account for splitscreen header when decoding 2020-02-24 21:20:25 +00:00
93597dcd50 SkinData: fixed loss of data from packet decode 2020-02-24 20:48:03 +00:00
778814a35e changelog: fix typo 2020-02-24 20:18:47 +00:00
3cd1da196a UpdateTradePacket: fix order of fields, closes #3327 2020-02-24 20:16:07 +00:00
365d4a1592 better fix for 1.14.30 movement bug 2020-02-23 19:31:32 +00:00
2d7f37ac47 avoid direct mutation of Item->count field, use Item->pop() instead
I think this change was already applied on the master branch, but I don't remember for sure.
2020-02-23 17:37:25 +00:00
50fcdd6e7e Item: fixed documentation of pop() return type (it's not fluent) 2020-02-23 17:32:50 +00:00
10317527e4 Item: restrict bounds of count to 0-255 2020-02-23 17:23:53 +00:00
46ac4cbca1 3.11.7 is next 2020-02-21 19:18:48 +00:00
cb9e79b398 Release 3.11.6 2020-02-21 19:18:48 +00:00
2f1fad2745 Bucket: implement MaybeConsumable, fixes #3306
this is a nauseating fix, but it's only needed for stable.
2020-02-21 17:49:55 +00:00
44182dccbd Human: an additional hack for MoveActor(Absolute|Delta)Packet on 1.14.30+
before anyone asks, we still can't use this for regular player movement, because it would cause the player to receive their own movement. This was OK with MoveActor, but isn't OK with MovePlayer.
2020-02-21 12:35:17 +00:00
2f3d2d4a0b Bump phpstan/phpstan from 0.12.10 to 0.12.11 (#3311) 2020-02-19 18:57:53 +00:00
8ac7f7f11f Level: fix type of randomTickBlocks and friends 2020-02-17 15:13:40 +00:00
dbe7caab7b updated build/preprocessor submodule 2020-02-14 08:21:46 +00:00
b581fab31a updated build/php submodule 2020-02-14 08:19:23 +00:00
7b7dfc36d1 Living: fixed broken @var tag 2020-02-14 08:17:51 +00:00
d63d6b73f6 Player: workaround 1.14.30 movement bug
I can understand why this bug happened, but it doesn't mean I like it.
Fix it pls mojang, this sucks.
2020-02-13 19:40:31 +00:00
a860ccd259 Bump phpstan/phpstan from 0.12.9 to 0.12.10
Bumps [phpstan/phpstan](https://github.com/phpstan/phpstan) from 0.12.9 to 0.12.10.
- [Release notes](https://github.com/phpstan/phpstan/releases)
- [Commits](https://github.com/phpstan/phpstan/compare/0.12.9...0.12.10)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-13 11:24:13 +00:00
2bb497b716 Chunk: flag hasChanged when changing generated/populated/light-populated flags 2020-02-11 08:26:12 +00:00
613bd40601 PopulationTask: move setPopulated() call to make it more obvious what is going on 2020-02-10 18:22:19 +00:00
398b636759 PopulationTask: fixed chunks being generated empty in flat worlds
the flat generator just clones a pregenerated chunk instead of modifying the provided chunks, which means that the references that population task has would be the outdated ones.
2020-02-10 18:21:08 +00:00
1257378198 clean up function imports 2020-02-08 09:31:15 +00:00
758a68aa2c ItemFactory: add Item[] as type for list field (for auto complete) 2020-02-07 20:11:31 +00:00
bfce478e72 BlockFactory: keep the generic types for PHPStan, which actually understands it 2020-02-07 20:10:40 +00:00
681dd469a2 PluginManager: add class-string phpstan param to registerEvent() 2020-02-07 20:05:41 +00:00
3edbea8545 PluginManager: fix spacing of phpdoc comment for registerEvent() 2020-02-07 19:37:22 +00:00
ada8cbb545 phpstan: drop some ignoreErrors that don't occur on 0.12.9 2020-02-06 21:01:05 +00:00
0ac5e03ce9 Require PHPStan 0.12.9 minimum 2020-02-06 20:59:43 +00:00
9b02b8e51e Item: do not compare serialized NBT in equals()
this isn't cached anymore, and would be a performance drag.
It would be nice to have some kind of fast path for this, but comparing NBT binary isn't it.
2020-02-06 20:23:58 +00:00
6c7dada232 finally, integrate phpstan-strict-rules 2020-02-06 19:44:10 +00:00
25bc95cd1e removing more unnecessary casts 2020-02-06 19:33:34 +00:00
213bf8366a TranslationContainer: fix parameter type of setParameters() 2020-02-06 19:33:34 +00:00
4e693e91e6 ChestInventory: document that getHolder() may return Position
there is a variance issue with EnderChestInventory that was detected by phpstan-strict-rules which can't be addressed without a BC break. This fix will at least allow static analysers to be aware that code using this function might catch fire when it sees an EnderChestInventory without realizing it.
2020-02-06 19:33:34 +00:00
a1622fa345 UtilsTest: silence a phpstan-strict-rules warning 2020-02-06 18:53:05 +00:00
0ec869932f Item: clean up internal NBT storage, discard useless legacy network cache
this will now bail if the NBT string given is invalid upon setCompoundTag(), rather than shitting the bed when it's accessed.
2020-02-06 17:59:05 +00:00
79acaa3253 Utils: remove useless typecasts 2020-02-06 16:06:58 +00:00
da3742b39e Remove useless typecasts 2020-02-06 16:00:57 +00:00
d26fcf7dee Removed useless casts() from min/max calls 2020-02-06 15:58:27 +00:00
812424a619 GroundCover: drop useless variable in calculating startY 2020-02-06 14:26:03 +00:00
1bdc61dd5f Ore: do not destroy outer scope vars in for loops 2020-02-06 14:24:57 +00:00
86fc33fe26 Level: add phpstan generics to getNearestEntity() 2020-02-06 14:20:19 +00:00
70eb41470c ContainerInventory: remove redundant check 2020-02-06 14:19:33 +00:00
3a5709bf5e start using phpstan-phpunit
not using extension-installer because I want to part-integrate phpstan-strict-rules later on.
2020-02-06 13:23:18 +00:00
5ad66c3c9b BlockTest: throw exception instead of always-false assert 2020-02-06 13:21:39 +00:00
7885b54824 phpstan: run static analysis on tests 2020-02-06 13:13:12 +00:00
532dc0fb6f tests/phpunit: populate iterable types for phpstan 2020-02-06 13:11:56 +00:00
54ccc330d5 Bump irstea/phpunit-shim from 7.5.20 to 8.5.2 (#3296) 2020-02-06 12:50:51 +00:00
e12618c705 tests/phpunit: added missing native typehints 2020-02-06 12:13:42 +00:00
7d5f2eac8d Merge branch 'stable' of https://github.com/pmmp/pocketmine-mp into stable 2020-02-06 08:38:12 +00:00
e964dd2ca8 travis: cache composer vcs directory too 2020-02-06 08:37:38 +00:00
dbb594f130 Merge pull request #3297 from pmmp/dependabot/composer/adhocore/json-comment-0.1.0
Bump adhocore/json-comment from 0.0.7 to 0.1.0
2020-02-05 22:47:04 +00:00
8f434b9edd Bump adhocore/json-comment from 0.0.7 to 0.1.0
Bumps [adhocore/json-comment](https://github.com/adhocore/php-json-comment) from 0.0.7 to 0.1.0.
- [Release notes](https://github.com/adhocore/php-json-comment/releases)
- [Changelog](https://github.com/adhocore/php-json-comment/blob/master/CHANGELOG.md)
- [Commits](https://github.com/adhocore/php-json-comment/compare/v0.0.7...0.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-05 22:40:41 +00:00
34972c3327 Assume that getmypid() never returns false
my background research on this informs me that this returns false on negative PID, which never happens because the underlying C API call never fails - not on linux, bsd, or windows.
2020-02-05 21:00:56 +00:00
037c34d961 Living: fixed bad @var confusing PHPStan 2020-02-05 20:58:38 +00:00
4518d9d9ce Item: drop useless @var confusing PHPStan 2020-02-05 20:55:58 +00:00
1a5228e7a6 Fixed property types with missing null PhpDoc types 2020-02-05 20:55:03 +00:00
495bfda044 Drop a bunch of invalid null defaults
phpstan doesn't report these out of the box, for reasons I'm not clear on. It's also not clear if having null defaults has any effect on nullability behaviour, so they are best removed. In addition, these would be problematic on 7.4.
2020-02-05 20:53:54 +00:00
41b1fa7b48 Config: clean up inconsistent data parsing & handling 2020-02-05 20:50:36 +00:00
e689fd545b PocketMine.php: avoid use of short ternary 2020-02-05 20:48:54 +00:00
889cd5e206 PlayerNetworkSessionAdapter: clean up leftovers from multi quote support for json decode 2020-02-05 20:45:13 +00:00
e1ddf90695 Chunk: remove useless instanceof checks
these are always CompoundTags, and if they aren't we have a bug somewhere else.
2020-02-05 20:44:27 +00:00
2f325b8c91 Permission: loadPermission() never returns null 2020-02-05 20:43:40 +00:00
ac4f00be81 PluginManager: combine conditions into something less useless
the left side was already implying that the var is a Plugin instance, but PHPStan doesn't like non-bool conditions in strict mode.
2020-02-05 20:42:40 +00:00
914450c30b Entity: remove useless assert()
namedtag is always non-null here, and if it isn't, it should just catch fire the normal way.
2020-02-05 20:40:34 +00:00
25554f0d61 Level: remove useless code from unload() 2020-02-05 20:39:38 +00:00
e1a61cb51a BaseLang: get() never returns null 2020-02-05 20:38:45 +00:00
fe5620f097 ThreadManager: Lazy-init during getInstance() 2020-02-05 20:36:44 +00:00
faef4e8736 SimpleCommandMap: Command->getLabel() never returns null 2020-02-05 20:33:27 +00:00
0d19f6c968 Server: initialize auto updater before loading plugins, not after
from a plugin PoV, getUpdater() is always supposed to return an AutoUpdater instance, but it would return null during onLoad(), which is bad.
2020-02-05 20:32:51 +00:00
ecf662bf74 Server: Lazy-init static sleeper as-needed
this makes it testable without a server context.
2020-02-05 20:31:01 +00:00
8cba2e0346 Server: fixed wrong non-nullability of queryHandler 2020-02-05 19:56:16 +00:00
dfc8a6ffdd Player: remove useless code from save() 2020-02-05 19:54:50 +00:00
262728b091 PopulationTask: clean up overcomplicated garbage 2020-02-05 18:31:51 +00:00
4572ec8175 travis: run composer with --prefer-dist 2020-02-05 17:14:11 +00:00
0f6949ac34 phpstan 0.12.9 2020-02-05 17:11:08 +00:00
df8e0cf1f5 MemoryManager: eliminate unnecessary reference abuse in continueDump()
this makes the flow of data easier to understand, and also sidesteps some PHPStan bugs.
2020-02-05 17:06:05 +00:00
ad87c11ae1 ThreadManager: use array-access instead of variable property access 2020-02-05 16:36:11 +00:00
fa82cb26d8 added native types to closures (phpstan-strict-rules) 2020-02-05 16:35:10 +00:00
fd2a7797bd include make-release.php in phpstan analysis 2020-02-05 15:55:41 +00:00
e5a2cfb65f avoid type juggling in conditions, always use explicit boolean conditions 2020-02-05 15:44:06 +00:00
b96bb7d824 Player: use strict base64_decode() for login decoding
though, perhaps we should beware of false returns?
2020-02-05 13:55:38 +00:00
896cca0778 store composer cache for travis 2020-02-05 13:36:45 +00:00
59cf8e95f0 Tree: fixed populator not growing trees any lower than y=2
this would only be a problem for custom generators, but nonetheless...
2020-02-05 13:17:09 +00:00
99038c752c Avoid usage of for-loop vars outside of for-loop context
these problems were reported by PHPStan strict rules. They aren't actually bugs, but they could become bugs in the future.
2020-02-05 13:16:09 +00:00
88afedd1e8 Human: avoid overwriting non-foreach vars in foreach 2020-02-05 12:59:59 +00:00
c43e21235d HelpCommand: do not overwrite non-foreach vars in foreach 2020-02-05 12:57:27 +00:00
3f7e7352fb added SplFixedArray generics for phpstan 0.12.9 2020-02-05 11:57:37 +00:00
32d6ea0fba Chest: do not crash on failure to fetch pair, closes #2701
isPaired() returning true is not semantically equivalent to getPair() returning non-null. getPair() might return null if the pair is inaccessible, such as when it's in an unloaded chunk (it doesn't check this yet, but it should).
For the sake of opening inventory, we don't care if the chest believes if it is paired, we care if there is actually a pair to be accessed for inventory viewing.
In addition, it's possible to create this broken-data scenario artificially by close()ing a chest tile without unpairing it first, because a tile doesn't know the difference between being closed due to unload and being destroyed.
2020-02-03 19:32:58 +00:00
28c787371a Server::$rcon may be null (disabled or failed to start) 2020-02-03 19:25:56 +00:00
dba14c9f08 PharPluginLoader: remove useless instanceof, offset is always PharFileInfo at this point 2020-02-03 12:35:34 +00:00
0e35ee8cb7 build/server-phar: drop unused imports 2020-02-03 11:18:21 +00:00
da5b7f47df build/server-phar: import global functions 2020-02-03 11:17:51 +00:00
d418dd7a09 build/make-release: fix formatting 2020-02-03 11:17:16 +00:00
f3209ccc33 build/make-release: remove unused import 2020-02-03 11:16:51 +00:00
4a4c28cd8c travis.sh: ditch PHP_BINARY variable, use PATH prefix instead
this is how normal people do it ...
2020-02-03 09:30:43 +00:00
eba8d77034 3.11.6 is next 2020-02-02 18:31:51 +00:00
13e4772f98 Release 3.11.5 2020-02-02 18:31:51 +00:00
4bc2f28c6d Provide a ChunkUtils stub for PHPStan, so it doesn't get confused when the extension is loaded
for some reason the presence of the type problems were reported as
problems on ChunkUtils.php, despite being outside of the project scope
and the errors not applying to the polyfill.
2020-02-02 18:12:41 +00:00
663469dfa7 travis: remove xdebug to improve build time
xdebug is almost completely useless here.
2020-02-02 16:30:00 +00:00
963abb718f build/server-phar: compress using gzip (except stub)
this produces a 75% reduction in phar size, at the expense of a slight degradation of autoloading speed and needing a writable tmpdir.
2020-02-02 16:27:38 +00:00
1f2fb73297 updated DevTools submodule to 1.14.0 2020-02-02 10:21:32 +00:00
ff55b520b9 updated composer dependencies 2020-02-01 22:55:27 +00:00
cedd8abf0c README: no need to specify 'community' Discord [ci skip] 2020-02-01 22:19:24 +00:00
496732999c reintroduce BedrockData submodule 2020-02-01 22:05:07 +00:00
6a8105f5a0 delete BedrockData submodule 2020-02-01 22:01:22 +00:00
0a566f8218 LevelProvider::generate() accepts class-string<Generator>, not any
string
2020-02-01 20:16:05 +00:00
829dd02eea Server: fixed more bad non-nullable phpdocs 2020-02-01 19:30:47 +00:00
b11c350b2b composer: use new pocketmine/log & pocketmine/classloader classes 2020-01-31 15:51:26 +00:00
f624e36faf composer: all of these packages are now available on packagist 2020-01-31 15:49:33 +00:00
14ce9c10bb BUILDING.md: fix typo 2020-01-31 13:27:29 +00:00
b27aaaeeb2 added build instructions, close #2839 2020-01-31 11:32:28 +00:00
f1083bd9c4 SimpleCommandMap: beware case mismatches in alias recursion, closes #3281 2020-01-31 10:36:47 +00:00
199fa61aef update composer dependencies 2020-01-30 22:41:58 +00:00
af82a6bbe1 phpstan: enable checkMissingIterableValueType 2020-01-30 22:31:42 +00:00
004f7ef82e phpstan: stub out the iterable bullshit with pthreads
this isn't a perfect fix, but it's better than it whining about all the things.
2020-01-30 22:31:15 +00:00
89ebd2b880 remove some dead ignoreErrors 2020-01-30 22:30:04 +00:00
799183e13e make use of phpstan class-string in some areas 2020-01-30 22:23:11 +00:00
260ac47588 add some phpstan array types 2020-01-30 22:23:11 +00:00
4ff4434a22 build/server-phar: mark metadata as mixed[] 2020-01-30 21:49:52 +00:00
5d8bb84269 add more mixed[] to item namespace 2020-01-30 21:48:11 +00:00
9eebfa7cc3 populate missing array value types in root namespace 2020-01-30 21:43:00 +00:00
d3021c6281 populate missing array value types in utils namespace, pass 2 2020-01-30 21:39:15 +00:00
9097d6c4d3 AutoUpdater: fixed type doc for updateInfo 2020-01-30 21:34:26 +00:00
da43ae82fe populate missing array value types in utils namespace, pass 1 2020-01-30 21:30:01 +00:00
60b405d944 populate missing array value types in updater namespace 2020-01-30 21:23:05 +00:00
92a752053d populate missing array value types in tile namespace 2020-01-30 21:20:42 +00:00
0537c66849 populate missing array value types in scheduler namespace 2020-01-30 21:19:15 +00:00
d94995e161 populate missing array value types in plugin namespace 2020-01-30 21:17:13 +00:00
58bc08838b populate missing array value types in permission namespace 2020-01-30 21:14:18 +00:00
fc0619ee6e populate missing array value types in network namespace 2020-01-30 21:12:00 +00:00
a5764b3ae9 populate missing array value types in level namespace 2020-01-30 21:01:59 +00:00
8bf469f7fc populate missing array value types in lang namespace 2020-01-30 20:55:03 +00:00
3b9a5c5ccc populate missing array value types in item namespace 2020-01-30 20:54:38 +00:00
4c36ca58e2 populate missing array value types in inventory namespace 2020-01-30 20:53:41 +00:00
a67fa5c007 populate missing array value types in event namespace 2020-01-30 20:52:54 +00:00
839a789180 populate missing array value types in entity namespace 2020-01-30 20:50:24 +00:00
e61c3e8bf6 populate missing array value types in command namespace 2020-01-30 20:48:14 +00:00
7ce6c8aa13 TimingsCommand: fix confusing indentation 2020-01-30 20:47:33 +00:00
9abcc99c10 Command: fixed spacing of phpdoc on execute() 2020-01-30 20:46:25 +00:00
5c8a625d88 populate missing iterable value types in block namespace 2020-01-30 20:43:13 +00:00
259f0425a9 ClientboundMapItemDataPacket: replace assoc array with MapDecoration class
I thought I'd done this already, but it appears not.
2020-01-30 20:05:18 +00:00
9cdea43794 provide more array type information for Internet functions 2020-01-29 20:45:03 +00:00
e007fad5b8 fix return types for Utils/Internet getURL()/postURL() 2020-01-29 20:43:09 +00:00
5cf2fcbbb7 simpleCurl() second return value is string[][], not string[] 2020-01-29 20:38:19 +00:00
9e6cbb5b6a Internet: fix type information for getURL(), postURL() and simpleCurl() 2020-01-29 20:20:52 +00:00
64b3d02974 Chunk: remove useless condition from populateSkyLight()
this was detected by latest bleeding-edge PHPStan.
2020-01-29 16:42:42 +00:00
640df1003c add some Generator generics for PHPStan 2020-01-29 16:38:50 +00:00
2b402e525a add some PHPStan-specific callable prototypes 2020-01-29 15:03:55 +00:00
e2871fad8e composer.json: move require-dev next to require 2020-01-28 14:32:55 +00:00
41d02003c2 Install PHPStan and PHPUnit via dev dependencies 2020-01-27 12:04:42 +00:00
156ecd9bd8 travis: use phpstan 0.12.8 2020-01-27 09:31:27 +00:00
fa7736efbb phpstan 0.12.7 2020-01-25 17:16:14 +00:00
d71a7ff2fa travis.sh: fix indentation 2020-01-25 17:15:37 +00:00
8184a6b114 SkinImage: enforce that height/width must be positive 2020-01-22 14:58:36 +00:00
b8d44ff162 SkinImage: fix formatting error 2020-01-22 14:58:00 +00:00
f6611a38bc Explosion: fix trailing whitespace in explodeA() phpdoc 2020-01-22 14:51:49 +00:00
24ed823d96 WritableBook: remove extra line from phpdoc on setPages() 2020-01-22 14:51:14 +00:00
f624871b3f strip extra blank lines (php-cs-fixer) 2020-01-22 14:50:29 +00:00
9cd6b3e1c7 fix remaining multiline @var annotations 2020-01-22 14:44:36 +00:00
aad1eb5b3e CoreConstants: fix EOF newline 2020-01-22 14:40:03 +00:00
bff5bf25ae LegacySkinAdapter: make resource patch validity check more robust 2020-01-22 14:36:40 +00:00
cda90fd7f1 Merge pull request #3280 from pmmp/stable-phpdoc-armageddon
Mass-removal of redundant @param / @return PhpDoc annotations
2020-01-22 10:48:50 +00:00
9f44adf04a pass 2, manual removal of incorrect non-nullable @param for nullable native types 2020-01-21 15:44:34 +00:00
c4793241f5 Mass removal of useless @param/@return PHPDoc annotations, pass 1 2020-01-21 15:10:18 +00:00
7532c609fb 3.11.5 is next 2020-01-20 18:06:46 +00:00
541 changed files with 3258 additions and 6555 deletions

6
.gitmodules vendored
View File

@ -7,9 +7,9 @@
[submodule "tests/plugins/PocketMine-DevTools"] [submodule "tests/plugins/PocketMine-DevTools"]
path = tests/plugins/PocketMine-DevTools path = tests/plugins/PocketMine-DevTools
url = https://github.com/pmmp/PocketMine-DevTools.git url = https://github.com/pmmp/PocketMine-DevTools.git
[submodule "src/pocketmine/resources/vanilla"]
path = src/pocketmine/resources/vanilla
url = https://github.com/pmmp/BedrockData.git
[submodule "build/php"] [submodule "build/php"]
path = build/php path = build/php
url = https://github.com/pmmp/php-build-scripts.git url = https://github.com/pmmp/php-build-scripts.git
[submodule "src/pocketmine/resources/vanilla"]
path = src/pocketmine/resources/vanilla
url = https://github.com/pmmp/BedrockData.git

View File

@ -5,6 +5,7 @@ php:
- 7.3 - 7.3
before_script: before_script:
- phpenv config-rm xdebug.ini
# - pecl install channel://pecl.php.net/pthreads-3.1.6 # - pecl install channel://pecl.php.net/pthreads-3.1.6
- echo | pecl install channel://pecl.php.net/yaml-2.0.4 - echo | pecl install channel://pecl.php.net/yaml-2.0.4
- git clone https://github.com/pmmp/pthreads.git - git clone https://github.com/pmmp/pthreads.git
@ -16,10 +17,18 @@ before_script:
- make install - make install
- cd .. - cd ..
- echo "extension=pthreads.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini - echo "extension=pthreads.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
- composer install
script: script:
- composer install --prefer-dist
- ./vendor/bin/phpstan analyze --no-progress --memory-limit=2G
- ./vendor/bin/phpunit --bootstrap vendor/autoload.php --fail-on-warning tests/phpunit
- composer install --no-dev --prefer-dist
- ./tests/travis.sh -t4 - ./tests/travis.sh -t4
cache:
directories:
- $HOME/.composer/cache/files
- $HOME/.composer/cache/vcs
notifications: notifications:
email: false email: false

38
BUILDING.md Normal file
View File

@ -0,0 +1,38 @@
# Building
## Pre-requisites
- A bash shell (git bash is sufficient for Windows)
- [`git`](https://git-scm.com) available in your shell
- PHP 7.2 or newer available in your shell
- [`composer`](https://getcomposer.org) available in your shell
## Custom PHP binaries
Because PocketMine-MP requires several non-standard PHP extensions and configuration, PMMP provides scripts to build custom binaries for running PocketMine-MP, as well as prebuilt binaries.
- [Prebuilt binaries](https://jenkins.pmmp.io/job/PHP-7.3-Aggregate)
- [Compile scripts](https://github.com/pmmp/php-build-scripts) are provided as a submodule in the path `build/php`
If you use a custom binary, you'll need to replace `composer` usages in this guide with `path/to/your/php path/to/your/composer.phar`.
## Setting up environment
1. `git clone --recursive https://github.com/pmmp/PocketMine-MP.git`
2. `composer install`
## Checking out a different branch to build
1. `git checkout <branch to checkout>`
2. `git submodule update --init`
3. Re-run `composer install` to synchronize dependencies.
## Optimizing for release builds
1. Add the flags `--no-dev --classmap-authoritative` to your `composer install` command. This will reduce build size and improve autoloading speed.
2. Preprocess the source code by running `build/preprocessor/PreProcessor.php`. Usage instructions are provided in `build/preprocessor/README.md`.
### Note
Preprocessor requires that the `cpp` (c preprocessor) is available in your PATH.
## Building `PocketMine-MP.phar`
Run `build/server.phar` using your preferred PHP binary. It'll drop a `PocketMine-MP.phar` into the current working directory.
You can also use the `--out` option to change the output filename.
## Running PocketMine-MP from source code
Run `src/pocketmine/PocketMine.php` using your preferred PHP binary.

View File

@ -13,10 +13,11 @@
## Discussion/Help ## Discussion/Help
- [Forums](https://forums.pmmp.io/) - [Forums](https://forums.pmmp.io/)
- [Community Discord](https://discord.gg/bmSAZBG) - [Discord](https://discord.gg/bmSAZBG)
- [StackOverflow](https://stackoverflow.com/tags/pocketmine) - [StackOverflow](https://stackoverflow.com/tags/pocketmine)
## For developers ## For developers
* [Building and running from source](BUILDING.md)
* [Latest API documentation](https://jenkins.pmmp.io/job/PocketMine-MP-doc/doxygen/) - Doxygen documentation generated from development * [Latest API documentation](https://jenkins.pmmp.io/job/PocketMine-MP-doc/doxygen/) - Doxygen documentation generated from development
* [DevTools](https://github.com/pmmp/PocketMine-DevTools/) - Development tools plugin for creating plugins * [DevTools](https://github.com/pmmp/PocketMine-DevTools/) - Development tools plugin for creating plugins
* [ExamplePlugin](https://github.com/pmmp/ExamplePlugin/) - Example plugin demonstrating some basic API features * [ExamplePlugin](https://github.com/pmmp/ExamplePlugin/) - Example plugin demonstrating some basic API features

View File

@ -21,14 +21,13 @@
declare(strict_types=1); declare(strict_types=1);
namespace pocketmine\build_script; namespace pocketmine\build\make_release;
use pocketmine\utils\VersionString; use pocketmine\utils\VersionString;
use function dirname; use function dirname;
use function fgets; use function fgets;
use function file_get_contents; use function file_get_contents;
use function file_put_contents; use function file_put_contents;
use function preg_quote;
use function preg_replace; use function preg_replace;
use function sleep; use function sleep;
use function sprintf; use function sprintf;
@ -38,17 +37,6 @@ use const STDIN;
require_once dirname(__DIR__) . '/vendor/autoload.php'; require_once dirname(__DIR__) . '/vendor/autoload.php';
if(isset($argv[1])){
$currentVer = new VersionString($argv[1]);
}else{
$currentVer = new VersionString(BASE_VERSION);
}
$nextVer = new VersionString(sprintf(
"%u.%u.%u",
$currentVer->getMajor(),
$currentVer->getMinor(),
$currentVer->getPatch() + 1
));
function replaceVersion(string $versionInfoPath, string $newVersion, bool $isDev) : void{ function replaceVersion(string $versionInfoPath, string $newVersion, bool $isDev) : void{
$versionInfo = file_get_contents($versionInfoPath); $versionInfo = file_get_contents($versionInfoPath);
@ -59,22 +47,45 @@ function replaceVersion(string $versionInfoPath, string $newVersion, bool $isDev
); );
$versionInfo = preg_replace( $versionInfo = preg_replace(
'/^const IS_DEVELOPMENT_BUILD = (?:true|false);$/m', '/^const IS_DEVELOPMENT_BUILD = (?:true|false);$/m',
'const IS_DEVELOPMENT_BUILD = ' . ($isDev ? 'true' : 'false'). ';', 'const IS_DEVELOPMENT_BUILD = ' . ($isDev ? 'true' : 'false') . ';',
$versionInfo $versionInfo
); );
file_put_contents($versionInfoPath, $versionInfo); file_put_contents($versionInfoPath, $versionInfo);
} }
$versionInfoPath = dirname(__DIR__) . '/src/pocketmine/VersionInfo.php';
replaceVersion($versionInfoPath, $currentVer->getBaseVersion(), false);
echo "please add appropriate notes to the changelog and press enter..."; /**
fgets(STDIN); * @param string[] $argv
system('git add "' . dirname(__DIR__) . '/changelogs"'); * @phpstan-param list<string> $argv
system('git commit -m "Release ' . $currentVer->getBaseVersion() . '" --include "' . $versionInfoPath . '"'); */
system('git tag ' . $currentVer->getBaseVersion()); function main(array $argv) : void{
replaceVersion($versionInfoPath, $nextVer->getBaseVersion(), true); if(isset($argv[1])){
system('git add "' . $versionInfoPath . '"'); $currentVer = new VersionString($argv[1]);
system('git commit -m "' . $nextVer->getBaseVersion() . ' is next" --include "' . $versionInfoPath . '"'); }else{
echo "pushing changes in 5 seconds\n"; $currentVer = new VersionString(BASE_VERSION);
sleep(5); }
system('git push origin HEAD ' . $currentVer->getBaseVersion()); $nextVer = new VersionString(sprintf(
"%u.%u.%u",
$currentVer->getMajor(),
$currentVer->getMinor(),
$currentVer->getPatch() + 1
));
$versionInfoPath = dirname(__DIR__) . '/src/pocketmine/VersionInfo.php';
replaceVersion($versionInfoPath, $currentVer->getBaseVersion(), false);
echo "please add appropriate notes to the changelog and press enter...";
fgets(STDIN);
system('git add "' . dirname(__DIR__) . '/changelogs"');
system('git commit -m "Release ' . $currentVer->getBaseVersion() . '" --include "' . $versionInfoPath . '"');
system('git tag ' . $currentVer->getBaseVersion());
replaceVersion($versionInfoPath, $nextVer->getBaseVersion(), true);
system('git add "' . $versionInfoPath . '"');
system('git commit -m "' . $nextVer->getBaseVersion() . ' is next" --include "' . $versionInfoPath . '"');
echo "pushing changes in 5 seconds\n";
sleep(5);
system('git push origin HEAD ' . $currentVer->getBaseVersion());
}
if(!defined('pocketmine\_PHPSTAN_ANALYSIS')){
main($argv);
}

View File

@ -24,12 +24,28 @@ declare(strict_types=1);
namespace pocketmine\build\server_phar; namespace pocketmine\build\server_phar;
use pocketmine\utils\Git; use pocketmine\utils\Git;
use function array_map;
use function count;
use function defined;
use function dirname;
use function file_exists;
use function getcwd;
use function getopt;
use function implode;
use function ini_get;
use function microtime;
use function preg_quote;
use function realpath;
use function round;
use function rtrim;
use function sprintf;
use function str_replace;
use function unlink;
require dirname(__DIR__) . '/vendor/autoload.php'; require dirname(__DIR__) . '/vendor/autoload.php';
/** /**
* @param string[] $strings * @param string[] $strings
* @param string|null $delim
* *
* @return string[] * @return string[]
*/ */
@ -38,19 +54,15 @@ function preg_quote_array(array $strings, string $delim = null) : array{
} }
/** /**
* @param string $pharPath
* @param string $basePath
* @param string[] $includedPaths * @param string[] $includedPaths
* @param array $metadata * @param mixed[] $metadata
* @param string $stub * @phpstan-param array<string, mixed> $metadata
* @param int $signatureAlgo
* @param int|null $compression
* *
* @return \Generator|string[] * @return \Generator|string[]
*/ */
function buildPhar(string $pharPath, string $basePath, array $includedPaths, array $metadata, string $stub, int $signatureAlgo = \Phar::SHA1, ?int $compression = null){ function buildPhar(string $pharPath, string $basePath, array $includedPaths, array $metadata, string $stub, int $signatureAlgo = \Phar::SHA1, ?int $compression = null){
$basePath = rtrim(str_replace("/", DIRECTORY_SEPARATOR, $basePath), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; $basePath = rtrim(str_replace("/", DIRECTORY_SEPARATOR, $basePath), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
$includedPaths = array_map(function($path){ $includedPaths = array_map(function(string $path) : string{
return rtrim(str_replace("/", DIRECTORY_SEPARATOR, $path), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; return rtrim(str_replace("/", DIRECTORY_SEPARATOR, $path), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
}, $includedPaths); }, $includedPaths);
yield "Creating output file $pharPath"; yield "Creating output file $pharPath";
@ -103,14 +115,9 @@ function buildPhar(string $pharPath, string $basePath, array $includedPaths, arr
yield "Added $count files"; yield "Added $count files";
if($compression !== null){ if($compression !== null){
yield "Checking for compressible files..."; yield "Compressing files...";
foreach($phar as $file => $finfo){ $phar->compressFiles($compression);
/** @var \PharFileInfo $finfo */ yield "Finished compression";
if($finfo->getSize() > (1024 * 512)){
yield "Compressing " . $finfo->getFilename();
$finfo->compress($compression);
}
}
} }
$phar->stopBuffering(); $phar->stopBuffering();
@ -123,9 +130,13 @@ function main() : void{
exit(1); exit(1);
} }
$opts = getopt("", ["out:"]); $opts = getopt("", ["out:", "git:"]);
$gitHash = Git::getRepositoryStatePretty(dirname(__DIR__)); if(isset($opts["git"])){
echo "Git hash detected as $gitHash" . PHP_EOL; $gitHash = $opts["git"];
}else{
$gitHash = Git::getRepositoryStatePretty(dirname(__DIR__));
echo "Git hash detected as $gitHash" . PHP_EOL;
}
foreach(buildPhar( foreach(buildPhar(
$opts["out"] ?? getcwd() . DIRECTORY_SEPARATOR . "PocketMine-MP.phar", $opts["out"] ?? getcwd() . DIRECTORY_SEPARATOR . "PocketMine-MP.phar",
dirname(__DIR__) . DIRECTORY_SEPARATOR, dirname(__DIR__) . DIRECTORY_SEPARATOR,
@ -136,7 +147,23 @@ function main() : void{
[ [
'git' => $gitHash 'git' => $gitHash
], ],
'<?php require("phar://" . __FILE__ . "/src/pocketmine/PocketMine.php"); __HALT_COMPILER();' <<<'STUB'
<?php
$tmpDir = sys_get_temp_dir();
if(!is_readable($tmpDir) or !is_writable($tmpDir)){
echo "ERROR: tmpdir $tmpDir is not accessible." . PHP_EOL;
echo "Check that the directory exists, and that the current user has read/write permissions for it." . PHP_EOL;
echo "Alternatively, set 'sys_temp_dir' to a different directory in your php.ini file." . PHP_EOL;
exit(1);
}
require("phar://" . __FILE__ . "/src/pocketmine/PocketMine.php");
__HALT_COMPILER();
STUB
,
\Phar::SHA1,
\Phar::GZ
) as $line){ ) as $line){
echo $line . PHP_EOL; echo $line . PHP_EOL;
} }

View File

@ -53,3 +53,45 @@ Plugin developers should **only** update their required API to this version if y
- Populate type information in lots of places where it was previously missing; this will improve the quality of static analysis for plugins. - 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 logs previous exceptions recursively.
- `MainLogger::logException()` now always logs exceptions as `critical`. - `MainLogger::logException()` now always logs exceptions as `critical`.
# 3.11.5
- PHPStan and PHPUnit are now managed as Composer dev dependencies.
- Core code is now analyzed using PHPStan level 6 (full, including iterable types checking).
- Improved type information available to PHPStan in many areas.
- Mass-removal of useless PHPDoc.
- Fixed incorrect documentation of `Internet::getURL()`, `Internet::postURL()` and `Internet::simpleCurl()`.
- Fixed crash on use of case-mismatched recursive command aliases.
- Basic build instructions are now provided in `BUILDING.md`.
- `build/server-phar.php` now uses GZIP compression on created phars, providing a 75% size reduction.
- `ClientboundMapItemDataPacket` now uses `MapDecoration` objects for decorations instead of associative arrays.
- Updated Composer dependencies to get bug fixes in `pocketmine/nbt` and other libraries.
- Packages `pocketmine/classloader` and `pocketmine/log` are now required; these provide classes previously part of `pocketmine/spl`. This change has no effect on API compatibility.
# 3.11.6
- Core code, tests and build scripts are now analyzed using `phpstan-strict-rules` and `phpstan-phpunit` rules.
- Added more PHPStan-specific type annotations to improve static analysis.
- Fixed more incorrect PHPDoc types.
- Added a workaround for player movement not working since 1.14.30.
- Fixed lava and water buckets being edible since 1.13.
- `AutoUpdater` is now created before any plugins are loaded.
- Fixed trees not generating below y=2 in custom generators.
- Fixed crash when opening a chest improperly unpaired from its pair (destroyed, setBlock(), unloaded, etc.).
- `ThreadManager` is now lazily initialized.
- Removed raw NBT storage from `Item` internals. The following methods are now deprecated:
- `Item::setCompoundTag()`
# 3.11.7
- Build system: Fixed crash reports of Jenkins builds being rejected by the crash archive as invalid.
- Introduced a new dependency on `pocketmine/log-pthreads`, which contains classes separated from `pocketmine/log`.
- Fixed minimum composer stability preventing any newer version of `pocketmine/pocketmine-mp` being installed than 3.3.4 by replacing `daverandom/callback-validator` with [`pocketmine/callback-validator`](https://github.com/pmmp/CallbackValidator).
- Fixed every player seeing eating particles when any player eats.
- Fixed setting held item not working during `BlockBreakEvent`, `PlayerInteractEvent` and `EntityDamageEvent`.
- Fixed some incorrect documented types in `PlayerQuitEvent` reported by PHPStan.
- Fixed documentation of `Item->pop()` return value.
- Fixed server crash on encountering corrupted compressed data stored in region files.
- Protocol: Split screen header is now properly accounted for during decoding. Note that split screen is still not supported natively, but their packets can be decoded properly now.
- Protocol: Fixed wrong order of fields in `UpdateTradePacket`.
- Protocol: Fixed loss of `fullSkinId` when decoding network skins.
- Fixed RCON not being able to bind to port after a fast server restart.

18
changelogs/3.12.md Normal file
View File

@ -0,0 +1,18 @@
**For Minecraft: Bedrock Edition 1.14.60**
### Note about API versions
Plugins which don't touch the protocol and compatible with any previous 3.x.y version will also run on these releases and do not need API bumps.
Plugin developers should **only** update their required API to this version if you need the changes in this build.
**WARNING: If your plugin uses the protocol, you're not shielded by API change constraints.** You should consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you do.
# 3.12.0
- Added support for Minecraft: Bedrock Edition 1.14.60
- Removed compatibility with 1.14.0-1.14.30
# 3.12.1
- Fixed parsing of single-line doc comments for event handlers, e.g. `/** @ignoreCancelled */` should now work correctly.
- The server will no longer crash on failure to load `level.dat` contents, but will gracefully shutdown instead without producing a crashdump.
- Fixed some bugs in login verification that could cause undefined behaviour.
- Fixed item-use behaviour when sneaking - sneaking and clicking a block with an empty hand, and sneaking and using an item, both now follow vanilla behaviour.
- `start.sh` will now work on platforms where `/bin/bash` is not available, as long as `/usr/bin/env` knows where bash is.

View File

@ -24,14 +24,23 @@
"ext-yaml": ">=2.0.0", "ext-yaml": ">=2.0.0",
"ext-zip": "*", "ext-zip": "*",
"ext-zlib": ">=1.2.11", "ext-zlib": ">=1.2.11",
"pocketmine/raklib": "^0.12.5", "pocketmine/raklib": "^0.12.7",
"pocketmine/spl": "^0.3.5", "pocketmine/spl": "^0.4.0",
"pocketmine/binaryutils": "^0.1.9", "pocketmine/binaryutils": "^0.1.9",
"pocketmine/nbt": "^0.2.10", "pocketmine/nbt": "^0.2.10",
"pocketmine/math": "^0.2.0", "pocketmine/math": "^0.2.0",
"pocketmine/snooze": "^0.1.0", "pocketmine/snooze": "^0.1.0",
"daverandom/callback-validator": "dev-master", "pocketmine/classloader": "^0.1.0",
"adhocore/json-comment": "^0.0.7" "pocketmine/log": "^0.2.0",
"pocketmine/log-pthreads": "^0.1.0",
"pocketmine/callback-validator": "^1.0.1",
"adhocore/json-comment": "^0.1.0"
},
"require-dev": {
"phpstan/phpstan": "^0.12.25",
"irstea/phpunit-shim": "^8.5",
"phpstan/phpstan-phpunit": "^0.12.6",
"phpstan/phpstan-strict-rules": "^0.12.2"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {
@ -47,31 +56,5 @@
"psr-4": { "psr-4": {
"pocketmine\\": "tests/phpunit/" "pocketmine\\": "tests/phpunit/"
} }
}, }
"repositories": [
{
"type": "vcs",
"url": "https://github.com/pmmp/RakLib"
},
{
"type": "vcs",
"url": "https://github.com/pmmp/SPL"
},
{
"type": "vcs",
"url": "https://github.com/pmmp/BinaryUtils"
},
{
"type": "vcs",
"url": "https://github.com/pmmp/NBT"
},
{
"type": "vcs",
"url": "https://github.com/pmmp/Math"
},
{
"type": "vcs",
"url": "https://github.com/pmmp/Snooze"
}
]
} }

523
composer.lock generated
View File

@ -4,27 +4,27 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "f693f278b3bb9c1d266079fa17644dcb", "content-hash": "f9441d6ef46bddf299b260c672bfa54b",
"packages": [ "packages": [
{ {
"name": "adhocore/json-comment", "name": "adhocore/json-comment",
"version": "v0.0.7", "version": "0.1.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/adhocore/php-json-comment.git", "url": "https://github.com/adhocore/php-json-comment.git",
"reference": "135356c7e7336ef59924f1d921c770045f937a76" "reference": "8448076039389f558f39ad0553aab87db3f81614"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/adhocore/php-json-comment/zipball/135356c7e7336ef59924f1d921c770045f937a76", "url": "https://api.github.com/repos/adhocore/php-json-comment/zipball/8448076039389f558f39ad0553aab87db3f81614",
"reference": "135356c7e7336ef59924f1d921c770045f937a76", "reference": "8448076039389f558f39ad0553aab87db3f81614",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=5.4" "php": ">=5.4"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^4.8 || ^5.7 || ^6.5" "phpunit/phpunit": "^6.5 || ^7.5"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
@ -48,28 +48,65 @@
"json", "json",
"strip-comment" "strip-comment"
], ],
"time": "2018-08-01T12:27:26+00:00" "time": "2020-01-03T13:51:23+00:00"
}, },
{ {
"name": "daverandom/callback-validator", "name": "pocketmine/binaryutils",
"version": "dev-master", "version": "0.1.11",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/DaveRandom/CallbackValidator.git", "url": "https://github.com/pmmp/BinaryUtils.git",
"reference": "d87a08cddbc6099816ed01e50ce25cdfc43b542f" "reference": "e8cb65db1b7998eebb739b124f2a989fe87366eb"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/DaveRandom/CallbackValidator/zipball/d87a08cddbc6099816ed01e50ce25cdfc43b542f", "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/e8cb65db1b7998eebb739b124f2a989fe87366eb",
"reference": "d87a08cddbc6099816ed01e50ce25cdfc43b542f", "reference": "e8cb65db1b7998eebb739b124f2a989fe87366eb",
"shasum": ""
},
"require": {
"php": ">=7.2",
"php-64bit": "*"
},
"require-dev": {
"phpstan/phpstan": "^0.12.8"
},
"type": "library",
"autoload": {
"psr-4": {
"pocketmine\\utils\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-3.0"
],
"description": "Classes and methods for conveniently handling binary data",
"time": "2020-01-28T12:09:56+00:00"
},
{
"name": "pocketmine/callback-validator",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/pmmp/CallbackValidator.git",
"reference": "4aef6bb25f97d0b830ba0b4f66834b1a9c86fc9a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/CallbackValidator/zipball/4aef6bb25f97d0b830ba0b4f66834b1a9c86fc9a",
"reference": "4aef6bb25f97d0b830ba0b4f66834b1a9c86fc9a",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"ext-reflection": "*", "ext-reflection": "*",
"php": ">=7.0" "php": ">=7.1"
},
"replace": {
"daverandom/callback-validator": "*"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^6.0" "phpunit/phpunit": "^7.5 || ^8.5 || ^9.0"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
@ -87,89 +124,168 @@
"email": "cw@daverandom.com" "email": "cw@daverandom.com"
} }
], ],
"description": "Tools for validating callback signatures", "description": "Fork of daverandom/callback-validator - Tools for validating callback signatures",
"time": "2017-04-03T15:22:41+00:00" "time": "2020-03-17T12:04:22+00:00"
}, },
{ {
"name": "pocketmine/binaryutils", "name": "pocketmine/classloader",
"version": "0.1.10", "version": "0.1.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/pmmp/BinaryUtils.git", "url": "https://github.com/pmmp/ClassLoader.git",
"reference": "435f2ee265bce75ef1aa9563f9b60ff36d705e80" "reference": "4ccdb30e48f030bfcad04bb0a208d198ec631993"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/435f2ee265bce75ef1aa9563f9b60ff36d705e80", "url": "https://api.github.com/repos/pmmp/ClassLoader/zipball/4ccdb30e48f030bfcad04bb0a208d198ec631993",
"reference": "435f2ee265bce75ef1aa9563f9b60ff36d705e80", "reference": "4ccdb30e48f030bfcad04bb0a208d198ec631993",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=7.2", "ext-pthreads": "~3.2.0",
"php-64bit": "*" "ext-reflection": "*",
"php": ">=7.2.0"
},
"conflict": {
"pocketmine/spl": "<0.4"
},
"require-dev": {
"phpstan/phpstan": "^0.12.8"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
"psr-4": { "classmap": [
"pocketmine\\utils\\": "src/" "./src"
} ]
}, },
"notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"LGPL-3.0" "LGPL-3.0"
], ],
"description": "Classes and methods for conveniently handling binary data", "description": "Ad-hoc autoloading components used by PocketMine-MP",
"support": { "time": "2020-01-31T14:25:52+00:00"
"source": "https://github.com/pmmp/BinaryUtils/tree/0.1.10",
"issues": "https://github.com/pmmp/BinaryUtils/issues"
},
"time": "2019-10-21T14:40:32+00:00"
}, },
{ {
"name": "pocketmine/math", "name": "pocketmine/log",
"version": "0.2.3", "version": "0.2.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/pmmp/Math.git", "url": "https://github.com/pmmp/Log.git",
"reference": "68be8a79fd0169043ef514797c304517cb8a6071" "reference": "e59bedb5d4bbeb9a26647cb7c367cb2fa72addfa"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/pmmp/Math/zipball/68be8a79fd0169043ef514797c304517cb8a6071", "url": "https://api.github.com/repos/pmmp/Log/zipball/e59bedb5d4bbeb9a26647cb7c367cb2fa72addfa",
"reference": "68be8a79fd0169043ef514797c304517cb8a6071", "reference": "e59bedb5d4bbeb9a26647cb7c367cb2fa72addfa",
"shasum": ""
},
"require": {
"php": ">=7.2"
},
"conflict": {
"pocketmine/spl": "<0.4"
},
"require-dev": {
"phpstan/phpstan": "^0.12.8",
"phpstan/phpstan-strict-rules": "^0.12.2"
},
"type": "library",
"autoload": {
"classmap": [
"./src"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-3.0"
],
"description": "Logging components used by PocketMine-MP and related projects",
"time": "2020-03-31T15:43:47+00:00"
},
{
"name": "pocketmine/log-pthreads",
"version": "0.1.0",
"source": {
"type": "git",
"url": "https://github.com/pmmp/LogPthreads.git",
"reference": "9bbcef398b01487ab47c234a6a7054722abbe067"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/LogPthreads/zipball/9bbcef398b01487ab47c234a6a7054722abbe067",
"reference": "9bbcef398b01487ab47c234a6a7054722abbe067",
"shasum": ""
},
"require": {
"ext-pthreads": "~3.2.0",
"php": ">=7.2",
"pocketmine/log": "^0.2.0"
},
"conflict": {
"pocketmine/spl": "<0.4"
},
"require-dev": {
"phpstan/phpstan": "^0.12.18"
},
"type": "library",
"autoload": {
"classmap": [
"./src"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-3.0"
],
"description": "Logging components specialized for pthreads used by PocketMine-MP and related projects",
"time": "2020-03-31T16:17:19+00:00"
},
{
"name": "pocketmine/math",
"version": "0.2.4",
"source": {
"type": "git",
"url": "https://github.com/pmmp/Math.git",
"reference": "b1c28b236df8b795d7b06cf8421f9962b12ac410"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/Math/zipball/b1c28b236df8b795d7b06cf8421f9962b12ac410",
"reference": "b1c28b236df8b795d7b06cf8421f9962b12ac410",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=7.2.0", "php": ">=7.2.0",
"php-64bit": "*" "php-64bit": "*"
}, },
"require-dev": {
"phpstan/phpstan": "^0.12.8"
},
"type": "library", "type": "library",
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"pocketmine\\math\\": "src/" "pocketmine\\math\\": "src/"
} }
}, },
"notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"LGPL-3.0" "LGPL-3.0"
], ],
"description": "PHP library containing math related code used in PocketMine-MP", "description": "PHP library containing math related code used in PocketMine-MP",
"support": { "time": "2020-01-28T14:11:54+00:00"
"source": "https://github.com/pmmp/Math/tree/0.2.3",
"issues": "https://github.com/pmmp/Math/issues"
},
"time": "2019-10-21T14:35:10+00:00"
}, },
{ {
"name": "pocketmine/nbt", "name": "pocketmine/nbt",
"version": "0.2.12", "version": "0.2.14",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/pmmp/NBT.git", "url": "https://github.com/pmmp/NBT.git",
"reference": "b5777265329753b74dd40bb105eedabeefb98724" "reference": "b31dca98443328c4bab76dc1b84c1473c79be20e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/pmmp/NBT/zipball/b5777265329753b74dd40bb105eedabeefb98724", "url": "https://api.github.com/repos/pmmp/NBT/zipball/b31dca98443328c4bab76dc1b84c1473c79be20e",
"reference": "b5777265329753b74dd40bb105eedabeefb98724", "reference": "b31dca98443328c4bab76dc1b84c1473c79be20e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -178,51 +294,51 @@
"php-64bit": "*", "php-64bit": "*",
"pocketmine/binaryutils": "^0.1.9" "pocketmine/binaryutils": "^0.1.9"
}, },
"require-dev": {
"irstea/phpunit-shim": "^7.5 || ^8.0",
"phpstan/phpstan": "^0.12.11"
},
"type": "library", "type": "library",
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"pocketmine\\nbt\\": "src/" "pocketmine\\nbt\\": "src/"
} }
}, },
"autoload-dev": { "notification-url": "https://packagist.org/downloads/",
"psr-4": {
"pocketmine\\nbt\\": "tests/phpunit/"
}
},
"license": [ "license": [
"LGPL-3.0" "LGPL-3.0"
], ],
"description": "PHP library for working with Named Binary Tags", "description": "PHP library for working with Named Binary Tags",
"support": { "time": "2020-04-15T11:29:25+00:00"
"source": "https://github.com/pmmp/NBT/tree/0.2",
"issues": "https://github.com/pmmp/NBT/issues"
},
"time": "2019-12-01T08:20:26+00:00"
}, },
{ {
"name": "pocketmine/raklib", "name": "pocketmine/raklib",
"version": "0.12.6", "version": "0.12.8",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/pmmp/RakLib.git", "url": "https://github.com/pmmp/RakLib.git",
"reference": "18450e01185e6064790bda563ac672e7141c6992" "reference": "9fea763ffc922db083e4528d4acd0b13d0ea83a4"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/pmmp/RakLib/zipball/18450e01185e6064790bda563ac672e7141c6992", "url": "https://api.github.com/repos/pmmp/RakLib/zipball/9fea763ffc922db083e4528d4acd0b13d0ea83a4",
"reference": "18450e01185e6064790bda563ac672e7141c6992", "reference": "9fea763ffc922db083e4528d4acd0b13d0ea83a4",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"ext-bcmath": "*",
"ext-pthreads": "~3.2.0", "ext-pthreads": "~3.2.0",
"ext-sockets": "*", "ext-sockets": "*",
"php": ">=7.2.0", "php": ">=7.2.0",
"php-64bit": "*", "php-64bit": "*",
"php-ipv6": "*", "php-ipv6": "*",
"pocketmine/binaryutils": "^0.1.9", "pocketmine/binaryutils": "^0.1.9",
"pocketmine/snooze": "^0.1.0", "pocketmine/log": "^0.2.0",
"pocketmine/spl": "^0.3.0" "pocketmine/log-pthreads": "^0.1.0",
"pocketmine/snooze": "^0.1.0"
},
"require-dev": {
"phpstan/phpstan": "^0.12.18",
"phpstan/phpstan-strict-rules": "^0.12.2"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
@ -230,87 +346,303 @@
"raklib\\": "src/" "raklib\\": "src/"
} }
}, },
"notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"GPL-3.0" "GPL-3.0"
], ],
"description": "A RakNet server implementation written in PHP", "description": "A RakNet server implementation written in PHP",
"support": { "time": "2020-03-31T17:28:28+00:00"
"source": "https://github.com/pmmp/RakLib/tree/0.12.6",
"issues": "https://github.com/pmmp/RakLib/issues"
},
"time": "2019-12-07T13:43:34+00:00"
}, },
{ {
"name": "pocketmine/snooze", "name": "pocketmine/snooze",
"version": "0.1.1", "version": "0.1.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/pmmp/Snooze.git", "url": "https://github.com/pmmp/Snooze.git",
"reference": "b7bd231bdb75e69300cac89ccd515fc731c38c40" "reference": "88420da3d9335dbcb3ee2decfd5e5453d057dcdf"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/pmmp/Snooze/zipball/b7bd231bdb75e69300cac89ccd515fc731c38c40", "url": "https://api.github.com/repos/pmmp/Snooze/zipball/88420da3d9335dbcb3ee2decfd5e5453d057dcdf",
"reference": "b7bd231bdb75e69300cac89ccd515fc731c38c40", "reference": "88420da3d9335dbcb3ee2decfd5e5453d057dcdf",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"ext-pthreads": ">=3.1.7dev", "ext-pthreads": ">=3.1.7dev",
"php-64bit": ">=7.2.0" "php-64bit": ">=7.2.0"
}, },
"require-dev": {
"phpstan/phpstan": "^0.12.8"
},
"type": "library", "type": "library",
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"pocketmine\\snooze\\": "src/" "pocketmine\\snooze\\": "src/"
} }
}, },
"notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"LGPL-3.0" "LGPL-3.0"
], ],
"description": "Thread notification management library for code using the pthreads extension", "description": "Thread notification management library for code using the pthreads extension",
"support": { "time": "2020-01-28T19:08:10+00:00"
"source": "https://github.com/pmmp/Snooze/tree/0.1.1",
"issues": "https://github.com/pmmp/Snooze/issues"
},
"time": "2019-01-04T15:54:45+00:00"
}, },
{ {
"name": "pocketmine/spl", "name": "pocketmine/spl",
"version": "0.3.5", "version": "0.4.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/pmmp/SPL.git", "url": "https://github.com/pmmp/SPL.git",
"reference": "88052c67d3df2cc2dc2d99ebeae3d7ede3fc64ab" "reference": "ff0579a0be41bbe65d3637607715c0f87728a838"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/pmmp/SPL/zipball/88052c67d3df2cc2dc2d99ebeae3d7ede3fc64ab", "url": "https://api.github.com/repos/pmmp/SPL/zipball/ff0579a0be41bbe65d3637607715c0f87728a838",
"reference": "88052c67d3df2cc2dc2d99ebeae3d7ede3fc64ab", "reference": "ff0579a0be41bbe65d3637607715c0f87728a838",
"shasum": "" "shasum": ""
}, },
"require": {
"php": ">=7.2"
},
"require-dev": {
"phpstan/phpstan": "^0.12.8"
},
"type": "library", "type": "library",
"autoload": { "autoload": {
"classmap": [ "classmap": [
"./" "./src"
] ]
}, },
"notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"LGPL-3.0" "LGPL-3.0"
], ],
"description": "Standard library files required by PocketMine-MP and related projects", "description": "Standard library files required by PocketMine-MP and related projects",
"support": { "time": "2020-01-31T16:18:03+00:00"
"source": "https://github.com/pmmp/SPL/tree/0.3", }
"issues": "https://github.com/pmmp/SPL/issues" ],
}, "packages-dev": [
"time": "2020-01-14T16:23:26+00:00" {
"name": "irstea/phpunit-shim",
"version": "8.5.4",
"source": {
"type": "git",
"url": "https://gitlab.irstea.fr/pole-is/tools/phpunit-shim.git",
"reference": "25b3ffe1502bfd35d5cd23dc37f2f2e70cdf0b54"
},
"require": {
"ext-dom": "*",
"ext-json": "*",
"ext-libxml": "*",
"ext-mbstring": "*",
"ext-xml": "*",
"ext-xmlwriter": "*",
"php": "^7.2"
},
"replace": {
"phpunit/phpunit": "self.version"
},
"suggest": {
"ext-soap": "*",
"ext-xdebug": "*"
},
"bin": [
"phpunit"
],
"type": "library",
"autoload": {
"exclude-from-classmap": [
"phpunit"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de",
"role": "lead"
}
],
"description": "Shim repository for phpunit/phpunit",
"homepage": "https://phpunit.de/",
"keywords": [
"phpunit",
"shim",
"testing",
"xunit"
],
"time": "2020-04-24T02:20:21+00:00"
},
{
"name": "phpstan/phpstan",
"version": "0.12.25",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan.git",
"reference": "9619551d68b2d4c0d681a8df73f3c847c798ee64"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/9619551d68b2d4c0d681a8df73f3c847c798ee64",
"reference": "9619551d68b2d4c0d681a8df73f3c847c798ee64",
"shasum": ""
},
"require": {
"php": "^7.1"
},
"conflict": {
"phpstan/phpstan-shim": "*"
},
"bin": [
"phpstan",
"phpstan.phar"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "0.12-dev"
}
},
"autoload": {
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "PHPStan - PHP Static Analysis Tool",
"funding": [
{
"url": "https://github.com/ondrejmirtes",
"type": "github"
},
{
"url": "https://www.patreon.com/phpstan",
"type": "patreon"
},
{
"url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan",
"type": "tidelift"
}
],
"time": "2020-05-10T20:36:16+00:00"
},
{
"name": "phpstan/phpstan-phpunit",
"version": "0.12.8",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan-phpunit.git",
"reference": "7232c17e2493dc598173da784477ce0afb2c4e0e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/7232c17e2493dc598173da784477ce0afb2c4e0e",
"reference": "7232c17e2493dc598173da784477ce0afb2c4e0e",
"shasum": ""
},
"require": {
"php": "~7.1",
"phpstan/phpstan": "^0.12.6"
},
"conflict": {
"phpunit/phpunit": "<7.0"
},
"require-dev": {
"consistence/coding-standard": "^3.5",
"dealerdirect/phpcodesniffer-composer-installer": "^0.4.4",
"ergebnis/composer-normalize": "^2.0.2",
"jakub-onderka/php-parallel-lint": "^1.0",
"phing/phing": "^2.16.0",
"phpstan/phpstan-strict-rules": "^0.12",
"phpunit/phpunit": "^7.0",
"satooshi/php-coveralls": "^1.0",
"slevomat/coding-standard": "^4.7.2"
},
"type": "phpstan-extension",
"extra": {
"branch-alias": {
"dev-master": "0.12-dev"
},
"phpstan": {
"includes": [
"extension.neon",
"rules.neon"
]
}
},
"autoload": {
"psr-4": {
"PHPStan\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "PHPUnit extensions and rules for PHPStan",
"time": "2020-04-17T08:04:10+00:00"
},
{
"name": "phpstan/phpstan-strict-rules",
"version": "0.12.2",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan-strict-rules.git",
"reference": "a670a59aff7cf96f75d21b974860ada10e25b2ee"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/a670a59aff7cf96f75d21b974860ada10e25b2ee",
"reference": "a670a59aff7cf96f75d21b974860ada10e25b2ee",
"shasum": ""
},
"require": {
"php": "~7.1",
"phpstan/phpstan": "^0.12.6"
},
"require-dev": {
"consistence/coding-standard": "^3.0.1",
"dealerdirect/phpcodesniffer-composer-installer": "^0.4.4",
"ergebnis/composer-normalize": "^2.0.2",
"jakub-onderka/php-parallel-lint": "^1.0",
"phing/phing": "^2.16.0",
"phpstan/phpstan-phpunit": "^0.12",
"phpunit/phpunit": "^7.0",
"slevomat/coding-standard": "^4.5.2"
},
"type": "phpstan-extension",
"extra": {
"branch-alias": {
"dev-master": "0.12-dev"
},
"phpstan": {
"includes": [
"rules.neon"
]
}
},
"autoload": {
"psr-4": {
"PHPStan\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Extra strict and opinionated rules for PHPStan",
"time": "2020-01-20T13:08:52+00:00"
} }
], ],
"packages-dev": [],
"aliases": [], "aliases": [],
"minimum-stability": "stable", "minimum-stability": "stable",
"stability-flags": { "stability-flags": [],
"daverandom/callback-validator": 20
},
"prefer-stable": false, "prefer-stable": false,
"prefer-lowest": false, "prefer-lowest": false,
"platform": { "platform": {
@ -334,5 +666,6 @@
"ext-zip": "*", "ext-zip": "*",
"ext-zlib": ">=1.2.11" "ext-zlib": ">=1.2.11"
}, },
"platform-dev": [] "platform-dev": [],
"plugin-api-version": "1.1.0"
} }

View File

@ -1,118 +1,36 @@
includes: includes:
- tests/phpstan/configs/actual-problems.neon
- tests/phpstan/configs/com-dotnet-magic.neon - tests/phpstan/configs/com-dotnet-magic.neon
- tests/phpstan/configs/custom-leveldb.neon - tests/phpstan/configs/custom-leveldb.neon
- tests/phpstan/configs/gc-hacks.neon - tests/phpstan/configs/gc-hacks.neon
- tests/phpstan/configs/php-bugs.neon
- tests/phpstan/configs/phpstan-bugs.neon - tests/phpstan/configs/phpstan-bugs.neon
- tests/phpstan/configs/phpunit-wiring-tests.neon
- tests/phpstan/configs/pthreads-bugs.neon - tests/phpstan/configs/pthreads-bugs.neon
- tests/phpstan/configs/runtime-type-checks.neon - tests/phpstan/configs/runtime-type-checks.neon
- vendor/phpstan/phpstan-phpunit/extension.neon
- vendor/phpstan/phpstan-phpunit/rules.neon
- vendor/phpstan/phpstan-strict-rules/rules.neon
parameters: parameters:
level: 6 level: 6
autoload_files: autoload_files:
- tests/phpstan/bootstrap.php - tests/phpstan/bootstrap.php
- src/pocketmine/PocketMine.php - src/pocketmine/PocketMine.php
- build/make-release.php
- build/server-phar.php - build/server-phar.php
- vendor/irstea/phpunit-shim/phpunit
paths: paths:
- src - src
- build/make-release.php
- build/server-phar.php - build/server-phar.php
- tests/phpunit
dynamicConstantNames: dynamicConstantNames:
- pocketmine\IS_DEVELOPMENT_BUILD - pocketmine\IS_DEVELOPMENT_BUILD
- pocketmine\DEBUG - pocketmine\DEBUG
stubFiles:
- tests/phpstan/stubs/pthreads.stub
- tests/phpstan/stubs/chunkutils.stub
reportUnmatchedIgnoredErrors: false #no other way to silence platform-specific non-warnings reportUnmatchedIgnoredErrors: false #no other way to silence platform-specific non-warnings
checkMissingIterableValueType: false #TODO: pthreads Threaded base for too many things, fix this later staticReflectionClassNamePatterns:
ignoreErrors: - "#^COM$#"
-
message: "#^Cannot instantiate interface pocketmine\\\\level\\\\format\\\\io\\\\LevelProvider\\.$#"
count: 1
path: src/pocketmine/Server.php
-
message: "#^Call to an undefined method pocketmine\\\\command\\\\CommandSender\\:\\:teleport\\(\\)\\.$#"
count: 1
path: src/pocketmine/command/defaults/TeleportCommand.php
# comment: "not actually possible, but high cost to fix warning"
-
message: "#^Array \\(array\\<string\\>\\) does not accept pocketmine\\\\entity\\\\Entity\\.$#"
count: 2
path: src/pocketmine/entity/Entity.php
-
message: "#^Invalid array key type pocketmine\\\\entity\\\\Entity\\.$#"
count: 1
path: src/pocketmine/entity/Entity.php
-
message: "#^Method pocketmine\\\\event\\\\entity\\\\EntityDeathEvent\\:\\:getEntity\\(\\) should return pocketmine\\\\entity\\\\Living but returns pocketmine\\\\entity\\\\Entity\\.$#"
count: 1
path: src/pocketmine/event/entity/EntityDeathEvent.php
-
message: "#^Method pocketmine\\\\event\\\\entity\\\\EntityShootBowEvent\\:\\:getEntity\\(\\) should return pocketmine\\\\entity\\\\Living but returns pocketmine\\\\entity\\\\Entity\\.$#"
count: 1
path: src/pocketmine/event/entity/EntityShootBowEvent.php
-
message: "#^Property pocketmine\\\\event\\\\entity\\\\EntityShootBowEvent\\:\\:\\$projectile \\(pocketmine\\\\entity\\\\projectile\\\\Projectile\\) does not accept pocketmine\\\\entity\\\\Entity\\.$#"
count: 1
path: src/pocketmine/event/entity/EntityShootBowEvent.php
-
message: "#^Method pocketmine\\\\event\\\\entity\\\\ItemDespawnEvent\\:\\:getEntity\\(\\) should return pocketmine\\\\entity\\\\object\\\\ItemEntity but returns pocketmine\\\\entity\\\\Entity\\.$#"
count: 1
path: src/pocketmine/event/entity/ItemDespawnEvent.php
-
message: "#^Method pocketmine\\\\event\\\\entity\\\\ItemSpawnEvent\\:\\:getEntity\\(\\) should return pocketmine\\\\entity\\\\object\\\\ItemEntity but returns pocketmine\\\\entity\\\\Entity\\.$#"
count: 1
path: src/pocketmine/event/entity/ItemSpawnEvent.php
-
message: "#^Method pocketmine\\\\event\\\\entity\\\\ProjectileHitEvent\\:\\:getEntity\\(\\) should return pocketmine\\\\entity\\\\projectile\\\\Projectile but returns pocketmine\\\\entity\\\\Entity\\.$#"
count: 1
path: src/pocketmine/event/entity/ProjectileHitEvent.php
-
message: "#^Method pocketmine\\\\event\\\\entity\\\\ProjectileLaunchEvent\\:\\:getEntity\\(\\) should return pocketmine\\\\entity\\\\projectile\\\\Projectile but returns pocketmine\\\\entity\\\\Entity\\.$#"
count: 1
path: src/pocketmine/event/entity/ProjectileLaunchEvent.php
-
message: "#^Constructor of class pocketmine\\\\level\\\\generator\\\\hell\\\\Nether has an unused parameter \\$options\\.$#"
count: 1
path: src/pocketmine/level/generator/hell/Nether.php
-
message: "#^Constructor of class pocketmine\\\\level\\\\generator\\\\normal\\\\Normal has an unused parameter \\$options\\.$#"
count: 1
path: src/pocketmine/level/generator/normal/Normal.php
-
message: "#^Constructor of class pocketmine\\\\scheduler\\\\TaskScheduler has an unused parameter \\$logger\\.$#"
count: 1
path: src/pocketmine/scheduler/TaskScheduler.php
-
message: "#^Constant pocketmine\\\\COMPOSER_AUTOLOADER_PATH not found\\.$#"
path: src
-
message: "#^Constant pocketmine\\\\DATA not found\\.$#"
path: src
-
message: "#^Constant pocketmine\\\\GIT_COMMIT not found\\.$#"
path: src
-
message: "#^Constant pocketmine\\\\PLUGIN_PATH not found\\.$#"
path: src
-
message: "#^Constant pocketmine\\\\START_TIME not found\\.$#"
path: src
-
message: "#^Constant pocketmine\\\\VERSION not found\\.$#"
path: src

View File

@ -30,9 +30,7 @@ use pocketmine\utils\TextFormat;
* Handles the achievement list and a bit more * Handles the achievement list and a bit more
*/ */
abstract class Achievement{ abstract class Achievement{
/** /** @var array[] */
* @var array[]
*/
public static $list = [ public static $list = [
/*"openInventory" => array( /*"openInventory" => array(
"name" => "Taking Inventory", "name" => "Taking Inventory",
@ -106,13 +104,6 @@ abstract class Achievement{
]; ];
/**
* @param Player $player
* @param string $achievementId
*
* @return bool
*/
public static function broadcast(Player $player, string $achievementId) : bool{ public static function broadcast(Player $player, string $achievementId) : bool{
if(isset(Achievement::$list[$achievementId])){ if(isset(Achievement::$list[$achievementId])){
$translation = new TranslationContainer("chat.type.achievement", [$player->getDisplayName(), TextFormat::GREEN . Achievement::$list[$achievementId]["name"] . TextFormat::RESET]); $translation = new TranslationContainer("chat.type.achievement", [$player->getDisplayName(), TextFormat::GREEN . Achievement::$list[$achievementId]["name"] . TextFormat::RESET]);
@ -129,11 +120,7 @@ abstract class Achievement{
} }
/** /**
* @param string $achievementId * @param string[] $requires
* @param string $achievementName
* @param array $requires
*
* @return bool
*/ */
public static function add(string $achievementId, string $achievementName, array $requires = []) : bool{ public static function add(string $achievementId, string $achievementName, array $requires = []) : bool{
if(!isset(Achievement::$list[$achievementId])){ if(!isset(Achievement::$list[$achievementId])){

View File

@ -23,6 +23,10 @@ declare(strict_types=1);
namespace pocketmine; namespace pocketmine;
use function define;
use function defined;
use function dirname;
// composer autoload doesn't use require_once and also pthreads can inherit things // composer autoload doesn't use require_once and also pthreads can inherit things
if(defined('pocketmine\_CORE_CONSTANTS_INCLUDED')){ if(defined('pocketmine\_CORE_CONSTANTS_INCLUDED')){
return; return;
@ -30,4 +34,4 @@ if(defined('pocketmine\_CORE_CONSTANTS_INCLUDED')){
define('pocketmine\_CORE_CONSTANTS_INCLUDED', true); define('pocketmine\_CORE_CONSTANTS_INCLUDED', true);
define('pocketmine\PATH', dirname(__DIR__, 2) . '/'); define('pocketmine\PATH', dirname(__DIR__, 2) . '/');
define('pocketmine\RESOURCE_PATH', __DIR__ . '/resources/'); define('pocketmine\RESOURCE_PATH', __DIR__ . '/resources/');

View File

@ -100,7 +100,10 @@ class CrashDump{
private $fp; private $fp;
/** @var int */ /** @var int */
private $time; private $time;
/** @var mixed[] */ /**
* @var mixed[]
* @phpstan-var array<string, mixed>
*/
private $data = []; private $data = [];
/** @var string */ /** @var string */
private $encodedData = ""; private $encodedData = "";
@ -144,6 +147,10 @@ class CrashDump{
return $this->encodedData; return $this->encodedData;
} }
/**
* @return mixed[]
* @phpstan-return array<string, mixed>
*/
public function getData() : array{ public function getData() : array{
return $this->data; return $this->data;
} }

View File

@ -19,6 +19,8 @@
* *
*/ */
declare(strict_types=1);
// composer autoload doesn't use require_once and also pthreads can inherit things // composer autoload doesn't use require_once and also pthreads can inherit things
if(defined('pocketmine\_GLOBAL_CONSTANTS_INCLUDED')){ if(defined('pocketmine\_GLOBAL_CONSTANTS_INCLUDED')){
return; return;

View File

@ -27,36 +27,20 @@ use pocketmine\permission\ServerOperator;
interface IPlayer extends ServerOperator{ interface IPlayer extends ServerOperator{
/**
* @return bool
*/
public function isOnline() : bool; public function isOnline() : bool;
/**
* @return string
*/
public function getName() : string; public function getName() : string;
/**
* @return bool
*/
public function isBanned() : bool; public function isBanned() : bool;
/** /**
* @param bool $banned
*
* @return void * @return void
*/ */
public function setBanned(bool $banned); public function setBanned(bool $banned);
/**
* @return bool
*/
public function isWhitelisted() : bool; public function isWhitelisted() : bool;
/** /**
* @param bool $value
*
* @return void * @return void
*/ */
public function setWhitelisted(bool $value); public function setWhitelisted(bool $value);
@ -76,9 +60,6 @@ interface IPlayer extends ServerOperator{
*/ */
public function getLastPlayed(); public function getLastPlayed();
/**
* @return bool
*/
public function hasPlayedBefore() : bool; public function hasPlayedBefore() : bool;
} }

View File

@ -169,39 +169,24 @@ class MemoryManager{
gc_enable(); gc_enable();
} }
/**
* @return bool
*/
public function isLowMemory() : bool{ public function isLowMemory() : bool{
return $this->lowMemory; return $this->lowMemory;
} }
/**
* @return bool
*/
public function canUseChunkCache() : bool{ public function canUseChunkCache() : bool{
return !$this->lowMemory or !$this->lowMemDisableChunkCache; return !$this->lowMemory or !$this->lowMemDisableChunkCache;
} }
/** /**
* Returns the allowed chunk radius based on the current memory usage. * Returns the allowed chunk radius based on the current memory usage.
*
* @param int $distance
*
* @return int
*/ */
public function getViewDistance(int $distance) : int{ public function getViewDistance(int $distance) : int{
return ($this->lowMemory and $this->lowMemChunkRadiusOverride > 0) ? (int) min($this->lowMemChunkRadiusOverride, $distance) : $distance; return ($this->lowMemory and $this->lowMemChunkRadiusOverride > 0) ? min($this->lowMemChunkRadiusOverride, $distance) : $distance;
} }
/** /**
* Triggers garbage collection and cache cleanup to try and free memory. * Triggers garbage collection and cache cleanup to try and free memory.
* *
* @param int $memory
* @param int $limit
* @param bool $global
* @param int $triggerCount
*
* @return void * @return void
*/ */
public function trigger(int $memory, int $limit, bool $global = false, int $triggerCount = 0){ public function trigger(int $memory, int $limit, bool $global = false, int $triggerCount = 0){
@ -272,9 +257,6 @@ class MemoryManager{
Timings::$memoryManagerTimer->stopTiming(); Timings::$memoryManagerTimer->stopTiming();
} }
/**
* @return int
*/
public function triggerGarbageCollector() : int{ public function triggerGarbageCollector() : int{
Timings::$garbageCollectorTimer->startTiming(); Timings::$garbageCollectorTimer->startTiming();
@ -298,10 +280,6 @@ class MemoryManager{
/** /**
* Dumps the server memory into the specified output folder. * Dumps the server memory into the specified output folder.
* *
* @param string $outputFolder
* @param int $maxNesting
* @param int $maxStringSize
*
* @return void * @return void
*/ */
public function dumpServerMemory(string $outputFolder, int $maxNesting, int $maxStringSize){ public function dumpServerMemory(string $outputFolder, int $maxNesting, int $maxStringSize){
@ -320,10 +298,6 @@ class MemoryManager{
* Static memory dumper accessible from any thread. * Static memory dumper accessible from any thread.
* *
* @param mixed $startingObject * @param mixed $startingObject
* @param string $outputFolder
* @param int $maxNesting
* @param int $maxStringSize
* @param \Logger $logger
* *
* @return void * @return void
* @throws \ReflectionException * @throws \ReflectionException
@ -363,7 +337,7 @@ class MemoryManager{
} }
$staticCount++; $staticCount++;
self::continueDump($property->getValue(), $staticProperties[$className][$property->getName()], $objects, $refCounts, 0, $maxNesting, $maxStringSize); $staticProperties[$className][$property->getName()] = self::continueDump($property->getValue(), $objects, $refCounts, 0, $maxNesting, $maxStringSize);
} }
if(count($staticProperties[$className]) === 0){ if(count($staticProperties[$className]) === 0){
@ -396,14 +370,14 @@ class MemoryManager{
} }
$globalCount++; $globalCount++;
self::continueDump($value, $globalVariables[$varName], $objects, $refCounts, 0, $maxNesting, $maxStringSize); $globalVariables[$varName] = self::continueDump($value, $objects, $refCounts, 0, $maxNesting, $maxStringSize);
} }
file_put_contents($outputFolder . "/globalVariables.js", json_encode($globalVariables, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); file_put_contents($outputFolder . "/globalVariables.js", json_encode($globalVariables, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
$logger->info("[Dump] Wrote $globalCount global variables"); $logger->info("[Dump] Wrote $globalCount global variables");
} }
self::continueDump($startingObject, $data, $objects, $refCounts, 0, $maxNesting, $maxStringSize); $data = self::continueDump($startingObject, $objects, $refCounts, 0, $maxNesting, $maxStringSize);
do{ do{
$continue = false; $continue = false;
@ -451,14 +425,13 @@ class MemoryManager{
$property->setAccessible(true); $property->setAccessible(true);
} }
self::continueDump($property->getValue($object), $info["properties"][$name], $objects, $refCounts, 0, $maxNesting, $maxStringSize); $info["properties"][$name] = self::continueDump($property->getValue($object), $objects, $refCounts, 0, $maxNesting, $maxStringSize);
} }
} }
fwrite($obData, "$hash@$className: " . json_encode($info, JSON_UNESCAPED_SLASHES) . "\n"); fwrite($obData, "$hash@$className: " . json_encode($info, JSON_UNESCAPED_SLASHES) . "\n");
} }
}while($continue); }while($continue);
$logger->info("[Dump] Wrote " . count($objects) . " objects"); $logger->info("[Dump] Wrote " . count($objects) . " objects");
@ -479,17 +452,14 @@ class MemoryManager{
/** /**
* @param mixed $from * @param mixed $from
* @param mixed $data reference parameter
* @param object[] $objects reference parameter * @param object[] $objects reference parameter
* @param int[] $refCounts reference parameter * @param int[] $refCounts reference parameter
* @param int $recursion *
* @param int $maxNesting * @return mixed
* @param int $maxStringSize
*/ */
private static function continueDump($from, &$data, array &$objects, array &$refCounts, int $recursion, int $maxNesting, int $maxStringSize) : void{ private static function continueDump($from, array &$objects, array &$refCounts, int $recursion, int $maxNesting, int $maxStringSize){
if($maxNesting <= 0){ if($maxNesting <= 0){
$data = "(error) NESTING LIMIT REACHED"; return "(error) NESTING LIMIT REACHED";
return;
} }
--$maxNesting; --$maxNesting;
@ -505,12 +475,11 @@ class MemoryManager{
$data = "(object) $hash@" . get_class($from); $data = "(object) $hash@" . get_class($from);
}elseif(is_array($from)){ }elseif(is_array($from)){
if($recursion >= 5){ if($recursion >= 5){
$data = "(error) ARRAY RECURSION LIMIT REACHED"; return "(error) ARRAY RECURSION LIMIT REACHED";
return;
} }
$data = []; $data = [];
foreach($from as $key => $value){ foreach($from as $key => $value){
self::continueDump($value, $data[$key], $objects, $refCounts, $recursion + 1, $maxNesting, $maxStringSize); $data[$key] = self::continueDump($value, $objects, $refCounts, $recursion + 1, $maxNesting, $maxStringSize);
} }
}elseif(is_string($from)){ }elseif(is_string($from)){
$data = "(string) len(" . strlen($from) . ") " . substr(Utils::printable($from), 0, $maxStringSize); $data = "(string) len(" . strlen($from) . ") " . substr(Utils::printable($from), 0, $maxStringSize);
@ -519,5 +488,7 @@ class MemoryManager{
}else{ }else{
$data = $from; $data = $from;
} }
return $data;
} }
} }

View File

@ -37,10 +37,6 @@ class OfflinePlayer implements IPlayer, Metadatable{
/** @var CompoundTag|null */ /** @var CompoundTag|null */
private $namedtag = null; private $namedtag = null;
/**
* @param Server $server
* @param string $name
*/
public function __construct(Server $server, string $name){ public function __construct(Server $server, string $name){
$this->server = $server; $this->server = $server;
$this->name = $name; $this->name = $name;

View File

@ -81,6 +81,7 @@ use pocketmine\item\Durable;
use pocketmine\item\enchantment\EnchantmentInstance; use pocketmine\item\enchantment\EnchantmentInstance;
use pocketmine\item\enchantment\MeleeWeaponEnchantment; use pocketmine\item\enchantment\MeleeWeaponEnchantment;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\item\MaybeConsumable;
use pocketmine\item\WritableBook; use pocketmine\item\WritableBook;
use pocketmine\item\WrittenBook; use pocketmine\item\WrittenBook;
use pocketmine\lang\TextContainer; use pocketmine\lang\TextContainer;
@ -145,6 +146,8 @@ use pocketmine\network\mcpe\protocol\types\CommandEnum;
use pocketmine\network\mcpe\protocol\types\CommandParameter; use pocketmine\network\mcpe\protocol\types\CommandParameter;
use pocketmine\network\mcpe\protocol\types\ContainerIds; use pocketmine\network\mcpe\protocol\types\ContainerIds;
use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\network\mcpe\protocol\types\DimensionIds;
use pocketmine\network\mcpe\protocol\types\PersonaPieceTintColor;
use pocketmine\network\mcpe\protocol\types\PersonaSkinPiece;
use pocketmine\network\mcpe\protocol\types\PlayerPermissions; use pocketmine\network\mcpe\protocol\types\PlayerPermissions;
use pocketmine\network\mcpe\protocol\types\SkinAdapterSingleton; use pocketmine\network\mcpe\protocol\types\SkinAdapterSingleton;
use pocketmine\network\mcpe\protocol\types\SkinAnimation; use pocketmine\network\mcpe\protocol\types\SkinAnimation;
@ -202,7 +205,6 @@ use const M_PI;
use const M_SQRT3; use const M_SQRT3;
use const PHP_INT_MAX; use const PHP_INT_MAX;
/** /**
* Main class that handles networking, recovery, and packet sending to the server part * Main class that handles networking, recovery, and packet sending to the server part
*/ */
@ -216,10 +218,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** /**
* Validates the given username. * Validates the given username.
*
* @param string $name
*
* @return bool
*/ */
public static function isValidUserName(?string $name) : bool{ public static function isValidUserName(?string $name) : bool{
if($name === null){ if($name === null){
@ -231,7 +229,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return $lname !== "rcon" and $lname !== "console" and $len >= 1 and $len <= 16 and preg_match("/[^A-Za-z0-9_ ]/", $name) === 0; return $lname !== "rcon" and $lname !== "console" and $len >= 1 and $len <= 16 and preg_match("/[^A-Za-z0-9_ ]/", $name) === 0;
} }
/** @var SourceInterface */ /** @var SourceInterface */
protected $interface; protected $interface;
@ -258,13 +255,14 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
*/ */
protected $lastPingMeasure = 1; protected $lastPingMeasure = 1;
/** @var float */ /** @var float */
public $creationTime = 0; public $creationTime = 0;
/** @var bool */ /** @var bool */
public $loggedIn = false; public $loggedIn = false;
/** @var bool */
private $seenLoginPacket = false;
/** @var bool */ /** @var bool */
private $resourcePacksDone = false; private $resourcePacksDone = false;
@ -293,7 +291,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** @var PlayerCursorInventory */ /** @var PlayerCursorInventory */
protected $cursorInventory; protected $cursorInventory;
/** @var CraftingGrid */ /** @var CraftingGrid */
protected $craftingGrid = null; protected $craftingGrid;
/** @var CraftingTransaction|null */ /** @var CraftingTransaction|null */
protected $craftingTransaction = null; protected $craftingTransaction = null;
@ -355,7 +353,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
protected $flying = false; protected $flying = false;
/** @var PermissibleBase */ /** @var PermissibleBase */
private $perm = null; private $perm;
/** @var int|null */ /** @var int|null */
protected $lineHeight = null; protected $lineHeight = null;
@ -432,8 +430,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** /**
* If the player is logged into Xbox Live, returns their Xbox user ID (XUID) as a string. Returns an empty string if * If the player is logged into Xbox Live, returns their Xbox user ID (XUID) as a string. Returns an empty string if
* the player is not logged into Xbox Live. * the player is not logged into Xbox Live.
*
* @return string
*/ */
public function getXuid() : string{ public function getXuid() : string{
return $this->xuid; return $this->xuid;
@ -453,8 +449,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
* (In the olden days this method used to return a fake UUID computed by the server, which was used by plugins such * (In the olden days this method used to return a fake UUID computed by the server, which was used by plugins such
* as SimpleAuth for authentication. This is NOT SAFE anymore as this UUID is now what was given by the client, NOT * as SimpleAuth for authentication. This is NOT SAFE anymore as this UUID is now what was given by the client, NOT
* a server-computed UUID.) * a server-computed UUID.)
*
* @return UUID|null
*/ */
public function getUniqueId() : ?UUID{ public function getUniqueId() : ?UUID{
return parent::getUniqueId(); return parent::getUniqueId();
@ -477,8 +471,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
/** /**
* @param bool $value
*
* @return void * @return void
*/ */
public function setAllowFlight(bool $value){ public function setAllowFlight(bool $value){
@ -491,8 +483,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
/** /**
* @param bool $value
*
* @return void * @return void
*/ */
public function setFlying(bool $value){ public function setFlying(bool $value){
@ -508,8 +498,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
/** /**
* @param bool $value
*
* @return void * @return void
*/ */
public function setAutoJump(bool $value){ public function setAutoJump(bool $value){
@ -526,17 +514,12 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
/** /**
* @param bool $value
*
* @return void * @return void
*/ */
public function setAllowMovementCheats(bool $value = true){ public function setAllowMovementCheats(bool $value = true){
$this->allowMovementCheats = $value; $this->allowMovementCheats = $value;
} }
/**
* @param Player $player
*/
public function spawnTo(Player $player) : void{ public function spawnTo(Player $player) : void{
if($this->spawned and $player->spawned and $this->isAlive() and $player->isAlive() and $player->getLevel() === $this->level and $player->canSee($this) and !$this->isSpectator()){ if($this->spawned and $player->spawned and $this->isAlive() and $player->isAlive() and $player->getLevel() === $this->level and $player->canSee($this) and !$this->isSpectator()){
parent::spawnTo($player); parent::spawnTo($player);
@ -550,16 +533,11 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return $this->server; return $this->server;
} }
/**
* @return bool
*/
public function getRemoveFormat() : bool{ public function getRemoveFormat() : bool{
return $this->removeFormat; return $this->removeFormat;
} }
/** /**
* @param bool $remove
*
* @return void * @return void
*/ */
public function setRemoveFormat(bool $remove = true){ public function setRemoveFormat(bool $remove = true){
@ -577,18 +555,11 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$this->lineHeight = $height; $this->lineHeight = $height;
} }
/**
* @param Player $player
*
* @return bool
*/
public function canSee(Player $player) : bool{ public function canSee(Player $player) : bool{
return !isset($this->hiddenPlayers[$player->getRawUniqueId()]); return !isset($this->hiddenPlayers[$player->getRawUniqueId()]);
} }
/** /**
* @param Player $player
*
* @return void * @return void
*/ */
public function hidePlayer(Player $player){ public function hidePlayer(Player $player){
@ -600,8 +571,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
/** /**
* @param Player $player
*
* @return void * @return void
*/ */
public function showPlayer(Player $player){ public function showPlayer(Player $player){
@ -632,8 +601,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
/** /**
* @param int $distance
*
* @return void * @return void
*/ */
public function setViewDistance(int $distance){ public function setViewDistance(int $distance){
@ -650,23 +617,15 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$this->server->getLogger()->debug("Setting view distance for " . $this->getName() . " to " . $this->viewDistance . " (requested " . $distance . ")"); $this->server->getLogger()->debug("Setting view distance for " . $this->getName() . " to " . $this->viewDistance . " (requested " . $distance . ")");
} }
/**
* @return bool
*/
public function isOnline() : bool{ public function isOnline() : bool{
return $this->isConnected() and $this->loggedIn; return $this->isConnected() and $this->loggedIn;
} }
/**
* @return bool
*/
public function isOp() : bool{ public function isOp() : bool{
return $this->server->isOp($this->getName()); return $this->server->isOp($this->getName());
} }
/** /**
* @param bool $value
*
* @return void * @return void
*/ */
public function setOp(bool $value){ public function setOp(bool $value){
@ -685,8 +644,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** /**
* @param permission\Permission|string $name * @param permission\Permission|string $name
*
* @return bool
*/ */
public function isPermissionSet($name) : bool{ public function isPermissionSet($name) : bool{
return $this->perm->isPermissionSet($name); return $this->perm->isPermissionSet($name);
@ -695,8 +652,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** /**
* @param permission\Permission|string $name * @param permission\Permission|string $name
* *
* @return bool
*
* @throws \InvalidStateException if the player is closed * @throws \InvalidStateException if the player is closed
*/ */
public function hasPermission($name) : bool{ public function hasPermission($name) : bool{
@ -706,20 +661,11 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return $this->perm->hasPermission($name); return $this->perm->hasPermission($name);
} }
/**
* @param Plugin $plugin
* @param string $name
* @param bool $value
*
* @return PermissionAttachment
*/
public function addAttachment(Plugin $plugin, string $name = null, bool $value = null) : PermissionAttachment{ public function addAttachment(Plugin $plugin, string $name = null, bool $value = null) : PermissionAttachment{
return $this->perm->addAttachment($plugin, $name, $value); return $this->perm->addAttachment($plugin, $name, $value);
} }
/** /**
* @param PermissionAttachment $attachment
*
* @return void * @return void
*/ */
public function removeAttachment(PermissionAttachment $attachment){ public function removeAttachment(PermissionAttachment $attachment){
@ -797,11 +743,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
/**
* @param SourceInterface $interface
* @param string $ip
* @param int $port
*/
public function __construct(SourceInterface $interface, string $ip, int $port){ public function __construct(SourceInterface $interface, string $ip, int $port){
$this->interface = $interface; $this->interface = $interface;
$this->perm = new PermissibleBase($this); $this->perm = new PermissibleBase($this);
@ -823,40 +764,29 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$this->sessionAdapter = new PlayerNetworkSessionAdapter($this->server, $this); $this->sessionAdapter = new PlayerNetworkSessionAdapter($this->server, $this);
} }
/**
* @return bool
*/
public function isConnected() : bool{ public function isConnected() : bool{
return $this->sessionAdapter !== null; return $this->sessionAdapter !== null;
} }
/** /**
* Gets the username * Gets the username
* @return string
*/ */
public function getName() : string{ public function getName() : string{
return $this->username; return $this->username;
} }
/**
* @return string
*/
public function getLowerCaseName() : string{ public function getLowerCaseName() : string{
return $this->iusername; return $this->iusername;
} }
/** /**
* Returns the "friendly" display name of this player to use in the chat. * Returns the "friendly" display name of this player to use in the chat.
*
* @return string
*/ */
public function getDisplayName() : string{ public function getDisplayName() : string{
return $this->displayName; return $this->displayName;
} }
/** /**
* @param string $name
*
* @return void * @return void
*/ */
public function setDisplayName(string $name){ public function setDisplayName(string $name){
@ -868,7 +798,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** /**
* Returns the player's locale, e.g. en_US. * Returns the player's locale, e.g. en_US.
* @return string
*/ */
public function getLocale() : string{ public function getLocale() : string{
return $this->locale; return $this->locale;
@ -877,12 +806,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** /**
* Called when a player changes their skin. * Called when a player changes their skin.
* Plugin developers should not use this, use setSkin() and sendSkin() instead. * Plugin developers should not use this, use setSkin() and sendSkin() instead.
*
* @param Skin $skin
* @param string $newSkinName
* @param string $oldSkinName
*
* @return bool
*/ */
public function changeSkin(Skin $skin, string $newSkinName, string $oldSkinName) : bool{ public function changeSkin(Skin $skin, string $newSkinName, string $oldSkinName) : bool{
if(!$skin->isValid()){ if(!$skin->isValid()){
@ -913,16 +836,11 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** /**
* Gets the player IP address * Gets the player IP address
*
* @return string
*/ */
public function getAddress() : string{ public function getAddress() : string{
return $this->ip; return $this->ip;
} }
/**
* @return int
*/
public function getPort() : int{ public function getPort() : int{
return $this->port; return $this->port;
} }
@ -930,8 +848,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** /**
* Returns the last measured latency for this player, in milliseconds. This is measured automatically and reported * Returns the last measured latency for this player, in milliseconds. This is measured automatically and reported
* back by the network interface. * back by the network interface.
*
* @return int
*/ */
public function getPing() : int{ public function getPing() : int{
return $this->lastPingMeasure; return $this->lastPingMeasure;
@ -942,17 +858,12 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
* *
* @internal Plugins should not use this method. * @internal Plugins should not use this method.
* *
* @param int $pingMS
*
* @return void * @return void
*/ */
public function updatePing(int $pingMS){ public function updatePing(int $pingMS){
$this->lastPingMeasure = $pingMS; $this->lastPingMeasure = $pingMS;
} }
/**
* @return Position
*/
public function getNextPosition() : Position{ public function getNextPosition() : Position{
return $this->newPosition !== null ? Position::fromObject($this->newPosition, $this->level) : $this->getPosition(); return $this->newPosition !== null ? Position::fromObject($this->newPosition, $this->level) : $this->getPosition();
} }
@ -963,15 +874,12 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** /**
* Returns whether the player is currently using an item (right-click and hold). * Returns whether the player is currently using an item (right-click and hold).
* @return bool
*/ */
public function isUsingItem() : bool{ public function isUsingItem() : bool{
return $this->getGenericFlag(self::DATA_FLAG_ACTION) and $this->startAction > -1; return $this->getGenericFlag(self::DATA_FLAG_ACTION) and $this->startAction > -1;
} }
/** /**
* @param bool $value
*
* @return void * @return void
*/ */
public function setUsingItem(bool $value){ public function setUsingItem(bool $value){
@ -982,8 +890,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** /**
* Returns how long the player has been using their currently-held item for. Used for determining arrow shoot force * Returns how long the player has been using their currently-held item for. Used for determining arrow shoot force
* for bows. * for bows.
*
* @return int
*/ */
public function getItemUseDuration() : int{ public function getItemUseDuration() : int{
return $this->startAction === -1 ? -1 : ($this->server->getTick() - $this->startAction); return $this->startAction === -1 ? -1 : ($this->server->getTick() - $this->startAction);
@ -991,10 +897,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** /**
* Returns whether the player has a cooldown period left before it can use the given item again. * Returns whether the player has a cooldown period left before it can use the given item again.
*
* @param Item $item
*
* @return bool
*/ */
public function hasItemCooldown(Item $item) : bool{ public function hasItemCooldown(Item $item) : bool{
$this->checkItemCooldowns(); $this->checkItemCooldowns();
@ -1003,8 +905,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** /**
* Resets the player's cooldown time for the given item back to the maximum. * Resets the player's cooldown time for the given item back to the maximum.
*
* @param Item $item
*/ */
public function resetItemCooldown(Item $item) : void{ public function resetItemCooldown(Item $item) : void{
$ticks = $item->getCooldownTicks(); $ticks = $item->getCooldownTicks();
@ -1044,10 +944,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
/** /**
* @param int $x
* @param int $z
* @param Level|null $level
*
* @return void * @return void
*/ */
protected function unloadChunk(int $x, int $z, Level $level = null){ protected function unloadChunk(int $x, int $z, Level $level = null){
@ -1067,10 +963,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
/** /**
* @param int $x
* @param int $z
* @param BatchPacket $payload
*
* @return void * @return void
*/ */
public function sendChunk(int $x, int $z, BatchPacket $payload){ public function sendChunk(int $x, int $z, BatchPacket $payload){
@ -1185,9 +1077,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
/** /**
* @param Vector3 $pos
* @param int $respawnState
*
* @return void * @return void
*/ */
protected function sendRespawnPacket(Vector3 $pos, int $respawnState = RespawnPacket::SEARCHING_FOR_SPAWN){ protected function sendRespawnPacket(Vector3 $pos, int $respawnState = RespawnPacket::SEARCHING_FOR_SPAWN){
@ -1241,7 +1130,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
unset($unloadChunks[$index]); unset($unloadChunks[$index]);
/* Bottom left quadrant */ /* Bottom left quadrant */
if(!isset($this->usedChunks[$index = Level::chunkHash($centerX - $x - 1, $centerZ - $z - 1)]) or $this->usedChunks[$index] === false){ if(!isset($this->usedChunks[$index = Level::chunkHash($centerX - $x - 1, $centerZ - $z - 1)]) or $this->usedChunks[$index] === false){
$newOrder[$index] = true; $newOrder[$index] = true;
@ -1307,9 +1195,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
} }
/**
* @return bool
*/
public function hasValidSpawnPosition() : bool{ public function hasValidSpawnPosition() : bool{
return $this->spawnPosition !== null and $this->spawnPosition->isValid(); return $this->spawnPosition !== null and $this->spawnPosition->isValid();
} }
@ -1338,18 +1223,10 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$this->dataPacket($pk); $this->dataPacket($pk);
} }
/**
* @return bool
*/
public function isSleeping() : bool{ public function isSleeping() : bool{
return $this->sleeping !== null; return $this->sleeping !== null;
} }
/**
* @param Vector3 $pos
*
* @return bool
*/
public function sleepOn(Vector3 $pos) : bool{ public function sleepOn(Vector3 $pos) : bool{
if(!$this->isOnline()){ if(!$this->isOnline()){
return false; return false;
@ -1404,11 +1281,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
} }
/**
* @param string $achievementId
*
* @return bool
*/
public function hasAchievement(string $achievementId) : bool{ public function hasAchievement(string $achievementId) : bool{
if(!isset(Achievement::$list[$achievementId])){ if(!isset(Achievement::$list[$achievementId])){
return false; return false;
@ -1417,11 +1289,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return $this->achievements[$achievementId] ?? false; return $this->achievements[$achievementId] ?? false;
} }
/**
* @param string $achievementId
*
* @return bool
*/
public function awardAchievement(string $achievementId) : bool{ public function awardAchievement(string $achievementId) : bool{
if(isset(Achievement::$list[$achievementId]) and !$this->hasAchievement($achievementId)){ if(isset(Achievement::$list[$achievementId]) and !$this->hasAchievement($achievementId)){
foreach(Achievement::$list[$achievementId]["requires"] as $requirementId){ foreach(Achievement::$list[$achievementId]["requires"] as $requirementId){
@ -1445,8 +1312,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
/** /**
* @param string $achievementId
*
* @return void * @return void
*/ */
public function removeAchievement(string $achievementId){ public function removeAchievement(string $achievementId){
@ -1455,9 +1320,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
} }
/**
* @return int
*/
public function getGamemode() : int{ public function getGamemode() : int{
return $this->gamemode; return $this->gamemode;
} }
@ -1469,10 +1331,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
* This function takes care of handling gamemodes known to MCPE (as of 1.1.0.3, that includes Survival, Creative and Adventure) * This function takes care of handling gamemodes known to MCPE (as of 1.1.0.3, that includes Survival, Creative and Adventure)
* *
* TODO: remove this when Spectator Mode gets added properly to MCPE * TODO: remove this when Spectator Mode gets added properly to MCPE
*
* @param int $gamemode
*
* @return int
*/ */
public static function getClientFriendlyGamemode(int $gamemode) : int{ public static function getClientFriendlyGamemode(int $gamemode) : int{
$gamemode &= 0x03; $gamemode &= 0x03;
@ -1486,10 +1344,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** /**
* Sets the gamemode, and if needed, kicks the Player. * Sets the gamemode, and if needed, kicks the Player.
* *
* @param int $gm
* @param bool $client if the client made this change in their GUI * @param bool $client if the client made this change in their GUI
*
* @return bool
*/ */
public function setGamemode(int $gm, bool $client = false) : bool{ public function setGamemode(int $gm, bool $client = false) : bool{
if($gm < 0 or $gm > 3 or $this->gamemode === $gm){ if($gm < 0 or $gm > 3 or $this->gamemode === $gm){
@ -1572,8 +1427,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
* in Adventure Mode. Supply the $literal parameter as true to force a literal Survival Mode check. * in Adventure Mode. Supply the $literal parameter as true to force a literal Survival Mode check.
* *
* @param bool $literal whether a literal check should be performed * @param bool $literal whether a literal check should be performed
*
* @return bool
*/ */
public function isSurvival(bool $literal = false) : bool{ public function isSurvival(bool $literal = false) : bool{
if($literal){ if($literal){
@ -1588,8 +1441,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
* in Spectator Mode. Supply the $literal parameter as true to force a literal Creative Mode check. * in Spectator Mode. Supply the $literal parameter as true to force a literal Creative Mode check.
* *
* @param bool $literal whether a literal check should be performed * @param bool $literal whether a literal check should be performed
*
* @return bool
*/ */
public function isCreative(bool $literal = false) : bool{ public function isCreative(bool $literal = false) : bool{
if($literal){ if($literal){
@ -1604,8 +1455,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
* in Spectator Mode. Supply the $literal parameter as true to force a literal Adventure Mode check. * in Spectator Mode. Supply the $literal parameter as true to force a literal Adventure Mode check.
* *
* @param bool $literal whether a literal check should be performed * @param bool $literal whether a literal check should be performed
*
* @return bool
*/ */
public function isAdventure(bool $literal = false) : bool{ public function isAdventure(bool $literal = false) : bool{
if($literal){ if($literal){
@ -1615,9 +1464,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
} }
/**
* @return bool
*/
public function isSpectator() : bool{ public function isSpectator() : bool{
return $this->gamemode === Player::SPECTATOR; return $this->gamemode === Player::SPECTATOR;
} }
@ -1670,8 +1516,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
/** /**
* @param int $tickDiff
*
* @return void * @return void
*/ */
protected function processMovement(int $tickDiff){ protected function processMovement(int $tickDiff){
@ -1817,8 +1661,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
/** /**
* @param bool $sendAll
*
* @return void * @return void
*/ */
public function sendAttributes(bool $sendAll = false){ public function sendAttributes(bool $sendAll = false){
@ -1952,11 +1794,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** /**
* Returns whether the player can interact with the specified position. This checks distance and direction. * Returns whether the player can interact with the specified position. This checks distance and direction.
* *
* @param Vector3 $pos
* @param float $maxDistance
* @param float $maxDiff defaults to half of the 3D diagonal width of a block * @param float $maxDiff defaults to half of the 3D diagonal width of a block
*
* @return bool
*/ */
public function canInteract(Vector3 $pos, float $maxDistance, float $maxDiff = M_SQRT3 / 2) : bool{ public function canInteract(Vector3 $pos, float $maxDistance, float $maxDiff = M_SQRT3 / 2) : bool{
$eyePos = $this->getPosition()->add(0, $this->getEyeHeight(), 0); $eyePos = $this->getPosition()->add(0, $this->getEyeHeight(), 0);
@ -1980,9 +1818,10 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
public function handleLogin(LoginPacket $packet) : bool{ public function handleLogin(LoginPacket $packet) : bool{
if($this->loggedIn){ if($this->seenLoginPacket){
return false; return false;
} }
$this->seenLoginPacket = true;
if($packet->protocol !== ProtocolInfo::CURRENT_PROTOCOL){ if($packet->protocol !== ProtocolInfo::CURRENT_PROTOCOL){
if($packet->protocol < ProtocolInfo::CURRENT_PROTOCOL){ if($packet->protocol < ProtocolInfo::CURRENT_PROTOCOL){
@ -2025,18 +1864,34 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$animations[] = new SkinAnimation(new SkinImage($animation["ImageHeight"], $animation["ImageWidth"], base64_decode($animation["Image"], true)), $animation["Type"], $animation["Frames"]); $animations[] = new SkinAnimation(new SkinImage($animation["ImageHeight"], $animation["ImageWidth"], base64_decode($animation["Image"], true)), $animation["Type"], $animation["Frames"]);
} }
$personaPieces = [];
foreach($packet->clientData["PersonaPieces"] as $piece){
$personaPieces[] = new PersonaSkinPiece($piece["PieceId"], $piece["PieceType"], $piece["PackId"], $piece["IsDefault"], $piece["ProductId"]);
}
$pieceTintColors = [];
foreach($packet->clientData["PieceTintColors"] as $tintColor){
$pieceTintColors[] = new PersonaPieceTintColor($tintColor["PieceType"], $tintColor["Colors"]);
}
$skinData = new SkinData( $skinData = new SkinData(
$packet->clientData["SkinId"], $packet->clientData["SkinId"],
base64_decode($packet->clientData["SkinResourcePatch"] ?? ""), base64_decode($packet->clientData["SkinResourcePatch"] ?? "", true),
new SkinImage($packet->clientData["SkinImageHeight"], $packet->clientData["SkinImageWidth"], base64_decode($packet->clientData["SkinData"])), new SkinImage($packet->clientData["SkinImageHeight"], $packet->clientData["SkinImageWidth"], base64_decode($packet->clientData["SkinData"], true)),
$animations, $animations,
new SkinImage($packet->clientData["CapeImageHeight"], $packet->clientData["CapeImageWidth"], base64_decode($packet->clientData["CapeData"] ?? "")), new SkinImage($packet->clientData["CapeImageHeight"], $packet->clientData["CapeImageWidth"], base64_decode($packet->clientData["CapeData"] ?? "", true)),
base64_decode($packet->clientData["SkinGeometryData"] ?? ""), base64_decode($packet->clientData["SkinGeometryData"] ?? "", true),
base64_decode($packet->clientData["SkinAnimationData"] ?? ""), base64_decode($packet->clientData["SkinAnimationData"] ?? "", true),
$packet->clientData["PremiumSkin"] ?? false, $packet->clientData["PremiumSkin"] ?? false,
$packet->clientData["PersonaSkin"] ?? false, $packet->clientData["PersonaSkin"] ?? false,
$packet->clientData["CapeOnClassicSkin"] ?? false, $packet->clientData["CapeOnClassicSkin"] ?? false,
$packet->clientData["CapeId"] ?? "" $packet->clientData["CapeId"] ?? "",
null,
$packet->clientData["ArmSize"] ?? SkinData::ARM_SIZE_WIDE,
$packet->clientData["SkinColor"] ?? "",
$personaPieces,
$pieceTintColors,
true
); );
$skin = SkinAdapterSingleton::get()->fromSkinData($skinData); $skin = SkinAdapterSingleton::get()->fromSkinData($skinData);
@ -2078,9 +1933,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
/** /**
* @param int $status
* @param bool $immediate
*
* @return void * @return void
*/ */
public function sendPlayStatus(int $status, bool $immediate = false){ public function sendPlayStatus(int $status, bool $immediate = false){
@ -2342,10 +2194,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** /**
* Sends a chat message as this player. If the message begins with a / (forward-slash) it will be treated * Sends a chat message as this player. If the message begins with a / (forward-slash) it will be treated
* as a command. * as a command.
*
* @param string $message
*
* @return bool
*/ */
public function chat(string $message) : bool{ public function chat(string $message) : bool{
if(!$this->spawned or !$this->isAlive()){ if(!$this->spawned or !$this->isAlive()){
@ -2422,6 +2270,10 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
public function handleEntityEvent(ActorEventPacket $packet) : bool{ public function handleEntityEvent(ActorEventPacket $packet) : bool{
if($packet->entityRuntimeId !== $this->id){
//TODO HACK: EATING_ITEM is sent back to the server when the server sends it for other players (1.14 bug, maybe earlier)
return $packet->event === ActorEventPacket::EATING_ITEM;
}
if(!$this->spawned or !$this->isAlive()){ if(!$this->spawned or !$this->isAlive()){
return true; return true;
} }
@ -2445,10 +2297,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** /**
* Don't expect much from this handler. Most of it is roughly hacked and duct-taped together. * Don't expect much from this handler. Most of it is roughly hacked and duct-taped together.
*
* @param InventoryTransactionPacket $packet
*
* @return bool
*/ */
public function handleInventoryTransaction(InventoryTransactionPacket $packet) : bool{ public function handleInventoryTransaction(InventoryTransactionPacket $packet) : bool{
if(!$this->spawned or !$this->isAlive()){ if(!$this->spawned or !$this->isAlive()){
@ -2565,7 +2413,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$item = $this->inventory->getItemInHand(); $item = $this->inventory->getItemInHand();
$oldItem = clone $item; $oldItem = clone $item;
if($this->level->useItemOn($blockVector, $item, $face, $packet->trData->clickPos, $this, true)){ if($this->level->useItemOn($blockVector, $item, $face, $packet->trData->clickPos, $this, true)){
if(!$item->equalsExact($oldItem)){ if(!$item->equalsExact($oldItem) and $oldItem->equalsExact($this->inventory->getItemInHand())){
$this->inventory->setItemInHand($item); $this->inventory->setItemInHand($item);
$this->inventory->sendHeldItem($this->hasSpawned); $this->inventory->sendHeldItem($this->hasSpawned);
} }
@ -2597,7 +2445,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
if($this->canInteract($blockVector->add(0.5, 0.5, 0.5), $this->isCreative() ? 13 : 7) and $this->level->useBreakOn($blockVector, $item, $this, true)){ if($this->canInteract($blockVector->add(0.5, 0.5, 0.5), $this->isCreative() ? 13 : 7) and $this->level->useBreakOn($blockVector, $item, $this, true)){
if($this->isSurvival()){ if($this->isSurvival()){
if(!$item->equalsExact($oldItem)){ if(!$item->equalsExact($oldItem) and $oldItem->equalsExact($this->inventory->getItemInHand())){
$this->inventory->setItemInHand($item); $this->inventory->setItemInHand($item);
$this->inventory->sendHeldItem($this->hasSpawned); $this->inventory->sendHeldItem($this->hasSpawned);
} }
@ -2628,7 +2476,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
case InventoryTransactionPacket::USE_ITEM_ACTION_CLICK_AIR: case InventoryTransactionPacket::USE_ITEM_ACTION_CLICK_AIR:
if($this->isUsingItem()){ if($this->isUsingItem()){
$slot = $this->inventory->getItemInHand(); $slot = $this->inventory->getItemInHand();
if($slot instanceof Consumable){ if($slot instanceof Consumable and !($slot instanceof MaybeConsumable and !$slot->canBeConsumed())){
$ev = new PlayerItemConsumeEvent($this, $slot); $ev = new PlayerItemConsumeEvent($this, $slot);
if($this->hasItemCooldown($slot)){ if($this->hasItemCooldown($slot)){
$ev->setCancelled(); $ev->setCancelled();
@ -2708,6 +2556,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$cancelled = false; $cancelled = false;
$heldItem = $this->inventory->getItemInHand(); $heldItem = $this->inventory->getItemInHand();
$oldItem = clone $heldItem;
if(!$this->canInteract($target, 8)){ if(!$this->canInteract($target, 8)){
$cancelled = true; $cancelled = true;
@ -2767,7 +2616,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
if($this->isAlive()){ if($this->isAlive()){
//reactive damage like thorns might cause us to be killed by attacking another mob, which //reactive damage like thorns might cause us to be killed by attacking another mob, which
//would mean we'd already have dropped the inventory by the time we reached here //would mean we'd already have dropped the inventory by the time we reached here
if($heldItem->onAttackEntity($target) and $this->isSurvival()){ //always fire the hook, even if we are survival if($heldItem->onAttackEntity($target) and $this->isSurvival() and $oldItem->equalsExact($this->inventory->getItemInHand())){ //always fire the hook, even if we are survival
$this->inventory->setItemInHand($heldItem); $this->inventory->setItemInHand($heldItem);
} }
@ -3054,8 +2903,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** /**
* Drops an item on the ground in front of the player. Returns if the item drop was successful. * Drops an item on the ground in front of the player. Returns if the item drop was successful.
* *
* @param Item $item
*
* @return bool if the item was dropped or if the item was null * @return bool if the item was dropped or if the item was null
*/ */
public function dropItem(Item $item) : bool{ public function dropItem(Item $item) : bool{
@ -3267,8 +3114,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** /**
* Called when a packet is received from the client. This method will call DataPacketReceiveEvent. * Called when a packet is received from the client. This method will call DataPacketReceiveEvent.
* *
* @param DataPacket $packet
*
* @return void * @return void
*/ */
public function handleDataPacket(DataPacket $packet){ public function handleDataPacket(DataPacket $packet){
@ -3279,10 +3124,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** /**
* Batch a Data packet into the channel list to send at the end of the tick * Batch a Data packet into the channel list to send at the end of the tick
*
* @param DataPacket $packet
*
* @return bool
*/ */
public function batchDataPacket(DataPacket $packet) : bool{ public function batchDataPacket(DataPacket $packet) : bool{
if(!$this->isConnected()){ if(!$this->isConnected()){
@ -3304,10 +3145,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
/** /**
* @param DataPacket $packet
* @param bool $needACK
* @param bool $immediate
*
* @return bool|int * @return bool|int
*/ */
public function sendDataPacket(DataPacket $packet, bool $needACK = false, bool $immediate = false){ public function sendDataPacket(DataPacket $packet, bool $needACK = false, bool $immediate = false){
@ -3343,9 +3180,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
/** /**
* @param DataPacket $packet
* @param bool $needACK
*
* @return bool|int * @return bool|int
*/ */
public function dataPacket(DataPacket $packet, bool $needACK = false){ public function dataPacket(DataPacket $packet, bool $needACK = false){
@ -3353,9 +3187,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
/** /**
* @param DataPacket $packet
* @param bool $needACK
*
* @return bool|int * @return bool|int
*/ */
public function directDataPacket(DataPacket $packet, bool $needACK = false){ public function directDataPacket(DataPacket $packet, bool $needACK = false){
@ -3390,11 +3221,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** /**
* Kicks a player from the server * Kicks a player from the server
* *
* @param string $reason
* @param bool $isAdmin
* @param TextContainer|string $quitMessage * @param TextContainer|string $quitMessage
*
* @return bool
*/ */
public function kick(string $reason = "", bool $isAdmin = true, $quitMessage = null) : bool{ public function kick(string $reason = "", bool $isAdmin = true, $quitMessage = null) : bool{
$ev = new PlayerKickEvent($this, $reason, $quitMessage ?? $this->getLeaveMessage()); $ev = new PlayerKickEvent($this, $reason, $quitMessage ?? $this->getLeaveMessage());
@ -3422,8 +3249,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** /**
* Adds a title text to the user's screen, with an optional subtitle. * Adds a title text to the user's screen, with an optional subtitle.
* *
* @param string $title
* @param string $subtitle
* @param int $fadeIn Duration in ticks for fade-in. If -1 is given, client-sided defaults will be used. * @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 $stay Duration in ticks to stay on screen for
* @param int $fadeOut Duration in ticks for fade-out. * @param int $fadeOut Duration in ticks for fade-out.
@ -3441,8 +3266,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** /**
* Sets the subtitle message, without sending a title. * Sets the subtitle message, without sending a title.
* *
* @param string $subtitle
*
* @return void * @return void
*/ */
public function addSubTitle(string $subtitle){ public function addSubTitle(string $subtitle){
@ -3452,8 +3275,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** /**
* Adds small text to the user's screen. * Adds small text to the user's screen.
* *
* @param string $message
*
* @return void * @return void
*/ */
public function addActionBarMessage(string $message){ public function addActionBarMessage(string $message){
@ -3505,9 +3326,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** /**
* Internal function used for sending titles. * Internal function used for sending titles.
* *
* @param string $title
* @param int $type
*
* @return void * @return void
*/ */
protected function sendTitleText(string $title, int $type){ protected function sendTitleText(string $title, int $type){
@ -3540,7 +3358,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
/** /**
* @param string $message
* @param string[] $parameters * @param string[] $parameters
* *
* @return void * @return void
@ -3567,7 +3384,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
* *
* TODO: add translation type popups * TODO: add translation type popups
* *
* @param string $message
* @param string $subtitle @deprecated * @param string $subtitle @deprecated
* *
* @return void * @return void
@ -3580,8 +3396,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
/** /**
* @param string $message
*
* @return void * @return void
*/ */
public function sendTip(string $message){ public function sendTip(string $message){
@ -3592,9 +3406,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
/** /**
* @param string $sender
* @param string $message
*
* @return void * @return void
*/ */
public function sendWhisper(string $sender, string $message){ public function sendWhisper(string $sender, string $message){
@ -3607,8 +3418,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** /**
* Sends a Form to the player, or queue to send it if a form is already open. * Sends a Form to the player, or queue to send it if a form is already open.
*
* @param Form $form
*/ */
public function sendForm(Form $form) : void{ public function sendForm(Form $form) : void{
$id = $this->formIdCounter++; $id = $this->formIdCounter++;
@ -3624,10 +3433,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
/** /**
* @param int $formId
* @param mixed $responseData * @param mixed $responseData
*
* @return bool
*/ */
public function onFormSubmit(int $formId, $responseData) : bool{ public function onFormSubmit(int $formId, $responseData) : bool{
if(!isset($this->forms[$formId])){ if(!isset($this->forms[$formId])){
@ -3653,7 +3459,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
* *
* @param TextContainer|string $message Message to be broadcasted * @param TextContainer|string $message Message to be broadcasted
* @param string $reason Reason showed in console * @param string $reason Reason showed in console
* @param bool $notify
*/ */
final public function close($message = "", string $reason = "generic reason", bool $notify = true) : void{ final public function close($message = "", string $reason = "generic reason", bool $notify = true) : void{
if($this->isConnected() and !$this->closed){ if($this->isConnected() and !$this->closed){
@ -3795,7 +3600,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$this->namedtag->setInt("playerGameType", $this->gamemode); $this->namedtag->setInt("playerGameType", $this->gamemode);
$this->namedtag->setLong("lastPlayed", (int) floor(microtime(true) * 1000)); $this->namedtag->setLong("lastPlayed", (int) floor(microtime(true) * 1000));
if($this->username != "" and $this->namedtag instanceof CompoundTag){ if($this->username != ""){
$this->server->saveOfflinePlayerData($this->username, $this->namedtag); $this->server->saveOfflinePlayerData($this->username, $this->namedtag);
} }
} }
@ -3921,10 +3726,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
/** /**
* @param Vector3 $pos
* @param float|null $yaw
* @param float|null $pitch
* @param int $mode
* @param Player[]|null $targets * @param Player[]|null $targets
* *
* @return void * @return void
@ -4004,9 +3805,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return $this->craftingGrid; return $this->craftingGrid;
} }
/**
* @param CraftingGrid $grid
*/
public function setCraftingGrid(CraftingGrid $grid) : void{ public function setCraftingGrid(CraftingGrid $grid) : void{
$this->craftingGrid = $grid; $this->craftingGrid = $grid;
} }
@ -4033,10 +3831,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** /**
* Returns the window ID which the inventory has for this player, or -1 if the window is not open to the player. * Returns the window ID which the inventory has for this player, or -1 if the window is not open to the player.
*
* @param Inventory $inventory
*
* @return int
*/ */
public function getWindowId(Inventory $inventory) : int{ public function getWindowId(Inventory $inventory) : int{
return $this->windows[spl_object_hash($inventory)] ?? ContainerIds::NONE; return $this->windows[spl_object_hash($inventory)] ?? ContainerIds::NONE;
@ -4046,8 +3840,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
* Returns the inventory window open to the player with the specified window ID, or null if no window is open with * Returns the inventory window open to the player with the specified window ID, or null if no window is open with
* that ID. * that ID.
* *
* @param int $windowId
*
* @return Inventory|null * @return Inventory|null
*/ */
public function getWindow(int $windowId){ public function getWindow(int $windowId){
@ -4058,12 +3850,9 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
* Opens an inventory window to the player. Returns the ID of the created window, or the existing window ID if the * Opens an inventory window to the player. Returns the ID of the created window, or the existing window ID if the
* player is already viewing the specified inventory. * player is already viewing the specified inventory.
* *
* @param Inventory $inventory
* @param int|null $forceId Forces a special ID for the window * @param int|null $forceId Forces a special ID for the window
* @param bool $isPermanent Prevents the window being removed if true. * @param bool $isPermanent Prevents the window being removed if true.
* *
* @return int
*
* @throws \InvalidArgumentException if a forceID which is already in use is specified * @throws \InvalidArgumentException if a forceID which is already in use is specified
* @throws \InvalidStateException if trying to add a window without forceID when no slots are free * @throws \InvalidStateException if trying to add a window without forceID when no slots are free
*/ */
@ -4105,7 +3894,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** /**
* Removes an inventory window from the player. * Removes an inventory window from the player.
* *
* @param Inventory $inventory
* @param bool $force Forces removal of permanent windows such as normal inventory, cursor * @param bool $force Forces removal of permanent windows such as normal inventory, cursor
* *
* @return void * @return void

View File

@ -173,19 +173,18 @@ namespace pocketmine {
$opts = getopt("", ["bootstrap:"]); $opts = getopt("", ["bootstrap:"]);
if(isset($opts["bootstrap"])){ if(isset($opts["bootstrap"])){
$bootstrap = realpath($opts["bootstrap"]) ?: $opts["bootstrap"]; $bootstrap = ($real = realpath($opts["bootstrap"])) !== false ? $real : $opts["bootstrap"];
}else{ }else{
$bootstrap = dirname(__FILE__, 3) . '/vendor/autoload.php'; $bootstrap = dirname(__FILE__, 3) . '/vendor/autoload.php';
} }
define('pocketmine\COMPOSER_AUTOLOADER_PATH', $bootstrap);
if(\pocketmine\COMPOSER_AUTOLOADER_PATH !== false and is_file(\pocketmine\COMPOSER_AUTOLOADER_PATH)){ if($bootstrap === false or !is_file($bootstrap)){
require_once(\pocketmine\COMPOSER_AUTOLOADER_PATH);
}else{
critical_error("Composer autoloader not found at " . $bootstrap); critical_error("Composer autoloader not found at " . $bootstrap);
critical_error("Please install/update Composer dependencies or use provided builds."); critical_error("Please install/update Composer dependencies or use provided builds.");
exit(1); exit(1);
} }
define('pocketmine\COMPOSER_AUTOLOADER_PATH', $bootstrap);
require_once(\pocketmine\COMPOSER_AUTOLOADER_PATH);
set_error_handler([Utils::class, 'errorExceptionHandler']); set_error_handler([Utils::class, 'errorExceptionHandler']);
@ -263,7 +262,6 @@ namespace pocketmine {
//TODO: move this to a Server field //TODO: move this to a Server field
define('pocketmine\START_TIME', microtime(true)); define('pocketmine\START_TIME', microtime(true));
ThreadManager::init();
/* /*
* We now use the Composer autoloader, but this autoloader is still for loading plugins. * We now use the Composer autoloader, but this autoloader is still for loading plugins.

File diff suppressed because it is too large Load Diff

View File

@ -23,6 +23,8 @@ declare(strict_types=1);
namespace pocketmine; namespace pocketmine;
use const PTHREADS_INHERIT_ALL;
/** /**
* This class must be extended by all custom threading classes * This class must be extended by all custom threading classes
*/ */
@ -44,8 +46,6 @@ abstract class Thread extends \Thread{
} }
/** /**
* @param \ClassLoader|null $loader
*
* @return void * @return void
*/ */
public function setClassLoader(\ClassLoader $loader = null){ public function setClassLoader(\ClassLoader $loader = null){
@ -80,7 +80,7 @@ abstract class Thread extends \Thread{
* *
* @return bool * @return bool
*/ */
public function start(?int $options = \PTHREADS_INHERIT_ALL){ public function start(?int $options = PTHREADS_INHERIT_ALL){
ThreadManager::getInstance()->add($this); ThreadManager::getInstance()->add($this);
if($this->getClassLoader() === null){ if($this->getClassLoader() === null){

View File

@ -28,10 +28,11 @@ use function spl_object_hash;
class ThreadManager extends \Volatile{ class ThreadManager extends \Volatile{
/** @var ThreadManager */ /** @var ThreadManager|null */
private static $instance = null; private static $instance = null;
/** /**
* @deprecated
* @return void * @return void
*/ */
public static function init(){ public static function init(){
@ -42,6 +43,9 @@ class ThreadManager extends \Volatile{
* @return ThreadManager * @return ThreadManager
*/ */
public static function getInstance(){ public static function getInstance(){
if(self::$instance === null){
self::$instance = new ThreadManager();
}
return self::$instance; return self::$instance;
} }
@ -52,7 +56,7 @@ class ThreadManager extends \Volatile{
*/ */
public function add($thread){ public function add($thread){
if($thread instanceof Thread or $thread instanceof Worker){ if($thread instanceof Thread or $thread instanceof Worker){
$this->{spl_object_hash($thread)} = $thread; $this[spl_object_hash($thread)] = $thread;
} }
} }
@ -63,7 +67,7 @@ class ThreadManager extends \Volatile{
*/ */
public function remove($thread){ public function remove($thread){
if($thread instanceof Thread or $thread instanceof Worker){ if($thread instanceof Thread or $thread instanceof Worker){
unset($this->{spl_object_hash($thread)}); unset($this[spl_object_hash($thread)]);
} }
} }

View File

@ -23,6 +23,8 @@ declare(strict_types=1);
namespace pocketmine; namespace pocketmine;
use function defined;
// composer autoload doesn't use require_once and also pthreads can inherit things // composer autoload doesn't use require_once and also pthreads can inherit things
// TODO: drop this file and use a final class with constants // TODO: drop this file and use a final class with constants
if(defined('pocketmine\_VERSION_INFO_INCLUDED')){ if(defined('pocketmine\_VERSION_INFO_INCLUDED')){
@ -30,8 +32,7 @@ if(defined('pocketmine\_VERSION_INFO_INCLUDED')){
} }
const _VERSION_INFO_INCLUDED = true; const _VERSION_INFO_INCLUDED = true;
const NAME = "PocketMine-MP"; const NAME = "PocketMine-MP";
const BASE_VERSION = "3.11.4"; const BASE_VERSION = "3.12.1";
const IS_DEVELOPMENT_BUILD = false; const IS_DEVELOPMENT_BUILD = false;
const BUILD_NUMBER = 0; const BUILD_NUMBER = 0;

View File

@ -23,6 +23,8 @@ declare(strict_types=1);
namespace pocketmine; namespace pocketmine;
use const PTHREADS_INHERIT_ALL;
/** /**
* This class must be extended by all custom threading classes * This class must be extended by all custom threading classes
*/ */
@ -44,8 +46,6 @@ abstract class Worker extends \Worker{
} }
/** /**
* @param \ClassLoader|null $loader
*
* @return void * @return void
*/ */
public function setClassLoader(\ClassLoader $loader = null){ public function setClassLoader(\ClassLoader $loader = null){
@ -80,7 +80,7 @@ abstract class Worker extends \Worker{
* *
* @return bool * @return bool
*/ */
public function start(?int $options = \PTHREADS_INHERIT_ALL){ public function start(?int $options = PTHREADS_INHERIT_ALL){
ThreadManager::getInstance()->add($this); ThreadManager::getInstance()->add($this);
if($this->getClassLoader() === null){ if($this->getClassLoader() === null){

View File

@ -26,7 +26,6 @@ namespace pocketmine\block;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\math\AxisAlignedBB; use pocketmine\math\AxisAlignedBB;
/** /**
* Air block * Air block
*/ */

View File

@ -78,7 +78,7 @@ class Anvil extends Fallable{
public function recalculateBoundingBox() : ?AxisAlignedBB{ public function recalculateBoundingBox() : ?AxisAlignedBB{
$inset = 0.125; $inset = 0.125;
if($this->meta & 0x01){ //east/west if(($this->meta & 0x01) !== 0){ //east/west
return new AxisAlignedBB( return new AxisAlignedBB(
$this->x, $this->x,
$this->y, $this->y,

View File

@ -99,6 +99,11 @@ abstract class BaseRail extends Flowable{
return false; return false;
} }
/**
* @param int[] $connections
* @param int[][] $lookup
* @phpstan-param array<int, list<int>> $lookup
*/
protected static function searchState(array $connections, array $lookup) : int{ protected static function searchState(array $connections, array $lookup) : int{
$meta = array_search($connections, $lookup, true); $meta = array_search($connections, $lookup, true);
if($meta === false){ if($meta === false){
@ -114,9 +119,7 @@ abstract class BaseRail extends Flowable{
/** /**
* Returns a meta value for the rail with the given connections. * Returns a meta value for the rail with the given connections.
* *
* @param array $connections * @param int[] $connections
*
* @return int
* *
* @throws \InvalidArgumentException if no state matches the given connections * @throws \InvalidArgumentException if no state matches the given connections
*/ */
@ -164,6 +167,12 @@ abstract class BaseRail extends Flowable{
return $connections; return $connections;
} }
/**
* @param int[] $constraints
*
* @return true[]
* @phpstan-return array<int, true>
*/
private function getPossibleConnectionDirections(array $constraints) : array{ private function getPossibleConnectionDirections(array $constraints) : array{
switch(count($constraints)){ switch(count($constraints)){
case 0: case 0:
@ -188,6 +197,10 @@ abstract class BaseRail extends Flowable{
} }
} }
/**
* @return true[]
* @phpstan-return array<int, true>
*/
protected function getPossibleConnectionDirectionsOneConstraint(int $constraint) : array{ protected function getPossibleConnectionDirectionsOneConstraint(int $constraint) : array{
$opposite = Vector3::getOppositeSide($constraint & ~self::FLAG_ASCEND); $opposite = Vector3::getOppositeSide($constraint & ~self::FLAG_ASCEND);
@ -247,6 +260,9 @@ abstract class BaseRail extends Flowable{
} }
} }
/**
* @param int[] $connections
*/
private function updateState(array $connections) : void{ private function updateState(array $connections) : void{
if(count($connections) === 1){ if(count($connections) === 1){
$connections[] = Vector3::getOppositeSide($connections[0] & ~self::FLAG_ASCEND); $connections[] = Vector3::getOppositeSide($connections[0] & ~self::FLAG_ASCEND);

View File

@ -69,16 +69,11 @@ class Bed extends Transparent{
return ($this->meta & self::BITFLAG_HEAD) !== 0; return ($this->meta & self::BITFLAG_HEAD) !== 0;
} }
/**
* @return bool
*/
public function isOccupied() : bool{ public function isOccupied() : bool{
return ($this->meta & self::BITFLAG_OCCUPIED) !== 0; return ($this->meta & self::BITFLAG_OCCUPIED) !== 0;
} }
/** /**
* @param bool $occupied
*
* @return void * @return void
*/ */
public function setOccupied(bool $occupied = true){ public function setOccupied(bool $occupied = true){
@ -95,12 +90,6 @@ class Bed extends Transparent{
} }
} }
/**
* @param int $meta
* @param bool $isHead
*
* @return int
*/
public static function getOtherHalfSide(int $meta, bool $isHead = false) : int{ public static function getOtherHalfSide(int $meta, bool $isHead = false) : int{
$rotation = $meta & 0x03; $rotation = $meta & 0x03;
$side = -1; $side = -1;
@ -127,9 +116,6 @@ class Bed extends Transparent{
return $side; return $side;
} }
/**
* @return Bed|null
*/
public function getOtherHalf() : ?Bed{ public function getOtherHalf() : ?Bed{
$other = $this->getSide(self::getOtherHalfSide($this->meta, $this->isHeadPart())); $other = $this->getSide(self::getOtherHalfSide($this->meta, $this->isHeadPart()));
if($other instanceof Bed and $other->getId() === $this->getId() and $other->isHeadPart() !== $this->isHeadPart() and (($other->getDamage() & 0x03) === ($this->getDamage() & 0x03))){ if($other instanceof Bed and $other->getId() === $this->getId() and $other->isHeadPart() !== $this->isHeadPart() and (($other->getDamage() & 0x03) === ($this->getDamage() & 0x03))){

View File

@ -50,12 +50,6 @@ class Block extends Position implements BlockIds, Metadatable{
* Returns a new Block instance with the specified ID, meta and position. * Returns a new Block instance with the specified ID, meta and position.
* *
* This function redirects to {@link BlockFactory#get}. * This function redirects to {@link BlockFactory#get}.
*
* @param int $id
* @param int $meta
* @param Position|null $pos
*
* @return Block
*/ */
public static function get(int $id, int $meta = 0, Position $pos = null) : Block{ public static function get(int $id, int $meta = 0, Position $pos = null) : Block{
return BlockFactory::get($id, $meta, $pos); return BlockFactory::get($id, $meta, $pos);
@ -73,7 +67,6 @@ class Block extends Position implements BlockIds, Metadatable{
/** @var AxisAlignedBB|null */ /** @var AxisAlignedBB|null */
protected $boundingBox = null; protected $boundingBox = null;
/** @var AxisAlignedBB[]|null */ /** @var AxisAlignedBB[]|null */
protected $collisionBoxes = null; protected $collisionBoxes = null;
@ -90,16 +83,10 @@ class Block extends Position implements BlockIds, Metadatable{
$this->itemId = $itemId; $this->itemId = $itemId;
} }
/**
* @return string
*/
public function getName() : string{ public function getName() : string{
return $this->fallbackName ?? "Unknown"; return $this->fallbackName ?? "Unknown";
} }
/**
* @return int
*/
final public function getId() : int{ final public function getId() : int{
return $this->id; return $this->id;
} }
@ -107,8 +94,6 @@ class Block extends Position implements BlockIds, Metadatable{
/** /**
* Returns the ID of the item form of the block. * Returns the ID of the item form of the block.
* Used for drops for blocks (some blocks such as doors have a different item ID). * Used for drops for blocks (some blocks such as doors have a different item ID).
*
* @return int
*/ */
public function getItemId() : int{ public function getItemId() : int{
return $this->itemId ?? $this->getId(); return $this->itemId ?? $this->getId();
@ -116,22 +101,15 @@ class Block extends Position implements BlockIds, Metadatable{
/** /**
* @internal * @internal
* @return int
*/ */
public function getRuntimeId() : int{ public function getRuntimeId() : int{
return RuntimeBlockMapping::toStaticRuntimeId($this->getId(), $this->getDamage()); return RuntimeBlockMapping::toStaticRuntimeId($this->getId(), $this->getDamage());
} }
/**
* @return int
*/
final public function getDamage() : int{ final public function getDamage() : int{
return $this->meta; return $this->meta;
} }
/**
* @param int $meta
*/
final public function setDamage(int $meta) : void{ final public function setDamage(int $meta) : void{
if($meta < 0 or $meta > 0xf){ if($meta < 0 or $meta > 0xf){
throw new \InvalidArgumentException("Block damage values must be 0-15, not $meta"); throw new \InvalidArgumentException("Block damage values must be 0-15, not $meta");
@ -145,8 +123,6 @@ class Block extends Position implements BlockIds, Metadatable{
* *
* If your block should not have any meta value when it's dropped as an item, override this to return 0 in * If your block should not have any meta value when it's dropped as an item, override this to return 0 in
* descendent classes. * descendent classes.
*
* @return int
*/ */
public function getVariantBitmask() : int{ public function getVariantBitmask() : int{
return -1; return -1;
@ -154,24 +130,18 @@ class Block extends Position implements BlockIds, Metadatable{
/** /**
* Returns the block meta, stripped of non-variant flags. * Returns the block meta, stripped of non-variant flags.
* @return int
*/ */
public function getVariant() : int{ public function getVariant() : int{
return $this->meta & $this->getVariantBitmask(); return $this->meta & $this->getVariantBitmask();
} }
/** /**
* AKA: Block->isPlaceable * AKA: Block->isPlaceable
* @return bool
*/ */
public function canBePlaced() : bool{ public function canBePlaced() : bool{
return true; return true;
} }
/**
* @return bool
*/
public function canBeReplaced() : bool{ public function canBeReplaced() : bool{
return false; return false;
} }
@ -182,15 +152,6 @@ class Block extends Position implements BlockIds, Metadatable{
/** /**
* Places the Block, using block space and block target, and side. Returns if the block has been placed. * Places the Block, using block space and block target, and side. Returns if the block has been placed.
*
* @param Item $item
* @param Block $blockReplace
* @param Block $blockClicked
* @param int $face
* @param Vector3 $clickVector
* @param Player|null $player
*
* @return bool
*/ */
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
return $this->getLevel()->setBlock($this, $this, true, true); return $this->getLevel()->setBlock($this, $this, true, true);
@ -198,18 +159,11 @@ class Block extends Position implements BlockIds, Metadatable{
/** /**
* Returns if the block can be broken with an specific Item * Returns if the block can be broken with an specific Item
*
* @param Item $item
*
* @return bool
*/ */
public function isBreakable(Item $item) : bool{ public function isBreakable(Item $item) : bool{
return true; return true;
} }
/**
* @return int
*/
public function getToolType() : int{ public function getToolType() : int{
return BlockToolType::TYPE_NONE; return BlockToolType::TYPE_NONE;
} }
@ -223,8 +177,6 @@ class Block extends Position implements BlockIds, Metadatable{
* Otherwise, 1 should be returned if a tool is required, 0 if not. * Otherwise, 1 should be returned if a tool is required, 0 if not.
* *
* @see Item::getBlockToolHarvestLevel() * @see Item::getBlockToolHarvestLevel()
*
* @return int
*/ */
public function getToolHarvestLevel() : int{ public function getToolHarvestLevel() : int{
return 0; return 0;
@ -236,10 +188,6 @@ class Block extends Position implements BlockIds, Metadatable{
* *
* In most cases this is also used to determine whether block drops should be created or not, except in some * In most cases this is also used to determine whether block drops should be created or not, except in some
* special cases such as vines. * special cases such as vines.
*
* @param Item $tool
*
* @return bool
*/ */
public function isCompatibleWithTool(Item $tool) : bool{ public function isCompatibleWithTool(Item $tool) : bool{
if($this->getHardness() < 0){ if($this->getHardness() < 0){
@ -254,23 +202,14 @@ class Block extends Position implements BlockIds, Metadatable{
/** /**
* Do the actions needed so the block is broken with the Item * Do the actions needed so the block is broken with the Item
*
* @param Item $item
* @param Player|null $player
*
* @return bool
*/ */
public function onBreak(Item $item, Player $player = null) : bool{ public function onBreak(Item $item, Player $player = null) : bool{
return $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true, true); return $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true, true);
} }
/** /**
* Returns the seconds that this block takes to be broken using an specific Item * Returns the seconds that this block takes to be broken using an specific Item
* *
* @param Item $item
*
* @return float
* @throws \InvalidArgumentException if the item efficiency is not a positive number * @throws \InvalidArgumentException if the item efficiency is not a positive number
*/ */
public function getBreakTime(Item $item) : float{ public function getBreakTime(Item $item) : float{
@ -300,8 +239,6 @@ class Block extends Position implements BlockIds, Metadatable{
/** /**
* Returns whether random block updates will be done on this block. * Returns whether random block updates will be done on this block.
*
* @return bool
*/ */
public function ticksRandomly() : bool{ public function ticksRandomly() : bool{
return false; return false;
@ -324,11 +261,6 @@ class Block extends Position implements BlockIds, Metadatable{
/** /**
* Do actions when activated by Item. Returns if it has done anything * Do actions when activated by Item. Returns if it has done anything
*
* @param Item $item
* @param Player|null $player
*
* @return bool
*/ */
public function onActivate(Item $item, Player $player = null) : bool{ public function onActivate(Item $item, Player $player = null) : bool{
return false; return false;
@ -336,7 +268,6 @@ class Block extends Position implements BlockIds, Metadatable{
/** /**
* Returns a base value used to compute block break times. * Returns a base value used to compute block break times.
* @return float
*/ */
public function getHardness() : float{ public function getHardness() : float{
return 10; return 10;
@ -344,15 +275,11 @@ class Block extends Position implements BlockIds, Metadatable{
/** /**
* Returns the block's resistance to explosions. Usually 5x hardness. * Returns the block's resistance to explosions. Usually 5x hardness.
* @return float
*/ */
public function getBlastResistance() : float{ public function getBlastResistance() : float{
return $this->getHardness() * 5; return $this->getHardness() * 5;
} }
/**
* @return float
*/
public function getFrictionFactor() : float{ public function getFrictionFactor() : float{
return 0.6; return 0.6;
} }
@ -380,16 +307,11 @@ class Block extends Position implements BlockIds, Metadatable{
* Examples of this behaviour include leaves and cobwebs. * Examples of this behaviour include leaves and cobwebs.
* *
* Light-diffusing blocks are included by the heightmap. * Light-diffusing blocks are included by the heightmap.
*
* @return bool
*/ */
public function diffusesSkyLight() : bool{ public function diffusesSkyLight() : bool{
return false; return false;
} }
/**
* @return bool
*/
public function isTransparent() : bool{ public function isTransparent() : bool{
return false; return false;
} }
@ -400,7 +322,6 @@ class Block extends Position implements BlockIds, Metadatable{
/** /**
* AKA: Block->isFlowable * AKA: Block->isFlowable
* @return bool
*/ */
public function canBeFlowedInto() : bool{ public function canBeFlowedInto() : bool{
return false; return false;
@ -416,21 +337,17 @@ class Block extends Position implements BlockIds, Metadatable{
/** /**
* Returns whether entities can climb up this block. * Returns whether entities can climb up this block.
* @return bool
*/ */
public function canClimb() : bool{ public function canClimb() : bool{
return false; return false;
} }
public function addVelocityToEntity(Entity $entity, Vector3 $vector) : void{ public function addVelocityToEntity(Entity $entity, Vector3 $vector) : void{
} }
/** /**
* Sets the block position to a new Position object * Sets the block position to a new Position object
*
* @param Position $v
*/ */
final public function position(Position $v) : void{ final public function position(Position $v) : void{
$this->x = (int) $v->x; $this->x = (int) $v->x;
@ -443,8 +360,6 @@ class Block extends Position implements BlockIds, Metadatable{
/** /**
* Returns an array of Item objects to be dropped * Returns an array of Item objects to be dropped
* *
* @param Item $item
*
* @return Item[] * @return Item[]
*/ */
public function getDrops(Item $item) : array{ public function getDrops(Item $item) : array{
@ -462,8 +377,6 @@ class Block extends Position implements BlockIds, Metadatable{
/** /**
* Returns an array of Items to be dropped when the block is broken using the correct tool type. * Returns an array of Items to be dropped when the block is broken using the correct tool type.
* *
* @param Item $item
*
* @return Item[] * @return Item[]
*/ */
public function getDropsForCompatibleTool(Item $item) : array{ public function getDropsForCompatibleTool(Item $item) : array{
@ -475,8 +388,6 @@ class Block extends Position implements BlockIds, Metadatable{
/** /**
* Returns an array of Items to be dropped when the block is broken using a compatible Silk Touch-enchanted tool. * Returns an array of Items to be dropped when the block is broken using a compatible Silk Touch-enchanted tool.
* *
* @param Item $item
*
* @return Item[] * @return Item[]
*/ */
public function getSilkTouchDrops(Item $item) : array{ public function getSilkTouchDrops(Item $item) : array{
@ -487,10 +398,6 @@ class Block extends Position implements BlockIds, Metadatable{
/** /**
* Returns how much XP will be dropped by breaking this block with the given item. * Returns how much XP will be dropped by breaking this block with the given item.
*
* @param Item $item
*
* @return int
*/ */
public function getXpDropForTool(Item $item) : int{ public function getXpDropForTool(Item $item) : int{
if($item->hasEnchantment(Enchantment::SILK_TOUCH) or !$this->isCompatibleWithTool($item)){ if($item->hasEnchantment(Enchantment::SILK_TOUCH) or !$this->isCompatibleWithTool($item)){
@ -502,8 +409,6 @@ class Block extends Position implements BlockIds, Metadatable{
/** /**
* Returns how much XP this block will drop when broken with an appropriate tool. * Returns how much XP this block will drop when broken with an appropriate tool.
*
* @return int
*/ */
protected function getXpDropAmount() : int{ protected function getXpDropAmount() : int{
return 0; return 0;
@ -512,8 +417,6 @@ class Block extends Position implements BlockIds, Metadatable{
/** /**
* Returns whether Silk Touch enchanted tools will cause this block to drop as itself. Since most blocks drop * Returns whether Silk Touch enchanted tools will cause this block to drop as itself. Since most blocks drop
* themselves anyway, this is implicitly true. * themselves anyway, this is implicitly true.
*
* @return bool
*/ */
public function isAffectedBySilkTouch() : bool{ public function isAffectedBySilkTouch() : bool{
return true; return true;
@ -521,7 +424,6 @@ class Block extends Position implements BlockIds, Metadatable{
/** /**
* Returns the item that players will equip when middle-clicking on this block. * Returns the item that players will equip when middle-clicking on this block.
* @return Item
*/ */
public function getPickedItem() : Item{ public function getPickedItem() : Item{
return ItemFactory::get($this->getItemId(), $this->getVariant()); return ItemFactory::get($this->getItemId(), $this->getVariant());
@ -529,7 +431,6 @@ class Block extends Position implements BlockIds, Metadatable{
/** /**
* Returns the time in ticks which the block will fuel a furnace for. * Returns the time in ticks which the block will fuel a furnace for.
* @return int
*/ */
public function getFuelTime() : int{ public function getFuelTime() : int{
return 0; return 0;
@ -538,8 +439,6 @@ class Block extends Position implements BlockIds, Metadatable{
/** /**
* Returns the chance that the block will catch fire from nearby fire sources. Higher values lead to faster catching * Returns the chance that the block will catch fire from nearby fire sources. Higher values lead to faster catching
* fire. * fire.
*
* @return int
*/ */
public function getFlameEncouragement() : int{ public function getFlameEncouragement() : int{
return 0; return 0;
@ -547,8 +446,6 @@ class Block extends Position implements BlockIds, Metadatable{
/** /**
* Returns the base flammability of this block. Higher values lead to the block burning away more quickly. * Returns the base flammability of this block. Higher values lead to the block burning away more quickly.
*
* @return int
*/ */
public function getFlammability() : int{ public function getFlammability() : int{
return 0; return 0;
@ -556,8 +453,6 @@ class Block extends Position implements BlockIds, Metadatable{
/** /**
* Returns whether fire lit on this block will burn indefinitely. * Returns whether fire lit on this block will burn indefinitely.
*
* @return bool
*/ */
public function burnsForever() : bool{ public function burnsForever() : bool{
return false; return false;
@ -565,8 +460,6 @@ class Block extends Position implements BlockIds, Metadatable{
/** /**
* Returns whether this block can catch fire. * Returns whether this block can catch fire.
*
* @return bool
*/ */
public function isFlammable() : bool{ public function isFlammable() : bool{
return $this->getFlammability() > 0; return $this->getFlammability() > 0;
@ -582,9 +475,6 @@ class Block extends Position implements BlockIds, Metadatable{
/** /**
* Returns the Block on the side $side, works like Vector3::getSide() * Returns the Block on the side $side, works like Vector3::getSide()
* *
* @param int $side
* @param int $step
*
* @return Block * @return Block
*/ */
public function getSide(int $side, int $step = 1){ public function getSide(int $side, int $step = 1){
@ -643,10 +533,6 @@ class Block extends Position implements BlockIds, Metadatable{
/** /**
* Checks for collision against an AxisAlignedBB * Checks for collision against an AxisAlignedBB
*
* @param AxisAlignedBB $bb
*
* @return bool
*/ */
public function collidesWithBB(AxisAlignedBB $bb) : bool{ public function collidesWithBB(AxisAlignedBB $bb) : bool{
foreach($this->getCollisionBoxes() as $bb2){ foreach($this->getCollisionBoxes() as $bb2){
@ -658,9 +544,6 @@ class Block extends Position implements BlockIds, Metadatable{
return false; return false;
} }
/**
* @param Entity $entity
*/
public function onEntityCollide(Entity $entity) : void{ public function onEntityCollide(Entity $entity) : void{
} }
@ -680,16 +563,13 @@ class Block extends Position implements BlockIds, Metadatable{
* @return AxisAlignedBB[] * @return AxisAlignedBB[]
*/ */
protected function recalculateCollisionBoxes() : array{ protected function recalculateCollisionBoxes() : array{
if($bb = $this->recalculateBoundingBox()){ if(($bb = $this->recalculateBoundingBox()) !== null){
return [$bb]; return [$bb];
} }
return []; return [];
} }
/**
* @return AxisAlignedBB|null
*/
public function getBoundingBox() : ?AxisAlignedBB{ public function getBoundingBox() : ?AxisAlignedBB{
if($this->boundingBox === null){ if($this->boundingBox === null){
$this->boundingBox = $this->recalculateBoundingBox(); $this->boundingBox = $this->recalculateBoundingBox();
@ -697,9 +577,6 @@ class Block extends Position implements BlockIds, Metadatable{
return $this->boundingBox; return $this->boundingBox;
} }
/**
* @return AxisAlignedBB|null
*/
protected function recalculateBoundingBox() : ?AxisAlignedBB{ protected function recalculateBoundingBox() : ?AxisAlignedBB{
return new AxisAlignedBB( return new AxisAlignedBB(
$this->x, $this->x,
@ -720,12 +597,6 @@ class Block extends Position implements BlockIds, Metadatable{
$this->collisionBoxes = null; $this->collisionBoxes = null;
} }
/**
* @param Vector3 $pos1
* @param Vector3 $pos2
*
* @return RayTraceResult|null
*/
public function calculateIntercept(Vector3 $pos1, Vector3 $pos2) : ?RayTraceResult{ public function calculateIntercept(Vector3 $pos1, Vector3 $pos2) : ?RayTraceResult{
$bbs = $this->getCollisionBoxes(); $bbs = $this->getCollisionBoxes();
if(count($bbs) === 0){ if(count($bbs) === 0){

View File

@ -32,23 +32,47 @@ use function min;
* Manages block registration and instance creation * Manages block registration and instance creation
*/ */
class BlockFactory{ class BlockFactory{
/** @var \SplFixedArray<Block> */ /**
private static $fullList = null; * @var \SplFixedArray|Block[]
* @phpstan-var \SplFixedArray<Block>
*/
private static $fullList;
/** @var \SplFixedArray<bool> */ /**
public static $solid = null; * @var \SplFixedArray|bool[]
/** @var \SplFixedArray<bool> */ * @phpstan-var \SplFixedArray<bool>
public static $transparent = null; */
/** @var \SplFixedArray<float> */ public static $solid;
public static $hardness = null; /**
/** @var \SplFixedArray<int> */ * @var \SplFixedArray|bool[]
public static $light = null; * @phpstan-var \SplFixedArray<bool>
/** @var \SplFixedArray<int> */ */
public static $lightFilter = null; public static $transparent;
/** @var \SplFixedArray<bool> */ /**
public static $diffusesSkyLight = null; * @var \SplFixedArray|float[]
/** @var \SplFixedArray<float> */ * @phpstan-var \SplFixedArray<float>
public static $blastResistance = null; */
public static $hardness;
/**
* @var \SplFixedArray|int[]
* @phpstan-var \SplFixedArray<int>
*/
public static $light;
/**
* @var \SplFixedArray|int[]
* @phpstan-var \SplFixedArray<int>
*/
public static $lightFilter;
/**
* @var \SplFixedArray|bool[]
* @phpstan-var \SplFixedArray<bool>
*/
public static $diffusesSkyLight;
/**
* @var \SplFixedArray|float[]
* @phpstan-var \SplFixedArray<float>
*/
public static $blastResistance;
/** /**
* Initializes the block factory. By default this is called only once on server start, however you may wish to use * Initializes the block factory. By default this is called only once on server start, however you may wish to use
@ -334,7 +358,6 @@ class BlockFactory{
* NOTE: If you are registering a new block type, you will need to add it to the creative inventory yourself - it * NOTE: If you are registering a new block type, you will need to add it to the creative inventory yourself - it
* will not automatically appear there. * will not automatically appear there.
* *
* @param Block $block
* @param bool $override Whether to override existing registrations * @param bool $override Whether to override existing registrations
* *
* @throws \RuntimeException if something attempted to override an already-registered block without specifying the * @throws \RuntimeException if something attempted to override an already-registered block without specifying the
@ -364,12 +387,6 @@ class BlockFactory{
/** /**
* Returns a new Block instance with the specified ID, meta and position. * Returns a new Block instance with the specified ID, meta and position.
*
* @param int $id
* @param int $meta
* @param Position $pos
*
* @return Block
*/ */
public static function get(int $id, int $meta = 0, Position $pos = null) : Block{ public static function get(int $id, int $meta = 0, Position $pos = null) : Block{
if($meta < 0 or $meta > 0xf){ if($meta < 0 or $meta > 0xf){
@ -398,7 +415,7 @@ class BlockFactory{
/** /**
* @internal * @internal
* @return \SplFixedArray * @phpstan-return \SplFixedArray<Block>
*/ */
public static function getBlockStatesArray() : \SplFixedArray{ public static function getBlockStatesArray() : \SplFixedArray{
return self::$fullList; return self::$fullList;
@ -406,10 +423,6 @@ class BlockFactory{
/** /**
* Returns whether a specified block ID is already registered in the block factory. * Returns whether a specified block ID is already registered in the block factory.
*
* @param int $id
*
* @return bool
*/ */
public static function isRegistered(int $id) : bool{ public static function isRegistered(int $id) : bool{
$b = self::$fullList[$id << 4]; $b = self::$fullList[$id << 4];
@ -419,11 +432,6 @@ class BlockFactory{
/** /**
* @internal * @internal
* @deprecated * @deprecated
*
* @param int $id
* @param int $meta
*
* @return int
*/ */
public static function toStaticRuntimeId(int $id, int $meta = 0) : int{ public static function toStaticRuntimeId(int $id, int $meta = 0) : int{
return RuntimeBlockMapping::toStaticRuntimeId($id, $meta); return RuntimeBlockMapping::toStaticRuntimeId($id, $meta);
@ -433,8 +441,6 @@ class BlockFactory{
* @deprecated * @deprecated
* @internal * @internal
* *
* @param int $runtimeId
*
* @return int[] [id, meta] * @return int[] [id, meta]
*/ */
public static function fromStaticRuntimeId(int $runtimeId) : array{ public static function fromStaticRuntimeId(int $runtimeId) : array{

View File

@ -116,7 +116,7 @@ class Chest extends Transparent{
if( if(
!$this->getSide(Vector3::SIDE_UP)->isTransparent() or !$this->getSide(Vector3::SIDE_UP)->isTransparent() or
($chest->isPaired() and !$chest->getPair()->getBlock()->getSide(Vector3::SIDE_UP)->isTransparent()) or (($pair = $chest->getPair()) !== null and !$pair->getBlock()->getSide(Vector3::SIDE_UP)->isTransparent()) or
!$chest->canOpenWith($item->getCustomName()) !$chest->canOpenWith($item->getCustomName())
){ ){
return true; return true;

View File

@ -112,8 +112,6 @@ class CobblestoneWall extends Transparent{
} }
/** /**
* @param Block $block
*
* @return bool * @return bool
*/ */
public function canConnect(Block $block){ public function canConnect(Block $block){

View File

@ -53,16 +53,10 @@ class ConcretePowder extends Fallable{
} }
} }
/**
* @return null|Block
*/
public function tickFalling() : ?Block{ public function tickFalling() : ?Block{
return $this->checkAdjacentWater(); return $this->checkAdjacentWater();
} }
/**
* @return null|Block
*/
private function checkAdjacentWater() : ?Block{ private function checkAdjacentWater() : ?Block{
for($i = 1; $i < 6; ++$i){ //Do not check underneath for($i = 1; $i < 6; ++$i){ //Do not check underneath
if($this->getSide($i) instanceof Water){ if($this->getSide($i) instanceof Water){

View File

@ -41,7 +41,6 @@ abstract class Crops extends Flowable{
return false; return false;
} }
public function onActivate(Item $item, Player $player = null) : bool{ public function onActivate(Item $item, Player $player = null) : bool{
if($this->meta < 7 and $item->getId() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal if($this->meta < 7 and $item->getId() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal
$block = clone $this; $block = clone $this;
@ -56,7 +55,7 @@ abstract class Crops extends Flowable{
$this->getLevel()->setBlock($this, $ev->getNewState(), true, true); $this->getLevel()->setBlock($this, $ev->getNewState(), true, true);
} }
$item->count--; $item->pop();
return true; return true;
} }

View File

@ -39,7 +39,6 @@ class Dandelion extends Flowable{
return "Dandelion"; return "Dandelion";
} }
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
$down = $this->getSide(Vector3::SIDE_DOWN); $down = $this->getSide(Vector3::SIDE_DOWN);
if($down->getId() === Block::GRASS or $down->getId() === Block::DIRT or $down->getId() === Block::FARMLAND){ if($down->getId() === Block::GRASS or $down->getId() === Block::DIRT or $down->getId() === Block::FARMLAND){

View File

@ -29,7 +29,6 @@ use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\Player; use pocketmine\Player;
abstract class Door extends Transparent{ abstract class Door extends Transparent{
public function isSolid() : bool{ public function isSolid() : bool{

View File

@ -68,10 +68,9 @@ class DoublePlant extends Flowable{
/** /**
* Returns whether this double-plant has a corresponding other half. * Returns whether this double-plant has a corresponding other half.
* @return bool
*/ */
public function isValidHalfPlant() : bool{ public function isValidHalfPlant() : bool{
if($this->meta & self::BITFLAG_TOP){ if(($this->meta & self::BITFLAG_TOP) !== 0){
$other = $this->getSide(Vector3::SIDE_DOWN); $other = $this->getSide(Vector3::SIDE_DOWN);
}else{ }else{
$other = $this->getSide(Vector3::SIDE_UP); $other = $this->getSide(Vector3::SIDE_UP);
@ -103,7 +102,7 @@ class DoublePlant extends Flowable{
} }
public function getDrops(Item $item) : array{ public function getDrops(Item $item) : array{
if($this->meta & self::BITFLAG_TOP){ if(($this->meta & self::BITFLAG_TOP) !== 0){
if($this->isCompatibleWithTool($item)){ if($this->isCompatibleWithTool($item)){
return parent::getDrops($item); return parent::getDrops($item);
} }

View File

@ -45,9 +45,6 @@ abstract class Fallable extends Solid{
} }
} }
/**
* @return null|Block
*/
public function tickFalling() : ?Block{ public function tickFalling() : ?Block{
return null; return null;
} }

View File

@ -48,7 +48,6 @@ class Farmland extends Transparent{
return BlockToolType::TYPE_SHOVEL; return BlockToolType::TYPE_SHOVEL;
} }
protected function recalculateBoundingBox() : ?AxisAlignedBB{ protected function recalculateBoundingBox() : ?AxisAlignedBB{
return new AxisAlignedBB( return new AxisAlignedBB(
$this->x, $this->x,

View File

@ -104,8 +104,6 @@ abstract class Fence extends Transparent{
} }
/** /**
* @param Block $block
*
* @return bool * @return bool
*/ */
public function canConnect(Block $block){ public function canConnect(Block $block){

View File

@ -39,7 +39,6 @@ class FenceGate extends Transparent{
return BlockToolType::TYPE_AXE; return BlockToolType::TYPE_AXE;
} }
protected function recalculateBoundingBox() : ?AxisAlignedBB{ protected function recalculateBoundingBox() : ?AxisAlignedBB{
if(($this->getDamage() & 0x04) > 0){ if(($this->getDamage() & 0x04) > 0){

View File

@ -23,7 +23,6 @@ declare(strict_types=1);
namespace pocketmine\block; namespace pocketmine\block;
class Furnace extends BurningFurnace{ class Furnace extends BurningFurnace{
protected $id = self::FURNACE; protected $id = self::FURNACE;

View File

@ -1,6 +1,5 @@
<?php <?php
/* /*
* *
* ____ _ _ __ __ _ __ __ ____ * ____ _ _ __ __ _ __ __ ____

View File

@ -23,7 +23,6 @@ declare(strict_types=1);
namespace pocketmine\block; namespace pocketmine\block;
use pocketmine\item\TieredTool; use pocketmine\item\TieredTool;
class GlowingObsidian extends Solid{ class GlowingObsidian extends Solid{

View File

@ -99,7 +99,7 @@ class Grass extends Solid{
public function onActivate(Item $item, Player $player = null) : bool{ public function onActivate(Item $item, Player $player = null) : bool{
if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){ if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){
$item->count--; $item->pop();
TallGrassObject::growGrass($this->getLevel(), $this, new Random(mt_rand()), 8, 2); TallGrassObject::growGrass($this->getLevel(), $this, new Random(mt_rand()), 8, 2);
return true; return true;

View File

@ -90,7 +90,6 @@ class Ladder extends Transparent{
); );
} }
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
if(!$blockClicked->isTransparent()){ if(!$blockClicked->isTransparent()){
$faces = [ $faces = [

View File

@ -68,7 +68,10 @@ class Leaves extends Transparent{
return true; return true;
} }
/**
* @param true[] $visited reference parameter
* @phpstan-param array<string, true> $visited
*/
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; $index = $pos->x . "." . $pos->y . "." . $pos->z;
if(isset($visited[$index])){ if(isset($visited[$index])){
@ -169,7 +172,7 @@ class Leaves extends Transparent{
} }
public function getDrops(Item $item) : array{ public function getDrops(Item $item) : array{
if($item->getBlockToolType() & BlockToolType::TYPE_SHEARS){ if(($item->getBlockToolType() & BlockToolType::TYPE_SHEARS) !== 0){
return $this->getDropsForCompatibleTool($item); return $this->getDropsForCompatibleTool($item);
} }

View File

@ -211,8 +211,6 @@ abstract class Liquid extends Transparent{
/** /**
* Returns how many liquid levels are lost per block flowed horizontally. Affects how far the liquid can flow. * Returns how many liquid levels are lost per block flowed horizontally. Affects how far the liquid can flow.
*
* @return int
*/ */
public function getFlowDecayPerBlock() : int{ public function getFlowDecayPerBlock() : int{
return 1; return 1;

View File

@ -23,7 +23,6 @@ declare(strict_types=1);
namespace pocketmine\block; namespace pocketmine\block;
class MossyCobblestone extends Cobblestone{ class MossyCobblestone extends Cobblestone{
protected $id = self::MOSSY_COBBLESTONE; protected $id = self::MOSSY_COBBLESTONE;

View File

@ -23,7 +23,6 @@ declare(strict_types=1);
namespace pocketmine\block; namespace pocketmine\block;
use pocketmine\event\block\BlockGrowEvent; use pocketmine\event\block\BlockGrowEvent;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\item\ItemFactory; use pocketmine\item\ItemFactory;

View File

@ -72,7 +72,7 @@ class Sapling extends Flowable{
//TODO: change log type //TODO: change log type
Tree::growTree($this->getLevel(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->getVariant()); Tree::growTree($this->getLevel(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->getVariant());
$item->count--; $item->pop();
return true; return true;
} }

View File

@ -57,7 +57,6 @@ class SignPost extends Transparent{
return null; return null;
} }
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
if($face !== Vector3::SIDE_DOWN){ if($face !== Vector3::SIDE_DOWN){

View File

@ -23,7 +23,6 @@ declare(strict_types=1);
namespace pocketmine\block; namespace pocketmine\block;
class Sponge extends Solid{ class Sponge extends Solid{
protected $id = self::SPONGE; protected $id = self::SPONGE;

View File

@ -62,7 +62,7 @@ class Sugarcane extends Flowable{
$this->getLevel()->setBlock($this, $this, true); $this->getLevel()->setBlock($this, $this, true);
} }
$item->count--; $item->pop();
return true; return true;
} }

View File

@ -75,8 +75,6 @@ class TNT extends Solid{
} }
/** /**
* @param int $fuse
*
* @return void * @return void
*/ */
public function ignite(int $fuse = 80){ public function ignite(int $fuse = 80){

View File

@ -23,7 +23,6 @@ declare(strict_types=1);
namespace pocketmine\block; namespace pocketmine\block;
abstract class Transparent extends Block{ abstract class Transparent extends Block{
public function isTransparent() : bool{ public function isTransparent() : bool{

View File

@ -197,7 +197,7 @@ class Vine extends Flowable{
} }
public function getDrops(Item $item) : array{ public function getDrops(Item $item) : array{
if($item->getBlockToolType() & BlockToolType::TYPE_SHEARS){ if(($item->getBlockToolType() & BlockToolType::TYPE_SHEARS) !== 0){
return $this->getDropsForCompatibleTool($item); return $this->getDropsForCompatibleTool($item);
} }

View File

@ -55,7 +55,6 @@ class WaterLily extends Flowable{
); );
} }
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
if($blockClicked instanceof Water){ if($blockClicked instanceof Water){
$up = $blockClicked->getSide(Vector3::SIDE_UP); $up = $blockClicked->getSide(Vector3::SIDE_UP);

View File

@ -23,7 +23,6 @@ declare(strict_types=1);
namespace pocketmine\block; namespace pocketmine\block;
class Wood2 extends Wood{ class Wood2 extends Wood{
public const ACACIA = 0; public const ACACIA = 0;

View File

@ -50,9 +50,7 @@ abstract class Command{
/** @var string[] */ /** @var string[] */
private $aliases = []; private $aliases = [];
/** /** @var string[] */
* @var string[]
*/
private $activeAliases = []; private $activeAliases = [];
/** @var CommandMap|null */ /** @var CommandMap|null */
@ -67,16 +65,13 @@ abstract class Command{
/** @var string|null */ /** @var string|null */
private $permission = null; private $permission = null;
/** @var string */ /** @var string|null */
private $permissionMessage = null; private $permissionMessage = null;
/** @var TimingsHandler */ /** @var TimingsHandler|null */
public $timings; public $timings = null;
/** /**
* @param string $name
* @param string $description
* @param string $usageMessage
* @param string[] $aliases * @param string[] $aliases
*/ */
public function __construct(string $name, string $description = "", string $usageMessage = null, array $aliases = []){ public function __construct(string $name, string $description = "", string $usageMessage = null, array $aliases = []){
@ -88,18 +83,13 @@ abstract class Command{
} }
/** /**
* @param CommandSender $sender * @param string[] $args
* @param string $commandLabel
* @param string[] $args
* *
* @return mixed * @return mixed
* @throws CommandException * @throws CommandException
*/ */
abstract public function execute(CommandSender $sender, string $commandLabel, array $args); abstract public function execute(CommandSender $sender, string $commandLabel, array $args);
/**
* @return string
*/
public function getName() : string{ public function getName() : string{
return $this->name; return $this->name;
} }
@ -111,21 +101,13 @@ abstract class Command{
return $this->permission; return $this->permission;
} }
/** /**
* @param string|null $permission
*
* @return void * @return void
*/ */
public function setPermission(string $permission = null){ public function setPermission(string $permission = null){
$this->permission = $permission; $this->permission = $permission;
} }
/**
* @param CommandSender $target
*
* @return bool
*/
public function testPermission(CommandSender $target) : bool{ public function testPermission(CommandSender $target) : bool{
if($this->testPermissionSilent($target)){ if($this->testPermissionSilent($target)){
return true; return true;
@ -140,11 +122,6 @@ abstract class Command{
return false; return false;
} }
/**
* @param CommandSender $target
*
* @return bool
*/
public function testPermissionSilent(CommandSender $target) : bool{ public function testPermissionSilent(CommandSender $target) : bool{
if($this->permission === null or $this->permission === ""){ if($this->permission === null or $this->permission === ""){
return true; return true;
@ -159,9 +136,6 @@ abstract class Command{
return false; return false;
} }
/**
* @return string
*/
public function getLabel() : string{ public function getLabel() : string{
return $this->label; return $this->label;
} }
@ -183,10 +157,6 @@ abstract class Command{
/** /**
* Registers the command into a Command map * Registers the command into a Command map
*
* @param CommandMap $commandMap
*
* @return bool
*/ */
public function register(CommandMap $commandMap) : bool{ public function register(CommandMap $commandMap) : bool{
if($this->allowChangesFrom($commandMap)){ if($this->allowChangesFrom($commandMap)){
@ -198,11 +168,6 @@ abstract class Command{
return false; return false;
} }
/**
* @param CommandMap $commandMap
*
* @return bool
*/
public function unregister(CommandMap $commandMap) : bool{ public function unregister(CommandMap $commandMap) : bool{
if($this->allowChangesFrom($commandMap)){ if($this->allowChangesFrom($commandMap)){
$this->commandMap = null; $this->commandMap = null;
@ -215,18 +180,10 @@ abstract class Command{
return false; return false;
} }
/**
* @param CommandMap $commandMap
*
* @return bool
*/
private function allowChangesFrom(CommandMap $commandMap) : bool{ private function allowChangesFrom(CommandMap $commandMap) : bool{
return $this->commandMap === null or $this->commandMap === $commandMap; return $this->commandMap === null or $this->commandMap === $commandMap;
} }
/**
* @return bool
*/
public function isRegistered() : bool{ public function isRegistered() : bool{
return $this->commandMap !== null; return $this->commandMap !== null;
} }
@ -238,23 +195,14 @@ abstract class Command{
return $this->activeAliases; return $this->activeAliases;
} }
/**
* @return string|null
*/
public function getPermissionMessage() : ?string{ public function getPermissionMessage() : ?string{
return $this->permissionMessage; return $this->permissionMessage;
} }
/**
* @return string
*/
public function getDescription() : string{ public function getDescription() : string{
return $this->description; return $this->description;
} }
/**
* @return string
*/
public function getUsage() : string{ public function getUsage() : string{
return $this->usageMessage; return $this->usageMessage;
} }
@ -272,8 +220,6 @@ abstract class Command{
} }
/** /**
* @param string $description
*
* @return void * @return void
*/ */
public function setDescription(string $description){ public function setDescription(string $description){
@ -281,8 +227,6 @@ abstract class Command{
} }
/** /**
* @param string $permissionMessage
*
* @return void * @return void
*/ */
public function setPermissionMessage(string $permissionMessage){ public function setPermissionMessage(string $permissionMessage){
@ -290,8 +234,6 @@ abstract class Command{
} }
/** /**
* @param string $usage
*
* @return void * @return void
*/ */
public function setUsage(string $usage){ public function setUsage(string $usage){
@ -299,9 +241,7 @@ abstract class Command{
} }
/** /**
* @param CommandSender $source
* @param TextContainer|string $message * @param TextContainer|string $message
* @param bool $sendToSource
* *
* @return void * @return void
*/ */
@ -338,9 +278,6 @@ abstract class Command{
} }
} }
/**
* @return string
*/
public function __toString() : string{ public function __toString() : string{
return $this->name; return $this->name;
} }

View File

@ -23,16 +23,10 @@ declare(strict_types=1);
namespace pocketmine\command; namespace pocketmine\command;
interface CommandExecutor{ interface CommandExecutor{
/** /**
* @param CommandSender $sender
* @param Command $command
* @param string $label
* @param string[] $args * @param string[] $args
*
* @return bool
*/ */
public function onCommand(CommandSender $sender, Command $command, string $label, array $args) : bool; public function onCommand(CommandSender $sender, Command $command, string $label, array $args) : bool;

View File

@ -23,32 +23,17 @@ declare(strict_types=1);
namespace pocketmine\command; namespace pocketmine\command;
interface CommandMap{ interface CommandMap{
/** /**
* @param string $fallbackPrefix
* @param Command[] $commands * @param Command[] $commands
* *
* @return void * @return void
*/ */
public function registerAll(string $fallbackPrefix, array $commands); public function registerAll(string $fallbackPrefix, array $commands);
/**
* @param string $fallbackPrefix
* @param Command $command
* @param string|null $label
*
* @return bool
*/
public function register(string $fallbackPrefix, Command $command, string $label = null) : bool; public function register(string $fallbackPrefix, Command $command, string $label = null) : bool;
/**
* @param CommandSender $sender
* @param string $cmdLine
*
* @return bool
*/
public function dispatch(CommandSender $sender, string $cmdLine) : bool; public function dispatch(CommandSender $sender, string $cmdLine) : bool;
/** /**
@ -57,11 +42,8 @@ interface CommandMap{
public function clearCommands(); public function clearCommands();
/** /**
* @param string $name
*
* @return Command|null * @return Command|null
*/ */
public function getCommand(string $name); public function getCommand(string $name);
} }

View File

@ -116,8 +116,6 @@ class CommandReader extends Thread{
* Checks if the specified stream is a FIFO pipe. * Checks if the specified stream is a FIFO pipe.
* *
* @param resource $stream * @param resource $stream
*
* @return bool
*/ */
private function isPipe($stream) : bool{ private function isPipe($stream) : bool{
return is_resource($stream) and (!stream_isatty($stream) or ((fstat($stream)["mode"] & 0170000) === 0010000)); return is_resource($stream) and (!stream_isatty($stream) or ((fstat($stream)["mode"] & 0170000) === 0010000));
@ -156,7 +154,7 @@ class CommandReader extends Thread{
case self::TYPE_PIPED: case self::TYPE_PIPED:
if(($raw = fgets(self::$stdin)) === false){ //broken pipe or EOF if(($raw = fgets(self::$stdin)) === false){ //broken pipe or EOF
$this->initStdin(); $this->initStdin();
$this->synchronized(function(){ $this->synchronized(function() : void{
$this->wait(200000); $this->wait(200000);
}); //prevent CPU waste if it's end of pipe }); //prevent CPU waste if it's end of pipe
return true; //loop back round return true; //loop back round

View File

@ -41,24 +41,17 @@ interface CommandSender extends Permissible{
*/ */
public function getServer(); public function getServer();
/**
* @return string
*/
public function getName() : string; public function getName() : string;
/** /**
* Returns the line height of the command-sender's screen. Used for determining sizes for command output pagination * Returns the line height of the command-sender's screen. Used for determining sizes for command output pagination
* such as in the /help command. * such as in the /help command.
*
* @return int
*/ */
public function getScreenLineHeight() : int; public function getScreenLineHeight() : int;
/** /**
* Sets the line height used for command output pagination for this command sender. `null` will reset it to default. * 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 * @return void
*/ */
public function setScreenLineHeight(int $height = null); public function setScreenLineHeight(int $height = null);

View File

@ -49,8 +49,6 @@ class ConsoleCommandSender implements CommandSender{
/** /**
* @param Permission|string $name * @param Permission|string $name
*
* @return bool
*/ */
public function isPermissionSet($name) : bool{ public function isPermissionSet($name) : bool{
return $this->perm->isPermissionSet($name); return $this->perm->isPermissionSet($name);
@ -58,27 +56,16 @@ class ConsoleCommandSender implements CommandSender{
/** /**
* @param Permission|string $name * @param Permission|string $name
*
* @return bool
*/ */
public function hasPermission($name) : bool{ public function hasPermission($name) : bool{
return $this->perm->hasPermission($name); return $this->perm->hasPermission($name);
} }
/**
* @param Plugin $plugin
* @param string $name
* @param bool $value
*
* @return PermissionAttachment
*/
public function addAttachment(Plugin $plugin, string $name = null, bool $value = null) : PermissionAttachment{ public function addAttachment(Plugin $plugin, string $name = null, bool $value = null) : PermissionAttachment{
return $this->perm->addAttachment($plugin, $name, $value); return $this->perm->addAttachment($plugin, $name, $value);
} }
/** /**
* @param PermissionAttachment $attachment
*
* @return void * @return void
*/ */
public function removeAttachment(PermissionAttachment $attachment){ public function removeAttachment(PermissionAttachment $attachment){
@ -120,23 +107,15 @@ class ConsoleCommandSender implements CommandSender{
} }
} }
/**
* @return string
*/
public function getName() : string{ public function getName() : string{
return "CONSOLE"; return "CONSOLE";
} }
/**
* @return bool
*/
public function isOp() : bool{ public function isOp() : bool{
return true; return true;
} }
/** /**
* @param bool $value
*
* @return void * @return void
*/ */
public function setOp(bool $value){ public function setOp(bool $value){

View File

@ -36,7 +36,6 @@ class FormattedCommandAlias extends Command{
private $formatStrings = []; private $formatStrings = [];
/** /**
* @param string $alias
* @param string[] $formatStrings * @param string[] $formatStrings
*/ */
public function __construct(string $alias, array $formatStrings){ public function __construct(string $alias, array $formatStrings){
@ -66,10 +65,7 @@ class FormattedCommandAlias extends Command{
} }
/** /**
* @param string $formatString * @param string[] $args
* @param array $args
*
* @return string
*/ */
private function buildCommand(string $formatString, array $args) : string{ private function buildCommand(string $formatString, array $args) : string{
$index = strpos($formatString, '$'); $index = strpos($formatString, '$');
@ -144,13 +140,6 @@ class FormattedCommandAlias extends Command{
return $formatString; return $formatString;
} }
/**
* @param int $i
* @param int $j
* @param int $k
*
* @return bool
*/
private static function inRange(int $i, int $j, int $k) : bool{ private static function inRange(int $i, int $j, int $k) : bool{
return $i >= $j and $i <= $k; return $i >= $j and $i <= $k;
} }

View File

@ -34,10 +34,6 @@ class PluginCommand extends Command implements PluginIdentifiableCommand{
/** @var CommandExecutor */ /** @var CommandExecutor */
private $executor; private $executor;
/**
* @param string $name
* @param Plugin $owner
*/
public function __construct(string $name, Plugin $owner){ public function __construct(string $name, Plugin $owner){
parent::__construct($name); parent::__construct($name);
$this->owningPlugin = $owner; $this->owningPlugin = $owner;
@ -69,17 +65,12 @@ class PluginCommand extends Command implements PluginIdentifiableCommand{
} }
/** /**
* @param CommandExecutor $executor
*
* @return void * @return void
*/ */
public function setExecutor(CommandExecutor $executor){ public function setExecutor(CommandExecutor $executor){
$this->executor = $executor; $this->executor = $executor;
} }
/**
* @return Plugin
*/
public function getPlugin() : Plugin{ public function getPlugin() : Plugin{
return $this->owningPlugin; return $this->owningPlugin;
} }

View File

@ -27,8 +27,5 @@ use pocketmine\plugin\Plugin;
interface PluginIdentifiableCommand{ interface PluginIdentifiableCommand{
/**
* @return Plugin
*/
public function getPlugin() : Plugin; public function getPlugin() : Plugin;
} }

View File

@ -72,6 +72,7 @@ use function explode;
use function implode; use function implode;
use function min; use function min;
use function preg_match_all; use function preg_match_all;
use function strcasecmp;
use function stripslashes; use function stripslashes;
use function strpos; use function strpos;
use function strtolower; use function strtolower;
@ -79,9 +80,7 @@ use function trim;
class SimpleCommandMap implements CommandMap{ class SimpleCommandMap implements CommandMap{
/** /** @var Command[] */
* @var Command[]
*/
protected $knownCommands = []; protected $knownCommands = [];
/** @var Server */ /** @var Server */
@ -137,20 +136,12 @@ class SimpleCommandMap implements CommandMap{
]); ]);
} }
public function registerAll(string $fallbackPrefix, array $commands){ public function registerAll(string $fallbackPrefix, array $commands){
foreach($commands as $command){ foreach($commands as $command){
$this->register($fallbackPrefix, $command); $this->register($fallbackPrefix, $command);
} }
} }
/**
* @param string $fallbackPrefix
* @param Command $command
* @param string|null $label
*
* @return bool
*/
public function register(string $fallbackPrefix, Command $command, string $label = null) : bool{ public function register(string $fallbackPrefix, Command $command, string $label = null) : bool{
if($label === null){ if($label === null){
$label = $command->getName(); $label = $command->getName();
@ -177,11 +168,6 @@ class SimpleCommandMap implements CommandMap{
return $registered; return $registered;
} }
/**
* @param Command $command
*
* @return bool
*/
public function unregister(Command $command) : bool{ public function unregister(Command $command) : bool{
foreach($this->knownCommands as $lbl => $cmd){ foreach($this->knownCommands as $lbl => $cmd){
if($cmd === $command){ if($cmd === $command){
@ -194,21 +180,13 @@ class SimpleCommandMap implements CommandMap{
return true; return true;
} }
/**
* @param Command $command
* @param bool $isAlias
* @param string $fallbackPrefix
* @param string $label
*
* @return bool
*/
private function registerAlias(Command $command, bool $isAlias, string $fallbackPrefix, string $label) : bool{ private function registerAlias(Command $command, bool $isAlias, string $fallbackPrefix, string $label) : bool{
$this->knownCommands[$fallbackPrefix . ":" . $label] = $command; $this->knownCommands[$fallbackPrefix . ":" . $label] = $command;
if(($command instanceof VanillaCommand or $isAlias) and isset($this->knownCommands[$label])){ if(($command instanceof VanillaCommand or $isAlias) and isset($this->knownCommands[$label])){
return false; return false;
} }
if(isset($this->knownCommands[$label]) and $this->knownCommands[$label]->getLabel() !== null and $this->knownCommands[$label]->getLabel() === $label){ if(isset($this->knownCommands[$label]) and $this->knownCommands[$label]->getLabel() === $label){
return false; return false;
} }
@ -296,7 +274,6 @@ class SimpleCommandMap implements CommandMap{
return $this->knownCommands; return $this->knownCommands;
} }
/** /**
* @return void * @return void
*/ */
@ -318,10 +295,9 @@ class SimpleCommandMap implements CommandMap{
$commandName = ""; $commandName = "";
$command = $this->matchCommand($commandName, $args); $command = $this->matchCommand($commandName, $args);
if($command === null){ if($command === null){
$bad[] = $commandString; $bad[] = $commandString;
}elseif($commandName === $alias){ }elseif(strcasecmp($commandName, $alias) === 0){
$recursive[] = $commandString; $recursive[] = $commandString;
}else{ }else{
$targets[] = $commandString; $targets[] = $commandString;

View File

@ -63,7 +63,7 @@ class BanListCommand extends VanillaCommand{
} }
$list = $list->getEntries(); $list = $list->getEntries();
$message = implode(", ", array_map(function(BanEntry $entry){ $message = implode(", ", array_map(function(BanEntry $entry) : string{
return $entry->getName(); return $entry->getName();
}, $list)); }, $list));

View File

@ -76,7 +76,7 @@ class EffectCommand extends VanillaCommand{
} }
if($effect === null){ if($effect === null){
$sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.effect.notFound", [(string) $args[1]])); $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.effect.notFound", [$args[1]]));
return true; return true;
} }
@ -124,7 +124,6 @@ class EffectCommand extends VanillaCommand{
self::broadcastCommandMessage($sender, new TranslationContainer("%commands.effect.success", [$effect->getName(), $instance->getAmplifier(), $player->getDisplayName(), $instance->getDuration() / 20, $effect->getId()])); self::broadcastCommandMessage($sender, new TranslationContainer("%commands.effect.success", [$effect->getName(), $instance->getAmplifier(), $player->getDisplayName(), $instance->getDuration() / 20, $effect->getId()]));
} }
return true; return true;
} }
} }

View File

@ -88,7 +88,6 @@ class EnchantCommand extends VanillaCommand{
$item->addEnchantment(new EnchantmentInstance($enchantment, $level)); $item->addEnchantment(new EnchantmentInstance($enchantment, $level));
$player->getInventory()->setItemInHand($item); $player->getInventory()->setItemInHand($item);
self::broadcastCommandMessage($sender, new TranslationContainer("%commands.enchant.success", [$player->getName()])); self::broadcastCommandMessage($sender, new TranslationContainer("%commands.enchant.success", [$player->getName()]));
return true; return true;
} }

View File

@ -57,22 +57,22 @@ class HelpCommand extends VanillaCommand{
} }
if(count($args) === 0){ if(count($args) === 0){
$command = ""; $commandName = "";
$pageNumber = 1; $pageNumber = 1;
}elseif(is_numeric($args[count($args) - 1])){ }elseif(is_numeric($args[count($args) - 1])){
$pageNumber = (int) array_pop($args); $pageNumber = (int) array_pop($args);
if($pageNumber <= 0){ if($pageNumber <= 0){
$pageNumber = 1; $pageNumber = 1;
} }
$command = implode(" ", $args); $commandName = implode(" ", $args);
}else{ }else{
$command = implode(" ", $args); $commandName = implode(" ", $args);
$pageNumber = 1; $pageNumber = 1;
} }
$pageHeight = $sender->getScreenLineHeight(); $pageHeight = $sender->getScreenLineHeight();
if($command === ""){ if($commandName === ""){
/** @var Command[][] $commands */ /** @var Command[][] $commands */
$commands = []; $commands = [];
foreach($sender->getServer()->getCommandMap()->getCommands() as $command){ foreach($sender->getServer()->getCommandMap()->getCommands() as $command){
@ -82,7 +82,7 @@ class HelpCommand extends VanillaCommand{
} }
ksort($commands, SORT_NATURAL | SORT_FLAG_CASE); ksort($commands, SORT_NATURAL | SORT_FLAG_CASE);
$commands = array_chunk($commands, $pageHeight); $commands = array_chunk($commands, $pageHeight);
$pageNumber = (int) min(count($commands), $pageNumber); $pageNumber = min(count($commands), $pageNumber);
if($pageNumber < 1){ if($pageNumber < 1){
$pageNumber = 1; $pageNumber = 1;
} }
@ -95,7 +95,7 @@ class HelpCommand extends VanillaCommand{
return true; return true;
}else{ }else{
if(($cmd = $sender->getServer()->getCommandMap()->getCommand(strtolower($command))) instanceof Command){ if(($cmd = $sender->getServer()->getCommandMap()->getCommand(strtolower($commandName))) instanceof Command){
if($cmd->testPermissionSilent($sender)){ if($cmd->testPermissionSilent($sender)){
$message = TextFormat::YELLOW . "--------- " . TextFormat::WHITE . " Help: /" . $cmd->getName() . TextFormat::YELLOW . " ---------\n"; $message = TextFormat::YELLOW . "--------- " . TextFormat::WHITE . " Help: /" . $cmd->getName() . TextFormat::YELLOW . " ---------\n";
$message .= TextFormat::GOLD . "Description: " . TextFormat::WHITE . $cmd->getDescription() . "\n"; $message .= TextFormat::GOLD . "Description: " . TextFormat::WHITE . $cmd->getDescription() . "\n";
@ -105,7 +105,7 @@ class HelpCommand extends VanillaCommand{
return true; return true;
} }
} }
$sender->sendMessage(TextFormat::RED . "No help for " . strtolower($command)); $sender->sendMessage(TextFormat::RED . "No help for " . strtolower($commandName));
return true; return true;
} }

View File

@ -68,7 +68,6 @@ class KickCommand extends VanillaCommand{
$sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound")); $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound"));
} }
return true; return true;
} }
} }

View File

@ -47,9 +47,9 @@ class ListCommand extends VanillaCommand{
return true; return true;
} }
$playerNames = array_map(function(Player $player){ $playerNames = array_map(function(Player $player) : string{
return $player->getName(); return $player->getName();
}, array_filter($sender->getServer()->getOnlinePlayers(), function(Player $player) use ($sender){ }, array_filter($sender->getServer()->getOnlinePlayers(), function(Player $player) use ($sender) : bool{
return $player->isOnline() and (!($sender instanceof Player) or $sender->canSee($player)); return $player->isOnline() and (!($sender instanceof Player) or $sender->canSee($player));
})); }));

View File

@ -119,7 +119,6 @@ class ParticleCommand extends VanillaCommand{
return true; return true;
} }
$sender->sendMessage(new TranslationContainer("commands.particle.success", [$name, $count])); $sender->sendMessage(new TranslationContainer("commands.particle.success", [$name, $count]));
$random = new Random((int) (microtime(true) * 1000) + mt_rand()); $random = new Random((int) (microtime(true) * 1000) + mt_rand());
@ -137,13 +136,6 @@ class ParticleCommand extends VanillaCommand{
} }
/** /**
* @param string $name
* @param Vector3 $pos
* @param float $xd
* @param float $yd
* @param float $zd
* @param int|null $data
*
* @return Particle|null * @return Particle|null
*/ */
private function getParticle(string $name, Vector3 $pos, float $xd, float $yd, float $zd, int $data = null){ private function getParticle(string $name, Vector3 $pos, float $xd, float $yd, float $zd, int $data = null){

View File

@ -52,7 +52,7 @@ class TeleportCommand extends VanillaCommand{
return true; return true;
} }
$args = array_values(array_filter($args, function($arg){ $args = array_values(array_filter($args, function(string $arg) : bool{
return $arg !== ""; return $arg !== "";
})); }));
if(count($args) < 1 or count($args) > 6){ if(count($args) < 1 or count($args) > 6){

View File

@ -85,7 +85,6 @@ class TimeCommand extends VanillaCommand{
return true; return true;
} }
if(count($args) < 2){ if(count($args) < 2){
throw new InvalidCommandSyntaxException(); throw new InvalidCommandSyntaxException();
} }

View File

@ -126,18 +126,25 @@ class TimingsCommand extends VanillaCommand{
/** @var string */ /** @var string */
private $host; private $host;
/**
* @param string[] $data
* @phpstan-param array<string, string> $data
*/
public function __construct(CommandSender $sender, string $host, string $agent, array $data){ public function __construct(CommandSender $sender, string $host, string $agent, array $data){
parent::__construct([ parent::__construct([
["page" => "https://$host?upload=true", "extraOpts" => [ [
CURLOPT_HTTPHEADER => [ "page" => "https://$host?upload=true",
"User-Agent: $agent", "extraOpts" => [
"Content-Type: application/x-www-form-urlencoded" CURLOPT_HTTPHEADER => [
], "User-Agent: $agent",
CURLOPT_POST => true, "Content-Type: application/x-www-form-urlencoded"
CURLOPT_POSTFIELDS => http_build_query($data), ],
CURLOPT_AUTOREFERER => false, CURLOPT_POST => true,
CURLOPT_FOLLOWLOCATION => false CURLOPT_POSTFIELDS => http_build_query($data),
]] CURLOPT_AUTOREFERER => false,
CURLOPT_FOLLOWLOCATION => false
]
]
], $sender); ], $sender);
$this->host = $host; $this->host = $host;
} }

View File

@ -21,10 +21,8 @@
declare(strict_types=1); declare(strict_types=1);
namespace pocketmine\command\defaults; namespace pocketmine\command\defaults;
use pocketmine\command\CommandSender; use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\Player; use pocketmine\Player;

View File

@ -36,12 +36,7 @@ abstract class VanillaCommand extends Command{
public const MIN_COORD = -30000000; public const MIN_COORD = -30000000;
/** /**
* @param CommandSender $sender
* @param mixed $value * @param mixed $value
* @param int $min
* @param int $max
*
* @return int
*/ */
protected function getInteger(CommandSender $sender, $value, int $min = self::MIN_COORD, int $max = self::MAX_COORD) : int{ protected function getInteger(CommandSender $sender, $value, int $min = self::MIN_COORD, int $max = self::MAX_COORD) : int{
$i = (int) $value; $i = (int) $value;
@ -55,15 +50,6 @@ abstract class VanillaCommand extends Command{
return $i; return $i;
} }
/**
* @param float $original
* @param CommandSender $sender
* @param string $input
* @param float $min
* @param float $max
*
* @return float
*/
protected function getRelativeDouble(float $original, CommandSender $sender, string $input, float $min = self::MIN_COORD, float $max = self::MAX_COORD) : float{ protected function getRelativeDouble(float $original, CommandSender $sender, string $input, float $min = self::MIN_COORD, float $max = self::MAX_COORD) : float{
if($input[0] === "~"){ if($input[0] === "~"){
$value = $this->getDouble($sender, substr($input, 1)); $value = $this->getDouble($sender, substr($input, 1));
@ -75,12 +61,7 @@ abstract class VanillaCommand extends Command{
} }
/** /**
* @param CommandSender $sender
* @param mixed $value * @param mixed $value
* @param float $min
* @param float $max
*
* @return float
*/ */
protected function getDouble(CommandSender $sender, $value, float $min = self::MIN_COORD, float $max = self::MAX_COORD) : float{ protected function getDouble(CommandSender $sender, $value, float $min = self::MIN_COORD, float $max = self::MAX_COORD) : float{
$i = (double) $value; $i = (double) $value;

View File

@ -23,7 +23,6 @@ declare(strict_types=1);
namespace pocketmine\entity; namespace pocketmine\entity;
interface Ageable{ interface Ageable{
public function isBaby() : bool; public function isBaby() : bool;
} }

View File

@ -23,7 +23,6 @@ declare(strict_types=1);
namespace pocketmine\entity; namespace pocketmine\entity;
abstract class Animal extends Creature implements Ageable{ abstract class Animal extends Creature implements Ageable{
public function isBaby() : bool{ public function isBaby() : bool{

View File

@ -87,15 +87,6 @@ class Attribute{
} }
/** /**
* @param int $id
* @param string $name
* @param float $minValue
* @param float $maxValue
* @param float $defaultValue
* @param bool $shouldSend
*
* @return Attribute
*
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public static function addAttribute(int $id, string $name, float $minValue, float $maxValue, float $defaultValue, bool $shouldSend = true) : Attribute{ public static function addAttribute(int $id, string $name, float $minValue, float $maxValue, float $defaultValue, bool $shouldSend = true) : Attribute{
@ -106,20 +97,10 @@ class Attribute{
return self::$attributes[$id] = new Attribute($id, $name, $minValue, $maxValue, $defaultValue, $shouldSend); return self::$attributes[$id] = new Attribute($id, $name, $minValue, $maxValue, $defaultValue, $shouldSend);
} }
/**
* @param int $id
*
* @return Attribute|null
*/
public static function getAttribute(int $id) : ?Attribute{ public static function getAttribute(int $id) : ?Attribute{
return isset(self::$attributes[$id]) ? clone self::$attributes[$id] : null; return isset(self::$attributes[$id]) ? clone self::$attributes[$id] : null;
} }
/**
* @param string $name
*
* @return Attribute|null
*/
public static function getAttributeByName(string $name) : ?Attribute{ public static function getAttributeByName(string $name) : ?Attribute{
foreach(self::$attributes as $a){ foreach(self::$attributes as $a){
if($a->getName() === $name){ if($a->getName() === $name){
@ -146,8 +127,6 @@ class Attribute{
} }
/** /**
* @param float $minValue
*
* @return $this * @return $this
*/ */
public function setMinValue(float $minValue){ public function setMinValue(float $minValue){
@ -167,8 +146,6 @@ class Attribute{
} }
/** /**
* @param float $maxValue
*
* @return $this * @return $this
*/ */
public function setMaxValue(float $maxValue){ public function setMaxValue(float $maxValue){
@ -188,8 +165,6 @@ class Attribute{
} }
/** /**
* @param float $defaultValue
*
* @return $this * @return $this
*/ */
public function setDefaultValue(float $defaultValue){ public function setDefaultValue(float $defaultValue){
@ -213,10 +188,6 @@ class Attribute{
} }
/** /**
* @param float $value
* @param bool $fit
* @param bool $forceSend
*
* @return $this * @return $this
*/ */
public function setValue(float $value, bool $fit = false, bool $forceSend = false){ public function setValue(float $value, bool $fit = false, bool $forceSend = false){

View File

@ -36,11 +36,6 @@ class AttributeMap implements \ArrayAccess{
$this->attributes[$attribute->getId()] = $attribute; $this->attributes[$attribute->getId()] = $attribute;
} }
/**
* @param int $id
*
* @return Attribute|null
*/
public function getAttribute(int $id) : ?Attribute{ public function getAttribute(int $id) : ?Attribute{
return $this->attributes[$id] ?? null; return $this->attributes[$id] ?? null;
} }
@ -56,15 +51,13 @@ class AttributeMap implements \ArrayAccess{
* @return Attribute[] * @return Attribute[]
*/ */
public function needSend() : array{ public function needSend() : array{
return array_filter($this->attributes, function(Attribute $attribute){ return array_filter($this->attributes, function(Attribute $attribute) : bool{
return $attribute->isSyncable() and $attribute->isDesynchronized(); return $attribute->isSyncable() and $attribute->isDesynchronized();
}); });
} }
/** /**
* @param int $offset * @param int $offset
*
* @return bool
*/ */
public function offsetExists($offset) : bool{ public function offsetExists($offset) : bool{
return isset($this->attributes[$offset]); return isset($this->attributes[$offset]);
@ -72,18 +65,19 @@ class AttributeMap implements \ArrayAccess{
/** /**
* @param int $offset * @param int $offset
*
* @return float
*/ */
public function offsetGet($offset) : float{ public function offsetGet($offset) : float{
return $this->attributes[$offset]->getValue(); return $this->attributes[$offset]->getValue();
} }
/** /**
* @param int $offset * @param int|null $offset
* @param float $value * @param float $value
*/ */
public function offsetSet($offset, $value) : void{ public function offsetSet($offset, $value) : void{
if($offset === null){
throw new \InvalidArgumentException("Array push syntax is not supported");
}
$this->attributes[$offset]->setValue($value); $this->attributes[$offset]->setValue($value);
} }

View File

@ -23,7 +23,6 @@ declare(strict_types=1);
namespace pocketmine\entity; namespace pocketmine\entity;
abstract class Creature extends Living{ abstract class Creature extends Living{
} }

View File

@ -23,7 +23,6 @@ declare(strict_types=1);
namespace pocketmine\entity; namespace pocketmine\entity;
interface Damageable{ interface Damageable{
} }

View File

@ -32,112 +32,68 @@ use function is_string;
class DataPropertyManager{ class DataPropertyManager{
/** @var mixed[][] */ /**
* @var mixed[][]
* @phpstan-var array<int, array{0: int, 1: mixed}>
*/
private $properties = []; private $properties = [];
/** @var mixed[][] */ /**
* @var mixed[][]
* @phpstan-var array<int, array{0: int, 1: mixed}>
*/
private $dirtyProperties = []; private $dirtyProperties = [];
public function __construct(){ public function __construct(){
} }
/**
* @param int $key
*
* @return int|null
*/
public function getByte(int $key) : ?int{ public function getByte(int $key) : ?int{
$value = $this->getPropertyValue($key, Entity::DATA_TYPE_BYTE); $value = $this->getPropertyValue($key, Entity::DATA_TYPE_BYTE);
assert(is_int($value) or $value === null); assert(is_int($value) or $value === null);
return $value; return $value;
} }
/**
* @param int $key
* @param int $value
* @param bool $force
*/
public function setByte(int $key, int $value, bool $force = false) : void{ public function setByte(int $key, int $value, bool $force = false) : void{
$this->setPropertyValue($key, Entity::DATA_TYPE_BYTE, $value, $force); $this->setPropertyValue($key, Entity::DATA_TYPE_BYTE, $value, $force);
} }
/**
* @param int $key
*
* @return int|null
*/
public function getShort(int $key) : ?int{ public function getShort(int $key) : ?int{
$value = $this->getPropertyValue($key, Entity::DATA_TYPE_SHORT); $value = $this->getPropertyValue($key, Entity::DATA_TYPE_SHORT);
assert(is_int($value) or $value === null); assert(is_int($value) or $value === null);
return $value; return $value;
} }
/**
* @param int $key
* @param int $value
* @param bool $force
*/
public function setShort(int $key, int $value, bool $force = false) : void{ public function setShort(int $key, int $value, bool $force = false) : void{
$this->setPropertyValue($key, Entity::DATA_TYPE_SHORT, $value, $force); $this->setPropertyValue($key, Entity::DATA_TYPE_SHORT, $value, $force);
} }
/**
* @param int $key
*
* @return int|null
*/
public function getInt(int $key) : ?int{ public function getInt(int $key) : ?int{
$value = $this->getPropertyValue($key, Entity::DATA_TYPE_INT); $value = $this->getPropertyValue($key, Entity::DATA_TYPE_INT);
assert(is_int($value) or $value === null); assert(is_int($value) or $value === null);
return $value; return $value;
} }
/**
* @param int $key
* @param int $value
* @param bool $force
*/
public function setInt(int $key, int $value, bool $force = false) : void{ public function setInt(int $key, int $value, bool $force = false) : void{
$this->setPropertyValue($key, Entity::DATA_TYPE_INT, $value, $force); $this->setPropertyValue($key, Entity::DATA_TYPE_INT, $value, $force);
} }
/**
* @param int $key
*
* @return float|null
*/
public function getFloat(int $key) : ?float{ public function getFloat(int $key) : ?float{
$value = $this->getPropertyValue($key, Entity::DATA_TYPE_FLOAT); $value = $this->getPropertyValue($key, Entity::DATA_TYPE_FLOAT);
assert(is_float($value) or $value === null); assert(is_float($value) or $value === null);
return $value; return $value;
} }
/**
* @param int $key
* @param float $value
* @param bool $force
*/
public function setFloat(int $key, float $value, bool $force = false) : void{ public function setFloat(int $key, float $value, bool $force = false) : void{
$this->setPropertyValue($key, Entity::DATA_TYPE_FLOAT, $value, $force); $this->setPropertyValue($key, Entity::DATA_TYPE_FLOAT, $value, $force);
} }
/**
* @param int $key
*
* @return null|string
*/
public function getString(int $key) : ?string{ public function getString(int $key) : ?string{
$value = $this->getPropertyValue($key, Entity::DATA_TYPE_STRING); $value = $this->getPropertyValue($key, Entity::DATA_TYPE_STRING);
assert(is_string($value) or $value === null); assert(is_string($value) or $value === null);
return $value; return $value;
} }
/**
* @param int $key
* @param string $value
* @param bool $force
*/
public function setString(int $key, string $value, bool $force = false) : void{ public function setString(int $key, string $value, bool $force = false) : void{
$this->setPropertyValue($key, Entity::DATA_TYPE_STRING, $value, $force); $this->setPropertyValue($key, Entity::DATA_TYPE_STRING, $value, $force);
} }
@ -152,87 +108,44 @@ class DataPropertyManager{
$this->setPropertyValue($key, Entity::DATA_TYPE_COMPOUND_TAG, $value, $force); $this->setPropertyValue($key, Entity::DATA_TYPE_COMPOUND_TAG, $value, $force);
} }
/**
* @param int $key
*
* @return null|Vector3
*/
public function getBlockPos(int $key) : ?Vector3{ public function getBlockPos(int $key) : ?Vector3{
$value = $this->getPropertyValue($key, Entity::DATA_TYPE_POS); $value = $this->getPropertyValue($key, Entity::DATA_TYPE_POS);
assert($value instanceof Vector3 or $value === null); assert($value instanceof Vector3 or $value === null);
return $value; return $value;
} }
/**
* @param int $key
* @param null|Vector3 $value
* @param bool $force
*/
public function setBlockPos(int $key, ?Vector3 $value, bool $force = false) : void{ public function setBlockPos(int $key, ?Vector3 $value, bool $force = false) : void{
$this->setPropertyValue($key, Entity::DATA_TYPE_POS, $value ? $value->floor() : null, $force); $this->setPropertyValue($key, Entity::DATA_TYPE_POS, $value !== null ? $value->floor() : null, $force);
} }
/**
* @param int $key
*
* @return int|null
*/
public function getLong(int $key) : ?int{ public function getLong(int $key) : ?int{
$value = $this->getPropertyValue($key, Entity::DATA_TYPE_LONG); $value = $this->getPropertyValue($key, Entity::DATA_TYPE_LONG);
assert(is_int($value) or $value === null); assert(is_int($value) or $value === null);
return $value; return $value;
} }
/**
* @param int $key
* @param int $value
* @param bool $force
*/
public function setLong(int $key, int $value, bool $force = false) : void{ public function setLong(int $key, int $value, bool $force = false) : void{
$this->setPropertyValue($key, Entity::DATA_TYPE_LONG, $value, $force); $this->setPropertyValue($key, Entity::DATA_TYPE_LONG, $value, $force);
} }
/**
* @param int $key
*
* @return null|Vector3
*/
public function getVector3(int $key) : ?Vector3{ public function getVector3(int $key) : ?Vector3{
$value = $this->getPropertyValue($key, Entity::DATA_TYPE_VECTOR3F); $value = $this->getPropertyValue($key, Entity::DATA_TYPE_VECTOR3F);
assert($value instanceof Vector3 or $value === null); assert($value instanceof Vector3 or $value === null);
return $value; return $value;
} }
/**
* @param int $key
* @param null|Vector3 $value
* @param bool $force
*/
public function setVector3(int $key, ?Vector3 $value, bool $force = false) : void{ public function setVector3(int $key, ?Vector3 $value, bool $force = false) : void{
$this->setPropertyValue($key, Entity::DATA_TYPE_VECTOR3F, $value ? $value->asVector3() : null, $force); $this->setPropertyValue($key, Entity::DATA_TYPE_VECTOR3F, $value !== null ? $value->asVector3() : null, $force);
} }
/**
* @param int $key
*/
public function removeProperty(int $key) : void{ public function removeProperty(int $key) : void{
unset($this->properties[$key]); unset($this->properties[$key]);
} }
/**
* @param int $key
*
* @return bool
*/
public function hasProperty(int $key) : bool{ public function hasProperty(int $key) : bool{
return isset($this->properties[$key]); return isset($this->properties[$key]);
} }
/**
* @param int $key
*
* @return int
*/
public function getPropertyType(int $key) : int{ public function getPropertyType(int $key) : int{
if(isset($this->properties[$key])){ if(isset($this->properties[$key])){
return $this->properties[$key][0]; return $this->properties[$key][0];
@ -248,9 +161,6 @@ class DataPropertyManager{
} }
/** /**
* @param int $key
* @param int $type
*
* @return mixed * @return mixed
*/ */
public function getPropertyValue(int $key, int $type){ public function getPropertyValue(int $key, int $type){
@ -261,10 +171,7 @@ class DataPropertyManager{
} }
/** /**
* @param int $key
* @param int $type
* @param mixed $value * @param mixed $value
* @param bool $force
*/ */
public function setPropertyValue(int $key, int $type, $value, bool $force = false) : void{ public function setPropertyValue(int $key, int $type, $value, bool $force = false) : void{
if(!$force){ if(!$force){
@ -276,7 +183,8 @@ class DataPropertyManager{
/** /**
* Returns all properties. * Returns all properties.
* *
* @return array * @return mixed[][]
* @phpstan-return array<int, array{0: int, 1: mixed}>
*/ */
public function getAll() : array{ public function getAll() : array{
return $this->properties; return $this->properties;
@ -285,7 +193,8 @@ class DataPropertyManager{
/** /**
* Returns properties that have changed and need to be broadcasted. * Returns properties that have changed and need to be broadcasted.
* *
* @return array * @return mixed[][]
* @phpstan-return array<int, array{0: int, 1: mixed}>
*/ */
public function getDirty() : array{ public function getDirty() : array{
return $this->dirtyProperties; return $this->dirtyProperties;

View File

@ -93,27 +93,14 @@ class Effect{
self::registerEffect(new Effect(Effect::CONDUIT_POWER, "%potion.conduitPower", new Color(0x1d, 0xc2, 0xd1))); self::registerEffect(new Effect(Effect::CONDUIT_POWER, "%potion.conduitPower", new Color(0x1d, 0xc2, 0xd1)));
} }
/**
* @param Effect $effect
*/
public static function registerEffect(Effect $effect) : void{ public static function registerEffect(Effect $effect) : void{
self::$effects[$effect->getId()] = $effect; self::$effects[$effect->getId()] = $effect;
} }
/**
* @param int $id
*
* @return Effect|null
*/
public static function getEffect(int $id) : ?Effect{ public static function getEffect(int $id) : ?Effect{
return self::$effects[$id] ?? null; return self::$effects[$id] ?? null;
} }
/**
* @param string $name
*
* @return Effect|null
*/
public static function getEffectByName(string $name) : ?Effect{ public static function getEffectByName(string $name) : ?Effect{
$const = self::class . "::" . strtoupper($name); $const = self::class . "::" . strtoupper($name);
if(defined($const)){ if(defined($const)){
@ -138,7 +125,7 @@ class Effect{
/** /**
* @param int $id Effect ID as per Minecraft PE * @param int $id Effect ID as per Minecraft PE
* @param string $name Translation key used for effect name * @param string $name Translation key used for effect name
* @param Color $color * @param Color $color Color of bubbles given by this effect
* @param bool $isBad Whether the effect is harmful * @param bool $isBad Whether the effect is harmful
* @param int $defaultDuration Duration in ticks the effect will last for by default if applied without a duration. * @param int $defaultDuration Duration in ticks the effect will last for by default if applied without a duration.
* @param bool $hasBubbles Whether the effect has potion bubbles. Some do not (e.g. Instant Damage has its own particles instead of bubbles) * @param bool $hasBubbles Whether the effect has potion bubbles. Some do not (e.g. Instant Damage has its own particles instead of bubbles)
@ -154,7 +141,6 @@ class Effect{
/** /**
* Returns the effect ID as per Minecraft PE * Returns the effect ID as per Minecraft PE
* @return int
*/ */
public function getId() : int{ public function getId() : int{
return $this->id; return $this->id;
@ -162,7 +148,6 @@ class Effect{
/** /**
* Returns the translation key used to translate this effect's name. * Returns the translation key used to translate this effect's name.
* @return string
*/ */
public function getName() : string{ public function getName() : string{
return $this->name; return $this->name;
@ -170,7 +155,6 @@ class Effect{
/** /**
* Returns a Color object representing this effect's particle colour. * Returns a Color object representing this effect's particle colour.
* @return Color
*/ */
public function getColor() : Color{ public function getColor() : Color{
return clone $this->color; return clone $this->color;
@ -179,8 +163,6 @@ class Effect{
/** /**
* Returns whether this effect is harmful. * Returns whether this effect is harmful.
* TODO: implement inverse effect results for undead mobs * TODO: implement inverse effect results for undead mobs
*
* @return bool
*/ */
public function isBad() : bool{ public function isBad() : bool{
return $this->bad; return $this->bad;
@ -188,7 +170,6 @@ class Effect{
/** /**
* Returns whether the effect is by default an instant effect. * Returns whether the effect is by default an instant effect.
* @return bool
*/ */
public function isInstantEffect() : bool{ public function isInstantEffect() : bool{
return $this->defaultDuration <= 1; return $this->defaultDuration <= 1;
@ -196,8 +177,6 @@ class Effect{
/** /**
* Returns the default duration (in ticks) this effect will apply for if a duration is not specified. * Returns the default duration (in ticks) this effect will apply for if a duration is not specified.
*
* @return int
*/ */
public function getDefaultDuration() : int{ public function getDefaultDuration() : int{
return $this->defaultDuration; return $this->defaultDuration;
@ -205,7 +184,6 @@ class Effect{
/** /**
* Returns whether this effect will give the subject potion bubbles. * Returns whether this effect will give the subject potion bubbles.
* @return bool
*/ */
public function hasBubbles() : bool{ public function hasBubbles() : bool{
return $this->hasBubbles; return $this->hasBubbles;
@ -213,10 +191,6 @@ class Effect{
/** /**
* Returns whether the effect will do something on the current tick. * Returns whether the effect will do something on the current tick.
*
* @param EffectInstance $instance
*
* @return bool
*/ */
public function canTick(EffectInstance $instance) : bool{ public function canTick(EffectInstance $instance) : bool{
switch($this->id){ switch($this->id){
@ -249,12 +223,6 @@ class Effect{
/** /**
* Applies effect results to an entity. This will not be called unless canTick() returns true. * Applies effect results to an entity. This will not be called unless canTick() returns true.
*
* @param Living $entity
* @param EffectInstance $instance
* @param float $potency
* @param null|Entity $source
* @param null|Entity $sourceOwner
*/ */
public function applyEffect(Living $entity, EffectInstance $instance, float $potency = 1.0, ?Entity $source = null, ?Entity $sourceOwner = null) : void{ public function applyEffect(Living $entity, EffectInstance $instance, float $potency = 1.0, ?Entity $source = null, ?Entity $sourceOwner = null) : void{
switch($this->id){ switch($this->id){
@ -315,9 +283,6 @@ class Effect{
/** /**
* Applies effects to the entity when the effect is first added. * Applies effects to the entity when the effect is first added.
*
* @param Living $entity
* @param EffectInstance $instance
*/ */
public function add(Living $entity, EffectInstance $instance) : void{ public function add(Living $entity, EffectInstance $instance) : void{
switch($this->id){ switch($this->id){
@ -348,9 +313,6 @@ class Effect{
/** /**
* Removes the effect from the entity, resetting any changed values back to their original defaults. * Removes the effect from the entity, resetting any changed values back to their original defaults.
*
* @param Living $entity
* @param EffectInstance $instance
*/ */
public function remove(Living $entity, EffectInstance $instance) : void{ public function remove(Living $entity, EffectInstance $instance) : void{
switch($this->id){ switch($this->id){

View File

@ -47,12 +47,7 @@ class EffectInstance{
private $color; private $color;
/** /**
* @param Effect $effectType
* @param int|null $duration Passing null will use the effect type's default duration * @param int|null $duration Passing null will use the effect type's default duration
* @param int $amplifier
* @param bool $visible
* @param bool $ambient
* @param null|Color $overrideColor
*/ */
public function __construct(Effect $effectType, ?int $duration = null, int $amplifier = 0, bool $visible = true, bool $ambient = false, ?Color $overrideColor = null){ public function __construct(Effect $effectType, ?int $duration = null, int $amplifier = 0, bool $visible = true, bool $ambient = false, ?Color $overrideColor = null){
$this->effectType = $effectType; $this->effectType = $effectType;
@ -67,17 +62,12 @@ class EffectInstance{
return $this->effectType->getId(); return $this->effectType->getId();
} }
/**
* @return Effect
*/
public function getType() : Effect{ public function getType() : Effect{
return $this->effectType; return $this->effectType;
} }
/** /**
* Returns the number of ticks remaining until the effect expires. * Returns the number of ticks remaining until the effect expires.
*
* @return int
*/ */
public function getDuration() : int{ public function getDuration() : int{
return $this->duration; return $this->duration;
@ -86,8 +76,6 @@ class EffectInstance{
/** /**
* Sets the number of ticks remaining until the effect expires. * Sets the number of ticks remaining until the effect expires.
* *
* @param int $duration
*
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
* *
* @return $this * @return $this
@ -104,8 +92,6 @@ class EffectInstance{
/** /**
* Decreases the duration by the given number of ticks, without dropping below zero. * Decreases the duration by the given number of ticks, without dropping below zero.
* *
* @param int $ticks
*
* @return $this * @return $this
*/ */
public function decreaseDuration(int $ticks) : EffectInstance{ public function decreaseDuration(int $ticks) : EffectInstance{
@ -116,32 +102,23 @@ class EffectInstance{
/** /**
* Returns whether the duration has run out. * Returns whether the duration has run out.
*
* @return bool
*/ */
public function hasExpired() : bool{ public function hasExpired() : bool{
return $this->duration <= 0; return $this->duration <= 0;
} }
/**
* @return int
*/
public function getAmplifier() : int{ public function getAmplifier() : int{
return $this->amplifier; return $this->amplifier;
} }
/** /**
* Returns the level of this effect, which is always one higher than the amplifier. * Returns the level of this effect, which is always one higher than the amplifier.
*
* @return int
*/ */
public function getEffectLevel() : int{ public function getEffectLevel() : int{
return $this->amplifier + 1; return $this->amplifier + 1;
} }
/** /**
* @param int $amplifier
*
* @return $this * @return $this
*/ */
public function setAmplifier(int $amplifier) : EffectInstance{ public function setAmplifier(int $amplifier) : EffectInstance{
@ -152,16 +129,12 @@ class EffectInstance{
/** /**
* Returns whether this effect will produce some visible effect, such as bubbles or particles. * Returns whether this effect will produce some visible effect, such as bubbles or particles.
*
* @return bool
*/ */
public function isVisible() : bool{ public function isVisible() : bool{
return $this->visible; return $this->visible;
} }
/** /**
* @param bool $visible
*
* @return $this * @return $this
*/ */
public function setVisible(bool $visible = true) : EffectInstance{ public function setVisible(bool $visible = true) : EffectInstance{
@ -174,16 +147,12 @@ class EffectInstance{
* Returns whether the effect originated from the ambient environment. * Returns whether the effect originated from the ambient environment.
* Ambient effects can originate from things such as a Beacon's area of effect radius. * Ambient effects can originate from things such as a Beacon's area of effect radius.
* If this flag is set, the amount of visible particles will be reduced by a factor of 5. * If this flag is set, the amount of visible particles will be reduced by a factor of 5.
*
* @return bool
*/ */
public function isAmbient() : bool{ public function isAmbient() : bool{
return $this->ambient; return $this->ambient;
} }
/** /**
* @param bool $ambient
*
* @return $this * @return $this
*/ */
public function setAmbient(bool $ambient = true) : EffectInstance{ public function setAmbient(bool $ambient = true) : EffectInstance{
@ -195,8 +164,6 @@ class EffectInstance{
/** /**
* Returns the particle colour of this effect instance. This can be overridden on a per-EffectInstance basis, so it * Returns the particle colour of this effect instance. This can be overridden on a per-EffectInstance basis, so it
* is not reflective of the default colour of the effect. * is not reflective of the default colour of the effect.
*
* @return Color
*/ */
public function getColor() : Color{ public function getColor() : Color{
return clone $this->color; return clone $this->color;
@ -204,10 +171,6 @@ class EffectInstance{
/** /**
* Sets the colour of this EffectInstance. * Sets the colour of this EffectInstance.
*
* @param Color $color
*
* @return EffectInstance
*/ */
public function setColor(Color $color) : EffectInstance{ public function setColor(Color $color) : EffectInstance{
$this->color = clone $color; $this->color = clone $color;
@ -217,8 +180,6 @@ class EffectInstance{
/** /**
* Resets the colour of this EffectInstance to the default specified by its type. * Resets the colour of this EffectInstance to the default specified by its type.
*
* @return EffectInstance
*/ */
public function resetColor() : EffectInstance{ public function resetColor() : EffectInstance{
$this->color = $this->effectType->getColor(); $this->color = $this->effectType->getColor();

View File

@ -297,11 +297,11 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
public const DATA_FLAG_OVER_SCAFFOLDING = 69; public const DATA_FLAG_OVER_SCAFFOLDING = 69;
public const DATA_FLAG_FALL_THROUGH_SCAFFOLDING = 70; public const DATA_FLAG_FALL_THROUGH_SCAFFOLDING = 70;
public const DATA_FLAG_BLOCKING = 71; //shield public const DATA_FLAG_BLOCKING = 71; //shield
public const DATA_FLAG_DISABLE_BLOCKING = 72; public const DATA_FLAG_TRANSITION_BLOCKING = 72;
//73 is set when a player is attacked while using shield, unclear on purpose public const DATA_FLAG_BLOCKED_USING_SHIELD = 73;
//74 related to shield usage, needs further investigation public const DATA_FLAG_BLOCKED_USING_DAMAGED_SHIELD = 74;
public const DATA_FLAG_SLEEPING = 75; public const DATA_FLAG_SLEEPING = 75;
//76 related to sleeping, unclear usage public const DATA_FLAG_WANTS_TO_WAKE = 76;
public const DATA_FLAG_TRADE_INTEREST = 77; public const DATA_FLAG_TRADE_INTEREST = 77;
public const DATA_FLAG_DOOR_BREAKER = 78; //... public const DATA_FLAG_DOOR_BREAKER = 78; //...
public const DATA_FLAG_BREAKING_OBSTRUCTION = 79; public const DATA_FLAG_BREAKING_OBSTRUCTION = 79;
@ -311,17 +311,27 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
public const DATA_FLAG_ROARING = 83; public const DATA_FLAG_ROARING = 83;
public const DATA_FLAG_DELAYED_ATTACKING = 84; public const DATA_FLAG_DELAYED_ATTACKING = 84;
public const DATA_FLAG_AVOIDING_MOBS = 85; public const DATA_FLAG_AVOIDING_MOBS = 85;
//86 used by RangedAttackGoal public const DATA_FLAG_FACING_TARGET_TO_RANGE_ATTACK = 86;
//87 used by NearestAttackableTargetGoal public const DATA_FLAG_HIDDEN_WHEN_INVISIBLE = 87; //??????????????????
public const DATA_FLAG_IS_IN_UI = 88;
public const DATA_FLAG_STALKING = 89;
public const DATA_FLAG_EMOTING = 90;
public const DATA_FLAG_CELEBRATING = 91;
public const DATA_PLAYER_FLAG_SLEEP = 1; public const DATA_PLAYER_FLAG_SLEEP = 1;
public const DATA_PLAYER_FLAG_DEAD = 2; //TODO: CHECK public const DATA_PLAYER_FLAG_DEAD = 2; //TODO: CHECK
/** @var int */ /** @var int */
public static $entityCount = 1; public static $entityCount = 1;
/** @var string[] */ /**
* @var string[]
* @phpstan-var array<int|string, class-string<Entity>>
*/
private static $knownEntities = []; private static $knownEntities = [];
/** @var string[][] */ /**
* @var string[][]
* @phpstan-var array<class-string<Entity>, list<string>>
*/
private static $saveNames = []; private static $saveNames = [];
/** /**
@ -353,17 +363,12 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
PaintingMotive::init(); PaintingMotive::init();
} }
/** /**
* Creates an entity with the specified type, level and NBT, with optional additional arguments to pass to the * Creates an entity with the specified type, level and NBT, with optional additional arguments to pass to the
* entity's constructor * entity's constructor
* *
* @param int|string $type * @param int|string $type
* @param Level $level
* @param CompoundTag $nbt
* @param mixed ...$args * @param mixed ...$args
*
* @return Entity|null
*/ */
public static function createEntity($type, Level $level, CompoundTag $nbt, ...$args) : ?Entity{ public static function createEntity($type, Level $level, CompoundTag $nbt, ...$args) : ?Entity{
if(isset(self::$knownEntities[$type])){ if(isset(self::$knownEntities[$type])){
@ -381,15 +386,12 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
* @param string $className Class that extends Entity * @param string $className Class that extends Entity
* @param bool $force Force registration even if the entity does not have a valid network ID * @param bool $force Force registration even if the entity does not have a valid network ID
* @param string[] $saveNames An array of save names which this entity might be saved under. Defaults to the short name of the class itself if empty. * @param string[] $saveNames An array of save names which this entity might be saved under. Defaults to the short name of the class itself if empty.
* @phpstan-param class-string<Entity> $className
* *
* NOTE: The first save name in the $saveNames array will be used when saving the entity to disk. The reflection * NOTE: The first save name in the $saveNames array will be used when saving the entity to disk. The reflection
* name of the class will be appended to the end and only used if no other save names are specified. * name of the class will be appended to the end and only used if no other save names are specified.
*
* @return bool
*/ */
public static function registerEntity(string $className, bool $force = false, array $saveNames = []) : bool{ public static function registerEntity(string $className, bool $force = false, array $saveNames = []) : bool{
/** @var Entity $className */
$class = new \ReflectionClass($className); $class = new \ReflectionClass($className);
if(is_a($className, Entity::class, true) and !$class->isAbstract()){ if(is_a($className, Entity::class, true) and !$class->isAbstract()){
if($className::NETWORK_ID !== -1){ if($className::NETWORK_ID !== -1){
@ -417,13 +419,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
/** /**
* Helper function which creates minimal NBT needed to spawn an entity. * Helper function which creates minimal NBT needed to spawn an entity.
*
* @param Vector3 $pos
* @param Vector3|null $motion
* @param float $yaw
* @param float $pitch
*
* @return CompoundTag
*/ */
public static function createBaseNBT(Vector3 $pos, ?Vector3 $motion = null, float $yaw = 0.0, float $pitch = 0.0) : CompoundTag{ public static function createBaseNBT(Vector3 $pos, ?Vector3 $motion = null, float $yaw = 0.0, float $pitch = 0.0) : CompoundTag{
return new CompoundTag("", [ return new CompoundTag("", [
@ -433,9 +428,9 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
new DoubleTag("", $pos->z) new DoubleTag("", $pos->z)
]), ]),
new ListTag("Motion", [ new ListTag("Motion", [
new DoubleTag("", $motion ? $motion->x : 0.0), new DoubleTag("", $motion !== null ? $motion->x : 0.0),
new DoubleTag("", $motion ? $motion->y : 0.0), new DoubleTag("", $motion !== null ? $motion->y : 0.0),
new DoubleTag("", $motion ? $motion->z : 0.0) new DoubleTag("", $motion !== null ? $motion->z : 0.0)
]), ]),
new ListTag("Rotation", [ new ListTag("Rotation", [
new FloatTag("", $yaw), new FloatTag("", $yaw),
@ -444,9 +439,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
]); ]);
} }
/** /** @var Player[] */
* @var Player[]
*/
protected $hasSpawned = []; protected $hasSpawned = [];
/** @var int */ /** @var int */
@ -481,7 +474,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
/** @var Vector3 */ /** @var Vector3 */
public $temporalVector; public $temporalVector;
/** @var float */ /** @var float */
public $lastYaw; public $lastYaw;
/** @var float */ /** @var float */
@ -652,73 +644,42 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
} }
/**
* @return string
*/
public function getNameTag() : string{ public function getNameTag() : string{
return $this->propertyManager->getString(self::DATA_NAMETAG); return $this->propertyManager->getString(self::DATA_NAMETAG);
} }
/**
* @return bool
*/
public function isNameTagVisible() : bool{ public function isNameTagVisible() : bool{
return $this->getGenericFlag(self::DATA_FLAG_CAN_SHOW_NAMETAG); return $this->getGenericFlag(self::DATA_FLAG_CAN_SHOW_NAMETAG);
} }
/**
* @return bool
*/
public function isNameTagAlwaysVisible() : bool{ public function isNameTagAlwaysVisible() : bool{
return $this->propertyManager->getByte(self::DATA_ALWAYS_SHOW_NAMETAG) === 1; return $this->propertyManager->getByte(self::DATA_ALWAYS_SHOW_NAMETAG) === 1;
} }
/**
* @param string $name
*/
public function setNameTag(string $name) : void{ public function setNameTag(string $name) : void{
$this->propertyManager->setString(self::DATA_NAMETAG, $name); $this->propertyManager->setString(self::DATA_NAMETAG, $name);
} }
/**
* @param bool $value
*/
public function setNameTagVisible(bool $value = true) : void{ public function setNameTagVisible(bool $value = true) : void{
$this->setGenericFlag(self::DATA_FLAG_CAN_SHOW_NAMETAG, $value); $this->setGenericFlag(self::DATA_FLAG_CAN_SHOW_NAMETAG, $value);
} }
/**
* @param bool $value
*/
public function setNameTagAlwaysVisible(bool $value = true) : void{ public function setNameTagAlwaysVisible(bool $value = true) : void{
$this->propertyManager->setByte(self::DATA_ALWAYS_SHOW_NAMETAG, $value ? 1 : 0); $this->propertyManager->setByte(self::DATA_ALWAYS_SHOW_NAMETAG, $value ? 1 : 0);
} }
/**
* @return string|null
*/
public function getScoreTag() : ?string{ public function getScoreTag() : ?string{
return $this->propertyManager->getString(self::DATA_SCORE_TAG); return $this->propertyManager->getString(self::DATA_SCORE_TAG);
} }
/**
* @param string $score
*/
public function setScoreTag(string $score) : void{ public function setScoreTag(string $score) : void{
$this->propertyManager->setString(self::DATA_SCORE_TAG, $score); $this->propertyManager->setString(self::DATA_SCORE_TAG, $score);
} }
/**
* @return float
*/
public function getScale() : float{ public function getScale() : float{
return $this->propertyManager->getFloat(self::DATA_SCALE); return $this->propertyManager->getFloat(self::DATA_SCALE);
} }
/**
* @param float $value
*/
public function setScale(float $value) : void{ public function setScale(float $value) : void{
if($value <= 0){ if($value <= 0){
throw new \InvalidArgumentException("Scale must be greater than 0"); throw new \InvalidArgumentException("Scale must be greater than 0");
@ -789,7 +750,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
/** /**
* Returns whether the entity is able to climb blocks such as ladders or vines. * Returns whether the entity is able to climb blocks such as ladders or vines.
* @return bool
*/ */
public function canClimb() : bool{ public function canClimb() : bool{
return $this->getGenericFlag(self::DATA_FLAG_CAN_CLIMB); return $this->getGenericFlag(self::DATA_FLAG_CAN_CLIMB);
@ -797,8 +757,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
/** /**
* Sets whether the entity is able to climb climbable blocks. * Sets whether the entity is able to climb climbable blocks.
*
* @param bool $value
*/ */
public function setCanClimb(bool $value = true) : void{ public function setCanClimb(bool $value = true) : void{
$this->setGenericFlag(self::DATA_FLAG_CAN_CLIMB, $value); $this->setGenericFlag(self::DATA_FLAG_CAN_CLIMB, $value);
@ -806,8 +764,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
/** /**
* Returns whether this entity is climbing a block. By default this is only true if the entity is climbing a ladder or vine or similar block. * Returns whether this entity is climbing a block. By default this is only true if the entity is climbing a ladder or vine or similar block.
*
* @return bool
*/ */
public function canClimbWalls() : bool{ public function canClimbWalls() : bool{
return $this->getGenericFlag(self::DATA_FLAG_WALLCLIMBING); return $this->getGenericFlag(self::DATA_FLAG_WALLCLIMBING);
@ -815,8 +771,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
/** /**
* Sets whether the entity is climbing a block. If true, the entity can climb anything. * Sets whether the entity is climbing a block. If true, the entity can climb anything.
*
* @param bool $value
*/ */
public function setCanClimbWalls(bool $value = true) : void{ public function setCanClimbWalls(bool $value = true) : void{
$this->setGenericFlag(self::DATA_FLAG_WALLCLIMBING, $value); $this->setGenericFlag(self::DATA_FLAG_WALLCLIMBING, $value);
@ -824,7 +778,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
/** /**
* Returns the entity ID of the owning entity, or null if the entity doesn't have an owner. * Returns the entity ID of the owning entity, or null if the entity doesn't have an owner.
* @return int|null
*/ */
public function getOwningEntityId() : ?int{ public function getOwningEntityId() : ?int{
return $this->propertyManager->getLong(self::DATA_OWNER_EID); return $this->propertyManager->getLong(self::DATA_OWNER_EID);
@ -832,7 +785,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
/** /**
* Returns the owning entity, or null if the entity was not found. * Returns the owning entity, or null if the entity was not found.
* @return Entity|null
*/ */
public function getOwningEntity() : ?Entity{ public function getOwningEntity() : ?Entity{
$eid = $this->getOwningEntityId(); $eid = $this->getOwningEntityId();
@ -846,8 +798,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
/** /**
* Sets the owner of the entity. Passing null will remove the current owner. * Sets the owner of the entity. Passing null will remove the current owner.
* *
* @param Entity|null $owner
*
* @throws \InvalidArgumentException if the supplied entity is not valid * @throws \InvalidArgumentException if the supplied entity is not valid
*/ */
public function setOwningEntity(?Entity $owner) : void{ public function setOwningEntity(?Entity $owner) : void{
@ -862,7 +812,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
/** /**
* Returns the entity ID of the entity's target, or null if it doesn't have a target. * Returns the entity ID of the entity's target, or null if it doesn't have a target.
* @return int|null
*/ */
public function getTargetEntityId() : ?int{ public function getTargetEntityId() : ?int{
return $this->propertyManager->getLong(self::DATA_TARGET_EID); return $this->propertyManager->getLong(self::DATA_TARGET_EID);
@ -871,8 +820,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
/** /**
* Returns the entity's target entity, or null if not found. * Returns the entity's target entity, or null if not found.
* This is used for things like hostile mobs attacking entities, and for fishing rods reeling hit entities in. * This is used for things like hostile mobs attacking entities, and for fishing rods reeling hit entities in.
*
* @return Entity|null
*/ */
public function getTargetEntity() : ?Entity{ public function getTargetEntity() : ?Entity{
$eid = $this->getTargetEntityId(); $eid = $this->getTargetEntityId();
@ -886,8 +833,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
/** /**
* Sets the entity's target entity. Passing null will remove the current target. * Sets the entity's target entity. Passing null will remove the current target.
* *
* @param Entity|null $target
*
* @throws \InvalidArgumentException if the target entity is not valid * @throws \InvalidArgumentException if the target entity is not valid
*/ */
public function setTargetEntity(?Entity $target) : void{ public function setTargetEntity(?Entity $target) : void{
@ -902,7 +847,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
/** /**
* Returns whether this entity will be saved when its chunk is unloaded. * Returns whether this entity will be saved when its chunk is unloaded.
* @return bool
*/ */
public function canSaveWithChunk() : bool{ public function canSaveWithChunk() : bool{
return $this->savedWithChunk; return $this->savedWithChunk;
@ -911,8 +855,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
/** /**
* Sets whether this entity will be saved when its chunk is unloaded. This can be used to prevent the entity being * Sets whether this entity will be saved when its chunk is unloaded. This can be used to prevent the entity being
* saved to disk. * saved to disk.
*
* @param bool $value
*/ */
public function setCanSaveWithChunk(bool $value) : void{ public function setCanSaveWithChunk(bool $value) : void{
$this->savedWithChunk = $value; $this->savedWithChunk = $value;
@ -920,8 +862,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
/** /**
* Returns the short save name * Returns the short save name
*
* @return string
*/ */
public function getSaveId() : string{ public function getSaveId() : string{
if(!isset(self::$saveNames[static::class])){ if(!isset(self::$saveNames[static::class])){
@ -968,8 +908,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
} }
protected function initEntity() : void{ protected function initEntity() : void{
assert($this->namedtag instanceof CompoundTag);
if($this->namedtag->hasTag("CustomName", StringTag::class)){ if($this->namedtag->hasTag("CustomName", StringTag::class)){
$this->setNameTag($this->namedtag->getString("CustomName")); $this->setNameTag($this->namedtag->getString("CustomName"));
@ -987,9 +925,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
} }
/**
* @param EntityDamageEvent $source
*/
public function attack(EntityDamageEvent $source) : void{ public function attack(EntityDamageEvent $source) : void{
$source->call(); $source->call();
if($source->isCancelled()){ if($source->isCancelled()){
@ -1001,9 +936,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
$this->setHealth($this->getHealth() - $source->getFinalDamage()); $this->setHealth($this->getHealth() - $source->getFinalDamage());
} }
/**
* @param EntityRegainHealthEvent $source
*/
public function heal(EntityRegainHealthEvent $source) : void{ public function heal(EntityRegainHealthEvent $source) : void{
$source->call(); $source->call();
if($source->isCancelled()){ if($source->isCancelled()){
@ -1020,10 +952,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
/** /**
* Called to tick entities while dead. Returns whether the entity should be flagged for despawn yet. * Called to tick entities while dead. Returns whether the entity should be flagged for despawn yet.
*
* @param int $tickDiff
*
* @return bool
*/ */
protected function onDeathUpdate(int $tickDiff) : bool{ protected function onDeathUpdate(int $tickDiff) : bool{
return true; return true;
@ -1033,17 +961,12 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
return $this->health > 0; return $this->health > 0;
} }
/**
* @return float
*/
public function getHealth() : float{ public function getHealth() : float{
return $this->health; return $this->health;
} }
/** /**
* Sets the health of the Entity. This won't send any update to the players * Sets the health of the Entity. This won't send any update to the players
*
* @param float $amount
*/ */
public function setHealth(float $amount) : void{ public function setHealth(float $amount) : void{
if($amount == $this->health){ if($amount == $this->health){
@ -1062,30 +985,18 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
} }
} }
/**
* @return int
*/
public function getMaxHealth() : int{ public function getMaxHealth() : int{
return $this->maxHealth; return $this->maxHealth;
} }
/**
* @param int $amount
*/
public function setMaxHealth(int $amount) : void{ public function setMaxHealth(int $amount) : void{
$this->maxHealth = $amount; $this->maxHealth = $amount;
} }
/**
* @param EntityDamageEvent $type
*/
public function setLastDamageCause(EntityDamageEvent $type) : void{ public function setLastDamageCause(EntityDamageEvent $type) : void{
$this->lastDamageCause = $type; $this->lastDamageCause = $type;
} }
/**
* @return EntityDamageEvent|null
*/
public function getLastDamageCause() : ?EntityDamageEvent{ public function getLastDamageCause() : ?EntityDamageEvent{
return $this->lastDamageCause; return $this->lastDamageCause;
} }
@ -1148,15 +1059,11 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
$this->setGenericFlag(self::DATA_FLAG_ONFIRE, $this->isOnFire()); $this->setGenericFlag(self::DATA_FLAG_ONFIRE, $this->isOnFire());
} }
/**
* @return int
*/
public function getFireTicks() : int{ public function getFireTicks() : int{
return $this->fireTicks; return $this->fireTicks;
} }
/** /**
* @param int $fireTicks
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public function setFireTicks(int $fireTicks) : void{ public function setFireTicks(int $fireTicks) : void{
@ -1397,9 +1304,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
return false; return false;
} }
/**
* @return int|null
*/
public function getDirection() : ?int{ public function getDirection() : ?int{
$rotation = ($this->yaw - 90) % 360; $rotation = ($this->yaw - 90) % 360;
if($rotation < 0){ if($rotation < 0){
@ -1418,9 +1322,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
} }
} }
/**
* @return Vector3
*/
public function getDirectionVector() : Vector3{ public function getDirectionVector() : Vector3{
$y = -sin(deg2rad($this->pitch)); $y = -sin(deg2rad($this->pitch));
$xz = cos(deg2rad($this->pitch)); $xz = cos(deg2rad($this->pitch));
@ -1458,7 +1359,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
return true; return true;
} }
$this->timings->startTiming(); $this->timings->startTiming();
if($this->hasMovementUpdate()){ if($this->hasMovementUpdate()){
@ -1487,7 +1387,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
$hasUpdate = $this->entityBaseTick($tickDiff); $hasUpdate = $this->entityBaseTick($tickDiff);
Timings::$timerEntityBaseTick->stopTiming(); Timings::$timerEntityBaseTick->stopTiming();
$this->timings->stopTiming(); $this->timings->stopTiming();
//if($this->isStatic()) //if($this->isStatic())
@ -1510,8 +1409,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
/** /**
* Flags the entity as needing a movement update on the next tick. Setting this forces a movement update even if the * Flags the entity as needing a movement update on the next tick. Setting this forces a movement update even if the
* entity's motion is zero. Used to trigger movement updates when blocks change near entities. * entity's motion is zero. Used to trigger movement updates when blocks change near entities.
*
* @param bool $value
*/ */
final public function setForceMovementUpdate(bool $value = true) : void{ final public function setForceMovementUpdate(bool $value = true) : void{
$this->forceMovementUpdate = $value; $this->forceMovementUpdate = $value;
@ -1521,7 +1418,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
/** /**
* Returns whether the entity needs a movement update on the next tick. * Returns whether the entity needs a movement update on the next tick.
* @return bool
*/ */
public function hasMovementUpdate() : bool{ public function hasMovementUpdate() : bool{
return ( return (
@ -1541,10 +1437,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
$this->fallDistance = 0.0; $this->fallDistance = 0.0;
} }
/**
* @param float $distanceThisTick
* @param bool $onGround
*/
protected function updateFallState(float $distanceThisTick, bool $onGround) : void{ protected function updateFallState(float $distanceThisTick, bool $onGround) : void{
if($onGround){ if($onGround){
if($this->fallDistance > 0){ if($this->fallDistance > 0){
@ -1558,8 +1450,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
/** /**
* Called when a falling entity hits the ground. * Called when a falling entity hits the ground.
*
* @param float $fallDistance
*/ */
public function fall(float $fallDistance) : void{ public function fall(float $fallDistance) : void{
@ -1625,7 +1515,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
$this->isCollided = $this->onGround; $this->isCollided = $this->onGround;
$this->updateFallState($dy, $this->onGround); $this->updateFallState($dy, $this->onGround);
Timings::$entityMoveTimer->stopTiming(); Timings::$entityMoveTimer->stopTiming();
return true; return true;
@ -1710,7 +1599,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
$this->boundingBox->offset(0, 0, $dz); $this->boundingBox->offset(0, 0, $dz);
if($this->stepHeight > 0 and $fallingFlag and $this->ySize < 0.05 and ($movX != $dx or $movZ != $dz)){ if($this->stepHeight > 0 and $fallingFlag and $this->ySize < 0.05 and ($movX != $dx or $movZ != $dz)){
$cx = $dx; $cx = $dx;
$cy = $dy; $cy = $dy;
@ -1823,8 +1711,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
/** /**
* Returns whether this entity can be moved by currents in liquids. * Returns whether this entity can be moved by currents in liquids.
*
* @return bool
*/ */
public function canBeMovedByCurrents() : bool{ public function canBeMovedByCurrents() : bool{
return true; return true;
@ -1960,10 +1846,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
/** /**
* @param Vector3|Position|Location $pos * @param Vector3|Position|Location $pos
* @param float|null $yaw
* @param float|null $pitch
*
* @return bool
*/ */
public function teleport(Vector3 $pos, ?float $yaw = null, ?float $pitch = null) : bool{ public function teleport(Vector3 $pos, ?float $yaw = null, ?float $pitch = null) : bool{
if($pos instanceof Location){ if($pos instanceof Location){
@ -2032,8 +1914,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
/** /**
* Called by spawnTo() to send whatever packets needed to spawn the entity to the client. * Called by spawnTo() to send whatever packets needed to spawn the entity to the client.
*
* @param Player $player
*/ */
protected function sendSpawnPacket(Player $player) : void{ protected function sendSpawnPacket(Player $player) : void{
$pk = new AddActorPacket(); $pk = new AddActorPacket();
@ -2050,9 +1930,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
$player->dataPacket($pk); $player->dataPacket($pk);
} }
/**
* @param Player $player
*/
public function spawnTo(Player $player) : void{ public function spawnTo(Player $player) : void{
if(!isset($this->hasSpawned[$player->getLoaderId()]) and $this->chunk !== null and isset($player->usedChunks[Level::chunkHash($this->chunk->getX(), $this->chunk->getZ())])){ if(!isset($this->hasSpawned[$player->getLoaderId()]) and $this->chunk !== null and isset($player->usedChunks[Level::chunkHash($this->chunk->getX(), $this->chunk->getZ())])){
$this->hasSpawned[$player->getLoaderId()] = $player; $this->hasSpawned[$player->getLoaderId()] = $player;
@ -2082,9 +1959,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
/** /**
* @deprecated WARNING: This function DOES NOT permanently hide the entity from the player. As soon as the entity or * @deprecated WARNING: This function DOES NOT permanently hide the entity from the player. As soon as the entity or
* player moves, the player will once again be able to see the entity. * player moves, the player will once again be able to see the entity.
*
* @param Player $player
* @param bool $send
*/ */
public function despawnFrom(Player $player, bool $send = true) : void{ public function despawnFrom(Player $player, bool $send = true) : void{
if(isset($this->hasSpawned[$player->getLoaderId()])){ if(isset($this->hasSpawned[$player->getLoaderId()])){
@ -2121,7 +1995,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
/** /**
* Returns whether the entity has been "closed". * Returns whether the entity has been "closed".
* @return bool
*/ */
public function isClosed() : bool{ public function isClosed() : bool{
return $this->closed; return $this->closed;
@ -2161,12 +2034,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
} }
} }
/**
* @param int $propertyId
* @param int $flagId
* @param bool $value
* @param int $propertyType
*/
public function setDataFlag(int $propertyId, int $flagId, bool $value = true, int $propertyType = self::DATA_TYPE_LONG) : void{ public function setDataFlag(int $propertyId, int $flagId, bool $value = true, int $propertyType = self::DATA_TYPE_LONG) : void{
if($this->getDataFlag($propertyId, $flagId) !== $value){ if($this->getDataFlag($propertyId, $flagId) !== $value){
$flags = (int) $this->propertyManager->getPropertyValue($propertyId, $propertyType); $flags = (int) $this->propertyManager->getPropertyValue($propertyId, $propertyType);
@ -2175,22 +2042,12 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
} }
} }
/**
* @param int $propertyId
* @param int $flagId
*
* @return bool
*/
public function getDataFlag(int $propertyId, int $flagId) : bool{ public function getDataFlag(int $propertyId, int $flagId) : bool{
return (((int) $this->propertyManager->getPropertyValue($propertyId, -1)) & (1 << $flagId)) > 0; return (((int) $this->propertyManager->getPropertyValue($propertyId, -1)) & (1 << $flagId)) > 0;
} }
/** /**
* Wrapper around {@link Entity#getDataFlag} for generic data flag reading. * Wrapper around {@link Entity#getDataFlag} for generic data flag reading.
*
* @param int $flagId
*
* @return bool
*/ */
public function getGenericFlag(int $flagId) : bool{ public function getGenericFlag(int $flagId) : bool{
return $this->getDataFlag($flagId >= 64 ? self::DATA_FLAGS2 : self::DATA_FLAGS, $flagId % 64); return $this->getDataFlag($flagId >= 64 ? self::DATA_FLAGS2 : self::DATA_FLAGS, $flagId % 64);
@ -2198,9 +2055,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
/** /**
* Wrapper around {@link Entity#setDataFlag} for generic data flag setting. * Wrapper around {@link Entity#setDataFlag} for generic data flag setting.
*
* @param int $flagId
* @param bool $value
*/ */
public function setGenericFlag(int $flagId, bool $value = true) : void{ public function setGenericFlag(int $flagId, bool $value = true) : void{
$this->setDataFlag($flagId >= 64 ? self::DATA_FLAGS2 : self::DATA_FLAGS, $flagId % 64, $value, self::DATA_TYPE_LONG); $this->setDataFlag($flagId >= 64 ? self::DATA_FLAGS2 : self::DATA_FLAGS, $flagId % 64, $value, self::DATA_TYPE_LONG);
@ -2208,7 +2062,8 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
/** /**
* @param Player[]|Player $player * @param Player[]|Player $player
* @param array $data Properly formatted entity data, defaults to everything * @param mixed[][] $data Properly formatted entity data, defaults to everything
* @phpstan-param array<int, array{0: int, 1: mixed}> $data
*/ */
public function sendData($player, ?array $data = null) : void{ public function sendData($player, ?array $data = null) : void{
if(!is_array($player)){ if(!is_array($player)){
@ -2231,6 +2086,9 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
} }
} }
/**
* @param Player[]|null $players
*/
public function broadcastEntityEvent(int $eventId, ?int $eventData = null, ?array $players = null) : void{ public function broadcastEntityEvent(int $eventId, ?int $eventData = null, ?array $players = null) : void{
$pk = new ActorEventPacket(); $pk = new ActorEventPacket();
$pk->entityRuntimeId = $this->id; $pk->entityRuntimeId = $this->id;

View File

@ -23,7 +23,6 @@ declare(strict_types=1);
namespace pocketmine\entity; namespace pocketmine\entity;
interface Explosive{ interface Explosive{
/** /**

View File

@ -38,6 +38,7 @@ use pocketmine\item\Durable;
use pocketmine\item\enchantment\Enchantment; use pocketmine\item\enchantment\Enchantment;
use pocketmine\item\FoodSource; use pocketmine\item\FoodSource;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\item\MaybeConsumable;
use pocketmine\item\Totem; use pocketmine\item\Totem;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\nbt\NBT; use pocketmine\nbt\NBT;
@ -50,6 +51,7 @@ use pocketmine\network\mcpe\protocol\ActorEventPacket;
use pocketmine\network\mcpe\protocol\AddPlayerPacket; use pocketmine\network\mcpe\protocol\AddPlayerPacket;
use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket;
use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket;
use pocketmine\network\mcpe\protocol\MovePlayerPacket;
use pocketmine\network\mcpe\protocol\PlayerListPacket; use pocketmine\network\mcpe\protocol\PlayerListPacket;
use pocketmine\network\mcpe\protocol\PlayerSkinPacket; use pocketmine\network\mcpe\protocol\PlayerSkinPacket;
use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use pocketmine\network\mcpe\protocol\types\PlayerListEntry;
@ -116,9 +118,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
} }
/** /**
* @param CompoundTag $skinTag
*
* @return Skin
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
protected static function deserializeSkinNBT(CompoundTag $skinTag) : Skin{ protected static function deserializeSkinNBT(CompoundTag $skinTag) : Skin{
@ -137,32 +136,21 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
* @deprecated * @deprecated
* *
* Checks the length of a supplied skin bitmap and returns whether the length is valid. * Checks the length of a supplied skin bitmap and returns whether the length is valid.
*
* @param string $skin
*
* @return bool
*/ */
public static function isValidSkin(string $skin) : bool{ public static function isValidSkin(string $skin) : bool{
return in_array(strlen($skin), Skin::ACCEPTED_SKIN_SIZES, true); return in_array(strlen($skin), Skin::ACCEPTED_SKIN_SIZES, true);
} }
/**
* @return UUID|null
*/
public function getUniqueId() : ?UUID{ public function getUniqueId() : ?UUID{
return $this->uuid; return $this->uuid;
} }
/**
* @return string
*/
public function getRawUniqueId() : string{ public function getRawUniqueId() : string{
return $this->rawUUID; return $this->rawUUID;
} }
/** /**
* Returns a Skin object containing information about this human's skin. * Returns a Skin object containing information about this human's skin.
* @return Skin
*/ */
public function getSkin() : Skin{ public function getSkin() : Skin{
return $this->skin; return $this->skin;
@ -171,8 +159,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
/** /**
* Sets the human's skin. This will not send any update to viewers, you need to do that manually using * Sets the human's skin. This will not send any update to viewers, you need to do that manually using
* {@link sendSkin}. * {@link sendSkin}.
*
* @param Skin $skin
*/ */
public function setSkin(Skin $skin) : void{ public function setSkin(Skin $skin) : void{
$skin->validate(); $skin->validate();
@ -210,8 +196,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
* WARNING: This method does not check if full and may throw an exception if out of bounds. * WARNING: This method does not check if full and may throw an exception if out of bounds.
* Use {@link Human::addFood()} for this purpose * Use {@link Human::addFood()} for this purpose
* *
* @param float $new
*
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public function setFood(float $new) : void{ public function setFood(float $new) : void{
@ -241,8 +225,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
/** /**
* Returns whether this Human may consume objects requiring hunger. * Returns whether this Human may consume objects requiring hunger.
*
* @return bool
*/ */
public function isHungry() : bool{ public function isHungry() : bool{
return $this->getFood() < $this->getMaxFood(); return $this->getFood() < $this->getMaxFood();
@ -256,8 +238,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
* WARNING: This method does not check if saturated and may throw an exception if out of bounds. * WARNING: This method does not check if saturated and may throw an exception if out of bounds.
* Use {@link Human::addSaturation()} for this purpose * Use {@link Human::addSaturation()} for this purpose
* *
* @param float $saturation
*
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public function setSaturation(float $saturation) : void{ public function setSaturation(float $saturation) : void{
@ -276,8 +256,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
/** /**
* WARNING: This method does not check if exhausted and does not consume saturation/food. * WARNING: This method does not check if exhausted and does not consume saturation/food.
* Use {@link Human::exhaust()} for this purpose. * Use {@link Human::exhaust()} for this purpose.
*
* @param float $exhaustion
*/ */
public function setExhaustion(float $exhaustion) : void{ public function setExhaustion(float $exhaustion) : void{
$this->attributeMap->getAttribute(Attribute::EXHAUSTION)->setValue($exhaustion); $this->attributeMap->getAttribute(Attribute::EXHAUSTION)->setValue($exhaustion);
@ -286,9 +264,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
/** /**
* Increases a human's exhaustion level. * Increases a human's exhaustion level.
* *
* @param float $amount
* @param int $cause
*
* @return float the amount of exhaustion level increased * @return float the amount of exhaustion level increased
*/ */
public function exhaust(float $amount, int $cause = PlayerExhaustEvent::CAUSE_CUSTOM) : float{ public function exhaust(float $amount, int $cause = PlayerExhaustEvent::CAUSE_CUSTOM) : float{
@ -322,6 +297,10 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
} }
public function consumeObject(Consumable $consumable) : bool{ public function consumeObject(Consumable $consumable) : bool{
if($consumable instanceof MaybeConsumable and !$consumable->canBeConsumed()){
return false;
}
if($consumable instanceof FoodSource){ if($consumable instanceof FoodSource){
if($consumable->requiresHunger() and !$this->isHungry()){ if($consumable->requiresHunger() and !$this->isHungry()){
return false; return false;
@ -336,7 +315,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
/** /**
* Returns the player's experience level. * Returns the player's experience level.
* @return int
*/ */
public function getXpLevel() : int{ public function getXpLevel() : int{
return (int) $this->attributeMap->getAttribute(Attribute::EXPERIENCE_LEVEL)->getValue(); return (int) $this->attributeMap->getAttribute(Attribute::EXPERIENCE_LEVEL)->getValue();
@ -344,10 +322,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
/** /**
* Sets the player's experience level. This does not affect their total XP or their XP progress. * Sets the player's experience level. This does not affect their total XP or their XP progress.
*
* @param int $level
*
* @return bool
*/ */
public function setXpLevel(int $level) : bool{ public function setXpLevel(int $level) : bool{
return $this->setXpAndProgress($level, null); return $this->setXpAndProgress($level, null);
@ -355,11 +329,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
/** /**
* Adds a number of XP levels to the player. * Adds a number of XP levels to the player.
*
* @param int $amount
* @param bool $playSound
*
* @return bool
*/ */
public function addXpLevels(int $amount, bool $playSound = true) : bool{ public function addXpLevels(int $amount, bool $playSound = true) : bool{
$oldLevel = $this->getXpLevel(); $oldLevel = $this->getXpLevel();
@ -379,10 +348,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
/** /**
* Subtracts a number of XP levels from the player. * Subtracts a number of XP levels from the player.
*
* @param int $amount
*
* @return bool
*/ */
public function subtractXpLevels(int $amount) : bool{ public function subtractXpLevels(int $amount) : bool{
return $this->addXpLevels(-$amount); return $this->addXpLevels(-$amount);
@ -390,7 +355,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
/** /**
* Returns a value between 0.0 and 1.0 to indicate how far through the current level the player is. * Returns a value between 0.0 and 1.0 to indicate how far through the current level the player is.
* @return float
*/ */
public function getXpProgress() : float{ public function getXpProgress() : float{
return $this->attributeMap->getAttribute(Attribute::EXPERIENCE)->getValue(); return $this->attributeMap->getAttribute(Attribute::EXPERIENCE)->getValue();
@ -398,10 +362,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
/** /**
* Sets the player's progress through the current level to a value between 0.0 and 1.0. * Sets the player's progress through the current level to a value between 0.0 and 1.0.
*
* @param float $progress
*
* @return bool
*/ */
public function setXpProgress(float $progress) : bool{ public function setXpProgress(float $progress) : bool{
return $this->setXpAndProgress(null, $progress); return $this->setXpAndProgress(null, $progress);
@ -409,7 +369,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
/** /**
* Returns the number of XP points the player has progressed into their current level. * Returns the number of XP points the player has progressed into their current level.
* @return int
*/ */
public function getRemainderXp() : int{ public function getRemainderXp() : int{
return (int) (ExperienceUtils::getXpToCompleteLevel($this->getXpLevel()) * $this->getXpProgress()); return (int) (ExperienceUtils::getXpToCompleteLevel($this->getXpLevel()) * $this->getXpProgress());
@ -419,8 +378,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
* Returns the amount of XP points the player currently has, calculated from their current level and progress * Returns the amount of XP points the player currently has, calculated from their current level and progress
* through their current level. This will be reduced by enchanting deducting levels and is used to calculate the * through their current level. This will be reduced by enchanting deducting levels and is used to calculate the
* amount of XP the player drops on death. * amount of XP the player drops on death.
*
* @return int
*/ */
public function getCurrentTotalXp() : int{ public function getCurrentTotalXp() : int{
return ExperienceUtils::getXpToReachLevel($this->getXpLevel()) + $this->getRemainderXp(); return ExperienceUtils::getXpToReachLevel($this->getXpLevel()) + $this->getRemainderXp();
@ -429,10 +386,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
/** /**
* Sets the current total of XP the player has, recalculating their XP level and progress. * Sets the current total of XP the player has, recalculating their XP level and progress.
* Note that this DOES NOT update the player's lifetime total XP. * Note that this DOES NOT update the player's lifetime total XP.
*
* @param int $amount
*
* @return bool
*/ */
public function setCurrentTotalXp(int $amount) : bool{ public function setCurrentTotalXp(int $amount) : bool{
$newLevel = ExperienceUtils::getLevelFromXp($amount); $newLevel = ExperienceUtils::getLevelFromXp($amount);
@ -444,10 +397,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
* Adds an amount of XP to the player, recalculating their XP level and progress. XP amount will be added to the * Adds an amount of XP to the player, recalculating their XP level and progress. XP amount will be added to the
* player's lifetime XP. * player's lifetime XP.
* *
* @param int $amount
* @param bool $playSound Whether to play level-up and XP gained sounds. * @param bool $playSound Whether to play level-up and XP gained sounds.
*
* @return bool
*/ */
public function addXp(int $amount, bool $playSound = true) : bool{ public function addXp(int $amount, bool $playSound = true) : bool{
$this->totalXp += $amount; $this->totalXp += $amount;
@ -478,10 +428,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
/** /**
* Takes an amount of XP from the player, recalculating their XP level and progress. * Takes an amount of XP from the player, recalculating their XP level and progress.
*
* @param int $amount
*
* @return bool
*/ */
public function subtractXp(int $amount) : bool{ public function subtractXp(int $amount) : bool{
return $this->addXp(-$amount); return $this->addXp(-$amount);
@ -514,8 +460,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
/** /**
* Returns the total XP the player has collected in their lifetime. Resets when the player dies. * Returns the total XP the player has collected in their lifetime. Resets when the player dies.
* XP levels being removed in enchanting do not reduce this number. * XP levels being removed in enchanting do not reduce this number.
*
* @return int
*/ */
public function getLifetimeTotalXp() : int{ public function getLifetimeTotalXp() : int{
return $this->totalXp; return $this->totalXp;
@ -524,8 +468,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
/** /**
* Sets the lifetime total XP of the player. This does not recalculate their level or progress. Used for player * Sets the lifetime total XP of the player. This does not recalculate their level or progress. Used for player
* score when they die. (TODO: add this when MCPE supports it) * score when they die. (TODO: add this when MCPE supports it)
*
* @param int $amount
*/ */
public function setLifetimeTotalXp(int $amount) : void{ public function setLifetimeTotalXp(int $amount) : void{
if($amount < 0){ if($amount < 0){
@ -537,7 +479,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
/** /**
* Returns whether the human can pickup XP orbs (checks cooldown time) * Returns whether the human can pickup XP orbs (checks cooldown time)
* @return bool
*/ */
public function canPickupXp() : bool{ public function canPickupXp() : bool{
return $this->xpCooldown === 0; return $this->xpCooldown === 0;
@ -554,9 +495,9 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
$equipment[$mainHandIndex] = $item; $equipment[$mainHandIndex] = $item;
} }
//TODO: check offhand //TODO: check offhand
foreach($this->armorInventory->getContents() as $k => $item){ foreach($this->armorInventory->getContents() as $k => $armorItem){
if($item instanceof Durable and $item->hasEnchantment(Enchantment::MENDING)){ if($armorItem instanceof Durable and $armorItem->hasEnchantment(Enchantment::MENDING)){
$equipment[$k] = $item; $equipment[$k] = $armorItem;
} }
} }
@ -581,8 +522,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
/** /**
* Sets the duration in ticks until the human can pick up another XP orb. * Sets the duration in ticks until the human can pick up another XP orb.
*
* @param int $value
*/ */
public function resetXpCooldown(int $value = 2) : void{ public function resetXpCooldown(int $value = 2) : void{
$this->xpCooldown = $value; $this->xpCooldown = $value;
@ -591,7 +530,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
public function getXpDropAmount() : int{ public function getXpDropAmount() : int{
//this causes some XP to be lost on death when above level 1 (by design), dropping at most enough points for //this causes some XP to be lost on death when above level 1 (by design), dropping at most enough points for
//about 7.5 levels of XP. //about 7.5 levels of XP.
return (int) min(100, 7 * $this->getXpLevel()); return min(100, 7 * $this->getXpLevel());
} }
/** /**
@ -886,6 +825,23 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
} }
} }
public function broadcastMovement(bool $teleport = false) : void{
//TODO: workaround 1.14.30 bug: MoveActor(Absolute|Delta)Packet don't work on players anymore :(
$pk = new MovePlayerPacket();
$pk->entityRuntimeId = $this->getId();
$pk->position = $this->getOffsetPosition($this);
$pk->yaw = $this->yaw;
$pk->pitch = $this->pitch;
$pk->headYaw = $this->yaw;
$pk->mode = $teleport ? MovePlayerPacket::MODE_TELEPORT : MovePlayerPacket::MODE_NORMAL;
//we can't assume that everyone who is using our chunk wants to see this movement,
//because this human might be a player who shouldn't be receiving his own movement.
//this didn't matter when we were able to use MoveActorPacket because
//the client just ignored MoveActor for itself, but it doesn't ignore MovePlayer for itself.
$this->server->broadcastPacket($this->hasSpawned, $pk);
}
public function close() : void{ public function close() : void{
if(!$this->closed){ if(!$this->closed){
if($this->inventory !== null){ if($this->inventory !== null){
@ -902,10 +858,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
/** /**
* Wrapper around {@link Entity#getDataFlag} for player-specific data flag reading. * Wrapper around {@link Entity#getDataFlag} for player-specific data flag reading.
*
* @param int $flagId
*
* @return bool
*/ */
public function getPlayerFlag(int $flagId) : bool{ public function getPlayerFlag(int $flagId) : bool{
return $this->getDataFlag(self::DATA_PLAYER_FLAGS, $flagId); return $this->getDataFlag(self::DATA_PLAYER_FLAGS, $flagId);
@ -913,9 +865,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
/** /**
* Wrapper around {@link Entity#setDataFlag} for player-specific data flag setting. * Wrapper around {@link Entity#setDataFlag} for player-specific data flag setting.
*
* @param int $flagId
* @param bool $value
*/ */
public function setPlayerFlag(int $flagId, bool $value = true) : void{ public function setPlayerFlag(int $flagId, bool $value = true) : void{
$this->setDataFlag(self::DATA_PLAYER_FLAGS, $flagId, $value, self::DATA_TYPE_BYTE); $this->setDataFlag(self::DATA_PLAYER_FLAGS, $flagId, $value, self::DATA_TYPE_BYTE);

View File

@ -37,6 +37,7 @@ use pocketmine\item\Consumable;
use pocketmine\item\Durable; use pocketmine\item\Durable;
use pocketmine\item\enchantment\Enchantment; use pocketmine\item\enchantment\Enchantment;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\item\MaybeConsumable;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\math\VoxelRayTrace; use pocketmine\math\VoxelRayTrace;
use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\ByteTag;
@ -111,7 +112,7 @@ abstract class Living extends Entity implements Damageable{
$this->setHealth($health); $this->setHealth($health);
/** @var CompoundTag[]|ListTag $activeEffectsTag */ /** @var CompoundTag[]|ListTag|null $activeEffectsTag */
$activeEffectsTag = $this->namedtag->getListTag("ActiveEffects"); $activeEffectsTag = $this->namedtag->getListTag("ActiveEffects");
if($activeEffectsTag !== null){ if($activeEffectsTag !== null){
foreach($activeEffectsTag as $e){ foreach($activeEffectsTag as $e){
@ -187,7 +188,6 @@ abstract class Living extends Entity implements Damageable{
} }
} }
public function hasLineOfSight(Entity $entity) : bool{ public function hasLineOfSight(Entity $entity) : bool{
//TODO: head height //TODO: head height
return true; return true;
@ -213,8 +213,6 @@ abstract class Living extends Entity implements Damageable{
/** /**
* Removes the effect with the specified ID from the mob. * Removes the effect with the specified ID from the mob.
*
* @param int $effectId
*/ */
public function removeEffect(int $effectId) : void{ public function removeEffect(int $effectId) : void{
if(isset($this->effects[$effectId])){ if(isset($this->effects[$effectId])){
@ -240,10 +238,6 @@ abstract class Living extends Entity implements Damageable{
/** /**
* Returns the effect instance active on this entity with the specified ID, or null if the mob does not have the * Returns the effect instance active on this entity with the specified ID, or null if the mob does not have the
* effect. * effect.
*
* @param int $effectId
*
* @return EffectInstance|null
*/ */
public function getEffect(int $effectId) : ?EffectInstance{ public function getEffect(int $effectId) : ?EffectInstance{
return $this->effects[$effectId] ?? null; return $this->effects[$effectId] ?? null;
@ -251,10 +245,6 @@ abstract class Living extends Entity implements Damageable{
/** /**
* Returns whether the specified effect is active on the mob. * Returns whether the specified effect is active on the mob.
*
* @param int $effectId
*
* @return bool
*/ */
public function hasEffect(int $effectId) : bool{ public function hasEffect(int $effectId) : bool{
return isset($this->effects[$effectId]); return isset($this->effects[$effectId]);
@ -262,7 +252,6 @@ abstract class Living extends Entity implements Damageable{
/** /**
* Returns whether the mob has any active effects. * Returns whether the mob has any active effects.
* @return bool
*/ */
public function hasEffects() : bool{ public function hasEffects() : bool{
return count($this->effects) > 0; return count($this->effects) > 0;
@ -273,8 +262,6 @@ abstract class Living extends Entity implements Damageable{
* If a weaker effect of the same type is already applied, it will be replaced. * If a weaker effect of the same type is already applied, it will be replaced.
* If a weaker or equal-strength effect is already applied but has a shorter duration, it will be replaced. * If a weaker or equal-strength effect is already applied but has a shorter duration, it will be replaced.
* *
* @param EffectInstance $effect
*
* @return bool whether the effect has been successfully applied. * @return bool whether the effect has been successfully applied.
*/ */
public function addEffect(EffectInstance $effect) : bool{ public function addEffect(EffectInstance $effect) : bool{
@ -345,8 +332,6 @@ abstract class Living extends Entity implements Damageable{
/** /**
* Sends the mob's potion effects to the specified player. * Sends the mob's potion effects to the specified player.
*
* @param Player $player
*/ */
public function sendPotionEffects(Player $player) : void{ public function sendPotionEffects(Player $player) : void{
foreach($this->effects as $effect){ foreach($this->effects as $effect){
@ -373,12 +358,12 @@ abstract class Living extends Entity implements Damageable{
/** /**
* Causes the mob to consume the given Consumable object, applying applicable effects, health bonuses, food bonuses, * Causes the mob to consume the given Consumable object, applying applicable effects, health bonuses, food bonuses,
* etc. * etc.
*
* @param Consumable $consumable
*
* @return bool
*/ */
public function consumeObject(Consumable $consumable) : bool{ public function consumeObject(Consumable $consumable) : bool{
if($consumable instanceof MaybeConsumable and !$consumable->canBeConsumed()){
return false;
}
foreach($consumable->getAdditionalEffects() as $effect){ foreach($consumable->getAdditionalEffects() as $effect){
$this->addEffect($effect); $this->addEffect($effect);
} }
@ -390,7 +375,6 @@ abstract class Living extends Entity implements Damageable{
/** /**
* Returns the initial upwards velocity of a jumping entity in blocks/tick, including additional velocity due to effects. * Returns the initial upwards velocity of a jumping entity in blocks/tick, including additional velocity due to effects.
* @return float
*/ */
public function getJumpVelocity() : float{ public function getJumpVelocity() : float{
return $this->jumpVelocity + ($this->hasEffect(Effect::JUMP) ? ($this->getEffect(Effect::JUMP)->getEffectLevel() / 10) : 0); return $this->jumpVelocity + ($this->hasEffect(Effect::JUMP) ? ($this->getEffect(Effect::JUMP)->getEffectLevel() / 10) : 0);
@ -417,8 +401,6 @@ abstract class Living extends Entity implements Damageable{
* Returns how many armour points this mob has. Armour points provide a percentage reduction to damage. * Returns how many armour points this mob has. Armour points provide a percentage reduction to damage.
* For mobs which can wear armour, this should return the sum total of the armour points provided by their * For mobs which can wear armour, this should return the sum total of the armour points provided by their
* equipment. * equipment.
*
* @return int
*/ */
public function getArmorPoints() : int{ public function getArmorPoints() : int{
$total = 0; $total = 0;
@ -431,10 +413,6 @@ abstract class Living extends Entity implements Damageable{
/** /**
* Returns the highest level of the specified enchantment on any armour piece that the entity is currently wearing. * Returns the highest level of the specified enchantment on any armour piece that the entity is currently wearing.
*
* @param int $enchantmentId
*
* @return int
*/ */
public function getHighestArmorEnchantmentLevel(int $enchantmentId) : int{ public function getHighestArmorEnchantmentLevel(int $enchantmentId) : int{
$result = 0; $result = 0;
@ -445,9 +423,6 @@ abstract class Living extends Entity implements Damageable{
return $result; return $result;
} }
/**
* @return ArmorInventory
*/
public function getArmorInventory() : ArmorInventory{ public function getArmorInventory() : ArmorInventory{
return $this->armorInventory; return $this->armorInventory;
} }
@ -459,8 +434,6 @@ abstract class Living extends Entity implements Damageable{
/** /**
* Called prior to EntityDamageEvent execution to apply modifications to the event's damage, such as reduction due * Called prior to EntityDamageEvent execution to apply modifications to the event's damage, such as reduction due
* to effects or armour. * to effects or armour.
*
* @param EntityDamageEvent $source
*/ */
public function applyDamageModifiers(EntityDamageEvent $source) : void{ public function applyDamageModifiers(EntityDamageEvent $source) : void{
if($source->canBeReducedByArmor()){ if($source->canBeReducedByArmor()){
@ -488,8 +461,6 @@ abstract class Living extends Entity implements Damageable{
* Called after EntityDamageEvent execution to apply post-hurt effects, such as reducing absorption or modifying * Called after EntityDamageEvent execution to apply post-hurt effects, such as reducing absorption or modifying
* armour durability. * armour durability.
* This will not be called by damage sources causing death. * This will not be called by damage sources causing death.
*
* @param EntityDamageEvent $source
*/ */
protected function applyPostDamageEffects(EntityDamageEvent $source) : void{ protected function applyPostDamageEffects(EntityDamageEvent $source) : void{
$this->setAbsorption(max(0, $this->getAbsorption() + $source->getModifier(EntityDamageEvent::MODIFIER_ABSORPTION))); $this->setAbsorption(max(0, $this->getAbsorption() + $source->getModifier(EntityDamageEvent::MODIFIER_ABSORPTION)));
@ -519,8 +490,6 @@ abstract class Living extends Entity implements Damageable{
/** /**
* Damages the worn armour according to the amount of damage given. Each 4 points (rounded down) deals 1 damage * Damages the worn armour according to the amount of damage given. Each 4 points (rounded down) deals 1 damage
* point to each armour piece, but never less than 1 total. * point to each armour piece, but never less than 1 total.
*
* @param float $damage
*/ */
public function damageArmor(float $damage) : void{ public function damageArmor(float $damage) : void{
$durabilityRemoved = (int) max(floor($damage / 4), 1); $durabilityRemoved = (int) max(floor($damage / 4), 1);
@ -720,10 +689,6 @@ abstract class Living extends Entity implements Damageable{
/** /**
* Ticks the entity's air supply, consuming it when underwater and regenerating it when out of water. * Ticks the entity's air supply, consuming it when underwater and regenerating it when out of water.
*
* @param int $tickDiff
*
* @return bool
*/ */
protected function doAirSupplyTick(int $tickDiff) : bool{ protected function doAirSupplyTick(int $tickDiff) : bool{
$ticks = $this->getAirSupplyTicks(); $ticks = $this->getAirSupplyTicks();
@ -759,7 +724,6 @@ abstract class Living extends Entity implements Damageable{
/** /**
* Returns whether the entity can currently breathe. * Returns whether the entity can currently breathe.
* @return bool
*/ */
public function canBreathe() : bool{ public function canBreathe() : bool{
return $this->hasEffect(Effect::WATER_BREATHING) or $this->hasEffect(Effect::CONDUIT_POWER) or !$this->isUnderwater(); return $this->hasEffect(Effect::WATER_BREATHING) or $this->hasEffect(Effect::CONDUIT_POWER) or !$this->isUnderwater();
@ -767,7 +731,6 @@ abstract class Living extends Entity implements Damageable{
/** /**
* Returns whether the entity is currently breathing or not. If this is false, the entity's air supply will be used. * Returns whether the entity is currently breathing or not. If this is false, the entity's air supply will be used.
* @return bool
*/ */
public function isBreathing() : bool{ public function isBreathing() : bool{
return $this->getGenericFlag(self::DATA_FLAG_BREATHING); return $this->getGenericFlag(self::DATA_FLAG_BREATHING);
@ -776,8 +739,6 @@ abstract class Living extends Entity implements Damageable{
/** /**
* Sets whether the entity is currently breathing. If false, it will cause the entity's air supply to be used. * Sets whether the entity is currently breathing. If false, it will cause the entity's air supply to be used.
* For players, this also shows the oxygen bar. * For players, this also shows the oxygen bar.
*
* @param bool $value
*/ */
public function setBreathing(bool $value = true) : void{ public function setBreathing(bool $value = true) : void{
$this->setGenericFlag(self::DATA_FLAG_BREATHING, $value); $this->setGenericFlag(self::DATA_FLAG_BREATHING, $value);
@ -786,8 +747,6 @@ abstract class Living extends Entity implements Damageable{
/** /**
* Returns the number of ticks remaining in the entity's air supply. Note that the entity may survive longer than * Returns the number of ticks remaining in the entity's air supply. Note that the entity may survive longer than
* this amount of time without damage due to enchantments such as Respiration. * this amount of time without damage due to enchantments such as Respiration.
*
* @return int
*/ */
public function getAirSupplyTicks() : int{ public function getAirSupplyTicks() : int{
return $this->propertyManager->getShort(self::DATA_AIR); return $this->propertyManager->getShort(self::DATA_AIR);
@ -795,8 +754,6 @@ abstract class Living extends Entity implements Damageable{
/** /**
* Sets the number of air ticks left in the entity's air supply. * Sets the number of air ticks left in the entity's air supply.
*
* @param int $ticks
*/ */
public function setAirSupplyTicks(int $ticks) : void{ public function setAirSupplyTicks(int $ticks) : void{
$this->propertyManager->setShort(self::DATA_AIR, $ticks); $this->propertyManager->setShort(self::DATA_AIR, $ticks);
@ -804,7 +761,6 @@ abstract class Living extends Entity implements Damageable{
/** /**
* Returns the maximum amount of air ticks the entity's air supply can contain. * Returns the maximum amount of air ticks the entity's air supply can contain.
* @return int
*/ */
public function getMaxAirSupplyTicks() : int{ public function getMaxAirSupplyTicks() : int{
return $this->propertyManager->getShort(self::DATA_MAX_AIR); return $this->propertyManager->getShort(self::DATA_MAX_AIR);
@ -812,8 +768,6 @@ abstract class Living extends Entity implements Damageable{
/** /**
* Sets the maximum amount of air ticks the air supply can hold. * Sets the maximum amount of air ticks the air supply can hold.
*
* @param int $ticks
*/ */
public function setMaxAirSupplyTicks(int $ticks) : void{ public function setMaxAirSupplyTicks(int $ticks) : void{
$this->propertyManager->setShort(self::DATA_MAX_AIR, $ticks); $this->propertyManager->setShort(self::DATA_MAX_AIR, $ticks);
@ -837,16 +791,14 @@ abstract class Living extends Entity implements Damageable{
/** /**
* Returns the amount of XP this mob will drop on death. * Returns the amount of XP this mob will drop on death.
* @return int
*/ */
public function getXpDropAmount() : int{ public function getXpDropAmount() : int{
return 0; return 0;
} }
/** /**
* @param int $maxDistance * @param true[] $transparent
* @param int $maxLength * @phpstan-param array<int, true> $transparent
* @param array $transparent
* *
* @return Block[] * @return Block[]
*/ */
@ -888,10 +840,8 @@ abstract class Living extends Entity implements Damageable{
} }
/** /**
* @param int $maxDistance * @param true[] $transparent
* @param array $transparent * @phpstan-param array<int, true> $transparent
*
* @return Block|null
*/ */
public function getTargetBlock(int $maxDistance, array $transparent = []) : ?Block{ public function getTargetBlock(int $maxDistance, array $transparent = []) : ?Block{
$line = $this->getLineOfSight($maxDistance, 1, $transparent); $line = $this->getLineOfSight($maxDistance, 1, $transparent);
@ -905,8 +855,6 @@ abstract class Living extends Entity implements Damageable{
/** /**
* Changes the entity's yaw and pitch to make it look at the specified Vector3 position. For mobs, this will cause * Changes the entity's yaw and pitch to make it look at the specified Vector3 position. For mobs, this will cause
* their heads to turn. * their heads to turn.
*
* @param Vector3 $target
*/ */
public function lookAt(Vector3 $target) : void{ public function lookAt(Vector3 $target) : void{
$horizontal = sqrt(($target->x - $this->x) ** 2 + ($target->z - $this->z) ** 2); $horizontal = sqrt(($target->x - $this->x) ** 2 + ($target->z - $this->z) ** 2);

View File

@ -23,7 +23,6 @@ declare(strict_types=1);
namespace pocketmine\entity; namespace pocketmine\entity;
abstract class Monster extends Creature{ abstract class Monster extends Creature{
} }

View File

@ -23,7 +23,6 @@ declare(strict_types=1);
namespace pocketmine\entity; namespace pocketmine\entity;
interface NPC{ interface NPC{
} }

View File

@ -23,7 +23,6 @@ declare(strict_types=1);
namespace pocketmine\entity; namespace pocketmine\entity;
interface Rideable{ interface Rideable{
} }

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