Compare commits

..

62 Commits
4.0.1 ... 4.0.4

Author SHA1 Message Date
b903e90dc2 Release 4.0.4 2022-01-01 16:50:02 +00:00
c8247786d7 Player: check chat length check with strlen() before mb_strlen()
mb_strlen() is O(n), whereas strlen() is O(1). If we receive very large chat messages (e.g. 2 MB), mb_strlen() will take a very long time to return a result (around 8ms on my machine).
Since the max size of a UTF-8 character is 4 bytes (according to standard), we can use strlen() with 4x the char limit to gate it and prevent this from happening.
2022-01-01 16:46:00 +00:00
f486b5f4a7 Player: fixed fall damage when sprinting down stairs (#4685)
Due to the way positions are updated over the network, we only see the end result of a movement and not its preceding actions. In addition, we don't know for sure whether the MCPE collision checks work the same exact way as PM.

TL;DR: It's possible for the client to capture and send a movement frame after they collided with a step and then already moved forward from it some distance, resulting in a weird arc pattern.

This PR checks the range between the old and new positions for collision boxes to ensure that all possible areas are checked for detecting fall damage.

This has been tested and successfully resolves various issues involving running down stairs:
- missing sounds
- random fall damage
2022-01-01 15:41:19 +00:00
54d6b83fc2 Entity: pass the appropriate value for AFFECTED_BY_GRAVITY 2022-01-01 15:39:46 +00:00
eedea38669 Improve performance of loading player inventories 2022-01-01 15:26:42 +00:00
3c6146b5e0 ContainerTrait: avoid absurdly inefficient use of setItem()
this substantially improves the performance of loading containers such as chests.
2022-01-01 15:05:32 +00:00
72f2c794ab SimpleInventory: improved performance of setContents()
avoid the overhead incurred by clear() and setItem(), because in internalSetContents(), we already have no listeners or viewers to talk to anyway, so this is just spamming shit into /dev/null.
2021-12-31 18:32:19 +00:00
38b6b39cb3 Filesystem: workaround a stupid Windows issue in safeFilePutContents()
occasionally Windows will randomly decide to deny us access to rename the file for no reason whatsoever. If this happens, we attempt an old-style copy and delete.
If the rename failed for a legit reason, the copy and delete should also fail and generate an error message. If it was Windows being a spaz, it should work normally without errors.
2021-12-29 15:26:34 +00:00
fcc4757209 Merge branch 'legacy/pm3' into stable 2021-12-27 21:54:56 +00:00
d9c70cb176 start.cmd: prevent idiotic behaviour when paths contain characters such as brackets
god I hate this shit so much
2021-12-27 21:54:32 +00:00
4aab0565c0 ChunkCache: fixed corner case in cache restart on AsyncTask error
the cache may have been destroyed since the task inception, leading to an exception being thrown.
2021-12-27 18:11:55 +00:00
8943d8a2a7 Player: fixed maximum message size limits to match vanilla bugrock 2021-12-27 16:51:47 +00:00
0da29beb1d Bump pocketmine/locale-data from 2.2.0 to 2.2.1 (#4667)
Bumps [pocketmine/locale-data](https://github.com/pmmp/Language) from 2.2.0 to 2.2.1.
- [Release notes](https://github.com/pmmp/Language/releases)
- [Commits](https://github.com/pmmp/Language/compare/2.2.0...2.2.1)

---
updated-dependencies:
- dependency-name: pocketmine/locale-data
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-27 16:43:32 +00:00
157048264c Bump phpunit/phpunit from 9.5.10 to 9.5.11 (#4675)
Bumps [phpunit/phpunit](https://github.com/sebastianbergmann/phpunit) from 9.5.10 to 9.5.11.
- [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.10...9.5.11)

---
updated-dependencies:
- dependency-name: phpunit/phpunit
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-27 16:43:19 +00:00
b55aa78aec Changelog: Replaced non-existent method (#4676) 2021-12-27 15:33:02 +00:00
091673d8f1 Fixed "You can only sleep at night" message (#4671) 2021-12-23 23:52:07 +00:00
e3614d1a82 Entity: fixed game performance issue with large scale entities
this->size refers to the scaled height, but the client wants the base (unscaled) size in these properties.
This caused immense lag when, for example, setting the scale of a player to 10, because their collision box would become 180 by 60, instead of the expected 18 by 6.
2021-12-18 22:38:45 +00:00
93caf72f34 KickCommand: Add missing space
closes #4660
closes #4661
2021-12-17 21:09:14 +00:00
e6e1bca676 4.0.4 is next 2021-12-16 01:35:43 +00:00
795ebd1824 Release 4.0.3 2021-12-16 01:35:42 +00:00
5f03887b47 Merge branch 'legacy/pm3' into stable 2021-12-16 01:34:10 +00:00
9979a64ad2 3.26.5 is next 2021-12-16 01:23:22 +00:00
75a72786f9 Release 3.26.4 2021-12-16 01:23:21 +00:00
3d205c6e5f Updated transient dependency junk 2021-12-16 01:20:05 +00:00
2955a92837 Updated pocketmine/nbt to 0.2.19 2021-12-16 01:19:30 +00:00
e70f81a111 Updated pocketmine/nbt to 0.3.2 2021-12-16 01:08:23 +00:00
57e1509c3a Updated translation APIs 2021-12-15 03:24:13 +00:00
0da1810aaa Updated composer dependencies 2021-12-15 03:12:26 +00:00
4d37b79ff7 Server: fixed not being able to deop players whose names were added to ops.txt with uppercase letters in them
same as iTXTech/Genisys#1204

why didn't anyone report this???
2021-12-15 01:08:59 +00:00
ea1fceece2 Merge branch 'legacy/pm3' into stable 2021-12-14 23:15:53 +00:00
7fb1669c6d php-cs-fixer: added binary_operator_spaces and unary_operator_spaces rules 2021-12-14 23:14:39 +00:00
929abb04be Merge branch 'legacy/pm3' into stable 2021-12-14 22:54:17 +00:00
a09817864b php-cs-fixer: add return_type_declaration space_before 2021-12-14 22:50:43 +00:00
45c4a9673d Player: fixed arm swing animation not showing during attack cooldown of victim
closes #4650
2021-12-14 19:03:42 +00:00
4ad8cb02a5 BlockIdentifier: ensure that the tile class given is valid 2021-12-14 17:36:25 +00:00
7e6bbcc393 Sync composer deps 2021-12-14 01:27:11 +00:00
c334e6dec7 Updated locale-data dependency 2021-12-14 00:31:44 +00:00
89a766b799 Bump fgrosse/phpasn1 from 2.3.1 to 2.4.0 (#4644)
Bumps [fgrosse/phpasn1](https://github.com/fgrosse/PHPASN1) from 2.3.1 to 2.4.0.
- [Release notes](https://github.com/fgrosse/PHPASN1/releases)
- [Changelog](https://github.com/fgrosse/PHPASN1/blob/master/CHANGELOG.md)
- [Commits](https://github.com/fgrosse/PHPASN1/compare/v2.3.1...v2.4.0)

---
updated-dependencies:
- dependency-name: fgrosse/phpasn1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-13 21:39:44 +00:00
7e99e5167c Merge branch 'legacy/pm3' into stable 2021-12-13 12:36:26 +00:00
f5bbd30dbb Fixed skins appearing black when using RTX resource packs, closes #4537 2021-12-13 12:35:55 +00:00
3be8472ae2 MemoryManager: fixed dumping of uninitialized properties
closes #4643
2021-12-13 12:11:49 +00:00
22bb1ce8e0 4.0.3 is next 2021-12-12 23:27:54 +00:00
178dcb71a9 Release 4.0.2 2021-12-12 23:27:50 +00:00
0a58fd5472 GeneratorManager: fixed addGenerator() being case-sensitive when overwrite=true
this was caused by 083a1e1ff6.

This was discovered by a new PHPStan rule I'm working on, which disallows overwriting the values of parameter variables. During the refactor of this function to correct the error, another error appeared: Variable might not be defined.

This is yet another excellent example of why mutability is bad.
2021-12-12 21:58:07 +00:00
e06eefeab0 build/generate-known-translation-apis: fixed incorrect positional parameter order
closes #4639
2021-12-11 21:28:52 +00:00
ede07c4314 Mark KnownTranslationKeys and KnownTranslationFactory as @internal 2021-12-11 21:24:18 +00:00
cba00bf1e2 Merge branch 'stable' of github.com:pmmp/PocketMine-MP into stable 2021-12-10 23:24:38 +00:00
e81bee3866 ConsoleReaderThread: disable opcache for console reader subprocess 2021-12-10 23:24:18 +00:00
e6b85988b2 Bump fgrosse/phpasn1 from 2.3.0 to 2.3.1 (#4636)
Bumps [fgrosse/phpasn1](https://github.com/fgrosse/PHPASN1) from 2.3.0 to 2.3.1.
- [Release notes](https://github.com/fgrosse/PHPASN1/releases)
- [Changelog](https://github.com/fgrosse/PHPASN1/blob/master/CHANGELOG.md)
- [Commits](https://github.com/fgrosse/PHPASN1/compare/v2.3.0...v2.3.1)

---
updated-dependencies:
- dependency-name: fgrosse/phpasn1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-10 22:37:28 +00:00
b50591303b README: make shield show download count for 4.0.1, not 3.26.3 2021-12-10 20:23:48 +00:00
448f26cefc SimpleCommandMap: do not strip backslashes from unquoted command arguments 2021-12-10 18:27:49 +00:00
fa48100da5 PluginDescription: ensure base type of decoded document is actually an array
fixes #4628
2021-12-10 18:08:50 +00:00
bcf8a3424c Merge branch 'legacy/pm3' into stable 2021-12-10 18:02:06 +00:00
69d5bfa0d4 3.26.4 is next 2021-12-10 17:55:11 +00:00
549fb923bf Release 3.26.3 2021-12-10 17:55:07 +00:00
6d5c463bdd PlayerExperienceChangeEvent: added range checks to setNewProgress()
WE FINALLY FUCKING FOUND IT

This took several years to identify because PHP's exception stack traces don't show the actual values of parameters, but rather the values of the variables they were assigned to.

This means that if the parameter variable is mutated, the exception trace will show the value of the variable inside the function, not the value that was actually passed.
2021-12-10 17:29:57 +00:00
911ad344c9 Human: do not mutate parameter variables in setXpAndProgress()
this caused a mystery that took 3 entire years to debug.
2021-12-10 17:27:28 +00:00
3b77462935 WritableBookBase: fixed crash when finding pages containing corrupted UTF-8 characters
maybe we should treat this as corrupted? but for now, it's consistent with how we deal with signs.
2021-12-10 16:39:13 +00:00
6b40ed7bf8 Merge branch 'stable' of github.com:pmmp/PocketMine-MP into stable 2021-12-10 16:32:32 +00:00
1ed9302f5a ItemEntity: clone items given to the constructor directly
this fixes some bizarre mutability issues that occurred when using World->dropItem() with the same object multiple times.
2021-12-10 16:31:56 +00:00
b3dab0beef readme: added total downloads & latest downloads badges
[ci skip]
2021-12-10 00:40:29 +00:00
6ddaed97fa 4.0.2 is next 2021-12-09 00:48:45 +00:00
32 changed files with 272 additions and 99 deletions

View File

@ -18,6 +18,9 @@ return (new PhpCsFixer\Config)
'array_syntax' => [
'syntax' => 'short'
],
'binary_operator_spaces' => [
'default' => 'single_space'
],
'blank_line_after_namespace' => true,
'blank_line_after_opening_tag' => true,
'blank_line_before_statement' => [
@ -68,8 +71,12 @@ return (new PhpCsFixer\Config)
],
'phpdoc_trim' => true,
'phpdoc_trim_consecutive_blank_line_separation' => true,
'return_type_declaration' => [
'space_before' => 'one'
],
'single_import_per_statement' => true,
'strict_param' => true,
'unary_operator_spaces' => true,
])
->setFinder($finder)
->setIndent("\t")

View File

@ -8,6 +8,9 @@
<img alt="GitHub release (latest SemVer)" src="https://img.shields.io/github/v/release/pmmp/PocketMine-MP?label=release&sort=semver">
<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>
<br>
<img alt="GitHub all releases" src="https://img.shields.io/github/downloads/pmmp/PocketMine-MP/total?label=downloads%40total">
<img alt="GitHub release (latest by SemVer)" src="https://img.shields.io/github/downloads/pmmp/PocketMine-MP/latest/total?sort=semver">
</p>
## Getting started

View File

@ -41,6 +41,7 @@ use function preg_match_all;
use function str_replace;
use function strtoupper;
use const INI_SCANNER_RAW;
use const SORT_NUMERIC;
use const SORT_STRING;
use const STDERR;
@ -95,6 +96,8 @@ function generate_known_translation_keys(array $languageDefinitions) : void{
/**
* This class contains constants for all the translations known to PocketMine-MP as per the used version of pmmp/Language.
* This class is generated automatically, do NOT modify it by hand.
*
* @internal
*/
final class KnownTranslationKeys{
@ -127,6 +130,8 @@ function generate_known_translation_factory(array $languageDefinitions) : void{
* This class contains factory methods for all the translations known to PocketMine-MP as per the used version of
* pmmp/Language.
* This class is generated automatically, do NOT modify it by hand.
*
* @internal
*/
final class KnownTranslationFactory{
@ -138,15 +143,20 @@ HEADER;
$translationContainerClass = (new \ReflectionClass(Translatable::class))->getShortName();
foreach(Utils::stringifyKeys($languageDefinitions) as $key => $value){
$parameters = [];
$allParametersPositional = true;
if(preg_match_all($parameterRegex, $value, $matches) > 0){
foreach($matches[1] as $parameterName){
if(is_numeric($parameterName)){
$parameters[$parameterName] = "param$parameterName";
}else{
$parameters[$parameterName] = $parameterName;
$allParametersPositional = false;
}
}
}
if($allParametersPositional){
ksort($parameters, SORT_NUMERIC);
}
echo "\tpublic static function " .
functionify($key) .
"(" . implode(", ", array_map(fn(string $paramName) => "$translationContainerClass|string \$$paramName", $parameters)) . ") : $translationContainerClass{\n";

View File

@ -17,3 +17,12 @@ Plugin developers should **only** update their required API to this version if y
- Improved error messages shown by `start.cmd`, `start.sh` and `start.ps1` when the PHP binary was not found.
- The value of PHPRC is now shown when erroring out due to unsatisfied PHP requirements.
- Removed restriction on the range of valid channels for `auto-updater.channel` in `pocketmine.yml`.
# 3.26.3
- `PlayerExperienceChangeEvent->setNewProgress()` now performs range checks. This fixes the root of a very old and confusing crash bug which took several years to identify the cause of.
- Note that the defective plugin(s) which caused this problem will still cause a server crash, but the plugin responsible will now get blamed correctly.
# 3.26.4
- Fixed skins appearing black when using RTX resource packs.
- Fixed chunks containing furnaces in old worlds (pre-2017) being discarded as corrupted.
- This was caused by a strict corruption check detecting bad data created by a bug in PocketMine-MP that was fixed in 2017.

View File

@ -496,7 +496,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml`
- `Human->onPickupXp()` -> `ExperienceManager->onPickupXp()`
- `Human->resetXpCooldown()` -> `ExperienceManager->resetXpCooldown()`
- The following API methods have been removed:
- `Human->getRawUniqueId()`: use `Human->getUniqueId()->toBinary()` instead
- `Human->getRawUniqueId()`: use `Human->getUniqueId()->getBytes()` instead
- The following classes have been removed:
- `Creature`
- `Damageable`
@ -1547,3 +1547,47 @@ Released 9th December 2021.
- `Config->save()` will no longer write empty data to the file when using JSON and the data fails to encode - an exception will be thrown instead.
- `StringToItemParser` now returns the correct items for `bamboo`, `shulker_box`, `stone_slab`, `stone_stairs` and `tall_grass`.
- `StringToItemParser` now recognizes `slime` and `slime_block` (these were previously missing).
# 4.0.2
Released 12th December 2021.
## Fixes
### Core
- Fixed server crash when loading written books containing pages with invalid UTF-8 characters - the invalid characters are now scrubbed.
- Fixed server crash when root type of `plugin.yml` is valid, but not an array.
- Fixed ConsoleReader crash due OPcache ASLR issue - it's not clear what caused this, but OPcache is not needed in the subprocess anyway.
- Fixed backslashes getting stripped from unquoted command arguments - these were only supposed to be stripped from quoted arguments, to allow escaping of quotes.
- `build/generate-known-translation-apis.php` now sorts numerically-indexed arguments into ascending order, irrespective of the order they appear in the original string.
### API
- `KnownTranslationKeys` and `KnownTranslationFactory` are now marked `@internal`.
- `ItemEntity` now clones the itemstack passed to its constructor, fixing various confusing mutability issues.
- `PlayerExperienceChangeEvent->setNewProgress()` now performs range checks. This fixes the root of a very old and confusing crash bug which took several years to identify the cause of.
- Note that the defective plugin(s) which caused this problem will still cause a server crash, but the plugin responsible will now get blamed correctly.
- `GeneratorManager->addGenerator()` now consistently converts the given alias to lowercase. Due to a bug, it previously didn't do this if the `$overwrite` parameter was set to `true`, causing a range of confusing bugs.
# 4.0.3
Released 16th December 2021.
## Fixes
- Fixed `/dumpmemory` crashing when encountering uninitialized typed properties.
- Fixed all chunks containing furnaces being treated as corrupted in worlds older than 2017.
- This was caused by a strict corruption check detecting bad data created by a bug in PocketMine-MP that was fixed in 2017.
- Fixed player arm swing animation not being shown when attacks were cancelled by attack cooldown.
- Fixed being unable to use `/deop` to de-op a player whose name appeared in `ops.txt` with uppercase letters in it.
- Added a check for valid tile class in `BlockIdentifier`.
# 4.0.4
Released 1st January 2022.
## General
- Improved performance of loading chests and other containers from world saves.
- Improved performance of loading player inventories from saved data.
## Fixes
- Fixed a crash that could occur when a chunk failed to be prepared for chunk sending.
- Fixed fall damage when sprinting down stairs.
- Fixed message length limit for chat (now 512 instead of 255, and accounts for UTF-8).
- Fixed incorrect message being displayed when trying to sleep in a bed which is too far away.
- Fixed missing space between `Kicked by admin.` and `Reason` when using `/kick` to kick a player.
- Fixed client-side performance issue of entities with very large scale.

View File

@ -41,11 +41,11 @@
"pocketmine/classloader": "^0.2.0",
"pocketmine/color": "^0.2.0",
"pocketmine/errorhandler": "^0.3.0",
"pocketmine/locale-data": "^2.0.16",
"pocketmine/locale-data": "^2.1.0",
"pocketmine/log": "^0.4.0",
"pocketmine/log-pthreads": "^0.4.0",
"pocketmine/math": "^0.4.0",
"pocketmine/nbt": "^0.3.0",
"pocketmine/nbt": "^0.3.2",
"pocketmine/raklib": "^0.14.2",
"pocketmine/raklib-ipc": "^0.1.0",
"pocketmine/snooze": "^0.3.0",

88
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "b515e7eebbf12a6251d2df817ce56dbc",
"content-hash": "7e9247927fa23baf3e899811c8119f95",
"packages": [
{
"name": "adhocore/json-comment",
@ -123,24 +123,24 @@
},
{
"name": "fgrosse/phpasn1",
"version": "v2.3.0",
"version": "v2.4.0",
"source": {
"type": "git",
"url": "https://github.com/fgrosse/PHPASN1.git",
"reference": "20299033c35f4300eb656e7e8e88cf52d1d6694e"
"reference": "eef488991d53e58e60c9554b09b1201ca5ba9296"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/fgrosse/PHPASN1/zipball/20299033c35f4300eb656e7e8e88cf52d1d6694e",
"reference": "20299033c35f4300eb656e7e8e88cf52d1d6694e",
"url": "https://api.github.com/repos/fgrosse/PHPASN1/zipball/eef488991d53e58e60c9554b09b1201ca5ba9296",
"reference": "eef488991d53e58e60c9554b09b1201ca5ba9296",
"shasum": ""
},
"require": {
"php": ">=7.0.0"
"php": "~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0"
},
"require-dev": {
"phpunit/phpunit": "~6.3",
"satooshi/php-coveralls": "~2.0"
"php-coveralls/php-coveralls": "~2.0",
"phpunit/phpunit": "^6.3 || ^7.0 || ^8.0"
},
"suggest": {
"ext-bcmath": "BCmath is the fallback extension for big integer calculations",
@ -192,9 +192,9 @@
],
"support": {
"issues": "https://github.com/fgrosse/PHPASN1/issues",
"source": "https://github.com/fgrosse/PHPASN1/tree/v2.3.0"
"source": "https://github.com/fgrosse/PHPASN1/tree/v2.4.0"
},
"time": "2021-04-24T19:01:55+00:00"
"time": "2021-12-11T12:41:06+00:00"
},
{
"name": "netresearch/jsonmapper",
@ -275,16 +275,16 @@
},
{
"name": "pocketmine/bedrock-protocol",
"version": "7.0.0+bedrock-1.18.0",
"version": "7.1.0+bedrock-1.18.0",
"source": {
"type": "git",
"url": "https://github.com/pmmp/BedrockProtocol.git",
"reference": "040a883a4abb8c9b93114d5278cb5fecc635da82"
"reference": "42f2a00634c17c346fd98c05b2daf29d1fbf5805"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/040a883a4abb8c9b93114d5278cb5fecc635da82",
"reference": "040a883a4abb8c9b93114d5278cb5fecc635da82",
"url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/42f2a00634c17c346fd98c05b2daf29d1fbf5805",
"reference": "42f2a00634c17c346fd98c05b2daf29d1fbf5805",
"shasum": ""
},
"require": {
@ -316,9 +316,9 @@
"description": "An implementation of the Minecraft: Bedrock Edition protocol in PHP",
"support": {
"issues": "https://github.com/pmmp/BedrockProtocol/issues",
"source": "https://github.com/pmmp/BedrockProtocol/tree/7.0.0+bedrock-1.18.0"
"source": "https://github.com/pmmp/BedrockProtocol/tree/7.1.0+bedrock-1.18.0"
},
"time": "2021-11-30T19:02:41+00:00"
"time": "2021-12-15T03:07:05+00:00"
},
{
"name": "pocketmine/binaryutils",
@ -535,16 +535,16 @@
},
{
"name": "pocketmine/locale-data",
"version": "2.0.22",
"version": "2.2.1",
"source": {
"type": "git",
"url": "https://github.com/pmmp/Language.git",
"reference": "181eb9d42653296e65d55a1bbba10e0dd76bbd61"
"reference": "9fdd36f0ac3a2dfe1acacbee8b23eb6615129701"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/Language/zipball/181eb9d42653296e65d55a1bbba10e0dd76bbd61",
"reference": "181eb9d42653296e65d55a1bbba10e0dd76bbd61",
"url": "https://api.github.com/repos/pmmp/Language/zipball/9fdd36f0ac3a2dfe1acacbee8b23eb6615129701",
"reference": "9fdd36f0ac3a2dfe1acacbee8b23eb6615129701",
"shasum": ""
},
"type": "library",
@ -552,9 +552,9 @@
"description": "Language resources used by PocketMine-MP",
"support": {
"issues": "https://github.com/pmmp/Language/issues",
"source": "https://github.com/pmmp/Language/tree/2.0.22"
"source": "https://github.com/pmmp/Language/tree/2.2.1"
},
"time": "2021-12-04T22:37:10+00:00"
"time": "2021-12-17T23:42:12+00:00"
},
{
"name": "pocketmine/log",
@ -684,16 +684,16 @@
},
{
"name": "pocketmine/nbt",
"version": "0.3.1",
"version": "0.3.2",
"source": {
"type": "git",
"url": "https://github.com/pmmp/NBT.git",
"reference": "f43db89b8216b772407cdcedd90147db8eef34bc"
"reference": "3e0d9ef6b6c5fb45e3745a121296e75631b3eefe"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/NBT/zipball/f43db89b8216b772407cdcedd90147db8eef34bc",
"reference": "f43db89b8216b772407cdcedd90147db8eef34bc",
"url": "https://api.github.com/repos/pmmp/NBT/zipball/3e0d9ef6b6c5fb45e3745a121296e75631b3eefe",
"reference": "3e0d9ef6b6c5fb45e3745a121296e75631b3eefe",
"shasum": ""
},
"require": {
@ -702,10 +702,10 @@
"pocketmine/binaryutils": "^0.2.0"
},
"require-dev": {
"irstea/phpunit-shim": "^9.5",
"phpstan/extension-installer": "^1.0",
"phpstan/phpstan": "0.12.99",
"phpstan/phpstan-strict-rules": "^0.12.4"
"phpstan/phpstan": "1.2.0",
"phpstan/phpstan-strict-rules": "^1.0",
"phpunit/phpunit": "^9.5"
},
"type": "library",
"autoload": {
@ -720,9 +720,9 @@
"description": "PHP library for working with Named Binary Tags",
"support": {
"issues": "https://github.com/pmmp/NBT/issues",
"source": "https://github.com/pmmp/NBT/tree/0.3.1"
"source": "https://github.com/pmmp/NBT/tree/0.3.2"
},
"time": "2021-12-06T16:19:10+00:00"
"time": "2021-12-16T01:02:37+00:00"
},
{
"name": "pocketmine/raklib",
@ -1833,16 +1833,16 @@
},
{
"name": "phpspec/prophecy",
"version": "1.14.0",
"version": "v1.15.0",
"source": {
"type": "git",
"url": "https://github.com/phpspec/prophecy.git",
"reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e"
"reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e",
"reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13",
"reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13",
"shasum": ""
},
"require": {
@ -1894,9 +1894,9 @@
],
"support": {
"issues": "https://github.com/phpspec/prophecy/issues",
"source": "https://github.com/phpspec/prophecy/tree/1.14.0"
"source": "https://github.com/phpspec/prophecy/tree/v1.15.0"
},
"time": "2021-09-10T09:02:12+00:00"
"time": "2021-12-08T12:19:24+00:00"
},
{
"name": "phpstan/phpstan",
@ -2388,16 +2388,16 @@
},
{
"name": "phpunit/phpunit",
"version": "9.5.10",
"version": "9.5.11",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a"
"reference": "2406855036db1102126125537adb1406f7242fdd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c814a05837f2edb0d1471d6e3f4ab3501ca3899a",
"reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/2406855036db1102126125537adb1406f7242fdd",
"reference": "2406855036db1102126125537adb1406f7242fdd",
"shasum": ""
},
"require": {
@ -2475,11 +2475,11 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.10"
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.11"
},
"funding": [
{
"url": "https://phpunit.de/donate.html",
"url": "https://phpunit.de/sponsors.html",
"type": "custom"
},
{
@ -2487,7 +2487,7 @@
"type": "github"
}
],
"time": "2021-09-25T07:38:51+00:00"
"time": "2021-12-25T07:07:57+00:00"
},
{
"name": "sebastian/cli-parser",

View File

@ -325,6 +325,9 @@ class MemoryManager{
if(!$property->isPublic()){
$property->setAccessible(true);
}
if(!$property->isInitialized()){
continue;
}
$staticCount++;
$staticProperties[$className][$property->getName()] = self::continueDump($property->getValue(), $objects, $refCounts, 0, $maxNesting, $maxStringSize);
@ -448,6 +451,9 @@ class MemoryManager{
if(!$property->isPublic()){
$property->setAccessible(true);
}
if(!$property->isInitialized($object)){
continue;
}
$info["properties"][$name] = self::continueDump($property->getValue($object), $objects, $refCounts, 0, $maxNesting, $maxStringSize);
}

View File

@ -694,7 +694,13 @@ class Server{
}
public function removeOp(string $name) : void{
$this->operators->remove(strtolower($name));
$lowercaseName = strtolower($name);
foreach($this->operators->getAll() as $operatorName => $_){
$operatorName = (string) $operatorName;
if($lowercaseName === strtolower($operatorName)){
$this->operators->remove($operatorName);
}
}
if(($player = $this->getPlayerExact($name)) !== null){
$player->unsetBasePermission(DefaultPermissions::ROOT_OPERATOR);

View File

@ -31,7 +31,7 @@ use function str_repeat;
final class VersionInfo{
public const NAME = "PocketMine-MP";
public const BASE_VERSION = "4.0.1";
public const BASE_VERSION = "4.0.4";
public const IS_DEVELOPMENT_BUILD = false;
public const BUILD_CHANNEL = "stable";

View File

@ -145,7 +145,7 @@ class Bed extends Transparent{
$isNight = ($time >= World::TIME_NIGHT and $time < World::TIME_SUNRISE);
if(!$isNight){
$player->sendMessage(KnownTranslationFactory::tile_bed_tooFar()->prefix(TextFormat::GRAY));
$player->sendMessage(KnownTranslationFactory::tile_bed_noSleep()->prefix(TextFormat::GRAY));
return true;
}

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace pocketmine\block;
use pocketmine\block\tile\Tile;
use pocketmine\utils\Utils;
class BlockIdentifier{
@ -40,6 +41,10 @@ class BlockIdentifier{
$this->blockId = $blockId;
$this->variant = $variant;
$this->itemId = $itemId;
if($tileClass !== null){
Utils::testValidInstance($tileClass, Tile::class);
}
$this->tileClass = $tileClass;
}

View File

@ -48,11 +48,14 @@ trait ContainerTrait{
$inventory = $this->getRealInventory();
$listeners = $inventory->getListeners()->toArray();
$inventory->getListeners()->remove(...$listeners); //prevent any events being fired by initialization
$inventory->clearAll();
$newContents = [];
/** @var CompoundTag $itemNBT */
foreach($inventoryTag as $itemNBT){
$inventory->setItem($itemNBT->getByte("Slot"), Item::nbtDeserialize($itemNBT));
$newContents[$itemNBT->getByte("Slot")] = Item::nbtDeserialize($itemNBT);
}
$inventory->setContents($newContents);
$inventory->getListeners()->add(...$listeners);
}

View File

@ -206,7 +206,7 @@ class SimpleCommandMap implements CommandMap{
foreach($matches[0] as $k => $_){
for($i = 1; $i <= 2; ++$i){
if($matches[$i][$k] !== ""){
$args[$k] = stripslashes($matches[$i][$k]);
$args[$k] = $i === 1 ? stripslashes($matches[$i][$k]) : $matches[$i][$k];
break;
}
}

View File

@ -59,7 +59,7 @@ class KickCommand extends VanillaCommand{
$reason = trim(implode(" ", $args));
if(($player = $sender->getServer()->getPlayerByPrefix($name)) instanceof Player){
$player->kick("Kicked by admin." . ($reason !== "" ? "Reason: " . $reason : ""));
$player->kick("Kicked by admin." . ($reason !== "" ? " Reason: " . $reason : ""));
if($reason !== ""){
Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_kick_success_reason($player->getName(), $reason));
}else{

View File

@ -87,7 +87,7 @@ final class ConsoleReaderThread extends Thread{
//Windows sucks, and likes to corrupt UTF-8 file paths when they travel to the subprocess, so we base64 encode
//the path to avoid the problem. This is an abysmally shitty hack, but here we are :(
$sub = proc_open(
[PHP_BINARY, '-r', sprintf('require base64_decode("%s", true);', base64_encode(Path::join(__DIR__, 'ConsoleReaderChildProcess.php'))), $address],
[PHP_BINARY, '-dopcache.enable_cli=0', '-r', sprintf('require base64_decode("%s", true);', base64_encode(Path::join(__DIR__, 'ConsoleReaderChildProcess.php'))), $address],
[
2 => fopen("php://stderr", "w"),
],

View File

@ -832,10 +832,10 @@ abstract class Entity{
$diffZ = $z - $floorZ;
if($world->getBlockAt($floorX, $floorY, $floorZ)->isSolid()){
$westNonSolid = !$world->getBlockAt($floorX - 1, $floorY, $floorZ)->isSolid();
$eastNonSolid = !$world->getBlockAt($floorX + 1, $floorY, $floorZ)->isSolid();
$downNonSolid = !$world->getBlockAt($floorX, $floorY - 1, $floorZ)->isSolid();
$upNonSolid = !$world->getBlockAt($floorX, $floorY + 1, $floorZ)->isSolid();
$westNonSolid = !$world->getBlockAt($floorX - 1, $floorY, $floorZ)->isSolid();
$eastNonSolid = !$world->getBlockAt($floorX + 1, $floorY, $floorZ)->isSolid();
$downNonSolid = !$world->getBlockAt($floorX, $floorY - 1, $floorZ)->isSolid();
$upNonSolid = !$world->getBlockAt($floorX, $floorY + 1, $floorZ)->isSolid();
$northNonSolid = !$world->getBlockAt($floorX, $floorY, $floorZ - 1)->isSolid();
$southNonSolid = !$world->getBlockAt($floorX, $floorY, $floorZ + 1)->isSolid();
@ -1589,8 +1589,8 @@ abstract class Entity{
protected function syncNetworkData(EntityMetadataCollection $properties) : void{
$properties->setByte(EntityMetadataProperties::ALWAYS_SHOW_NAMETAG, $this->alwaysShowNameTag ? 1 : 0);
$properties->setFloat(EntityMetadataProperties::BOUNDING_BOX_HEIGHT, $this->size->getHeight());
$properties->setFloat(EntityMetadataProperties::BOUNDING_BOX_WIDTH, $this->size->getWidth());
$properties->setFloat(EntityMetadataProperties::BOUNDING_BOX_HEIGHT, $this->size->getHeight() / $this->scale);
$properties->setFloat(EntityMetadataProperties::BOUNDING_BOX_WIDTH, $this->size->getWidth() / $this->scale);
$properties->setFloat(EntityMetadataProperties::SCALE, $this->scale);
$properties->setLong(EntityMetadataProperties::LEAD_HOLDER_EID, -1);
$properties->setLong(EntityMetadataProperties::OWNER_EID, $this->ownerId ?? -1);
@ -1599,7 +1599,7 @@ abstract class Entity{
$properties->setString(EntityMetadataProperties::SCORE_TAG, $this->scoreTag);
$properties->setByte(EntityMetadataProperties::COLOR, 0);
$properties->setGenericFlag(EntityMetadataFlags::AFFECTED_BY_GRAVITY, true);
$properties->setGenericFlag(EntityMetadataFlags::AFFECTED_BY_GRAVITY, $this->gravityEnabled);
$properties->setGenericFlag(EntityMetadataFlags::CAN_CLIMB, $this->canClimb);
$properties->setGenericFlag(EntityMetadataFlags::CAN_SHOW_NAMETAG, $this->nameTagVisible);
$properties->setGenericFlag(EntityMetadataFlags::HAS_COLLISION, true);

View File

@ -27,7 +27,6 @@ use pocketmine\entity\utils\ExperienceUtils;
use pocketmine\event\player\PlayerExperienceChangeEvent;
use pocketmine\item\Durable;
use pocketmine\item\enchantment\VanillaEnchantments;
use pocketmine\utils\AssumptionFailedError;
use pocketmine\utils\Limits;
use pocketmine\world\sound\XpCollectSound;
use pocketmine\world\sound\XpLevelUpSound;
@ -36,7 +35,6 @@ use function ceil;
use function count;
use function max;
use function min;
use function sprintf;
class ExperienceManager{
@ -146,9 +144,6 @@ class ExperienceManager{
$xpLevel = (int) $newLevel;
$xpProgress = $newLevel - (int) $newLevel;
if($xpProgress > 1.0){
throw new AssumptionFailedError(sprintf("newLevel - (int) newLevel should never be bigger than 1, but have %.53f (newLevel=%.53f)", $xpProgress, $newLevel));
}
return $this->setXpAndProgress($xpLevel, $xpProgress);
}

View File

@ -217,6 +217,19 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
$this->uuid = Uuid::uuid3(Uuid::NIL, ((string) $this->getId()) . $this->skin->getSkinData() . $this->getNameTag());
}
/**
* @param Item[] $items
* @phpstan-param array<int, Item> $items
*/
private static function populateInventoryFromListTag(Inventory $inventory, array $items) : void{
$listeners = $inventory->getListeners()->toArray();
$inventory->getListeners()->clear();
$inventory->setContents($items);
$inventory->getListeners()->add(...$listeners);
}
protected function initEntity(CompoundTag $nbt) : void{
parent::initEntity($nbt);
@ -247,10 +260,8 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
$inventoryTag = $nbt->getListTag("Inventory");
if($inventoryTag !== null){
$armorListeners = $this->armorInventory->getListeners()->toArray();
$this->armorInventory->getListeners()->clear();
$inventoryListeners = $this->inventory->getListeners()->toArray();
$this->inventory->getListeners()->clear();
$inventoryItems = [];
$armorInventoryItems = [];
/** @var CompoundTag $item */
foreach($inventoryTag as $i => $item){
@ -258,14 +269,14 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
if($slot >= 0 and $slot < 9){ //Hotbar
//Old hotbar saving stuff, ignore it
}elseif($slot >= 100 and $slot < 104){ //Armor
$this->armorInventory->setItem($slot - 100, Item::nbtDeserialize($item));
$armorInventoryItems[$slot - 100] = Item::nbtDeserialize($item);
}elseif($slot >= 9 and $slot < $this->inventory->getSize() + 9){
$this->inventory->setItem($slot - 9, Item::nbtDeserialize($item));
$inventoryItems[$slot - 9] = Item::nbtDeserialize($item);
}
}
$this->armorInventory->getListeners()->add(...$armorListeners);
$this->inventory->getListeners()->add(...$inventoryListeners);
self::populateInventoryFromListTag($this->inventory, $inventoryItems);
self::populateInventoryFromListTag($this->armorInventory, $armorInventoryItems);
}
$offHand = $nbt->getCompoundTag("OffHandItem");
if($offHand !== null){
@ -279,10 +290,13 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
$enderChestInventoryTag = $nbt->getListTag("EnderChestInventory");
if($enderChestInventoryTag !== null){
$enderChestInventoryItems = [];
/** @var CompoundTag $item */
foreach($enderChestInventoryTag as $i => $item){
$this->enderInventory->setItem($item->getByte("Slot"), Item::nbtDeserialize($item));
$enderChestInventoryItems[$item->getByte("Slot")] = Item::nbtDeserialize($item);
}
self::populateInventoryFromListTag($this->enderInventory, $enderChestInventoryItems);
}
$this->inventory->setHeldItemIndex($nbt->getInt("SelectedInventorySlot", 0));

View File

@ -68,7 +68,7 @@ class ItemEntity extends Entity{
if($item->isNull()){
throw new \InvalidArgumentException("Item entity must have a non-air item with a count of at least 1");
}
$this->item = $item;
$this->item = clone $item;
parent::__construct($location, $nbt);
}

View File

@ -82,6 +82,9 @@ class PlayerExperienceChangeEvent extends EntityEvent implements Cancellable{
}
public function setNewProgress(?float $newProgress) : void{
if($newProgress < 0.0 || $newProgress > 1.0){
throw new \InvalidArgumentException("XP progress must be in range 0-1");
}
$this->newProgress = $newProgress;
}
}

View File

@ -71,10 +71,10 @@ class SimpleInventory extends BaseInventory{
protected function internalSetContents(array $items) : void{
for($i = 0, $size = $this->getSize(); $i < $size; ++$i){
if(!isset($items[$i])){
$this->clear($i);
if(!isset($items[$i]) || $items[$i]->isNull()){
$this->slots[$i] = null;
}else{
$this->setItem($i, $items[$i]);
$this->slots[$i] = clone $items[$i];
}
}
}

View File

@ -31,6 +31,7 @@ use function array_push;
use function array_slice;
use function array_values;
use function count;
use function mb_scrub;
abstract class WritableBookBase extends Item{
public const TAG_PAGES = "pages"; //TAG_List<TAG_Compound>
@ -168,12 +169,12 @@ abstract class WritableBookBase extends Item{
if($pages->getTagType() === NBT::TAG_Compound){ //PE format
/** @var CompoundTag $page */
foreach($pages as $page){
$this->pages[] = new WritableBookPage($page->getString(self::TAG_PAGE_TEXT), $page->getString(self::TAG_PAGE_PHOTONAME, ""));
$this->pages[] = new WritableBookPage(mb_scrub($page->getString(self::TAG_PAGE_TEXT), 'UTF-8'), $page->getString(self::TAG_PAGE_PHOTONAME, ""));
}
}elseif($pages->getTagType() === NBT::TAG_String){ //PC format
/** @var StringTag $page */
foreach($pages as $page){
$this->pages[] = new WritableBookPage($page->getValue());
$this->pages[] = new WritableBookPage(mb_scrub($page->getValue(), 'UTF-8'));
}
}
}

View File

@ -27,6 +27,8 @@ namespace pocketmine\lang;
* This class contains factory methods for all the translations known to PocketMine-MP as per the used version of
* pmmp/Language.
* This class is generated automatically, do NOT modify it by hand.
*
* @internal
*/
final class KnownTranslationFactory{
public static function ability_flight() : Translatable{
@ -242,10 +244,10 @@ final class KnownTranslationFactory{
return new Translatable(KnownTranslationKeys::COMMANDS_ENCHANT_USAGE, []);
}
public static function commands_gamemode_success_other(Translatable|string $param1, Translatable|string $param0) : Translatable{
public static function commands_gamemode_success_other(Translatable|string $param0, Translatable|string $param1) : Translatable{
return new Translatable(KnownTranslationKeys::COMMANDS_GAMEMODE_SUCCESS_OTHER, [
1 => $param1,
0 => $param0,
1 => $param1,
]);
}
@ -915,6 +917,12 @@ final class KnownTranslationFactory{
return new Translatable(KnownTranslationKeys::GAMEMODE_INFO, []);
}
public static function gamemode_options(Translatable|string $param0) : Translatable{
return new Translatable(KnownTranslationKeys::GAMEMODE_OPTIONS, [
0 => $param0,
]);
}
public static function invalid_port() : Translatable{
return new Translatable(KnownTranslationKeys::INVALID_PORT, []);
}
@ -2123,6 +2131,14 @@ final class KnownTranslationFactory{
return new Translatable(KnownTranslationKeys::SERVER_PORT, []);
}
public static function server_port_v4() : Translatable{
return new Translatable(KnownTranslationKeys::SERVER_PORT_V4, []);
}
public static function server_port_v6() : Translatable{
return new Translatable(KnownTranslationKeys::SERVER_PORT_V6, []);
}
public static function server_properties() : Translatable{
return new Translatable(KnownTranslationKeys::SERVER_PROPERTIES, []);
}
@ -2147,6 +2163,10 @@ final class KnownTranslationFactory{
return new Translatable(KnownTranslationKeys::TILE_BED_TOOFAR, []);
}
public static function view_distance() : Translatable{
return new Translatable(KnownTranslationKeys::VIEW_DISTANCE, []);
}
public static function welcome_to_pocketmine(Translatable|string $param0) : Translatable{
return new Translatable(KnownTranslationKeys::WELCOME_TO_POCKETMINE, [
0 => $param0,

View File

@ -26,6 +26,8 @@ namespace pocketmine\lang;
/**
* This class contains constants for all the translations known to PocketMine-MP as per the used version of pmmp/Language.
* This class is generated automatically, do NOT modify it by hand.
*
* @internal
*/
final class KnownTranslationKeys{
public const ABILITY_FLIGHT = "ability.flight";
@ -201,6 +203,7 @@ final class KnownTranslationKeys{
public const GAMEMODE_SPECTATOR = "gameMode.spectator";
public const GAMEMODE_SURVIVAL = "gameMode.survival";
public const GAMEMODE_INFO = "gamemode_info";
public const GAMEMODE_OPTIONS = "gamemode_options";
public const INVALID_PORT = "invalid_port";
public const IP_CONFIRM = "ip_confirm";
public const IP_GET = "ip_get";
@ -440,12 +443,15 @@ final class KnownTranslationKeys{
public const QUERY_WARNING1 = "query_warning1";
public const QUERY_WARNING2 = "query_warning2";
public const SERVER_PORT = "server_port";
public const SERVER_PORT_V4 = "server_port_v4";
public const SERVER_PORT_V6 = "server_port_v6";
public const SERVER_PROPERTIES = "server_properties";
public const SETTING_UP_SERVER_NOW = "setting_up_server_now";
public const SKIP_INSTALLER = "skip_installer";
public const TILE_BED_NOSLEEP = "tile.bed.noSleep";
public const TILE_BED_OCCUPIED = "tile.bed.occupied";
public const TILE_BED_TOOFAR = "tile.bed.tooFar";
public const VIEW_DISTANCE = "view_distance";
public const WELCOME_TO_POCKETMINE = "welcome_to_pocketmine";
public const WHITELIST_ENABLE = "whitelist_enable";
public const WHITELIST_INFO = "whitelist_info";

View File

@ -128,10 +128,12 @@ class ChunkCache implements ChunkListener{
$chunk,
$this->caches[$chunkHash],
$this->compressor,
function() use ($chunkX, $chunkZ) : void{
function() use ($chunkHash, $chunkX, $chunkZ) : void{
$this->world->getLogger()->error("Failed preparing chunk $chunkX $chunkZ, retrying");
$this->restartPendingRequest($chunkX, $chunkZ);
if(isset($this->caches[$chunkHash])){
$this->restartPendingRequest($chunkX, $chunkZ);
}
}
)
);

View File

@ -134,6 +134,7 @@ use function floor;
use function get_class;
use function is_int;
use function max;
use function mb_strlen;
use function microtime;
use function min;
use function preg_match;
@ -1080,6 +1081,10 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
$bb->minY = $this->location->y - 0.2;
$bb->maxY = $this->location->y + 0.2;
//we're already at the new position at this point; check if there are blocks we might have landed on between
//the old and new positions (running down stairs necessitates this)
$bb = $bb->addCoord(-$dx, -$dy, -$dz);
$this->onGround = $this->isCollided = count($this->getWorld()->getCollisionBlocks($bb, true)) > 0;
}
}
@ -1320,7 +1325,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
$message = TextFormat::clean($message, false);
foreach(explode("\n", $message) as $messagePart){
if(trim($messagePart) !== "" and strlen($messagePart) <= 255 and $this->messageCounter-- > 0){
if(trim($messagePart) !== "" and strlen($messagePart) <= 512 * 4 and mb_strlen($messagePart, 'UTF-8') <= 512 and $this->messageCounter-- > 0){
if(strpos($messagePart, './') === 0){
$messagePart = substr($messagePart, 1);
}
@ -1667,13 +1672,13 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
}
$entity->attack($ev);
$this->broadcastAnimation(new ArmSwingAnimation($this), $this->getViewers());
$soundPos = $entity->getPosition()->add(0, $entity->size->getHeight() / 2, 0);
if($ev->isCancelled()){
$this->getWorld()->addSound($soundPos, new EntityAttackNoDamageSound());
return false;
}
$this->broadcastAnimation(new ArmSwingAnimation($this), $this->getViewers());
$this->getWorld()->addSound($soundPos, new EntityAttackSound());
if($ev->getModifier(EntityDamageEvent::MODIFIER_CRITICAL) > 0 and $entity instanceof Living){

View File

@ -28,6 +28,7 @@ use pocketmine\permission\PermissionParser;
use pocketmine\permission\PermissionParserException;
use function array_map;
use function array_values;
use function get_debug_type;
use function is_array;
use function is_string;
use function preg_match;
@ -85,7 +86,18 @@ class PluginDescription{
* @param string|mixed[] $yamlString
*/
public function __construct($yamlString){
$this->loadMap(!is_array($yamlString) ? yaml_parse($yamlString) : $yamlString);
if(is_string($yamlString)){
$map = yaml_parse($yamlString);
if($map === false){
throw new PluginDescriptionParseException("YAML parsing error in plugin manifest");
}
if(!is_array($map)){
throw new PluginDescriptionParseException("Invalid structure of plugin manifest, expected array but have " . get_debug_type($map));
}
}else{
$map = $yamlString;
}
$this->loadMap($map);
}
/**

View File

@ -341,14 +341,14 @@ class Config{
$this->config[$base] = [];
}
$base =& $this->config[$base];
$base = &$this->config[$base];
while(count($vars) > 0){
$baseKey = array_shift($vars);
if(!isset($base[$baseKey])){
$base[$baseKey] = [];
}
$base =& $base[$baseKey];
$base = &$base[$baseKey];
}
$base = $value;
@ -393,14 +393,14 @@ class Config{
$vars = explode(".", $key);
$currentNode =& $this->config;
$currentNode = &$this->config;
while(count($vars) > 0){
$nodeName = array_shift($vars);
if(isset($currentNode[$nodeName])){
if(count($vars) === 0){ //final node
unset($currentNode[$nodeName]);
}elseif(is_array($currentNode[$nodeName])){
$currentNode =& $currentNode[$nodeName];
$currentNode = &$currentNode[$nodeName];
}
}else{
break;

View File

@ -265,12 +265,33 @@ final class Filesystem{
throw new \RuntimeException("Failed to write to temporary file $temporaryFileName (possibly out of free disk space)");
}
//TODO: the @ prevents us receiving the actual error message, but right now it's necessary since we can't assume
//that the error handler has been set :(
$renameTemporaryFileResult = $context !== null ?
rename($temporaryFileName, $fileName, $context) :
rename($temporaryFileName, $fileName);
@rename($temporaryFileName, $fileName, $context) :
@rename($temporaryFileName, $fileName);
if(!$renameTemporaryFileResult){
throw new \RuntimeException("Failed to move temporary file contents into target file");
/*
* The following code works around a bug in Windows where rename() will periodically decide to give us a
* spurious "Access is denied (code: 5)" error. As far as I could determine, the fault comes from Windows
* itself, but since I couldn't reliably reproduce the issue it's very hard to debug.
*
* The following code can be used to test. Usually it will fail anywhere before 100,000 iterations.
*
* for($i = 0; $i < 10_000_000; ++$i){
* file_put_contents('ops.txt.0.tmp', 'some data ' . $i, 0);
* if(!rename('ops.txt.0.tmp', 'ops.txt')){
* throw new \Error("something weird happened");
* }
* }
*/
$copyTemporaryFileResult = $context !== null ?
copy($temporaryFileName, $fileName, $context) :
copy($temporaryFileName, $fileName);
if(!$copyTemporaryFileResult){
throw new \RuntimeException("Failed to move temporary file contents into target file");
}
@unlink($temporaryFileName);
}
}
}

View File

@ -72,7 +72,8 @@ final class GeneratorManager{
public function addGenerator(string $class, string $name, \Closure $presetValidator, bool $overwrite = false) : void{
Utils::testValidInstance($class, Generator::class);
if(!$overwrite and isset($this->list[$name = strtolower($name)])){
$name = strtolower($name);
if(!$overwrite and isset($this->list[$name])){
throw new \InvalidArgumentException("Alias \"$name\" is already assigned");
}

View File

@ -16,7 +16,7 @@ if exist bin\php\php.exe (
)
if "%PHP_BINARY%"=="" (
echo Couldn't find a PHP binary in system PATH or %~dp0\bin\php
echo Couldn't find a PHP binary in system PATH or "%~dp0bin\php"
echo Please refer to the installation instructions at https://doc.pmmp.io/en/rtfd/installation.html
pause
exit 1