Compare commits

...

477 Commits

Author SHA1 Message Date
b307cd0aa1 Release 3.19.0 2021-04-07 19:03:36 +01:00
c9b83d7276 Protocol changes for 1.16.220 2021-04-07 18:59:01 +01:00
e22b6ff566 Revert "Revert "Backport InventoryTransactionPacket impl from PM4""
This reverts commit c7cdaeae85.
2021-04-07 18:42:07 +01:00
af88f49a21 3.18.3 is next 2021-04-07 18:32:14 +01:00
599d5253db Release 3.18.2 2021-04-07 18:32:10 +01:00
54cb5ee0fa ItemTranslator: ensure that the correct meta value is returned after translation
-1 is a PM-specific thing. Right now there is a hack in the NetworkBinaryStream which prevents this from becoming a problem, but that might not be the case in future.
2021-04-07 13:10:29 +01:00
cdae8b42eb Bump adhocore/json-comment to ^1.1.0, new version strips trailing comma as well (#4146) 2021-04-06 11:58:23 +01:00
Ali
a45a4a91ae Call InventoryCloseEvent in Player::removeWindow() (#4142)
closes #4130
2021-04-04 01:07:58 +01:00
21378b7f27 Regenerate PHPStan baselines
this should be the last time we get baselines randomly rearranging themselves on changes ...
2021-04-03 22:36:15 +01:00
502aed41b0 phpstan 0.12.83 2021-04-03 22:34:48 +01:00
125837324f Player: don't dump cursor contents on mouseover interaction
this can fire while the player has the inventory window open, because it also gets sent when the player swaps their held itemstack for something new.

We already had a special-case for mouseover with entity ID 0, but since
this isn't just a zero problem, a more general fix suits better
(particularly since we might need to handle the 0 case anyway).

closes #4140
closes #4141
2021-04-02 21:35:38 +01:00
Ali
609dff1aae Player: Revert invalid attempts to toggle flight, instead of kicking (#4139)
If allowFlight was toggled by the server (e.g. due to gamemode change), a race could occur due to network latency where the client could try to enable flight, and then get kicked for cheating.

Since this can happen in legitimate, non-cheating cases, we can't make any assumptions about whether a player is cheating, so instead we just revert it, like we do with every other bad input.
2021-04-01 17:57:26 +01:00
b03212053c 3.18.2 is next 2021-03-28 21:24:07 +01:00
fd4ac885bb Release 3.18.1 2021-03-28 21:24:03 +01:00
f35886f18a Updated composer dependencies 2021-03-28 21:14:02 +01:00
a9eaa55427 actions: added a php-cs-fixer run 2021-03-28 20:38:56 +01:00
5c41f79be4 Added php-cs-fixer configuration
this is by no means a complete code style guide, but it fixes a lot of common issues that show up, particularly in PRs.
2021-03-28 19:21:41 +01:00
34c2b62ffe Remove unused import 2021-03-28 19:12:18 +01:00
e42a691da9 Strip trailing whitespace 2021-03-28 19:02:51 +01:00
Ali
3b3fb5e662 fix ItemFrames (#4101)
removing items from item frames was broken due to behavioural changes in 1.16.210.
2021-03-28 18:53:46 +01:00
01ffe8bf57 Updated build/php submodule to pmmp/php-build-scripts@c64baa0f1c 2021-03-28 18:14:40 +01:00
4abf4aecad MainLogger: fixed potential deadlock during syncFlushBuffer()
the notify() to flush the buffer might arrive in between the writeLogStream() and synchronized() calls in the thread body, resulting in a deadlock if the logger thread managed to call wait() before the main thread did.
2021-03-28 18:10:23 +01:00
b29f83ee99 Added preprocessor test build job to Actions
this should catch problems like the one that broke 3.17.6 at the root.
2021-03-25 01:25:04 +00:00
4bc57f00b8 Updated LevelSoundEventPacket constants 2021-03-23 23:36:48 +00:00
ff61e1e018 ClientCacheBlobStatusPacket: fixed field order
miss comes first, not hit.
2021-03-23 19:52:25 +00:00
fb20bb3832 Don't handle NAN/INF in movements 2021-03-23 14:54:39 +00:00
3333df31df Bump phpunit/phpunit from 9.5.3 to 9.5.4 (#4104)
Bumps [phpunit/phpunit](https://github.com/sebastianbergmann/phpunit) from 9.5.3 to 9.5.4.
- [Release notes](https://github.com/sebastianbergmann/phpunit/releases)
- [Changelog](https://github.com/sebastianbergmann/phpunit/blob/master/ChangeLog-9.5.md)
- [Commits](https://github.com/sebastianbergmann/phpunit/compare/9.5.3...9.5.4)

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

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-03-23 13:53:45 +00:00
c09fcb2df2 Merge branch 'stable' of github.com:pmmp/PocketMine-MP into stable 2021-03-22 21:22:56 +00:00
c7cdaeae85 Revert "Backport InventoryTransactionPacket impl from PM4"
This reverts commit cb06be615a.

we can't push this to stable because it would break plugins without any
way to know (no protocol or API change).

At most, this should have been wrapped into a protocol change.
2021-03-22 21:21:11 +00:00
4416cd5a28 Bump phpstan/phpstan from 0.12.81 to 0.12.82 (#4088)
Bumps [phpstan/phpstan](https://github.com/phpstan/phpstan) from 0.12.81 to 0.12.82.
- [Release notes](https://github.com/phpstan/phpstan/releases)
- [Commits](https://github.com/phpstan/phpstan/compare/0.12.81...0.12.82)

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

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-03-22 13:26:07 +00:00
cb93095857 [ci skip] readme: added link to devdoc.pmmp.io 2021-03-21 16:59:58 +00:00
c8f396ecbc [ci skip] doxygen: link to devdoc.pmmp.io instead of the github repo 2021-03-21 16:56:23 +00:00
cb06be615a Backport InventoryTransactionPacket impl from PM4
this version is far better, and we're going to need it to deal with the PlayerAuthInputPacket bullshit.
2021-03-19 22:16:30 +00:00
0d3c11699c Clean up PHPStan baselines 2021-03-19 22:14:07 +00:00
3667e95ff6 Added PlayerAuthInputFlags 2021-03-19 21:41:22 +00:00
0e2dc51ec8 added some missing things to the protocol 2021-03-19 21:09:53 +00:00
eaf85b028a fix prebuilt binaries link (#4090) 2021-03-19 20:42:21 +00:00
9479a1a0ab Bump phpunit/phpunit from 9.5.2 to 9.5.3 (#4084)
Bumps [phpunit/phpunit](https://github.com/sebastianbergmann/phpunit) from 9.5.2 to 9.5.3.
- [Release notes](https://github.com/sebastianbergmann/phpunit/releases)
- [Changelog](https://github.com/sebastianbergmann/phpunit/blob/master/ChangeLog-9.5.md)
- [Commits](https://github.com/sebastianbergmann/phpunit/compare/9.5.2...9.5.3)

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

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-03-17 14:08:44 +00:00
1bb2d162ab Simplify CommandReader
while stream_select() doesn't work on pipes, if it ever starts working properly in the future, we'll need this code. In the meantime, it's harmless (it just immediately returns 1 anyway).
2021-03-16 21:42:35 +00:00
ee868bcccc update argument type constants (#4082) 2021-03-15 18:22:01 +00:00
cbc8576d4a Implement UPnP support without dotNET (#3378)
UPnP forwarding is now available on all supported platforms.
com_dotnet is no longer required for UPnP forwarding to work.

Closes #3216 .
2021-03-14 22:50:33 +00:00
edcf296086 RakLibInterface: fixed server being unjoinable if gamemode is Spectator
closes #4069
this happens because the client bans any server that has an invalid pong, which is very stupid in this case because the gamemode isn't even shown on the UI anyway ...
2021-03-14 20:35:17 +00:00
9e27c47116 Merge branch 'stable' of github.com:pmmp/PocketMine-MP into stable 2021-03-12 22:08:20 +00:00
a0368a843e 3.18.1 is next 2021-03-12 22:07:01 +00:00
3f64906263 Release 3.18.0 2021-03-12 22:07:01 +00:00
19bb8a00df Updated PHPStan baselines 2021-03-12 22:05:15 +00:00
4816a66fb8 Baseline protocol changes for 1.16.210
this is not a complete changeset, but it's sufficient to get servers back online.
There are additional changes to PlayerAuthInputPacket which need to be reversed.
2021-03-12 21:41:48 +00:00
06f4e1e4c2 Bump phpstan/phpstan from 0.12.80 to 0.12.81 (#4063) 2021-03-11 00:33:05 +00:00
5b8166c1f0 3.17.8 is next 2021-03-11 00:22:17 +00:00
30c5cad5b3 Release 3.17.7 2021-03-11 00:22:17 +00:00
a7a7fe3895 Merge branch 'stable' of github.com:pmmp/PocketMine-MP into stable 2021-03-11 00:15:48 +00:00
55ac2f07dc Updated PreProcessor submodule to pmmp/PreProcessor@1b9304de61 2021-03-11 00:15:33 +00:00
0660888029 Updated NBT dependency (again) 2021-03-11 00:15:00 +00:00
0476e6bcfc Updated PreProcessor submodule to pmmp/PreProcessor@934f92d388 2021-03-10 23:33:45 +00:00
72bd37e442 Updated PreProcessor submodule to pmmp/PreProcessor@652c6d8b4c 2021-03-10 23:02:47 +00:00
f95fcecb5b 3.17.7 is next 2021-03-10 20:49:10 +00:00
61391b6e23 Release 3.17.6 2021-03-10 20:48:57 +00:00
fbb6f1f81c Workaround for cursor sync in 1.13+, closes #4059 2021-03-07 21:17:52 +00:00
712df04bc4 Updated NBT dependency to 0.2.17 2021-03-07 21:06:08 +00:00
1563e25378 Updated composer dependencies 2021-03-07 19:57:16 +00:00
ed84252942 Player: Improved XUID verification
we check if an existing player is online with a matching XUID first; if there isn't, we don't bother loading the playerdata, since that other player couldn't have joined unless they had a match or were allowed to bypass.
2021-03-07 19:53:19 +00:00
3d90625020 Revert "Revert "Use PHP 7.4.16 for Actions""
This reverts commit 9f6b914925.
2021-03-07 16:37:33 +00:00
9f6b914925 Revert "Use PHP 7.4.16 for Actions"
This reverts commit 0e614ea8fd.

apparently php-build doesn't have 7.4.16 yet ...
2021-03-06 00:41:19 +00:00
0e614ea8fd Use PHP 7.4.16 for Actions 2021-03-06 00:32:56 +00:00
401bd09d60 Bump phpstan/phpstan from 0.12.79 to 0.12.80 (#4054) 2021-03-01 16:56:23 +00:00
649671cc69 Bump phpstan/phpstan from 0.12.78 to 0.12.79 (#4051) 2021-02-27 17:42:19 +00:00
e755e1dc23 ResourcePackClientResponsePacket: fixed non-deterministic decoding 2021-02-27 01:08:18 +00:00
e34a444dde Bump phpstan/phpstan from 0.12.77 to 0.12.78 (#4046) 2021-02-26 00:34:38 +00:00
78f9985377 Player: fixed PlayerMoveEvent->getFrom() returning unexpected results on movement reversion
fixes #4043
2021-02-26 00:30:42 +00:00
fac2bd3379 Liquid: mark getSmallestFlowDecay() as impure
this fixes two bogus PHPStan warnings.
2021-02-25 22:41:07 +00:00
fcfd51dfc7 CrashDump: do not put FALSE into crashdumps in case file_get_contents() failed 2021-02-23 19:39:21 +00:00
ccc76cf338 Make less noise about XBL being enabled
this has been in force for years now, it's expected by now.
2021-02-23 19:25:22 +00:00
10a73488ed Merge branch 'stable' of https://github.com/pmmp/pocketmine-mp into stable 2021-02-22 16:43:51 +00:00
9c5114084b Updated Snooze to fix race conditions 2021-02-22 16:42:54 +00:00
11630ab1aa Bump phpstan/phpstan from 0.12.76 to 0.12.77 (#4041) 2021-02-18 11:34:42 +00:00
a3068b39a2 Update composer dependencies 2021-02-16 22:31:01 +00:00
edbc73a72c 3.17.6 is next 2021-02-16 22:13:05 +00:00
3a0c8dd594 Release 3.17.5 2021-02-16 22:13:05 +00:00
16fa26405a Remove remaining usages of LevelDB::close()
this is handled by the object destructor.

closes #4035
2021-02-15 20:10:11 +00:00
57423540f0 BUILDING.md: Document server-phar.php's compression bug (#4037)
This bug is not fixable on PM's side because the fault lies with php-src. It was fixed recently in 1bb2a4f91c.
2021-02-15 19:53:44 +00:00
8f8821c904 Bump phpstan/phpstan from 0.12.75 to 0.12.76 (#4038) 2021-02-15 11:25:36 +00:00
094102fe92 fopen() might return FALSE if permission was denied to read/write the file 2021-02-12 16:16:36 +00:00
2aef83e7d7 MainLogger: fix type ambiguity 2021-02-12 15:05:24 +00:00
5c3e78e1d3 Bump phpstan/phpstan from 0.12.74 to 0.12.75 (#4033) 2021-02-12 14:58:01 +00:00
18666e5a60 Be compatible with newest versions of php-leveldb 2021-02-11 22:33:29 +00:00
f72163c173 Fixed build not failing when PHP build gets borked 2021-02-11 17:06:03 +00:00
7407e504b6 actions: bump PHP versions to 7.3.27 and 7.4.15 2021-02-11 16:35:19 +00:00
0e396dc47d actions: update PHP extension versions 2021-02-11 16:24:09 +00:00
d2204da1d5 [ci skip] center the build badges 2021-02-11 16:05:55 +00:00
2a51269305 Merge branch 'stable' of https://github.com/pmmp/pocketmine-mp into stable 2021-02-11 16:05:24 +00:00
928041ddf1 Bump phpstan/phpstan from 0.12.71 to 0.12.74 (#4028)
Bumps [phpstan/phpstan](https://github.com/phpstan/phpstan) from 0.12.71 to 0.12.74.
- [Release notes](https://github.com/phpstan/phpstan/releases)
- [Commits](https://github.com/phpstan/phpstan/compare/0.12.71...0.12.74)

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

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-02-08 21:42:08 +00:00
007f4f9350 CraftingDataPacket: Remove useless @var comment 2021-02-08 11:53:50 +00:00
46e9f0cec6 Player: fixed verify-xuid not kicking in by default on old configs 2021-02-07 21:10:23 +00:00
606d56b55d Composer: lock in PHP at ^7.3 || ^8.0, don't leave it unbounded 2021-02-07 17:31:32 +00:00
78a62a8b27 Remember and verify player XUIDs (controlled by player.verify-xuid in pocketmine.yml) 2021-02-05 14:42:57 +00:00
c5bdd7dd64 Added a unit test to ensure valid format of MINECRAFT_VERSION_NETWORK 2021-02-04 22:36:40 +00:00
8ee37a3033 Bump phpunit/phpunit from 9.5.1 to 9.5.2 (#4023) 2021-02-04 16:46:22 +00:00
7e3e63f342 Fixed race condition in MainLogger shutdown
this resulted in a deadlock in https://github.com/pmmp/PocketMine-MP/runs/1831812620?check_suite_focus=true because the notify() arrived while writeLogStream() was executing.
This ensures that either:
- the notification will occur before the sleep, and therefore no sleeping will occur (this->shutdown = true before the wait)
- the notification will arrive during the sleep.
2021-02-04 16:40:10 +00:00
8ef1e54e20 MainLogger: fixing CPU waste on logger thread
this doesn't need to keep spinning every 25ms; it can just wake up when there's actually log messages to write into the buffer.
2021-02-04 15:07:40 +00:00
eaf3a86981 MainLogger: fixed UB in writeLogStream()
notify() has to be used inside a synchronized block.
2021-02-04 15:03:14 +00:00
317a48d9b0 ItemStackRequest: expose filterStrings 2021-02-03 23:40:34 +00:00
bc14660e55 Added missing ItemStackRequest protocol changes 2021-02-03 23:37:41 +00:00
b1bb9fbd1c Reinstall PHP deps on cache hit
the 20.04 actions image doesn't have libzip5 and who knows what else is missing ...
2021-02-03 17:42:11 +00:00
96181f8cf5 Version PHP build caches by image version
we can't safely use `ubuntu-latest` because the build caches will break if they were built for 18.04 and used on 20.04, or vice versa. Instead, we pin the images (and caches) to a specific version.
2021-02-03 17:24:50 +00:00
4771e3dc28 3.17.5 is next 2021-02-02 14:04:51 +00:00
2e9117d102 Release 3.17.4 2021-02-02 14:04:50 +00:00
06493da7d9 Imports cleanup 2021-02-02 13:58:07 +00:00
bd303b1062 RegionLoader: fixed flaky region header validation since 3.17.3 2021-02-02 13:43:52 +00:00
fe731b9018 Added failing test case for region header validation
fucking PHP... what genius thought it was a good idea to cache file stats without even an attempt at keeping the cache up to date on modifications?
2021-02-02 13:43:12 +00:00
1a24afc6d1 InventoryTransaction: Fixed indexes persisting from balance calculation in crafting input/outputs
fixes #4019
the order of the actual items may not be the same across runs, but index 0 will at least be sure to exist.
2021-02-02 00:13:58 +00:00
bef906b0f0 phpstan 0.12.71 2021-02-02 00:05:53 +00:00
37e8dd6444 Fix PHP 8 optional before required parameters deprecation warnings (#4016) 2021-01-31 12:08:47 +00:00
02ee0f23c0 Removed old support requests configuration 2021-01-27 22:53:37 +00:00
cda472333c Add workflow for dessant/support-requests
we're using the legacy github app right now.
2021-01-27 22:47:33 +00:00
47cf58be8a phpstan 0.12.70 2021-01-27 20:11:37 +00:00
ccf9691927 Bump phpunit/phpunit from 9.5.0 to 9.5.1 (#4010) 2021-01-27 19:28:36 +00:00
16fa958416 phpstan: better hack for any-callable parameters
variadics are a bad fit for this because what we really need is to accept callable with any number of arguments. LSP requires that the provided number of arguments must be >= than the required number of arguments.
2021-01-27 19:25:28 +00:00
bac57c159f Player: fix bridging, towering and various other fast building bugs
clickPos is relative to the base block position, so if you keep aiming at the same spot on the block and jump, it thinks you're still spamming.
closes #2730
2021-01-27 00:11:14 +00:00
38b2d83799 MemoryManager: fixed protected properties being dumped multiple times
we don't need to scan the parent classes for anything other than private properties, because protected and public properties will appear on the main reflection as if they were declared directly as such.
2021-01-26 20:32:23 +00:00
c134b1cd8a [ci skip] README: add some badges 2021-01-26 17:34:05 +00:00
62deafda48 CommandReader: removed readline support
readline has been borked for a long time and it's not thread safe.
2021-01-25 17:53:25 +00:00
31b6df4376 3.17.4 is next 2021-01-25 17:15:43 +00:00
b296ae1b87 Release 3.17.3 2021-01-25 17:15:31 +00:00
f9e42b716a Scrub PHPStan baselines
these are now always generated with level 8.
2021-01-24 20:31:22 +00:00
34c1d455a7 phpstan: enable checkMissingCallableSignature 2021-01-24 20:27:53 +00:00
af8936dba5 phpstan 0.12.69 2021-01-24 20:14:42 +00:00
e8ffab1787 RegionLoader: avoid hitting the disk twice during chunk reads
this provides some performance improvement (although it's difficult to measure because of cache).
this does mean that we read some garbage data during chunk reads, but it's less costly than hitting the disk twice.
2021-01-20 21:05:44 +00:00
ecc1e1f698 RegionLoader: improve performance of region header validation
I was unaware that fseek actually makes a syscall which is rather costly, which became painfully obvious during large world conversions on PM4.
On average this problem appeared to be adding about 5ms to the load time for a newly loaded region, which is insanely expensive.
2021-01-20 20:04:21 +00:00
ea5931e274 Updated build/php submodule to pmmp/php-build-scripts@60194e8b14 2021-01-16 19:34:06 +00:00
988cf7f535 Fixed PHP 8.0 deprecation error 2021-01-16 19:31:07 +00:00
e156fb47e8 Disable xdebug on Actions 2021-01-15 21:09:45 +00:00
efc5f34877 wrong place ... when shared defaults :( 2021-01-15 17:53:39 +00:00
dd0d8842d5 actions: disable fail-fast 2021-01-15 17:35:27 +00:00
7bdc564ccc Update first-party dependencies to PHP 8.0 compatible versions
all deps of PM3 are ready (at least as far as PHPStan can show).
2021-01-15 16:59:51 +00:00
69fff23f1a LevelProviderManager: removed bogus @var
I'm not sure why this wasn't detected until 0.12.67...
2021-01-15 16:53:49 +00:00
ae43698e88 phpstan 0.12.67
for some reason dependabot shit itself while trying to scan for updates and thought this wasn't updatable ...
2021-01-15 16:53:49 +00:00
0987e03c03 Bump phpstan/phpstan-strict-rules from 0.12.8 to 0.12.9 (#4003) 2021-01-13 10:55:54 +00:00
97c124edf9 thanks git, this just sneaked in without any questions ................ 2021-01-12 21:43:34 +00:00
56501178b7 Updated composer dependencies 2021-01-12 21:41:25 +00:00
da663deea1 Bump phpstan/phpstan from 0.12.65 to 0.12.66 (#4001) 2021-01-12 10:41:59 +00:00
972c911485 phpstan 0.12.65 2021-01-09 18:04:42 +00:00
0d8858f948 composer.json: sort packages automatically 2021-01-09 17:38:22 +00:00
da71540fce first shot building multi PHP versions on actions 2021-01-05 22:03:51 +00:00
ec9b39862b bootstrap: commit suicide if composer dependencies are not in sync 2020-12-29 17:47:32 +00:00
efca8077d5 3.17.3 is next 2020-12-28 23:03:37 +00:00
5066d5225b Release 3.17.2 2020-12-28 23:03:32 +00:00
aefaf73685 Living: extract an applyConsumptionResults() method from consumeObject()
inspired by #3592, which has gone stale
2020-12-28 22:27:29 +00:00
15401d740f RegionLoader: mark area as garbage in removeChunk() 2020-12-27 19:16:05 +00:00
5920b0ba40 Remove _PHPSTAN_ANALYSIS constant
we don't need this anymore since PHPStan is able to intelligently decide whether to autoload a file or not.
2020-12-27 19:10:40 +00:00
dea75a0687 RegionLoader: do not attempt to auto-repair chunks with oversized lengths
In the old days, we used to try to correct this problem by adjusting the region header to match the
length found at the start of the chunk payload. However, this has a very good chance to cause corruption
of other chunks, since we can't do any fast overlap checks (an upsize might cause the chunk's alloocated
area to overlap into another one, causing corruption when either chunk's space gets written to).

This corruption risk has become more problematic since the
introduction of region garbage sector reuse, since a broken location
header could cause chunks to trash each others' saved data.

In addition, if there is a length mismatch, there's a good chance that the oversized chunk itself will
already be corrupted, so we'd just fail trying to decompress it later on.

So, instead of trying to fix this automatically, we bail and hope this doesn't occur often enough for
users to get upset, and allow external offline tools to attempt to repair the mess instead.
2020-12-27 18:50:52 +00:00
873e8740e0 3.17.2 is next 2020-12-23 22:20:24 +00:00
260c55f23a Release 3.17.1 2020-12-23 22:20:19 +00:00
9ed430acb9 CrashDump: fixed a bug in crashdump generation 2020-12-23 21:53:12 +00:00
f0241043de CrashDump: add server uptime to crash information 2020-12-23 20:26:18 +00:00
135f1c95e4 phpstan 0.12.64 2020-12-23 20:04:40 +00:00
5431807e43 Split tests up into multiple jobs
this gives a more granular view of test failures and also allows independent steps to run in parallel.
2020-12-23 19:48:39 +00:00
d49ae832e8 actions: rename cache miss fallback build step 2020-12-21 21:32:27 +00:00
ff9d013005 build: hash composer cache by lockfile instead of composer.json
this ensures a cache refresh when transitive dependencies are updated.
2020-12-20 23:58:37 +00:00
b0e1317818 Merge branch 'stable' of https://github.com/pmmp/pocketmine-mp into stable 2020-12-20 23:53:26 +00:00
8653afb0fb Updated composer dependencies 2020-12-20 23:53:09 +00:00
995b56aaa0 Fixed Composer package cache 2020-12-20 23:49:28 +00:00
3ecddf312d build.sh: sort configure parameters 2020-12-20 22:49:39 +00:00
470243ca6f experimental: build PHP in a separate build job 2020-12-20 22:30:47 +00:00
3f21e59917 Bump phpstan/phpstan-strict-rules from 0.12.5 to 0.12.7 (#3976) 2020-12-18 13:44:19 +00:00
fdd74a4f46 Bump phpstan/phpstan-phpunit from 0.12.16 to 0.12.17 (#3975) 2020-12-18 13:15:05 +00:00
a43b46a93c Merge branch 'stable' of https://github.com/pmmp/pocketmine-mp into stable 2020-12-18 00:33:10 +00:00
0604dfc9e5 phpstan 0.12.63 2020-12-18 00:32:55 +00:00
dd2c3db285 Fixed a bucket of lava disappearing when used in a furnace (#3973)
fixes #2385
2020-12-17 23:57:34 +00:00
c95e283507 fix CXXFLAGS 2020-12-14 22:02:16 +00:00
6afbd1f55c Squashed commit of the following:
commit 1f42169f0f929958f7d68a68f194c6f3492b7eb4
Author: Dylan K. Taylor <odigiman@gmail.com>
Date:   Mon Dec 14 21:23:44 2020 +0000

    ... install it in the right fucking place

commit d2a88abeda5fa937d3f508c4e0300a949af97846
Author: Dylan K. Taylor <odigiman@gmail.com>
Date:   Mon Dec 14 21:14:21 2020 +0000

    Build PHP using system libraries to reduce rebuild time
2020-12-14 21:58:58 +00:00
0682c93f5a Drop bcmath dependency
we haven't used bcmath since the days of 32-bit.
2020-12-14 20:59:07 +00:00
da90ae85da Updated composer dependencies 2020-12-14 19:24:36 +00:00
e87127f309 readme: drop travis badge in favour of GH Actions badge 2020-12-11 22:38:14 +00:00
0237a50d90 thank you for your service travis 2020-12-11 22:26:53 +00:00
8b53e4150e Setup GitHub Actions (#3966) 2020-12-11 22:25:08 +00:00
1c43538238 Fix that a hoe gets damage applied to it, when it's used to break a block (#3967)
closes #3965
2020-12-11 21:14:52 +00:00
68887105b2 Utils::cleanPath(): drop the square braces
this looks ugly, as well as breaking plugin crash detection (which tbh is too fragile, but it is what it is ...)
2020-12-09 20:26:08 +00:00
104e90b794 CrashDump: more robust core crash detection 2020-12-08 23:27:03 +00:00
994062f6dc CrashDump: fixed plugin detection on eval()'d code
it's possible we could clean the path up to detect which plugin caused the crash, but for now I'll be happy to not have them showing up as core crashes ...
2020-12-08 23:11:29 +00:00
69a41a5ed4 3.17.1 is next 2020-12-08 21:02:14 +00:00
3903b70ef5 Release 3.17.0 2020-12-08 21:02:13 +00:00
692e63ad7c Protocol changes for 1.16.200 2020-12-08 20:31:17 +00:00
4d1be4d41d McRegion: do not create a region file when trying to read a chunk that doesn't exist
fixes #3953
2020-12-07 18:44:49 +00:00
5f0310a8b6 3.16.2 is next 2020-12-07 17:16:11 +00:00
9b01fb3d89 Release 3.16.1 2020-12-07 17:16:10 +00:00
f28405fcfb phpstan 0.12.59 2020-12-07 17:12:55 +00:00
9c07c206f6 Updated DevTools submodule to pmmp/DevTools@1606a4307b 2020-12-05 20:02:14 +00:00
d0d701f232 Updated build/php submodule to pmmp/php-build-scripts@a42c7df20a 2020-12-05 19:42:41 +00:00
07cae8a129 Updated composer dependencies 2020-12-05 19:40:30 +00:00
6869ee1c2d Clean up nonsensical code in NetworkBinaryStream->getSlot() 2020-12-05 01:24:41 +00:00
26155acff2 register HellBiome (#3950) 2020-12-04 11:58:49 +00:00
b550cf5163 phpunit 9.4.4 2020-12-01 17:32:27 +00:00
48fa19fdcd PermissionAttachmentInfo::__construct() never throws an exception 2020-12-01 17:30:35 +00:00
bac986d0b2 Fixed crash when executing command /version with multiple authors declared in 'author' (#3940)
closes #3902
2020-12-01 15:47:55 +00:00
215bac8dd7 phpstan 0.12.58 2020-11-30 22:11:43 +00:00
3709ba172b Sync composer dependencies 2020-11-30 22:02:01 +00:00
ef034f2d68 PermissionAttachment: better document the apparently nonsensical code responsible for making sure the entire permission system doesn't burn down 2020-11-28 16:05:16 +00:00
ab18332572 PermissionManager: fixed nonsensical PHPDoc type 2020-11-27 19:54:05 +00:00
48595630fc [ci skip] update crash issue template 2020-11-27 17:38:14 +00:00
4102205ba6 Enhance type information in PlayerCreationEvent 2020-11-24 16:28:36 +00:00
9e85ee4a7a Fixed missing field on Persona skin encode 2020-11-21 18:01:56 +00:00
e8e6b9304c phpstan 0.12.57 2020-11-21 17:46:32 +00:00
23849b7f63 3.16.1 is next 2020-11-21 01:25:06 +00:00
d2f68836c6 Release 3.16.0 2020-11-21 01:25:06 +00:00
d19db5d2e4 fix phpstan warnings 2020-11-21 01:16:04 +00:00
98cdc80d37 Protocol changes for 1.16.100 2020-11-21 01:07:25 +00:00
8273f789ee Backport SingletonTrait to PM3 2020-11-20 21:00:47 +00:00
29eccba5f0 Updated composer dependencies 2020-11-17 23:25:15 +00:00
9984b15de6 fix build #3 2020-11-16 19:25:13 +00:00
6ea01e0dd4 fix build #2 2020-11-16 19:21:44 +00:00
46331df7db fix build 2020-11-16 19:06:56 +00:00
691c49fb32 I don't know how to pass custom arguments to these scripts :< 2020-11-16 19:05:04 +00:00
db815360d1 [ci skip] BUILDING.md: tell users to use 'composer make-server' instead of the server-phar script directly
this takes care of the dev dependencies automatically.
2020-11-16 19:03:39 +00:00
6e297168c2 travis.sh: use new composer commands 2020-11-16 19:01:07 +00:00
95dbb00d4c Added custom composer commands: 'composer make-devtools' and 'composer make-server' 2020-11-16 18:55:23 +00:00
50e29a5ed8 build/make-server: bail when composer dev dependencies are installed
these mess up the phar and make it extremely bloated. Almost everyone building for themselves unintentionally includes dev dependencies.
2020-11-16 18:54:07 +00:00
9f3fb935b5 Update composer dependencies 2020-11-12 22:03:32 +00:00
e30b1ee2c7 Clean up entity and tile saveID handling
we only ever need the first entry, so there's no point storing all of them. In addition, the field is private, which guarantees that nothing else needs the array either.
This also fixes phpstan/phpstan@c50650c5dd.
2020-11-12 21:49:12 +00:00
574b7f6343 3.15.5 is next 2020-11-10 16:48:18 +00:00
e8b6b56330 Release 3.15.4 2020-11-10 16:48:18 +00:00
c368ebb5e7 InventoryTransaction: beware of conflicting slot change actions with the same origin/target
these types of chains would never normally occur, but they've been seen in the wild. Attempting to resolve such chains has exponentially increasing complexity.
2020-11-10 16:45:20 +00:00
fa920aa868 Misplaced the changelog AGAIN 2020-11-08 19:25:55 +00:00
a421d32273 3.15.4 is next 2020-11-08 14:48:31 +00:00
6c21c23444 Release 3.15.3 2020-11-08 14:48:31 +00:00
55e0d9c520 Properly time chunk loading and chunk sending on timings reports, closes #3895 2020-11-08 14:30:12 +00:00
37ee3f2775 Player: fixed orderChunks performance issue on newly-generated maps
every time a chunk passed through Level->generateChunkCallback(), it fired onChunkChanged() for chunk listeners, which in turn caused players to rerun chunk orders even though the target chunk had not been sent yet anyway.
2020-11-05 16:17:39 +00:00
bfdcc12e81 phpstan 0.12.54 2020-11-05 14:49:00 +00:00
b2299e08e0 phpstan 0.12.53 2020-11-03 15:00:56 +00:00
d7741050c5 Updated composer dependencies 2020-11-03 14:54:50 +00:00
6cff08cd65 Chunk: fixed hasChanged being set on fastDeserialize() chunks (caused by 2bb497b716)
this caused some performance issues and silent bugs with the generator, notably that the generator would always think all chunks had been changed, causing them to be re-set back into the world 9 times.
2020-11-01 15:50:21 +00:00
fec42f16ba Level: properly define type of generator field 2020-11-01 14:36:05 +00:00
deb0cee8a0 BaseInventory::canAddItem(): consider item max stack size (#3881)
this fixes addItem() failing when canAddItem() reported that an item can be added.
2020-11-01 13:49:13 +00:00
c0dafe7872 Explosion: remove dead code
this was needed for the old ExplodePacket, which was removed a few versions back.
2020-10-29 13:32:56 +00:00
340881d590 remove superfluous newline 2020-10-26 15:59:57 +00:00
e2e960e43d tests: add missing function imports 2020-10-26 15:59:42 +00:00
500fd2d842 tests: strip useless phpdoc 2020-10-26 15:59:17 +00:00
0b550b346b imports cleanup 2020-10-26 15:43:25 +00:00
1424114cf2 Clean phpstan baselines
some of these are dead, others are FPs fixed by newer PHPStan versions.
2020-10-24 17:22:49 +01:00
a8980a0f67 phpstan 0.12.51 2020-10-24 17:10:31 +01:00
69aa7c5ac1 Support for Composer v2 (#3880) 2020-10-24 16:42:38 +01:00
11b74868ee CraftingTransaction: remove impossible condition
this is never hit thanks to the logic flow above - recipeItems is never empty.
2020-10-24 11:22:02 +01:00
9a53de0903 Utils: explode() never returns an empty array 2020-10-24 11:19:37 +01:00
0f8101d4a6 McRegion: Ignore files which don't have a valid file extension
previously a file with a 4-letter name ending in 'mca' in the region folder of a PMAnvil world would cause the world format to be unrecognized. This happens because strrpos() returns false when the substring isn't found, which gets coerced to 0 when used in addition.
2020-10-24 11:15:07 +01:00
55ecac4c80 Fixed always-true condition in world loading
this has a couple of side effects which need to be explored.
- first of all, this bug prevented generateLevel() from filling in the preset from server.properties. With this fix, worlds which don't have any extra generator settings will start to be generated using server.properties settings, which is almost certainly not expected behaviour.
- preset can now be specified separately from generator in pocketmine.yml, which is nicer for users.
2020-10-24 11:10:35 +01:00
2a1d1e90a2 php-cs-fixer nits 2020-10-21 16:44:57 +01:00
4444a79468 Bump phpunit/phpunit from 9.4.1 to 9.4.2 (#3875) 2020-10-20 09:06:46 +00:00
4cbeee3ab8 Bump phpstan/phpstan from 0.12.49 to 0.12.50 (#3874) 2020-10-17 13:44:43 +00:00
a251960c1c AsyncPool: expose workerUsage to the API
this allows plugins (and maybe later on the core) to detect async worker overload and warn the user about potential performance issues.
I planned to implement such detection in the core directly, but it turned out to be a bit more complex than I anticipated. At the least, this API might be useful to someone else.
2020-10-16 21:20:49 +01:00
52f734799e Human: do not modify totalXp unless setting XP succeeds 2020-10-16 20:43:03 +01:00
42171f6e06 Human: beware negative values in addXp() 2020-10-16 20:42:13 +01:00
1fe4fdc67c PluginDescription: fixed some very old refactoring errors 2020-10-15 13:55:40 +01:00
af4f30d1c8 Bump phpstan/phpstan from 0.12.48 to 0.12.49 (#3873) 2020-10-13 16:31:25 +00:00
3e2926441d PluginDescription: make sure that extensions constraints are actually strings 2020-10-13 17:21:10 +01:00
0b33762be0 PluginDescription: fixed type of extensions (reported by phpstan 0.12.49) 2020-10-13 17:21:10 +01:00
e6f89213dc Entity: properly account for upwards motion when calculating fall distance (#3867)
Previously, upwards movement wouldn't be considered, but downwards would, so if an entity bobbed up and down in the air for a while (e.g. while being comboed in PvP), the downwards distance would accumulate and deal a large amount of fall damage on touchdown.
This commit changes fall distance measurement to correctly account for upwards movement.

A better way of measuring fall distance would simply be to record the highest Y coordinate reached while in the air, and then measure the distance between that and the point of contact when landing. This would also remove the need to constantly update the fallDistance field. However, this would involve a BC break and will therefore have to wait until PM4.
2020-10-13 14:16:09 +01:00
f8d249b240 Isolate and always show IP details on install (#3870)
* Isolate and always show IP details on install

* camelCase
2020-10-13 14:11:28 +01:00
b39afa20d1 Bump phpunit/phpunit from 9.4.0 to 9.4.1 (#3872) 2020-10-13 13:09:56 +00:00
7027a9b972 camelCase 2020-10-12 08:25:34 -04:00
b02f3f4090 Isolate and always show IP details on install 2020-10-11 18:57:30 -04:00
8564912149 phpstan: define LEVELDB_ZLIB_RAW_COMPRESSION if it doesn't exist (for phpstan)
this improves the analysis quality by informing phpstan of the type of whatever should be there.
2020-10-11 23:01:21 +01:00
873535f719 Timezone: explicitly check result of getURL()
phpstan-strict-rules should report this, but it doesn't ...
2020-10-09 17:23:22 +01:00
78f4fcf6ab StatusCommand: removed "Maximum memory (system)"
it's not clear what this was actually supposed to represent, but it actually reports VmSize, which is already reported by "Total virtual memory". This line confuses users and is misleading.
2020-10-08 22:58:37 +01:00
90b749c260 net: reduce default compression level to 6
On larger packets, this worsens compression ratio by 1-2%, but reduces CPU load due to compression by 15-20%. Higher levels than 6 are far more expensive for diminishing returns.
Level 5 produces a further 25-30% CPU reduction, but increases bandwidth usage by 20-25%, so 6 is the sweet spot.
2020-10-08 16:51:10 +01:00
d5398b2781 3.15.3 is next 2020-10-06 13:33:42 +01:00
d7a66ad755 Release 3.15.2 2020-10-06 13:33:42 +01:00
b3f88e7b73 Updated language submodule to pmmp/Language@c85a7b79f3 2020-10-06 13:28:51 +01:00
55adc1ef63 Updated build/php submodule to pmmp/php-build-scripts@e45cfc1ece 2020-10-06 13:09:05 +01:00
868d236ddc Updated composer dependencies 2020-10-06 12:39:19 +01:00
59e9c84806 Merge branch 'stable' of https://github.com/pmmp/pocketmine-mp into stable 2020-10-06 12:35:51 +01:00
a110317d1b Bump phpstan/phpstan from 0.12.47 to 0.12.48 (#3851) 2020-10-05 13:23:19 +00:00
b169d89291 Added some documentation to FurnaceBurnEvent 2020-10-04 21:40:52 +01:00
74bef7f423 Bump phpunit/phpunit from 9.3.11 to 9.4.0 (#3850) 2020-10-02 11:02:17 +00:00
8db7867881 travis: notify about build results 2020-10-01 22:05:12 +01:00
d8f8afe531 Bump phpstan/phpstan from 0.12.46 to 0.12.47 (#3844) 2020-09-30 10:51:33 +00:00
7dabf305f8 Bump phpstan/phpstan from 0.12.44 to 0.12.46 (#3841) 2020-09-29 07:01:51 +00:00
ed0053d0ee Updated build/php submodule to pmmp/php-build-scripts@732ceba847 2020-09-26 13:20:45 +01:00
28255e35d1 Updated composer dependencies 2020-09-26 13:18:38 +01:00
0fc9170bbf Bump phpstan/phpstan from 0.12.43 to 0.12.44 (#3838) 2020-09-25 13:20:29 +00:00
7e2efae024 Bump phpstan/phpstan from 0.12.42 to 0.12.43 (#3831) 2020-09-24 11:23:32 +00:00
e9fa07b550 Bump phpunit/phpunit from 9.3.10 to 9.3.11 (#3835) 2020-09-24 09:57:58 +00:00
8ac32824a2 Bump phpunit/phpunit from 9.3.9 to 9.3.10 (#3828) 2020-09-15 17:01:03 +00:00
1322defead Bump phpunit/phpunit from 9.3.8 to 9.3.9 (#3825) 2020-09-12 12:32:33 +00:00
d084b7a34b RegionGarbageMap: add an extra overlap check
this shouldn't ever be triggered, but we want to know if it does.
2020-09-12 01:38:13 +01:00
c2d0605b1e Entity: avoid implicit float truncation in getDirection()
this didn't cause any bugs because of the way the function is written, but it might have in other circumstances.
2020-09-11 21:01:22 +01:00
0ff0b33047 StatusCommand: avoid modulo operator on float
this was detected by a custom PHPStan extension.
2020-09-11 20:56:18 +01:00
114df07622 RegionLoader: specify type of unpack() return
PHPStan has no idea what is going on in this code because unpack() returns mixed[].
Possibly it might be a good idea to implement a dynamic return type extension for this.
2020-09-11 20:48:37 +01:00
4a88db7f43 travis: update pthreads to pmmp/pthreads@b81ab29df5 2020-09-11 14:30:22 +01:00
d3ea29d527 Release memory to OS on garbage collection
ZMM often holds onto big chunks of memory after they aren't used anymore, which is fine in a webserver, but it's not OK for PM.
2020-09-09 01:40:18 +01:00
d2f1a3cf5b SubChunk: workaround opcache preloading constant issue
non-class constants aren't stored during preloading phase and for some reason they aren't pre-resolved in opcode arrays. However, they are resolved by value when referenced by class constants, and class constants stick, so we can use those instead.
2020-09-04 17:53:22 +01:00
f9c2ed6200 composer: do not install packages with min version higher than 7.3.0
running composer update on 7.4 will generate a lock file using the newest dependencies which work for the current PHP version, which usually isn't desirable for a project like this where developers might be using newer PHP versions than users.
2020-09-04 01:00:26 +01:00
e47a711494 Bump phpstan/phpstan from 0.12.40 to 0.12.42 (#3812) 2020-09-03 14:13:14 +00:00
2ea7a9e216 3.15.2 is next 2020-09-03 15:09:52 +01:00
9f60484212 Release 3.15.1 2020-09-03 15:09:52 +01:00
3031d89ec5 Potato: drop 1-5 potatoes per harvest, not 1-4 2020-09-03 14:54:58 +01:00
883e135bc0 Potato: drop poisonous potatoes when harvested, fixes #2830 2020-09-03 14:54:04 +01:00
4448f603a6 Updated build/php submodule to pmmp/php-build-scripts@3a3e3495c3 2020-09-03 14:53:23 +01:00
9365525efa ANTI CHEAT DOESN'T TRIP ON STAIRS ANYMORE 🎉
This commit fixes the 5+ years-old bug with the movement anti-cheat that everyone has complained about: sprinting on stairs causes rubberbanding.
This commit addresses this problem at long last, along with a handful of precursor commits that were necessary to fix this problem:
- dac76f0e0f
- 89fe8f7f10
- 2d77b1e364

Additionally, these changes now allow the anti-cheat to be accurate to at least 0.001 of a block, perhaps even better. I didn't commit a change to the threshold here, but it was instrumental to pinning down the exact nature of these bugs.

This closes #1475, at long last.
2020-09-03 14:27:11 +01:00
17bee5e349 Fixed crash when using strings for flatworld layers
I don't know why this didn't show up sooner.
2020-09-03 14:15:37 +01:00
c6e0753c3e clean up phpstan baselines 2020-09-02 15:04:37 +01:00
2ae7ba275b Updated Composer dependencies 2020-09-02 12:15:29 +01:00
6aa0a82341 Bump phpstan/phpstan-strict-rules from 0.12.4 to 0.12.5 (#3807) 2020-09-01 10:00:39 +00:00
0af08a7375 Call BlockGrowEvent when sugarcane grows (#3780) 2020-08-31 16:03:38 +01:00
81c1613e5d StupidJsonDecodeTest: added a callable prototype
for some reason this causes a new error to be reported which previously didn't show. I have no idea why.
2020-08-31 13:45:46 +01:00
9cf8f608d8 Provide a default for health (#3806) 2020-08-30 21:50:11 +01:00
dd4f26a9cf Switch "Auto: Spam" trap to direct links (#3550) 2020-08-30 18:03:38 +01:00
f976545f56 Delete security-dos-vulnerability.md 2020-08-29 23:41:37 +01:00
9929fb0abd Create SECURITY.md 2020-08-29 23:40:47 +01:00
37e453b875 Updated composer dependencies 2020-08-28 23:34:32 +01:00
b7578fef9c Fixup TesterPlugin to PHPStan standards 2020-08-28 21:17:21 +01:00
09eb904f6b fixed explicit-mixed errors exposed by upgrading pocketmine/nbt 2020-08-28 15:47:41 +01:00
b47d6bbc22 Bump phpstan/phpstan from 0.12.39 to 0.12.40 (#3800) 2020-08-27 11:45:20 +00:00
aa26ddf8b1 Bump phpunit/phpunit from 9.3.7 to 9.3.8 (#3799) 2020-08-27 11:44:54 +00:00
119c72980f Bump phpstan/phpstan from 0.12.37 to 0.12.39 (#3794) 2020-08-25 20:38:22 +00:00
eba888449d ExperienceUtils: handle an unhandled error condition explicitly
this would previously throw a TypeError on some negative numbers and crash. This should still crash, but this makes it explicit.
2020-08-25 21:28:29 +01:00
dac76f0e0f Player: reset ySize when syncing movement 2020-08-23 18:31:25 +01:00
89fe8f7f10 Entity: shift BB back down after trying to auto-step
this fixes bugs where the entity would jump in the air when walking on blocks like carpet. It also fixes a lot of the issues with stepping in the anti-cheat, allowing to reduce the error tolerance on movement processing.
2020-08-23 17:54:48 +01:00
2d77b1e364 Entity: fixed recalculateCollisionBox not taking ySize into account
this was causing the movement anti-cheat to shit itself after the first movement because it used setPosition() on the player if the position wasn't exactly perfect (which obviously it never is perfect, because of fp rounding errors).
2020-08-23 17:51:36 +01:00
e59a4296f8 LevelDB: fixed crash on corrupted level.dat 2020-08-22 19:36:22 +01:00
6856761946 Updated composer dependencies to fix some 7.4 issues 2020-08-21 22:09:26 +01:00
4fe3401182 travis: moved PHP-specific configuration to its own YAML file
this allows it to be imported by other repos using the same config (for example plugins needing PHPStan analysis) without them needing to copy paste big blocks of shit every time something little changes.
2020-08-21 17:42:47 +01:00
e80ad22702 Updated build/php submodule 2020-08-21 00:34:10 +01:00
c22ab37372 Player: pre-cancel PlayerInteractEvent when left-clicking a block in spectator mode
fixes #3778
2020-08-20 23:43:52 +01:00
1f9d672cfc Updated DevTools submodule to release 1.14.1 2020-08-20 16:49:49 +01:00
974cbae725 travis: added PHP 7.4 2020-08-20 16:21:58 +01:00
b53f88027e Explosion: fixed blocks getting updated too early
this bug became painfully obvious when testing bamboo. Detonating TNT near tall bamboo canes would result in bamboo canes not deleting themselves in some circumstances, because the non-destroyed parts of the cane would be updated before their supporting block was deleted, and subsequently would not be re-updated afterwards.
I think this bug should also reproduce with cacti, but I have not tested.
2020-08-16 00:09:17 +01:00
9a0f723dff Updated composer dependencies 2020-08-15 20:19:37 +01:00
ab2003a85d Merge branch 'stable' of https://github.com/pmmp/pocketmine-mp into stable 2020-08-15 20:17:04 +01:00
4befd9095a Updated build/php submodule to pmmp/php-build-scripts@f93a6f0e31 2020-08-15 20:16:29 +01:00
06623d788a Bump phpunit/phpunit from 9.3.5 to 9.3.7 (#3771) 2020-08-15 17:46:26 +00:00
730ee74a65 Use objects for internal structures created in TextFormat::toJSON() (#3747) 2020-08-15 18:30:26 +01:00
700e0afee0 Updated build/php submodule to pmmp/php-build-scripts@cfc425ad63 2020-08-11 21:39:15 +01:00
4b9712fdee fixed changelog typo 2020-08-11 21:37:15 +01:00
dbd015b866 3.15.1 is next 2020-08-11 21:26:12 +01:00
a498b0415a Release 3.15.0 2020-08-11 21:26:12 +01:00
5b01cf72dd Data sync and version bump for 1.16.20
this version doesn't change any packets as far as I know, but it does change some packet content (most notably, some blockstates changed, which are troublesome when not in sync).
2020-08-11 21:17:11 +01:00
ec21c2baa0 Merge branch 'stable' of https://github.com/pmmp/pocketmine-mp into stable 2020-08-11 21:07:06 +01:00
11a0d9b502 3.14.4 is next 2020-08-11 21:06:38 +01:00
a7fc245291 Release 3.14.3 2020-08-11 21:06:38 +01:00
6db51e2380 Updated CONTRIBUTING.md RFC label name 2020-08-11 12:35:12 +08:00
d6f35f2342 Bump phpunit/phpunit from 9.3.2 to 9.3.5 (#3764) 2020-08-10 19:15:28 +00:00
d1df72ec78 Bump phpstan/phpstan from 0.12.36 to 0.12.37 (#3765) 2020-08-10 19:10:19 +00:00
9bd6d5c67e Updated travis pthreads to pmmp/pthreads@45579e1e62 2020-08-10 17:45:06 +01:00
aaa23361d1 updated devtools links 2020-08-10 17:32:09 +01:00
691d92a959 moved tests/plugins/PocketMine-DevTools -> tests/plugins/DevTools 2020-08-10 17:29:44 +01:00
50101663f2 Use the up-to-date git submodule urls 2020-08-10 17:25:48 +01:00
e369966890 updated composer.lock 2020-08-07 20:00:12 +01:00
63f57841de PlayerAuthInputPacket: fixed yaw/pitch being the wrong way round, closes #3757 2020-08-07 19:50:49 +01:00
ac3bba0a11 Bump phpunit/phpunit from 9.2.6 to 9.3.2 (#3758) 2020-08-07 15:38:57 +00:00
1ff3df6ff0 Bump phpstan/phpstan-phpunit from 0.12.15 to 0.12.16 (#3753) 2020-08-05 19:49:04 +00:00
4e29b216bf Bump phpstan/phpstan from 0.12.35 to 0.12.36 (#3752) 2020-08-05 18:12:12 +00:00
809dad2ac8 Bump phpstan/phpstan-phpunit from 0.12.11 to 0.12.15
Bumps [phpstan/phpstan-phpunit](https://github.com/phpstan/phpstan-phpunit) from 0.12.11 to 0.12.15.
- [Release notes](https://github.com/phpstan/phpstan-phpunit/releases)
- [Commits](https://github.com/phpstan/phpstan-phpunit/compare/0.12.11...0.12.15)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-05 10:46:27 +00:00
e238d583b8 Bump phpstan/phpstan-strict-rules from 0.12.3 to 0.12.4 (#3748) 2020-08-05 10:38:00 +00:00
3f89bd7bff TaskHandler->getOwnerName() never returns NULL 2020-08-04 16:58:27 +01:00
8da7e789fd LoginPacket: protocol cannot be NULL 2020-08-04 16:55:47 +01:00
0766952f39 FINALLY, a usable new build of phpstan 2020-08-04 11:38:00 +01:00
eeee1fbe73 Updated composer dependencies 2020-08-04 11:32:25 +01:00
46c224da86 phpstan: remove an obsolete ignored error pattern from explicit-mixed baseline 2020-08-03 19:54:53 +01:00
3c001b310f fix phpstan analyze failure 2020-08-03 19:54:14 +01:00
198a106b9f Merge branch 'stable' of https://github.com/pmmp/pocketmine-mp into stable 2020-08-03 19:37:30 +01:00
1f5e0bc96d Updated BedrockData submodule, new recipes.json format 2020-08-03 19:36:32 +01:00
41f7c07703 Entity: report the class in getSaveId() unregistered entity exception (#3744) 2020-08-03 00:20:28 +01:00
f0a0c9a85f Player: remove useless var 2020-08-02 23:49:07 +01:00
5b620d964e Do not assume the presence of a crafting transaction closing marker
fixes #3655, fixes #3241
instead of guessing where the end of the transaction is, we attempt validation after every piece of the transaction, with the assumption being that a crafting transaction will not validate until it's complete.
2020-08-02 23:37:33 +01:00
756840f11d Fixed matchItems corrupting CraftingTransaction internal state on repeated validation
This bug became apparent while developing a more robust fix for 1.16 crafting.
2020-08-02 23:07:47 +01:00
df2c3136c9 VersionString: added missing start anchor to regex 2020-08-02 21:10:47 +01:00
a6b5cddd5a remove unused import 2020-07-21 19:26:24 +01:00
5b9453af43 WhitelistCommand: fixed incorrect implode() parameter order
PHP allows this to work either way for legacy reasons, but glue-first is the canonical way for a long time.
2020-07-21 11:46:11 +01:00
8bba25f4f5 Fix wrong hardness value for Podzol (#3709) 2020-07-16 22:07:41 +01:00
f9bd7016aa Bump phpstan/phpstan-strict-rules from 0.12.2 to 0.12.3 (#3705) 2020-07-16 15:24:42 +00:00
213406fc60 Bump phpunit/phpunit from 9.2.5 to 9.2.6 (#3701) 2020-07-14 16:44:35 +00:00
7ff6e5895e added missing 3.14.2 changelog 2020-07-13 11:55:08 +01:00
2e6b62fdec 3.14.3 is next 2020-07-13 10:46:58 +01:00
4fc5b9772a Release 3.14.2 2020-07-13 10:46:57 +01:00
5d4880b0a7 SendUsageTask: fixed json_encode() choking on player list keys 2020-07-11 20:14:04 +01:00
2b1a0e1e72 PlayerRespawnEvent: harden setRespawnPosition()
apparently plugins like to pass around positions which have null worlds, which aside from being quite stupid, also breaks a lot of stuff and makes it look like PM is to blame when it's just trying to make everything work the way it's supposed to ...
2020-07-10 20:37:45 +01:00
cd022f1592 EmotePacket: make FLAG_SERVER constant public 2020-07-10 20:02:32 +01:00
4ae3fd7734 Player: Reset spawn chunk send count if teleporting pre-spawn 2020-07-09 12:17:19 +01:00
b2249f93c0 TaskHandler: bail if given a task that already has a handler
This fixes undefined behaviour when scheduling the same task twice. This is usually accidental and almost never desirable.
Note that this still allows a task to be scheduled again after it has
been cancelled; it only disallows scheduling a task multiple times
concurrently.

This commit will probably break MyPlot and other plugins that have
self-scheduling tasks, but as far as I can tell those use-cases should
be replaced with self-cancelling repeating tasks anyway.
2020-07-08 11:02:33 +01:00
303344783a CheckTestCompletionTask: use TaskHandler->cancel() 2020-07-08 10:57:20 +01:00
75e0844ff5 MainLogger: log stack traces with CRITICAL level
maybe this will get people to send the whole thing instead of just the error message? ...
2020-07-08 10:45:15 +01:00
18fabf5466 3.14.2 is next 2020-07-08 10:32:07 +01:00
2751c59979 Release 3.14.1 2020-07-08 10:32:07 +01:00
d99ffbd66c Attribute: register lava_movement attribute
this is purely to fix crashes when decoding net packets
2020-07-08 10:21:20 +01:00
a34f3261cb event: harden APIs that accept arrays
plugin devs can't be relied on to pass the proper types to these APIs, and when the wrong types get passed it makes type errors appear from inside the internals.
2020-07-04 21:55:23 +01:00
8ce0022de6 protocol: added UUInventorySlotOffset constants 2020-07-04 21:37:37 +01:00
fb6491ddeb BanListCommand: sort output into lexical order 2020-07-03 11:23:00 +01:00
3b961d0e5f WhitelistCommand: sort output of /whitelist list into lexical order 2020-07-03 11:19:23 +01:00
a60fc4cc28 ListCommand: sort output into lexical order 2020-07-03 11:15:31 +01:00
b747899fdd PluginsCommand: sort plugins list into lexical order 2020-07-03 11:13:32 +01:00
57b6451e16 Fix projectile motion being changed by the ladder, close #3602 (#3631) 2020-06-27 21:18:39 +01:00
8cf025a2df Default isVerified to true (#3644) 2020-06-27 21:17:34 +01:00
8480ee82ea Player: track hardcoded window state, fixes crashes opening inventory on high-latency connections 2020-06-27 18:34:39 +01:00
a6c1b7bf9c InventoryTransactionPacket: added missing field for encode 2020-06-26 20:57:48 +01:00
c267137fde 3.14.1 is next 2020-06-26 14:19:02 +01:00
461bc94236 Release 3.14.0 2020-06-26 14:19:02 +01:00
4fed08bcd4 ProtocolInfo: fixed version number 2020-06-26 14:15:58 +01:00
e990c5a0a5 Protocol changes for 1.16.0 2020-06-26 14:06:41 +01:00
c616d9bb7c 3.13.2 is next 2020-06-26 12:31:56 +01:00
81051441ba Release 3.13.1 2020-06-26 12:31:56 +01:00
3ecae0db19 WindowTypes: fill in a couple of blanks 2020-06-26 12:04:11 +01:00
c5bbb2bcbc Move crafting action detection from InventoryTransactionPacket to Player 2020-06-26 11:59:30 +01:00
24a2889758 NetworkInventoryAction does not require an InventoryTransactionPacket 2020-06-26 11:51:06 +01:00
60b26a7ea8 NetworkBinaryStream: unknown byte preceding NBT is a version, not a count 2020-06-26 11:47:08 +01:00
22b52f03d1 Player: fixed formatting error in InteractPacket debug message 2020-06-26 11:44:41 +01:00
df76c02e7a Explicitly release server.lock file when shutdown the server. (#3619)
Previously, this relied on PHP itself to release locks during the resource destructor phase during process exit, but sometimes it doesn't for god knows what reason. This change makes the lock file get explicitly released before the process dies.
2020-06-26 11:41:39 +01:00
d343187e58 phpstan: drop 2 obsolete level 8 error patterns fixed by 763c8ebfe3 2020-06-23 12:57:25 +01:00
c5ad127854 BaseInventory: mark eventProcessor as nullable, fixes a phpstan level 8 error 2020-06-23 12:55:06 +01:00
0f6dc9082a lock phpstan at 0.12.29
0.12.30 starts reporting non-ignorable errors for overriding Thread::start() due to outdated stubs for pthreads that I can't replace
2020-06-22 20:57:12 +01:00
2b6dcbc2e2 BaseLang: fixed passing onlyPrefix to str_replace()'s count reference parameter 2020-06-22 20:34:23 +01:00
763c8ebfe3 Thread/Worker: drop nullability flag from start() (fixed in pthreads 3.2.0, which we require as a minimum) 2020-06-21 19:07:01 +01:00
c572e9bb6a phpstan: regenerate l7 baseline 2020-06-21 18:58:41 +01:00
89521f166d Explosion: account for multi-block structures, fixes #2767 2020-06-21 17:28:38 +01:00
49d3a42120 phpstan: make EntityEvent generic, fix a bunch of 'actual-problems' ignored errors 2020-06-21 00:27:32 +01:00
c523595e85 Rewrite TeleportCommand (sadly I can't make this commit any smaller)
this pile of shit was overdue a rewrite. The new version is much easier to understand.
2020-06-21 00:04:18 +01:00
7c7e4f2093 WhitelistCommand: fixed silence on unknown subcommand 2020-06-20 23:05:39 +01:00
88c1014f03 TimingsCommand: fixed silence when using a nonexisting subcommand 2020-06-20 23:04:08 +01:00
e32180ce93 phpstan: drop an obsolete phpstan-bugs ignoreError 2020-06-19 10:41:41 +01:00
e105578be0 LegacySkinAdapter: an extra check for resourcePatch (fixes 3 phpstan explicitMixed errors) 2020-06-18 20:08:38 +01:00
a9d98bdf73 phpstan: baseline our way into checkExplicitMixed territory 2020-06-18 18:07:21 +01:00
c601352777 Fixed wrong meta value when pick cake block. (#3593) 2020-06-18 11:14:57 +01:00
77c71e22b2 SkinAdapter::fromSkinData() may now throw InvalidSkinException
fixes a rogue TODO in LegacySkinAdapter and invalid skins maybe showing up as Steve instead of getting kicked off the server
2020-06-17 21:44:22 +01:00
1c13ba5656 Avoid parameter ordering bugs during packet decoding
A PhpStorm refactor could have side effects on code that directly reads stuff from the packet input stream in the arguments block, because those calls will get moved into a different order if the constructor gets refactored. This would, obviously, break packet decoding, so that's something we should avoid and really should not encourage.
2020-06-17 21:01:01 +01:00
f970be0e4d SkinImage: 128x64 is not a valid classic skin size
MC itself doesn't accept classic skins of this size.
2020-06-17 20:31:28 +01:00
11a3f9f1b9 VerifyLoginTask: fast-fail by checking header x5u before verifying signature
this is less costly, although it doesn't make any difference except in invalid cases.
2020-06-17 17:52:19 +01:00
09771849ae VerifyLoginTask optimisation: do not copy the entire LoginPacket into the worker thread
this is especially bad considering the fact that the cached buffer is copied. That said, it's only a few kilobytes so it's not a huge problem, but nonetheless...
2020-06-17 17:46:22 +01:00
57a310230a ScoreboardIdentityPacketEntry: added missing field default 2020-06-15 23:59:53 +01:00
130c55d9f1 EntityLink: remove rogue default ctor parameters 2020-06-15 23:58:11 +01:00
2712befa82 SkinData: fixed capeImage type violation (doesn't accept null) 2020-06-15 23:51:48 +01:00
a4e250a3e6 TextFormat: improved exception messages for PCRE failures 2020-06-15 23:43:01 +01:00
23b97d8e2d TextFormat: wrap all preg_replace() usages in a type-safe exception-throwing version
fixes 3 phpstan level 8 errors
2020-06-15 23:31:46 +01:00
1fb5043eb1 build/server-phar: fixed a phpstan level 8 error 2020-06-15 23:16:40 +01:00
b0b1b29de4 Chunk: specify list<int> for heightMap 2020-06-15 23:07:35 +01:00
1c3b641e37 ChunkUtils: be more specific in extension stub too 2020-06-15 23:07:05 +01:00
f3063e797f ChunkUtils: provide a more explicit parameter type 2020-06-15 23:05:52 +01:00
8dcc88712c ChunkUtils: fixed phpstan level 7 type inference error 2020-06-15 23:04:12 +01:00
04191ec44a Rail: specify type for local static variable
fixes a phpstan level 7 error
phpstan doesn't make any assumptions about local static variable types because analysing them would require too much work, apparently.
2020-06-15 22:47:20 +01:00
62ea7c93a9 added a dedicated InvalidSkinException 2020-06-15 21:48:24 +01:00
cf06b5b8cf Player: explicitly check for false return of dataPacket()
fixes a phpstan error on l7
this won't ever actually be a problem, but this isn't obvious from the type system.
2020-06-15 21:24:19 +01:00
a8ec51daac Player: do not assign maybe-false result of json_encode() to ModalFormRequestPacket
fixes a phpstan error on l7
2020-06-15 21:22:33 +01:00
6a7b77fee2 first look at making region writes reuse old space 2020-06-15 18:36:54 +01:00
da42c8d020 Bump phpunit/phpunit from 9.2.2 to 9.2.3 (#3588) 2020-06-15 16:30:50 +00:00
b902f9ded0 RegionLoader: fixed 2 phpstan level 7 errors (eof reading region header) 2020-06-15 15:09:37 +01:00
9bb8a8f761 RegionLoader: added utility function getProportionUnusedSpace() 2020-06-15 13:49:03 +01:00
63b14a083c RegionLoader: added utility function generateSectorMap()
this proved very useful while debugging some internal issues.
2020-06-15 13:48:17 +01:00
627a7c951a RegionLoader: added missing const import 2020-06-15 13:46:03 +01:00
bb2685ca65 RegionLocationTableEntry: cap firstSector at 16777216
this is the biggest sector start that the location table can represent, due to the binary format. Larger values than this will overflow and cause corruption.
This provides an effective limit of 64 GB on region files.
2020-06-15 13:23:08 +01:00
d38709a7ae RegionLoader: remove unused variable 2020-06-15 12:26:20 +01:00
b559a65346 RegionLoader: account for possible corrupted header pointing to itself 2020-06-15 12:13:42 +01:00
b92a2ded8a RegionLoader: check for zero sector count when loading location table
implementations shouldn't be writing location entries that have an offset but zero sectors, but just in case they do, we need to be aware of it.
2020-06-15 12:08:55 +01:00
22f25dfbdb RegionLocationTableEntry: require sector count to be at least 1 2020-06-15 12:05:48 +01:00
6bf840c72e RegionLoader: use actual null instead of zeroed entry for non-allocated chunks
this forces the code to be properly aware of non-allocated chunks, because it'll crash with NPE if it isn't.
2020-06-15 12:02:03 +01:00
745be19a56 RegionLoader: fixed regions ballooning when writing chunks to the end of file
we already have a region growth problem due to the lack of garbage collection, but this bug was making it worse. If the region already contained 1024 allocated chunks, 4MB of file space would get wasted before the next chunk would be appended to the file.
2020-06-14 23:40:33 +01:00
e05bee5ffb RegionLoader: do a full check for chunk overlaps during initial load 2020-06-14 22:39:01 +01:00
087ba0cc1d phpstan: update config to use new 0.12.26+ options 2020-06-14 19:57:36 +01:00
d8d994351b phpstan 0.12.29 2020-06-14 16:25:55 +01:00
0029efa370 Server: add getPlayerDataPath(), reduce logic duplication 2020-06-14 12:40:24 +01:00
df13e967fd imports cleanup 2020-06-14 10:27:15 +01:00
097c260dbb Eradicate all usages of strtoupper()
strtoupper() is an evil function whose behaviour depends on the system locale. mb_strtoupper() has more consistent behaviour.
2020-06-13 19:47:00 +01:00
a219b727f2 updated build/php submodule to pmmp/php-build-scripts@cec63c3093 2020-06-13 11:14:21 +01:00
710c162604 QueryRegenerateEvent: fixed possible type violation on listPlugins 2020-06-10 12:11:39 +01:00
409c8c1703 TimingsCommand: workaround a PHPStan type specifying bug 2020-06-10 12:11:10 +01:00
376926c700 TimingsCommand: fix missing type information for async task local storage 2020-06-10 12:10:33 +01:00
c3fabe833e FileWriteTask: mark as deprecated 2020-06-10 11:22:18 +01:00
3e09ff5350 EnchantTable: fix formatting issue [ci skip] 2020-06-10 10:54:22 +01:00
7255065106 LevelDB: stop passing false to places where it's not expected 2020-06-10 10:45:54 +01:00
a7f10d8ccf phpstan: ignore a FP (fixed in 0.12.26, but we can't upgrade yet) 2020-06-10 10:45:28 +01:00
76f1add3b3 Timezone: return false if date_parse() fails
I hate this, but I don't want to change it to throw right now because it'll create a bunch of extra work.
2020-06-10 10:34:34 +01:00
fcc9e62c65 CommandEnum: specify enumValues type
phpstan 0.12.26 starts reporting errors about the result of array_search() being given to some constructor or another because of the lack of key type specification.
2020-06-10 10:33:35 +01:00
42613618a5 phpstan: add LevelDB::get() stub to fix return type 2020-06-10 10:31:54 +01:00
1bbeb62457 Bump phpunit/phpunit from 9.2.1 to 9.2.2 (#3566) 2020-06-08 17:32:39 +00:00
64893426fa Bump phpunit/phpunit from 8.5.5 to 9.2.1 (#3557) 2020-06-06 10:13:46 +00:00
3d50aafcc4 ShapedRecipe: remove a curly-brace array-access that nothing noticed 2020-06-06 11:12:45 +01:00
50fed41642 README: we're now on travis-ci.com 2020-06-05 13:02:31 +01:00
3f971a0c65 phpstan: fixed analyze failure caused by a27b29897c 2020-06-05 12:58:18 +01:00
a27b29897c TimingsCommand: tell operators what's going on for audit purposes
previously nobody except the person who was managing timings would know that timings was running, being pasted or whatever else. Since timings can impact performance (and, for example, block the main thread when writing timings to a file), access to it should be logged so that server owners know what's going on.
2020-06-05 11:12:36 +01:00
a90132a30e added missing 3.12.6 changelog 2020-06-04 20:38:06 +01:00
dfbd857771 3.13.1 is next 2020-06-04 20:01:28 +01:00
322 changed files with 11253 additions and 3603 deletions

11
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,11 @@
blank_issues_enabled: false
contact_links:
- name: Help & support on Discord
url: https://discord.gg/bmSAZBG
about: We don't accept support requests on the issue tracker. Please try asking on Discord instead.
- name: Help & support on forums
url: https://forums.pmmp.io
about: We don't accept support requests on the issue tracker. Please try asking on forums instead.
- name: Documentation
url: https://pmmp.rtfd.io
about: PocketMine-MP documentation

View File

@ -9,6 +9,7 @@ assignees: ''
<!--- submit crashdump files to https://crash.pmmp.io -->
<!--- or, copy the data between ===BEGIN CRASH DUMP=== and ===END CRASH DUMP and paste it on a site like https://pastebin.com -->
<!--- DON'T JUST PASTE the crashdump into an issue -->
Link to crashdump:
<!--- write additional information about the crash to help us find the problem -->

View File

@ -1,14 +0,0 @@
---
name: Help & support
about: We don't accept support requests here. Try the links on the README.
title: ''
labels: Support request
assignees: ''
---
We don't accept support requests on the issue tracker. Please try the following links instead:
Documentation: http://pmmp.rtfd.io
Forums: https://forums.pmmp.io
Discord: https://discord.gg/bmSAZBG

View File

@ -1,12 +0,0 @@
---
name: Security/DoS vulnerability
about: 'Bug or exploit that can be used to attack servers (hint: don''t report it
on a public issue tracker)'
title: ''
labels: 'Auto: Spam'
assignees: ''
---
Please DO NOT report security vulnerabilities here.
Instead, send an email to team@pmmp.io or contact a developer directly, IN PRIVATE.

16
.github/support.yml vendored
View File

@ -1,16 +0,0 @@
# Configuration for support-requests - https://github.com/dessant/support-requests
# Label used to mark issues as support requests
supportLabel: "Support request"
# Comment to post on issues marked as support requests. Add a link
# to a support page, or set to `false` to disable
supportComment: >
Thanks, but this issue tracker is not intended for support requests. Please read the guidelines on [submitting an issue](https://github.com/pmmp/PocketMine-MP/blob/master/CONTRIBUTING.md#creating-an-issue).
[Docs](https://pmmp.rtfd.io) | [Discord](https://discord.gg/bmSAZBG) | [Forums](https://forums.pmmp.io)
# Whether to close issues marked as support requests
close: true
# Whether to lock issues marked as support requests
lock: false

281
.github/workflows/main.yml vendored Normal file
View File

@ -0,0 +1,281 @@
name: CI
on:
push:
pull_request:
workflow_dispatch:
jobs:
build-php:
name: Prepare PHP
runs-on: ${{ matrix.image }}
strategy:
matrix:
image: [ubuntu-20.04]
php: [7.3.27, 7.4.16]
steps:
- uses: actions/checkout@v2 #needed for build.sh
- name: Check for PHP build cache
id: php-build-cache
uses: actions/cache@v2
with:
path: "./bin"
key: "php-build-generic-${{ matrix.php }}-${{ matrix.image }}-${{ hashFiles('./tests/gh-actions/build.sh') }}"
- name: Compile PHP
if: steps.php-build-cache.outputs.cache-hit != 'true'
run: ./tests/gh-actions/build.sh "${{ matrix.php }}"
phpstan:
name: PHPStan analysis
needs: build-php
runs-on: ${{ matrix.image }}
strategy:
fail-fast: false
matrix:
image: [ubuntu-20.04]
php: [7.3.27, 7.4.16]
steps:
- uses: actions/checkout@v2
- name: Restore PHP build cache
id: php-build-cache
uses: actions/cache@v2
with:
path: "./bin"
key: "php-build-generic-${{ matrix.php }}-${{ matrix.image }}-${{ hashFiles('./tests/gh-actions/build.sh') }}"
- name: Kill build on PHP build cache miss (should never happen)
if: steps.php-build-cache.outputs.cache-hit != 'true'
run: exit 1
- name: Install cached PHP's dependencies
if: steps.php-build-cache.outputs.cache-hit == 'true'
run: chmod +x ./bin/php7/install-dependencies.sh && ./bin/php7/install-dependencies.sh
- name: Prefix PHP to PATH
run: echo "$(pwd)/bin/php7/bin" >> $GITHUB_PATH
- name: Install Composer
run: curl -sS https://getcomposer.org/installer | php
- name: Restore Composer package cache
uses: actions/cache@v2
with:
path: |
~/.cache/composer/files
~/.cache/composer/vcs
key: "composer-v2-cache-${{ matrix.php }}-${{ hashFiles('./composer.lock') }}"
restore-keys: |
composer-v2-cache-
- name: Install Composer dependencies
run: php composer.phar install --prefer-dist --no-interaction
- name: Run PHPStan
run: ./vendor/bin/phpstan analyze --no-progress --memory-limit=2G
phpunit:
name: PHPUnit tests
needs: build-php
runs-on: ${{ matrix.image }}
strategy:
fail-fast: false
matrix:
image: [ubuntu-20.04]
php: [7.3.27, 7.4.16]
steps:
- uses: actions/checkout@v2
- name: Restore PHP build cache
id: php-build-cache
uses: actions/cache@v2
with:
path: "./bin"
key: "php-build-generic-${{ matrix.php }}-${{ matrix.image }}-${{ hashFiles('./tests/gh-actions/build.sh') }}"
- name: Kill build on PHP build cache miss (should never happen)
if: steps.php-build-cache.outputs.cache-hit != 'true'
run: exit 1
- name: Install cached PHP's dependencies
if: steps.php-build-cache.outputs.cache-hit == 'true'
run: chmod +x ./bin/php7/install-dependencies.sh && ./bin/php7/install-dependencies.sh
- name: Prefix PHP to PATH
run: echo "$(pwd)/bin/php7/bin" >> $GITHUB_PATH
- name: Install Composer
run: curl -sS https://getcomposer.org/installer | php
- name: Restore Composer package cache
uses: actions/cache@v2
with:
path: |
~/.cache/composer/files
~/.cache/composer/vcs
key: "composer-v2-cache-${{ matrix.php }}-${{ hashFiles('./composer.lock') }}"
restore-keys: |
composer-v2-cache-
- name: Install Composer dependencies
run: php composer.phar install --prefer-dist --no-interaction
- name: Run PHPUnit tests
run: ./vendor/bin/phpunit --bootstrap vendor/autoload.php --fail-on-warning tests/phpunit
integration:
name: Integration tests
needs: build-php
runs-on: ${{ matrix.image }}
strategy:
fail-fast: false
matrix:
image: [ubuntu-20.04]
php: [7.3.27, 7.4.16]
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Restore PHP build cache
id: php-build-cache
uses: actions/cache@v2
with:
path: "./bin"
key: "php-build-generic-${{ matrix.php }}-${{ matrix.image }}-${{ hashFiles('./tests/gh-actions/build.sh') }}"
- name: Kill build on PHP build cache miss (should never happen)
if: steps.php-build-cache.outputs.cache-hit != 'true'
run: exit 1
- name: Install cached PHP's dependencies
if: steps.php-build-cache.outputs.cache-hit == 'true'
run: chmod +x ./bin/php7/install-dependencies.sh && ./bin/php7/install-dependencies.sh
- name: Prefix PHP to PATH
run: echo "$(pwd)/bin/php7/bin" >> $GITHUB_PATH
- name: Install Composer
run: curl -sS https://getcomposer.org/installer | php
- name: Restore Composer package cache
uses: actions/cache@v2
with:
path: |
~/.cache/composer/files
~/.cache/composer/vcs
key: "composer-v2-cache-${{ matrix.php }}-${{ hashFiles('./composer.lock') }}"
restore-keys: |
composer-v2-cache-
- name: Install Composer dependencies
run: php composer.phar install --no-dev --prefer-dist --no-interaction
- name: Run integration tests
run: ./tests/travis.sh -t4
preprocessor:
name: Preprocessor tests
needs: build-php
runs-on: ${{ matrix.image }}
strategy:
fail-fast: false
matrix:
image: [ubuntu-20.04]
php: [7.3.27, 7.4.16]
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Restore PHP build cache
id: php-build-cache
uses: actions/cache@v2
with:
path: "./bin"
key: "php-build-generic-${{ matrix.php }}-${{ matrix.image }}-${{ hashFiles('./tests/gh-actions/build.sh') }}"
- name: Kill build on PHP build cache miss (should never happen)
if: steps.php-build-cache.outputs.cache-hit != 'true'
run: exit 1
- name: Install cached PHP's dependencies
if: steps.php-build-cache.outputs.cache-hit == 'true'
run: chmod +x ./bin/php7/install-dependencies.sh && ./bin/php7/install-dependencies.sh
- name: Prefix PHP to PATH
run: echo "$(pwd)/bin/php7/bin" >> $GITHUB_PATH
- name: Install Composer
run: curl -sS https://getcomposer.org/installer | php
- name: Restore Composer package cache
uses: actions/cache@v2
with:
path: |
~/.cache/composer/files
~/.cache/composer/vcs
key: "composer-v2-cache-${{ matrix.php }}-${{ hashFiles('./composer.lock') }}"
restore-keys: |
composer-v2-cache-
- name: Install Composer dependencies
run: php composer.phar install --no-dev --prefer-dist --no-interaction
- name: Run preprocessor
run: |
PM_PREPROCESSOR_PATH="$GITHUB_WORKSPACE/build/preprocessor"
php "$PM_PREPROCESSOR_PATH/PreProcessor.php" --path=src --multisize || (echo "Preprocessor exited with code $?" && exit 1)
#dump the diff of preprocessor replacements to a patch in case it has bugs
git diff > preprocessor_diff.patch
VENDOR_PM="$GITHUB_WORKSPACE/vendor"
VENDOR_PM_BACKUP="$GITHUB_WORKSPACE/vendor-before-preprocess"
cp -r "$VENDOR_PM" "$VENDOR_PM_BACKUP"
for f in $(ls $VENDOR_PM/pocketmine); do
echo "Processing directory \"$f\"..."
php "$PM_PREPROCESSOR_PATH/PreProcessor.php" --path="$VENDOR_PM/pocketmine/$f" --multisize || (echo "Preprocessor exited with code $?" && exit 1)
echo "Checking for changes in \"$f\"..."
DIFF=$(git diff --no-index "$VENDOR_PM_BACKUP/pocketmine/$f" "$VENDOR_PM/pocketmine/$f" || true)
if [ "$DIFF" != "" ]; then
PATCH="$GITHUB_WORKSPACE/preprocessor_diff_$f.patch"
echo "$DIFF" > "$PATCH"
echo "Generated patch file \"$PATCH\""
else
echo "No diff generated for \"$f\" (preprocessor made no changes)"
fi
done
- name: Upload preprocessor diffs
uses: actions/upload-artifact@v2
if: always()
with:
name: preprocessor_diffs_${{ matrix.php }}_${{ matrix.image }}
path: ${{ github.workspace }}/preprocessor_diff*.patch
codestyle:
name: Code Style checks
runs-on: ubuntu-20.04
strategy:
fail-fast: false
steps:
- uses: actions/checkout@v2
- name: Setup PHP and tools
uses: shivammathur/setup-php@2.9.0
with:
php-version: 7.4
tools: php-cs-fixer
- name: Run PHP-CS-Fixer
run: php-cs-fixer fix --dry-run --diff --diff-format=udiff

22
.github/workflows/support.yml vendored Normal file
View File

@ -0,0 +1,22 @@
name: 'Manage support request issues'
on:
issues:
types: [labeled, unlabeled, reopened]
jobs:
support:
runs-on: ubuntu-latest
steps:
- uses: dessant/support-requests@v2
with:
github-token: ${{ github.token }}
support-label: "Support request"
issue-comment: >
Thanks, but this issue tracker is not intended for support requests. Please read the guidelines on [submitting an issue](https://github.com/pmmp/PocketMine-MP/blob/master/CONTRIBUTING.md#creating-an-issue).
[Docs](https://pmmp.rtfd.io) | [Discord](https://discord.gg/bmSAZBG) | [Forums](https://forums.pmmp.io)
close-issue: true
lock-issue: false

8
.gitmodules vendored
View File

@ -1,12 +1,12 @@
[submodule "src/pocketmine/lang/locale"]
path = src/pocketmine/lang/locale
url = https://github.com/pmmp/PocketMine-Language.git
url = https://github.com/pmmp/Language.git
[submodule "tests/preprocessor"]
path = build/preprocessor
url = https://github.com/pmmp/preprocessor.git
[submodule "tests/plugins/PocketMine-DevTools"]
path = tests/plugins/PocketMine-DevTools
url = https://github.com/pmmp/PocketMine-DevTools.git
[submodule "tests/plugins/DevTools"]
path = tests/plugins/DevTools
url = https://github.com/pmmp/DevTools.git
[submodule "build/php"]
path = build/php
url = https://github.com/pmmp/php-build-scripts.git

71
.php_cs Normal file
View File

@ -0,0 +1,71 @@
<?php
$finder = PhpCsFixer\Finder::create()
->in(__DIR__ . '/src')
->in(__DIR__ . '/build')
->in(__DIR__ . '/tests')
->notPath('plugins/DevTools')
->notPath('preprocessor')
->notContains('#ifndef COMPILE') //preprocessor will break if these are changed
->notName('PocketMine.php');
return PhpCsFixer\Config::create()
->setRiskyAllowed(true)
->setRules([
'align_multiline_comment' => [
'comment_type' => 'phpdocs_only'
],
'array_indentation' => true,
'array_syntax' => [
'syntax' => 'short'
],
'blank_line_after_namespace' => true,
'blank_line_after_opening_tag' => true,
'blank_line_before_statement' => [
'statements' => [
'declare'
]
],
'cast_spaces' => [
'space' => 'single'
],
'concat_space' => [
'spacing' => 'one'
],
'declare_strict_types' => true,
'elseif' => true,
'global_namespace_import' => [
'import_constants' => true,
'import_functions' => true,
'import_classes' => null,
],
'indentation_type' => true,
'native_function_invocation' => [
'scope' => 'namespaced'
],
'no_closing_tag' => true,
'no_empty_phpdoc' => true,
'no_extra_blank_lines' => true,
'no_superfluous_phpdoc_tags' => [
'allow_mixed' => true,
],
'no_trailing_whitespace' => true,
'no_trailing_whitespace_in_comment' => true,
'no_whitespace_in_blank_line' => true,
'no_unused_imports' => true,
'ordered_imports' => [
'imports_order' => [
'class',
'function',
'const',
],
'sort_algorithm' => 'alpha'
],
'phpdoc_trim' => true,
'phpdoc_trim_consecutive_blank_line_separation' => true,
'single_import_per_statement' => true,
'strict_param' => true,
])
->setFinder($finder)
->setIndent("\t")
->setLineEnding("\n");

View File

@ -1,32 +0,0 @@
language: php
php:
- 7.3
before_script:
- phpenv config-rm xdebug.ini
- echo | pecl install channel://pecl.php.net/yaml-2.1.0
- git clone https://github.com/pmmp/pthreads.git
- cd pthreads
- git checkout 646dac62ae0d48c1ada7b007e15575fb84f7d71d
- phpize
- ./configure
- make
- make install
- cd ..
- echo "extension=pthreads.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
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
cache:
directories:
- $HOME/.composer/cache/files
- $HOME/.composer/cache/vcs
notifications:
email: false

View File

@ -8,7 +8,7 @@
## 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)
- [Prebuilt binaries](https://jenkins.pmmp.io/job/PHP-7.4-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`.
@ -30,9 +30,15 @@ If you use a custom binary, you'll need to replace `composer` usages in this gui
Preprocessor requires that the `cpp` (c preprocessor) is available in your PATH.
## Building `PocketMine-MP.phar`
Run `build/server-phar.php` using your preferred PHP binary. It'll drop a `PocketMine-MP.phar` into the current working directory.
Run `composer make-server` 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.
There is a bug in PHP that might cause an error which looks like this:
```
Fatal error: Uncaught BadMethodCallException: unable to create temporary file in PocketMine-MP/build/server-phar.php:119
```
You can work around it by setting `ulimit -n` to some bigger number, e.g. `8192`, or by updating your PHP version to at least 7.4.16 or 8.0.3.
## Running PocketMine-MP from source code
Run `src/pocketmine/PocketMine.php` using your preferred PHP binary.

View File

@ -116,7 +116,7 @@ class ExampleClass{
<!-- TODO: RFC and voting on the forums instead -->
### RFC and Voting
* These are big Pull Requests or contributions that change important behavior.
* RFCs will be tagged with the *PR: RFC* label
* RFCs will be tagged with the *Type: Request For Comments* label
* A vote will be held once the RFC is ready. All users can vote commenting on the Pull Request
* Comments MUST use "Yes" or "No" on the FIRST sentence to signify the vote, except when they don't want it to be counted.
* If your comment is a voting comment, specify the reason of your vote or it won't be counted.

View File

@ -3,7 +3,12 @@
<b>A highly customisable, open source server software for Minecraft: Bedrock Edition written in PHP</b>
</p>
[![Build Status](https://travis-ci.org/pmmp/PocketMine-MP.svg?branch=master)](https://travis-ci.org/pmmp/PocketMine-MP)
<p align="center">
<img src="https://github.com/pmmp/PocketMine-MP/workflows/CI/badge.svg" alt="CI" />
<a href="https://github.com/pmmp/PocketMine-MP/releases"><img src="https://img.shields.io/github/v/tag/pmmp/PocketMine-MP?label=release&logo=github" alt="GitHub tag (latest semver)" /></a>
<a href="https://hub.docker.com/r/pmmp/pocketmine-mp"><img src="https://img.shields.io/docker/v/pmmp/pocketmine-mp?logo=docker&label=image" alt="Docker image version (latest semver)" /></a>
<a href="https://discord.gg/bmSAZBG"><img src="https://img.shields.io/discord/373199722573201408?label=discord&color=7289DA&logo=discord" alt="Discord" /></a>
</p>
## Getting started
- [Documentation](http://pmmp.readthedocs.org/)
@ -18,8 +23,9 @@
## For developers
* [Building and running from source](BUILDING.md)
* [Developer documentation](https://devdoc.pmmp.io) - General documentation for PocketMine-MP plugin developers
* [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/DevTools/) - Development tools plugin for creating plugins
* [ExamplePlugin](https://github.com/pmmp/ExamplePlugin/) - Example plugin demonstrating some basic API features
* [Contributing Guidelines](CONTRIBUTING.md)

33
SECURITY.md Normal file
View File

@ -0,0 +1,33 @@
# Security Policy
## Supported Versions
The following release lines are currently receiving active security updates and bug fixes:
| Version | Supported |
| -------- | ------------------ |
| 3.15.x | :white_check_mark: |
| < 3.15.0 | :x: |
## Reporting a Vulnerability
**DO NOT report vulnerabilities on the GitHub issue tracker.**
GitHub is public and anyone can see the issues you post on the issue tracker, including people who would exploit vulnerabilities for their own gain.
**WARNING: You may put live servers at risk by reporting a vulnerability on the GitHub issue tracker.**
**Contact us** by sending an email to [**team@pmmp.io**](mailto:team@pmmp.io?subject=Security%20Vulnerability%20in%20PocketMine-MP). Include the following information:
- Version of PocketMine-MP
- Detailed description of the vulnerability (e.g. how to exploit it, what the effects are)
Please note that we can't guarantee a reply to every email.
## FAQ
### Do you offer a bug bounty?
No.
### How soon can I expect a fix for a vulnerability I've reported?
This depends on the nature of the problem. We can't provide any general ETA (nor would it be wise to provide one).
In general, it depends on when developers have time to look into the problem, how complex the problem is to fix, and how many users it impacts.
When a fix for a severe vulnerability is pushed, a patch release for the target version will usually be released within 24 hours so that users can update.

View File

@ -37,7 +37,6 @@ use const STDIN;
require_once dirname(__DIR__) . '/vendor/autoload.php';
function replaceVersion(string $versionInfoPath, string $newVersion, bool $isDev) : void{
$versionInfo = file_get_contents($versionInfoPath);
$versionInfo = preg_replace(
@ -72,7 +71,7 @@ function main(array $argv) : void{
$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"');
@ -86,6 +85,4 @@ function main(array $argv) : void{
system('git push origin HEAD ' . $currentVer->getBaseVersion());
}
if(!defined('pocketmine\_PHPSTAN_ANALYSIS')){
main($argv);
}
main($argv);

View File

@ -26,7 +26,6 @@ namespace pocketmine\build\server_phar;
use pocketmine\utils\Git;
use function array_map;
use function count;
use function defined;
use function dirname;
use function file_exists;
use function getcwd;
@ -41,6 +40,7 @@ use function rtrim;
use function sprintf;
use function str_replace;
use function unlink;
use const PHP_EOL;
require dirname(__DIR__) . '/vendor/autoload.php';
@ -49,7 +49,7 @@ require dirname(__DIR__) . '/vendor/autoload.php';
*
* @return string[]
*/
function preg_quote_array(array $strings, string $delim = null) : array{
function preg_quote_array(array $strings, string $delim) : array{
return array_map(function(string $str) use ($delim) : string{ return preg_quote($str, $delim); }, $strings);
}
@ -129,6 +129,10 @@ function main() : void{
echo "Set phar.readonly to 0 with -dphar.readonly=0" . PHP_EOL;
exit(1);
}
if(file_exists(dirname(__DIR__) . '/vendor/phpunit')){
echo "Remove Composer dev dependencies before building (composer install --no-dev)" . PHP_EOL;
exit(1);
}
$opts = getopt("", ["out:", "git:"]);
if(isset($opts["git"])){
@ -169,6 +173,4 @@ STUB
}
}
if(!defined('pocketmine\_PHPSTAN_ANALYSIS')){
main();
}
main();

View File

@ -50,4 +50,9 @@ Plugin developers should **only** update their required API to this version if y
- Fixed absorption hearts not being consumed.
# 3.12.5
- Fixed broken attack cooldowns.
- Fixed broken attack cooldowns.
# 3.12.6
- Fixed entities not getting movement updates after teleports.
- Fixed slow flight in spectator mode when starting from the ground and after teleportation.
- Errors communicating with the crash archive on automatic crash submission are now logged.

View File

@ -109,3 +109,23 @@ AsyncTask thread-local storage has been improved, making it simpler and easier t
- `Utils::recursiveUnlink()`
- `Terminal::write()`
- `Terminal::writeLine()`
# 3.13.1
- Fixed issues with `server.lock` not being unlocked on some platforms. Now, the server explicitly releases it before exiting.
- `/timings` now sends a usage message when using an unknown subcommand. Previously, it would just give no output.
- `/whitelist` now sends a usage message when using an unknown subcommand. Previously, it would just give no output.
- The output from `/timings` is now broadcasted on the `pocketmine.broadcast.admin` broadcast channel for auditability, similarly to other operator commands.
- Fixed `ShapedRecipe` deprecation warning on PHP 7.4.
- Fixed some potential crashes with Bedrock worlds when chunk data is corrupted or missing.
- Fixed a bug in region handling that caused region loaders to overestimate the amount of space used in the file. This resulted in an up to 4 MB growth of the file size every time the region was reloaded after writing a chunk.
- Region handlers now try to reuse free space in region files before putting the chunk at the end of the file. Previously, space was only reused if the new version of the chunk was <= the size of the old. This fixes endless growth of region files.
- Regions now never directly overwrite old copies of chunks when saving; instead they try to find an alternative location (preferring unused space within the file first). This avoids chunk corruption on power failure (the old copy of the chunk won't be damaged, so a rollback might occur instead), and as happy side effect, causes oversized regions to gradually shrink towards their most packed state over time, saving disk space.
- Regions now have a hard size cap at 64 GB. This is because the header pointers will overflow beyond 64 GB (besides, a normal region shouldn't be this big anyway).
- Fixed a crash that could occur when reading a too-short region header.
- `VerifyLoginTask` now only copies JWTs to verify instead of the entire login packet. This reduces the amount of data copied between threads, improving performance.
- Added a fast-fail check to `VerifyLoginTask` by checking the JWT header's `x5u` against the expected public key.
- `Skin->validate()` now throws `InvalidSkinException` instead of `\InvalidArgumentException`.
- A debug message is now logged when a player is kicked for having an invalid skin, giving a brief line of detail why.
- Fixed players not being kicked for having an invalid `resourcePatch`.
- Fixed block meta value of cake being preserved when using pick-block.
- Fixed explosions not fully destroying multi-block objects like beds and doors.

40
changelogs/3.14.md Normal file
View File

@ -0,0 +1,40 @@
**For Minecraft: Bedrock Edition 1.16.0**
### 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.14.0
- Added support for Minecraft: Bedrock Edition 1.16.0.
- Removed compatibility with 1.14.60.
## Known issues (please don't open issues for these)
- Walls don't connect to each other
- Pumpkin and melon stems may not connect to their corresponding pumpkin/melon
- New blocks, items & mobs aren't implemented
- Nether doesn't exist
# 3.14.1
- All skins are now trusted, bypassing the client-side trusted skin setting. Note that this means that NSFW skin filtering will **not** apply.
- Fixed projectile motion being altered by ladders.
- Fixed client-sided crashes when pressing E repeatedly very quickly on a high-latency connection.
- `/plugins`, `/whitelist list`, `/banlist` and `/list` now show output in alphabetical order.
- Some `pocketmine\event` APIs which accept arrays now have more robust type checking, fixing type errors caused by plugin input occurring in core code.
- `Attribute::getAttributeByName()` is now aware of the `minecraft:lava_movement` attribute.
# 3.14.2
- Exception stack traces are now logged as CRITICAL. It's hoped that users will recognize that they are just as important as the error message and not leave them out when asking for help with errors on Discord.
- `TaskScheduler` no longer accepts tasks that already have a handler. This fixes undefined behaviour which occurs when scheduling the same task instance twice, but it does break plugins such as **MyPlot** which unintentionally used this buggy behaviour.
- Players will now correctly receive the needed number of spawn chunks if they are teleported between `PlayerLoginEvent` and `PlayerJoinEvent`. This fixes a bug that could occur when teleporting players in delayed tasks between login and join.
- `PlayerRespawnEvent->setRespawnPosition()` now throws an exception if the provided `Position` has an invalid world associated with it (null or unloaded).
- Fixed a crash that occurred when stats reporting was enabled.
# 3.14.3
- Fixed deprecation error when running `/whitelist list` on PHP 7.4.
- Fixed podzol breaking animation being incorrect (incorrect hardness).
- `Entity::getSaveId()` now reports the class name in the message thrown for unregistered entities.
- Fixed `CraftingManager->validate()` producing different results when called multiple times for the same transaction.
- Fixed various issues with batch-crafting items using the recipe book and shift-clicking.
- `tests/plugins/PocketMine-DevTools` submodule has been renamed to `tests/plugins/DevTools`.

54
changelogs/3.15.md Normal file
View File

@ -0,0 +1,54 @@
**For Minecraft: Bedrock Edition 1.16.20**
### 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.15.0
- Added support for Minecraft: Bedrock Edition 1.16.20.
- Removed compatibility with 1.16.0.
## Known issues (please don't open issues for these)
- Walls don't connect to each other
- Pumpkin and melon stems may not connect to their corresponding pumpkin/melon
- New blocks, items & mobs aren't implemented
- Nether doesn't exist
# 3.15.1
- Fixed various PHP 7.4 compatibility issues in Composer dependencies (primarily callback-validator).
- Fixed LevelDB worlds with corrupted `level.dat` crashing the server instead of failing gracefully.
- Fixed error spam when using strings for layers in flatworld presets (`e.g. bedrock,3xdirt,grass`).
- Fixed blocks not getting updated properly on explosions.
- Fixed `BlockGrowEvent` not being called when sugarcane grows.
- Potato crops now drop poisonous potatoes when harvested.
- Fixed the wrong number of potatoes being dropped when harvesting potato crops.
- Players no longer get pullbacks when sprinting on slabs, stairs and various other blocks when `player.anti-cheat.allow-movement-cheats` is set to `false`. (This bug has been around for over 5 years, so many of you will be used to its existence.)
- Fixed entity collision box calculation not taking clip distance into account.
- Entities now step up the correct height of the target block, instead of jumping into the air 0.6 blocks and falling back down.
# 3.15.2
- Fixed issues with preloading `SubChunk`.
- `/gc` and automatic garbage collection will now release unused heap blocks back to the OS. Previously, the PHP process might hold onto these blocks indefinitely even when not used, causing elevated real memory usage.
- Added some documentation to `FurnaceBurnEvent`.
# 3.15.3
- Fixed fall damage accumulation over continuous knockbacks (e.g. combo attacks in PvP).
- Fixed a bug in `Human->addXp()` that would cause a crash when saving player data.
- `Human->addXp()` will no longer modify the target's total XP if `PlayerExperienceChangeEvent` was cancelled.
- `AsyncPool->getTaskQueueSizes()` has been added to allow external detection of async pool overload. This is planned to be implemented as a core feature in the future, but it hasn't been done yet.
- `BaseInventory->canAddItem()` behaviour now matches `addItem()` by considering the max stack size of the given item.
- Fixed a bug in generator options handling for worlds loaded via `pocketmine.yml`. This fix has the following side effects:
- It's now possible to provide generator options as an `options` key when loading a world via `pocketmine.yml`.
- If generator options are not provided, the options from `server.properties` will be used, instead of using an empty preset. (It's not clear whether this is desired behaviour, but it was clearly intended, since there is code to do this which was broken until this release. As such, this behaviour is subject to change in the future.)
- Fixed a bug in region-based world loading where some files without filename extensions and names containing a region filename extension (e.g a file named `amca` in a McRegion world) would cause the world not to load. These files are now ignored.
- Default network compression level has been lowered to 6, due to level 7 being 25% more expensive for only a marginal improvement in bandwidth.
- Fixed a performance issue with chunk requesting when players trigger chunk generation on first join.
- Setup wizard will now always show IP information, even if the user chose to skip the setup wizard when prompted. (This doesn't affect `--no-wizard` in any way.)
- `Maximum memory (system)` is no longer reported in `/status` due to having a misleading output (it was the same as the current memory usage).
- The `Player Chunk Send` timer on timings reports now actually reports measurements of chunk sending, not chunk loading.
- A new parent timer `World Load` has been added to timings reports, which aggregates timings from `syncChunkLoad` and subtimings from all worlds.
# 3.15.4
- Fixed a bug in the inventory transaction system that caused the server to freeze under some circumstances.

24
changelogs/3.16.md Normal file
View File

@ -0,0 +1,24 @@
**For Minecraft: Bedrock Edition 1.16.100**
### 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.16.0
- Added support for Minecraft: Bedrock Edition 1.16.100.
- Removed compatibility with earlier versions.
- Added new custom composer commands `make-server` and `make-devtools` to ease setting up a development environment and building the server.
## Known issues (please don't open issues for these)
- Walls don't connect to each other
- Pumpkin and melon stems may not connect to their corresponding pumpkin/melon
- New blocks, items & mobs aren't implemented
- Nether doesn't exist
# 3.16.1
- Fixed incorrect encoding of skins in the protocol.
- `/version` no longer crashes when a plugin provides `string[]` for the `author` field in `plugin.yml`.
- `author` in `plugin.yml` now accepts arrays, just like `authors`.
- Fixed `HellBiome` never being registered.

63
changelogs/3.17.md Normal file
View File

@ -0,0 +1,63 @@
**For Minecraft: Bedrock Edition 1.16.200**
### 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.17.0
- Added support for Minecraft: Bedrock Edition 1.16.200.
- Removed compatibility with earlier versions.
## Known issues (please don't open issues for these)
- Walls don't connect to each other
- Pumpkin and melon stems may not connect to their corresponding pumpkin/melon
- New blocks, items & mobs aren't implemented
- Nether doesn't exist
# 3.17.1
- Fixed some instances of plugin-caused crashes not being detected (eval()'d code, custom plugin paths).
- Server uptime is now included in crash reports.
- Hoes now take damage when used to break sponges.
- Using lava as fuel in a furnace now leaves behind an empty bucket.
# 3.17.2
- Fixed region header corruption when chunks with larger-than-expected lengths are found. These chunks are now treated as corrupted, instead of automatically attempting to salvage them (which usually fails anyway).
- `RegionLoader->removeChunk()` now allows the space used by the removed chunk to be reused by future region saves.
- Extracted `Living->applyConsumptionResults()` from `Living->consumeObject()` (preparation for a future bug fix).
# 3.17.3
- Improved performance of chunk loading in Region-based worlds.
- Improved performance of region header validation in Region-based worlds (indirect improvement to chunk loading performance).
- Fixed some PHP 8.0 language-level compatibility issues.
- Source installations will now exit with an error when Composer dependencies are not in sync with the current Git revision. Now, it's required to run `composer install` after every git pull to make sure the correct dependency versions are installed.
# 3.17.4
- Removed `readline` support. This hasn't been maintained for many years, never worked correctly, and isn't thread-safe in any case.
- Fixed false-positives of region corruption in Region-based worlds (outdated file stat cache).
- Fixed more deprecation warnings on PHP 8.0 (optional parameter before required).
- `CraftItemEvent->getInputs()` now returns a list starting at offset 0, instead of random offsets. (Note that the contents still won't be ordered.)
- `CraftItemEvent->getOutputs()` now returns a list starting at offset 0, instead of random offsets. (Note that the contents still won't be ordered.)
- Fixed a bug that broke synchronized building, bridging, towering and more.
- Objects in memory dumps no longer show inherited properties multiple times.
# 3.17.5
- Reduced CPU wastage by the logger thread.
- Fixed LevelDB deprecation errors on PHP 8.0.
- Added some protocol changes for 1.16.200 which were previously overlooked.
- Player XUIDs are now tracked. If a player's XUID does not match the previously recorded XUID when they next join the server, they will be kicked. This can be disabled by the `player.verify-xuid` setting in `pocketmine.yml`.
- `BUILDING.md` now has a note about `build/server-phar.php`'s compression bug (a bug in PHP).
# 3.17.6
- Fixed core race conditions that could have led to server freezes (race conditions in pmmp/Snooze).
- The log message about Xbox Live authentication being enabled has been reduced to INFO, and the tip on how to turn it off removed (disabling it should usually only be done by power users anyway).
- Fixed `PlayerMoveEvent->getFrom()` returning incorrect results for players who experienced movement reversions.
- Fixed a bug in `ResourcePackClientResponsePacket` decoding that caused unexpected results when decoding the packet twice.
- XUID verification now compares XUIDs against players who are already on the server to detect mismatches to avoid unnecessary loading of playerdata.
- Fixed an inventory duplication bug which could occur when the same player joined with two devices at the same time.
- Fixed cursor item not being synced on inventory transaction rollbacks.
- Fixed items with TAG_Float in their NBT not being able to be moved around in the inventory.
# 3.17.7
- Fixed crash caused by preprocessor in 3.17.6.

31
changelogs/3.18.md Normal file
View File

@ -0,0 +1,31 @@
**For Minecraft: Bedrock Edition 1.16.210**
### 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.18.0
- Added support for Minecraft: Bedrock Edition 1.16.210.
- Removed compatibility with earlier versions.
## Known issues (please don't open issues for these)
- Walls don't connect to each other
- Pumpkin and melon stems may not connect to their corresponding pumpkin/melon
- New blocks, items & mobs aren't implemented
- Nether doesn't exist
- Items can't be removed from item frames in Survival mode
# 3.18.1
- UPnP is now supported on all platforms instead of just Windows. Note that it's still experimental. Please file issues for any bugs that you find.
- Fixed server joining when default game mode is set to Spectator mode.
- Fixed items not being able to be removed from item frames in Survival mode.
- Fixed field order in ClientCacheBlobStatusPacket (hits and misses were inverted).
- Fixed a deadlock that could occur when MainLogger->syncFlushBuffer() was used (usually only used during exception logging).
- Updated constants for various things in the protocol.
# 3.18.2
- Fixed `InventoryCloseEvent` not being called on server-initiated inventory closures.
- `PlayerToggleFlightEvent` may now be pre-cancelled if the player attempted to enable flight when flying was not allowed. This replaces the previous behaviour of kicking the player.
- Fixed being unable to change the item in hand from the inventory window when looking at an entity.

17
changelogs/3.19.md Normal file
View File

@ -0,0 +1,17 @@
**For Minecraft: Bedrock Edition 1.16.220**
### 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.19.0
- Added support for Minecraft: Bedrock Edition 1.16.220.
- Removed compatibility with earlier versions.
## Known issues (please don't open issues for these)
- Walls don't connect to each other
- Pumpkin and melon stems may not connect to their corresponding pumpkin/melon
- New blocks, items & mobs aren't implemented
- Nether doesn't exist

View File

@ -5,11 +5,10 @@
"homepage": "https://pmmp.io",
"license": "LGPL-3.0",
"require": {
"php": ">=7.3.0",
"php": "^7.3 || ^8.0",
"php-64bit": "*",
"ext-bcmath": "*",
"ext-curl": "*",
"ext-ctype": "*",
"ext-curl": "*",
"ext-date": "*",
"ext-hash": "*",
"ext-json": "*",
@ -19,29 +18,30 @@
"ext-phar": "*",
"ext-pthreads": "~3.2.0",
"ext-reflection": "*",
"ext-simplexml": "*",
"ext-sockets": "*",
"ext-spl": "*",
"ext-yaml": ">=2.0.0",
"ext-zip": "*",
"ext-zlib": ">=1.2.11",
"pocketmine/raklib": "^0.12.7",
"pocketmine/spl": "^0.4.0",
"composer-runtime-api": "^2.0",
"adhocore/json-comment": "^1.1",
"pocketmine/binaryutils": "^0.1.9",
"pocketmine/nbt": "^0.2.10",
"pocketmine/math": "^0.2.0",
"pocketmine/snooze": "^0.1.0",
"pocketmine/callback-validator": "^1.0.2",
"pocketmine/classloader": "^0.1.0",
"pocketmine/log": "^0.2.0",
"pocketmine/log-pthreads": "^0.1.0",
"pocketmine/callback-validator": "^1.0.1",
"adhocore/json-comment": "^0.1.0",
"ocramius/package-versions": "^1.5"
"pocketmine/math": "^0.2.0",
"pocketmine/nbt": "^0.2.18",
"pocketmine/raklib": "^0.12.7",
"pocketmine/snooze": "^0.1.0",
"pocketmine/spl": "^0.4.0"
},
"require-dev": {
"phpstan/phpstan": "^0.12.25",
"phpstan/phpstan": "0.12.83",
"phpstan/phpstan-phpunit": "^0.12.6",
"phpstan/phpstan-strict-rules": "^0.12.2",
"phpunit/phpunit": "^8.5"
"phpunit/phpunit": "^9.2"
},
"autoload": {
"psr-4": {
@ -57,5 +57,18 @@
"psr-4": {
"pocketmine\\": "tests/phpunit/"
}
},
"config": {
"platform": {
"php": "7.3.0"
},
"sort-packages": true
},
"scripts": {
"make-devtools": "@php -dphar.readonly=0 tests/plugins/DevTools/src/DevTools/ConsoleScript.php --make tests/plugins/DevTools --out plugins/DevTools.phar",
"make-server": [
"@composer install --no-dev --classmap-authoritative",
"@php -dphar.readonly=0 build/server-phar.php"
]
}
}

1767
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +5,6 @@ This site contains auto-generated API documentation for PocketMine-MP (and depen
This site can be accessed via https://apidoc.pmmp.io.
### Additional developer resources
- [DevTools](https://github.com/pmmp/PocketMine-DevTools/) - Development tools plugin for creating plugins
- [DevTools](https://github.com/pmmp/DevTools/) - Development tools plugin for creating plugins
- [ExamplePlugin](https://github.com/pmmp/ExamplePlugin/) - Example plugin demonstrating some basic API features
- [DeveloperDocs](https://github.com/pmmp/DeveloperDocs/) - Reference, guides and specifications for the PocketMine-MP API
- [DeveloperDocs](https://devdoc.pmmp.io) - General documentation for PocketMine-MP plugin developers

View File

@ -1,7 +1,6 @@
includes:
- tests/phpstan/configs/actual-problems.neon
- tests/phpstan/configs/com-dotnet-magic.neon
- tests/phpstan/configs/custom-leveldb.neon
- tests/phpstan/configs/check-explicit-mixed-baseline.neon
- tests/phpstan/configs/gc-hacks.neon
- tests/phpstan/configs/l7-baseline.neon
- tests/phpstan/configs/l8-baseline.neon
@ -16,8 +15,13 @@ includes:
parameters:
level: 8
autoload_files:
checkExplicitMixed: true
checkMissingCallableSignature: true
bootstrapFiles:
- tests/phpstan/bootstrap.php
scanDirectories:
- tests/plugins/TesterPlugin
scanFiles:
- src/pocketmine/PocketMine.php
- build/make-release.php
- build/server-phar.php
@ -26,12 +30,20 @@ parameters:
- build/make-release.php
- build/server-phar.php
- tests/phpunit
- tests/plugins/TesterPlugin
dynamicConstantNames:
- pocketmine\IS_DEVELOPMENT_BUILD
- pocketmine\DEBUG
stubFiles:
- tests/phpstan/stubs/pthreads.stub
- tests/phpstan/stubs/chunkutils.stub
- tests/phpstan/stubs/leveldb.stub
reportUnmatchedIgnoredErrors: false #no other way to silence platform-specific non-warnings
staticReflectionClassNamePatterns:
- "#^COM$#"
typeAliases:
#variadics don't work for this - mixed probably shouldn't work either, but for now it does
#what we actually need is something that accepts an infinite number of parameters, but in the absence of that,
#we'll just fill it with 10 - it's very unlikely to encounter a callable with 10 parameters anyway.
anyCallable: 'callable(mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed) : mixed'
anyClosure: '\Closure(mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed) : mixed'

View File

@ -23,11 +23,12 @@ declare(strict_types=1);
namespace pocketmine;
use PackageVersions\Versions;
use Composer\InstalledVersions;
use pocketmine\network\mcpe\protocol\ProtocolInfo;
use pocketmine\plugin\PluginBase;
use pocketmine\plugin\PluginLoadOrder;
use pocketmine\plugin\PluginManager;
use pocketmine\utils\AssumptionFailedError;
use pocketmine\utils\Utils;
use pocketmine\utils\VersionString;
use function base64_encode;
@ -46,6 +47,7 @@ use function is_resource;
use function json_encode;
use function json_last_error_msg;
use function max;
use function microtime;
use function mkdir;
use function ob_end_clean;
use function ob_get_contents;
@ -54,10 +56,10 @@ use function php_uname;
use function phpinfo;
use function phpversion;
use function preg_replace;
use function sprintf;
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;
@ -88,7 +90,7 @@ 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 = 3;
private const FORMAT_VERSION = 4;
private const PLUGIN_INVOLVEMENT_NONE = "none";
private const PLUGIN_INVOLVEMENT_DIRECT = "direct";
@ -98,7 +100,7 @@ class CrashDump{
private $server;
/** @var resource */
private $fp;
/** @var int */
/** @var float */
private $time;
/**
* @var mixed[]
@ -111,12 +113,12 @@ class CrashDump{
private $path;
public function __construct(Server $server){
$this->time = time();
$this->time = microtime(true);
$this->server = $server;
if(!is_dir($this->server->getDataPath() . "crashdumps")){
mkdir($this->server->getDataPath() . "crashdumps");
}
$this->path = $this->server->getDataPath() . "crashdumps/" . date("D_M_j-H.i.s-T_Y", $this->time) . ".log";
$this->path = $this->server->getDataPath() . "crashdumps/" . date("D_M_j-H.i.s-T_Y", (int) $this->time) . ".log";
$fp = @fopen($this->path, "wb");
if(!is_resource($fp)){
throw new \RuntimeException("Could not create Crash Dump");
@ -124,7 +126,8 @@ class CrashDump{
$this->fp = $fp;
$this->data["format_version"] = self::FORMAT_VERSION;
$this->data["time"] = $this->time;
$this->addLine($this->server->getName() . " Crash Dump " . date("D M j H:i:s T Y", $this->time));
$this->data["uptime"] = $this->time - \pocketmine\START_TIME;
$this->addLine($this->server->getName() . " Crash Dump " . date("D M j H:i:s T Y", (int) $this->time));
$this->addLine();
$this->baseCrash();
$this->generalData();
@ -165,7 +168,9 @@ class CrashDump{
if($json === false){
throw new \RuntimeException("Failed to encode crashdump JSON: " . json_last_error_msg());
}
$this->encodedData = zlib_encode($json, ZLIB_ENCODING_DEFLATE, 9);
$zlibEncoded = zlib_encode($json, ZLIB_ENCODING_DEFLATE, 9);
if($zlibEncoded === false) throw new AssumptionFailedError("ZLIB compression failed");
$this->encodedData = $zlibEncoded;
foreach(str_split(base64_encode($this->encodedData), 76) as $line){
$this->addLine($line);
}
@ -201,9 +206,16 @@ class CrashDump{
if($this->server->getProperty("auto-report.send-settings", true) !== false){
$this->data["parameters"] = (array) $argv;
$this->data["server.properties"] = @file_get_contents($this->server->getDataPath() . "server.properties");
$this->data["server.properties"] = preg_replace("#^rcon\\.password=(.*)$#m", "rcon.password=******", $this->data["server.properties"]);
$this->data["pocketmine.yml"] = @file_get_contents($this->server->getDataPath() . "pocketmine.yml");
if(($serverDotProperties = @file_get_contents($this->server->getDataPath() . "server.properties")) !== false){
$this->data["server.properties"] = preg_replace("#^rcon\\.password=(.*)$#m", "rcon.password=******", $serverDotProperties);
}else{
$this->data["server.properties"] = $serverDotProperties;
}
if(($pocketmineDotYml = @file_get_contents($this->server->getDataPath() . "pocketmine.yml")) !== false){
$this->data["pocketmine.yml"] = $pocketmineDotYml;
}else{
$this->data["pocketmine.yml"] = "";
}
}else{
$this->data["pocketmine.yml"] = "";
$this->data["server.properties"] = "";
@ -309,8 +321,8 @@ class CrashDump{
}
private function determinePluginFromFile(string $filePath, bool $crashFrame) : bool{
$frameCleanPath = Utils::cleanPath($filePath); //this will be empty in phar stub
if(strpos($frameCleanPath, "plugins") === 0 and file_exists($filePath)){
$frameCleanPath = Utils::cleanPath($filePath);
if(strpos($frameCleanPath, Utils::CLEAN_PATH_SRC_PREFIX) !== 0){
$this->addLine();
if($crashFrame){
$this->addLine("THIS CRASH WAS CAUSED BY A PLUGIN");
@ -320,15 +332,17 @@ class CrashDump{
$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;
if(file_exists($filePath)){
$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;
@ -338,6 +352,15 @@ class CrashDump{
private function generalData() : void{
$version = new VersionString(\pocketmine\BASE_VERSION, \pocketmine\IS_DEVELOPMENT_BUILD, \pocketmine\BUILD_NUMBER);
$composerLibraries = [];
foreach(InstalledVersions::getInstalledPackages() as $package){
$composerLibraries[$package] = sprintf(
"%s@%s",
InstalledVersions::getPrettyVersion($package) ?? "unknown",
InstalledVersions::getReference($package) ?? "unknown"
);
}
$this->data["general"] = [];
$this->data["general"]["name"] = $this->server->getName();
$this->data["general"]["base_version"] = \pocketmine\BASE_VERSION;
@ -350,7 +373,7 @@ class CrashDump{
$this->data["general"]["zend"] = zend_version();
$this->data["general"]["php_os"] = PHP_OS;
$this->data["general"]["os"] = Utils::getOS();
$this->data["general"]["composer_libraries"] = Versions::VERSIONS;
$this->data["general"]["composer_libraries"] = $composerLibraries;
$this->addLine($this->server->getName() . " version: " . $version->getFullVersion(true) . " [Protocol " . ProtocolInfo::CURRENT_PROTOCOL . "]");
$this->addLine("Git commit: " . \pocketmine\GIT_COMMIT);
$this->addLine("uname -a: " . php_uname("a"));
@ -358,7 +381,7 @@ class CrashDump{
$this->addLine("Zend version: " . zend_version());
$this->addLine("OS : " . PHP_OS . ", " . Utils::getOS());
$this->addLine("Composer libraries: ");
foreach(Versions::VERSIONS as $library => $libraryVersion){
foreach($composerLibraries as $library => $libraryVersion){
$this->addLine("- $library $libraryVersion");
}
}

View File

@ -40,6 +40,7 @@ use function fwrite;
use function gc_collect_cycles;
use function gc_disable;
use function gc_enable;
use function gc_mem_caches;
use function get_class;
use function get_declared_classes;
use function implode;
@ -50,6 +51,7 @@ use function is_object;
use function is_resource;
use function is_string;
use function json_encode;
use function mb_strtoupper;
use function min;
use function mkdir;
use function preg_match;
@ -58,7 +60,6 @@ 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;
@ -127,7 +128,7 @@ class MemoryManager{
if($m <= 0){
$defaultMemory = 0;
}else{
switch(strtoupper($matches[2])){
switch(mb_strtoupper($matches[2])){
case "K":
$defaultMemory = $m / 1024;
break;
@ -273,6 +274,7 @@ class MemoryManager{
}
$cycles = gc_collect_cycles();
gc_mem_caches();
Timings::$garbageCollectorTimer->stopTiming();
@ -421,8 +423,12 @@ class MemoryManager{
}
$name = $property->getName();
if($reflection !== $original and !$property->isPublic()){
$name = $reflection->getName() . ":" . $name;
if($reflection !== $original){
if($property->isPrivate()){
$name = $reflection->getName() . ":" . $name;
}else{
continue;
}
}
if(!$property->isPublic()){
$property->setAccessible(true);

File diff suppressed because it is too large Load Diff

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace pocketmine {
use Composer\InstalledVersions;
use pocketmine\utils\Git;
use pocketmine\utils\MainLogger;
use pocketmine\utils\Process;
@ -73,7 +74,6 @@ namespace pocketmine {
}
$extensions = [
"bcmath" => "BC Math",
"curl" => "cURL",
"ctype" => "ctype",
"date" => "Date",
@ -206,6 +206,19 @@ namespace pocketmine {
define('pocketmine\GIT_COMMIT', $gitHash);
$composerGitHash = InstalledVersions::getReference('pocketmine/pocketmine-mp');
if($composerGitHash !== null){
$currentGitHash = explode("-", \pocketmine\GIT_COMMIT)[0];
if($currentGitHash !== $composerGitHash){
critical_error("Composer dependencies and/or autoloader are out of sync.");
critical_error("- Current revision is $currentGitHash");
critical_error("- Composer dependencies were last synchronized for revision $composerGitHash");
critical_error("Out-of-sync Composer dependencies may result in crashes and classes not being found.");
critical_error("Please synchronize Composer dependencies before running the server.");
exit(1);
}
}
$opts = getopt("", ["data:", "plugins:", "no-wizard", "enable-ansi", "disable-ansi"]);
define('pocketmine\DATA', isset($opts["data"]) ? $opts["data"] . DIRECTORY_SEPARATOR : realpath(getcwd()) . DIRECTORY_SEPARATOR);
@ -215,7 +228,12 @@ namespace pocketmine {
mkdir(\pocketmine\DATA, 0777, true);
}
define('pocketmine\LOCK_FILE', fopen(\pocketmine\DATA . 'server.lock', "a+b"));
$lockFile = fopen(\pocketmine\DATA . 'server.lock', "a+b");
if($lockFile === false){
critical_error("Unable to open server.lock file. Please check that the current user has read/write permissions to it.");
exit(1);
}
define('pocketmine\LOCK_FILE', $lockFile);
if(!flock(\pocketmine\LOCK_FILE, LOCK_EX | LOCK_NB)){
//wait for a shared lock to avoid race conditions if two servers started at the same time - this makes sure the
//other server wrote its PID and released exclusive lock before we get our lock
@ -280,7 +298,7 @@ namespace pocketmine {
if(ThreadManager::getInstance()->stopAll() > 0){
$logger->debug("Some threads could not be stopped, performing a force-kill");
Process::kill(getmypid());
Process::kill(Process::pid());
}
}while(false);
@ -289,10 +307,16 @@ namespace pocketmine {
echo Terminal::$FORMAT_RESET . PHP_EOL;
if(!flock(\pocketmine\LOCK_FILE, LOCK_UN)){
critical_error("Failed to release the server.lock file.");
}
if(!fclose(\pocketmine\LOCK_FILE)){
critical_error("Could not close server.lock resource.");
}
exit($exitCode);
}
if(!defined('pocketmine\_PHPSTAN_ANALYSIS')){
\pocketmine\server();
}
\pocketmine\server();
}

View File

@ -126,7 +126,6 @@ use function file_put_contents;
use function filemtime;
use function function_exists;
use function get_class;
use function getmypid;
use function getopt;
use function gettype;
use function implode;
@ -693,29 +692,32 @@ class Server{
return $result;
}
private function getPlayerDataPath(string $username) : string{
return $this->getDataPath() . '/players/' . strtolower($username) . '.dat';
}
/**
* Returns whether the server has stored any saved data for this player.
*/
public function hasOfflinePlayerData(string $name) : bool{
$name = strtolower($name);
return file_exists($this->getDataPath() . "players/$name.dat");
return file_exists($this->getPlayerDataPath($name));
}
public function getOfflinePlayerData(string $name) : CompoundTag{
$name = strtolower($name);
$path = $this->getDataPath() . "players/";
$path = $this->getPlayerDataPath($name);
if($this->shouldSavePlayerData()){
if(file_exists($path . "$name.dat")){
if(file_exists($path)){
try{
$nbt = new BigEndianNBTStream();
$compound = $nbt->readCompressed(file_get_contents($path . "$name.dat"));
$compound = $nbt->readCompressed(file_get_contents($path));
if(!($compound instanceof CompoundTag)){
throw new \RuntimeException("Invalid data found in \"$name.dat\", expected " . CompoundTag::class . ", got " . (is_object($compound) ? get_class($compound) : gettype($compound)));
}
return $compound;
}catch(\Throwable $e){ //zlib decode error / corrupt data
rename($path . "$name.dat", $path . "$name.dat.bak");
rename($path, $path . '.bak');
$this->logger->notice($this->getLanguage()->translateString("pocketmine.data.playerCorrupted", [$name]));
}
}else{
@ -776,7 +778,7 @@ class Server{
if(!$ev->isCancelled()){
$nbt = new BigEndianNBTStream();
try{
file_put_contents($this->getDataPath() . "players/" . strtolower($name) . ".dat", $nbt->writeCompressed($ev->getSaveData()));
file_put_contents($this->getPlayerDataPath($name), $nbt->writeCompressed($ev->getSaveData()));
}catch(\Throwable $e){
$this->logger->critical($this->getLanguage()->translateString("pocketmine.data.saveError", [$name, $e->getMessage()]));
$this->logger->logException($e);
@ -1397,10 +1399,10 @@ class Server{
Network::$BATCH_THRESHOLD = -1;
}
$this->networkCompressionLevel = (int) $this->getProperty("network.compression-level", 7);
$this->networkCompressionLevel = (int) $this->getProperty("network.compression-level", 6);
if($this->networkCompressionLevel < 1 or $this->networkCompressionLevel > 9){
$this->logger->warning("Invalid network compression level $this->networkCompressionLevel set, setting to default 7");
$this->networkCompressionLevel = 7;
$this->logger->warning("Invalid network compression level $this->networkCompressionLevel set, setting to default 6");
$this->networkCompressionLevel = 6;
}
$this->networkCompressionAsync = (bool) $this->getProperty("network.async-compression", true);
@ -1459,8 +1461,7 @@ class Server{
$this->onlineMode = $this->getConfigBool("xbox-auth", true);
if($this->onlineMode){
$this->logger->notice($this->getLanguage()->translateString("pocketmine.server.auth.enabled"));
$this->logger->notice($this->getLanguage()->translateString("pocketmine.server.authProperty.enabled"));
$this->logger->info($this->getLanguage()->translateString("pocketmine.server.auth.enabled"));
}else{
$this->logger->warning($this->getLanguage()->translateString("pocketmine.server.auth.disabled"));
$this->logger->warning($this->getLanguage()->translateString("pocketmine.server.authWarning"));
@ -1540,7 +1541,7 @@ class Server{
if(isset($options["generator"])){
$generatorOptions = explode(":", $options["generator"]);
$generator = GeneratorManager::getGenerator(array_shift($generatorOptions));
if(count($options) > 0){
if(count($generatorOptions) > 0){
$options["preset"] = implode(":", $generatorOptions);
}
}else{
@ -1936,7 +1937,7 @@ class Server{
}catch(\Throwable $e){
$this->logger->logException($e);
$this->logger->emergency("Crashed while crashing, killing process");
@Process::kill(getmypid());
@Process::kill(Process::pid());
}
}
@ -2129,7 +2130,7 @@ class Server{
echo "--- Waiting $spacing seconds to throttle automatic restart (you can kill the process safely now) ---" . PHP_EOL;
sleep($spacing);
}
@Process::kill(getmypid());
@Process::kill(Process::pid());
exit(1);
}

View File

@ -76,11 +76,9 @@ abstract class Thread extends \Thread{
}
/**
* @param int|null $options TODO: pthreads bug
*
* @return bool
*/
public function start(?int $options = PTHREADS_INHERIT_ALL){
public function start(int $options = PTHREADS_INHERIT_ALL){
ThreadManager::getInstance()->add($this);
if($this->getClassLoader() === null){

View File

@ -33,6 +33,6 @@ if(defined('pocketmine\_VERSION_INFO_INCLUDED')){
const _VERSION_INFO_INCLUDED = true;
const NAME = "PocketMine-MP";
const BASE_VERSION = "3.13.0";
const BASE_VERSION = "3.19.0";
const IS_DEVELOPMENT_BUILD = false;
const BUILD_NUMBER = 0;

View File

@ -76,11 +76,9 @@ abstract class Worker extends \Worker{
}
/**
* @param int|null $options TODO: pthreads bug
*
* @return bool
*/
public function start(?int $options = PTHREADS_INHERIT_ALL){
public function start(int $options = PTHREADS_INHERIT_ALL){
ThreadManager::getInstance()->add($this);
if($this->getClassLoader() === null){

View File

@ -36,7 +36,7 @@ use pocketmine\math\RayTraceResult;
use pocketmine\math\Vector3;
use pocketmine\metadata\Metadatable;
use pocketmine\metadata\MetadataValue;
use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping;
use pocketmine\network\mcpe\convert\RuntimeBlockMapping;
use pocketmine\Player;
use pocketmine\plugin\Plugin;
use function array_merge;

View File

@ -25,7 +25,7 @@ namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\level\Position;
use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping;
use pocketmine\network\mcpe\convert\RuntimeBlockMapping;
use function min;
/**

View File

@ -35,5 +35,6 @@ interface BlockToolType{
public const TYPE_PICKAXE = 1 << 2;
public const TYPE_AXE = 1 << 3;
public const TYPE_SHEARS = 1 << 4;
public const TYPE_HOE = 1 << 5;
}

View File

@ -109,6 +109,10 @@ class Cake extends Transparent implements FoodSource{
return true;
}
public function getVariantBitmask() : int{
return 0;
}
/**
* @return Block
*/

View File

@ -25,7 +25,10 @@ namespace pocketmine\block;
use pocketmine\inventory\CraftingGrid;
use pocketmine\item\Item;
use pocketmine\network\mcpe\protocol\ContainerOpenPacket;
use pocketmine\network\mcpe\protocol\types\WindowTypes;
use pocketmine\Player;
use function array_key_exists;
class CraftingTable extends Solid{
@ -50,6 +53,19 @@ class CraftingTable extends Solid{
public function onActivate(Item $item, Player $player = null) : bool{
if($player instanceof Player){
$player->setCraftingGrid(new CraftingGrid($player, CraftingGrid::SIZE_BIG));
if(!array_key_exists($windowId = Player::HARDCODED_CRAFTING_GRID_WINDOW_ID, $player->openHardcodedWindows)){
//TODO: HACK! crafting grid doesn't fit very well into the current PM container system, so this hack allows
//it to carry on working approximately the same way as it did in 1.14
$pk = new ContainerOpenPacket();
$pk->windowId = $windowId;
$pk->type = WindowTypes::WORKBENCH;
$pk->x = $this->getFloorX();
$pk->y = $this->getFloorY();
$pk->z = $this->getFloorZ();
$player->sendDataPacket($pk);
$player->openHardcodedWindows[$windowId] = true;
}
}
return true;

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace pocketmine\block;
use pocketmine\entity\Entity;
use pocketmine\entity\Living;
use pocketmine\item\Item;
use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Vector3;
@ -58,7 +59,7 @@ class Ladder extends Transparent{
}
public function onEntityCollide(Entity $entity) : void{
if($entity->asVector3()->floor()->distanceSquared($this) < 1){ //entity coordinates must be inside block
if($entity instanceof Living and $entity->asVector3()->floor()->distanceSquared($this) < 1){ //entity coordinates must be inside block
$entity->resetFallDistance();
$entity->onGround = true;
}

View File

@ -418,6 +418,9 @@ abstract class Liquid extends Transparent{
return $isOptimalFlowDirection;
}
/**
* @phpstan-impure This function modifies the adjacent sources count (premature optimisation)
*/
private function getSmallestFlowDecay(Block $block, int $decay) : int{
$blockDecay = $this->getFlowDecay($block);

View File

@ -40,6 +40,6 @@ class Podzol extends Solid{
}
public function getHardness() : float{
return 2.5;
return 0.5;
}
}

View File

@ -40,9 +40,13 @@ class Potato extends Crops{
}
public function getDropsForCompatibleTool(Item $item) : array{
return [
ItemFactory::get(Item::POTATO, 0, $this->getDamage() >= 0x07 ? mt_rand(1, 4) : 1)
$result = [
ItemFactory::get(Item::POTATO, 0, $this->getDamage() >= 0x07 ? mt_rand(1, 5) : 1)
];
if($this->getDamage() >= 7 && mt_rand(0, 49) === 0){
$result[] = ItemFactory::get(Item::POISONOUS_POTATO);
}
return $result;
}
public function getPickedItem() : Item{

View File

@ -71,6 +71,7 @@ class Rail extends BaseRail{
}
protected function getPossibleConnectionDirectionsOneConstraint(int $constraint) : array{
/** @var int[] $horizontal */
static $horizontal = [
Vector3::SIDE_NORTH,
Vector3::SIDE_SOUTH,

View File

@ -31,6 +31,10 @@ class Sponge extends Solid{
$this->meta = $meta;
}
public function getToolType() : int{
return BlockToolType::TYPE_HOE;
}
public function getHardness() : float{
return 0.6;
}

View File

@ -87,7 +87,12 @@ class Sugarcane extends Flowable{
for($y = 1; $y < 3; ++$y){
$b = $this->getLevelNonNull()->getBlockAt($this->x, $this->y + $y, $this->z);
if($b->getId() === self::AIR){
$this->getLevelNonNull()->setBlock($b, BlockFactory::get(Block::SUGARCANE_BLOCK), true);
$ev = new BlockGrowEvent($b, BlockFactory::get(Block::SUGARCANE_BLOCK));
$ev->call();
if($ev->isCancelled()){
break;
}
$this->getLevelNonNull()->setBlock($b, $ev->getNewState(), true);
break;
}
}

View File

@ -25,23 +25,18 @@ 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{
@ -65,12 +60,6 @@ class CommandReader extends Thread{
public function __construct(?SleeperNotifier $notifier = null){
$this->buffer = new \Threaded;
$this->notifier = $notifier;
$opts = getopt("", ["disable-readline", "enable-readline"]);
if(extension_loaded("readline") and (Utils::getOS() === Utils::OS_WINDOWS ? isset($opts["enable-readline"]) : !isset($opts["disable-readline"])) and !$this->isPipe(STDIN)){
$this->type = self::TYPE_READLINE;
}
}
/**
@ -127,44 +116,28 @@ class CommandReader extends Thread{
* @return bool if the main execution should continue reading lines
*/
private function readLine() : bool{
$line = "";
if($this->type === self::TYPE_READLINE){
if(($raw = readline("> ")) !== false and ($line = trim($raw)) !== ""){
readline_add_history($line);
}else{
return true;
}
}else{
if(!is_resource(self::$stdin)){
$this->initStdin();
}
switch($this->type){
/** @noinspection PhpMissingBreakStatementInspection */
case self::TYPE_STREAM:
//stream_select doesn't work on piped streams for some reason
$r = [self::$stdin];
$w = $e = null;
if(($count = stream_select($r, $w, $e, 0, 200000)) === 0){ //nothing changed in 200000 microseconds
return true;
}elseif($count === false){ //stream error
$this->initStdin();
}
case self::TYPE_PIPED:
if(($raw = fgets(self::$stdin)) === false){ //broken pipe or EOF
$this->initStdin();
$this->synchronized(function() : void{
$this->wait(200000);
}); //prevent CPU waste if it's end of pipe
return true; //loop back round
}
$line = trim($raw);
break;
}
if(!is_resource(self::$stdin)){
$this->initStdin();
}
$r = [self::$stdin];
$w = $e = null;
if(($count = stream_select($r, $w, $e, 0, 200000)) === 0){ //nothing changed in 200000 microseconds
return true;
}elseif($count === false){ //stream error
$this->initStdin();
}
if(($raw = fgets(self::$stdin)) === false){ //broken pipe or EOF
$this->initStdin();
$this->synchronized(function() : void{
$this->wait(200000);
}); //prevent CPU waste if it's end of pipe
return true; //loop back round
}
$line = trim($raw);
if($line !== ""){
$this->buffer[] = preg_replace("#\\x1b\\x5b([^\\x1b]*\\x7e|[\\x40-\\x50])#", "", $line);
if($this->notifier !== null){
@ -193,17 +166,11 @@ class CommandReader extends Thread{
*/
public function run(){
$this->registerClassLoader();
if($this->type !== self::TYPE_READLINE){
$this->initStdin();
}
$this->initStdin();
while(!$this->shutdown and $this->readLine());
if($this->type !== self::TYPE_READLINE){
fclose(self::$stdin);
}
fclose(self::$stdin);
}
public function getThreadName() : string{

View File

@ -30,7 +30,9 @@ use pocketmine\permission\BanEntry;
use function array_map;
use function count;
use function implode;
use function sort;
use function strtolower;
use const SORT_STRING;
class BanListCommand extends VanillaCommand{
@ -62,10 +64,11 @@ class BanListCommand extends VanillaCommand{
$args[0] = "players";
}
$list = $list->getEntries();
$message = implode(", ", array_map(function(BanEntry $entry) : string{
$list = array_map(function(BanEntry $entry) : string{
return $entry->getName();
}, $list));
}, $list->getEntries());
sort($list, SORT_STRING);
$message = implode(", ", $list);
if($args[0] === "ips"){
$sender->sendMessage(new TranslationContainer("commands.banlist.ips", [count($list)]));

View File

@ -30,6 +30,8 @@ use function array_filter;
use function array_map;
use function count;
use function implode;
use function sort;
use const SORT_STRING;
class ListCommand extends VanillaCommand{
@ -52,6 +54,7 @@ class ListCommand extends VanillaCommand{
}, array_filter($sender->getServer()->getOnlinePlayers(), function(Player $player) use ($sender) : bool{
return $player->isOnline() and (!($sender instanceof Player) or $sender->canSee($player));
}));
sort($playerNames, SORT_STRING);
$sender->sendMessage(new TranslationContainer("commands.players.list", [count($playerNames), $sender->getServer()->getMaxPlayers()]));
$sender->sendMessage(implode(", ", $playerNames));

View File

@ -30,6 +30,8 @@ use pocketmine\utils\TextFormat;
use function array_map;
use function count;
use function implode;
use function sort;
use const SORT_STRING;
class PluginsCommand extends VanillaCommand{
@ -51,6 +53,7 @@ class PluginsCommand extends VanillaCommand{
$list = array_map(function(Plugin $plugin) : string{
return ($plugin->isEnabled() ? TextFormat::GREEN : TextFormat::RED) . $plugin->getDescription()->getFullName();
}, $sender->getServer()->getPluginManager()->getPlugins());
sort($list, SORT_STRING);
$sender->sendMessage(new TranslationContainer("pocketmine.command.plugins.success", [count($list), implode(TextFormat::WHITE . ", ", $list)]));
return true;

View File

@ -54,9 +54,9 @@ class StatusCommand extends VanillaCommand{
$server = $sender->getServer();
$sender->sendMessage(TextFormat::GREEN . "---- " . TextFormat::WHITE . "Server status" . TextFormat::GREEN . " ----");
$time = microtime(true) - \pocketmine\START_TIME;
$time = (int) (microtime(true) - \pocketmine\START_TIME);
$seconds = floor($time % 60);
$seconds = $time % 60;
$minutes = null;
$hours = null;
$days = null;
@ -100,7 +100,6 @@ class StatusCommand extends VanillaCommand{
$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), 2) . " MB.");

View File

@ -27,11 +27,11 @@ use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
use pocketmine\math\Vector3;
use pocketmine\level\Location;
use pocketmine\Player;
use pocketmine\utils\AssumptionFailedError;
use pocketmine\utils\TextFormat;
use function array_filter;
use function array_values;
use function array_shift;
use function count;
use function round;
@ -47,84 +47,83 @@ class TeleportCommand extends VanillaCommand{
$this->setPermission("pocketmine.command.teleport");
}
private function findPlayer(CommandSender $sender, string $playerName) : ?Player{
$subject = $sender->getServer()->getPlayer($playerName);
if($subject === null){
$sender->sendMessage(TextFormat::RED . "Can't find player " . $playerName);
return null;
}
return $subject;
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
if(!$this->testPermission($sender)){
return true;
}
$args = array_values(array_filter($args, function(string $arg) : bool{
return $arg !== "";
}));
if(count($args) < 1 or count($args) > 6){
throw new InvalidCommandSyntaxException();
}
$target = null;
$origin = $sender;
if(count($args) === 1 or count($args) === 3){
if($sender instanceof Player){
$target = $sender;
}else{
$sender->sendMessage(TextFormat::RED . "Please provide a player!");
return true;
}
if(count($args) === 1){
$target = $sender->getServer()->getPlayer($args[0]);
if($target === null){
$sender->sendMessage(TextFormat::RED . "Can't find player " . $args[0]);
switch(count($args)){
case 1: // /tp targetPlayer
case 3: // /tp x y z
case 5: // /tp x y z yaw pitch - TODO: 5 args could be target x y z yaw :(
if(!($sender instanceof Player)){
$sender->sendMessage(TextFormat::RED . "Please provide a player!");
return true;
}
}
}else{
$target = $sender->getServer()->getPlayer($args[0]);
if($target === null){
$sender->sendMessage(TextFormat::RED . "Can't find player " . $args[0]);
return true;
}
if(count($args) === 2){
$origin = $target;
$target = $sender->getServer()->getPlayer($args[1]);
if($target === null){
$sender->sendMessage(TextFormat::RED . "Can't find player " . $args[1]);
$subject = $sender;
$targetArgs = $args;
break;
case 2: // /tp player1 player2
case 4: // /tp player1 x y z - TODO: 4 args could be x y z yaw :(
case 6: // /tp player1 x y z yaw pitch
$subject = $this->findPlayer($sender, $args[0]);
if($subject === null){
return true;
}
}
$targetArgs = $args;
array_shift($targetArgs);
break;
default:
throw new InvalidCommandSyntaxException();
}
if(count($args) < 3){
$origin->teleport($target);
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.tp.success", [$origin->getName(), $target->getName()]));
switch(count($targetArgs)){
case 1:
$targetPlayer = $this->findPlayer($sender, $targetArgs[0]);
if($targetPlayer === null){
return true;
}
return true;
}elseif($target->isValid()){
if(count($args) === 4 or count($args) === 6){
$pos = 1;
}else{
$pos = 0;
}
$subject->teleport($targetPlayer->getLocation());
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.tp.success", [$subject->getName(), $targetPlayer->getName()]));
$x = $this->getRelativeDouble($target->x, $sender, $args[$pos++]);
$y = $this->getRelativeDouble($target->y, $sender, $args[$pos++], 0, 256);
$z = $this->getRelativeDouble($target->z, $sender, $args[$pos++]);
$yaw = $target->getYaw();
$pitch = $target->getPitch();
return true;
case 3:
case 5:
$base = $subject->getLocation();
if(count($targetArgs) === 5){
$yaw = (float) $targetArgs[3];
$pitch = (float) $targetArgs[4];
}else{
$yaw = $base->yaw;
$pitch = $base->pitch;
}
if(count($args) === 6 or (count($args) === 5 and $pos === 3)){
$yaw = (float) $args[$pos++];
$pitch = (float) $args[$pos++];
}
$x = $this->getRelativeDouble($base->x, $sender, $targetArgs[0]);
$y = $this->getRelativeDouble($base->y, $sender, $targetArgs[1], 0, 256);
$z = $this->getRelativeDouble($base->z, $sender, $targetArgs[2]);
$targetLocation = new Location($x, $y, $z, $yaw, $pitch, $base->getLevelNonNull());
$target->teleport(new Vector3($x, $y, $z), $yaw, $pitch);
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.tp.success.coordinates", [$target->getName(), round($x, 2), round($y, 2), round($z, 2)]));
return true;
$subject->teleport($targetLocation);
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.tp.success.coordinates", [
$subject->getName(),
round($targetLocation->x, 2),
round($targetLocation->y, 2),
round($targetLocation->z, 2)
]));
return true;
default:
throw new AssumptionFailedError("This branch should be unreachable (for now)");
}
throw new InvalidCommandSyntaxException();
}
}

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace pocketmine\command\defaults;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\TranslationContainer;
@ -72,12 +73,12 @@ class TimingsCommand extends VanillaCommand{
if($mode === "on"){
TimingsHandler::setEnabled();
$sender->sendMessage(new TranslationContainer("pocketmine.command.timings.enable"));
Command::broadcastCommandMessage($sender, new TranslationContainer("pocketmine.command.timings.enable"));
return true;
}elseif($mode === "off"){
TimingsHandler::setEnabled(false);
$sender->sendMessage(new TranslationContainer("pocketmine.command.timings.disable"));
Command::broadcastCommandMessage($sender, new TranslationContainer("pocketmine.command.timings.disable"));
return true;
}
@ -91,7 +92,7 @@ class TimingsCommand extends VanillaCommand{
if($mode === "reset"){
TimingsHandler::reload();
$sender->sendMessage(new TranslationContainer("pocketmine.command.timings.reset"));
Command::broadcastCommandMessage($sender, new TranslationContainer("pocketmine.command.timings.reset"));
}elseif($mode === "merged" or $mode === "report" or $paste){
$timings = "";
if($paste){
@ -150,6 +151,7 @@ class TimingsCommand extends VanillaCommand{
}
public function onCompletion(Server $server){
/** @var CommandSender $sender */
$sender = $this->fetchLocal();
if($sender instanceof Player and !$sender->isOnline()){ // TODO replace with a more generic API method for checking availability of CommandSender
return;
@ -159,18 +161,21 @@ class TimingsCommand extends VanillaCommand{
$server->getLogger()->logException($result);
return;
}
if(isset($result[0]) && is_array($response = json_decode($result[0], true)) && isset($response["id"])){
$sender->sendMessage(new TranslationContainer("pocketmine.command.timings.timingsRead",
$response = json_decode($result[0], true);
if(is_array($response) && isset($response["id"])){
Command::broadcastCommandMessage($sender, new TranslationContainer("pocketmine.command.timings.timingsRead",
["https://" . $this->host . "/?id=" . $response["id"]]));
}else{
$sender->sendMessage(new TranslationContainer("pocketmine.command.timings.pasteError"));
Command::broadcastCommandMessage($sender, new TranslationContainer("pocketmine.command.timings.pasteError"));
}
}
});
}else{
fclose($fileTimings);
$sender->sendMessage(new TranslationContainer("pocketmine.command.timings.timingsWrite", [$timings]));
Command::broadcastCommandMessage($sender, new TranslationContainer("pocketmine.command.timings.timingsWrite", [$timings]));
}
}else{
throw new InvalidCommandSyntaxException();
}
return true;

View File

@ -31,7 +31,9 @@ use pocketmine\Player;
use pocketmine\utils\TextFormat;
use function count;
use function implode;
use function sort;
use function strtolower;
use const SORT_STRING;
class WhitelistCommand extends VanillaCommand{
@ -49,10 +51,6 @@ class WhitelistCommand extends VanillaCommand{
return true;
}
if(count($args) === 0 or count($args) > 2){
throw new InvalidCommandSyntaxException();
}
if(count($args) === 1){
if($this->badPerm($sender, strtolower($args[0]))){
return false;
@ -75,7 +73,8 @@ class WhitelistCommand extends VanillaCommand{
return true;
case "list":
$entries = $sender->getServer()->getWhitelisted()->getAll(true);
$result = implode($entries, ", ");
sort($entries, SORT_STRING);
$result = implode(", ", $entries);
$count = count($entries);
$sender->sendMessage(new TranslationContainer("commands.whitelist.list", [$count, $count]));
@ -112,7 +111,7 @@ class WhitelistCommand extends VanillaCommand{
}
}
return true;
throw new InvalidCommandSyntaxException();
}
private function badPerm(CommandSender $sender, string $subcommand) : bool{

View File

@ -45,6 +45,7 @@ class Attribute{
public const FALL_DAMAGE = 13;
public const HORSE_JUMP_STRENGTH = 14;
public const ZOMBIE_SPAWN_REINFORCEMENTS = 15;
public const LAVA_MOVEMENT = 16;
/** @var int */
private $id;
@ -84,6 +85,7 @@ class Attribute{
self::addAttribute(self::FALL_DAMAGE, "minecraft:fall_damage", 0.0, 340282346638528859811704183484516925440.0, 1.0);
self::addAttribute(self::HORSE_JUMP_STRENGTH, "minecraft:horse.jump_strength", 0.0, 2.0, 0.7);
self::addAttribute(self::ZOMBIE_SPAWN_REINFORCEMENTS, "minecraft:zombie.spawn_reinforcements", 0.0, 1.0, 0.0);
self::addAttribute(self::LAVA_MOVEMENT, "minecraft:lava_movement", 0.0, 340282346638528859811704183484516925440.0, 0.02);
}
/**

View File

@ -31,7 +31,7 @@ use pocketmine\event\player\PlayerExhaustEvent;
use pocketmine\utils\Color;
use function constant;
use function defined;
use function strtoupper;
use function mb_strtoupper;
class Effect{
public const SPEED = 1;
@ -102,7 +102,7 @@ class Effect{
}
public static function getEffectByName(string $name) : ?Effect{
$const = self::class . "::" . strtoupper($name);
$const = self::class . "::" . mb_strtoupper($name);
if(defined($const)){
return self::getEffect(constant($const));
}

View File

@ -77,9 +77,9 @@ use function abs;
use function assert;
use function cos;
use function count;
use function current;
use function deg2rad;
use function floor;
use function fmod;
use function get_class;
use function in_array;
use function is_a;
@ -94,6 +94,7 @@ use const M_PI_2;
abstract class Entity extends Location implements Metadatable, EntityIds{
public const MOTION_THRESHOLD = 0.00001;
protected const STEP_CLIP_MULTIPLIER = 0.4;
public const NETWORK_ID = -1;
@ -174,56 +175,56 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
public const DATA_RIDER_ROTATION_LOCKED = 57; //byte
public const DATA_RIDER_MAX_ROTATION = 58; //float
public const DATA_RIDER_MIN_ROTATION = 59; //float
public const DATA_AREA_EFFECT_CLOUD_RADIUS = 60; //float
public const DATA_AREA_EFFECT_CLOUD_WAITING = 61; //int
public const DATA_AREA_EFFECT_CLOUD_PARTICLE_ID = 62; //int
/* 63 (int) shulker-related */
public const DATA_SHULKER_ATTACH_FACE = 64; //byte
/* 65 (short) shulker-related */
public const DATA_SHULKER_ATTACH_POS = 66; //block coords
public const DATA_TRADING_PLAYER_EID = 67; //long
public const DATA_AREA_EFFECT_CLOUD_RADIUS = 61; //float
public const DATA_AREA_EFFECT_CLOUD_WAITING = 62; //int
public const DATA_AREA_EFFECT_CLOUD_PARTICLE_ID = 63; //int
/* 64 (int) shulker-related */
public const DATA_SHULKER_ATTACH_FACE = 65; //byte
/* 66 (short) shulker-related */
public const DATA_SHULKER_ATTACH_POS = 67; //block coords
public const DATA_TRADING_PLAYER_EID = 68; //long
/* 69 (byte) command-block */
public const DATA_COMMAND_BLOCK_COMMAND = 70; //string
public const DATA_COMMAND_BLOCK_LAST_OUTPUT = 71; //string
public const DATA_COMMAND_BLOCK_TRACK_OUTPUT = 72; //byte
public const DATA_CONTROLLING_RIDER_SEAT_NUMBER = 73; //byte
public const DATA_STRENGTH = 74; //int
public const DATA_MAX_STRENGTH = 75; //int
/* 76 (int) */
public const DATA_LIMITED_LIFE = 77;
public const DATA_ARMOR_STAND_POSE_INDEX = 78; //int
public const DATA_ENDER_CRYSTAL_TIME_OFFSET = 79; //int
public const DATA_ALWAYS_SHOW_NAMETAG = 80; //byte: -1 = default, 0 = only when looked at, 1 = always
public const DATA_COLOR_2 = 81; //byte
/* 82 (unknown) */
public const DATA_SCORE_TAG = 83; //string
public const DATA_BALLOON_ATTACHED_ENTITY = 84; //int64, entity unique ID of owner
public const DATA_PUFFERFISH_SIZE = 85; //byte
public const DATA_BOAT_BUBBLE_TIME = 86; //int (time in bubble column)
public const DATA_PLAYER_AGENT_EID = 87; //long
/* 88 (float) related to panda sitting
* 89 (float) related to panda sitting */
public const DATA_EAT_COUNTER = 90; //int (used by pandas)
public const DATA_FLAGS2 = 91; //long (extended data flags)
/* 92 (float) related to panda lying down
* 93 (float) related to panda lying down */
public const DATA_AREA_EFFECT_CLOUD_DURATION = 94; //int
public const DATA_AREA_EFFECT_CLOUD_SPAWN_TIME = 95; //int
public const DATA_AREA_EFFECT_CLOUD_RADIUS_PER_TICK = 96; //float, usually negative
public const DATA_AREA_EFFECT_CLOUD_RADIUS_CHANGE_ON_PICKUP = 97; //float
public const DATA_AREA_EFFECT_CLOUD_PICKUP_COUNT = 98; //int
public const DATA_INTERACTIVE_TAG = 99; //string (button text)
public const DATA_TRADE_TIER = 100; //int
public const DATA_MAX_TRADE_TIER = 101; //int
public const DATA_TRADE_XP = 102; //int
public const DATA_SKIN_ID = 103; //int ???
/* 104 (int) related to wither */
public const DATA_COMMAND_BLOCK_TICK_DELAY = 105; //int
public const DATA_COMMAND_BLOCK_EXECUTE_ON_FIRST_TICK = 106; //byte
public const DATA_AMBIENT_SOUND_INTERVAL_MIN = 107; //float
public const DATA_AMBIENT_SOUND_INTERVAL_RANGE = 108; //float
public const DATA_AMBIENT_SOUND_EVENT = 109; //string
/* 70 (byte) command-block */
public const DATA_COMMAND_BLOCK_COMMAND = 71; //string
public const DATA_COMMAND_BLOCK_LAST_OUTPUT = 72; //string
public const DATA_COMMAND_BLOCK_TRACK_OUTPUT = 73; //byte
public const DATA_CONTROLLING_RIDER_SEAT_NUMBER = 74; //byte
public const DATA_STRENGTH = 75; //int
public const DATA_MAX_STRENGTH = 76; //int
/* 77 (int) */
public const DATA_LIMITED_LIFE = 78;
public const DATA_ARMOR_STAND_POSE_INDEX = 79; //int
public const DATA_ENDER_CRYSTAL_TIME_OFFSET = 80; //int
public const DATA_ALWAYS_SHOW_NAMETAG = 81; //byte: -1 = default, 0 = only when looked at, 1 = always
public const DATA_COLOR_2 = 82; //byte
/* 83 (unknown) */
public const DATA_SCORE_TAG = 84; //string
public const DATA_BALLOON_ATTACHED_ENTITY = 85; //int64, entity unique ID of owner
public const DATA_PUFFERFISH_SIZE = 86; //byte
public const DATA_BOAT_BUBBLE_TIME = 87; //int (time in bubble column)
public const DATA_PLAYER_AGENT_EID = 88; //long
/* 89 (float) related to panda sitting
* 90 (float) related to panda sitting */
public const DATA_EAT_COUNTER = 91; //int (used by pandas)
public const DATA_FLAGS2 = 92; //long (extended data flags)
/* 93 (float) related to panda lying down
* 94 (float) related to panda lying down */
public const DATA_AREA_EFFECT_CLOUD_DURATION = 95; //int
public const DATA_AREA_EFFECT_CLOUD_SPAWN_TIME = 96; //int
public const DATA_AREA_EFFECT_CLOUD_RADIUS_PER_TICK = 97; //float, usually negative
public const DATA_AREA_EFFECT_CLOUD_RADIUS_CHANGE_ON_PICKUP = 98; //float
public const DATA_AREA_EFFECT_CLOUD_PICKUP_COUNT = 99; //int
public const DATA_INTERACTIVE_TAG = 100; //string (button text)
public const DATA_TRADE_TIER = 101; //int
public const DATA_MAX_TRADE_TIER = 102; //int
public const DATA_TRADE_XP = 103; //int
public const DATA_SKIN_ID = 104; //int ???
/* 105 (int) related to wither */
public const DATA_COMMAND_BLOCK_TICK_DELAY = 106; //int
public const DATA_COMMAND_BLOCK_EXECUTE_ON_FIRST_TICK = 107; //byte
public const DATA_AMBIENT_SOUND_INTERVAL_MIN = 108; //float
public const DATA_AMBIENT_SOUND_INTERVAL_RANGE = 109; //float
public const DATA_AMBIENT_SOUND_EVENT = 110; //string
public const DATA_FLAG_ONFIRE = 0;
public const DATA_FLAG_SNEAKING = 1;
@ -311,12 +312,15 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
public const DATA_FLAG_ROARING = 83;
public const DATA_FLAG_DELAYED_ATTACKING = 84;
public const DATA_FLAG_AVOIDING_MOBS = 85;
public const DATA_FLAG_FACING_TARGET_TO_RANGE_ATTACK = 86;
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_FLAG_AVOIDING_BLOCK = 86;
public const DATA_FLAG_FACING_TARGET_TO_RANGE_ATTACK = 87;
public const DATA_FLAG_HIDDEN_WHEN_INVISIBLE = 88; //??????????????????
public const DATA_FLAG_IS_IN_UI = 89;
public const DATA_FLAG_STALKING = 90;
public const DATA_FLAG_EMOTING = 91;
public const DATA_FLAG_CELEBRATING = 92;
public const DATA_FLAG_ADMIRING = 93;
public const DATA_FLAG_CELEBRATING_SPECIAL = 94;
public const DATA_PLAYER_FLAG_SLEEP = 1;
public const DATA_PLAYER_FLAG_DEAD = 2; //TODO: CHECK
@ -329,8 +333,8 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
*/
private static $knownEntities = [];
/**
* @var string[][]
* @phpstan-var array<class-string<Entity>, list<string>>
* @var string[]
* @phpstan-var array<class-string<Entity>, string>
*/
private static $saveNames = [];
@ -409,7 +413,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
self::$knownEntities[$name] = $className;
}
self::$saveNames[$className] = $saveNames;
self::$saveNames[$className] = reset($saveNames);
return true;
}
@ -704,10 +708,10 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
$this->boundingBox->setBounds(
$this->x - $halfWidth,
$this->y,
$this->y + $this->ySize,
$this->z - $halfWidth,
$this->x + $halfWidth,
$this->y + $this->height,
$this->y + $this->height + $this->ySize,
$this->z + $halfWidth
);
}
@ -865,10 +869,9 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
*/
public function getSaveId() : string{
if(!isset(self::$saveNames[static::class])){
throw new \InvalidStateException("Entity is not registered");
throw new \InvalidStateException("Entity " . static::class . " is not registered");
}
reset(self::$saveNames[static::class]);
return current(self::$saveNames[static::class]);
return self::$saveNames[static::class];
}
public function saveNBT() : void{
@ -1308,7 +1311,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
}
public function getDirection() : ?int{
$rotation = ($this->yaw - 90) % 360;
$rotation = fmod($this->yaw - 90, 360);
if($rotation < 0){
$rotation += 360.0;
}
@ -1446,8 +1449,14 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
$this->fall($this->fallDistance);
$this->resetFallDistance();
}
}elseif($distanceThisTick < 0){
}elseif($distanceThisTick < $this->fallDistance){
//we've fallen some distance (distanceThisTick is negative)
//or we ascended back towards where fall distance was measured from initially (distanceThisTick is positive but less than existing fallDistance)
$this->fallDistance -= $distanceThisTick;
}else{
//we ascended past the apex where fall distance was originally being measured from
//reset it so it will be measured starting from the new, higher position
$this->fallDistance = 0;
}
}
@ -1535,7 +1544,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
if($this->keepMovement){
$this->boundingBox->offset($dx, $dy, $dz);
}else{
$this->ySize *= 0.4;
$this->ySize *= self::STEP_CLIP_MULTIPLIER;
/*
if($this->isColliding){ //With cobweb?
@ -1602,7 +1611,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
$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 ($movX != $dx or $movZ != $dz)){
$cx = $dx;
$cy = $dy;
$cz = $dz;
@ -1634,13 +1643,20 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
$this->boundingBox->offset(0, 0, $dz);
$reverseDY = -$dy;
foreach($list as $bb){
$reverseDY = $bb->calculateYOffset($this->boundingBox, $reverseDY);
}
$dy += $reverseDY;
$this->boundingBox->offset(0, $reverseDY, 0);
if(($cx ** 2 + $cz ** 2) >= ($dx ** 2 + $dz ** 2)){
$dx = $cx;
$dy = $cy;
$dz = $cz;
$this->boundingBox->setBB($axisalignedbb1);
}else{
$this->ySize += 0.5; //FIXME: this should be the height of the block it walked up, not fixed 0.5
$this->ySize += $dy;
}
}
}

View File

@ -54,6 +54,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket;
use pocketmine\network\mcpe\protocol\MovePlayerPacket;
use pocketmine\network\mcpe\protocol\PlayerListPacket;
use pocketmine\network\mcpe\protocol\PlayerSkinPacket;
use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper;
use pocketmine\network\mcpe\protocol\types\PlayerListEntry;
use pocketmine\network\mcpe\protocol\types\SkinAdapterSingleton;
use pocketmine\Player;
@ -300,17 +301,20 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
if($consumable instanceof MaybeConsumable and !$consumable->canBeConsumed()){
return false;
}
if($consumable instanceof FoodSource && $consumable->requiresHunger() and !$this->isHungry()){
return false;
}
return parent::consumeObject($consumable);
}
protected function applyConsumptionResults(Consumable $consumable) : void{
if($consumable instanceof FoodSource){
if($consumable->requiresHunger() and !$this->isHungry()){
return false;
}
$this->addFood($consumable->getFoodRestore());
$this->addSaturation($consumable->getSaturationRestore());
}
return parent::consumeObject($consumable);
parent::applyConsumptionResults($consumable);
}
/**
@ -400,12 +404,14 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
* @param bool $playSound Whether to play level-up and XP gained sounds.
*/
public function addXp(int $amount, bool $playSound = true) : bool{
$this->totalXp += $amount;
$oldLevel = $this->getXpLevel();
$oldTotal = $this->getCurrentTotalXp();
if($this->setCurrentTotalXp($oldTotal + $amount)){
if($amount > 0){
$this->totalXp += $amount;
}
if($playSound){
$newLevel = $this->getXpLevel();
if((int) ($newLevel / 5) > (int) ($oldLevel / 5)){
@ -808,7 +814,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
$pk->motion = $this->getMotion();
$pk->yaw = $this->yaw;
$pk->pitch = $this->pitch;
$pk->item = $this->getInventory()->getItemInHand();
$pk->item = ItemStackWrapper::legacy($this->getInventory()->getItemInHand());
$pk->metadata = $this->propertyManager->getAll();
$player->dataPacket($pk);

View File

@ -0,0 +1,28 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\entity;
final class InvalidSkinException extends \InvalidArgumentException{
}

View File

@ -45,6 +45,7 @@ use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\FloatTag;
use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\ShortTag;
use pocketmine\network\mcpe\protocol\ActorEventPacket;
use pocketmine\network\mcpe\protocol\LevelSoundEventPacket;
use pocketmine\network\mcpe\protocol\MobEffectPacket;
@ -97,17 +98,15 @@ abstract class Living extends Entity implements Damageable{
//TODO: load/save armor inventory contents
$this->armorInventory->setEventProcessor(new ArmorInventoryEventProcessor($this));
$health = $this->getMaxHealth();
if($this->namedtag->hasTag("HealF", FloatTag::class)){
$health = $this->namedtag->getFloat("HealF");
$this->namedtag->removeTag("HealF");
}elseif($this->namedtag->hasTag("Health")){
$healthTag = $this->namedtag->getTag("Health");
$health = (float) $healthTag->getValue(); //Older versions of PocketMine-MP incorrectly saved this as a short instead of a float
if(!($healthTag instanceof FloatTag)){
$this->namedtag->removeTag("Health");
}
}elseif($this->namedtag->hasTag("Health", ShortTag::class)){
//Older versions of PocketMine-MP incorrectly saved this as a short instead of a float
$health = $this->namedtag->getShort("Health");
$this->namedtag->removeTag("Health");
}else{
$health = $this->namedtag->getFloat("Health", $this->getMaxHealth());
}
$this->setHealth($health);
@ -364,13 +363,20 @@ abstract class Living extends Entity implements Damageable{
return false;
}
$this->applyConsumptionResults($consumable);
return true;
}
/**
* Applies effects from consuming the object. This shouldn't do any can-consume checks (those are expected to be
* handled by the caller).
*/
protected function applyConsumptionResults(Consumable $consumable) : void{
foreach($consumable->getAdditionalEffects() as $effect){
$this->addEffect($effect);
}
$consumable->onConsume($this);
return true;
}
/**

View File

@ -62,24 +62,24 @@ class Skin{
try{
$this->validate();
return true;
}catch(\InvalidArgumentException $e){
}catch(InvalidSkinException $e){
return false;
}
}
/**
* @throws \InvalidArgumentException
* @throws InvalidSkinException
*/
public function validate() : void{
if($this->skinId === ""){
throw new \InvalidArgumentException("Skin ID must not be empty");
throw new InvalidSkinException("Skin ID must not be empty");
}
$len = strlen($this->skinData);
if(!in_array($len, self::ACCEPTED_SKIN_SIZES, true)){
throw new \InvalidArgumentException("Invalid skin data size $len bytes (allowed sizes: " . implode(", ", self::ACCEPTED_SKIN_SIZES) . ")");
throw new InvalidSkinException("Invalid skin data size $len bytes (allowed sizes: " . implode(", ", self::ACCEPTED_SKIN_SIZES) . ")");
}
if($this->capeData !== "" and strlen($this->capeData) !== 8192){
throw new \InvalidArgumentException("Invalid cape data size " . strlen($this->capeData) . " bytes (must be exactly 8192 bytes)");
throw new InvalidSkinException("Invalid cape data size " . strlen($this->capeData) . " bytes (must be exactly 8192 bytes)");
}
//TODO: validate geometry
}

View File

@ -30,6 +30,7 @@ use pocketmine\event\inventory\InventoryPickupItemEvent;
use pocketmine\item\Item;
use pocketmine\network\mcpe\protocol\AddItemActorPacket;
use pocketmine\network\mcpe\protocol\TakeItemActorPacket;
use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper;
use pocketmine\Player;
use function get_class;
@ -173,7 +174,7 @@ class ItemEntity extends Entity{
$pk->entityRuntimeId = $this->getId();
$pk->position = $this->asVector3();
$pk->motion = $this->getMotion();
$pk->item = $this->getItem();
$pk->item = ItemStackWrapper::legacy($this->getItem());
$pk->metadata = $this->propertyManager->getAll();
$player->dataPacket($pk);

View File

@ -24,6 +24,8 @@ declare(strict_types=1);
namespace pocketmine\entity\utils;
use pocketmine\math\Math;
use pocketmine\utils\AssumptionFailedError;
use function count;
use function max;
abstract class ExperienceUtils{
@ -59,6 +61,9 @@ abstract class ExperienceUtils{
* This returns a floating-point number, the decimal part being the progress through the resulting level.
*/
public static function getLevelFromXp(int $xp) : float{
if($xp < 0){
throw new \InvalidArgumentException("XP must be at least 0");
}
if($xp <= self::getXpToReachLevel(16)){
$a = 1;
$b = 6;
@ -74,6 +79,9 @@ abstract class ExperienceUtils{
}
$x = Math::solveQuadratic($a, $b, $c - $xp);
if(count($x) === 0){
throw new AssumptionFailedError("Expected at least 1 solution");
}
return max($x); //we're only interested in the positive solution
}

View File

@ -25,7 +25,7 @@ namespace pocketmine\event;
use function constant;
use function defined;
use function strtoupper;
use function mb_strtoupper;
/**
* List of event priorities
@ -79,7 +79,7 @@ abstract class EventPriority{
* @throws \InvalidArgumentException
*/
public static function fromString(string $name) : int{
$name = strtoupper($name);
$name = mb_strtoupper($name);
$const = self::class . "::" . $name;
if($name !== "ALL" and defined($const)){
return constant($const);

View File

@ -48,7 +48,7 @@ class BlockBreakEvent extends BlockEvent implements Cancellable{
/**
* @param Item[] $drops
*/
public function __construct(Player $player, Block $block, Item $item, bool $instaBreak = false, array $drops, int $xpDrops = 0){
public function __construct(Player $player, Block $block, Item $item, bool $instaBreak = false, array $drops = [], int $xpDrops = 0){
parent::__construct($block);
$this->item = $item;
$this->player = $player;

View File

@ -26,6 +26,7 @@ namespace pocketmine\event\block;
use pocketmine\block\Block;
use pocketmine\event\Cancellable;
use pocketmine\Player;
use pocketmine\utils\Utils;
use function count;
/**
@ -79,6 +80,7 @@ class SignChangeEvent extends BlockEvent implements Cancellable{
if(count($lines) !== 4){
throw new \InvalidArgumentException("Array size must be 4!");
}
Utils::validateArrayValueType($lines, function(string $_) : void{});
$this->lines = $lines;
}

View File

@ -29,6 +29,7 @@ use pocketmine\event\Cancellable;
/**
* Called when an Entity, excluding players, changes a block directly
* @phpstan-extends EntityEvent<Entity>
*/
class EntityBlockChangeEvent extends EntityEvent implements Cancellable{
/** @var Block */

View File

@ -26,6 +26,9 @@ namespace pocketmine\event\entity;
use pocketmine\entity\Entity;
use pocketmine\event\Cancellable;
/**
* @phpstan-extends EntityEvent<Entity>
*/
class EntityCombustEvent extends EntityEvent implements Cancellable{
/** @var int */
protected $duration;

View File

@ -30,6 +30,7 @@ use function max;
/**
* Called when an entity takes damage.
* @phpstan-extends EntityEvent<Entity>
*/
class EntityDamageEvent extends EntityEvent implements Cancellable{
public const MODIFIER_ARMOR = 1;

View File

@ -25,7 +25,11 @@ namespace pocketmine\event\entity;
use pocketmine\entity\Living;
use pocketmine\item\Item;
use pocketmine\utils\Utils;
/**
* @phpstan-extends EntityEvent<Living>
*/
class EntityDeathEvent extends EntityEvent{
/** @var Item[] */
private $drops = [];
@ -59,6 +63,7 @@ class EntityDeathEvent extends EntityEvent{
* @param Item[] $drops
*/
public function setDrops(array $drops) : void{
Utils::validateArrayValueType($drops, function(Item $_) : void{});
$this->drops = $drops;
}

View File

@ -32,6 +32,7 @@ use pocketmine\entity\Vehicle;
/**
* Called when a entity is despawned
* @phpstan-extends EntityEvent<Entity>
*/
class EntityDespawnEvent extends EntityEvent{
/** @var int */

View File

@ -27,6 +27,9 @@ use pocketmine\entity\EffectInstance;
use pocketmine\entity\Entity;
use pocketmine\event\Cancellable;
/**
* @phpstan-extends EntityEvent<Entity>
*/
class EntityEffectEvent extends EntityEvent implements Cancellable{
/** @var EffectInstance */
private $effect;

View File

@ -29,12 +29,19 @@ namespace pocketmine\event\entity;
use pocketmine\entity\Entity;
use pocketmine\event\Event;
/**
* @phpstan-template TEntity of Entity
*/
abstract class EntityEvent extends Event{
/** @var Entity */
/**
* @var Entity
* @phpstan-var TEntity
*/
protected $entity;
/**
* @return Entity
* @phpstan-return TEntity
*/
public function getEntity(){
return $this->entity;

View File

@ -27,9 +27,11 @@ use pocketmine\block\Block;
use pocketmine\entity\Entity;
use pocketmine\event\Cancellable;
use pocketmine\level\Position;
use pocketmine\utils\Utils;
/**
* Called when a entity explodes
* @phpstan-extends EntityEvent<Entity>
*/
class EntityExplodeEvent extends EntityEvent implements Cancellable{
/** @var Position */
@ -66,6 +68,7 @@ class EntityExplodeEvent extends EntityEvent implements Cancellable{
* @param Block[] $blocks
*/
public function setBlockList(array $blocks) : void{
Utils::validateArrayValueType($blocks, function(Block $_) : void{});
$this->blocks = $blocks;
}

View File

@ -29,6 +29,7 @@ use pocketmine\item\Item;
/**
* Called before a slot in an entity's inventory changes.
* @phpstan-extends EntityEvent<Entity>
*/
class EntityInventoryChangeEvent extends EntityEvent implements Cancellable{
/** @var Item */

View File

@ -27,6 +27,9 @@ use pocketmine\entity\Entity;
use pocketmine\event\Cancellable;
use pocketmine\level\Level;
/**
* @phpstan-extends EntityEvent<Entity>
*/
class EntityLevelChangeEvent extends EntityEvent implements Cancellable{
/** @var Level */
private $originLevel;

View File

@ -27,6 +27,9 @@ use pocketmine\entity\Entity;
use pocketmine\event\Cancellable;
use pocketmine\math\Vector3;
/**
* @phpstan-extends EntityEvent<Entity>
*/
class EntityMotionEvent extends EntityEvent implements Cancellable{
/** @var Vector3 */
private $mot;

View File

@ -26,6 +26,9 @@ namespace pocketmine\event\entity;
use pocketmine\entity\Entity;
use pocketmine\event\Cancellable;
/**
* @phpstan-extends EntityEvent<Entity>
*/
class EntityRegainHealthEvent extends EntityEvent implements Cancellable{
public const CAUSE_REGEN = 0;
public const CAUSE_EATING = 1;

View File

@ -30,6 +30,9 @@ use pocketmine\event\Cancellable;
use pocketmine\item\Item;
use function count;
/**
* @phpstan-extends EntityEvent<Living>
*/
class EntityShootBowEvent extends EntityEvent implements Cancellable{
/** @var Item */
private $bow;

View File

@ -33,6 +33,7 @@ use pocketmine\level\Position;
/**
* Called when a entity is spawned
* @phpstan-extends EntityEvent<Entity>
*/
class EntitySpawnEvent extends EntityEvent{
/** @var int */

View File

@ -27,6 +27,9 @@ use pocketmine\entity\Entity;
use pocketmine\event\Cancellable;
use pocketmine\level\Position;
/**
* @phpstan-extends EntityEvent<Entity>
*/
class EntityTeleportEvent extends EntityEvent implements Cancellable{
/** @var Position */
private $from;

View File

@ -28,6 +28,7 @@ use pocketmine\event\Cancellable;
/**
* Called when a entity decides to explode
* @phpstan-extends EntityEvent<Entity>
*/
class ExplosionPrimeEvent extends EntityEvent implements Cancellable{
/** @var float */

View File

@ -26,6 +26,9 @@ namespace pocketmine\event\entity;
use pocketmine\entity\object\ItemEntity;
use pocketmine\event\Cancellable;
/**
* @phpstan-extends EntityEvent<ItemEntity>
*/
class ItemDespawnEvent extends EntityEvent implements Cancellable{
public function __construct(ItemEntity $item){

View File

@ -25,6 +25,9 @@ namespace pocketmine\event\entity;
use pocketmine\entity\object\ItemEntity;
/**
* @phpstan-extends EntityEvent<ItemEntity>
*/
class ItemSpawnEvent extends EntityEvent{
public function __construct(ItemEntity $item){

View File

@ -28,6 +28,7 @@ use pocketmine\math\RayTraceResult;
/**
* @allowHandle
* @phpstan-extends EntityEvent<Projectile>
*/
abstract class ProjectileHitEvent extends EntityEvent{
/** @var RayTraceResult */

View File

@ -26,6 +26,9 @@ namespace pocketmine\event\entity;
use pocketmine\entity\projectile\Projectile;
use pocketmine\event\Cancellable;
/**
* @phpstan-extends EntityEvent<Projectile>
*/
class ProjectileLaunchEvent extends EntityEvent implements Cancellable{
public function __construct(Projectile $entity){
$this->entity = $entity;

View File

@ -28,6 +28,9 @@ use pocketmine\event\Cancellable;
use pocketmine\item\Item;
use pocketmine\tile\Furnace;
/**
* Called when a furnace is about to consume a new fuel item.
*/
class FurnaceBurnEvent extends BlockEvent implements Cancellable{
/** @var Furnace */
private $furnace;
@ -53,18 +56,31 @@ class FurnaceBurnEvent extends BlockEvent implements Cancellable{
return $this->fuel;
}
/**
* Returns the number of ticks that the furnace will be powered for.
*/
public function getBurnTime() : int{
return $this->burnTime;
}
/**
* Sets the number of ticks that the given fuel will power the furnace for.
*/
public function setBurnTime(int $burnTime) : void{
$this->burnTime = $burnTime;
}
/**
* Returns whether the fuel item will be consumed.
*/
public function isBurning() : bool{
return $this->burning;
}
/**
* Sets whether the fuel will be consumed. If false, the furnace will smelt as if it consumed fuel, but no fuel
* will be deducted.
*/
public function setBurning(bool $burning) : void{
$this->burning = $burning;
}

View File

@ -28,6 +28,7 @@ use pocketmine\event\Cancellable;
use pocketmine\permission\PermissionManager;
use pocketmine\Player;
use pocketmine\Server;
use pocketmine\utils\Utils;
use function spl_object_id;
/**
@ -97,6 +98,7 @@ class PlayerChatEvent extends PlayerEvent implements Cancellable{
* @param CommandSender[] $recipients
*/
public function setRecipients(array $recipients) : void{
Utils::validateArrayValueType($recipients, function(CommandSender $_) : void{});
$this->recipients = $recipients;
}
}

View File

@ -39,14 +39,22 @@ class PlayerCreationEvent extends Event{
/** @var int */
private $port;
/** @var string */
/**
* @var string
* @phpstan-var class-string<Player>
*/
private $baseClass;
/** @var string */
/**
* @var string
* @phpstan-var class-string<Player>
*/
private $playerClass;
/**
* @param string $baseClass
* @param string $playerClass
* @phpstan-param class-string<Player> $baseClass
* @phpstan-param class-string<Player> $playerClass
*/
public function __construct(SourceInterface $interface, $baseClass, $playerClass, string $address, int $port){
$this->interface = $interface;
@ -80,6 +88,7 @@ class PlayerCreationEvent extends Event{
/**
* @return string
* @phpstan-return class-string<Player>
*/
public function getBaseClass(){
return $this->baseClass;
@ -87,6 +96,7 @@ class PlayerCreationEvent extends Event{
/**
* @param string $class
* @phpstan-param class-string<Player> $class
*
* @return void
*/
@ -100,6 +110,7 @@ class PlayerCreationEvent extends Event{
/**
* @return string
* @phpstan-return class-string<Player>
*/
public function getPlayerClass(){
return $this->playerClass;
@ -107,6 +118,7 @@ class PlayerCreationEvent extends Event{
/**
* @param string $class
* @phpstan-param class-string<Player> $class
*
* @return void
*/

View File

@ -27,6 +27,9 @@ use pocketmine\entity\Human;
use pocketmine\event\Cancellable;
use pocketmine\event\entity\EntityEvent;
/**
* @phpstan-extends EntityEvent<Human>
*/
class PlayerExhaustEvent extends EntityEvent implements Cancellable{
public const CAUSE_ATTACK = 1;
public const CAUSE_DAMAGE = 2;

View File

@ -29,6 +29,7 @@ use pocketmine\event\entity\EntityEvent;
/**
* Called when a player gains or loses XP levels and/or progress.
* @phpstan-extends EntityEvent<Human>
*/
class PlayerExperienceChangeEvent extends EntityEvent implements Cancellable{
/** @var Human */

View File

@ -43,6 +43,9 @@ class PlayerRespawnEvent extends PlayerEvent{
}
public function setRespawnPosition(Position $position) : void{
if(!$position->isValid()){
throw new \InvalidArgumentException("Spawn position must reference a valid and loaded World");
}
$this->position = $position;
}
}

View File

@ -27,6 +27,7 @@ use pocketmine\Player;
use pocketmine\plugin\Plugin;
use pocketmine\Server;
use pocketmine\utils\Binary;
use pocketmine\utils\Utils;
use function chr;
use function count;
use function str_replace;
@ -76,7 +77,7 @@ class QueryRegenerateEvent extends ServerEvent{
public function __construct(Server $server){
$this->serverName = $server->getMotd();
$this->listPlugins = $server->getProperty("settings.query-plugins", true);
$this->listPlugins = (bool) $server->getProperty("settings.query-plugins", true);
$this->plugins = $server->getPluginManager()->getPlugins();
$this->players = [];
foreach($server->getOnlinePlayers() as $player){
@ -145,6 +146,7 @@ class QueryRegenerateEvent extends ServerEvent{
* @param Plugin[] $plugins
*/
public function setPlugins(array $plugins) : void{
Utils::validateArrayValueType($plugins, function(Plugin $_) : void{});
$this->plugins = $plugins;
$this->destroyCache();
}
@ -160,6 +162,7 @@ class QueryRegenerateEvent extends ServerEvent{
* @param Player[] $players
*/
public function setPlayerList(array $players) : void{
Utils::validateArrayValueType($players, function(Player $_) : void{});
$this->players = $players;
$this->destroyCache();
}

View File

@ -28,7 +28,9 @@ use pocketmine\item\Item;
use pocketmine\network\mcpe\protocol\InventoryContentPacket;
use pocketmine\network\mcpe\protocol\InventorySlotPacket;
use pocketmine\network\mcpe\protocol\MobArmorEquipmentPacket;
use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper;
use pocketmine\Player;
use function array_map;
use function array_merge;
class ArmorInventory extends BaseInventory{
@ -96,10 +98,10 @@ class ArmorInventory extends BaseInventory{
$pk = new MobArmorEquipmentPacket();
$pk->entityRuntimeId = $this->getHolder()->getId();
$pk->head = $this->getHelmet();
$pk->chest = $this->getChestplate();
$pk->legs = $this->getLeggings();
$pk->feet = $this->getBoots();
$pk->head = ItemStackWrapper::legacy($this->getHelmet());
$pk->chest = ItemStackWrapper::legacy($this->getChestplate());
$pk->legs = ItemStackWrapper::legacy($this->getLeggings());
$pk->feet = ItemStackWrapper::legacy($this->getBoots());
$pk->encode();
foreach($target as $player){
@ -109,7 +111,7 @@ class ArmorInventory extends BaseInventory{
$pk2 = new InventorySlotPacket();
$pk2->windowId = $player->getWindowId($this);
$pk2->inventorySlot = $index;
$pk2->item = $this->getItem($index);
$pk2->item = ItemStackWrapper::legacy($this->getItem($index));
$player->dataPacket($pk2);
}else{
$player->dataPacket($pk);
@ -124,17 +126,17 @@ class ArmorInventory extends BaseInventory{
$pk = new MobArmorEquipmentPacket();
$pk->entityRuntimeId = $this->getHolder()->getId();
$pk->head = $this->getHelmet();
$pk->chest = $this->getChestplate();
$pk->legs = $this->getLeggings();
$pk->feet = $this->getBoots();
$pk->head = ItemStackWrapper::legacy($this->getHelmet());
$pk->chest = ItemStackWrapper::legacy($this->getChestplate());
$pk->legs = ItemStackWrapper::legacy($this->getLeggings());
$pk->feet = ItemStackWrapper::legacy($this->getBoots());
$pk->encode();
foreach($target as $player){
if($player === $this->getHolder()){
$pk2 = new InventoryContentPacket();
$pk2->windowId = $player->getWindowId($this);
$pk2->items = $this->getContents(true);
$pk2->items = array_map([ItemStackWrapper::class, 'legacy'], $this->getContents(true));
$player->dataPacket($pk2);
}else{
$player->dataPacket($pk);

View File

@ -31,7 +31,9 @@ use pocketmine\math\Vector3;
use pocketmine\network\mcpe\protocol\InventoryContentPacket;
use pocketmine\network\mcpe\protocol\InventorySlotPacket;
use pocketmine\network\mcpe\protocol\types\ContainerIds;
use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper;
use pocketmine\Player;
use function array_map;
use function array_slice;
use function count;
use function max;
@ -53,7 +55,7 @@ abstract class BaseInventory implements Inventory{
protected $slots;
/** @var Player[] */
protected $viewers = [];
/** @var InventoryEventProcessor */
/** @var InventoryEventProcessor|null */
protected $eventProcessor;
/**
@ -250,11 +252,11 @@ abstract class BaseInventory implements Inventory{
for($i = 0, $size = $this->getSize(); $i < $size; ++$i){
$slot = $this->getItem($i);
if($item->equals($slot)){
if(($diff = $slot->getMaxStackSize() - $slot->getCount()) > 0){
if(($diff = min($slot->getMaxStackSize(), $item->getMaxStackSize()) - $slot->getCount()) > 0){
$count -= $diff;
}
}elseif($slot->isNull()){
$count -= $this->getMaxStackSize();
$count -= min($this->getMaxStackSize(), $item->getMaxStackSize());
}
if($count <= 0){
@ -433,7 +435,7 @@ abstract class BaseInventory implements Inventory{
}
$pk = new InventoryContentPacket();
$pk->items = $this->getContents(true);
$pk->items = array_map([ItemStackWrapper::class, 'legacy'], $this->getContents(true));
foreach($target as $player){
if(($id = $player->getWindowId($this)) === ContainerIds::NONE){
@ -455,7 +457,7 @@ abstract class BaseInventory implements Inventory{
$pk = new InventorySlotPacket();
$pk->inventorySlot = $index;
$pk->item = $this->getItem($index);
$pk->item = ItemStackWrapper::legacy($this->getItem($index));
foreach($target as $player){
if(($id = $player->getWindowId($this)) === ContainerIds::NONE){

View File

@ -64,6 +64,7 @@ abstract class ContainerInventory extends BaseInventory{
public function onClose(Player $who) : void{
$pk = new ContainerClosePacket();
$pk->windowId = $who->getWindowId($this);
$pk->server = $who->getClosingWindowId() !== $pk->windowId;
$who->dataPacket($pk);
parent::onClose($who);
}

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