Compare commits

...

103 Commits
3.5.3 ... 3.6.0

Author SHA1 Message Date
02a6ca84a9 Releass 3.6.0 2019-02-07 22:06:33 +00:00
b8703d5dff Protocol changes for 1.9.0 2019-02-07 21:56:42 +00:00
37c2d78731 3.5.11 is next 2019-02-07 20:47:05 +00:00
b7663e5815 Release 3.5.10 2019-02-07 20:46:27 +00:00
1d0ffa06f8 TallGrass: fixed placement on dirt, closes #2552 2019-02-07 16:55:25 +00:00
768cfe3953 Updated composer dependencies 2019-02-07 16:47:16 +00:00
2822465f33 Updated submodules 2019-02-07 16:20:45 +00:00
5da48f429f Fixed some remaining one-line field declarations, added type docs 2019-02-05 14:03:27 +00:00
dbd0d04549 fix wrong doc comments in Thread & Worker 2019-02-05 13:58:18 +00:00
0f92ec6d2a Level: Record a debug message when chunks are loaded without loaders 2019-02-03 16:24:10 +00:00
791b4d8ef3 SplashPotion: measure distance from eye height instead of base
this fixes effect durations being off (mostly), closes #2650
there are still some minor differences, but this is closer matching than the previous version.
2019-02-03 11:32:47 +00:00
0b7ff6f2e7 Level: properly mark some functions as @internal
this ensures these functions won't appear in the documentation.
2019-02-01 14:33:06 +00:00
af092b01e1 3.5.10 is next 2019-01-31 18:47:57 +00:00
d811217755 Release 3.5.9 2019-01-31 18:47:32 +00:00
d7f86f0240 Hack for client side regeneration (disable natural regeneration gamerule) (#2722) 2019-01-31 18:45:25 +00:00
5fe1d2e396 Level: fixed setChunk() bug introduced by eebd90ec42
Anyone who is using getChunkPlayers() should probably check that their code is actually doing what they think it's doing.
2019-01-31 18:28:42 +00:00
ddbb5363ef Block->getBreakTime() now throws InvalidArgumentException on items with bad efficiency values 2019-01-30 19:10:24 +00:00
d3704bfae4 3.5.9 is next 2019-01-30 12:49:46 +00:00
07f034d2da Release 3.5.8 2019-01-30 12:49:16 +00:00
331ae5498f Crash the generator when encountering invalid presets
this is a partial fix for #2717, but still not ideal because it'll spam whenever a chunk is attempted to be generated. However, fixing this properly requires potentially breaking API changes.
2019-01-30 12:29:04 +00:00
eebd90ec42 Level: fixed setChunk() leaking memory when not copying tiles/entities
closes #2719
2019-01-30 10:58:35 +00:00
8e47a40b4c Level: rename poorly-named parameter of setChunk()
this now has a mouthful of a name. I'd like to invert it, but I can't do that without silently breaking backwards compatibility, which is unacceptable.
2019-01-30 10:26:18 +00:00
0f9fdf6442 Fixed Cactus and Sugarcane growing through bad blocks
closes #2714
2019-01-29 17:32:48 +00:00
5364e4de68 Explosion: fix chest unpairing (root cause of #2701)
not ready to call this "fixed" yet because any chests that were already affected by the bug will still be affected. This change will prevent the creation of more broken chests like this.
2019-01-29 13:58:47 +00:00
1099e2044b SetupWizard: fixed user being able to avoid agreeing to license, closes #2703 2019-01-29 13:43:13 +00:00
80d48161d3 Crops: fixed consuming bonemeal on fully-grown crop, closes #2704 2019-01-29 13:41:02 +00:00
fbe8485696 Player: fixed falling causing starvation, closes #2708 2019-01-29 13:36:24 +00:00
a150f39b02 Fixed fall handling when flying, closes #2709 2019-01-29 13:28:43 +00:00
71d17c50d6 Fixed internal IP detection (#2711), closes #2702 2019-01-29 12:51:53 +00:00
3a18bdd6a0 Prevent block-picking unknown blocks 2019-01-28 17:45:48 +00:00
96857c65b6 Player: Fixed subscribing to broadcast permissions too early
Plugins would indirectly trigger permissible recalculation too early in the login sequence, which then caused their permissions to be recalculated and subscribing them to the broadcast permission far too early.
2019-01-27 15:08:08 +00:00
9826abd83e Stair: fixed crash if player is null 2019-01-26 16:59:03 +00:00
48c8c2a8c3 ItemFrame: address crashdump 2113950
thanks Mojang for designing this lovely system where so much undefined behaviour is able to take place :(
2019-01-26 16:58:25 +00:00
c83b7d9b69 Utils: fixed getNiceClosureName() not processing namespaced closures properly 2019-01-26 12:08:07 +00:00
c66dc7b273 Level: Optimize blockticking coordinate selection
generating 1 large bounded random costs the same as generating 4 small ones, so it makes more sense to do it like this instead.

Note that prior to 7.1 this code would not work due to it not handling 64-bit appropriately.
2019-01-25 19:43:16 +00:00
5bf7350ee5 Level: change some stupid var names 2019-01-25 17:10:44 +00:00
636cc1c199 Level: some mitigations for #2675
this reduces the performance impact by using smaller keys, which reduces the key distance for nearby blocks.
2019-01-25 13:17:33 +00:00
62b6405371 Use 2 space indents in YAML files
this is (mostly) a backport of #2593 to 3.5. Closes #2593.
2019-01-24 18:44:06 +00:00
9ecf23d3ee Fix some bugs in doxygen config 2019-01-24 11:26:48 +00:00
187f36fe38 ExperienceOrb: clean up some confusing code 2019-01-23 16:46:18 +00:00
dc89b48354 Human: Fixed XP drop amount to match vanilla
In vanilla it doesn't drop the exact number of points you collected. Rather, you lose a little for every level above 1 you had (1 level requires 7 points, later levels require +2 per level), and can recover at most 100 points. Hence, if you had 10 levels, you get back enough points to fill 5 levels and most of a 6th. 14-15 levels gets you the upper bound of about 7.5 levels.
2019-01-23 12:39:25 +00:00
e6d1c1dfbc Living: Get rid of delayed XP spawning, closes #2644
This is not identical to vanilla, but I don't care because it gets rid of edge cases and also makes it easier to integrate with EntityDeathEvent in the future.
2019-01-23 12:31:05 +00:00
5a8812b1dc 3.5.8 is next 2019-01-22 22:14:19 +00:00
4b8e4123af Release 3.5.7 2019-01-22 22:13:35 +00:00
45a4252c26 RCON: Explicitly specify connection backlog size, fixes #2685
I believe this is caused by a bug in the linux kernel, since it only impacts certain machines I tested (one, to be specific). Whatever the case, setting a max backlog size is prudent anyway, and fixes the problem.
2019-01-22 22:11:32 +00:00
feaaa925a7 Fixed a series of denial-of-service bugs in RCON
Packets with a too-short payload would either cause the RCON thread to hang until the client disconnected, or crash the RCON thread entirely.

commit 90bb1894d7f87645b806f5fc67d1b877bb963180
Author: Dylan K. Taylor <odigiman@gmail.com>
Date:   Tue Jan 22 18:15:46 2019 +0000

    fix some bugs in RCON
2019-01-22 22:05:15 +00:00
5221db1178 Updated BinaryUtils dependency 2019-01-22 17:22:11 +00:00
47321114eb login: allow 60 seconds clock drift on login JWT
can everyone please just use NTP already?
2019-01-20 15:51:29 +00:00
a27c9409f1 ExperienceOrb: fixed wrong condition 2019-01-20 12:30:24 +00:00
854f851525 ExperienceOrb: don't follow players in other worlds 2019-01-20 12:30:09 +00:00
9003b38be3 Fixed a wtf in Player->removeWindow() 2019-01-19 19:14:21 +00:00
a6a93f822f 3.5.7 is next 2019-01-19 17:48:16 +00:00
d4851a8f1f Release 3.5.6 2019-01-19 17:33:07 +00:00
480a513f30 Sign: fixed asserts on loading NBT, closes #2636 2019-01-19 16:42:22 +00:00
4fd3bee360 Entity: Address fireticks crashdumps
This will now throw an exception at the source instead of crashing when the entity is saved, which should put the blame on the correct plugin responsible for this.
This also includes magic method hacks to preserve backwards compatibility, since the fireTicks field is now protected.
2019-01-19 16:05:10 +00:00
41fd7545e3 RegionLoader: Account for unexpected EOF when reading chunks, closes #2676 2019-01-19 15:49:19 +00:00
82dddde159 Remove dead code in /time command handler 2019-01-19 15:15:04 +00:00
bc709efb77 Prevent stupidity with /enchant 2019-01-19 15:14:51 +00:00
cd98e6a23e Updated PreProcessor submodule 2019-01-19 13:57:17 +00:00
cb591a98f4 NetworkBinaryStream: Skip item NBT which is too large when encoded
Encoded tags larger than 32KB overflow the length field, so we can't send these over network. However, it's unreasonable to randomly throw this burden off onto users by crashing their servers, so the next best solution is to just not send the NBT. This is also not an ideal solution (books and the like with too-large tags won't work on the client side) but it's better than crashing the server or client due to a protocol bug. Mojang have confirmed this will be resolved by a future MCPE release, so we'll just work around this problem until then.
2019-01-16 21:50:43 +00:00
e9d1af0aee Fixed stack trace encoding bug in CrashDump
it was encoding the real (full) trace, instead of emitting the printable version.
2019-01-16 18:56:56 +00:00
0f545c410a Bow: Improve consistency with vanilla (JE at least), closes #2660
This change causes the existing test I did to now report ~55-60 blocks, which is much closer to parity with vanilla.
2019-01-15 14:42:41 +00:00
1c2ed0836f Sync composer dependencies 2019-01-15 10:26:33 +00:00
6cf30dc813 build 7.3 on travis 2019-01-11 23:54:44 +00:00
f7d9247d39 Server: Permit NULL value entries in pocketmine.yml worlds
this permits listing worlds to load as keys without values.
2019-01-10 19:30:37 +00:00
3380aa3ac2 Config: Assert only whitespace precedes .properties key, fixes #commented properties not being skipped 2019-01-07 12:25:05 +00:00
6a9cad8fb7 3.5.6 is next 2019-01-06 20:18:32 +00:00
c9e598cdb9 Release 3.5.5 2019-01-06 19:55:21 +00:00
a6e5b6e158 Log a debug message when not sending crash due to folder plugin 2019-01-06 19:52:20 +00:00
22a6b817d7 Distinguish between direct and indirect plugin crash involvement
If a plugin was involved in a crash, we can't safely blame it for the crash, since it might have innocently triggered a core bug. Furthermore, it's difficult to accurately detect plugin causing things like invalid argument crashes.
2019-01-06 18:07:29 +00:00
2cdf97b7b5 CrashDump: Scan full stack trace to determine plugin involvement 2019-01-06 18:07:29 +00:00
836cb67850 Server: don't abuse random_bytes() to generate integers 2019-01-06 17:22:31 +00:00
ab37df4484 Server: micro-optimization: avoid unnecessary array_shift()
it's much less expensive to just calculate the modulo of the current tick and 20, and overwrite past entries. The effect is the same. The only difference is that the arrays won't be ordered by time, but that doesn't matter anyway.
2019-01-06 01:08:56 +00:00
93969197f7 Enable status,gc,dumpmemory OOB
dumpmemory has been confined to console by default due to the hazards it poses to a running server.

closes #2528
2019-01-05 18:56:57 +00:00
946a1036f1 Drop warn-if-enabled for asserts
I don't know why this is optional when no other debug warnings are.
2019-01-05 18:49:15 +00:00
43410cdafb Server: warn on assertions !== -1, closes #2640 2019-01-05 18:47:29 +00:00
a99e15012c Backport no-ai hack to disable pre-spawn movement 2019-01-05 17:39:20 +00:00
b22a2ef914 Living: Despawn in endDeathAnimation()
this removes the necessity for the player to do this.
2019-01-05 12:46:11 +00:00
f7f7be896e Server: drop misleading config values 2019-01-05 11:12:09 +00:00
254281cd5e Ice: don't create water for creative players, fixes #2622 2019-01-05 09:26:35 +00:00
5dfceeea98 Fix typo in command.op.take permission description 2019-01-04 23:56:29 +00:00
4b9a142a5d Import global functions and constants for enhanced performance
This is better for performance because these then don't need to be reevaluated every time they are called.

When encountering an unqualified function or constant reference, PHP will first try to locate a symbol in the current namespace by that name, and then fall back to the global namespace.
This short-circuits the check, which has substantial performance effects in some cases - in particular, ord(), chr() and strlen() show ~1500x faster calls when they are fully qualified.

However, this doesn't mean that PM is getting a massive amount faster. In real world terms, this translates to about 10-15% performance improvement.
But before anyone gets excited, you should know that the CodeOptimizer in the PreProcessor repo has been applying fully-qualified symbol optimizations to Jenkins builds for years, which is one of the reasons why Jenkins builds have better performance than home-built or source installations.
We're choosing to do this for the sake of future SafePHP integration and also to be able to get rid of the buggy CodeOptimizer, so that phar and source are more consistent.
2019-01-04 20:43:15 +00:00
0bacf51729 Fix another swathe of number_format() truncation bugs 2019-01-04 19:39:51 +00:00
33f6b441d8 Fixed /gc truncating memory freed
wtf PHP?
2019-01-04 17:30:35 +00:00
11b59498d9 TakeItemEntityPacket: add missing decode, close #2633 2019-01-04 11:45:37 +00:00
d71a543d10 Fixed a bunch of things PHPStan finds unpalatable
close #2614, fix a bunch of docs bugs, fix sendCreativeContents() crash on Human holders, move some inline variable declarations
2019-01-04 00:23:09 +00:00
5e0c3333cf Player: catch more specific exceptions for transactions 2019-01-03 17:57:37 +00:00
0f941410f6 Use more appropriate exceptions in the protocol layer 2019-01-03 17:57:06 +00:00
504cc3bf8b AddEntityPacket: fix some bugs in legacy ID conversion handling 2019-01-03 17:00:16 +00:00
6bd1491b8b AsyncPool: Apply a cooldown to workers to cut down unnecessary GC lag spikes
Since 3.2 there have been some runtime performance issues related to garbage collection and dynamic AsyncWorker booting. This is partly because of GC being dumb about shutting down what it thinks are "unused" workers. A worker which has been idle for a single tick is considered the same as a worker which has been idle for hours. The result of this is that on active servers, workers would get shut down and then immediately restarted because of something like chunk sending. Since booting an async worker is frightfully expensive, this causes lag spikes, which is obviously bad.

This commit changes the GC mechanism to only shutdown workers which have not been used for the last 5 minutes.
2019-01-03 15:06:53 +00:00
658786f2f6 TitleCommand: fix off-by-one bug in "times" subcommand 2019-01-02 21:04:25 +00:00
d34f3f1af3 Add a terminal message for the crash strangler 2019-01-02 19:10:05 +00:00
8650c187f9 Entity: fixed mob head yaw 2019-01-02 15:04:56 +00:00
4b4820cf53 3.5.5 is next 2019-01-01 13:55:45 +00:00
d33acc4fd0 Release 3.5.4 2019-01-01 12:33:17 +00:00
f7de6eb59f Network: Deprecate some garbage
Deprecations on a patch version breaks release protocol, but I don't care at this point. Nobody should have been using this shit anyway.
2018-12-31 22:52:39 +00:00
75a0627bf2 Network: cut this catch-all bullshit out as well
If a network interface crashes, it should take out the whole server, not try to keep on ticking.
2018-12-31 22:40:13 +00:00
8752e363c9 EXCUSE ME, HOW DARE YOU NOT LOG NETWORK ERRORS?! 2018-12-31 22:33:56 +00:00
9ed1b5ca7f Event: More detailed errors for non-cancellable events 2018-12-31 21:29:22 +00:00
1cbb31f1db Player: Reintroduce permission checks for command hints
This was removed way back in 2016 because of an unidentified bug which caused permissible commands not to show up on the client. Back then, command parsing and validity checks were client-sided, and the client would simply not send the command at all if it didn't recognize it. Now, that problem is gone, so it doesn't matter as much if there are permission bugs which cause commands to be erroneously missing.
closes #2625
2018-12-31 19:35:59 +00:00
1393b4c4e2 Player: aDd a HacK foR CliEnt SidE rIghT cLicK SpaM BuG
this bug has existed for so long I forgot it was still here. People stopped pestering me to do something about it, and as a result I forgot to do anything about it.

This hack isn't perfect, but it filters out the worst of the noise. It has side effects for legitimate fast double-clicks, but I don't think anyone will be too bothered - just click more slowly.

This hack may also have negative side effects on poor connections where latency spikes are a problem, but there isn't really much that can be done about that.
2018-12-31 19:16:13 +00:00
2921c86b3c Torch: fixed crash on blockupdate with corrupted meta 2018-12-30 19:50:35 +00:00
9c3a929b65 3.5.4 is next 2018-12-30 19:04:47 +00:00
290 changed files with 2523 additions and 586 deletions

View File

@ -4,3 +4,7 @@ root = yes
[*]
indent_size = 4
indent_style = tab
[*.yml]
indent_size = 2
indent_style = space

View File

@ -2,13 +2,14 @@ language: php
php:
- 7.2
- 7.3
before_script:
# - pecl install channel://pecl.php.net/pthreads-3.1.6
- echo | pecl install channel://pecl.php.net/yaml-2.0.2
- echo | pecl install channel://pecl.php.net/yaml-2.0.4
- git clone https://github.com/pmmp/pthreads.git
- cd pthreads
- git checkout c8cfacda84f21032d6014b53e72bf345ac901dac
- git checkout 6ca019c58b4fa09ee2ff490f2444e34bef0773d0
- phpize
- ./configure
- make

View File

@ -27,7 +27,7 @@
"pocketmine/raklib": "^0.12.0",
"pocketmine/spl": "^0.3.0",
"pocketmine/binaryutils": "^0.1.0",
"pocketmine/nbt": "^0.2.1",
"pocketmine/nbt": "^0.2.6",
"pocketmine/math": "^0.2.0",
"pocketmine/snooze": "^0.1.0",
"daverandom/callback-validator": "dev-master",

64
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "d3fb809caf4d5a5c99054f47f28ff271",
"content-hash": "2f5313e4ebd7b62c785cf683b27464b4",
"packages": [
{
"name": "adhocore/json-comment",
@ -92,16 +92,16 @@
},
{
"name": "pocketmine/binaryutils",
"version": "0.1.3",
"version": "0.1.8",
"source": {
"type": "git",
"url": "https://github.com/pmmp/BinaryUtils.git",
"reference": "925001c8eff97a36519b16bbd095964b0fc52772"
"reference": "33f511715d22418c03368b49b45a6c25d6b33806"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/925001c8eff97a36519b16bbd095964b0fc52772",
"reference": "925001c8eff97a36519b16bbd095964b0fc52772",
"url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/33f511715d22418c03368b49b45a6c25d6b33806",
"reference": "33f511715d22418c03368b49b45a6c25d6b33806",
"shasum": ""
},
"require": {
@ -119,23 +119,23 @@
],
"description": "Classes and methods for conveniently handling binary data",
"support": {
"source": "https://github.com/pmmp/BinaryUtils/tree/0.1.3",
"source": "https://github.com/pmmp/BinaryUtils/tree/0.1.8",
"issues": "https://github.com/pmmp/BinaryUtils/issues"
},
"time": "2018-12-30T12:17:51+00:00"
"time": "2019-01-16T17:31:44+00:00"
},
{
"name": "pocketmine/math",
"version": "0.2.1",
"version": "0.2.2",
"source": {
"type": "git",
"url": "https://github.com/pmmp/Math.git",
"reference": "ee299f5c9c444ca526c9c691b920f321458cf0b6"
"reference": "b755d3fb7025c4ddb7d9d6df0ba7e0b65125e51c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/Math/zipball/ee299f5c9c444ca526c9c691b920f321458cf0b6",
"reference": "ee299f5c9c444ca526c9c691b920f321458cf0b6",
"url": "https://api.github.com/repos/pmmp/Math/zipball/b755d3fb7025c4ddb7d9d6df0ba7e0b65125e51c",
"reference": "b755d3fb7025c4ddb7d9d6df0ba7e0b65125e51c",
"shasum": ""
},
"require": {
@ -153,23 +153,23 @@
],
"description": "PHP library containing math related code used in PocketMine-MP",
"support": {
"source": "https://github.com/pmmp/Math/tree/0.2.1",
"source": "https://github.com/pmmp/Math/tree/0.2.2",
"issues": "https://github.com/pmmp/Math/issues"
},
"time": "2018-08-15T15:43:27+00:00"
"time": "2019-01-04T15:42:36+00:00"
},
{
"name": "pocketmine/nbt",
"version": "0.2.3",
"version": "0.2.6",
"source": {
"type": "git",
"url": "https://github.com/pmmp/NBT.git",
"reference": "291bf5cc2a94500eada1edbda51d15bed25a1e1c"
"reference": "92eaf84dd61f700d3ec02ebd01b606cb5b1590d4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/NBT/zipball/291bf5cc2a94500eada1edbda51d15bed25a1e1c",
"reference": "291bf5cc2a94500eada1edbda51d15bed25a1e1c",
"url": "https://api.github.com/repos/pmmp/NBT/zipball/92eaf84dd61f700d3ec02ebd01b606cb5b1590d4",
"reference": "92eaf84dd61f700d3ec02ebd01b606cb5b1590d4",
"shasum": ""
},
"require": {
@ -194,23 +194,23 @@
],
"description": "PHP library for working with Named Binary Tags",
"support": {
"source": "https://github.com/pmmp/NBT/tree/0.2.3",
"source": "https://github.com/pmmp/NBT/tree/0.2.6",
"issues": "https://github.com/pmmp/NBT/issues"
},
"time": "2018-12-03T16:08:28+00:00"
"time": "2019-02-07T16:28:11+00:00"
},
{
"name": "pocketmine/raklib",
"version": "0.12.0",
"version": "0.12.2",
"source": {
"type": "git",
"url": "https://github.com/pmmp/RakLib.git",
"reference": "922da28efd828e2af6c19db1676ea9b6a267071c"
"reference": "54a36d55eeba0a182e00439920ee2fcfa8c72bf3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/RakLib/zipball/922da28efd828e2af6c19db1676ea9b6a267071c",
"reference": "922da28efd828e2af6c19db1676ea9b6a267071c",
"url": "https://api.github.com/repos/pmmp/RakLib/zipball/54a36d55eeba0a182e00439920ee2fcfa8c72bf3",
"reference": "54a36d55eeba0a182e00439920ee2fcfa8c72bf3",
"shasum": ""
},
"require": {
@ -235,23 +235,23 @@
],
"description": "A RakNet server implementation written in PHP",
"support": {
"source": "https://github.com/pmmp/RakLib/tree/0.12.0",
"source": "https://github.com/pmmp/RakLib/tree/0.12",
"issues": "https://github.com/pmmp/RakLib/issues"
},
"time": "2018-06-13T10:06:14+00:00"
"time": "2019-01-21T14:17:30+00:00"
},
{
"name": "pocketmine/snooze",
"version": "0.1.0",
"version": "0.1.1",
"source": {
"type": "git",
"url": "https://github.com/pmmp/Snooze.git",
"reference": "3cc9d0164230889acb08e22cc126133809e9d346"
"reference": "b7bd231bdb75e69300cac89ccd515fc731c38c40"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/Snooze/zipball/3cc9d0164230889acb08e22cc126133809e9d346",
"reference": "3cc9d0164230889acb08e22cc126133809e9d346",
"url": "https://api.github.com/repos/pmmp/Snooze/zipball/b7bd231bdb75e69300cac89ccd515fc731c38c40",
"reference": "b7bd231bdb75e69300cac89ccd515fc731c38c40",
"shasum": ""
},
"require": {
@ -269,10 +269,10 @@
],
"description": "Thread notification management library for code using the pthreads extension",
"support": {
"source": "https://github.com/pmmp/Snooze/tree/0.1.0",
"source": "https://github.com/pmmp/Snooze/tree/0.1.1",
"issues": "https://github.com/pmmp/Snooze/issues"
},
"time": "2018-06-13T09:36:11+00:00"
"time": "2019-01-04T15:54:45+00:00"
},
{
"name": "pocketmine/spl",
@ -302,7 +302,7 @@
],
"description": "Standard library files required by PocketMine-MP and related projects",
"support": {
"source": "https://github.com/pmmp/SPL/tree/master"
"source": "https://github.com/pmmp/SPL/tree/0.3.2"
},
"time": "2018-08-12T15:17:39+00:00"
}

View File

@ -51,7 +51,7 @@ PROJECT_BRIEF =
# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo
# to the output directory.
PROJECT_LOGO = "/home/jenkins/PocketMine-h-64.png"
PROJECT_LOGO =
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
# into which the generated documentation will be written. If a relative path is
@ -240,7 +240,7 @@ OPTIMIZE_OUTPUT_FOR_C = NO
# qualified scopes will look different, etc.
# The default value is: NO.
OPTIMIZE_OUTPUT_JAVA = YES
OPTIMIZE_OUTPUT_JAVA = NO
# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
# sources. Doxygen will then generate output that is tailored for Fortran.
@ -737,7 +737,9 @@ WARN_LOGFILE =
# spaces.
# Note: If this tag is empty the current directory is searched.
INPUT = ./
INPUT = ./src \
./vendor/pocketmine \
./README.md
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
@ -757,9 +759,7 @@ INPUT_ENCODING = UTF-8
# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
# *.qsf, *.as and *.js.
FILE_PATTERNS = *.php \
*.sh \
*.md
FILE_PATTERNS = *.php
# The RECURSIVE tag can be used to specify whether or not subdirectories should
# be searched for input files as well.
@ -793,7 +793,10 @@ EXCLUDE_SYMLINKS = YES
EXCLUDE_PATTERNS = */bin/* \
*/players/* \
*/worlds/* \
*/plugins/*
*/plugins/* \
*/plugin_data/* \
*/tests/* \
*/stubs/*
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the
@ -878,7 +881,7 @@ FILTER_SOURCE_PATTERNS =
# (index.html). This can be useful if you have a project on for instance GitHub
# and want to reuse the introduction page also for the doxygen output.
USE_MDFILE_AS_MAINPAGE = README.md
USE_MDFILE_AS_MAINPAGE = ./README.md
#---------------------------------------------------------------------------
# Configuration options related to source browsing

View File

@ -30,6 +30,55 @@ use pocketmine\plugin\PluginManager;
use pocketmine\utils\Utils;
use pocketmine\utils\VersionString;
use raklib\RakLib;
use function base64_encode;
use function date;
use function error_get_last;
use function fclose;
use function file;
use function file_exists;
use function file_get_contents;
use function fopen;
use function fwrite;
use function get_loaded_extensions;
use function implode;
use function is_dir;
use function is_resource;
use function json_encode;
use function json_last_error_msg;
use function max;
use function mkdir;
use function ob_end_clean;
use function ob_get_contents;
use function ob_start;
use function php_uname;
use function phpinfo;
use function phpversion;
use function preg_replace;
use function str_split;
use function strpos;
use function substr;
use function time;
use function zend_version;
use function zlib_encode;
use const E_COMPILE_ERROR;
use const E_COMPILE_WARNING;
use const E_CORE_ERROR;
use const E_CORE_WARNING;
use const E_DEPRECATED;
use const E_ERROR;
use const E_NOTICE;
use const E_PARSE;
use const E_RECOVERABLE_ERROR;
use const E_STRICT;
use const E_USER_DEPRECATED;
use const E_USER_ERROR;
use const E_USER_NOTICE;
use const E_USER_WARNING;
use const E_WARNING;
use const FILE_IGNORE_NEW_LINES;
use const JSON_UNESCAPED_SLASHES;
use const PHP_EOL;
use const PHP_OS;
class CrashDump{
@ -39,7 +88,11 @@ class CrashDump{
* having their content changed, version format changing, etc.
* It is not necessary to increase this when adding new fields.
*/
private const FORMAT_VERSION = 1;
private const FORMAT_VERSION = 2;
private const PLUGIN_INVOLVEMENT_NONE = "none";
private const PLUGIN_INVOLVEMENT_DIRECT = "direct";
private const PLUGIN_INVOLVEMENT_INDIRECT = "indirect";
/** @var Server */
private $server;
@ -94,7 +147,11 @@ class CrashDump{
$this->addLine("----------------------REPORT THE DATA BELOW THIS LINE-----------------------");
$this->addLine();
$this->addLine("===BEGIN CRASH DUMP===");
$this->encodedData = zlib_encode(json_encode($this->data, JSON_UNESCAPED_SLASHES), ZLIB_ENCODING_DEFLATE, 9);
$json = json_encode($this->data, JSON_UNESCAPED_SLASHES);
if($json === false){
throw new \RuntimeException("Failed to encode crashdump JSON: " . json_last_error_msg());
}
$this->encodedData = zlib_encode($json, ZLIB_ENCODING_DEFLATE, 9);
foreach(str_split(base64_encode($this->encodedData), 76) as $line){
$this->addLine($line);
}
@ -159,7 +216,7 @@ class CrashDump{
$error = $lastExceptionError;
}else{
$error = (array) error_get_last();
$error["trace"] = Utils::printableCurrentTrace(3); //Skipping CrashDump->baseCrash, CrashDump->construct, Server->crashDump
$error["trace"] = Utils::currentTrace(3); //Skipping CrashDump->baseCrash, CrashDump->construct, Server->crashDump
$errorConversion = [
E_ERROR => "E_ERROR",
E_WARNING => "E_WARNING",
@ -186,6 +243,9 @@ class CrashDump{
}
if(isset($lastError)){
if(isset($lastError["trace"])){
$lastError["trace"] = Utils::printableTrace($lastError["trace"]);
}
$this->data["lastError"] = $lastError;
}
@ -197,24 +257,16 @@ class CrashDump{
$this->addLine("Line: " . $error["line"]);
$this->addLine("Type: " . $error["type"]);
if(strpos($error["file"], "src/pocketmine/") === false and strpos($error["file"], "vendor/pocketmine/") === false and file_exists($error["fullFile"])){
$this->addLine();
$this->addLine("THIS CRASH WAS CAUSED BY A PLUGIN");
$this->data["plugin"] = true;
$reflection = new \ReflectionClass(PluginBase::class);
$file = $reflection->getProperty("file");
$file->setAccessible(true);
foreach($this->server->getPluginManager()->getPlugins() as $plugin){
$filePath = Utils::cleanPath($file->getValue($plugin));
if(strpos($error["file"], $filePath) === 0){
$this->data["plugin"] = $plugin->getName();
$this->addLine("BAD PLUGIN: " . $plugin->getDescription()->getFullName());
$this->data["plugin_involvement"] = self::PLUGIN_INVOLVEMENT_NONE;
if(!$this->determinePluginFromFile($error["fullFile"], true)){ //fatal errors won't leave any stack trace
foreach($error["trace"] as $frame){
if(!isset($frame["file"])){
continue; //PHP core
}
if($this->determinePluginFromFile($frame["file"], false)){
break;
}
}
}else{
$this->data["plugin"] = false;
}
$this->addLine();
@ -231,12 +283,40 @@ class CrashDump{
$this->addLine();
$this->addLine("Backtrace:");
foreach(($this->data["trace"] = $error["trace"]) as $line){
foreach(($this->data["trace"] = Utils::printableTrace($error["trace"])) as $line){
$this->addLine($line);
}
$this->addLine();
}
private function determinePluginFromFile(string $filePath, bool $crashFrame) : bool{
$frameCleanPath = Utils::cleanPath($filePath); //this will be empty in phar stub
if($frameCleanPath !== "" and strpos($frameCleanPath, "src/pocketmine/") === false and strpos($frameCleanPath, "vendor/pocketmine/") === false and file_exists($filePath)){
$this->addLine();
if($crashFrame){
$this->addLine("THIS CRASH WAS CAUSED BY A PLUGIN");
$this->data["plugin_involvement"] = self::PLUGIN_INVOLVEMENT_DIRECT;
}else{
$this->addLine("A PLUGIN WAS INVOLVED IN THIS CRASH");
$this->data["plugin_involvement"] = self::PLUGIN_INVOLVEMENT_INDIRECT;
}
$reflection = new \ReflectionClass(PluginBase::class);
$file = $reflection->getProperty("file");
$file->setAccessible(true);
foreach($this->server->getPluginManager()->getPlugins() as $plugin){
$filePath = Utils::cleanPath($file->getValue($plugin));
if(strpos($frameCleanPath, $filePath) === 0){
$this->data["plugin"] = $plugin->getName();
$this->addLine("BAD PLUGIN: " . $plugin->getDescription()->getFullName());
break;
}
}
return true;
}
return false;
}
private function generalData(){
$version = new VersionString(\pocketmine\BASE_VERSION, \pocketmine\IS_DEVELOPMENT_BUILD, \pocketmine\BUILD_NUMBER);
$this->data["general"] = [];

View File

@ -28,6 +28,39 @@ use pocketmine\scheduler\DumpWorkerMemoryTask;
use pocketmine\scheduler\GarbageCollectionTask;
use pocketmine\timings\Timings;
use pocketmine\utils\Utils;
use function arsort;
use function count;
use function fclose;
use function file_exists;
use function file_put_contents;
use function fopen;
use function fwrite;
use function gc_collect_cycles;
use function gc_disable;
use function gc_enable;
use function get_class;
use function get_declared_classes;
use function implode;
use function ini_get;
use function ini_set;
use function is_array;
use function is_object;
use function is_resource;
use function is_string;
use function json_encode;
use function min;
use function mkdir;
use function preg_match;
use function print_r;
use function round;
use function spl_object_hash;
use function sprintf;
use function strlen;
use function strtoupper;
use function substr;
use const JSON_PRETTY_PRINT;
use const JSON_UNESCAPED_SLASHES;
use const SORT_NUMERIC;
class MemoryManager{

View File

@ -26,6 +26,7 @@ namespace pocketmine;
use pocketmine\block\Bed;
use pocketmine\block\Block;
use pocketmine\block\BlockFactory;
use pocketmine\block\UnknownBlock;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\entity\Effect;
@ -160,6 +161,41 @@ use pocketmine\tile\Tile;
use pocketmine\timings\Timings;
use pocketmine\utils\TextFormat;
use pocketmine\utils\UUID;
use function abs;
use function array_merge;
use function assert;
use function base64_decode;
use function ceil;
use function count;
use function explode;
use function floor;
use function fmod;
use function get_class;
use function gettype;
use function implode;
use function in_array;
use function is_int;
use function is_object;
use function is_string;
use function json_encode;
use function json_last_error_msg;
use function lcg_value;
use function max;
use function microtime;
use function min;
use function preg_match;
use function round;
use function spl_object_hash;
use function sqrt;
use function strlen;
use function strpos;
use function strtolower;
use function substr;
use function trim;
use function ucfirst;
use const M_PI;
use const M_SQRT3;
use const PHP_INT_MAX;
/**
@ -327,6 +363,11 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** @var Form[] */
protected $forms = [];
/** @var float */
protected $lastRightClickTime = 0.0;
/** @var Vector3|null */
protected $lastRightClickPos = null;
/**
* @return TranslationContainer|string
*/
@ -436,8 +477,11 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
}
public function setFlying(bool $value){
$this->flying = $value;
$this->sendSettings();
if($this->flying !== $value){
$this->flying = $value;
$this->resetFallDistance();
$this->sendSettings();
}
}
public function isFlying() : bool{
@ -649,14 +693,14 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$this->perm->recalculatePermissions();
if($this->hasPermission(Server::BROADCAST_CHANNEL_USERS)){
$permManager->subscribeToPermission(Server::BROADCAST_CHANNEL_USERS, $this);
}
if($this->hasPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE)){
$permManager->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this);
}
if($this->spawned){
if($this->hasPermission(Server::BROADCAST_CHANNEL_USERS)){
$permManager->subscribeToPermission(Server::BROADCAST_CHANNEL_USERS, $this);
}
if($this->hasPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE)){
$permManager->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this);
}
$this->sendCommandData();
}
}
@ -671,7 +715,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
public function sendCommandData(){
$pk = new AvailableCommandsPacket();
foreach($this->server->getCommandMap()->getCommands() as $name => $command){
if(isset($pk->commandData[$command->getName()]) or $command->getName() === "help"){
if(isset($pk->commandData[$command->getName()]) or $command->getName() === "help" or !$command->testPermissionSilent($this)){
continue;
}
@ -1037,6 +1081,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$this->server->broadcastMessage($ev->getJoinMessage());
}
$this->setImmobile(false);
$this->noDamageTicks = 60;
foreach($this->usedChunks as $index => $c){
@ -1369,19 +1414,17 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$this->allowFlight = $this->isCreative();
if($this->isSpectator()){
$this->flying = true;
$this->setFlying(true);
$this->keepMovement = true;
$this->despawnFromAll();
}else{
$this->keepMovement = $this->allowMovementCheats;
if($this->isSurvival()){
$this->flying = false;
$this->setFlying(false);
}
$this->spawnToAll();
}
$this->resetFallDistance();
$this->namedtag->setInt("playerGameType", $this->gamemode);
if(!$client){ //Gamemode changed by server, do not send for client changes
$this->sendGamemode();
@ -1607,7 +1650,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
}else{
$this->broadcastMovement();
$distance = $from->distance($to);
$distance = sqrt((($from->x - $to->x) ** 2) + (($from->z - $to->z) ** 2));
//TODO: check swimming (adds 0.015 exhaustion in MCPE)
if($this->isSprinting()){
$this->exhaust(0.1 * $distance, PlayerExhaustEvent::CAUSE_SPRINTING);
@ -1638,6 +1681,12 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$this->newPosition = null;
}
public function fall(float $fallDistance) : void{
if(!$this->flying){
parent::fall($fallDistance);
}
}
public function jump() : void{
(new PlayerJumpEvent($this))->call();
parent::jump();
@ -2104,6 +2153,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$this->setNameTagVisible();
$this->setNameTagAlwaysVisible();
$this->setCanClimb();
$this->setImmobile(); //disable pre-spawn movement
$this->server->getLogger()->info($this->getServer()->getLanguage()->translateString("pocketmine.player.logIn", [
TextFormat::AQUA . $this->username . TextFormat::WHITE,
@ -2263,7 +2313,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
if($action !== null){
$actions[] = $action;
}
}catch(\Exception $e){
}catch(\UnexpectedValueException $e){
$this->server->getLogger()->debug("Unhandled inventory action from " . $this->getName() . ": " . $e->getMessage());
$this->sendAllInventories();
return false;
@ -2333,6 +2383,19 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$type = $packet->trData->actionType;
switch($type){
case InventoryTransactionPacket::USE_ITEM_ACTION_CLICK_BLOCK:
//TODO: start hack for client spam bug
$spamBug = ($this->lastRightClickPos !== null and
microtime(true) - $this->lastRightClickTime < 0.1 and //100ms
$this->lastRightClickPos->distanceSquared($packet->trData->clickPos) < 0.00001 //signature spam bug has 0 distance, but allow some error
);
//get rid of continued spam if the player clicks and holds right-click
$this->lastRightClickPos = clone $packet->trData->clickPos;
$this->lastRightClickTime = microtime(true);
if($spamBug){
return true;
}
//TODO: end hack for client spam bug
$this->setUsingItem(false);
if(!$this->canInteract($blockVector->add(0.5, 0.5, 0.5), 13) or $this->isSpectator()){
@ -2660,6 +2723,9 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
public function handleBlockPickRequest(BlockPickRequestPacket $packet) : bool{
$block = $this->level->getBlockAt($packet->blockX, $packet->blockY, $packet->blockZ);
if($block instanceof UnknownBlock){
return true;
}
$item = $block->getPickedItem();
if($packet->addUserData){
@ -2884,8 +2950,9 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$ev->call();
if($ev->isCancelled()){
$this->sendSettings();
}else{
}else{ //don't use setFlying() here, to avoid feedback loops
$this->flying = $ev->isFlying();
$this->resetFallDistance();
}
$handled = true;
@ -3573,10 +3640,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
}
protected function onDeathUpdate(int $tickDiff) : bool{
if(parent::onDeathUpdate($tickDiff)){
$this->despawnFromAll(); //non-player entities rely on close() to do this for them
}
parent::onDeathUpdate($tickDiff);
return false; //never flag players for despawn
}
@ -3830,13 +3894,13 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
* @param Inventory $inventory
* @param bool $force Forces removal of permanent windows such as normal inventory, cursor
*
* @throws \BadMethodCallException if trying to remove a fixed inventory window without the `force` parameter as true
* @throws \InvalidArgumentException if trying to remove a fixed inventory window without the `force` parameter as true
*/
public function removeWindow(Inventory $inventory, bool $force = false){
$id = $this->windows[$hash = spl_object_hash($inventory)] ?? null;
if($id !== null and !$force and isset($this->permanentWindows[$id])){
throw new \BadMethodCallException("Cannot remove fixed window $id (" . get_class($inventory) . ") from " . $this->getName());
throw new \InvalidArgumentException("Cannot remove fixed window $id (" . get_class($inventory) . ") from " . $this->getName());
}
$inventory->close($this);

View File

@ -37,7 +37,7 @@ namespace pocketmine {
use pocketmine\wizard\SetupWizard;
const NAME = "PocketMine-MP";
const BASE_VERSION = "3.5.3";
const BASE_VERSION = "3.6.0";
const IS_DEVELOPMENT_BUILD = false;
const BUILD_NUMBER = 0;

View File

@ -98,7 +98,6 @@ use pocketmine\tile\Tile;
use pocketmine\timings\Timings;
use pocketmine\timings\TimingsHandler;
use pocketmine\updater\AutoUpdater;
use pocketmine\utils\Binary;
use pocketmine\utils\Config;
use pocketmine\utils\Internet;
use pocketmine\utils\MainLogger;
@ -106,6 +105,77 @@ use pocketmine\utils\Terminal;
use pocketmine\utils\TextFormat;
use pocketmine\utils\Utils;
use pocketmine\utils\UUID;
use function array_filter;
use function array_key_exists;
use function array_shift;
use function array_sum;
use function asort;
use function assert;
use function base64_encode;
use function bin2hex;
use function class_exists;
use function count;
use function define;
use function explode;
use function extension_loaded;
use function file_exists;
use function file_get_contents;
use function file_put_contents;
use function filemtime;
use function floor;
use function function_exists;
use function gc_collect_cycles;
use function get_class;
use function getmypid;
use function getopt;
use function gettype;
use function implode;
use function ini_get;
use function ini_set;
use function is_array;
use function is_bool;
use function is_dir;
use function is_object;
use function is_string;
use function is_subclass_of;
use function json_decode;
use function max;
use function microtime;
use function min;
use function mkdir;
use function pcntl_signal;
use function pcntl_signal_dispatch;
use function preg_replace;
use function random_bytes;
use function random_int;
use function realpath;
use function register_shutdown_function;
use function rename;
use function round;
use function scandir;
use function sleep;
use function spl_object_hash;
use function sprintf;
use function str_repeat;
use function str_replace;
use function stripos;
use function strlen;
use function strrpos;
use function strtolower;
use function substr;
use function time;
use function touch;
use function trim;
use const DIRECTORY_SEPARATOR;
use const INT32_MAX;
use const INT32_MIN;
use const PHP_EOL;
use const PHP_INT_MAX;
use const PTHREADS_INHERIT_NONE;
use const SCANDIR_SORT_NONE;
use const SIGHUP;
use const SIGINT;
use const SIGTERM;
/**
* The class that manages everything
@ -1059,7 +1129,7 @@ class Server{
return false;
}
$seed = $seed ?? Binary::readInt(random_bytes(4));
$seed = $seed ?? random_int(INT32_MIN, INT32_MAX);
if(!isset($options["preset"])){
$options["preset"] = $this->getConfigString("generator-settings", "");
@ -1449,8 +1519,6 @@ class Server{
"announce-player-achievements" => true,
"spawn-protection" => 16,
"max-players" => 20,
"spawn-animals" => true,
"spawn-mobs" => true,
"gamemode" => 0,
"force-gamemode" => false,
"hardcore" => false,
@ -1485,7 +1553,7 @@ class Server{
return;
}
if(((int) ini_get('zend.assertions')) > 0 and ((bool) $this->getProperty("debug.assertions.warn-if-enabled", true)) !== false){
if(((int) ini_get('zend.assertions')) !== -1){
$this->logger->warning("Debugging assertions are enabled, this may impact on performance. To disable them, set `zend.assertions = -1` in php.ini.");
}
@ -1663,7 +1731,9 @@ class Server{
GeneratorManager::registerDefaultGenerators();
foreach((array) $this->getProperty("worlds", []) as $name => $options){
if(!is_array($options)){
if($options === null){
$options = [];
}elseif(!is_array($options)){
continue;
}
if(!$this->loadLevel($name)){
@ -2173,7 +2243,7 @@ class Server{
"fullFile" => $e->getFile(),
"file" => $errfile,
"line" => $errline,
"trace" => Utils::printableTrace($trace)
"trace" => $trace
];
global $lastExceptionError, $lastError;
@ -2212,7 +2282,7 @@ class Server{
if(is_string($plugin)){
$p = $this->pluginManager->getPlugin($plugin);
if($p instanceof Plugin and !($p->getPluginLoader() instanceof PharPluginLoader)){
$report = false;
$this->logger->debug("Not sending crashdump due to caused by non-phar plugin");
}
}
@ -2254,6 +2324,7 @@ class Server{
//Force minimum uptime to be >= 120 seconds, to reduce the impact of spammy crash loops
$spacing = ((int) \pocketmine\START_TIME) - time() + 120;
if($spacing > 0){
echo "--- Waiting $spacing seconds to throttle automatic restart (you can kill the process safely now) ---" . PHP_EOL;
sleep($spacing);
}
@Utils::kill(getmypid());
@ -2491,9 +2562,7 @@ class Server{
$this->logger->debug("Unhandled raw packet from $address $port: " . bin2hex($payload));
}
}catch(\Throwable $e){
if(\pocketmine\DEBUG > 1){
$this->logger->logException($e);
}
$this->logger->logException($e);
$this->getNetwork()->blockAddress($address, 600);
}
@ -2584,10 +2653,9 @@ class Server{
TimingsHandler::tick($this->currentTPS <= $this->profilingTickRate);
array_shift($this->tickAverage);
$this->tickAverage[] = $this->currentTPS;
array_shift($this->useAverage);
$this->useAverage[] = $this->currentUse;
$idx = $this->tickCounter % 20;
$this->tickAverage[$idx] = $this->currentTPS;
$this->useAverage[$idx] = $this->currentUse;
if(($this->nextTick - $tickTime) < -1){
$this->nextTick = $tickTime;

View File

@ -28,7 +28,7 @@ namespace pocketmine;
*/
abstract class Thread extends \Thread{
/** @var \ClassLoader */
/** @var \ClassLoader|null */
protected $classLoader;
/** @var string|null */
protected $composerAutoloaderPath;

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace pocketmine;
use pocketmine\utils\MainLogger;
use function spl_object_hash;
class ThreadManager extends \Volatile{

View File

@ -28,7 +28,7 @@ namespace pocketmine;
*/
abstract class Worker extends \Worker{
/** @var \ClassLoader */
/** @var \ClassLoader|null */
protected $classLoader;
/** @var string|null */
protected $composerAutoloaderPath;

View File

@ -26,6 +26,13 @@ namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\math\Vector3;
use pocketmine\Player;
use function array_map;
use function array_reverse;
use function array_search;
use function array_shift;
use function count;
use function implode;
use function in_array;
abstract class BaseRail extends Flowable{
@ -98,7 +105,7 @@ abstract class BaseRail extends Flowable{
$meta = array_search(array_reverse($connections), $lookup, true);
}
if($meta === false){
throw new \InvalidArgumentException("No meta value matches connections " . implode(", ", array_map('dechex', $connections)));
throw new \InvalidArgumentException("No meta value matches connections " . implode(", ", array_map('\dechex', $connections)));
}
return $meta;

View File

@ -25,6 +25,7 @@ namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\item\ItemFactory;
use function mt_rand;
class Beetroot extends Crops{

View File

@ -38,6 +38,9 @@ use pocketmine\metadata\Metadatable;
use pocketmine\metadata\MetadataValue;
use pocketmine\Player;
use pocketmine\plugin\Plugin;
use function array_merge;
use function get_class;
use const PHP_INT_MAX;
class Block extends Position implements BlockIds, Metadatable{
@ -266,6 +269,7 @@ class Block extends Position implements BlockIds, Metadatable{
* @param Item $item
*
* @return float
* @throws \InvalidArgumentException if the item efficiency is not a positive number
*/
public function getBreakTime(Item $item) : float{
$base = $this->getHardness();
@ -277,7 +281,7 @@ class Block extends Position implements BlockIds, Metadatable{
$efficiency = $item->getMiningEfficiency($this);
if($efficiency <= 0){
throw new \RuntimeException("Item efficiency is invalid");
throw new \InvalidArgumentException(get_class($item) . " has invalid mining efficiency: expected >= 0, got $efficiency");
}
$base /= $efficiency;

View File

@ -25,6 +25,10 @@ namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\level\Position;
use function file_get_contents;
use function json_decode;
use function max;
use function min;
/**
* Manages block registration and instance creation
@ -426,8 +430,13 @@ class BlockFactory{
public static function registerStaticRuntimeIdMappings() : void{
/** @var mixed[] $runtimeIdMap */
$runtimeIdMap = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . "runtimeid_table.json"), true);
$legacyIdMap = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . "legacy_id_map.json"), true);
foreach($runtimeIdMap as $k => $obj){
self::registerMapping($k, $obj["id"], $obj["data"]);
//this has to use the json offset to make sure the mapping is consistent with what we send over network, even though we aren't using all the entries
if(!isset($legacyIdMap[$obj["name"]])){
continue;
}
self::registerMapping($k, $legacyIdMap[$obj["name"]], $obj["data"]);
}
}

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace pocketmine\block;
use pocketmine\item\Item;
use function mt_rand;
class BrownMushroomBlock extends RedMushroomBlock{

View File

@ -96,9 +96,12 @@ class Cactus extends Transparent{
if($b->getId() === self::AIR){
$ev = new BlockGrowEvent($b, BlockFactory::get(Block::CACTUS));
$ev->call();
if(!$ev->isCancelled()){
$this->getLevel()->setBlock($b, $ev->getNewState(), true);
if($ev->isCancelled()){
break;
}
$this->getLevel()->setBlock($b, $ev->getNewState(), true);
}else{
break;
}
}
$this->meta = 0;

View File

@ -25,6 +25,7 @@ namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\item\ItemFactory;
use function mt_rand;
class Carrot extends Crops{

View File

@ -26,6 +26,7 @@ namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\item\ItemFactory;
use pocketmine\item\TieredTool;
use function mt_rand;
class CoalOre extends Solid{

View File

@ -27,6 +27,7 @@ use pocketmine\event\block\BlockGrowEvent;
use pocketmine\item\Item;
use pocketmine\math\Vector3;
use pocketmine\Player;
use function mt_rand;
abstract class Crops extends Flowable{
@ -42,7 +43,7 @@ abstract class Crops extends Flowable{
public function onActivate(Item $item, Player $player = null) : bool{
if($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->meta += mt_rand(2, 5);
if($block->meta > 7){

View File

@ -27,6 +27,7 @@ use pocketmine\item\Item;
use pocketmine\item\ItemFactory;
use pocketmine\math\Vector3;
use pocketmine\Player;
use function mt_rand;
class DeadBush extends Flowable{

View File

@ -26,6 +26,7 @@ namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\item\ItemFactory;
use pocketmine\item\TieredTool;
use function mt_rand;
class DiamondOre extends Solid{

View File

@ -27,6 +27,7 @@ use pocketmine\item\Item;
use pocketmine\item\ItemFactory;
use pocketmine\math\Vector3;
use pocketmine\Player;
use function mt_rand;
class DoublePlant extends Flowable{
public const BITFLAG_TOP = 0x08;

View File

@ -26,6 +26,7 @@ namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\item\ItemFactory;
use pocketmine\item\TieredTool;
use function mt_rand;
class EmeraldOre extends Solid{

View File

@ -31,6 +31,8 @@ use pocketmine\event\entity\EntityDamageByBlockEvent;
use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\item\Item;
use pocketmine\math\Vector3;
use function min;
use function mt_rand;
class Fire extends Flowable{

View File

@ -25,6 +25,7 @@ namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\item\ItemFactory;
use function mt_rand;
class Glowstone extends Transparent{

View File

@ -32,6 +32,7 @@ use pocketmine\level\generator\object\TallGrass as TallGrassObject;
use pocketmine\math\Vector3;
use pocketmine\Player;
use pocketmine\utils\Random;
use function mt_rand;
class Grass extends Solid{

View File

@ -25,6 +25,7 @@ namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\item\ItemFactory;
use function mt_rand;
class Gravel extends Fallable{

View File

@ -56,7 +56,7 @@ class Ice extends Transparent{
}
public function onBreak(Item $item, Player $player = null) : bool{
if(!$item->hasEnchantment(Enchantment::SILK_TOUCH)){
if(($player === null or $player->isSurvival()) and !$item->hasEnchantment(Enchantment::SILK_TOUCH)){
return $this->getLevel()->setBlock($this, BlockFactory::get(Block::WATER), true);
}
return parent::onBreak($item, $player);

View File

@ -28,6 +28,7 @@ use pocketmine\math\Vector3;
use pocketmine\Player;
use pocketmine\tile\ItemFrame as TileItemFrame;
use pocketmine\tile\Tile;
use function lcg_value;
class ItemFrame extends Flowable{
protected $id = Block::ITEM_FRAME_BLOCK;
@ -64,7 +65,7 @@ class ItemFrame extends Flowable{
2 => Vector3::SIDE_NORTH,
3 => Vector3::SIDE_SOUTH
];
if(!$this->getSide($sides[$this->meta])->isSolid()){
if(isset($sides[$this->meta]) and !$this->getSide($sides[$this->meta])->isSolid()){
$this->level->useBreakOn($this);
}
}

View File

@ -26,6 +26,7 @@ namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\item\ItemFactory;
use pocketmine\item\TieredTool;
use function mt_rand;
class LapisOre extends Solid{

View File

@ -28,6 +28,7 @@ use pocketmine\item\Item;
use pocketmine\item\ItemFactory;
use pocketmine\math\Vector3;
use pocketmine\Player;
use function mt_rand;
class Leaves extends Transparent{
public const OAK = 0;

View File

@ -31,6 +31,9 @@ use pocketmine\level\Level;
use pocketmine\level\sound\FizzSound;
use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Vector3;
use function array_fill;
use function lcg_value;
use function min;
abstract class Liquid extends Transparent{

View File

@ -25,6 +25,7 @@ namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\item\ItemFactory;
use function mt_rand;
class Melon extends Transparent{

View File

@ -27,6 +27,7 @@ use pocketmine\event\block\BlockGrowEvent;
use pocketmine\item\Item;
use pocketmine\item\ItemFactory;
use pocketmine\math\Vector3;
use function mt_rand;
class MelonStem extends Crops{

View File

@ -25,6 +25,7 @@ namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\item\TieredTool;
use function mt_rand;
class MonsterSpawner extends Transparent{

View File

@ -27,6 +27,7 @@ use pocketmine\event\block\BlockSpreadEvent;
use pocketmine\item\Item;
use pocketmine\item\ItemFactory;
use pocketmine\math\Vector3;
use function mt_rand;
class Mycelium extends Solid{

View File

@ -26,6 +26,7 @@ namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\item\ItemFactory;
use pocketmine\item\TieredTool;
use function mt_rand;
class NetherQuartzOre extends Solid{

View File

@ -29,6 +29,7 @@ use pocketmine\item\Item;
use pocketmine\item\ItemFactory;
use pocketmine\math\Vector3;
use pocketmine\Player;
use function mt_rand;
class NetherWartPlant extends Flowable{
protected $id = Block::NETHER_WART_PLANT;

View File

@ -25,6 +25,7 @@ namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\item\ItemFactory;
use function mt_rand;
class Potato extends Crops{

View File

@ -27,6 +27,7 @@ use pocketmine\event\block\BlockGrowEvent;
use pocketmine\item\Item;
use pocketmine\item\ItemFactory;
use pocketmine\math\Vector3;
use function mt_rand;
class PumpkinStem extends Crops{

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace pocketmine\block;
use pocketmine\item\Item;
use function mt_rand;
class RedMushroomBlock extends Solid{

View File

@ -28,6 +28,7 @@ use pocketmine\item\ItemFactory;
use pocketmine\item\TieredTool;
use pocketmine\math\Vector3;
use pocketmine\Player;
use function mt_rand;
class RedstoneOre extends Solid{

View File

@ -28,6 +28,7 @@ use pocketmine\level\generator\object\Tree;
use pocketmine\math\Vector3;
use pocketmine\Player;
use pocketmine\utils\Random;
use function mt_rand;
class Sapling extends Flowable{
public const OAK = 0;

View File

@ -29,6 +29,7 @@ use pocketmine\math\Vector3;
use pocketmine\Player;
use pocketmine\tile\Sign as TileSign;
use pocketmine\tile\Tile;
use function floor;
class SignPost extends Transparent{

View File

@ -89,7 +89,7 @@ abstract class Stair extends Transparent{
2 => 1,
3 => 3
];
$this->meta = $faces[$player->getDirection()] & 0x03;
$this->meta = $player !== null ? $faces[$player->getDirection()] & 0x03 : 0;
if(($clickVector->y > 0.5 and $face !== Vector3::SIDE_UP) or $face === Vector3::SIDE_DOWN){
$this->meta |= 0x04; //Upside-down stairs
}

View File

@ -30,6 +30,7 @@ use pocketmine\math\Vector3;
use pocketmine\Player;
use pocketmine\tile\Banner as TileBanner;
use pocketmine\tile\Tile;
use function floor;
class StandingBanner extends Transparent{

View File

@ -50,9 +50,11 @@ class Sugarcane extends Flowable{
if($b->getId() === self::AIR){
$ev = new BlockGrowEvent($b, BlockFactory::get(Block::SUGARCANE_BLOCK));
$ev->call();
if(!$ev->isCancelled()){
$this->getLevel()->setBlock($b, $ev->getNewState(), true);
if($ev->isCancelled()){
break;
}
$this->getLevel()->setBlock($b, $ev->getNewState(), true);
}else{
break;
}
}

View File

@ -30,6 +30,9 @@ use pocketmine\item\Item;
use pocketmine\math\Vector3;
use pocketmine\Player;
use pocketmine\utils\Random;
use function cos;
use function sin;
use const M_PI;
class TNT extends Solid{

View File

@ -27,6 +27,7 @@ use pocketmine\item\Item;
use pocketmine\item\ItemFactory;
use pocketmine\math\Vector3;
use pocketmine\Player;
use function mt_rand;
class TallGrass extends Flowable{
@ -50,8 +51,8 @@ class TallGrass extends Flowable{
}
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
$down = $this->getSide(Vector3::SIDE_DOWN);
if($down->getId() === self::GRASS){
$down = $this->getSide(Vector3::SIDE_DOWN)->getId();
if($down === self::GRASS or $down === self::DIRT){
$this->getLevel()->setBlock($blockReplace, $this, true);
return true;

View File

@ -45,8 +45,8 @@ class Torch extends Flowable{
public function onNearbyBlockChange() : void{
$below = $this->getSide(Vector3::SIDE_DOWN);
$side = $this->getDamage();
$faces = [
$meta = $this->getDamage();
static $faces = [
0 => Vector3::SIDE_DOWN,
1 => Vector3::SIDE_WEST,
2 => Vector3::SIDE_EAST,
@ -54,8 +54,9 @@ class Torch extends Flowable{
4 => Vector3::SIDE_SOUTH,
5 => Vector3::SIDE_DOWN
];
$face = $faces[$meta] ?? Vector3::SIDE_DOWN;
if($this->getSide($faces[$side])->isTransparent() and !($faces[$side] === Vector3::SIDE_DOWN and ($below->getId() === self::FENCE or $below->getId() === self::COBBLESTONE_WALL))){
if($this->getSide($face)->isTransparent() and !($face === Vector3::SIDE_DOWN and ($below->getId() === self::FENCE or $below->getId() === self::COBBLESTONE_WALL))){
$this->getLevel()->useBreakOn($this);
}
}

View File

@ -28,6 +28,8 @@ use pocketmine\item\Item;
use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Vector3;
use pocketmine\Player;
use function max;
use function min;
class Vine extends Flowable{
public const FLAG_SOUTH = 0x01;

View File

@ -67,7 +67,7 @@ class Water extends Liquid{
public function onEntityCollide(Entity $entity) : void{
$entity->resetFallDistance();
if($entity->fireTicks > 0){
if($entity->isOnFire()){
$entity->extinguish();
}

View File

@ -25,6 +25,7 @@ namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\item\ItemFactory;
use function mt_rand;
class Wheat extends Crops{

View File

@ -32,6 +32,8 @@ use pocketmine\permission\PermissionManager;
use pocketmine\Server;
use pocketmine\timings\TimingsHandler;
use pocketmine\utils\TextFormat;
use function explode;
use function str_replace;
abstract class Command{

View File

@ -26,6 +26,22 @@ namespace pocketmine\command;
use pocketmine\snooze\SleeperNotifier;
use pocketmine\Thread;
use pocketmine\utils\Utils;
use function extension_loaded;
use function fclose;
use function fgets;
use function fopen;
use function fstat;
use function getopt;
use function is_resource;
use function microtime;
use function preg_replace;
use function readline;
use function readline_add_history;
use function stream_isatty;
use function stream_select;
use function trim;
use function usleep;
use const STDIN;
class CommandReader extends Thread{

View File

@ -31,6 +31,9 @@ use pocketmine\permission\PermissionAttachmentInfo;
use pocketmine\plugin\Plugin;
use pocketmine\Server;
use pocketmine\utils\MainLogger;
use function explode;
use function trim;
use const PHP_INT_MAX;
class ConsoleCommandSender implements CommandSender{

View File

@ -25,6 +25,11 @@ namespace pocketmine\command;
use pocketmine\Server;
use pocketmine\utils\TextFormat;
use function count;
use function ord;
use function strlen;
use function strpos;
use function substr;
class FormattedCommandAlias extends Command{
private $formatStrings = [];

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace pocketmine\command;
use pocketmine\lang\TextContainer;
use function trim;
class RemoteConsoleCommandSender extends ConsoleCommandSender{

View File

@ -66,6 +66,16 @@ use pocketmine\command\defaults\VersionCommand;
use pocketmine\command\defaults\WhitelistCommand;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\Server;
use function array_map;
use function array_shift;
use function count;
use function explode;
use function implode;
use function min;
use function str_getcsv;
use function strpos;
use function strtolower;
use function trim;
class SimpleCommandMap implements CommandMap{
@ -90,9 +100,11 @@ class SimpleCommandMap implements CommandMap{
new DefaultGamemodeCommand("defaultgamemode"),
new DeopCommand("deop"),
new DifficultyCommand("difficulty"),
new DumpMemoryCommand("dumpmemory"),
new EffectCommand("effect"),
new EnchantCommand("enchant"),
new GamemodeCommand("gamemode"),
new GarbageCollectorCommand("gc"),
new GiveCommand("give"),
new HelpCommand("help"),
new KickCommand("kick"),
@ -112,6 +124,7 @@ class SimpleCommandMap implements CommandMap{
new SeedCommand("seed"),
new SetWorldSpawnCommand("setworldspawn"),
new SpawnpointCommand("spawnpoint"),
new StatusCommand("status"),
new StopCommand("stop"),
new TeleportCommand("tp"),
new TellCommand("tell"),
@ -122,14 +135,6 @@ class SimpleCommandMap implements CommandMap{
new VersionCommand("version"),
new WhitelistCommand("whitelist")
]);
if($this->server->getProperty("debug.commands", false)){
$this->registerAll("pocketmine", [
new StatusCommand("status"),
new GarbageCollectorCommand("gc"),
new DumpMemoryCommand("dumpmemory")
]);
}
}
@ -242,7 +247,7 @@ class SimpleCommandMap implements CommandMap{
}
public function dispatch(CommandSender $sender, string $commandLine) : bool{
$args = array_map("stripslashes", str_getcsv($commandLine, " "));
$args = array_map("\stripslashes", str_getcsv($commandLine, " "));
$sentCommandLabel = "";
$target = $this->matchCommand($sentCommandLabel, $args);

View File

@ -28,6 +28,9 @@ use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\Player;
use function array_shift;
use function count;
use function implode;
class BanCommand extends VanillaCommand{

View File

@ -28,6 +28,10 @@ use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\Player;
use function array_shift;
use function count;
use function implode;
use function preg_match;
class BanIpCommand extends VanillaCommand{

View File

@ -27,6 +27,10 @@ use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\permission\BanEntry;
use function array_map;
use function count;
use function implode;
use function strtolower;
class BanListCommand extends VanillaCommand{

View File

@ -27,6 +27,7 @@ use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\Server;
use function count;
class DefaultGamemodeCommand extends VanillaCommand{

View File

@ -29,6 +29,8 @@ use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\Player;
use pocketmine\utils\TextFormat;
use function array_shift;
use function count;
class DeopCommand extends VanillaCommand{

View File

@ -28,6 +28,7 @@ use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\level\Level;
use function count;
class DifficultyCommand extends VanillaCommand{

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\CommandSender;
use function date;
class DumpMemoryCommand extends VanillaCommand{

View File

@ -29,6 +29,9 @@ use pocketmine\entity\Effect;
use pocketmine\entity\EffectInstance;
use pocketmine\lang\TranslationContainer;
use pocketmine\utils\TextFormat;
use function count;
use function strtolower;
use const INT32_MAX;
class EffectCommand extends VanillaCommand{

View File

@ -29,6 +29,8 @@ use pocketmine\item\enchantment\Enchantment;
use pocketmine\item\enchantment\EnchantmentInstance;
use pocketmine\lang\TranslationContainer;
use pocketmine\utils\TextFormat;
use function count;
use function is_numeric;
class EnchantCommand extends VanillaCommand{
@ -75,7 +77,15 @@ class EnchantCommand extends VanillaCommand{
return true;
}
$item->addEnchantment(new EnchantmentInstance($enchantment, (int) ($args[2] ?? 1)));
$level = 1;
if(isset($args[2])){
$level = $this->getBoundedInt($sender, $args[2], 1, $enchantment->getMaxLevel());
if($level === null){
return false;
}
}
$item->addEnchantment(new EnchantmentInstance($enchantment, $level));
$player->getInventory()->setItemInHand($item);

View File

@ -30,6 +30,7 @@ use pocketmine\lang\TranslationContainer;
use pocketmine\Player;
use pocketmine\Server;
use pocketmine\utils\TextFormat;
use function count;
class GamemodeCommand extends VanillaCommand{

View File

@ -25,6 +25,10 @@ namespace pocketmine\command\defaults;
use pocketmine\command\CommandSender;
use pocketmine\utils\TextFormat;
use function count;
use function memory_get_usage;
use function number_format;
use function round;
class GarbageCollectorCommand extends VanillaCommand{
@ -66,7 +70,7 @@ class GarbageCollectorCommand extends VanillaCommand{
$sender->sendMessage(TextFormat::GOLD . "Tiles: " . TextFormat::RED . number_format($tilesCollected));
$sender->sendMessage(TextFormat::GOLD . "Cycles: " . TextFormat::RED . number_format($cyclesCollected));
$sender->sendMessage(TextFormat::GOLD . "Memory freed: " . TextFormat::RED . number_format(round((($memory - memory_get_usage()) / 1024) / 1024, 2)) . " MB");
$sender->sendMessage(TextFormat::GOLD . "Memory freed: " . TextFormat::RED . number_format(round((($memory - memory_get_usage()) / 1024) / 1024, 2), 2) . " MB");
return true;
}
}

View File

@ -31,6 +31,9 @@ use pocketmine\lang\TranslationContainer;
use pocketmine\nbt\JsonNbtParser;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\utils\TextFormat;
use function array_slice;
use function count;
use function implode;
class GiveCommand extends VanillaCommand{

View File

@ -27,6 +27,17 @@ use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\lang\TranslationContainer;
use pocketmine\utils\TextFormat;
use function array_chunk;
use function array_pop;
use function count;
use function explode;
use function implode;
use function is_numeric;
use function ksort;
use function min;
use function strtolower;
use const SORT_FLAG_CASE;
use const SORT_NATURAL;
class HelpCommand extends VanillaCommand{

View File

@ -29,6 +29,10 @@ use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\Player;
use pocketmine\utils\TextFormat;
use function array_shift;
use function count;
use function implode;
use function trim;
class KickCommand extends VanillaCommand{

View File

@ -30,6 +30,7 @@ use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\lang\TranslationContainer;
use pocketmine\Player;
use pocketmine\utils\TextFormat;
use function count;
class KillCommand extends VanillaCommand{

View File

@ -26,6 +26,10 @@ namespace pocketmine\command\defaults;
use pocketmine\command\CommandSender;
use pocketmine\lang\TranslationContainer;
use pocketmine\Player;
use function array_filter;
use function array_map;
use function count;
use function implode;
class ListCommand extends VanillaCommand{

View File

@ -28,6 +28,8 @@ use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\Player;
use pocketmine\utils\TextFormat;
use function count;
use function implode;
class MeCommand extends VanillaCommand{

View File

@ -29,6 +29,8 @@ use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\Player;
use pocketmine\utils\TextFormat;
use function array_shift;
use function count;
class OpCommand extends VanillaCommand{

View File

@ -27,6 +27,7 @@ use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use function count;
class PardonCommand extends VanillaCommand{

View File

@ -27,6 +27,8 @@ use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use function count;
use function preg_match;
class PardonIpCommand extends VanillaCommand{

View File

@ -62,6 +62,13 @@ use pocketmine\math\Vector3;
use pocketmine\Player;
use pocketmine\utils\Random;
use pocketmine\utils\TextFormat;
use function count;
use function explode;
use function max;
use function microtime;
use function mt_rand;
use function strpos;
use function strtolower;
class ParticleCommand extends VanillaCommand{
@ -216,12 +223,12 @@ class ParticleCommand extends VanillaCommand{
}elseif(strpos($name, "blockcrack_") === 0){
$d = explode("_", $name);
if(count($d) === 2){
return new TerrainParticle($pos, BlockFactory::get($d[1] & 0xff, $d[1] >> 12));
return new TerrainParticle($pos, BlockFactory::get(((int) $d[1]) & 0xff, ((int) $d[1]) >> 12));
}
}elseif(strpos($name, "blockdust_") === 0){
$d = explode("_", $name);
if(count($d) >= 4){
return new DustParticle($pos, $d[1] & 0xff, $d[2] & 0xff, $d[3] & 0xff, isset($d[4]) ? $d[4] & 0xff : 255);
return new DustParticle($pos, ((int) $d[1]) & 0xff, ((int) $d[2]) & 0xff, ((int) $d[3]) & 0xff, isset($d[4]) ? ((int) $d[4]) & 0xff : 255);
}
}

View File

@ -27,6 +27,9 @@ use pocketmine\command\CommandSender;
use pocketmine\lang\TranslationContainer;
use pocketmine\plugin\Plugin;
use pocketmine\utils\TextFormat;
use function array_map;
use function count;
use function implode;
class PluginsCommand extends VanillaCommand{

View File

@ -29,6 +29,8 @@ use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\Player;
use pocketmine\utils\TextFormat;
use function count;
use function implode;
class SayCommand extends VanillaCommand{

View File

@ -30,6 +30,8 @@ use pocketmine\lang\TranslationContainer;
use pocketmine\math\Vector3;
use pocketmine\Player;
use pocketmine\utils\TextFormat;
use function count;
use function round;
class SetWorldSpawnCommand extends VanillaCommand{

View File

@ -31,6 +31,8 @@ use pocketmine\level\Level;
use pocketmine\level\Position;
use pocketmine\Player;
use pocketmine\utils\TextFormat;
use function count;
use function round;
class SpawnpointCommand extends VanillaCommand{

View File

@ -26,6 +26,11 @@ namespace pocketmine\command\defaults;
use pocketmine\command\CommandSender;
use pocketmine\utils\TextFormat;
use pocketmine\utils\Utils;
use function count;
use function floor;
use function microtime;
use function number_format;
use function round;
class StatusCommand extends VanillaCommand{
@ -91,14 +96,14 @@ class StatusCommand extends VanillaCommand{
$sender->sendMessage(TextFormat::GOLD . "Thread count: " . TextFormat::RED . Utils::getThreadCount());
$sender->sendMessage(TextFormat::GOLD . "Main thread memory: " . TextFormat::RED . number_format(round(($mUsage[0] / 1024) / 1024, 2)) . " MB.");
$sender->sendMessage(TextFormat::GOLD . "Total memory: " . TextFormat::RED . number_format(round(($mUsage[1] / 1024) / 1024, 2)) . " MB.");
$sender->sendMessage(TextFormat::GOLD . "Total virtual memory: " . TextFormat::RED . number_format(round(($mUsage[2] / 1024) / 1024, 2)) . " MB.");
$sender->sendMessage(TextFormat::GOLD . "Heap memory: " . TextFormat::RED . number_format(round(($rUsage[0] / 1024) / 1024, 2)) . " MB.");
$sender->sendMessage(TextFormat::GOLD . "Maximum memory (system): " . TextFormat::RED . number_format(round(($mUsage[2] / 1024) / 1024, 2)) . " MB.");
$sender->sendMessage(TextFormat::GOLD . "Main thread memory: " . TextFormat::RED . number_format(round(($mUsage[0] / 1024) / 1024, 2), 2) . " MB.");
$sender->sendMessage(TextFormat::GOLD . "Total memory: " . TextFormat::RED . number_format(round(($mUsage[1] / 1024) / 1024, 2), 2) . " MB.");
$sender->sendMessage(TextFormat::GOLD . "Total virtual memory: " . TextFormat::RED . number_format(round(($mUsage[2] / 1024) / 1024, 2), 2) . " MB.");
$sender->sendMessage(TextFormat::GOLD . "Heap memory: " . TextFormat::RED . number_format(round(($rUsage[0] / 1024) / 1024, 2), 2) . " MB.");
$sender->sendMessage(TextFormat::GOLD . "Maximum memory (system): " . TextFormat::RED . number_format(round(($mUsage[2] / 1024) / 1024, 2), 2) . " MB.");
if($server->getProperty("memory.global-limit") > 0){
$sender->sendMessage(TextFormat::GOLD . "Maximum memory (manager): " . TextFormat::RED . number_format(round($server->getProperty("memory.global-limit"), 2)) . " MB.");
$sender->sendMessage(TextFormat::GOLD . "Maximum memory (manager): " . TextFormat::RED . number_format(round($server->getProperty("memory.global-limit"), 2), 2) . " MB.");
}
foreach($server->getLevels() as $level){

View File

@ -30,6 +30,10 @@ use pocketmine\lang\TranslationContainer;
use pocketmine\math\Vector3;
use pocketmine\Player;
use pocketmine\utils\TextFormat;
use function array_filter;
use function array_values;
use function count;
use function round;
class TeleportCommand extends VanillaCommand{

View File

@ -28,6 +28,9 @@ use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\Player;
use pocketmine\utils\TextFormat;
use function array_shift;
use function count;
use function implode;
class TellCommand extends VanillaCommand{

View File

@ -30,6 +30,7 @@ use pocketmine\lang\TranslationContainer;
use pocketmine\level\Level;
use pocketmine\Player;
use pocketmine\utils\TextFormat;
use function count;
class TimeCommand extends VanillaCommand{
@ -54,9 +55,7 @@ class TimeCommand extends VanillaCommand{
return true;
}
foreach($sender->getServer()->getLevels() as $level){
$level->checkTime();
$level->startTime();
$level->checkTime();
}
Command::broadcastCommandMessage($sender, "Restarted the time");
return true;
@ -67,9 +66,7 @@ class TimeCommand extends VanillaCommand{
return true;
}
foreach($sender->getServer()->getLevels() as $level){
$level->checkTime();
$level->stopTime();
$level->checkTime();
}
Command::broadcastCommandMessage($sender, "Stopped the time");
return true;
@ -109,9 +106,7 @@ class TimeCommand extends VanillaCommand{
}
foreach($sender->getServer()->getLevels() as $level){
$level->checkTime();
$level->setTime($value);
$level->checkTime();
}
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.time.set", [$value]));
}elseif($args[0] === "add"){
@ -123,9 +118,7 @@ class TimeCommand extends VanillaCommand{
$value = $this->getInteger($sender, $args[1], 0);
foreach($sender->getServer()->getLevels() as $level){
$level->checkTime();
$level->setTime($level->getTime() + $value);
$level->checkTime();
}
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.time.added", [$value]));
}else{

View File

@ -31,6 +31,22 @@ use pocketmine\scheduler\BulkCurlTask;
use pocketmine\Server;
use pocketmine\timings\TimingsHandler;
use pocketmine\utils\InternetException;
use function count;
use function fclose;
use function file_exists;
use function fopen;
use function fseek;
use function http_build_query;
use function is_array;
use function json_decode;
use function mkdir;
use function stream_get_contents;
use function strtolower;
use const CURLOPT_AUTOREFERER;
use const CURLOPT_FOLLOWLOCATION;
use const CURLOPT_HTTPHEADER;
use const CURLOPT_POST;
use const CURLOPT_POSTFIELDS;
class TimingsCommand extends VanillaCommand{

View File

@ -26,6 +26,9 @@ namespace pocketmine\command\defaults;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use function array_slice;
use function count;
use function implode;
class TitleCommand extends VanillaCommand{
@ -82,7 +85,7 @@ class TitleCommand extends VanillaCommand{
$player->addActionBarMessage(implode(" ", array_slice($args, 2)));
break;
case "times":
if(count($args) < 4){
if(count($args) < 5){
throw new InvalidCommandSyntaxException();
}

View File

@ -28,6 +28,7 @@ namespace pocketmine\command\defaults;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\Player;
use function count;
class TransferServerCommand extends VanillaCommand{

View File

@ -28,6 +28,8 @@ use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\utils\TextFormat;
use function is_numeric;
use function substr;
abstract class VanillaCommand extends Command{
public const MAX_COORD = 30000000;

View File

@ -28,6 +28,10 @@ use pocketmine\lang\TranslationContainer;
use pocketmine\network\mcpe\protocol\ProtocolInfo;
use pocketmine\plugin\Plugin;
use pocketmine\utils\TextFormat;
use function count;
use function implode;
use function stripos;
use function strtolower;
class VersionCommand extends VanillaCommand{

View File

@ -28,6 +28,9 @@ use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\utils\TextFormat;
use function count;
use function implode;
use function strtolower;
class WhitelistCommand extends VanillaCommand{

View File

@ -23,6 +23,9 @@ declare(strict_types=1);
namespace pocketmine\entity;
use function max;
use function min;
class Attribute{
public const ABSORPTION = 0;

View File

@ -23,6 +23,8 @@ declare(strict_types=1);
namespace pocketmine\entity;
use function array_filter;
class AttributeMap implements \ArrayAccess{
/** @var Attribute[] */
private $attributes = [];

View File

@ -25,6 +25,10 @@ namespace pocketmine\entity;
use pocketmine\item\Item;
use pocketmine\math\Vector3;
use function assert;
use function is_float;
use function is_int;
use function is_string;
class DataPropertyManager{

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