mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-11 12:08:05 +00:00
Compare commits
262 Commits
5.0.0-ALPH
...
5.0.0-ALPH
Author | SHA1 | Date | |
---|---|---|---|
da4315df05 | |||
83bfe790fa | |||
16f90f4120 | |||
ec59dc1c80 | |||
973b8130db | |||
99faeb8d05 | |||
1305fd5fb2 | |||
7a137f932f | |||
63e8b1cf3a | |||
65bce762ff | |||
529700bb8b | |||
f38b15cf83 | |||
0efd928db6 | |||
9809909072 | |||
de3af9e660 | |||
a30c649607 | |||
d7ebabd771 | |||
be1087c071 | |||
b27c47335c | |||
58eec637c1 | |||
4f86ea9933 | |||
6e2685cbbb | |||
b2017c8462 | |||
bf44edd179 | |||
44e288554a | |||
ffa88aff67 | |||
aa374083d8 | |||
1785cbb6b5 | |||
3d75094874 | |||
8c0d3943d8 | |||
d02c6668b2 | |||
880d01daea | |||
50b70708fb | |||
ba4d038972 | |||
437fa615b8 | |||
0ee6cdb058 | |||
97d6a79b25 | |||
8b5e4c1c16 | |||
c5d716dc9d | |||
4d79aced07 | |||
95d0a3bf41 | |||
cf707e15c2 | |||
1308cda5c2 | |||
214a5ddc15 | |||
9f7dfe3355 | |||
9b55d18393 | |||
84f9136b95 | |||
31465525e3 | |||
74613b9b09 | |||
1cefe24414 | |||
4357c110c8 | |||
8bf85d4a18 | |||
b5e6dec0c6 | |||
a3306914cc | |||
3b32ea1b0b | |||
7ec32f981e | |||
b0c87e9d06 | |||
99996b62d6 | |||
fed2a6d917 | |||
8e600b4a78 | |||
1d4b6dc66e | |||
1cb6d9f5af | |||
18c2e90574 | |||
142ccc7e87 | |||
174c9a48f5 | |||
0a9b52618d | |||
7ae6425d05 | |||
b5cfab497d | |||
ca3b5c38b7 | |||
bc8def3be1 | |||
774e23137e | |||
3984d220bb | |||
43bc3c7b25 | |||
eb62dc3294 | |||
28d8526d8d | |||
0b497654f2 | |||
279056fe2f | |||
cd233b123b | |||
64dd5e3bf6 | |||
4e5cc57560 | |||
d476a4c1aa | |||
95263795a8 | |||
2db86d151f | |||
8f20b9da91 | |||
b0c6e8d8e0 | |||
f0358b09b7 | |||
80a432d9ff | |||
ec9f9a469f | |||
d450264e1c | |||
5e92f55d35 | |||
58c1bfe5d2 | |||
d03caafc2b | |||
641d35a30f | |||
642630a4d2 | |||
b6982a84ef | |||
d634b3de18 | |||
d79e6354a0 | |||
ff63983de4 | |||
588215044e | |||
5c1e9a35a9 | |||
aad9f5fb45 | |||
a8dca190c6 | |||
fdb07cdbcd | |||
3b6ff3c42b | |||
e5f5fe80f9 | |||
36ab34df29 | |||
23ae0c7cac | |||
1bc5e225ab | |||
dda8ff18b1 | |||
6562335120 | |||
0c463a8721 | |||
a66f966b08 | |||
cca22046ab | |||
858d3dce8e | |||
d19f0bf7be | |||
ff2391e74a | |||
39e10da88d | |||
34839da757 | |||
b3b8516661 | |||
90305a0b92 | |||
613ce251c5 | |||
beed6efd4e | |||
e5bc4deb12 | |||
2fcff13578 | |||
b4b8ef1c6b | |||
9650b7f03a | |||
a205d64732 | |||
a3502a711d | |||
83ddcce987 | |||
732dac6fc1 | |||
d5e3636908 | |||
ef100b248b | |||
d03bbb0426 | |||
93e661aa4e | |||
50efcf7424 | |||
a7ac6070dc | |||
069062f122 | |||
bf7014e0ec | |||
824ed0a56a | |||
b3ccf41307 | |||
a39938e6b6 | |||
d5bf88acc0 | |||
2d0602d19f | |||
1a5cc8212c | |||
3a2a23b236 | |||
1a8c8af523 | |||
1e9d83f014 | |||
68e862b6fa | |||
c915334c2b | |||
6153a2ac70 | |||
ed452b9ccd | |||
c19880e045 | |||
01bad344a0 | |||
cdbdcb5d67 | |||
29301614e8 | |||
2fdc46c165 | |||
bfd1b2c635 | |||
d9638cef96 | |||
1671405cd0 | |||
fe982c697b | |||
1572b31b8d | |||
fba4895a17 | |||
b6f6671a81 | |||
6da467b142 | |||
44af519cd6 | |||
fb31e6085e | |||
e4548da173 | |||
0d5287bf0b | |||
a9361b3f8b | |||
6e4c62744e | |||
9a0ead6deb | |||
d74824c8d5 | |||
d4eb73abe9 | |||
d1d5020c53 | |||
9f6c6b2b71 | |||
bd01a919e5 | |||
7864294336 | |||
2a910c1cc2 | |||
cd04a3db2e | |||
572def9245 | |||
20f5bed926 | |||
14d17a9546 | |||
b74c092d9b | |||
53cae8911d | |||
7bcc663b60 | |||
b3bda788d9 | |||
2cc8a56e68 | |||
b70f7afbd6 | |||
92783a6db9 | |||
57deb60355 | |||
92e47b98f8 | |||
b84c110819 | |||
e1b0e00c6f | |||
774df0fa4c | |||
f88ae93897 | |||
4fadb63f67 | |||
c83f0896ac | |||
0d29a138fb | |||
421379fc77 | |||
293cea7714 | |||
15645759e9 | |||
8dc0d506f4 | |||
8c651ce4b4 | |||
db7cee6f22 | |||
6ae7cb288e | |||
7df2719fce | |||
10b8dcfdd1 | |||
c1fbac412e | |||
3feaa18f6c | |||
1c6a2b66f7 | |||
41970feb57 | |||
0edf2ea6a4 | |||
cd4bb91676 | |||
2be527060f | |||
6f68c6d8a0 | |||
ac16378410 | |||
1f9dfa77bf | |||
0c7f8470b9 | |||
fc56c041f3 | |||
d6bbf8217d | |||
22486dd75e | |||
37ec1193ea | |||
1366a43c22 | |||
383dc2a2b9 | |||
bda0ca23b4 | |||
b21cd82e94 | |||
1c7b1e9e5d | |||
4b41b2f9ae | |||
b87e4d8bd3 | |||
a6cc611e9f | |||
86a2f8e360 | |||
def2f8c145 | |||
6f4ea886b0 | |||
ed7c95549d | |||
cfb0cad7e0 | |||
83e5b0adb6 | |||
4650a3bb22 | |||
5e5661de75 | |||
e2f1b10165 | |||
455f9fa92e | |||
dec188d4ad | |||
2db3498891 | |||
ab0202ba29 | |||
9295afe8b9 | |||
a7dfa0907c | |||
f448b2e685 | |||
6a0c54f850 | |||
77a18d0aea | |||
140a809c40 | |||
cb7c136035 | |||
1bc8fb1851 | |||
f6a9949942 | |||
18c9ccb01c | |||
83a136a176 | |||
3f7d8a3777 | |||
3c55db531d | |||
93d4475111 | |||
e4fc523251 | |||
7804172846 | |||
7d29ac8293 | |||
481bda8cd5 | |||
d1c75da14b |
8
.github/workflows/build-docker-image.yml
vendored
8
.github/workflows/build-docker-image.yml
vendored
@ -46,7 +46,7 @@ jobs:
|
||||
run: echo ::set-output name=NAME::$(echo "${GITHUB_REPOSITORY,,}")
|
||||
|
||||
- name: Build image for tag
|
||||
uses: docker/build-push-action@v3.1.1
|
||||
uses: docker/build-push-action@v3.2.0
|
||||
with:
|
||||
push: true
|
||||
context: ./pocketmine-mp
|
||||
@ -59,7 +59,7 @@ jobs:
|
||||
|
||||
- name: Build image for major tag
|
||||
if: steps.channel.outputs.CHANNEL == 'stable'
|
||||
uses: docker/build-push-action@v3.1.1
|
||||
uses: docker/build-push-action@v3.2.0
|
||||
with:
|
||||
push: true
|
||||
context: ./pocketmine-mp
|
||||
@ -72,7 +72,7 @@ jobs:
|
||||
|
||||
- name: Build image for minor tag
|
||||
if: steps.channel.outputs.CHANNEL == 'stable'
|
||||
uses: docker/build-push-action@v3.1.1
|
||||
uses: docker/build-push-action@v3.2.0
|
||||
with:
|
||||
push: true
|
||||
context: ./pocketmine-mp
|
||||
@ -85,7 +85,7 @@ jobs:
|
||||
|
||||
- name: Build image for latest tag
|
||||
if: steps.channel.outputs.CHANNEL == 'stable'
|
||||
uses: docker/build-push-action@v3.1.1
|
||||
uses: docker/build-push-action@v3.2.0
|
||||
with:
|
||||
push: true
|
||||
context: ./pocketmine-mp
|
||||
|
2
.github/workflows/discord-release-notify.yml
vendored
2
.github/workflows/discord-release-notify.yml
vendored
@ -13,7 +13,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup PHP and tools
|
||||
uses: shivammathur/setup-php@2.21.2
|
||||
uses: shivammathur/setup-php@2.22.0
|
||||
with:
|
||||
php-version: 8.0
|
||||
|
||||
|
4
.github/workflows/draft-release.yml
vendored
4
.github/workflows/draft-release.yml
vendored
@ -18,7 +18,7 @@ jobs:
|
||||
submodules: true
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@2.21.2
|
||||
uses: shivammathur/setup-php@2.22.0
|
||||
with:
|
||||
php-version: 8.0
|
||||
|
||||
@ -69,7 +69,7 @@ jobs:
|
||||
${{ github.workspace }}/build_info.json
|
||||
|
||||
- name: Create draft release
|
||||
uses: ncipollo/release-action@v1.10.0
|
||||
uses: ncipollo/release-action@v1.12.0
|
||||
with:
|
||||
artifacts: ${{ github.workspace }}/PocketMine-MP.phar,${{ github.workspace }}/start.*,${{ github.workspace }}/build_info.json
|
||||
commit: ${{ github.sha }}
|
||||
|
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
@ -198,7 +198,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup PHP and tools
|
||||
uses: shivammathur/setup-php@2.21.2
|
||||
uses: shivammathur/setup-php@2.22.0
|
||||
with:
|
||||
php-version: 8.0
|
||||
tools: php-cs-fixer:3.11
|
||||
|
2
.github/workflows/support.yml
vendored
2
.github/workflows/support.yml
vendored
@ -8,7 +8,7 @@ jobs:
|
||||
support:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dessant/support-requests@v2
|
||||
- uses: dessant/support-requests@v3
|
||||
with:
|
||||
github-token: ${{ github.token }}
|
||||
support-label: "Support request"
|
||||
|
5
.idea/codeStyles/Project.xml
generated
5
.idea/codeStyles/Project.xml
generated
@ -62,6 +62,11 @@
|
||||
<option name="USE_TAB_CHARACTER" value="true" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="Shell Script">
|
||||
<indentOptions>
|
||||
<option name="USE_TAB_CHARACTER" value="true" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="neon">
|
||||
<indentOptions>
|
||||
<option name="USE_TAB_CHARACTER" value="true" />
|
||||
|
@ -66,6 +66,9 @@ BODY,
|
||||
],
|
||||
'indentation_type' => true,
|
||||
'logical_operators' => true,
|
||||
'native_constant_invocation' => [
|
||||
'scope' => 'namespaced'
|
||||
],
|
||||
'native_function_invocation' => [
|
||||
'scope' => 'namespaced',
|
||||
'include' => ['@all'],
|
||||
@ -92,6 +95,12 @@ BODY,
|
||||
],
|
||||
'sort_algorithm' => 'alpha'
|
||||
],
|
||||
'phpdoc_align' => [
|
||||
'align' => 'vertical',
|
||||
'tags' => [
|
||||
'param',
|
||||
]
|
||||
],
|
||||
'phpdoc_line_span' => [
|
||||
'property' => 'single',
|
||||
'method' => null,
|
||||
|
@ -18,6 +18,32 @@ Larger contributions like feature additions should be preceded by a [Change Prop
|
||||
## Other things you'll need
|
||||
- [git](https://git-scm.com/)
|
||||
|
||||
## Choosing a target branch
|
||||
PocketMine-MP has three primary branches of development.
|
||||
|
||||
| Type of change | `stable` | `next-minor` | `next-major` |
|
||||
|:---------------|:--------:|:------------:|:------------:|
|
||||
| Bug fixes | ✔️ | ✔️ | ✔️ |
|
||||
| Improvements to API docs | ✔️ | ✔️ | ✔️ |
|
||||
| Cleaning up code | ❌ | ✔️ | ✔️ |
|
||||
| Changing code formatting or style | ❌ | ✔️ | ✔️ |
|
||||
| Addition of new core features | ❌ | 🟡 Only if non-disruptive | ✔️ |
|
||||
| Changing core behaviour (e.g. making something use threads) | ❌ | ✔️ | ✔️ |
|
||||
| Addition of new configuration options | ❌ | 🟡 Only if optional | ✔️ |
|
||||
| Addition of new API classes, methods or constants | ❌ | ✔️ | ✔️ |
|
||||
| Deprecating API classes, methods or constants | ❌ | ✔️ | ✔️ |
|
||||
| Adding optional parameters to an API method | ❌ | ✔️ | ✔️ |
|
||||
| Changing API behaviour | ❌ | 🟡 Only if backwards-compatible | ✔️ |
|
||||
| Removal of API | ❌ | ❌ | ✔️ |
|
||||
| Backwards-incompatible API change (e.g. renaming a method) | ❌ | ❌ | ✔️ |
|
||||
|
||||
### Notes
|
||||
- **Non-disruptive** means that usage should not be significantly altered by the change.
|
||||
- Examples of **non-disruptive** changes include adding new commands, or gameplay features like blocks and items.
|
||||
- Examples of **disruptive** changes include changing the way the server is run, world format changes (since those require downtime for the user to convert their world).
|
||||
- **API** includes all public and protected classes, functions and constants (unless marked as `@internal`).
|
||||
- Private members are not part of the API, **unless in a trait**.
|
||||
|
||||
## Making a pull request
|
||||
The basic procedure to create a pull request is:
|
||||
1. [Fork the repository on GitHub](https://github.com/pmmp/PocketMine-MP/fork). This gives you your own copy of the repository to make changes to.
|
||||
|
@ -48,6 +48,8 @@ use function sort;
|
||||
use function strrpos;
|
||||
use function strtoupper;
|
||||
use function substr;
|
||||
use const SORT_STRING;
|
||||
use const STDERR;
|
||||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
|
@ -36,6 +36,8 @@ use function file_get_contents;
|
||||
use function fopen;
|
||||
use function fwrite;
|
||||
use function strtoupper;
|
||||
use const SORT_STRING;
|
||||
use const STDERR;
|
||||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
|
@ -25,7 +25,7 @@ namespace pocketmine\build\generate_known_translation_apis;
|
||||
|
||||
use pocketmine\lang\Translatable;
|
||||
use pocketmine\utils\Utils;
|
||||
use Webmozart\PathUtil\Path;
|
||||
use Symfony\Component\Filesystem\Path;
|
||||
use function array_map;
|
||||
use function count;
|
||||
use function dirname;
|
||||
|
@ -39,6 +39,7 @@ use function sprintf;
|
||||
use function str_replace;
|
||||
use function substr;
|
||||
use const SORT_STRING;
|
||||
use const STDERR;
|
||||
|
||||
if(count($argv) !== 2){
|
||||
fwrite(STDERR, "Provide a path to process\n");
|
||||
|
@ -48,6 +48,7 @@ use function lcfirst;
|
||||
use function log;
|
||||
use function ob_get_clean;
|
||||
use function ob_start;
|
||||
use const SORT_STRING;
|
||||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
|
Submodule build/php updated: cf79c01722...6b605ed7c4
@ -40,12 +40,13 @@ use function rtrim;
|
||||
use function sprintf;
|
||||
use function str_replace;
|
||||
use function unlink;
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
use const PHP_EOL;
|
||||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
/**
|
||||
* @param string[] $strings
|
||||
* @param string[] $strings
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
|
53
changelogs/4.10.md
Normal file
53
changelogs/4.10.md
Normal file
@ -0,0 +1,53 @@
|
||||
**For Minecraft: Bedrock Edition 1.19.40**
|
||||
|
||||
### Note about API versions
|
||||
Plugins which don't touch the protocol and compatible with any previous 4.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.
|
||||
|
||||
# 4.10.0
|
||||
Released 26th October 2022.
|
||||
|
||||
## General
|
||||
- Added support for Minecraft: Bedrock Edition 1.19.40.
|
||||
- Removed support for older versions.
|
||||
|
||||
## Fixes
|
||||
- Fixed incorrect command descriptions showing in `/help` when multiple commands use the same name. Previously, the most recently registered command would show, even though it wouldn't actually be invoked.
|
||||
- Fixed splash potions affecting players in spectator mode.
|
||||
- Fixed `World->addParticle()` sending particles to players who couldn't possibly see them when a list of targets was used.
|
||||
- Fixed `World->addSound()` sending sounds to players who couldn't possibly hear them when a list of targets was used.
|
||||
|
||||
## Documentation
|
||||
- Improved type information available for various API methods in `World`.
|
||||
|
||||
# 4.10.1
|
||||
Released 7th November 2022.
|
||||
|
||||
## Fixes
|
||||
- Fixed spawning in the void if spawn terrain in a world is solid at the default spawn position.
|
||||
- Fixed totems of undying activating when the player has 1 HP remaining.
|
||||
- Fixed durable items such as tools becoming unbreakable when in stacks larger than 1. Now, the durability correctly resets when the tool breaks.
|
||||
- TPS below 12 now correctly shows as red in `/status`. Previously, it showed as orange due to a condition ordering bug.
|
||||
- Improved handling of missing arguments in user-defined `pocketmine.yml` command aliases. Previously, missing arguments would be filled with an empty string, which caused a variety of unexpected behaviour.
|
||||
|
||||
## Internals
|
||||
- Added validation for the array given to `BaseInventory->setContents()` to ensure that it contains only `Item` instances.
|
||||
- Silenced `PlayerAuthInputPacket` spam when the session is in the "spawn response" state.
|
||||
- Updated to PHPStan 1.9.
|
||||
|
||||
# 4.10.2
|
||||
Released 25th November 2022.
|
||||
|
||||
## Fixes
|
||||
- Fixed crashes on macOS and Linux when using console colours without the `TERM` environment variable set.
|
||||
- Fixed crashdumps not being generated when error messages contained invalid UTF-8 characters.
|
||||
|
||||
## Documentation
|
||||
- Clarified documentation of caching behaviour for `Internet::getIP()`.
|
||||
- Added and improved documentation for many `Inventory` methods.
|
||||
- Rewritten documentation for `PlayerCreationEvent` with warnings and more detail.
|
||||
|
||||
## Internals
|
||||
- Non-arrow projectile damage is now unscaled. Scaling according to velocity is only applied to arrows. This currently doesn't cause any observable change in behaviour, but is required for future additions.
|
92
changelogs/4.11-beta.md
Normal file
92
changelogs/4.11-beta.md
Normal file
@ -0,0 +1,92 @@
|
||||
**For Minecraft: Bedrock Edition 1.19.40**
|
||||
|
||||
This is a minor feature release for PocketMine-MP, introducing some new features and improvements.
|
||||
|
||||
### Note about API versions
|
||||
Plugins which don't touch the protocol and compatible with any previous 4.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.
|
||||
|
||||
# 4.11.0-BETA1
|
||||
Released 7th November 2022.
|
||||
|
||||
## General
|
||||
- Packet receive timings have now been split into two subcategories - Decode and Handle.
|
||||
- Console command entry can now be disabled via the `console.enable-input` setting in `pocketmine.yml`.
|
||||
- Best suited for headless servers (e.g. in a Docker container) where the console will never be used anyway.
|
||||
- Disabling the console reader slightly reduces memory usage, because console reading currently requires an additional subprocess.
|
||||
- Console command output now appears on the terminal only, and is not written to the log file.
|
||||
- The output from console commands now appears with a `Command output |` prefix, instead of as a log message.
|
||||
- Introduced validation for the `--data` and `--plugins` command line options.
|
||||
- Encrypted resource packs are now supported, by means of adding a `.key` file alongside the pack in the `resource_packs` folder.
|
||||
- e.g. `MyEncryptedPack.zip` -> `MyEncryptedPack.zip.key`
|
||||
|
||||
## Gameplay
|
||||
- Fixed supporting blocks of dead bush to be in line with vanilla.
|
||||
- Sugarcane can now be grown using bonemeal on any part of the sugarcane. Previously, it only worked when used on the bottom block.
|
||||
- Fixed modifier values for Instant Damage and Regeneration effects.
|
||||
|
||||
## API
|
||||
### General
|
||||
- Plugins are now always disabled before their dependencies, to ensure that they are able to shutdown properly (e.g. a core plugin depending on a database plugin may want to save data to a DB during `onDisable()`).
|
||||
- [`webmozart/path-util`](https://packagist.org/packages/webmozart/path-util) has been deprecated, and will be dropped in favour of [`symfony/filesystem`](https://packagist.org/packages/symfony/filesystem) in PM5.
|
||||
- To prepare for this change, simply replace any usage of `Webmozart\PathUtil\Path` with `Symfony\Component\Filesystem\Path`, which is available as a dependency in this release.
|
||||
|
||||
### `pocketmine`
|
||||
- The following API methods are now deprecated:
|
||||
- `Server->getPlayerByPrefix()`
|
||||
|
||||
### `pocketmine\entity`
|
||||
- `EntitySpawnEvent` and `ItemSpawnEvent` are now fired on the first tick after the entity is added to the world. Previously, these events were called directly from the entity constructor, making it impossible to get properties like velocity which are often set after the entity is created.
|
||||
- The following API methods are now deprecated:
|
||||
- `Living->hasLineOfSight()`
|
||||
|
||||
### `pocketmine\item`
|
||||
- The following new API methods have been added:
|
||||
- `public Armor->clearCustomColor() : $this`
|
||||
|
||||
### `pocketmine\inventory\transaction`
|
||||
- Introduced a `TransactionBuilder` class. This makes it less of a hassle to build an `InventoryTransaction` server-side, since the regular `Inventory` API methods can be used, rather than having to manually create `SlotChangeAction`s.
|
||||
|
||||
### `pocketmine\player`
|
||||
- The following new API methods have been added:
|
||||
- `public Player->sendToastNotification(string $title, string $body) : void` - makes a grey box appear at the top of the player's screen containing the specified message
|
||||
|
||||
### `pocketmine\utils`
|
||||
- The following new API methods have been added:
|
||||
- `public static TextFormat::addBase(string $baseFormat, string $string) : string` - used for coloured log messages, changes the base formatting of a string by inserting the given formatting codes after every RESET code
|
||||
|
||||
## Internals
|
||||
- Improved performance of `ContainerTrait` dropping items on block destroy. (24e72ec109c1442b09558df89b6833cf2f2e0ec7)
|
||||
- Avoid repeated calls to `Position->getWorld()` (use local variables). (2940547026db40ce76deb46e992870de3ead79ad)
|
||||
- Revamped the way `InventoryManager` handles fake inventory slot mappings for stuff like crafting tables. (e90abecf38d9c57635fa0497514bba7e546a2469)
|
||||
- Console polling is now done on the main thread (no longer a performance concern).
|
||||
- Console reader subprocess should now automatically die if the server main process is killed, instead of persisting as a zombie.
|
||||
- `ConsoleCommandSender` is no longer responsible for relaying broadcast messages to `MainLogger`. A new `BroadcastLoggerForwarder` has been added, which is subscribed to the appropriate server broadcast channels in order to relay messages. This ensures that chat messages and command audit messages are logged.
|
||||
- `DelegateInventory` now uses `WeakReference` to track its inventory listener. This allows the delegate to be reused.
|
||||
|
||||
# 4.11.0-BETA2
|
||||
Released 13th November 2022.
|
||||
|
||||
## Configuration
|
||||
- The `chunk-ticking.per-tick` setting is now deprecated, and will be removed in a future release.
|
||||
- The functionality of this setting has been removed, since it caused more problems than it solved.
|
||||
- Setting it to zero will still disable chunk ticking (for now), but this should now be done by setting `chunk-ticking.tick-radius` to `0` instead.
|
||||
|
||||
## Gameplay
|
||||
- Improved chunk random ticking:
|
||||
- Removed the limit on chunks ticked per tick, and its associated config option is no longer respected.
|
||||
- This change significantly improves crop and plant growth with large numbers of players, but may cause higher CPU usage.
|
||||
- This limit was causing a linear decrease in chunk ticking speed with larger numbers of players, leading to worsened gameplay experience.
|
||||
- Every chunk within the configured tick radius of a player will be ticked. Previously, chunks were randomly selected from the radius.
|
||||
- Implemented Darkness effect.
|
||||
|
||||
## API
|
||||
### `pocketmine\world`
|
||||
- The following new API methods have been added:
|
||||
- `public World->getChunkTickRadius() : int` - returns the world's simulation radius
|
||||
- `public World->setChunkTickRadius(int $radius) : void` - sets the world's simulation radius
|
||||
|
||||
## Internals
|
||||
- Non-arrow projectile damage is now unscaled. Scaling according to velocity is only applied to arrows. This currently doesn't cause any observable change in behaviour, but is required for future additions.
|
106
changelogs/4.11.md
Normal file
106
changelogs/4.11.md
Normal file
@ -0,0 +1,106 @@
|
||||
**For Minecraft: Bedrock Edition 1.19.40**
|
||||
|
||||
This is a minor feature release for PocketMine-MP, introducing some new features and improvements.
|
||||
|
||||
### Note about API versions
|
||||
Plugins which don't touch the protocol and compatible with any previous 4.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.
|
||||
|
||||
# 4.11.0
|
||||
Released 25th November 2022.
|
||||
|
||||
## General
|
||||
- Packet receive timings have now been split into two subcategories - Decode and Handle.
|
||||
- Console command entry can now be disabled via the `console.enable-input` setting in `pocketmine.yml`.
|
||||
- Best suited for headless servers (e.g. in a Docker container) where the console will never be used anyway.
|
||||
- Disabling the console reader slightly reduces memory usage, because console reading currently requires an additional subprocess.
|
||||
- Console command output now appears on the terminal only, and is not written to the log file.
|
||||
- The output from console commands now appears with a `Command output |` prefix, instead of as a log message.
|
||||
- User-defined `pocketmine.yml` custom commands now use a generic description which makes clear the command is config-defined.
|
||||
- Introduced validation for the `--data` and `--plugins` command line options.
|
||||
- Encrypted resource packs are now supported, by means of adding a `.key` file alongside the pack in the `resource_packs` folder.
|
||||
- e.g. `MyEncryptedPack.zip` -> `MyEncryptedPack.zip.key`
|
||||
- The file must contain the raw key bytes, and must not end with a newline.
|
||||
|
||||
## Configuration
|
||||
- The `chunk-ticking.per-tick` setting is now deprecated, and will be removed in a future release.
|
||||
- The functionality of this setting has been removed, since it caused more problems than it solved.
|
||||
- Setting it to zero will still disable chunk ticking (for now), but this should now be done by setting `chunk-ticking.tick-radius` to `0` instead.
|
||||
|
||||
## Gameplay
|
||||
- Fixed supporting blocks of dead bush to be in line with vanilla.
|
||||
- Sugarcane can now be grown using bonemeal on any part of the sugarcane. Previously, it only worked when used on the bottom block.
|
||||
- Fixed missing sounds when adding, rotating, or removing items in item frames.
|
||||
- Fixed modifier values for Instant Damage and Regeneration effects.
|
||||
- Implemented Darkness effect.
|
||||
- Improved chunk random ticking:
|
||||
- Removed the limit on chunks ticked per tick, and its associated config option is no longer respected.
|
||||
- This change significantly improves crop and plant growth with large numbers of players.
|
||||
- This limit was causing a linear decrease in chunk ticking speed with larger numbers of players, leading to worsened gameplay experience.
|
||||
- **Warning: This change will result in increased CPU usage if players are spread over a very large area.**
|
||||
- Every chunk within the configured tick radius of a player will be ticked. Previously, chunks were randomly selected from the radius.
|
||||
|
||||
## API
|
||||
### General
|
||||
- Plugins are now always disabled before their dependencies, to ensure that they are able to shutdown properly (e.g. a core plugin depending on a database plugin may want to save data to a DB during `onDisable()`).
|
||||
- [`webmozart/path-util`](https://packagist.org/packages/webmozart/path-util) has been deprecated, and will be dropped in favour of [`symfony/filesystem`](https://packagist.org/packages/symfony/filesystem) in PM5.
|
||||
- To prepare for this change, simply replace any usage of `Webmozart\PathUtil\Path` with `Symfony\Component\Filesystem\Path`, which is available as a dependency in this release.
|
||||
|
||||
### `pocketmine`
|
||||
- The following API methods are now deprecated:
|
||||
- `Server->getPlayerByPrefix()`
|
||||
|
||||
### `pocketmine\entity`
|
||||
- `EntitySpawnEvent` and `ItemSpawnEvent` are now fired on the first tick after the entity is added to the world. Previously, these events were called directly from the entity constructor, making it impossible to get properties like velocity which are often set after the entity is created.
|
||||
- The following API methods are now deprecated:
|
||||
- `Living->hasLineOfSight()`
|
||||
|
||||
### `pocketmine\event\block`
|
||||
- The following new classes have been added:
|
||||
- `BlockDeathEvent` - event called when coral or coral blocks die due to lack of water
|
||||
|
||||
### `pocketmine\item`
|
||||
- The following new API methods have been added:
|
||||
- `public Armor->clearCustomColor() : $this`
|
||||
|
||||
### `pocketmine\inventory\transaction`
|
||||
- Introduced a `TransactionBuilder` class. This makes it less of a hassle to build an `InventoryTransaction` server-side, since the regular `Inventory` API methods can be used, rather than having to manually create `SlotChangeAction`s.
|
||||
|
||||
### `pocketmine\lang`
|
||||
- The following new API methods have been added:
|
||||
- `public Language->getAll() : array<string, string>`
|
||||
|
||||
### `pocketmine\player`
|
||||
- The following new API methods have been added:
|
||||
- `public Player->sendToastNotification(string $title, string $body) : void` - makes a grey box appear at the top of the player's screen containing the specified message
|
||||
|
||||
### `pocketmine\utils`
|
||||
- The following new API methods have been added:
|
||||
- `public static TextFormat::addBase(string $baseFormat, string $string) : string` - used for coloured log messages, changes the base formatting of a string by inserting the given formatting codes after every RESET code
|
||||
|
||||
### `pocketmine\world`
|
||||
- The following new API methods have been added:
|
||||
- `public World->getChunkTickRadius() : int` - returns the world's simulation radius
|
||||
- `public World->setChunkTickRadius(int $radius) : void` - sets the world's simulation radius
|
||||
|
||||
### `pocketmine\world\sound`
|
||||
- The following new classes have been added:
|
||||
- `ItemFrameAddItemSound`
|
||||
- `ItemFrameRemoveItemSound`
|
||||
- `ItemFrameRotateItemSound`
|
||||
|
||||
## Internals
|
||||
- Improved performance of `ContainerTrait` dropping items on block destroy. ([link](https://github.com/pmmp/PocketMine-MP/commits/24e72ec109c1442b09558df89b6833cf2f2e0ec7))
|
||||
- Avoid repeated calls to `Position->getWorld()` (use local variables). ([link](https://github.com/pmmp/PocketMine-MP/commit/2940547026db40ce76deb46e992870de3ead79ad))
|
||||
- Revamped the way `InventoryManager` handles fake inventory slot mappings for stuff like crafting tables. ([link](https://github.com/pmmp/PocketMine-MP/commit/e90abecf38d9c57635fa0497514bba7e546a2469))
|
||||
- Inventories are now mapped on a per-slot basis. This means that more than one inventory can be mapped to the same window ID, which is necessary for correctly handling "UI" inventories like crafting tables.
|
||||
- `InventoryManager->getWindow(int $windowId) : ?Inventory` is replaced by `locateWindowAndSlot` (see below).
|
||||
- Added `InventoryManager->locateWindowAndSlot(int $windowId, int $netSlotId) : array{Inventory, int}` - accepts a window ID and absolute slot ID, and returns the associated inventory and the slot relative to the inventory's own start (for use with `getItem()` etc.).
|
||||
- Slot offset mapping for "UI" inventories is now handled in `InventoryManager->createComplexSlotMapping()` instead of in `TypeConverter`.
|
||||
- Console polling is now done on the main thread (no longer a performance concern). ([link](https://github.com/pmmp/PocketMine-MP/commit/b3f03d7ae645de67a54b7300c09b94eeca16298e))
|
||||
- Console reader subprocess should now automatically die if the server main process is killed, instead of persisting as a zombie. ([link](https://github.com/pmmp/PocketMine-MP/commit/2585160ca2c4df5758b8b980331307402ff9f0fb))
|
||||
- `ConsoleCommandSender` is no longer responsible for relaying broadcast messages to `MainLogger`. A new `BroadcastLoggerForwarder` has been added, which is subscribed to the appropriate server broadcast channels in order to relay messages. This ensures that chat messages and command audit messages are logged. ([link](https://github.com/pmmp/PocketMine-MP/commit/83e5b0adb6fa0dddec377182bb1c7945ac8f7820))
|
||||
- `DelegateInventory` now uses `WeakReference` to track its inventory listener. This allows the delegate to be reused. ([link](https://github.com/pmmp/PocketMine-MP/commit/3feaa18f6c10c3a99c0deca75f57ec2d74b92ab4))
|
||||
- Non-arrow projectile damage is now unscaled. Scaling according to velocity is only applied to arrows. This currently doesn't cause any observable change in behaviour, but is required for future additions.
|
32
changelogs/4.12.md
Normal file
32
changelogs/4.12.md
Normal file
@ -0,0 +1,32 @@
|
||||
**For Minecraft: Bedrock Edition 1.19.50**
|
||||
|
||||
### Note about API versions
|
||||
Plugins which don't touch the protocol and compatible with any previous 4.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.
|
||||
|
||||
# 4.12.0
|
||||
Released 30th November 2022.
|
||||
|
||||
## General
|
||||
- Added support for Minecraft: Bedrock Edition 1.19.50.
|
||||
- Removed support for older versions.
|
||||
|
||||
# 4.12.1
|
||||
Released 4th December 2022.
|
||||
|
||||
## Fixes
|
||||
- Fixed items glitching when dragging a stack of items across the crafting grid (desync issues).
|
||||
|
||||
# 4.12.2
|
||||
Released 15th December 2022.
|
||||
|
||||
## Fixes
|
||||
- Folder used for plugins (optionally specified by `--plugins`) is no longer required to be writable.
|
||||
- Fixed broken writable check for server data folder (`is_writable()` broken on NFS and similar filesystems).
|
||||
- `Filesystem::createLockFile()` exceptions now include more information about why the lock file could not be created.
|
||||
- Fixed client-side item predictions not being rolled back when cancelling events such as `PlayerItemUseEvent`.
|
||||
|
||||
## Dependencies
|
||||
- Updated BedrockProtocol to [17.1.0](https://github.com/pmmp/BedrockProtocol/releases/tag/17.1.0+bedrock-1.19.50). This adds some missing `LevelSoundEvent` constants and fixes the values for `ContainerUIIds`.
|
@ -12,3 +12,25 @@ Released 20th September 2022.
|
||||
## General
|
||||
- Added support for Minecraft: Bedrock Edition 1.19.30.
|
||||
- Removed support for older versions.
|
||||
|
||||
# 4.9.1
|
||||
Released 11th October 2022.
|
||||
|
||||
## Documentation
|
||||
- Added and improved documentation for many API methods in `Player` and `Block`.
|
||||
- Added missing `@internal` tag for `TaskHandler->setNextRun()`, `TaskHandler->remove()` and `TaskHandler->run()`.
|
||||
|
||||
## Fixes
|
||||
- Flight state is now locked by the server in spectator mode. This prevents any attempt by the client to toggle flight mode.
|
||||
- Fixed entity health exceeding its max health after the expiry of Health Boost effect.
|
||||
- Fixed burp sound not being played when a player eats food.
|
||||
- Fixed placement conditions for mushrooms - they can now only be placed when the light level at the target is <= 12, or on podzol or mycelium.
|
||||
- Fixed sign text appearing to change colour and/or glow when using dye on a sign - since this feature is not yet implemented, no change should occur.
|
||||
- Fixed players drowning when sprint-swimming on the surface of water.
|
||||
|
||||
## Internals
|
||||
- Added more detailed debug logging during the player login sequence.
|
||||
- Silenced debug spam during `PreSpawnPacketHandler`, considerably reducing debug noise when players join.
|
||||
- Fixed an edge case in `InventoryManager->removeWindow()`. This bug didn't have any effect on stable versions, but caused a `next-minor` development version to crash.
|
||||
- `Item`s returned by event getters are now cloned if modifying the result will have no useful side effects.
|
||||
- Updated `pocketmine/bedrock-data` to [`1.11.1`](https://github.com/pmmp/BedrockData/tree/1.11.1%2Bbedrock-1.19.30), which reduces bandwidth consumption during logins by not sending useless biome generation data.
|
||||
|
@ -618,3 +618,122 @@ Released 24th September 2022.
|
||||
### Effects
|
||||
- Updated damage modifier amounts for Instant Damage to be more in line with vanilla.
|
||||
- Updated duration modifier amounts for Regeneration to be more like vanilla.
|
||||
|
||||
# 5.0.0-ALPHA5
|
||||
Released 13th November 2022.
|
||||
|
||||
**This release includes changes from [4.11.0-BETA2](https://github.com/pmmp/PocketMine-MP/releases/4.11.0-BETA2) and earlier, which may not be listed here.**
|
||||
|
||||
## General
|
||||
- Added support for Minecraft: Bedrock 1.19.40.
|
||||
- Removed support for earlier versions.
|
||||
|
||||
## API
|
||||
### `pocketmine\block`
|
||||
- `FallableTrait` now includes a default implementation of `tickFalling()`.
|
||||
|
||||
### `pocketmine\event`
|
||||
- The following API methods have been removed:
|
||||
- `PlayerCommandPreprocessEvent`
|
||||
- The following API methods have been added:
|
||||
- `public DataPacketSendEvent->setPackets(list<ClientboundPacket> $packets) : void`
|
||||
|
||||
## Gameplay
|
||||
### General
|
||||
- Fixed dyeing leather armour in cauldrons.
|
||||
|
||||
### Blocks
|
||||
- Copper blocks now play the correct scrape sound when using an axe on them.
|
||||
|
||||
## Internals
|
||||
- Moved command timings to `Timings`.
|
||||
|
||||
# 5.0.0-ALPHA6
|
||||
Released 19th December 2022.
|
||||
|
||||
**This release includes changes from the following releases, which may not be mentioned:**
|
||||
- [4.10.2](https://github.com/pmmp/PocketMine-MP/releases/tag/4.10.2)
|
||||
- [4.11.0](https://github.com/pmmp/PocketMine-MP/releases/tag/4.11.0)
|
||||
- [4.12.0](https://github.com/pmmp/PocketMine-MP/releases/tag/4.12.0)
|
||||
- [4.12.1](https://github.com/pmmp/PocketMine-MP/releases/tag/4.12.1)
|
||||
- [4.12.2](https://github.com/pmmp/PocketMine-MP/releases/tag/4.12.2)
|
||||
|
||||
## General
|
||||
- Fixed the Bedrock client asking to upgrade worlds exported from PocketMine-MP to Bedrock (missing level.dat fields).
|
||||
- Added support for 1.19.40 and newer Bedrock worlds.
|
||||
- Commands are now enabled by default in worlds exported from PocketMine-MP to Bedrock.
|
||||
|
||||
## Gameplay
|
||||
### Blocks
|
||||
- Added the following new blocks:
|
||||
- Twisting Vines
|
||||
- Weeping Vines
|
||||
- Anvils are now damaged when they hit the ground after falling.
|
||||
- Added missing sounds for anvils hitting the ground after falling.
|
||||
- Fixed missing sounds when a projectile strikes an amethyst block.
|
||||
- Fixed some blocks being incorrectly able to be placed on top of a candle cake.
|
||||
|
||||
### Items
|
||||
- Added the following new items:
|
||||
- Music Disc (5)
|
||||
- Music Disc (Otherside)
|
||||
- Music Disc (Pigstep)
|
||||
- Implemented Swift Sneak enchantment.
|
||||
- Armour durability is now only reduced when the wearer receives a type of damage that the armour can protect against.
|
||||
|
||||
## API
|
||||
### General
|
||||
- Union and mixed native parameter, return and property types are now used where appropriate.
|
||||
|
||||
### `pocketmine\block`
|
||||
- The following new API methods have been added:
|
||||
- `public Furnace->getType() : utils\FurnaceType`
|
||||
- The following interfaces have new requirements:
|
||||
- `utils\Fallable` now requires `onHitGround()` to be implemented (although filled by default implementation in `FallableTrait`).
|
||||
- `utils\Fallable` now requires `getLandSound()` to be implemented (although filled by default implementation in `FallableTrait`).
|
||||
- The following new API constants have been added:
|
||||
- `public BlockTypeTags::FIRE` - used by fire and soul fire
|
||||
|
||||
### `pocketmine\crafting`
|
||||
- The `$type` parameter of `ShapelessRecipe->__construct()` is now mandatory.
|
||||
|
||||
### `pocketmine\entity`
|
||||
- The following new API methods have been added:
|
||||
- `public Living->getDisplayName() : string`
|
||||
- The following API methods have changed signatures:
|
||||
- `EntityFactory->register()` no longer accepts a `$legacyMcpeSaveId` parameter (now handled by internal conversions instead).
|
||||
|
||||
### `pocketmine\event`
|
||||
- The following classes have been renamed:
|
||||
- `entity\ExplosionPrimeEvent` -> `entity\EntityPreExplodeEvent`
|
||||
- The following new classes have been added:
|
||||
- `world\WorldParticleEvent` - called when a particle is spawned in a world
|
||||
- `world\WorldSoundEvent` - called when a sound is played in a world
|
||||
- The following API methods have changed signatures:
|
||||
- `entity\EntityPreExplodeEvent->__construct()` has the `$force` parameter renamed to `$radius`
|
||||
- `entity\EntityPreExplodeEvent->getForce() : float` -> `entity\EntityPreExplodeEvent->getRadius() : float`
|
||||
- `entity\EntityPreExplodeEvent->setForce(float $force) : void` -> `entity\EntityPreExplodeEvent->setRadius(float $radius) : void`
|
||||
|
||||
### `pocketmine\item`
|
||||
- The following new API methods have been added:
|
||||
- `public Item->keepOnDeath() : bool` - returns whether this item will be retained when a player carrying it dies
|
||||
- `public Item->onInteractEntity(Player $player, Entity $entity, Vector3 $clickPos) : bool` - called when a player interacts with an entity with this item in their hand
|
||||
- `public Item->setKeepOnDeath(bool $keepOnDeath) : void` - sets whether this item will be retained when a player carrying it dies
|
||||
- `public StringToItemParser->lookupAliases(Item $item) : list<string>` - returns a list of all registered aliases for the given item
|
||||
- `public StringToItemParser->lookupBlockAliases(Block $block) : list<string>` - returns a list of all registered aliases for the given block
|
||||
|
||||
### `pocketmine\resourcepacks`
|
||||
- The following new API methods have been added:
|
||||
- `public ResourcePackManager->setPackEncryptionKey(string $id, ?string $key) : void` - sets the encryption key to be used for the resource pack identified by the given UUID
|
||||
- `public ResourcePackManager->setResourceStack(list<ResourcePack> $resourceStack) : void` - sets the resource stack to be used by the server
|
||||
|
||||
### `pocketmine\world`
|
||||
- The following API methods have changed signatures:
|
||||
- `Explosion->__construct()` has the `$size` parameter renamed to `$radius`
|
||||
- The following public properties have been renamed:
|
||||
- `Explosion->size` -> `Explosion->radius`
|
||||
|
||||
## Internals
|
||||
- `EntityLegacyIds` has been removed. Legacy entity IDs found during world loading are now converted via `LegacyEntityIdToStringIdMap`.
|
||||
- All usages of NBT keys now use class constants instead of hardcoded strings (except for an occasional overlooked one).
|
||||
- All members of `BlockTypeTags` now have a `pocketmine:` prefix on the value. This does not affect constant usages.
|
||||
|
@ -37,13 +37,13 @@
|
||||
"pocketmine/bedrock-block-upgrade-schema": "dev-master@dev",
|
||||
"pocketmine/bedrock-data": "dev-modern-world-support@dev",
|
||||
"pocketmine/bedrock-item-upgrade-schema": "dev-master",
|
||||
"pocketmine/bedrock-protocol": "~13.0.0+bedrock-1.19.30",
|
||||
"pocketmine/bedrock-protocol": "~17.1.0+bedrock-1.19.50",
|
||||
"pocketmine/binaryutils": "^0.2.1",
|
||||
"pocketmine/callback-validator": "^1.0.2",
|
||||
"pocketmine/classloader": "^0.2.0",
|
||||
"pocketmine/color": "^0.2.0",
|
||||
"pocketmine/errorhandler": "^0.6.0",
|
||||
"pocketmine/locale-data": "~2.8.0 <2.8.9",
|
||||
"pocketmine/locale-data": "~2.11.0",
|
||||
"pocketmine/log": "^0.4.0",
|
||||
"pocketmine/log-pthreads": "^0.4.0",
|
||||
"pocketmine/math": "^0.4.0",
|
||||
@ -52,10 +52,10 @@
|
||||
"pocketmine/raklib-ipc": "^0.1.0",
|
||||
"pocketmine/snooze": "^0.3.0",
|
||||
"ramsey/uuid": "^4.1",
|
||||
"webmozart/path-util": "^2.3"
|
||||
"symfony/filesystem": "^5.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "1.8.5",
|
||||
"phpstan/phpstan": "1.9.4",
|
||||
"phpstan/phpstan-phpunit": "^1.1.0",
|
||||
"phpstan/phpstan-strict-rules": "^1.2.0",
|
||||
"phpunit/phpunit": "^9.2"
|
||||
|
620
composer.lock
generated
620
composer.lock
generated
@ -4,20 +4,20 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "284e89a86c5b7fdb4d97ec5516666b36",
|
||||
"content-hash": "2d4da4bb4787764fbe706a04311c3cbf",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/json-comment",
|
||||
"version": "1.1.2",
|
||||
"version": "1.2.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/adhocore/php-json-comment.git",
|
||||
"reference": "fc2f76979f0a44a5f5bc2a2b600d0762fe0e78e7"
|
||||
"reference": "651023f9fe52e9efa2198cbaf6e481d1968e2377"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/adhocore/php-json-comment/zipball/fc2f76979f0a44a5f5bc2a2b600d0762fe0e78e7",
|
||||
"reference": "fc2f76979f0a44a5f5bc2a2b600d0762fe0e78e7",
|
||||
"url": "https://api.github.com/repos/adhocore/php-json-comment/zipball/651023f9fe52e9efa2198cbaf6e481d1968e2377",
|
||||
"reference": "651023f9fe52e9efa2198cbaf6e481d1968e2377",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -51,15 +51,19 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/adhocore/php-json-comment/issues",
|
||||
"source": "https://github.com/adhocore/php-json-comment/tree/1.1.2"
|
||||
"source": "https://github.com/adhocore/php-json-comment/tree/1.2.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://paypal.me/ji10",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/adhocore",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-04-09T03:06:06+00:00"
|
||||
"time": "2022-10-02T11:22:07+00:00"
|
||||
},
|
||||
{
|
||||
"name": "brick/math",
|
||||
@ -119,24 +123,24 @@
|
||||
},
|
||||
{
|
||||
"name": "fgrosse/phpasn1",
|
||||
"version": "v2.4.0",
|
||||
"version": "v2.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/fgrosse/PHPASN1.git",
|
||||
"reference": "eef488991d53e58e60c9554b09b1201ca5ba9296"
|
||||
"reference": "42060ed45344789fb9f21f9f1864fc47b9e3507b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/fgrosse/PHPASN1/zipball/eef488991d53e58e60c9554b09b1201ca5ba9296",
|
||||
"reference": "eef488991d53e58e60c9554b09b1201ca5ba9296",
|
||||
"url": "https://api.github.com/repos/fgrosse/PHPASN1/zipball/42060ed45344789fb9f21f9f1864fc47b9e3507b",
|
||||
"reference": "42060ed45344789fb9f21f9f1864fc47b9e3507b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0"
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"php-coveralls/php-coveralls": "~2.0",
|
||||
"phpunit/phpunit": "^6.3 || ^7.0 || ^8.0"
|
||||
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-bcmath": "BCmath is the fallback extension for big integer calculations",
|
||||
@ -188,22 +192,23 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/fgrosse/PHPASN1/issues",
|
||||
"source": "https://github.com/fgrosse/PHPASN1/tree/v2.4.0"
|
||||
"source": "https://github.com/fgrosse/PHPASN1/tree/v2.5.0"
|
||||
},
|
||||
"time": "2021-12-11T12:41:06+00:00"
|
||||
"abandoned": true,
|
||||
"time": "2022-12-19T11:08:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "netresearch/jsonmapper",
|
||||
"version": "v4.0.0",
|
||||
"version": "v4.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/cweiske/jsonmapper.git",
|
||||
"reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d"
|
||||
"reference": "cfa81ea1d35294d64adb9c68aa4cb9e92400e53f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d",
|
||||
"reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d",
|
||||
"url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/cfa81ea1d35294d64adb9c68aa4cb9e92400e53f",
|
||||
"reference": "cfa81ea1d35294d64adb9c68aa4cb9e92400e53f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -239,9 +244,9 @@
|
||||
"support": {
|
||||
"email": "cweiske@cweiske.de",
|
||||
"issues": "https://github.com/cweiske/jsonmapper/issues",
|
||||
"source": "https://github.com/cweiske/jsonmapper/tree/v4.0.0"
|
||||
"source": "https://github.com/cweiske/jsonmapper/tree/v4.1.0"
|
||||
},
|
||||
"time": "2020-12-01T19:48:11+00:00"
|
||||
"time": "2022-12-08T20:46:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/bedrock-block-upgrade-schema",
|
||||
@ -276,12 +281,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/BedrockData.git",
|
||||
"reference": "1ca9241ce66358cdfb2dbde65d609eb9c185c515"
|
||||
"reference": "d64617faab77300d828debcd1e3597b3403b63b7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockData/zipball/1ca9241ce66358cdfb2dbde65d609eb9c185c515",
|
||||
"reference": "1ca9241ce66358cdfb2dbde65d609eb9c185c515",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockData/zipball/d64617faab77300d828debcd1e3597b3403b63b7",
|
||||
"reference": "d64617faab77300d828debcd1e3597b3403b63b7",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
@ -294,7 +299,7 @@
|
||||
"issues": "https://github.com/pmmp/BedrockData/issues",
|
||||
"source": "https://github.com/pmmp/BedrockData/tree/modern-world-support"
|
||||
},
|
||||
"time": "2022-09-21T13:59:15+00:00"
|
||||
"time": "2022-12-02T13:01:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/bedrock-item-upgrade-schema",
|
||||
@ -325,16 +330,16 @@
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/bedrock-protocol",
|
||||
"version": "13.0.0+bedrock-1.19.30",
|
||||
"version": "17.1.0+bedrock-1.19.50",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/BedrockProtocol.git",
|
||||
"reference": "94de2221676ca717587e1ff4e45445c24ada1749"
|
||||
"reference": "c572706cf5e3202718dd35a35dd30fe08cd671de"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/94de2221676ca717587e1ff4e45445c24ada1749",
|
||||
"reference": "94de2221676ca717587e1ff4e45445c24ada1749",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/c572706cf5e3202718dd35a35dd30fe08cd671de",
|
||||
"reference": "c572706cf5e3202718dd35a35dd30fe08cd671de",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -348,7 +353,7 @@
|
||||
"ramsey/uuid": "^4.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "1.8.0",
|
||||
"phpstan/phpstan": "1.9.3",
|
||||
"phpstan/phpstan-phpunit": "^1.0.0",
|
||||
"phpstan/phpstan-strict-rules": "^1.0.0",
|
||||
"phpunit/phpunit": "^9.5"
|
||||
@ -366,9 +371,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/bedrock-1.19.30"
|
||||
"source": "https://github.com/pmmp/BedrockProtocol/tree/17.1.0+bedrock-1.19.50"
|
||||
},
|
||||
"time": "2022-09-20T18:35:00+00:00"
|
||||
"time": "2022-12-15T20:34:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/binaryutils",
|
||||
@ -586,16 +591,16 @@
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/locale-data",
|
||||
"version": "2.8.7",
|
||||
"version": "2.11.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/Language.git",
|
||||
"reference": "e115d3d64a508065f1cedad1be55528906308456"
|
||||
"reference": "4b33d8fa53eda53d9662a7478806ebae2e4a5c53"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/Language/zipball/e115d3d64a508065f1cedad1be55528906308456",
|
||||
"reference": "e115d3d64a508065f1cedad1be55528906308456",
|
||||
"url": "https://api.github.com/repos/pmmp/Language/zipball/4b33d8fa53eda53d9662a7478806ebae2e4a5c53",
|
||||
"reference": "4b33d8fa53eda53d9662a7478806ebae2e4a5c53",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
@ -603,9 +608,9 @@
|
||||
"description": "Language resources used by PocketMine-MP",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/Language/issues",
|
||||
"source": "https://github.com/pmmp/Language/tree/2.8.7"
|
||||
"source": "https://github.com/pmmp/Language/tree/2.11.0"
|
||||
},
|
||||
"time": "2022-08-21T20:37:16+00:00"
|
||||
"time": "2022-11-25T14:24:34+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/log",
|
||||
@ -980,21 +985,20 @@
|
||||
},
|
||||
{
|
||||
"name": "ramsey/uuid",
|
||||
"version": "4.5.1",
|
||||
"version": "4.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ramsey/uuid.git",
|
||||
"reference": "a161a26d917604dc6d3aa25100fddf2556e9f35d"
|
||||
"reference": "ad63bc700e7d021039e30ce464eba384c4a1d40f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/ramsey/uuid/zipball/a161a26d917604dc6d3aa25100fddf2556e9f35d",
|
||||
"reference": "a161a26d917604dc6d3aa25100fddf2556e9f35d",
|
||||
"url": "https://api.github.com/repos/ramsey/uuid/zipball/ad63bc700e7d021039e30ce464eba384c4a1d40f",
|
||||
"reference": "ad63bc700e7d021039e30ce464eba384c4a1d40f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"brick/math": "^0.8.8 || ^0.9 || ^0.10",
|
||||
"ext-ctype": "*",
|
||||
"ext-json": "*",
|
||||
"php": "^8.0",
|
||||
"ramsey/collection": "^1.0"
|
||||
@ -1026,7 +1030,6 @@
|
||||
},
|
||||
"suggest": {
|
||||
"ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.",
|
||||
"ext-ctype": "Enables faster processing of character classification using ctype functions.",
|
||||
"ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.",
|
||||
"ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.",
|
||||
"paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter",
|
||||
@ -1058,7 +1061,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/ramsey/uuid/issues",
|
||||
"source": "https://github.com/ramsey/uuid/tree/4.5.1"
|
||||
"source": "https://github.com/ramsey/uuid/tree/4.6.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -1070,20 +1073,249 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-09-16T03:22:46+00:00"
|
||||
"time": "2022-11-05T23:03:38+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php81",
|
||||
"version": "v1.26.0",
|
||||
"name": "symfony/filesystem",
|
||||
"version": "v5.4.13",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php81.git",
|
||||
"reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1"
|
||||
"url": "https://github.com/symfony/filesystem.git",
|
||||
"reference": "ac09569844a9109a5966b9438fc29113ce77cf51"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/13f6d1271c663dc5ae9fb843a8f16521db7687a1",
|
||||
"reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/ac09569844a9109a5966b9438fc29113ce77cf51",
|
||||
"reference": "ac09569844a9109a5966b9438fc29113ce77cf51",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.5",
|
||||
"symfony/polyfill-ctype": "~1.8",
|
||||
"symfony/polyfill-mbstring": "~1.8",
|
||||
"symfony/polyfill-php80": "^1.16"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Filesystem\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Provides basic utilities for the filesystem",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/filesystem/tree/v5.4.13"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-09-21T19:53:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
"version": "v1.27.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||
"reference": "5bbc823adecdae860bb64756d639ecfec17b050a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a",
|
||||
"reference": "5bbc823adecdae860bb64756d639ecfec17b050a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"provide": {
|
||||
"ext-ctype": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-ctype": "For best performance"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.27-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Ctype\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Gert de Pagter",
|
||||
"email": "BackEndTea@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill for ctype functions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"ctype",
|
||||
"polyfill",
|
||||
"portable"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-11-03T14:55:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.27.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
"reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
|
||||
"reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"provide": {
|
||||
"ext-mbstring": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-mbstring": "For best performance"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.27-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Mbstring\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill for the Mbstring extension",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"mbstring",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-11-03T14:55:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php80",
|
||||
"version": "v1.27.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php80.git",
|
||||
"reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
|
||||
"reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1092,7 +1324,90 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.26-dev"
|
||||
"dev-main": "1.27-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Php80\\": ""
|
||||
},
|
||||
"classmap": [
|
||||
"Resources/stubs"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ion Bazan",
|
||||
"email": "ion.bazan@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-11-03T14:55:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php81",
|
||||
"version": "v1.27.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php81.git",
|
||||
"reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/707403074c8ea6e2edaf8794b0157a0bfa52157a",
|
||||
"reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.27-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
@ -1133,7 +1448,7 @@
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-php81/tree/v1.26.0"
|
||||
"source": "https://github.com/symfony/polyfill-php81/tree/v1.27.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -1149,116 +1464,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-05-24T11:49:31+00:00"
|
||||
},
|
||||
{
|
||||
"name": "webmozart/assert",
|
||||
"version": "1.11.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/webmozarts/assert.git",
|
||||
"reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991",
|
||||
"reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-ctype": "*",
|
||||
"php": "^7.2 || ^8.0"
|
||||
},
|
||||
"conflict": {
|
||||
"phpstan/phpstan": "<0.12.20",
|
||||
"vimeo/psalm": "<4.6.1 || 4.6.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^8.5.13"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.10-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Webmozart\\Assert\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Bernhard Schussek",
|
||||
"email": "bschussek@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Assertions to validate method input/output with nice error messages.",
|
||||
"keywords": [
|
||||
"assert",
|
||||
"check",
|
||||
"validate"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/webmozarts/assert/issues",
|
||||
"source": "https://github.com/webmozarts/assert/tree/1.11.0"
|
||||
},
|
||||
"time": "2022-06-03T18:03:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "webmozart/path-util",
|
||||
"version": "2.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/webmozart/path-util.git",
|
||||
"reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/webmozart/path-util/zipball/d939f7edc24c9a1bb9c0dee5cb05d8e859490725",
|
||||
"reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3",
|
||||
"webmozart/assert": "~1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.6",
|
||||
"sebastian/version": "^1.0.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.3-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Webmozart\\PathUtil\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Bernhard Schussek",
|
||||
"email": "bschussek@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "A robust cross-platform utility for normalizing, comparing and modifying file paths.",
|
||||
"support": {
|
||||
"issues": "https://github.com/webmozart/path-util/issues",
|
||||
"source": "https://github.com/webmozart/path-util/tree/2.3.0"
|
||||
},
|
||||
"abandoned": "symfony/filesystem",
|
||||
"time": "2015-12-17T08:42:14+00:00"
|
||||
"time": "2022-11-03T14:55:06+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
@ -1393,16 +1599,16 @@
|
||||
},
|
||||
{
|
||||
"name": "nikic/php-parser",
|
||||
"version": "v4.15.1",
|
||||
"version": "v4.15.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nikic/PHP-Parser.git",
|
||||
"reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900"
|
||||
"reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ef6c55a3f47f89d7a374e6f835197a0b5fcf900",
|
||||
"reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc",
|
||||
"reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1443,9 +1649,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/nikic/PHP-Parser/issues",
|
||||
"source": "https://github.com/nikic/PHP-Parser/tree/v4.15.1"
|
||||
"source": "https://github.com/nikic/PHP-Parser/tree/v4.15.2"
|
||||
},
|
||||
"time": "2022-09-04T07:30:47+00:00"
|
||||
"time": "2022-11-12T15:38:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phar-io/manifest",
|
||||
@ -1560,16 +1766,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan",
|
||||
"version": "1.8.5",
|
||||
"version": "1.9.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpstan.git",
|
||||
"reference": "f6598a5ff12ca4499a836815e08b4d77a2ddeb20"
|
||||
"reference": "d03bccee595e2146b7c9d174486b84f4dc61b0f2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/f6598a5ff12ca4499a836815e08b4d77a2ddeb20",
|
||||
"reference": "f6598a5ff12ca4499a836815e08b4d77a2ddeb20",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/d03bccee595e2146b7c9d174486b84f4dc61b0f2",
|
||||
"reference": "d03bccee595e2146b7c9d174486b84f4dc61b0f2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1599,7 +1805,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/phpstan/phpstan/issues",
|
||||
"source": "https://github.com/phpstan/phpstan/tree/1.8.5"
|
||||
"source": "https://github.com/phpstan/phpstan/tree/1.9.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -1615,25 +1821,25 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-09-07T16:05:32+00:00"
|
||||
"time": "2022-12-17T13:33:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan-phpunit",
|
||||
"version": "1.1.1",
|
||||
"version": "1.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpstan-phpunit.git",
|
||||
"reference": "4a3c437c09075736285d1cabb5c75bf27ed0bc84"
|
||||
"reference": "cd9c6938f8bbfcb6da3ed5a3c7ea60873825d088"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/4a3c437c09075736285d1cabb5c75bf27ed0bc84",
|
||||
"reference": "4a3c437c09075736285d1cabb5c75bf27ed0bc84",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/cd9c6938f8bbfcb6da3ed5a3c7ea60873825d088",
|
||||
"reference": "cd9c6938f8bbfcb6da3ed5a3c7ea60873825d088",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2 || ^8.0",
|
||||
"phpstan/phpstan": "^1.5.0"
|
||||
"phpstan/phpstan": "^1.9.3"
|
||||
},
|
||||
"conflict": {
|
||||
"phpunit/phpunit": "<7.0"
|
||||
@ -1665,27 +1871,27 @@
|
||||
"description": "PHPUnit extensions and rules for PHPStan",
|
||||
"support": {
|
||||
"issues": "https://github.com/phpstan/phpstan-phpunit/issues",
|
||||
"source": "https://github.com/phpstan/phpstan-phpunit/tree/1.1.1"
|
||||
"source": "https://github.com/phpstan/phpstan-phpunit/tree/1.3.2"
|
||||
},
|
||||
"time": "2022-04-20T15:24:25+00:00"
|
||||
"time": "2022-12-13T15:08:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan-strict-rules",
|
||||
"version": "1.4.3",
|
||||
"version": "1.4.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpstan-strict-rules.git",
|
||||
"reference": "431b3d6e8040075de196680cd5bc95735987b4ae"
|
||||
"reference": "23e5f377ee6395a1a04842d3d6ed4bd25e7b44a6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/431b3d6e8040075de196680cd5bc95735987b4ae",
|
||||
"reference": "431b3d6e8040075de196680cd5bc95735987b4ae",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/23e5f377ee6395a1a04842d3d6ed4bd25e7b44a6",
|
||||
"reference": "23e5f377ee6395a1a04842d3d6ed4bd25e7b44a6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2 || ^8.0",
|
||||
"phpstan/phpstan": "^1.8.3"
|
||||
"phpstan/phpstan": "^1.8.6"
|
||||
},
|
||||
"require-dev": {
|
||||
"nikic/php-parser": "^4.13.0",
|
||||
@ -1713,22 +1919,22 @@
|
||||
"description": "Extra strict and opinionated rules for PHPStan",
|
||||
"support": {
|
||||
"issues": "https://github.com/phpstan/phpstan-strict-rules/issues",
|
||||
"source": "https://github.com/phpstan/phpstan-strict-rules/tree/1.4.3"
|
||||
"source": "https://github.com/phpstan/phpstan-strict-rules/tree/1.4.4"
|
||||
},
|
||||
"time": "2022-08-26T15:05:46+00:00"
|
||||
"time": "2022-09-21T11:38:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
"version": "9.2.17",
|
||||
"version": "9.2.22",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
||||
"reference": "aa94dc41e8661fe90c7316849907cba3007b10d8"
|
||||
"reference": "e4bf60d2220b4baaa0572986b5d69870226b06df"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/aa94dc41e8661fe90c7316849907cba3007b10d8",
|
||||
"reference": "aa94dc41e8661fe90c7316849907cba3007b10d8",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/e4bf60d2220b4baaa0572986b5d69870226b06df",
|
||||
"reference": "e4bf60d2220b4baaa0572986b5d69870226b06df",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1784,7 +1990,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
|
||||
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.17"
|
||||
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.22"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -1792,7 +1998,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2022-08-30T12:24:04+00:00"
|
||||
"time": "2022-12-18T16:40:55+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-file-iterator",
|
||||
@ -2037,16 +2243,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "9.5.24",
|
||||
"version": "9.5.27",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "d0aa6097bef9fd42458a9b3c49da32c6ce6129c5"
|
||||
"reference": "a2bc7ffdca99f92d959b3f2270529334030bba38"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d0aa6097bef9fd42458a9b3c49da32c6ce6129c5",
|
||||
"reference": "d0aa6097bef9fd42458a9b3c49da32c6ce6129c5",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a2bc7ffdca99f92d959b3f2270529334030bba38",
|
||||
"reference": "a2bc7ffdca99f92d959b3f2270529334030bba38",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -2068,14 +2274,14 @@
|
||||
"phpunit/php-timer": "^5.0.2",
|
||||
"sebastian/cli-parser": "^1.0.1",
|
||||
"sebastian/code-unit": "^1.0.6",
|
||||
"sebastian/comparator": "^4.0.5",
|
||||
"sebastian/comparator": "^4.0.8",
|
||||
"sebastian/diff": "^4.0.3",
|
||||
"sebastian/environment": "^5.1.3",
|
||||
"sebastian/exporter": "^4.0.3",
|
||||
"sebastian/exporter": "^4.0.5",
|
||||
"sebastian/global-state": "^5.0.1",
|
||||
"sebastian/object-enumerator": "^4.0.3",
|
||||
"sebastian/resource-operations": "^3.0.3",
|
||||
"sebastian/type": "^3.1",
|
||||
"sebastian/type": "^3.2",
|
||||
"sebastian/version": "^3.0.2"
|
||||
},
|
||||
"suggest": {
|
||||
@ -2119,7 +2325,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.24"
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.27"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -2129,9 +2335,13 @@
|
||||
{
|
||||
"url": "https://github.com/sebastianbergmann",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-08-30T07:42:16+00:00"
|
||||
"time": "2022-12-09T07:31:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/cli-parser",
|
||||
|
@ -1,7 +1,6 @@
|
||||
includes:
|
||||
- tests/phpstan/analyse-for-current-php-version.neon.php
|
||||
- tests/phpstan/configs/actual-problems.neon
|
||||
- tests/phpstan/configs/gc-hacks.neon
|
||||
- tests/phpstan/configs/impossible-generics.neon
|
||||
- tests/phpstan/configs/php-bugs.neon
|
||||
- tests/phpstan/configs/phpstan-bugs.neon
|
||||
|
@ -119,8 +119,6 @@ chunk-sending:
|
||||
spawn-radius: 4
|
||||
|
||||
chunk-ticking:
|
||||
#Max amount of chunks processed each tick
|
||||
per-tick: 40
|
||||
#Radius of chunks around a player to tick
|
||||
tick-radius: 3
|
||||
#Number of blocks inside ticking areas' subchunks that get ticked every tick. Higher values will accelerate events
|
||||
|
@ -10,3 +10,4 @@ resource_stack:
|
||||
# - natural.zip
|
||||
# - vanilla.zip
|
||||
#If you want to force clients to use vanilla resources, you must place a vanilla resource pack in your resources folder and add it to the stack here.
|
||||
#To specify a resource encryption key, put the key in the <resource>.key file alongside the resource pack. Example: vanilla.zip.key
|
||||
|
@ -30,7 +30,7 @@ use pocketmine\scheduler\GarbageCollectionTask;
|
||||
use pocketmine\timings\Timings;
|
||||
use pocketmine\utils\Process;
|
||||
use pocketmine\utils\Utils;
|
||||
use Webmozart\PathUtil\Path;
|
||||
use Symfony\Component\Filesystem\Path;
|
||||
use function arsort;
|
||||
use function count;
|
||||
use function fclose;
|
||||
@ -285,10 +285,8 @@ class MemoryManager{
|
||||
|
||||
/**
|
||||
* Static memory dumper accessible from any thread.
|
||||
*
|
||||
* @param mixed $startingObject
|
||||
*/
|
||||
public static function dumpMemory($startingObject, string $outputFolder, int $maxNesting, int $maxStringSize, \Logger $logger) : void{
|
||||
public static function dumpMemory(mixed $startingObject, string $outputFolder, int $maxNesting, int $maxStringSize, \Logger $logger) : void{
|
||||
$hardLimit = Utils::assumeNotFalse(ini_get('memory_limit'), "memory_limit INI directive should always exist");
|
||||
ini_set('memory_limit', '-1');
|
||||
gc_disable();
|
||||
@ -398,7 +396,7 @@ class MemoryManager{
|
||||
|
||||
do{
|
||||
$continue = false;
|
||||
foreach($objects as $hash => $object){
|
||||
foreach(Utils::stringifyKeys($objects) as $hash => $object){
|
||||
if(!is_object($object)){
|
||||
continue;
|
||||
}
|
||||
@ -479,13 +477,15 @@ class MemoryManager{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $from
|
||||
* @param object[] $objects reference parameter
|
||||
* @param object[] $objects reference parameter
|
||||
* @param int[] $refCounts reference parameter
|
||||
*
|
||||
* @return mixed
|
||||
* @phpstan-param array<string, object> $objects
|
||||
* @phpstan-param array<string, int> $refCounts
|
||||
* @phpstan-param-out array<string, object> $objects
|
||||
* @phpstan-param-out array<string, int> $refCounts
|
||||
*/
|
||||
private static function continueDump($from, array &$objects, array &$refCounts, int $recursion, int $maxNesting, int $maxStringSize){
|
||||
private static function continueDump(mixed $from, array &$objects, array &$refCounts, int $recursion, int $maxNesting, int $maxStringSize) : mixed{
|
||||
if($maxNesting <= 0){
|
||||
return "(error) NESTING LIMIT REACHED";
|
||||
}
|
||||
|
@ -34,16 +34,19 @@ namespace pocketmine {
|
||||
use pocketmine\utils\Timezone;
|
||||
use pocketmine\utils\Utils;
|
||||
use pocketmine\wizard\SetupWizard;
|
||||
use Webmozart\PathUtil\Path;
|
||||
use Symfony\Component\Filesystem\Path;
|
||||
use function defined;
|
||||
use function extension_loaded;
|
||||
use function function_exists;
|
||||
use function getcwd;
|
||||
use function is_dir;
|
||||
use function mkdir;
|
||||
use function phpversion;
|
||||
use function preg_match;
|
||||
use function preg_quote;
|
||||
use function realpath;
|
||||
use function version_compare;
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
|
||||
require_once __DIR__ . '/VersionInfo.php';
|
||||
|
||||
@ -201,6 +204,22 @@ JIT_WARNING
|
||||
ini_set('assert.exception', '1');
|
||||
}
|
||||
|
||||
function getopt_string(string $opt) : ?string{
|
||||
$opts = getopt("", ["$opt:"]);
|
||||
if(isset($opts[$opt])){
|
||||
if(is_string($opts[$opt])){
|
||||
return $opts[$opt];
|
||||
}
|
||||
if(is_array($opts[$opt])){
|
||||
critical_error("Cannot specify --$opt multiple times");
|
||||
}else{
|
||||
critical_error("Missing value for --$opt");
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
@ -252,27 +271,42 @@ JIT_WARNING
|
||||
|
||||
ErrorToExceptionHandler::set();
|
||||
|
||||
$opts = getopt("", ["data:", "plugins:", "no-wizard", "enable-ansi", "disable-ansi"]);
|
||||
|
||||
$cwd = Utils::assumeNotFalse(realpath(Utils::assumeNotFalse(getcwd())));
|
||||
$dataPath = isset($opts["data"]) ? $opts["data"] . DIRECTORY_SEPARATOR : $cwd . DIRECTORY_SEPARATOR;
|
||||
$pluginPath = isset($opts["plugins"]) ? $opts["plugins"] . DIRECTORY_SEPARATOR : $cwd . DIRECTORY_SEPARATOR . "plugins" . DIRECTORY_SEPARATOR;
|
||||
$dataPath = getopt_string("data") ?? $cwd;
|
||||
$pluginPath = getopt_string("plugins") ?? $cwd . DIRECTORY_SEPARATOR . "plugins";
|
||||
Filesystem::addCleanedPath($pluginPath, Filesystem::CLEAN_PATH_PLUGINS_PREFIX);
|
||||
|
||||
if(!file_exists($dataPath)){
|
||||
mkdir($dataPath, 0777, true);
|
||||
if(!@mkdir($dataPath, 0777, true) && !is_dir($dataPath)){
|
||||
critical_error("Unable to create/access data directory at $dataPath. Check that the target location is accessible by the current user.");
|
||||
exit(1);
|
||||
}
|
||||
//this has to be done after we're sure the data path exists
|
||||
$dataPath = realpath($dataPath) . DIRECTORY_SEPARATOR;
|
||||
|
||||
$lockFilePath = Path::join($dataPath, 'server.lock');
|
||||
if(($pid = Filesystem::createLockFile($lockFilePath)) !== null){
|
||||
try{
|
||||
$pid = Filesystem::createLockFile($lockFilePath);
|
||||
}catch(\InvalidArgumentException $e){
|
||||
critical_error($e->getMessage());
|
||||
critical_error("Please ensure that there is enough space on the disk and that the current user has read/write permissions to the selected data directory $dataPath.");
|
||||
exit(1);
|
||||
}
|
||||
if($pid !== null){
|
||||
critical_error("Another " . VersionInfo::NAME . " instance (PID $pid) is already using this folder (" . realpath($dataPath) . ").");
|
||||
critical_error("Please stop the other server first before running a new one.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(!@mkdir($pluginPath, 0777, true) && !is_dir($pluginPath)){
|
||||
critical_error("Unable to create plugin directory at $pluginPath. Check that the target location is accessible by the current user.");
|
||||
exit(1);
|
||||
}
|
||||
$pluginPath = realpath($pluginPath) . DIRECTORY_SEPARATOR;
|
||||
|
||||
//Logger has a dependency on timezone
|
||||
Timezone::init();
|
||||
|
||||
$opts = getopt("", ["no-wizard", "enable-ansi", "disable-ansi"]);
|
||||
if(isset($opts["enable-ansi"])){
|
||||
Terminal::init(true);
|
||||
}elseif(isset($opts["disable-ansi"])){
|
||||
|
@ -93,6 +93,7 @@ use pocketmine\timings\Timings;
|
||||
use pocketmine\timings\TimingsHandler;
|
||||
use pocketmine\updater\UpdateChecker;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
use pocketmine\utils\BroadcastLoggerForwarder;
|
||||
use pocketmine\utils\Config;
|
||||
use pocketmine\utils\Filesystem;
|
||||
use pocketmine\utils\Internet;
|
||||
@ -114,7 +115,7 @@ use pocketmine\world\World;
|
||||
use pocketmine\world\WorldCreationOptions;
|
||||
use pocketmine\world\WorldManager;
|
||||
use Ramsey\Uuid\UuidInterface;
|
||||
use Webmozart\PathUtil\Path;
|
||||
use Symfony\Component\Filesystem\Path;
|
||||
use function array_sum;
|
||||
use function base64_encode;
|
||||
use function cli_set_process_title;
|
||||
@ -469,10 +470,7 @@ class Server{
|
||||
return $this->configGroup->getPropertyBool("player.save-player-data", true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OfflinePlayer|Player
|
||||
*/
|
||||
public function getOfflinePlayer(string $name){
|
||||
public function getOfflinePlayer(string $name) : Player|OfflinePlayer|null{
|
||||
$name = strtolower($name);
|
||||
$result = $this->getPlayerExact($name);
|
||||
|
||||
@ -559,7 +557,7 @@ class Server{
|
||||
$ev->call();
|
||||
$class = $ev->getPlayerClass();
|
||||
|
||||
if($offlinePlayerData !== null && ($world = $this->worldManager->getWorldByName($offlinePlayerData->getString("Level", ""))) !== null){
|
||||
if($offlinePlayerData !== null && ($world = $this->worldManager->getWorldByName($offlinePlayerData->getString(Player::TAG_LEVEL, ""))) !== null){
|
||||
$playerPos = EntityDataHelper::parseLocation($offlinePlayerData, $world);
|
||||
$spawn = $playerPos->asVector3();
|
||||
}else{
|
||||
@ -608,6 +606,10 @@ class Server{
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated This method's results are unpredictable. The string "Steve" will return the player named "SteveJobs",
|
||||
* until another player named "SteveJ" joins the server, at which point it will return that player instead. Prefer
|
||||
* filtering the results of {@link Server::getOnlinePlayers()} yourself.
|
||||
*
|
||||
* Returns an online player whose name begins with or equals the given string (case insensitive).
|
||||
* The closest match will be returned, or null if there are no online matches.
|
||||
*
|
||||
@ -1044,11 +1046,11 @@ class Server{
|
||||
$this->logger->info($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_server_donate(TextFormat::AQUA . "https://patreon.com/pocketminemp" . TextFormat::RESET)));
|
||||
$this->logger->info($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_server_startFinished(strval(round(microtime(true) - $this->startTime, 3)))));
|
||||
|
||||
//TODO: move console parts to a separate component
|
||||
$consoleSender = new ConsoleCommandSender($this, $this->language);
|
||||
$this->subscribeToBroadcastChannel(self::BROADCAST_CHANNEL_ADMINISTRATIVE, $consoleSender);
|
||||
$this->subscribeToBroadcastChannel(self::BROADCAST_CHANNEL_USERS, $consoleSender);
|
||||
$forwarder = new BroadcastLoggerForwarder($this, $this->logger, $this->language);
|
||||
$this->subscribeToBroadcastChannel(self::BROADCAST_CHANNEL_ADMINISTRATIVE, $forwarder);
|
||||
$this->subscribeToBroadcastChannel(self::BROADCAST_CHANNEL_USERS, $forwarder);
|
||||
|
||||
//TODO: move console parts to a separate component
|
||||
if($this->configGroup->getPropertyBool("console.enable-input", true)){
|
||||
$this->console = new ConsoleReaderChildProcessDaemon($this->logger);
|
||||
}
|
||||
@ -1263,7 +1265,7 @@ class Server{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CommandSender[]|null $recipients
|
||||
* @param CommandSender[]|null $recipients
|
||||
*/
|
||||
public function broadcastMessage(Translatable|string $message, ?array $recipients = null) : int{
|
||||
$recipients = $recipients ?? $this->getBroadcastChannelSubscribers(self::BROADCAST_CHANNEL_USERS);
|
||||
@ -1316,9 +1318,9 @@ class Server{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $fadeIn Duration in ticks for fade-in. If -1 is given, client-sided defaults will be used.
|
||||
* @param int $stay Duration in ticks to stay on screen for
|
||||
* @param int $fadeOut Duration in ticks for fade-out.
|
||||
* @param int $fadeIn Duration in ticks for fade-in. If -1 is given, client-sided defaults will be used.
|
||||
* @param int $stay Duration in ticks to stay on screen for
|
||||
* @param int $fadeOut Duration in ticks for fade-out.
|
||||
* @param Player[]|null $recipients
|
||||
*/
|
||||
public function broadcastTitle(string $title, string $subtitle = "", int $fadeIn = -1, int $stay = -1, int $fadeOut = -1, ?array $recipients = null) : int{
|
||||
@ -1358,6 +1360,7 @@ class Server{
|
||||
return false;
|
||||
}
|
||||
$recipients = $ev->getTargets();
|
||||
$packets = $ev->getPackets();
|
||||
|
||||
/** @var PacketBroadcaster[] $broadcasters */
|
||||
$broadcasters = [];
|
||||
@ -1532,7 +1535,7 @@ class Server{
|
||||
* @param mixed[][]|null $trace
|
||||
* @phpstan-param list<array<string, mixed>>|null $trace
|
||||
*/
|
||||
public function exceptionHandler(\Throwable $e, $trace = null) : void{
|
||||
public function exceptionHandler(\Throwable $e, ?array $trace = null) : void{
|
||||
while(@ob_end_flush()){}
|
||||
global $lastError;
|
||||
|
||||
@ -1711,7 +1714,7 @@ class Server{
|
||||
$session = $player->getNetworkSession();
|
||||
$position = $player->getPosition();
|
||||
$this->logger->info($this->language->translate(KnownTranslationFactory::pocketmine_player_logIn(
|
||||
TextFormat::AQUA . $player->getName() . TextFormat::WHITE,
|
||||
TextFormat::AQUA . $player->getName() . TextFormat::RESET,
|
||||
$session->getIp(),
|
||||
(string) $session->getPort(),
|
||||
(string) $player->getId(),
|
||||
@ -1849,10 +1852,12 @@ class Server{
|
||||
$this->getMemoryManager()->check();
|
||||
|
||||
if($this->console !== null){
|
||||
Timings::$serverCommand->startTiming();
|
||||
while(($line = $this->console->readLine()) !== null){
|
||||
$this->consoleSender ??= new ConsoleCommandSender($this, $this->language);
|
||||
$this->dispatchCommand($this->consoleSender, $line);
|
||||
}
|
||||
Timings::$serverCommand->stopTiming();
|
||||
}
|
||||
|
||||
Timings::$serverTick->stopTiming();
|
||||
|
@ -43,12 +43,7 @@ final class ServerConfigGroup{
|
||||
private Config $serverProperties
|
||||
){}
|
||||
|
||||
/**
|
||||
* @param mixed $defaultValue
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getProperty(string $variable, $defaultValue = null){
|
||||
public function getProperty(string $variable, mixed $defaultValue = null) : mixed{
|
||||
if(!array_key_exists($variable, $this->propertyCache)){
|
||||
$v = getopt("", ["$variable::"]);
|
||||
if(isset($v[$variable])){
|
||||
|
@ -31,7 +31,7 @@ use function str_repeat;
|
||||
|
||||
final class VersionInfo{
|
||||
public const NAME = "PocketMine-MP";
|
||||
public const BASE_VERSION = "5.0.0-ALPHA4";
|
||||
public const BASE_VERSION = "5.0.0-ALPHA6";
|
||||
public const IS_DEVELOPMENT_BUILD = false;
|
||||
public const BUILD_CHANNEL = "alpha";
|
||||
|
||||
|
@ -30,12 +30,17 @@ use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataReader;
|
||||
use pocketmine\data\runtime\RuntimeDataWriter;
|
||||
use pocketmine\entity\object\FallingBlock;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
use pocketmine\world\sound\AnvilFallSound;
|
||||
use pocketmine\world\sound\Sound;
|
||||
use function lcg_value;
|
||||
use function round;
|
||||
|
||||
class Anvil extends Transparent implements Fallable{
|
||||
use FallableTrait;
|
||||
@ -96,7 +101,18 @@ class Anvil extends Transparent implements Fallable{
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
public function tickFalling() : ?Block{
|
||||
return null;
|
||||
public function onHitGround(FallingBlock $blockEntity) : bool{
|
||||
if(lcg_value() < 0.05 + (round($blockEntity->getFallDistance()) - 1) * 0.05){
|
||||
if($this->damage !== self::VERY_DAMAGED){
|
||||
$this->damage = $this->damage + 1;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getLandSound() : ?Sound{
|
||||
return new AnvilFallSound();
|
||||
}
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ abstract class BaseBanner extends Transparent{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BannerPatternLayer[] $patterns
|
||||
* @param BannerPatternLayer[] $patterns
|
||||
*
|
||||
* @phpstan-param list<BannerPatternLayer> $patterns
|
||||
* @return $this
|
||||
|
@ -26,6 +26,7 @@ namespace pocketmine\block;
|
||||
use pocketmine\block\utils\CoralType;
|
||||
use pocketmine\block\utils\CoralTypeTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\event\block\BlockDeathEvent;
|
||||
use pocketmine\item\Item;
|
||||
use function mt_rand;
|
||||
|
||||
@ -45,7 +46,11 @@ abstract class BaseCoral extends Transparent{
|
||||
|
||||
public function onScheduledUpdate() : void{
|
||||
if(!$this->dead && !$this->isCoveredWithWater()){
|
||||
$this->position->getWorld()->setBlock($this->position, $this->setDead(true));
|
||||
$ev = new BlockDeathEvent($this, $this->setDead(true));
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$this->position->getWorld()->setBlock($this->position, $ev->getNewState());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ class Block{
|
||||
protected ?array $collisionBoxes = null;
|
||||
|
||||
/**
|
||||
* @param string $name English name of the block type (TODO: implement translations)
|
||||
* @param string $name English name of the block type (TODO: implement translations)
|
||||
*/
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
$this->idInfo = $idInfo;
|
||||
@ -76,21 +76,38 @@ class Block{
|
||||
$this->position = clone $this->position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an object containing information about how to identify and store this block type, such as type ID and
|
||||
* tile type (if any).
|
||||
*/
|
||||
public function getIdInfo() : BlockIdentifier{
|
||||
return $this->idInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the printable English name of the block.
|
||||
*/
|
||||
public function getName() : string{
|
||||
return $this->fallbackName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* Returns the full blockstate ID of this block. This is a compact way of representing a blockstate used to store
|
||||
* blocks in chunks at runtime.
|
||||
*
|
||||
* This ID can be used to later obtain a copy of this block using {@link BlockFactory::fromStateId()}.
|
||||
*/
|
||||
public function getStateId() : int{
|
||||
return ($this->getTypeId() << self::INTERNAL_STATE_DATA_BITS) | $this->computeStateData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the block as an item.
|
||||
* State information such as facing, powered/unpowered, open/closed, etc., is discarded.
|
||||
* Type information such as colour, wood type, etc. is preserved.
|
||||
*/
|
||||
public function asItem() : Item{
|
||||
return new ItemBlock($this);
|
||||
}
|
||||
@ -191,6 +208,12 @@ class Block{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes information about the block into the world. This writes the blockstate ID into the chunk, and creates
|
||||
* and/or removes tiles as necessary.
|
||||
*
|
||||
* Note: Do not call this directly. Pass the block to {@link World::setBlock()} instead.
|
||||
*/
|
||||
public function writeStateToWorld() : void{
|
||||
$world = $this->position->getWorld();
|
||||
$world->getOrLoadChunkAtPosition($this->position)->setFullBlock($this->position->x & Chunk::COORD_MASK, $this->position->y, $this->position->z & Chunk::COORD_MASK, $this->getStateId());
|
||||
@ -216,7 +239,7 @@ class Block{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a type ID that identifies this type of block. This does not include information like facing, colour,
|
||||
* Returns a type ID that identifies this type of block. This does not include information like facing, open/closed,
|
||||
* powered/unpowered, etc.
|
||||
*/
|
||||
public function getTypeId() : int{
|
||||
@ -263,22 +286,36 @@ class Block{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this block can be replaced by another block placed in the same position.
|
||||
*/
|
||||
public function canBeReplaced() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this block can replace the given block in the given placement conditions.
|
||||
* This is used to allow slabs of the same type to combine into double slabs.
|
||||
*/
|
||||
public function canBePlacedAt(Block $blockReplace, Vector3 $clickVector, int $face, bool $isClickedBlock) : bool{
|
||||
return $blockReplace->canBeReplaced();
|
||||
}
|
||||
|
||||
/**
|
||||
* Places the Block, using block space and block target, and side. Returns if the block has been placed.
|
||||
* Generates a block transaction to set all blocks affected by placing this block. Usually this is just the block
|
||||
* itself, but may be multiple blocks in some cases (such as doors).
|
||||
*
|
||||
* @return bool whether the placement should go ahead
|
||||
*/
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
$tx->addBlock($blockReplace->position, $this);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called immediately after the block has been placed in the world. Since placement uses a block transaction, some
|
||||
* things may not be possible until after the transaction has been executed.
|
||||
*/
|
||||
public function onPostPlace() : void{
|
||||
|
||||
}
|
||||
@ -320,7 +357,7 @@ class Block{
|
||||
|
||||
/**
|
||||
* Called when this block is randomly updated due to chunk ticking.
|
||||
* WARNING: This will not be called if ticksRandomly() does not return true!
|
||||
* WARNING: This will not be called if {@link Block::ticksRandomly()} does not return true!
|
||||
*/
|
||||
public function onRandomTick() : void{
|
||||
|
||||
@ -343,8 +380,7 @@ class Block{
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when this block is attacked (left-clicked). This is called when a player left-clicks the block to try and
|
||||
* start to break it in survival mode.
|
||||
* Called when this block is attacked (left-clicked) by a player attempting to start breaking it in survival.
|
||||
*
|
||||
* @return bool if an action took place, prevents starting to break the block if true.
|
||||
*/
|
||||
@ -352,11 +388,19 @@ class Block{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a multiplier applied to the velocity of entities moving on top of this block. A higher value will make
|
||||
* the block more slippery (like ice).
|
||||
*
|
||||
* @return float 0.0-1.0
|
||||
*/
|
||||
public function getFrictionFactor() : float{
|
||||
return 0.6;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amount of light emitted by this block.
|
||||
*
|
||||
* @return int 0-15
|
||||
*/
|
||||
public function getLightLevel() : int{
|
||||
@ -399,10 +443,6 @@ class Block{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function hasEntityCollision() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether entities can climb up this block.
|
||||
*/
|
||||
@ -410,10 +450,6 @@ class Block{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function addVelocityToEntity(Entity $entity) : ?Vector3{
|
||||
return null;
|
||||
}
|
||||
|
||||
final public function getPosition() : Position{
|
||||
return $this->position;
|
||||
}
|
||||
@ -496,6 +532,7 @@ class Block{
|
||||
|
||||
/**
|
||||
* Returns the item that players will equip when middle-clicking on this block.
|
||||
* If addUserData is true, additional data may be added, such as banner patterns, chest contents, etc.
|
||||
*/
|
||||
public function getPickedItem(bool $addUserData = false) : Item{
|
||||
$item = $this->asItem();
|
||||
@ -623,7 +660,7 @@ class Block{
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for collision against an AxisAlignedBB
|
||||
* Returns whether any of the block's collision boxes intersect with the given AxisAlignedBB.
|
||||
*/
|
||||
public function collidesWithBB(AxisAlignedBB $bb) : bool{
|
||||
foreach($this->getCollisionBoxes() as $bb2){
|
||||
@ -635,10 +672,21 @@ class Block{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the block has actions to be executed when an entity enters its cell (full cube space).
|
||||
*
|
||||
* @see Block::onEntityInside()
|
||||
*/
|
||||
public function hasEntityCollision() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an entity's bounding box clips inside this block's cell. Note that the entity may not be intersecting
|
||||
* with the collision box or bounding box.
|
||||
*
|
||||
* WARNING: This will not be called if {@link Block::hasEntityCollision()} returns false.
|
||||
*
|
||||
* @return bool Whether the block is still the same after the intersection. If it changed (e.g. due to an explosive
|
||||
* being ignited), this should return false.
|
||||
*/
|
||||
@ -646,6 +694,19 @@ class Block{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a direction vector describing which way an entity intersecting this block should be pushed.
|
||||
* This is used by liquids to push entities in liquid currents.
|
||||
*
|
||||
* The returned vector is summed with vectors from every other block the entity is intersecting, and normalized to
|
||||
* produce a final direction vector.
|
||||
*
|
||||
* WARNING: This will not be called if {@link Block::hasEntityCollision()} does not return true!
|
||||
*/
|
||||
public function addVelocityToEntity(Entity $entity) : ?Vector3{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an entity lands on this block (usually due to falling).
|
||||
* @return float|null The new vertical velocity of the entity, or null if unchanged.
|
||||
@ -662,6 +723,13 @@ class Block{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of collision bounding boxes for this block.
|
||||
* These are used for:
|
||||
* - entity movement collision checks (to ensure entities can't clip through blocks)
|
||||
* - projectile flight paths
|
||||
* - block placement (to ensure the player can't place blocks inside itself or another entity)
|
||||
* - anti-cheat checks in plugins
|
||||
*
|
||||
* @return AxisAlignedBB[]
|
||||
*/
|
||||
final public function getCollisionBoxes() : array{
|
||||
@ -692,6 +760,10 @@ class Block{
|
||||
return [AxisAlignedBB::one()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of support that the block can provide on the given face. This is used to determine whether
|
||||
* blocks placed on the given face can be supported by this block.
|
||||
*/
|
||||
public function getSupportType(int $facing) : SupportType{
|
||||
return SupportType::FULL();
|
||||
}
|
||||
@ -702,6 +774,10 @@ class Block{
|
||||
return count($bb) === 1 && $bb[0]->getAverageEdgeLength() >= 1 && $bb[0]->isCube();
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a ray trace along the line between the two positions using the block's collision boxes.
|
||||
* Returns the intersection point closest to pos1, or null if no intersection occurred.
|
||||
*/
|
||||
public function calculateIntercept(Vector3 $pos1, Vector3 $pos2) : ?RayTraceResult{
|
||||
$bbs = $this->getCollisionBoxes();
|
||||
if(count($bbs) === 0){
|
||||
|
@ -85,7 +85,7 @@ class BlockFactory{
|
||||
* NOTE: If you are registering a new block type, you will need to add it to the creative inventory yourself - it
|
||||
* will not automatically appear there.
|
||||
*
|
||||
* @param bool $override Whether to override existing registrations
|
||||
* @param bool $override Whether to override existing registrations
|
||||
*
|
||||
* @throws \InvalidArgumentException if something attempted to override an already-registered block without specifying the
|
||||
* $override parameter.
|
||||
|
@ -704,8 +704,10 @@ final class BlockTypeIds{
|
||||
public const MANGROVE_ROOTS = 10677;
|
||||
public const MUDDY_MANGROVE_ROOTS = 10678;
|
||||
public const FROGLIGHT = 10679;
|
||||
public const TWISTING_VINES = 10680;
|
||||
public const WEEPING_VINES = 10681;
|
||||
|
||||
public const FIRST_UNUSED_BLOCK_ID = 10680;
|
||||
public const FIRST_UNUSED_BLOCK_ID = 10682;
|
||||
|
||||
private static int $nextDynamicId = self::FIRST_UNUSED_BLOCK_ID;
|
||||
|
||||
|
@ -24,9 +24,11 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
final class BlockTypeTags{
|
||||
private const PREFIX = "pocketmine:";
|
||||
|
||||
public const DIRT = "dirt";
|
||||
public const MUD = "mud";
|
||||
public const SAND = "sand";
|
||||
public const POTTABLE_PLANTS = "pottable";
|
||||
public const DIRT = self::PREFIX . "dirt";
|
||||
public const MUD = self::PREFIX . "mud";
|
||||
public const SAND = self::PREFIX . "sand";
|
||||
public const POTTABLE_PLANTS = self::PREFIX . "pottable";
|
||||
public const FIRE = self::PREFIX . "fire";
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\CandleTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataReader;
|
||||
use pocketmine\data\runtime\RuntimeDataWriter;
|
||||
use pocketmine\item\Item;
|
||||
@ -94,6 +95,10 @@ class Candle extends Transparent{
|
||||
];
|
||||
}
|
||||
|
||||
public function getSupportType(int $facing) : SupportType{
|
||||
return SupportType::NONE();
|
||||
}
|
||||
|
||||
protected function getCandleIfCompatibleType(Block $block) : ?Candle{
|
||||
return $block instanceof Candle && $block->isSameType($this) ? $block : null;
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ class ConcretePowder extends Opaque implements Fallable{
|
||||
}
|
||||
|
||||
public function tickFalling() : ?Block{
|
||||
if ($this->getAdjacentWater() === null) {
|
||||
if($this->getAdjacentWater() === null){
|
||||
return null;
|
||||
}
|
||||
return VanillaBlocks::CONCRETE()->setColor($this->color);
|
||||
|
@ -25,6 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\CoralType;
|
||||
use pocketmine\block\utils\CoralTypeTrait;
|
||||
use pocketmine\event\block\BlockDeathEvent;
|
||||
use pocketmine\item\Item;
|
||||
use function mt_rand;
|
||||
|
||||
@ -54,7 +55,11 @@ final class CoralBlock extends Opaque{
|
||||
}
|
||||
}
|
||||
if(!$hasWater){
|
||||
$world->setBlock($this->position, $this->setDead(true));
|
||||
$ev = new BlockDeathEvent($this, $this->setDead(true));
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$world->setBlock($this->position, $ev->getNewState());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -44,10 +44,6 @@ class DragonEgg extends Transparent implements Fallable{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function tickFalling() : ?Block{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
$this->teleport();
|
||||
return true;
|
||||
|
@ -26,6 +26,10 @@ namespace pocketmine\block;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
|
||||
/**
|
||||
* "Flowable" blocks are destroyed if water flows into the same space as the block. These blocks usually don't have any
|
||||
* collision boxes, and can't provide support for other blocks.
|
||||
*/
|
||||
abstract class Flowable extends Transparent{
|
||||
|
||||
public function canBeFlowedInto() : bool{
|
||||
|
@ -26,6 +26,7 @@ namespace pocketmine\block;
|
||||
use pocketmine\block\tile\Furnace as TileFurnace;
|
||||
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\crafting\FurnaceType;
|
||||
use pocketmine\data\runtime\RuntimeDataReader;
|
||||
use pocketmine\data\runtime\RuntimeDataWriter;
|
||||
use pocketmine\item\Item;
|
||||
@ -37,8 +38,15 @@ class Furnace extends Opaque{
|
||||
use FacesOppositePlacingPlayerTrait;
|
||||
use HorizontalFacingTrait;
|
||||
|
||||
protected FurnaceType $furnaceType;
|
||||
|
||||
protected bool $lit = false;
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo, FurnaceType $furnaceType){
|
||||
$this->furnaceType = $furnaceType;
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
}
|
||||
|
||||
public function getRequiredStateDataBits() : int{ return 3; }
|
||||
|
||||
protected function describeState(RuntimeDataReader|RuntimeDataWriter $w) : void{
|
||||
@ -46,6 +54,10 @@ class Furnace extends Opaque{
|
||||
$w->bool($this->lit);
|
||||
}
|
||||
|
||||
public function getFurnaceType() : FurnaceType{
|
||||
return $this->furnaceType;
|
||||
}
|
||||
|
||||
public function getLightLevel() : int{
|
||||
return $this->lit ? 13 : 0;
|
||||
}
|
||||
|
@ -45,8 +45,4 @@ class Gravel extends Opaque implements Fallable{
|
||||
public function isAffectedBySilkTouch() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function tickFalling() : ?Block{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,9 @@ use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
use pocketmine\world\sound\ItemFrameAddItemSound;
|
||||
use pocketmine\world\sound\ItemFrameRemoveItemSound;
|
||||
use pocketmine\world\sound\ItemFrameRotateItemSound;
|
||||
use function is_infinite;
|
||||
use function is_nan;
|
||||
use function lcg_value;
|
||||
@ -149,8 +152,12 @@ class ItemFrame extends Flowable{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($this->framedItem !== null){
|
||||
$this->itemRotation = ($this->itemRotation + 1) % self::ROTATIONS;
|
||||
|
||||
$this->position->getWorld()->addSound($this->position, new ItemFrameRotateItemSound());
|
||||
}elseif(!$item->isNull()){
|
||||
$this->framedItem = $item->pop();
|
||||
|
||||
$this->position->getWorld()->addSound($this->position, new ItemFrameAddItemSound());
|
||||
}else{
|
||||
return true;
|
||||
}
|
||||
@ -167,6 +174,7 @@ class ItemFrame extends Flowable{
|
||||
$world = $this->position->getWorld();
|
||||
if(lcg_value() <= $this->itemDropChance){
|
||||
$world->dropItem($this->position->add(0.5, 0.5, 0.5), clone $this->framedItem);
|
||||
$world->addSound($this->position, new ItemFrameRemoveItemSound());
|
||||
}
|
||||
$this->setFramedItem(null);
|
||||
$world->setBlock($this->position, $this);
|
||||
|
@ -78,6 +78,7 @@ class Leaves extends Transparent{
|
||||
/**
|
||||
* @param true[] $visited reference parameter
|
||||
* @phpstan-param array<int, true> $visited
|
||||
* @phpstan-param-out array<int, true> $visited
|
||||
*/
|
||||
protected function findLog(Vector3 $pos, array &$visited = [], int $distance = 0) : bool{
|
||||
$index = World::blockHash($pos->x, $pos->y, $pos->z);
|
||||
|
@ -27,7 +27,7 @@ use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use function mt_rand;
|
||||
|
||||
class Melon extends Transparent{
|
||||
class Melon extends Opaque{
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
|
196
src/block/NetherVines.php
Normal file
196
src/block/NetherVines.php
Normal file
@ -0,0 +1,196 @@
|
||||
<?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\block;
|
||||
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataReader;
|
||||
use pocketmine\data\runtime\RuntimeDataWriter;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\event\block\StructureGrowEvent;
|
||||
use pocketmine\item\Fertilizer;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
use function min;
|
||||
use function mt_rand;
|
||||
|
||||
/**
|
||||
* This class is used for Weeping & Twisting vines, because they have same behaviour
|
||||
*/
|
||||
class NetherVines extends Flowable{
|
||||
public const MAX_AGE = 25;
|
||||
|
||||
/** Direction the vine grows towards. */
|
||||
private int $growthFace;
|
||||
|
||||
protected int $age = 0;
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo, int $growthFace){
|
||||
$this->growthFace = $growthFace;
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
}
|
||||
|
||||
public function getRequiredStateDataBits() : int{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function describeState(RuntimeDataWriter|RuntimeDataReader $w) : void{
|
||||
$w->boundedInt(5, 0, self::MAX_AGE, $this->age);
|
||||
}
|
||||
|
||||
public function getAge() : int{
|
||||
return $this->age;
|
||||
}
|
||||
|
||||
/** @return $this */
|
||||
public function setAge(int $age) : self{
|
||||
if($age < 0 || $age > self::MAX_AGE){
|
||||
throw new \InvalidArgumentException("Age must be in range 0-" . self::MAX_AGE);
|
||||
}
|
||||
|
||||
$this->age = $age;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isAffectedBySilkTouch() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function canClimb() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
private function getSupportFace() : int{
|
||||
return Facing::opposite($this->growthFace);
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
return $block->getSupportType($this->getSupportFace())->hasCenterSupport() || $block->isSameType($this);
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->canBeSupportedBy($this->getSide($this->getSupportFace()))){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the block at the end of the vine structure furthest from the supporting block.
|
||||
*/
|
||||
private function seekToTip() : NetherVines{
|
||||
$top = $this;
|
||||
while(($next = $top->getSide($this->growthFace)) instanceof NetherVines && $next->isSameType($this)){
|
||||
$top = $next;
|
||||
}
|
||||
return $top;
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if(!$this->canBeSupportedBy($blockReplace->getSide($this->getSupportFace()))){
|
||||
return false;
|
||||
}
|
||||
$this->age = mt_rand(0, self::MAX_AGE - 1);
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($item instanceof Fertilizer){
|
||||
if($this->grow($player, mt_rand(1, 5))){
|
||||
$item->pop();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onRandomTick() : void{
|
||||
if(mt_rand(1, 10) === 1 && $this->age < self::MAX_AGE){
|
||||
if($this->getSide($this->growthFace)->canBeReplaced()){
|
||||
$this->grow(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function grow(?Player $player, int $growthAmount = 1) : bool{
|
||||
$top = $this->seekToTip();
|
||||
$age = $top->getAge();
|
||||
$pos = $top->getPosition();
|
||||
$world = $pos->getWorld();
|
||||
$changedBlocks = 0;
|
||||
|
||||
$tx = new BlockTransaction($world);
|
||||
|
||||
for($i = 1; $i <= $growthAmount; $i++){
|
||||
$growthPos = $pos->getSide($this->growthFace, $i);
|
||||
if(!$world->isInWorld($growthPos->getFloorX(), $growthPos->getFloorY(), $growthPos->getFloorZ()) || !$world->getBlock($growthPos)->canBeReplaced()){
|
||||
break;
|
||||
}
|
||||
$tx->addBlock($growthPos, (clone $top)->setAge(min(++$age, self::MAX_AGE)));
|
||||
$changedBlocks++;
|
||||
}
|
||||
|
||||
if($changedBlocks > 0){
|
||||
$ev = new StructureGrowEvent($top, $tx, $player);
|
||||
$ev->call();
|
||||
|
||||
if($ev->isCancelled()){
|
||||
return false;
|
||||
}
|
||||
|
||||
return $tx->apply();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function hasEntityCollision() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onEntityInside(Entity $entity) : bool{
|
||||
$entity->resetFallDistance();
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
if(($item->getBlockToolType() & BlockToolType::SHEARS) !== 0 || mt_rand(1, 3) === 1){
|
||||
return [$this->asItem()];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getSupportType(int $facing) : SupportType{
|
||||
return SupportType::NONE();
|
||||
}
|
||||
}
|
@ -23,6 +23,10 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
/**
|
||||
* Opaque blocks do not allow light to pass through. They are usually collidable full-cube blocks.
|
||||
* Most blocks in Minecraft fall into this category.
|
||||
*/
|
||||
class Opaque extends Block{
|
||||
|
||||
public function isSolid() : bool{
|
||||
|
@ -43,7 +43,11 @@ class RedMushroom extends Flowable{
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
if(!$down->isTransparent()){
|
||||
$position = $this->getPosition();
|
||||
$lightLevel = $position->getWorld()->getFullLightAt($position->x, $position->y, $position->z);
|
||||
$downId = $down->getTypeId();
|
||||
//TODO: nylium support
|
||||
if(($lightLevel <= 12 && !$down->isTransparent()) || $downId === BlockTypeIds::MYCELIUM || $downId === BlockTypeIds::PODZOL){
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
|
@ -28,8 +28,4 @@ use pocketmine\block\utils\FallableTrait;
|
||||
|
||||
class Sand extends Opaque implements Fallable{
|
||||
use FallableTrait;
|
||||
|
||||
public function tickFalling() : ?Block{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -116,10 +116,6 @@ class SnowLayer extends Flowable implements Fallable{
|
||||
}
|
||||
}
|
||||
|
||||
public function tickFalling() : ?Block{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
VanillaItems::SNOWBALL()->setCount(max(1, (int) floor($this->layers / 2)))
|
||||
|
@ -32,6 +32,7 @@ use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
use pocketmine\world\Position;
|
||||
|
||||
class Sugarcane extends Flowable{
|
||||
public const MAX_AGE = 15;
|
||||
@ -44,14 +45,23 @@ class Sugarcane extends Flowable{
|
||||
$w->boundedInt(4, 0, self::MAX_AGE, $this->age);
|
||||
}
|
||||
|
||||
private function grow() : bool{
|
||||
$grew = false;
|
||||
private function seekToBottom() : Position{
|
||||
$world = $this->position->getWorld();
|
||||
$bottom = $this->position;
|
||||
while(($next = $world->getBlock($bottom->down()))->isSameType($this)){
|
||||
$bottom = $next->position;
|
||||
}
|
||||
return $bottom;
|
||||
}
|
||||
|
||||
private function grow(Position $pos) : bool{
|
||||
$grew = false;
|
||||
$world = $pos->getWorld();
|
||||
for($y = 1; $y < 3; ++$y){
|
||||
if(!$world->isInWorld($this->position->x, $this->position->y + $y, $this->position->z)){
|
||||
if(!$world->isInWorld($pos->x, $pos->y + $y, $pos->z)){
|
||||
break;
|
||||
}
|
||||
$b = $world->getBlockAt($this->position->x, $this->position->y + $y, $this->position->z);
|
||||
$b = $world->getBlockAt($pos->x, $pos->y + $y, $pos->z);
|
||||
if($b->getTypeId() === BlockTypeIds::AIR){
|
||||
$ev = new BlockGrowEvent($b, VanillaBlocks::SUGARCANE());
|
||||
$ev->call();
|
||||
@ -60,12 +70,12 @@ class Sugarcane extends Flowable{
|
||||
}
|
||||
$world->setBlock($b->position, $ev->getNewState());
|
||||
$grew = true;
|
||||
}else{
|
||||
}elseif(!$b->isSameType($this)){
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->age = 0;
|
||||
$world->setBlock($this->position, $this);
|
||||
$world->setBlock($pos, $this);
|
||||
return $grew;
|
||||
}
|
||||
|
||||
@ -82,7 +92,7 @@ class Sugarcane extends Flowable{
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($item instanceof Fertilizer){
|
||||
if(!$this->getSide(Facing::DOWN)->isSameType($this) && $this->grow()){
|
||||
if($this->grow($this->seekToBottom())){
|
||||
$item->pop();
|
||||
}
|
||||
|
||||
@ -113,7 +123,7 @@ class Sugarcane extends Flowable{
|
||||
public function onRandomTick() : void{
|
||||
if(!$this->getSide(Facing::DOWN)->isSameType($this)){
|
||||
if($this->age === self::MAX_AGE){
|
||||
$this->grow();
|
||||
$this->grow($this->position);
|
||||
}else{
|
||||
++$this->age;
|
||||
$this->position->getWorld()->setBlock($this->position, $this);
|
||||
|
@ -29,6 +29,9 @@ use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
use function count;
|
||||
|
||||
/**
|
||||
* Thin blocks behave like glass panes. They connect to full-cube blocks horizontally adjacent to them if possible.
|
||||
*/
|
||||
class Thin extends Transparent{
|
||||
/** @var bool[] facing => dummy */
|
||||
protected array $connections = [];
|
||||
|
@ -23,6 +23,12 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
/**
|
||||
* Transparent blocks do not block any light from propagating through them.
|
||||
*
|
||||
* Note: This does **not** imply that the block is **visually** transparent. For example, chests allow light to pass
|
||||
* through, but the player cannot see through them except at the edges.
|
||||
*/
|
||||
class Transparent extends Block{
|
||||
|
||||
public function isTransparent() : bool{
|
||||
|
@ -27,6 +27,9 @@ use pocketmine\data\runtime\RuntimeDataReader;
|
||||
use pocketmine\data\runtime\RuntimeDataWriter;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
/**
|
||||
* Represents a block which is unrecognized or not implemented.
|
||||
*/
|
||||
class UnknownBlock extends Transparent{
|
||||
|
||||
private int $stateData;
|
||||
|
@ -55,9 +55,15 @@ use pocketmine\block\tile\Skull as TileSkull;
|
||||
use pocketmine\block\tile\Smoker as TileSmoker;
|
||||
use pocketmine\block\utils\TreeType;
|
||||
use pocketmine\block\utils\WoodType;
|
||||
use pocketmine\crafting\FurnaceType;
|
||||
use pocketmine\entity\projectile\Projectile;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ToolTier;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\RayTraceResult;
|
||||
use pocketmine\utils\CloningRegistryTrait;
|
||||
use pocketmine\world\sound\AmethystBlockChimeSound;
|
||||
use pocketmine\world\sound\BlockPunchSound;
|
||||
use function mb_strtolower;
|
||||
|
||||
/**
|
||||
@ -691,6 +697,7 @@ use function mb_strtolower;
|
||||
* @method static Tripwire TRIPWIRE()
|
||||
* @method static TripwireHook TRIPWIRE_HOOK()
|
||||
* @method static Opaque TUFF()
|
||||
* @method static NetherVines TWISTING_VINES()
|
||||
* @method static UnderwaterTorch UNDERWATER_TORCH()
|
||||
* @method static Vine VINES()
|
||||
* @method static WallBanner WALL_BANNER()
|
||||
@ -711,6 +718,7 @@ use function mb_strtolower;
|
||||
* @method static Opaque WARPED_WART_BLOCK()
|
||||
* @method static Water WATER()
|
||||
* @method static WaterCauldron WATER_CAULDRON()
|
||||
* @method static NetherVines WEEPING_VINES()
|
||||
* @method static WeightedPressurePlateHeavy WEIGHTED_PRESSURE_PLATE_HEAVY()
|
||||
* @method static WeightedPressurePlateLight WEIGHTED_PRESSURE_PLATE_LIGHT()
|
||||
* @method static Wheat WHEAT()
|
||||
@ -821,7 +829,7 @@ final class VanillaBlocks{
|
||||
|
||||
self::register("ender_chest", new EnderChest(new BID(Ids::ENDER_CHEST, TileEnderChest::class), "Ender Chest", new Info(BreakInfo::pickaxe(22.5, ToolTier::WOOD(), 3000.0))));
|
||||
self::register("farmland", new Farmland(new BID(Ids::FARMLAND), "Farmland", new Info(BreakInfo::shovel(0.6), [Tags::DIRT])));
|
||||
self::register("fire", new Fire(new BID(Ids::FIRE), "Fire Block", new Info(BreakInfo::instant())));
|
||||
self::register("fire", new Fire(new BID(Ids::FIRE), "Fire Block", new Info(BreakInfo::instant(), [Tags::FIRE])));
|
||||
self::register("fletching_table", new FletchingTable(new BID(Ids::FLETCHING_TABLE), "Fletching Table", new Info(BreakInfo::axe(2.5, null, 2.5))));
|
||||
|
||||
$flowerTypeInfo = new Info(BreakInfo::instant(), [Tags::POTTABLE_PLANTS]);
|
||||
@ -839,9 +847,9 @@ final class VanillaBlocks{
|
||||
self::register("white_tulip", new Flower(new BID(Ids::WHITE_TULIP), "White Tulip", $flowerTypeInfo));
|
||||
self::register("flower_pot", new FlowerPot(new BID(Ids::FLOWER_POT, TileFlowerPot::class), "Flower Pot", $flowerTypeInfo));
|
||||
self::register("frosted_ice", new FrostedIce(new BID(Ids::FROSTED_ICE), "Frosted Ice", new Info(BreakInfo::pickaxe(2.5))));
|
||||
self::register("furnace", new Furnace(new BID(Ids::FURNACE, TileNormalFurnace::class), "Furnace", new Info(BreakInfo::pickaxe(3.5, ToolTier::WOOD()))));
|
||||
self::register("blast_furnace", new Furnace(new BID(Ids::BLAST_FURNACE, TileBlastFurnace::class), "Blast Furnace", new Info(BreakInfo::pickaxe(3.5, ToolTier::WOOD()))));
|
||||
self::register("smoker", new Furnace(new BID(Ids::SMOKER, TileSmoker::class), "Smoker", new Info(BreakInfo::pickaxe(3.5, ToolTier::WOOD()))));
|
||||
self::register("furnace", new Furnace(new BID(Ids::FURNACE, TileNormalFurnace::class), "Furnace", new Info(BreakInfo::pickaxe(3.5, ToolTier::WOOD())), FurnaceType::FURNACE()));
|
||||
self::register("blast_furnace", new Furnace(new BID(Ids::BLAST_FURNACE, TileBlastFurnace::class), "Blast Furnace", new Info(BreakInfo::pickaxe(3.5, ToolTier::WOOD())), FurnaceType::BLAST_FURNACE()));
|
||||
self::register("smoker", new Furnace(new BID(Ids::SMOKER, TileSmoker::class), "Smoker", new Info(BreakInfo::pickaxe(3.5, ToolTier::WOOD())), FurnaceType::SMOKER()));
|
||||
|
||||
$glassBreakInfo = new Info(new BreakInfo(0.3));
|
||||
self::register("glass", new Glass(new BID(Ids::GLASS), "Glass", $glassBreakInfo));
|
||||
@ -1449,7 +1457,7 @@ final class VanillaBlocks{
|
||||
self::register("cracked_polished_blackstone_bricks", new Opaque(new BID(Ids::CRACKED_POLISHED_BLACKSTONE_BRICKS), "Cracked Polished Blackstone Bricks", $blackstoneBreakInfo));
|
||||
|
||||
self::register("soul_torch", new Torch(new BID(Ids::SOUL_TORCH), "Soul Torch", new Info(BreakInfo::instant())));
|
||||
self::register("soul_fire", new SoulFire(new BID(Ids::SOUL_FIRE), "Soul Fire", new Info(BreakInfo::instant())));
|
||||
self::register("soul_fire", new SoulFire(new BID(Ids::SOUL_FIRE), "Soul Fire", new Info(BreakInfo::instant(), [Tags::FIRE])));
|
||||
|
||||
//TODO: soul soul ought to have 0.5 hardness (as per java) but it's 1.0 in Bedrock (probably parity bug)
|
||||
self::register("soul_soil", new Opaque(new BID(Ids::SOUL_SOIL), "Soul Soil", new Info(BreakInfo::shovel(1.0))));
|
||||
@ -1462,11 +1470,19 @@ final class VanillaBlocks{
|
||||
self::register("crying_obsidian", new class(new BID(Ids::CRYING_OBSIDIAN), "Crying Obsidian", new Info(BreakInfo::pickaxe(35.0 /* 50 in Java */, ToolTier::DIAMOND(), 6000.0))) extends Opaque{
|
||||
public function getLightLevel() : int{ return 10;}
|
||||
});
|
||||
|
||||
self::register("twisting_vines", new NetherVines(new BID(Ids::TWISTING_VINES), "Twisting Vines", new Info(BreakInfo::instant()), Facing::UP));
|
||||
self::register("weeping_vines", new NetherVines(new BID(Ids::WEEPING_VINES), "Weeping Vines", new Info(BreakInfo::instant()), Facing::DOWN));
|
||||
}
|
||||
|
||||
private static function registerBlocksR17() : void{
|
||||
//in java this can be acquired using any tool - seems to be a parity issue in bedrock
|
||||
self::register("amethyst", new Opaque(new BID(Ids::AMETHYST), "Amethyst", new Info(BreakInfo::pickaxe(1.5, ToolTier::WOOD()))));
|
||||
self::register("amethyst", new class(new BID(Ids::AMETHYST), "Amethyst", new Info(BreakInfo::pickaxe(1.5, ToolTier::WOOD()))) extends Opaque{
|
||||
public function onProjectileHit(Projectile $projectile, RayTraceResult $hitResult) : void{
|
||||
$this->position->getWorld()->addSound($this->position, new AmethystBlockChimeSound());
|
||||
$this->position->getWorld()->addSound($this->position, new BlockPunchSound($this));
|
||||
}
|
||||
});
|
||||
|
||||
self::register("calcite", new Opaque(new BID(Ids::CALCITE), "Calcite", new Info(BreakInfo::pickaxe(0.75, ToolTier::WOOD()))));
|
||||
self::register("tuff", new Opaque(new BID(Ids::TUFF), "Tuff", new Info(BreakInfo::pickaxe(1.5, ToolTier::WOOD(), 30.0))));
|
||||
|
@ -92,7 +92,6 @@ final class WaterCauldron extends FillableCauldron{
|
||||
$tile->setPotionItem(null);
|
||||
}
|
||||
|
||||
/** @return Color|null */
|
||||
public function getCustomWaterColor() : ?Color{ return $this->customWaterColor; }
|
||||
|
||||
/** @return $this */
|
||||
|
@ -135,7 +135,7 @@ class Banner extends Spawnable{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BannerPatternLayer[] $patterns
|
||||
* @param BannerPatternLayer[] $patterns
|
||||
*
|
||||
* @phpstan-param list<BannerPatternLayer> $patterns
|
||||
*/
|
||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block\tile;
|
||||
|
||||
use pocketmine\data\bedrock\item\SavedItemStackData;
|
||||
use pocketmine\data\SavedDataLoadingException;
|
||||
use pocketmine\inventory\Inventory;
|
||||
use pocketmine\item\Item;
|
||||
@ -51,7 +52,7 @@ trait ContainerTrait{
|
||||
/** @var CompoundTag $itemNBT */
|
||||
foreach($inventoryTag as $itemNBT){
|
||||
try{
|
||||
$newContents[$itemNBT->getByte("Slot")] = Item::nbtDeserialize($itemNBT);
|
||||
$newContents[$itemNBT->getByte(SavedItemStackData::TAG_SLOT)] = Item::nbtDeserialize($itemNBT);
|
||||
}catch(SavedDataLoadingException $e){
|
||||
//TODO: not the best solution
|
||||
\GlobalLogger::get()->logException($e);
|
||||
|
@ -34,7 +34,7 @@ use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\sound\CopperWaxApplySound;
|
||||
use pocketmine\world\sound\CopperWaxRemoveSound;
|
||||
use pocketmine\world\sound\ItemUseOnBlockSound;
|
||||
use pocketmine\world\sound\ScrapeSound;
|
||||
|
||||
trait CopperTrait{
|
||||
private CopperOxidation $oxidation;
|
||||
@ -93,7 +93,7 @@ trait CopperTrait{
|
||||
$this->oxidation = $previousOxidation;
|
||||
$this->position->getWorld()->setBlock($this->position, $this);
|
||||
//TODO: turquoise particles are supposed to appear when removing oxidation
|
||||
$this->position->getWorld()->addSound($this->position, new ItemUseOnBlockSound($this));
|
||||
$this->position->getWorld()->addSound($this->position, new ScrapeSound());
|
||||
$item->applyDamage(1);
|
||||
return true;
|
||||
}
|
||||
|
@ -24,6 +24,8 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block\utils;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\entity\object\FallingBlock;
|
||||
use pocketmine\world\sound\Sound;
|
||||
|
||||
interface Fallable{
|
||||
|
||||
@ -33,4 +35,15 @@ interface Fallable{
|
||||
* Return null if you don't want to change the usual behaviour.
|
||||
*/
|
||||
public function tickFalling() : ?Block;
|
||||
|
||||
/**
|
||||
* Called when FallingBlock hits the ground.
|
||||
* Returns whether the block should be placed.
|
||||
*/
|
||||
public function onHitGround(FallingBlock $blockEntity) : bool;
|
||||
|
||||
/**
|
||||
* Returns the sound that will be played when FallingBlock hits the ground.
|
||||
*/
|
||||
public function getLandSound() : ?Sound;
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ use pocketmine\entity\object\FallingBlock;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
use pocketmine\world\Position;
|
||||
use pocketmine\world\sound\Sound;
|
||||
|
||||
/**
|
||||
* This trait handles falling behaviour for blocks that need them.
|
||||
@ -54,4 +55,16 @@ trait FallableTrait{
|
||||
$fall->spawnToAll();
|
||||
}
|
||||
}
|
||||
|
||||
public function tickFalling() : ?Block{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function onHitGround(FallingBlock $blockEntity) : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getLandSound() : ?Sound{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -36,12 +36,15 @@ use pocketmine\utils\EnumTrait;
|
||||
*
|
||||
* @method static RecordType DISK_11()
|
||||
* @method static RecordType DISK_13()
|
||||
* @method static RecordType DISK_5()
|
||||
* @method static RecordType DISK_BLOCKS()
|
||||
* @method static RecordType DISK_CAT()
|
||||
* @method static RecordType DISK_CHIRP()
|
||||
* @method static RecordType DISK_FAR()
|
||||
* @method static RecordType DISK_MALL()
|
||||
* @method static RecordType DISK_MELLOHI()
|
||||
* @method static RecordType DISK_OTHERSIDE()
|
||||
* @method static RecordType DISK_PIGSTEP()
|
||||
* @method static RecordType DISK_STAL()
|
||||
* @method static RecordType DISK_STRAD()
|
||||
* @method static RecordType DISK_WAIT()
|
||||
@ -55,18 +58,20 @@ final class RecordType{
|
||||
protected static function setup() : void{
|
||||
self::registerAll(
|
||||
new RecordType("disk_13", "C418 - 13", LevelSoundEvent::RECORD_13, KnownTranslationFactory::item_record_13_desc()),
|
||||
new RecordType("disk_5", "Samuel Åberg - 5", LevelSoundEvent::RECORD_5, KnownTranslationFactory::item_record_5_desc()),
|
||||
new RecordType("disk_cat", "C418 - cat", LevelSoundEvent::RECORD_CAT, KnownTranslationFactory::item_record_cat_desc()),
|
||||
new RecordType("disk_blocks", "C418 - blocks", LevelSoundEvent::RECORD_BLOCKS, KnownTranslationFactory::item_record_blocks_desc()),
|
||||
new RecordType("disk_chirp", "C418 - chirp", LevelSoundEvent::RECORD_CHIRP, KnownTranslationFactory::item_record_chirp_desc()),
|
||||
new RecordType("disk_far", "C418 - far", LevelSoundEvent::RECORD_FAR, KnownTranslationFactory::item_record_far_desc()),
|
||||
new RecordType("disk_mall", "C418 - mall", LevelSoundEvent::RECORD_MALL, KnownTranslationFactory::item_record_mall_desc()),
|
||||
new RecordType("disk_mellohi", "C418 - mellohi", LevelSoundEvent::RECORD_MELLOHI, KnownTranslationFactory::item_record_mellohi_desc()),
|
||||
new RecordType("disk_otherside", "Lena Raine - otherside", LevelSoundEvent::RECORD_OTHERSIDE, KnownTranslationFactory::item_record_otherside_desc()),
|
||||
new RecordType("disk_pigstep", "Lena Raine - Pigstep", LevelSoundEvent::RECORD_PIGSTEP, KnownTranslationFactory::item_record_pigstep_desc()),
|
||||
new RecordType("disk_stal", "C418 - stal", LevelSoundEvent::RECORD_STAL, KnownTranslationFactory::item_record_stal_desc()),
|
||||
new RecordType("disk_strad", "C418 - strad", LevelSoundEvent::RECORD_STRAD, KnownTranslationFactory::item_record_strad_desc()),
|
||||
new RecordType("disk_ward", "C418 - ward", LevelSoundEvent::RECORD_WARD, KnownTranslationFactory::item_record_ward_desc()),
|
||||
new RecordType("disk_11", "C418 - 11", LevelSoundEvent::RECORD_11, KnownTranslationFactory::item_record_11_desc()),
|
||||
new RecordType("disk_wait", "C418 - wait", LevelSoundEvent::RECORD_WAIT, KnownTranslationFactory::item_record_wait_desc())
|
||||
//TODO: Lena Raine - Pigstep
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -87,10 +87,7 @@ class SignText{
|
||||
return $this->lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|string $index
|
||||
*/
|
||||
private function checkLineIndex($index) : void{
|
||||
private function checkLineIndex(int|string $index) : void{
|
||||
if(!is_int($index)){
|
||||
throw new \InvalidArgumentException("Index must be an integer");
|
||||
}
|
||||
|
@ -74,9 +74,7 @@ final class WoodType{
|
||||
|
||||
public function isFlammable() : bool{ return $this->flammable; }
|
||||
|
||||
/** @return string|null */
|
||||
public function getStandardLogSuffix() : ?string{ return $this->standardLogSuffix; }
|
||||
|
||||
/** @return string|null */
|
||||
public function getAllSidedLogSuffix() : ?string{ return $this->allSidedLogSuffix; }
|
||||
}
|
||||
|
@ -27,13 +27,11 @@ declare(strict_types=1);
|
||||
namespace pocketmine\command;
|
||||
|
||||
use pocketmine\command\utils\CommandException;
|
||||
use pocketmine\console\ConsoleCommandSender;
|
||||
use pocketmine\lang\KnownTranslationFactory;
|
||||
use pocketmine\lang\Translatable;
|
||||
use pocketmine\permission\PermissionManager;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\timings\Timings;
|
||||
use pocketmine\timings\TimingsHandler;
|
||||
use pocketmine\utils\BroadcastLoggerForwarder;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use function explode;
|
||||
use function str_replace;
|
||||
@ -60,8 +58,6 @@ abstract class Command{
|
||||
private ?string $permission = null;
|
||||
private ?string $permissionMessage = null;
|
||||
|
||||
public ?TimingsHandler $timings = null;
|
||||
|
||||
/**
|
||||
* @param string[] $aliases
|
||||
*/
|
||||
@ -136,7 +132,6 @@ abstract class Command{
|
||||
public function setLabel(string $name) : bool{
|
||||
$this->nextLabel = $name;
|
||||
if(!$this->isRegistered()){
|
||||
$this->timings = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Command: " . $name);
|
||||
$this->label = $name;
|
||||
|
||||
return true;
|
||||
@ -224,12 +219,12 @@ abstract class Command{
|
||||
$result = KnownTranslationFactory::chat_type_admin($source->getName(), $message);
|
||||
$colored = $result->prefix(TextFormat::GRAY . TextFormat::ITALIC);
|
||||
|
||||
if($sendToSource && !($source instanceof ConsoleCommandSender)){
|
||||
if($sendToSource){
|
||||
$source->sendMessage($message);
|
||||
}
|
||||
|
||||
foreach($users as $user){
|
||||
if($user instanceof ConsoleCommandSender){
|
||||
if($user instanceof BroadcastLoggerForwarder){
|
||||
$user->sendMessage($result);
|
||||
}elseif($user !== $source){
|
||||
$user->sendMessage($colored);
|
||||
|
@ -26,7 +26,7 @@ namespace pocketmine\command;
|
||||
interface CommandExecutor{
|
||||
|
||||
/**
|
||||
* @param string[] $args
|
||||
* @param string[] $args
|
||||
*/
|
||||
public function onCommand(CommandSender $sender, Command $command, string $label, array $args) : bool;
|
||||
|
||||
|
@ -26,11 +26,12 @@ namespace pocketmine\command;
|
||||
use pocketmine\command\utils\CommandStringHelper;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\lang\KnownTranslationFactory;
|
||||
use pocketmine\timings\Timings;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use function array_map;
|
||||
use function array_shift;
|
||||
use function count;
|
||||
use function implode;
|
||||
use function preg_match;
|
||||
use function strlen;
|
||||
use function strpos;
|
||||
@ -52,7 +53,7 @@ class FormattedCommandAlias extends Command{
|
||||
string $alias,
|
||||
private array $formatStrings
|
||||
){
|
||||
parent::__construct($alias);
|
||||
parent::__construct($alias, KnownTranslationFactory::pocketmine_command_userDefined_description());
|
||||
}
|
||||
|
||||
public function execute(CommandSender $sender, string $commandLabel, array $args){
|
||||
@ -62,7 +63,20 @@ class FormattedCommandAlias extends Command{
|
||||
foreach($this->formatStrings as $formatString){
|
||||
try{
|
||||
$formatArgs = CommandStringHelper::parseQuoteAware($formatString);
|
||||
$commands[] = array_map(fn(string $formatArg) => $this->buildCommand($formatArg, $args), $formatArgs);
|
||||
$unresolved = [];
|
||||
$processedArgs = [];
|
||||
foreach($formatArgs as $formatArg){
|
||||
$processedArg = $this->buildCommand($formatArg, $args);
|
||||
if($processedArg === null){
|
||||
$unresolved[] = $formatArg;
|
||||
}elseif(count($unresolved) !== 0){
|
||||
//unresolved args are OK only if they are at the end of the string - we can't have holes in the args list
|
||||
throw new \InvalidArgumentException("Unable to resolve format arguments (" . implode(", ", $unresolved) . ") in command string \"$formatString\" due to missing arguments");
|
||||
}else{
|
||||
$processedArgs[] = $processedArg;
|
||||
}
|
||||
}
|
||||
$commands[] = $processedArgs;
|
||||
}catch(\InvalidArgumentException $e){
|
||||
$sender->sendMessage(TextFormat::RED . $e->getMessage());
|
||||
return false;
|
||||
@ -82,14 +96,15 @@ class FormattedCommandAlias extends Command{
|
||||
}
|
||||
|
||||
if(($target = $commandMap->getCommand($commandLabel)) !== null){
|
||||
$target->timings->startTiming();
|
||||
$timings = Timings::getCommandDispatchTimings($target->getLabel());
|
||||
$timings->startTiming();
|
||||
|
||||
try{
|
||||
$target->execute($sender, $commandLabel, $commandArgs);
|
||||
}catch(InvalidCommandSyntaxException $e){
|
||||
$sender->sendMessage($sender->getLanguage()->translate(KnownTranslationFactory::commands_generic_usage($target->getUsage())));
|
||||
}finally{
|
||||
$target->timings->stopTiming();
|
||||
$timings->stopTiming();
|
||||
}
|
||||
}else{
|
||||
$sender->sendMessage($sender->getLanguage()->translate(KnownTranslationFactory::pocketmine_command_notFound($commandLabel, "/help")->prefix(TextFormat::RED)));
|
||||
@ -107,7 +122,7 @@ class FormattedCommandAlias extends Command{
|
||||
/**
|
||||
* @param string[] $args
|
||||
*/
|
||||
private function buildCommand(string $formatString, array $args) : string{
|
||||
private function buildCommand(string $formatString, array $args) : ?string{
|
||||
$index = 0;
|
||||
while(($index = strpos($formatString, '$', $index)) !== false){
|
||||
$start = $index;
|
||||
@ -129,6 +144,9 @@ class FormattedCommandAlias extends Command{
|
||||
}
|
||||
|
||||
$replacement = self::buildReplacement($args, $position, $rest);
|
||||
if($replacement === null){
|
||||
return null;
|
||||
}
|
||||
|
||||
$end = $index + strlen($fullPlaceholder);
|
||||
$formatString = substr($formatString, 0, $start) . $replacement . substr($formatString, $end);
|
||||
@ -143,9 +161,9 @@ class FormattedCommandAlias extends Command{
|
||||
* @param string[] $args
|
||||
* @phpstan-param list<string> $args
|
||||
*/
|
||||
private static function buildReplacement(array $args, int $position, bool $rest) : string{
|
||||
$replacement = "";
|
||||
private static function buildReplacement(array $args, int $position, bool $rest) : ?string{
|
||||
if($rest && $position < count($args)){
|
||||
$replacement = "";
|
||||
for($i = $position, $c = count($args); $i < $c; ++$i){
|
||||
if($i !== $position){
|
||||
$replacement .= " ";
|
||||
@ -153,11 +171,13 @@ class FormattedCommandAlias extends Command{
|
||||
|
||||
$replacement .= $args[$i];
|
||||
}
|
||||
|
||||
return $replacement;
|
||||
}elseif($position < count($args)){
|
||||
$replacement .= $args[$position];
|
||||
return $args[$position];
|
||||
}
|
||||
|
||||
return $replacement;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -68,6 +68,7 @@ use pocketmine\command\utils\CommandStringHelper;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\lang\KnownTranslationFactory;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\timings\Timings;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use function array_shift;
|
||||
use function count;
|
||||
@ -139,7 +140,7 @@ class SimpleCommandMap implements CommandMap{
|
||||
|
||||
public function register(string $fallbackPrefix, Command $command, ?string $label = null) : bool{
|
||||
if($label === null){
|
||||
$label = $command->getName();
|
||||
$label = $command->getLabel();
|
||||
}
|
||||
$label = trim($label);
|
||||
$fallbackPrefix = strtolower(trim($fallbackPrefix));
|
||||
@ -199,7 +200,8 @@ class SimpleCommandMap implements CommandMap{
|
||||
|
||||
$sentCommandLabel = array_shift($args);
|
||||
if($sentCommandLabel !== null && ($target = $this->getCommand($sentCommandLabel)) !== null){
|
||||
$target->timings->startTiming();
|
||||
$timings = Timings::getCommandDispatchTimings($target->getLabel());
|
||||
$timings->startTiming();
|
||||
|
||||
try{
|
||||
if($target->testPermission($sender)){
|
||||
@ -208,7 +210,7 @@ class SimpleCommandMap implements CommandMap{
|
||||
}catch(InvalidCommandSyntaxException $e){
|
||||
$sender->sendMessage($sender->getLanguage()->translate(KnownTranslationFactory::commands_generic_usage($target->getUsage())));
|
||||
}finally{
|
||||
$target->timings->stopTiming();
|
||||
$timings->stopTiming();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -274,10 +276,11 @@ class SimpleCommandMap implements CommandMap{
|
||||
}
|
||||
|
||||
//These registered commands have absolute priority
|
||||
$lowerAlias = strtolower($alias);
|
||||
if(count($targets) > 0){
|
||||
$this->knownCommands[strtolower($alias)] = new FormattedCommandAlias(strtolower($alias), $targets);
|
||||
$this->knownCommands[$lowerAlias] = new FormattedCommandAlias($lowerAlias, $targets);
|
||||
}else{
|
||||
unset($this->knownCommands[strtolower($alias)]);
|
||||
unset($this->knownCommands[$lowerAlias]);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ namespace pocketmine\command\defaults;
|
||||
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\permission\DefaultPermissionNames;
|
||||
use Webmozart\PathUtil\Path;
|
||||
use Symfony\Component\Filesystem\Path;
|
||||
use function date;
|
||||
|
||||
class DumpMemoryCommand extends VanillaCommand{
|
||||
|
@ -59,7 +59,7 @@ class GarbageCollectorCommand extends VanillaCommand{
|
||||
|
||||
$cyclesCollected = $sender->getServer()->getMemoryManager()->triggerGarbageCollector();
|
||||
|
||||
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_gc_header()->format(TextFormat::GREEN . "---- " . TextFormat::WHITE, TextFormat::GREEN . " ----" . TextFormat::WHITE));
|
||||
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_gc_header()->format(TextFormat::GREEN . "---- " . TextFormat::RESET, TextFormat::GREEN . " ----" . TextFormat::RESET));
|
||||
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_gc_chunks(TextFormat::RED . number_format($chunksCollected))->prefix(TextFormat::GOLD));
|
||||
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_gc_entities(TextFormat::RED . number_format($entitiesCollected))->prefix(TextFormat::GOLD));
|
||||
|
||||
|
@ -72,11 +72,10 @@ class HelpCommand extends VanillaCommand{
|
||||
$pageHeight = $sender->getScreenLineHeight();
|
||||
|
||||
if($commandName === ""){
|
||||
/** @var Command[][] $commands */
|
||||
$commands = [];
|
||||
foreach($sender->getServer()->getCommandMap()->getCommands() as $command){
|
||||
if($command->testPermissionSilent($sender)){
|
||||
$commands[$command->getName()] = $command;
|
||||
$commands[$command->getLabel()] = $command;
|
||||
}
|
||||
}
|
||||
ksort($commands, SORT_NATURAL | SORT_FLAG_CASE);
|
||||
@ -91,7 +90,7 @@ class HelpCommand extends VanillaCommand{
|
||||
foreach($commands[$pageNumber - 1] as $command){
|
||||
$description = $command->getDescription();
|
||||
$descriptionString = $description instanceof Translatable ? $lang->translate($description) : $description;
|
||||
$sender->sendMessage(TextFormat::DARK_GREEN . "/" . $command->getName() . ": " . TextFormat::WHITE . $descriptionString);
|
||||
$sender->sendMessage(TextFormat::DARK_GREEN . "/" . $command->getLabel() . ": " . TextFormat::RESET . $descriptionString);
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,19 +101,19 @@ class HelpCommand extends VanillaCommand{
|
||||
$lang = $sender->getLanguage();
|
||||
$description = $cmd->getDescription();
|
||||
$descriptionString = $description instanceof Translatable ? $lang->translate($description) : $description;
|
||||
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_help_specificCommand_header($cmd->getName())
|
||||
->format(TextFormat::YELLOW . "--------- " . TextFormat::WHITE, TextFormat::YELLOW . " ---------"));
|
||||
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_help_specificCommand_description(TextFormat::WHITE . $descriptionString)
|
||||
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_help_specificCommand_header($cmd->getLabel())
|
||||
->format(TextFormat::YELLOW . "--------- " . TextFormat::RESET, TextFormat::YELLOW . " ---------"));
|
||||
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_help_specificCommand_description(TextFormat::RESET . $descriptionString)
|
||||
->prefix(TextFormat::GOLD));
|
||||
|
||||
$usage = $cmd->getUsage();
|
||||
$usageString = $usage instanceof Translatable ? $lang->translate($usage) : $usage;
|
||||
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_help_specificCommand_usage(TextFormat::WHITE . implode("\n" . TextFormat::WHITE, explode("\n", $usageString)))
|
||||
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_help_specificCommand_usage(TextFormat::RESET . implode("\n" . TextFormat::RESET, explode("\n", $usageString)))
|
||||
->prefix(TextFormat::GOLD));
|
||||
|
||||
$aliases = $cmd->getAliases();
|
||||
sort($aliases, SORT_NATURAL);
|
||||
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_help_specificCommand_aliases(TextFormat::WHITE . implode(", ", $aliases))
|
||||
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_help_specificCommand_aliases(TextFormat::RESET . implode(", ", $aliases))
|
||||
->prefix(TextFormat::GOLD));
|
||||
|
||||
return true;
|
||||
|
@ -48,7 +48,7 @@ class MeCommand extends VanillaCommand{
|
||||
throw new InvalidCommandSyntaxException();
|
||||
}
|
||||
|
||||
$sender->getServer()->broadcastMessage(KnownTranslationFactory::chat_type_emote($sender instanceof Player ? $sender->getDisplayName() : $sender->getName(), TextFormat::WHITE . implode(" ", $args)));
|
||||
$sender->getServer()->broadcastMessage(KnownTranslationFactory::chat_type_emote($sender instanceof Player ? $sender->getDisplayName() : $sender->getName(), TextFormat::RESET . implode(" ", $args)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ class PluginsCommand extends VanillaCommand{
|
||||
}, $sender->getServer()->getPluginManager()->getPlugins());
|
||||
sort($list, SORT_STRING);
|
||||
|
||||
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_plugins_success((string) count($list), implode(TextFormat::WHITE . ", ", $list)));
|
||||
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_plugins_success((string) count($list), implode(TextFormat::RESET . ", ", $list)));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ class StatusCommand extends VanillaCommand{
|
||||
$mUsage = Process::getAdvancedMemoryUsage();
|
||||
|
||||
$server = $sender->getServer();
|
||||
$sender->sendMessage(TextFormat::GREEN . "---- " . TextFormat::WHITE . "Server status" . TextFormat::GREEN . " ----");
|
||||
$sender->sendMessage(TextFormat::GREEN . "---- " . TextFormat::RESET . "Server status" . TextFormat::GREEN . " ----");
|
||||
|
||||
$time = (int) (microtime(true) - $server->getStartTime());
|
||||
|
||||
@ -78,10 +78,10 @@ class StatusCommand extends VanillaCommand{
|
||||
$sender->sendMessage(TextFormat::GOLD . "Uptime: " . TextFormat::RED . $uptime);
|
||||
|
||||
$tpsColor = TextFormat::GREEN;
|
||||
if($server->getTicksPerSecond() < 17){
|
||||
$tpsColor = TextFormat::GOLD;
|
||||
}elseif($server->getTicksPerSecond() < 12){
|
||||
if($server->getTicksPerSecond() < 12){
|
||||
$tpsColor = TextFormat::RED;
|
||||
}elseif($server->getTicksPerSecond() < 17){
|
||||
$tpsColor = TextFormat::GOLD;
|
||||
}
|
||||
|
||||
$sender->sendMessage(TextFormat::GOLD . "Current TPS: {$tpsColor}{$server->getTicksPerSecond()} ({$server->getTickUsage()}%)");
|
||||
|
@ -35,7 +35,7 @@ use pocketmine\timings\TimingsHandler;
|
||||
use pocketmine\utils\InternetException;
|
||||
use pocketmine\utils\InternetRequestResult;
|
||||
use pocketmine\utils\Utils;
|
||||
use Webmozart\PathUtil\Path;
|
||||
use Symfony\Component\Filesystem\Path;
|
||||
use function count;
|
||||
use function fclose;
|
||||
use function file_exists;
|
||||
|
@ -53,17 +53,18 @@ class VersionCommand extends VanillaCommand{
|
||||
public function execute(CommandSender $sender, string $commandLabel, array $args){
|
||||
if(count($args) === 0){
|
||||
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_serverSoftwareName(
|
||||
VersionInfo::NAME
|
||||
TextFormat::GREEN . VersionInfo::NAME . TextFormat::RESET
|
||||
));
|
||||
$versionColor = VersionInfo::IS_DEVELOPMENT_BUILD ? TextFormat::YELLOW : TextFormat::GREEN;
|
||||
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_serverSoftwareVersion(
|
||||
VersionInfo::VERSION()->getFullVersion(),
|
||||
VersionInfo::GIT_HASH()
|
||||
$versionColor . VersionInfo::VERSION()->getFullVersion() . TextFormat::RESET,
|
||||
TextFormat::GREEN . VersionInfo::GIT_HASH() . TextFormat::RESET
|
||||
));
|
||||
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_minecraftVersion(
|
||||
ProtocolInfo::MINECRAFT_VERSION_NETWORK,
|
||||
(string) ProtocolInfo::CURRENT_PROTOCOL
|
||||
TextFormat::GREEN . ProtocolInfo::MINECRAFT_VERSION_NETWORK . TextFormat::RESET,
|
||||
TextFormat::GREEN . ProtocolInfo::CURRENT_PROTOCOL . TextFormat::RESET
|
||||
));
|
||||
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_phpVersion(PHP_VERSION));
|
||||
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_phpVersion(TextFormat::GREEN . PHP_VERSION . TextFormat::RESET));
|
||||
|
||||
$jitMode = Utils::getOpcacheJitMode();
|
||||
if($jitMode !== null){
|
||||
@ -75,8 +76,8 @@ class VersionCommand extends VanillaCommand{
|
||||
}else{
|
||||
$jitStatus = KnownTranslationFactory::pocketmine_command_version_phpJitNotSupported();
|
||||
}
|
||||
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_phpJitStatus($jitStatus));
|
||||
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_operatingSystem(Utils::getOS()));
|
||||
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_phpJitStatus($jitStatus->format(TextFormat::GREEN, TextFormat::RESET)));
|
||||
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_operatingSystem(TextFormat::GREEN . Utils::getOS() . TextFormat::RESET));
|
||||
}else{
|
||||
$pluginName = implode(" ", $args);
|
||||
$exactPlugin = $sender->getServer()->getPluginManager()->getPlugin($pluginName);
|
||||
@ -106,7 +107,7 @@ class VersionCommand extends VanillaCommand{
|
||||
|
||||
private function describeToSender(Plugin $plugin, CommandSender $sender) : void{
|
||||
$desc = $plugin->getDescription();
|
||||
$sender->sendMessage(TextFormat::DARK_GREEN . $desc->getName() . TextFormat::WHITE . " version " . TextFormat::DARK_GREEN . $desc->getVersion());
|
||||
$sender->sendMessage(TextFormat::DARK_GREEN . $desc->getName() . TextFormat::RESET . " version " . TextFormat::DARK_GREEN . $desc->getVersion());
|
||||
|
||||
if($desc->getDescription() !== ""){
|
||||
$sender->sendMessage($desc->getDescription());
|
||||
|
@ -30,6 +30,8 @@ use pocketmine\permission\DefaultPermissions;
|
||||
use pocketmine\permission\PermissibleBase;
|
||||
use pocketmine\permission\PermissibleDelegateTrait;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\utils\Terminal;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use function explode;
|
||||
use function trim;
|
||||
use const PHP_INT_MAX;
|
||||
@ -56,13 +58,12 @@ class ConsoleCommandSender implements CommandSender{
|
||||
}
|
||||
|
||||
public function sendMessage(Translatable|string $message) : void{
|
||||
$server = $this->getServer();
|
||||
if($message instanceof Translatable){
|
||||
$message = $this->getLanguage()->translate($message);
|
||||
}
|
||||
|
||||
foreach(explode("\n", trim($message)) as $line){
|
||||
$server->getLogger()->info($line);
|
||||
Terminal::writeLine(TextFormat::GREEN . "Command output | " . TextFormat::addBase(TextFormat::WHITE, $line));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ namespace pocketmine\console;
|
||||
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
use pocketmine\utils\Utils;
|
||||
use Webmozart\PathUtil\Path;
|
||||
use Symfony\Component\Filesystem\Path;
|
||||
use function base64_encode;
|
||||
use function fgets;
|
||||
use function fopen;
|
||||
|
@ -204,7 +204,7 @@ class CraftingManager{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Item[] $outputs
|
||||
* @param Item[] $outputs
|
||||
*/
|
||||
public function matchRecipe(CraftingGrid $grid, array $outputs) : ?CraftingRecipe{
|
||||
//TODO: try to match special recipes before anything else (first they need to be implemented!)
|
||||
|
@ -41,7 +41,7 @@ use pocketmine\item\Item;
|
||||
use pocketmine\nbt\LittleEndianNbtSerializer;
|
||||
use pocketmine\utils\Utils;
|
||||
use pocketmine\world\format\io\GlobalItemDataHandlers;
|
||||
use Webmozart\PathUtil\Path;
|
||||
use Symfony\Component\Filesystem\Path;
|
||||
use function base64_decode;
|
||||
use function file_get_contents;
|
||||
use function get_debug_type;
|
||||
@ -57,6 +57,9 @@ final class CraftingManagerFromDataHelper{
|
||||
//e.g. gold blocks crafted from 9 ingots, but each input item individually had a count of 9
|
||||
throw new SavedDataLoadingException("Recipe inputs should have a count of exactly 1");
|
||||
}
|
||||
if(isset($data->tag)){
|
||||
return new TagWildcardRecipeIngredient($data->tag);
|
||||
}
|
||||
|
||||
$meta = $data->meta ?? null;
|
||||
if($meta === RecipeIngredientData::WILDCARD_META_VALUE){
|
||||
|
@ -45,15 +45,15 @@ class ShapedRecipe implements CraftingRecipe{
|
||||
/**
|
||||
* Constructs a ShapedRecipe instance.
|
||||
*
|
||||
* @param string[] $shape <br>
|
||||
* Array of 1, 2, or 3 strings representing the rows of the recipe.
|
||||
* This accepts an array of 1, 2 or 3 strings. Each string should be of the same length and must be at most 3
|
||||
* characters long. Each character represents a unique type of ingredient. Spaces are interpreted as air.
|
||||
* @param RecipeIngredient[] $ingredients <br>
|
||||
* Char => Item map of items to be set into the shape.
|
||||
* This accepts an array of Items, indexed by character. Every unique character (except space) in the shape
|
||||
* array MUST have a corresponding item in this list. Space character is automatically treated as air.
|
||||
* @param Item[] $results List of items that this recipe produces when crafted.
|
||||
* @param string[] $shape <br>
|
||||
* Array of 1, 2, or 3 strings representing the rows of the recipe.
|
||||
* This accepts an array of 1, 2 or 3 strings. Each string should be of the same length and must be at most 3
|
||||
* characters long. Each character represents a unique type of ingredient. Spaces are interpreted as air.
|
||||
* @param RecipeIngredient[] $ingredients <br>
|
||||
* Char => Item map of items to be set into the shape.
|
||||
* This accepts an array of Items, indexed by character. Every unique character (except space) in the shape
|
||||
* array MUST have a corresponding item in this list. Space character is automatically treated as air.
|
||||
* @param Item[] $results List of items that this recipe produces when crafted.
|
||||
*
|
||||
* Note: Recipes **do not** need to be square. Do NOT add padding for empty rows/columns.
|
||||
*/
|
||||
|
@ -36,11 +36,10 @@ class ShapelessRecipe implements CraftingRecipe{
|
||||
|
||||
/**
|
||||
* @param RecipeIngredient[] $ingredients No more than 9 total. This applies to sum of item stack counts, not count of array.
|
||||
* @param Item[] $results List of result items created by this recipe.
|
||||
* TODO: we'll want to make the type parameter mandatory in PM5
|
||||
* @param Item[] $results List of result items created by this recipe.
|
||||
*/
|
||||
public function __construct(array $ingredients, array $results, ?ShapelessRecipeType $type = null){
|
||||
$this->type = $type ?? ShapelessRecipeType::CRAFTING();
|
||||
public function __construct(array $ingredients, array $results, ShapelessRecipeType $type){
|
||||
$this->type = $type;
|
||||
|
||||
if(count($ingredients) > 9){
|
||||
throw new \InvalidArgumentException("Shapeless recipes cannot have more than 9 ingredients");
|
||||
|
55
src/crafting/TagWildcardRecipeIngredient.php
Normal file
55
src/crafting/TagWildcardRecipeIngredient.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?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\crafting;
|
||||
|
||||
use pocketmine\data\bedrock\ItemTagToIdMap;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\world\format\io\GlobalItemDataHandlers;
|
||||
|
||||
/**
|
||||
* Recipe ingredient that matches items whose ID falls within a specific set. This is used for magic meta value
|
||||
* wildcards and also for ingredients which use item tags (since tags implicitly rely on ID only).
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class TagWildcardRecipeIngredient implements RecipeIngredient{
|
||||
|
||||
public function __construct(
|
||||
private string $tagName
|
||||
){}
|
||||
|
||||
public function getTagName() : string{ return $this->tagName; }
|
||||
|
||||
public function accepts(Item $item) : bool{
|
||||
if($item->getCount() < 1){
|
||||
return false;
|
||||
}
|
||||
|
||||
return ItemTagToIdMap::getInstance()->tagContainsId($this->tagName, GlobalItemDataHandlers::getSerializer()->serializeType($item)->getName());
|
||||
}
|
||||
|
||||
public function __toString() : string{
|
||||
return "TagWildcardRecipeIngredient($this->tagName)";
|
||||
}
|
||||
}
|
@ -54,9 +54,9 @@ final class ShapedRecipeData{
|
||||
/**
|
||||
* TODO: convert this to use promoted properties - avoiding them for now since it would break JsonMapper
|
||||
*
|
||||
* @param string[] $shape
|
||||
* @param string[] $shape
|
||||
* @param RecipeIngredientData[] $input
|
||||
* @param ItemStackData[] $output
|
||||
* @param ItemStackData[] $output
|
||||
*
|
||||
* @phpstan-param list<string> $shape
|
||||
* @phpstan-param array<string, RecipeIngredientData> $input
|
||||
|
@ -47,7 +47,7 @@ final class ShapelessRecipeData{
|
||||
|
||||
/**
|
||||
* @param RecipeIngredientData[] $input
|
||||
* @param ItemStackData[] $output
|
||||
* @param ItemStackData[] $output
|
||||
*
|
||||
* @phpstan-param list<RecipeIngredientData> $input
|
||||
* @phpstan-param list<ItemStackData> $output
|
||||
|
@ -33,7 +33,7 @@ use pocketmine\utils\AssumptionFailedError;
|
||||
use pocketmine\utils\Filesystem;
|
||||
use pocketmine\utils\Utils;
|
||||
use pocketmine\VersionInfo;
|
||||
use Webmozart\PathUtil\Path;
|
||||
use Symfony\Component\Filesystem\Path;
|
||||
use function base64_encode;
|
||||
use function error_get_last;
|
||||
use function file;
|
||||
@ -43,6 +43,7 @@ use function get_loaded_extensions;
|
||||
use function json_encode;
|
||||
use function ksort;
|
||||
use function max;
|
||||
use function mb_scrub;
|
||||
use function mb_strtoupper;
|
||||
use function microtime;
|
||||
use function ob_end_clean;
|
||||
@ -196,12 +197,14 @@ class CrashDump{
|
||||
$error["message"] = substr($error["message"], 0, $pos);
|
||||
}
|
||||
}
|
||||
$error["message"] = mb_scrub($error["message"], 'UTF-8');
|
||||
|
||||
if(isset($lastError)){
|
||||
if(isset($lastError["trace"])){
|
||||
$lastError["trace"] = Utils::printableTrace($lastError["trace"]);
|
||||
}
|
||||
$this->data->lastError = $lastError;
|
||||
$this->data->lastError["message"] = mb_scrub($this->data->lastError["message"], 'UTF-8');
|
||||
}
|
||||
|
||||
$this->data->error = $error;
|
||||
|
@ -74,6 +74,7 @@ final class EffectIdMap{
|
||||
//TODO: SLOW_FALLING
|
||||
//TODO: BAD_OMEN
|
||||
//TODO: VILLAGE_HERO
|
||||
$this->register(EffectIds::DARKNESS, VanillaEffects::DARKNESS());
|
||||
}
|
||||
|
||||
//TODO: not a big fan of the code duplication here :(
|
||||
|
@ -58,4 +58,5 @@ final class EffectIds{
|
||||
public const SLOW_FALLING = 27;
|
||||
public const BAD_OMEN = 28;
|
||||
public const VILLAGE_HERO = 29;
|
||||
public const DARKNESS = 30;
|
||||
}
|
||||
|
@ -73,6 +73,8 @@ final class EnchantmentIdMap{
|
||||
$this->register(EnchantmentIds::MENDING, VanillaEnchantments::MENDING());
|
||||
|
||||
$this->register(EnchantmentIds::VANISHING, VanillaEnchantments::VANISHING());
|
||||
|
||||
$this->register(EnchantmentIds::SWIFT_SNEAK, VanillaEnchantments::SWIFT_SNEAK());
|
||||
}
|
||||
|
||||
public function register(int $mcpeId, Enchantment $enchantment) : void{
|
||||
|
@ -66,4 +66,5 @@ final class EnchantmentIds{
|
||||
public const PIERCING = 34;
|
||||
public const QUICK_CHARGE = 35;
|
||||
public const SOUL_SPEED = 36;
|
||||
public const SWIFT_SNEAK = 37;
|
||||
}
|
||||
|
@ -1,134 +0,0 @@
|
||||
<?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\data\bedrock;
|
||||
|
||||
final class EntityLegacyIds{
|
||||
|
||||
public const CHICKEN = 10;
|
||||
public const COW = 11;
|
||||
public const PIG = 12;
|
||||
public const SHEEP = 13;
|
||||
public const WOLF = 14;
|
||||
public const VILLAGER = 15;
|
||||
public const MOOSHROOM = 16;
|
||||
public const SQUID = 17;
|
||||
public const RABBIT = 18;
|
||||
public const BAT = 19;
|
||||
public const IRON_GOLEM = 20;
|
||||
public const SNOW_GOLEM = 21;
|
||||
public const OCELOT = 22;
|
||||
public const HORSE = 23;
|
||||
public const DONKEY = 24;
|
||||
public const MULE = 25;
|
||||
public const SKELETON_HORSE = 26;
|
||||
public const ZOMBIE_HORSE = 27;
|
||||
public const POLAR_BEAR = 28;
|
||||
public const LLAMA = 29;
|
||||
public const PARROT = 30;
|
||||
public const DOLPHIN = 31;
|
||||
public const ZOMBIE = 32;
|
||||
public const CREEPER = 33;
|
||||
public const SKELETON = 34;
|
||||
public const SPIDER = 35;
|
||||
public const ZOMBIE_PIGMAN = 36;
|
||||
public const SLIME = 37;
|
||||
public const ENDERMAN = 38;
|
||||
public const SILVERFISH = 39;
|
||||
public const CAVE_SPIDER = 40;
|
||||
public const GHAST = 41;
|
||||
public const MAGMA_CUBE = 42;
|
||||
public const BLAZE = 43;
|
||||
public const ZOMBIE_VILLAGER = 44;
|
||||
public const WITCH = 45;
|
||||
public const STRAY = 46;
|
||||
public const HUSK = 47;
|
||||
public const WITHER_SKELETON = 48;
|
||||
public const GUARDIAN = 49;
|
||||
public const ELDER_GUARDIAN = 50;
|
||||
public const NPC = 51;
|
||||
public const WITHER = 52;
|
||||
public const ENDER_DRAGON = 53;
|
||||
public const SHULKER = 54;
|
||||
public const ENDERMITE = 55;
|
||||
public const AGENT = 56, LEARN_TO_CODE_MASCOT = 56;
|
||||
public const VINDICATOR = 57;
|
||||
public const PHANTOM = 58;
|
||||
|
||||
public const ARMOR_STAND = 61;
|
||||
public const TRIPOD_CAMERA = 62;
|
||||
public const PLAYER = 63;
|
||||
public const ITEM = 64;
|
||||
public const TNT = 65;
|
||||
public const FALLING_BLOCK = 66;
|
||||
public const MOVING_BLOCK = 67;
|
||||
public const XP_BOTTLE = 68;
|
||||
public const XP_ORB = 69;
|
||||
public const EYE_OF_ENDER_SIGNAL = 70;
|
||||
public const ENDER_CRYSTAL = 71;
|
||||
public const FIREWORKS_ROCKET = 72;
|
||||
public const THROWN_TRIDENT = 73, TRIDENT = 73;
|
||||
public const TURTLE = 74;
|
||||
public const CAT = 75;
|
||||
public const SHULKER_BULLET = 76;
|
||||
public const FISHING_HOOK = 77;
|
||||
public const CHALKBOARD = 78;
|
||||
public const DRAGON_FIREBALL = 79;
|
||||
public const ARROW = 80;
|
||||
public const SNOWBALL = 81;
|
||||
public const EGG = 82;
|
||||
public const PAINTING = 83;
|
||||
public const MINECART = 84;
|
||||
public const FIREBALL = 85, LARGE_FIREBALL = 85;
|
||||
public const SPLASH_POTION = 86;
|
||||
public const ENDER_PEARL = 87;
|
||||
public const LEASH_KNOT = 88;
|
||||
public const WITHER_SKULL = 89;
|
||||
public const BOAT = 90;
|
||||
public const WITHER_SKULL_DANGEROUS = 91;
|
||||
public const LIGHTNING_BOLT = 93;
|
||||
public const SMALL_FIREBALL = 94;
|
||||
public const AREA_EFFECT_CLOUD = 95;
|
||||
public const HOPPER_MINECART = 96;
|
||||
public const TNT_MINECART = 97;
|
||||
public const CHEST_MINECART = 98;
|
||||
|
||||
public const COMMAND_BLOCK_MINECART = 100;
|
||||
public const LINGERING_POTION = 101;
|
||||
public const LLAMA_SPIT = 102;
|
||||
public const EVOCATION_FANG = 103;
|
||||
public const EVOCATION_ILLAGER = 104;
|
||||
public const VEX = 105;
|
||||
public const ICE_BOMB = 106;
|
||||
public const BALLOON = 107;
|
||||
public const PUFFERFISH = 108;
|
||||
public const SALMON = 109;
|
||||
public const DROWNED = 110;
|
||||
public const TROPICALFISH = 111, TROPICAL_FISH = 111;
|
||||
public const COD = 112, FISH = 112;
|
||||
public const PANDA = 113;
|
||||
|
||||
private function __construct(){
|
||||
//NOOP
|
||||
}
|
||||
}
|
109
src/data/bedrock/ItemTagToIdMap.php
Normal file
109
src/data/bedrock/ItemTagToIdMap.php
Normal file
@ -0,0 +1,109 @@
|
||||
<?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\data\bedrock;
|
||||
|
||||
use pocketmine\errorhandler\ErrorToExceptionHandler;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
use pocketmine\utils\SingletonTrait;
|
||||
use pocketmine\utils\Utils;
|
||||
use Symfony\Component\Filesystem\Path;
|
||||
use function array_keys;
|
||||
use function file_get_contents;
|
||||
use function gettype;
|
||||
use function is_array;
|
||||
use function is_string;
|
||||
use function json_decode;
|
||||
use const JSON_THROW_ON_ERROR;
|
||||
use const pocketmine\BEDROCK_DATA_PATH;
|
||||
|
||||
/**
|
||||
* Tracks Minecraft Bedrock item tags, and the item IDs which belong to them
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class ItemTagToIdMap{
|
||||
use SingletonTrait;
|
||||
|
||||
private static function make() : self{
|
||||
$map = json_decode(ErrorToExceptionHandler::trapAndRemoveFalse(fn() => file_get_contents(Path::join(BEDROCK_DATA_PATH, 'item_tags.json'))), true, flags: JSON_THROW_ON_ERROR);
|
||||
if(!is_array($map)){
|
||||
throw new AssumptionFailedError("Invalid item tag map, expected array");
|
||||
}
|
||||
$cleanMap = [];
|
||||
foreach($map as $tagName => $ids){
|
||||
if(!is_string($tagName)){
|
||||
throw new AssumptionFailedError("Invalid item tag name $tagName, expected string as key");
|
||||
}
|
||||
if(!is_array($ids)){
|
||||
throw new AssumptionFailedError("Invalid item tag $tagName, expected array of IDs as value");
|
||||
}
|
||||
$cleanIds = [];
|
||||
foreach($ids as $id){
|
||||
if(!is_string($id)){
|
||||
throw new AssumptionFailedError("Invalid item tag $tagName, expected string as ID, got " . gettype($id));
|
||||
}
|
||||
$cleanIds[] = $id;
|
||||
}
|
||||
$cleanMap[$tagName] = $cleanIds;
|
||||
}
|
||||
|
||||
return new self($cleanMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* @var true[][]
|
||||
* @phpstan-var array<string, array<string, true>>
|
||||
*/
|
||||
private array $tagToIdsMap = [];
|
||||
|
||||
/**
|
||||
* @param string[][] $tagToIds
|
||||
* @phpstan-param array<string, list<string>> $tagToIds
|
||||
*/
|
||||
public function __construct(
|
||||
array $tagToIds
|
||||
){
|
||||
foreach(Utils::stringifyKeys($tagToIds) as $tag => $ids){
|
||||
foreach($ids as $id){
|
||||
$this->tagToIdsMap[$tag][$id] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
* @phpstan-return list<string>
|
||||
*/
|
||||
public function getIdsForTag(string $tag) : array{
|
||||
return array_keys($this->tagToIdsMap[$tag] ?? []);
|
||||
}
|
||||
|
||||
public function tagContainsId(string $tag, string $id) : bool{
|
||||
return isset($this->tagToIdsMap[$tag][$id]);
|
||||
}
|
||||
|
||||
public function addIdToTag(string $tag, string $id) : void{
|
||||
$this->tagToIdsMap[$tag][$id] = true;
|
||||
}
|
||||
}
|
@ -24,7 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\data\bedrock;
|
||||
|
||||
use pocketmine\utils\SingletonTrait;
|
||||
use Webmozart\PathUtil\Path;
|
||||
use Symfony\Component\Filesystem\Path;
|
||||
|
||||
final class LegacyBiomeIdToStringIdMap extends LegacyToStringIdMap{
|
||||
use SingletonTrait;
|
||||
|
@ -24,7 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\data\bedrock;
|
||||
|
||||
use pocketmine\utils\SingletonTrait;
|
||||
use Webmozart\PathUtil\Path;
|
||||
use Symfony\Component\Filesystem\Path;
|
||||
|
||||
final class LegacyEntityIdToStringIdMap extends LegacyToStringIdMap{
|
||||
use SingletonTrait;
|
||||
|
@ -33,13 +33,13 @@ final class PotionTypeIdMap{
|
||||
* @var PotionType[]
|
||||
* @phpstan-var array<int, PotionType>
|
||||
*/
|
||||
private array $idToEnum;
|
||||
private array $idToEnum = [];
|
||||
|
||||
/**
|
||||
* @var int[]
|
||||
* @phpstan-var array<int, int>
|
||||
*/
|
||||
private array $enumToId;
|
||||
private array $enumToId = [];
|
||||
|
||||
private function __construct(){
|
||||
$this->register(PotionTypeIds::WATER, PotionType::WATER());
|
||||
|
@ -33,13 +33,13 @@ final class SuspiciousStewTypeIdMap{
|
||||
* @var SuspiciousStewType[]
|
||||
* @phpstan-var array<int, SuspiciousStewType>
|
||||
*/
|
||||
private array $idToEnum;
|
||||
private array $idToEnum = [];
|
||||
|
||||
/**
|
||||
* @var int[]
|
||||
* @phpstan-var array<int, int>
|
||||
*/
|
||||
private array $enumToId;
|
||||
private array $enumToId = [];
|
||||
|
||||
private function __construct(){
|
||||
$this->register(SuspiciousStewTypeIds::POPPY, SuspiciousStewType::POPPY());
|
||||
|
@ -93,6 +93,7 @@ use pocketmine\block\LitPumpkin;
|
||||
use pocketmine\block\Loom;
|
||||
use pocketmine\block\MelonStem;
|
||||
use pocketmine\block\NetherPortal;
|
||||
use pocketmine\block\NetherVines;
|
||||
use pocketmine\block\NetherWartPlant;
|
||||
use pocketmine\block\Potato;
|
||||
use pocketmine\block\PoweredRail;
|
||||
@ -1389,6 +1390,10 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{
|
||||
->writeBool(StateNames::POWERED_BIT, $block->isPowered())
|
||||
->writeLegacyHorizontalFacing($block->getFacing());
|
||||
});
|
||||
$this->map(Blocks::TWISTING_VINES(), function(NetherVines $block) : Writer{
|
||||
return Writer::create(Ids::TWISTING_VINES)
|
||||
->writeInt(StateNames::TWISTING_VINES_AGE, $block->getAge());
|
||||
});
|
||||
$this->map(Blocks::UNDERWATER_TORCH(), function(UnderwaterTorch $block) : Writer{
|
||||
return Writer::create(Ids::UNDERWATER_TORCH)
|
||||
->writeTorchFacing($block->getFacing());
|
||||
@ -1425,6 +1430,10 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{
|
||||
$this->map(Blocks::WARPED_TRAPDOOR(), fn(Trapdoor $block) => Helper::encodeTrapdoor($block, new Writer(Ids::WARPED_TRAPDOOR)));
|
||||
$this->map(Blocks::WARPED_WALL_SIGN(), fn(WallSign $block) => Helper::encodeWallSign($block, new Writer(Ids::WARPED_WALL_SIGN)));
|
||||
$this->map(Blocks::WATER(), fn(Water $block) => Helper::encodeLiquid($block, Ids::WATER, Ids::FLOWING_WATER));
|
||||
$this->map(Blocks::WEEPING_VINES(), function(NetherVines $block) : Writer{
|
||||
return Writer::create(Ids::WEEPING_VINES)
|
||||
->writeInt(StateNames::WEEPING_VINES_AGE, $block->getAge());
|
||||
});
|
||||
$this->map(Blocks::WEIGHTED_PRESSURE_PLATE_HEAVY(), function(WeightedPressurePlateHeavy $block) : Writer{
|
||||
return Writer::create(Ids::HEAVY_WEIGHTED_PRESSURE_PLATE)
|
||||
->writeInt(StateNames::REDSTONE_SIGNAL, $block->getOutputSignalStrength());
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user