mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-13 12:55:06 +00:00
Compare commits
340 Commits
1.7dev-717
...
1.7dev-999
Author | SHA1 | Date | |
---|---|---|---|
2034caf71c | |||
89ccac7a8c | |||
f6e71d8296 | |||
b333a0e24c | |||
5b6762d0d5 | |||
68638f9779 | |||
8228774ad4 | |||
2a54726905 | |||
8b225fc4ef | |||
a014b44b69 | |||
c7544c1d25 | |||
eb28622823 | |||
68494f1c0d | |||
27ea0d360f | |||
d384df1f2e | |||
fe8102c062 | |||
8b15d85469 | |||
a5ba716232 | |||
db432bb024 | |||
91486a23a5 | |||
c276ef2b7f | |||
5138bdc4bd | |||
a30a157d8c | |||
e565cdeea4 | |||
556a465c05 | |||
280f2b7259 | |||
933b0e8b41 | |||
58279d4cfe | |||
1e21066c1c | |||
76854da7ba | |||
46cbcb0c42 | |||
af9b0b019d | |||
7db8845375 | |||
f47f593555 | |||
691df5c11d | |||
9a1d3aec6b | |||
670a53ba3b | |||
f22ad14c67 | |||
64540f36be | |||
e66b1953de | |||
aa6666872a | |||
646455f6e8 | |||
05a1e61e5b | |||
5f52e00213 | |||
476ac39988 | |||
5f1ae1059e | |||
08d8adae5b | |||
8d988af7db | |||
db5890fddb | |||
5b532fdcf5 | |||
e85fc54037 | |||
7fb237938c | |||
9a5f9c8586 | |||
4b16be7e0b | |||
47faf5a994 | |||
3f31f6d310 | |||
c06c1c7ce0 | |||
a889a0e517 | |||
9ed0d9d36f | |||
3134fa2744 | |||
2660448601 | |||
eb354916d4 | |||
033b44df5a | |||
ef2dd1de92 | |||
5b7b2dd0e2 | |||
3a10df634b | |||
f1aecc3a71 | |||
42d04a4418 | |||
3fe4ebc301 | |||
d97abfaa7b | |||
526f05631e | |||
ebaef89e06 | |||
6ab0cff9d3 | |||
ae31ce1d25 | |||
a1cf5dbd1e | |||
c86132028e | |||
5ce55bd3b0 | |||
c81f178cdb | |||
fc795b80ae | |||
99134de6b6 | |||
1fc388d6de | |||
eba1ca030c | |||
8ce0fab8cc | |||
5ed2d6022c | |||
37d085f793 | |||
69c54de460 | |||
b9d3bd22a3 | |||
d4d57aa9ea | |||
4ce1f228e6 | |||
4b03dbebba | |||
1d5978df98 | |||
5d32587cf7 | |||
d53258c943 | |||
773f760fff | |||
c20b16a0fe | |||
b151cb26a5 | |||
49622cc2a5 | |||
56328f66a7 | |||
f41a731493 | |||
ec332e3e60 | |||
a1090623a2 | |||
8572e9e560 | |||
bc836aaec1 | |||
145a4fad0f | |||
08c48d8145 | |||
81ecb56095 | |||
a6d7365a28 | |||
1f4f8ab3f0 | |||
1420cd1fa5 | |||
30a83544a0 | |||
7e20385bdb | |||
c7e803372c | |||
cf3638ad8d | |||
0dd8fd2651 | |||
c0c684b12e | |||
924334a776 | |||
be7c27f60d | |||
2b37b4a659 | |||
a4c50d3204 | |||
eb9f60f41c | |||
071aa44d29 | |||
25089f5e70 | |||
22dd8faf1d | |||
7354a55af8 | |||
611f5d684b | |||
9a099d3f5d | |||
5eb1ee3416 | |||
e4b6a18404 | |||
364d278714 | |||
c464d39401 | |||
a185b78486 | |||
c19cf22ac5 | |||
d2fb32c28a | |||
49fbbea7bf | |||
1648fff916 | |||
73e09392b6 | |||
209e28dfe5 | |||
ac5a91b67e | |||
24c5d7557e | |||
3d89bf5693 | |||
e48ec9fb71 | |||
95606b6e04 | |||
c243daabe1 | |||
357674cb54 | |||
9d5eeb328e | |||
b2ee6b2ca5 | |||
2860e9e8ee | |||
e82073834f | |||
7fcc538a75 | |||
7f6b8ad7c2 | |||
313b224bec | |||
d12b1d3e07 | |||
eeeef8df51 | |||
9c786089f8 | |||
e3cae7364f | |||
d542bbc736 | |||
e88541b269 | |||
fdad965db8 | |||
dd844f7ad3 | |||
596c8a7b4f | |||
9c598d1345 | |||
a2af838b1d | |||
bf97eab98f | |||
a9a55e9558 | |||
95fb1d1602 | |||
fa644edef3 | |||
ddc9dca8b4 | |||
86eee429bb | |||
4f20a504e3 | |||
6a1f8640f6 | |||
8a0414f306 | |||
d478661961 | |||
b8064aa45c | |||
00f596c4f8 | |||
3f7b14bf59 | |||
ba0a256834 | |||
f2f8c235e7 | |||
69b3bb183d | |||
cd35bd6872 | |||
d09a43cfef | |||
40b995a435 | |||
590826b9bd | |||
a5e87484d9 | |||
8a86e0825b | |||
b39bbffdc5 | |||
bd3d2451bc | |||
606407933e | |||
ad09e8c8d0 | |||
486edf0e55 | |||
2ee01eb195 | |||
9098502199 | |||
b130374e46 | |||
31106bc227 | |||
cc1a3d695f | |||
8020780fc5 | |||
2f266a5922 | |||
3827892e48 | |||
e06b78b0ee | |||
74cff89df3 | |||
a9957c3db3 | |||
2e9bf7e93b | |||
dbcc69c2de | |||
cdd3fe81e1 | |||
a8a3eb3866 | |||
83a3c6f614 | |||
8cc6a32a04 | |||
c1a2144f60 | |||
b2491a5874 | |||
2e125168c3 | |||
5059a92b91 | |||
ea5db98d12 | |||
1f77c074e9 | |||
73a5788774 | |||
dc3bf8546e | |||
c7f8796136 | |||
c5336776a5 | |||
b623c4aba1 | |||
49a39fc7bd | |||
2e4519cb36 | |||
2ff3b12376 | |||
9e4bccd8c0 | |||
1c5180b720 | |||
fa6d44ea9e | |||
9d018e8d9e | |||
ae2e1fdd5a | |||
97bfcf6e71 | |||
5457c7a202 | |||
ee28296d60 | |||
06af742bef | |||
6bdf5e15c0 | |||
d4eba3f4b1 | |||
5a89e80873 | |||
28e601bbb9 | |||
7e9f1324a7 | |||
973d5dc251 | |||
533d139385 | |||
6a94c8183c | |||
629a254639 | |||
732b931556 | |||
2dd1878d57 | |||
3104a312b2 | |||
d6d47feda9 | |||
0ba1b58ee0 | |||
ab2df8b11b | |||
eb01dcaf60 | |||
f0535df96d | |||
f903dbfe00 | |||
e0d5c79848 | |||
e024f381c9 | |||
2a09aaf456 | |||
0ad8ea6e92 | |||
bd47852ca4 | |||
2b036b1a5c | |||
e5ec8fa603 | |||
abe5d94d5b | |||
da5febc34a | |||
3de5e132a2 | |||
37e8c8d324 | |||
aa11dbb928 | |||
e7adaef2d2 | |||
6bf9ae0a18 | |||
e7b2dc87d6 | |||
d7a02793fa | |||
6a996611f8 | |||
ad8d67137e | |||
cbbed6a6c1 | |||
99ef3e6576 | |||
eeaf75ac85 | |||
6954bfac4b | |||
f27b62027c | |||
093cb5b39e | |||
3f41628bf3 | |||
a3fa8adf4a | |||
08daf655e5 | |||
61fc090cf2 | |||
ecd830463c | |||
ffe89f5e1b | |||
88a05845c2 | |||
2cabdca3f7 | |||
be1ddb9f5b | |||
7fc3eeab00 | |||
9395dbf9fa | |||
a7396d7ae9 | |||
3b632c2870 | |||
7dd834bca0 | |||
2b6e135c83 | |||
c26e3aa9fa | |||
aeba15c5c6 | |||
4c583ec8ab | |||
af2435f199 | |||
456987e212 | |||
8e6ec04abc | |||
42a7b7fa36 | |||
ce4e0bf69c | |||
dc84484c2b | |||
e7e4645c0b | |||
4e9e285e37 | |||
3962d32ffe | |||
a84aba5517 | |||
0b82d5c8d4 | |||
3aef4c5a09 | |||
6307952ae9 | |||
f66928c345 | |||
9abfd54cc1 | |||
4a85311c5f | |||
8a4f6eb6c2 | |||
6e7a693355 | |||
b7bd8dc7f1 | |||
b445825467 | |||
98d6aea7fe | |||
b75d121c7e | |||
88bbb03f12 | |||
9478bc281f | |||
7ec886faa2 | |||
610e62e2cd | |||
906442136b | |||
3b36d46a8f | |||
63fa6a36a9 | |||
bab2daf711 | |||
5858025d90 | |||
dbac2abafb | |||
266d1cb935 | |||
ffbb44673f | |||
a84a8ecc14 | |||
687886e70b | |||
bad323f5cc | |||
ca9f700fb0 | |||
c51cc6b2fe | |||
03c66f0f86 | |||
610b041631 | |||
75289b1498 | |||
4eea54780a | |||
e860d32b3a | |||
c4486d9ad7 | |||
8222b16d9a | |||
dcb53b1cbb | |||
a52a2f6d26 | |||
906d7eb176 | |||
bf3f5532ac | |||
54f7a88fbb |
2
.github/ISSUE_TEMPLATE.md
vendored
2
.github/ISSUE_TEMPLATE.md
vendored
@ -28,7 +28,7 @@ NO support whatsoever will be provided for third-party modified variants of Pock
|
||||
|
||||
Note that 32-bit platforms are no longer supported by PocketMine-MP and issues concerning 32-bit platforms will be closed.
|
||||
-->
|
||||
* PocketMine-MP:
|
||||
* PocketMine-MP: <!-- LATEST IS NOT A VALID VERSION -->
|
||||
* PHP:
|
||||
* Server OS:
|
||||
* Game version: PE/Win10 (delete as appropriate)
|
||||
|
12
.github/support.yml
vendored
Normal file
12
.github/support.yml
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
# Configuration for support-requests - https://github.com/dessant/support-requests
|
||||
|
||||
# Label used to mark issues as support requests
|
||||
supportLabel: "Support request"
|
||||
# Comment to post on issues marked as support requests. Add a link
|
||||
# to a support page, or set to `false` to disable
|
||||
supportComment: >
|
||||
This issue tracker is not a support forum. Please use the [forums](https://forums.pmmp.io) for support.
|
||||
# Whether to close issues marked as support requests
|
||||
close: true
|
||||
# Whether to lock issues marked as support requests
|
||||
lock: false
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -9,7 +9,7 @@ crashdumps/*
|
||||
*.phar
|
||||
server.properties
|
||||
/pocketmine.yml
|
||||
memoryDump_*/*
|
||||
memory_dumps/*
|
||||
resource_packs/
|
||||
|
||||
# Common IDEs
|
||||
|
@ -5,7 +5,7 @@
|
||||
"homepage": "https://pmmp.io",
|
||||
"license": "LGPL-3.0",
|
||||
"require": {
|
||||
"php": ">=7.2.0RC3",
|
||||
"php": ">=7.2.0",
|
||||
"ext-bcmath": "*",
|
||||
"ext-curl": "*",
|
||||
"ext-hash": "*",
|
||||
@ -21,13 +21,14 @@
|
||||
"ext-yaml": ">=2.0.0",
|
||||
"ext-zip": "*",
|
||||
"ext-zlib": ">=1.2.11",
|
||||
"pocketmine/raklib": "dev-master#eaa85c2b23bbc1a85030a621d4644c0e33e05950",
|
||||
"pocketmine/pocketmine-spl": "^0.2.0",
|
||||
"pocketmine/pocketmine-binaryutils": "dev-master#a7cd5303a3b215d26bf9be76682ce9311f40e887",
|
||||
"pocketmine/pocketmine-nbt": "dev-master#f8934c0aed90d1f55452588f7ebef7c4519518a5"
|
||||
"pocketmine/raklib": "0.11.0",
|
||||
"pocketmine/spl": "0.3.0",
|
||||
"pocketmine/binaryutils": "0.0.1",
|
||||
"pocketmine/nbt": "0.1.0",
|
||||
"pocketmine/math": "0.1.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"psr-4": {
|
||||
"": ["src"]
|
||||
}
|
||||
},
|
||||
@ -38,15 +39,19 @@
|
||||
},
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/pmmp/PocketMine-SPL"
|
||||
"url": "https://github.com/pmmp/SPL"
|
||||
},
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/pmmp/PocketMine-BinaryUtils"
|
||||
"url": "https://github.com/pmmp/BinaryUtils"
|
||||
},
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/pmmp/PocketMine-NBT"
|
||||
"url": "https://github.com/pmmp/NBT"
|
||||
},
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/pmmp/Math"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
178
composer.lock
generated
178
composer.lock
generated
@ -4,20 +4,20 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "5997f272811ed1148e7699a33335a0d2",
|
||||
"content-hash": "401dbada37e501304f05b0f1fa818953",
|
||||
"packages": [
|
||||
{
|
||||
"name": "pocketmine/pocketmine-binaryutils",
|
||||
"version": "dev-master",
|
||||
"name": "pocketmine/binaryutils",
|
||||
"version": "0.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/PocketMine-BinaryUtils.git",
|
||||
"reference": "a7cd5303a3b215d26bf9be76682ce9311f40e887"
|
||||
"url": "https://github.com/pmmp/BinaryUtils.git",
|
||||
"reference": "03e6851f814aba96487ec64181a6ae948edd9f7a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/PocketMine-BinaryUtils/zipball/a7cd5303a3b215d26bf9be76682ce9311f40e887",
|
||||
"reference": "a7cd5303a3b215d26bf9be76682ce9311f40e887",
|
||||
"url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/03e6851f814aba96487ec64181a6ae948edd9f7a",
|
||||
"reference": "03e6851f814aba96487ec64181a6ae948edd9f7a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -34,28 +34,61 @@
|
||||
],
|
||||
"description": "Classes and methods for conveniently handling binary data",
|
||||
"support": {
|
||||
"source": "https://github.com/pmmp/PocketMine-BinaryUtils/tree/master",
|
||||
"issues": "https://github.com/pmmp/PocketMine-BinaryUtils/issues"
|
||||
"source": "https://github.com/pmmp/BinaryUtils/tree/master",
|
||||
"issues": "https://github.com/pmmp/BinaryUtils/issues"
|
||||
},
|
||||
"time": "2018-01-14T18:53:25+00:00"
|
||||
"time": "2018-03-17T11:57:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/pocketmine-nbt",
|
||||
"version": "dev-master",
|
||||
"name": "pocketmine/math",
|
||||
"version": "0.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/PocketMine-NBT.git",
|
||||
"reference": "f8934c0aed90d1f55452588f7ebef7c4519518a5"
|
||||
"url": "https://github.com/pmmp/Math.git",
|
||||
"reference": "1df74f0352309a9c1e6728fa416a3f0493d07b16"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/PocketMine-NBT/zipball/f8934c0aed90d1f55452588f7ebef7c4519518a5",
|
||||
"reference": "f8934c0aed90d1f55452588f7ebef7c4519518a5",
|
||||
"url": "https://api.github.com/repos/pmmp/Math/zipball/1df74f0352309a9c1e6728fa416a3f0493d07b16",
|
||||
"reference": "1df74f0352309a9c1e6728fa416a3f0493d07b16",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"pocketmine\\math\\": "src/"
|
||||
}
|
||||
},
|
||||
"license": [
|
||||
"LGPL-3.0"
|
||||
],
|
||||
"description": "PHP library containing math related code used in PocketMine-MP",
|
||||
"support": {
|
||||
"source": "https://github.com/pmmp/Math/tree/master",
|
||||
"issues": "https://github.com/pmmp/Math/issues"
|
||||
},
|
||||
"time": "2018-03-18T18:01:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/nbt",
|
||||
"version": "0.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/NBT.git",
|
||||
"reference": "d79f8615442887bb45cfacdb52e1e6eb47c38fd7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/NBT/zipball/d79f8615442887bb45cfacdb52e1e6eb47c38fd7",
|
||||
"reference": "d79f8615442887bb45cfacdb52e1e6eb47c38fd7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.0",
|
||||
"pocketmine/pocketmine-binaryutils": "dev-master#8bb34e771fee69abcc5482d17d2fa0b4f0e15a5e"
|
||||
"pocketmine/binaryutils": "0.0.1"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@ -63,28 +96,71 @@
|
||||
"pocketmine\\nbt\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"pocketmine\\nbt\\": "tests/phpunit/"
|
||||
}
|
||||
},
|
||||
"license": [
|
||||
"LGPL-3.0"
|
||||
],
|
||||
"description": "PHP library for working with Named Binary Tags",
|
||||
"support": {
|
||||
"source": "https://github.com/pmmp/PocketMine-NBT/tree/master",
|
||||
"issues": "https://github.com/pmmp/PocketMine-NBT/issues"
|
||||
"source": "https://github.com/pmmp/NBT/tree/0.1.0",
|
||||
"issues": "https://github.com/pmmp/NBT/issues"
|
||||
},
|
||||
"time": "2018-01-11T13:51:50+00:00"
|
||||
"time": "2018-04-13T18:43:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/pocketmine-spl",
|
||||
"version": "0.2.0",
|
||||
"name": "pocketmine/raklib",
|
||||
"version": "0.11.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/PocketMine-SPL.git",
|
||||
"reference": "70c591a44b6c5aa541a1a55585764bed2b23148c"
|
||||
"url": "https://github.com/pmmp/RakLib.git",
|
||||
"reference": "1da1b4c6cc6bd5337ce5e468d22bbb013ae02b43"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/PocketMine-SPL/zipball/70c591a44b6c5aa541a1a55585764bed2b23148c",
|
||||
"reference": "70c591a44b6c5aa541a1a55585764bed2b23148c",
|
||||
"url": "https://api.github.com/repos/pmmp/RakLib/zipball/1da1b4c6cc6bd5337ce5e468d22bbb013ae02b43",
|
||||
"reference": "1da1b4c6cc6bd5337ce5e468d22bbb013ae02b43",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-bcmath": "*",
|
||||
"ext-pthreads": ">=3.1.7dev",
|
||||
"ext-sockets": "*",
|
||||
"php": ">=7.2.0RC3",
|
||||
"pocketmine/binaryutils": "0.0.1",
|
||||
"pocketmine/spl": "0.3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"./"
|
||||
]
|
||||
},
|
||||
"license": [
|
||||
"GPL-3.0"
|
||||
],
|
||||
"description": "A RakNet server implementation written in PHP",
|
||||
"support": {
|
||||
"source": "https://github.com/pmmp/RakLib/tree/0.11.0",
|
||||
"issues": "https://github.com/pmmp/RakLib/issues"
|
||||
},
|
||||
"time": "2018-04-13T19:05:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/spl",
|
||||
"version": "0.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/SPL.git",
|
||||
"reference": "ee32424c100fd11ae7f7b8df7604623fd475f0ec"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/SPL/zipball/ee32424c100fd11ae7f7b8df7604623fd475f0ec",
|
||||
"reference": "ee32424c100fd11ae7f7b8df7604623fd475f0ec",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
@ -101,63 +177,21 @@
|
||||
],
|
||||
"description": "Standard library files required by PocketMine-MP and related projects",
|
||||
"support": {
|
||||
"source": "https://github.com/pmmp/PocketMine-SPL/tree/master"
|
||||
"source": "https://github.com/pmmp/SPL/tree/master"
|
||||
},
|
||||
"time": "2018-01-11T13:03:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/raklib",
|
||||
"version": "dev-master",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/RakLib.git",
|
||||
"reference": "eaa85c2b23bbc1a85030a621d4644c0e33e05950"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/RakLib/zipball/eaa85c2b23bbc1a85030a621d4644c0e33e05950",
|
||||
"reference": "eaa85c2b23bbc1a85030a621d4644c0e33e05950",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-bcmath": "*",
|
||||
"ext-pthreads": ">=3.1.7dev",
|
||||
"ext-sockets": "*",
|
||||
"php": ">=7.2.0RC3",
|
||||
"pocketmine/pocketmine-binaryutils": "dev-master#a7cd5303a3b215d26bf9be76682ce9311f40e887",
|
||||
"pocketmine/pocketmine-spl": "^0.2.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"./"
|
||||
]
|
||||
},
|
||||
"license": [
|
||||
"GPL-3.0"
|
||||
],
|
||||
"description": "A RakNet server implementation written in PHP",
|
||||
"support": {
|
||||
"source": "https://github.com/pmmp/RakLib/tree/master",
|
||||
"issues": "https://github.com/pmmp/RakLib/issues"
|
||||
},
|
||||
"time": "2018-01-27T15:38:43+00:00"
|
||||
"time": "2018-03-17T11:56:20+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": {
|
||||
"php": 5,
|
||||
"ext-pthreads": 20,
|
||||
"pocketmine/raklib": 20,
|
||||
"pocketmine/pocketmine-binaryutils": 20,
|
||||
"pocketmine/pocketmine-nbt": 20
|
||||
"ext-pthreads": 20
|
||||
},
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
"php": ">=7.2.0RC3",
|
||||
"php": ">=7.2.0",
|
||||
"ext-bcmath": "*",
|
||||
"ext-curl": "*",
|
||||
"ext-hash": "*",
|
||||
|
@ -2319,4 +2319,3 @@ GENERATE_LEGEND = YES
|
||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||
|
||||
DOT_CLEANUP = YES
|
||||
|
||||
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\utils\TextFormat;
|
||||
|
||||
/**
|
||||
@ -116,7 +116,7 @@ abstract class Achievement{
|
||||
public static function broadcast(Player $player, string $achievementId) : bool{
|
||||
if(isset(Achievement::$list[$achievementId])){
|
||||
$translation = new TranslationContainer("chat.type.achievement", [$player->getDisplayName(), TextFormat::GREEN . Achievement::$list[$achievementId]["name"] . TextFormat::RESET]);
|
||||
if(Server::getInstance()->getConfigBool("announce-player-achievements", true) === true){
|
||||
if(Server::getInstance()->getConfigBool("announce-player-achievements", true)){
|
||||
Server::getInstance()->broadcastMessage($translation);
|
||||
}else{
|
||||
$player->sendMessage($translation);
|
||||
|
@ -115,10 +115,10 @@ class CrashDump{
|
||||
}
|
||||
|
||||
private function extraData(){
|
||||
global $arguments;
|
||||
global $argv;
|
||||
|
||||
if($this->server->getProperty("auto-report.send-settings", true) !== false){
|
||||
$this->data["parameters"] = (array) $arguments;
|
||||
$this->data["parameters"] = (array) $argv;
|
||||
$this->data["server.properties"] = @file_get_contents($this->server->getDataPath() . "server.properties");
|
||||
$this->data["server.properties"] = preg_replace("#^rcon\\.password=(.*)$#m", "rcon.password=******", $this->data["server.properties"]);
|
||||
$this->data["pocketmine.yml"] = @file_get_contents($this->server->getDataPath() . "pocketmine.yml");
|
||||
@ -148,7 +148,7 @@ class CrashDump{
|
||||
$error = $lastExceptionError;
|
||||
}else{
|
||||
$error = (array) error_get_last();
|
||||
$error["trace"] = getTrace(4); //Skipping CrashDump->baseCrash, CrashDump->construct, Server->crashDump
|
||||
$error["trace"] = Utils::getTrace(4); //Skipping CrashDump->baseCrash, CrashDump->construct, Server->crashDump
|
||||
$errorConversion = [
|
||||
E_ERROR => "E_ERROR",
|
||||
E_WARNING => "E_WARNING",
|
||||
@ -167,7 +167,7 @@ class CrashDump{
|
||||
E_USER_DEPRECATED => "E_USER_DEPRECATED"
|
||||
];
|
||||
$error["fullFile"] = $error["file"];
|
||||
$error["file"] = cleanPath($error["file"]);
|
||||
$error["file"] = Utils::cleanPath($error["file"]);
|
||||
$error["type"] = $errorConversion[$error["type"]] ?? $error["type"];
|
||||
if(($pos = strpos($error["message"], "\n")) !== false){
|
||||
$error["message"] = substr($error["message"], 0, $pos);
|
||||
@ -195,7 +195,7 @@ class CrashDump{
|
||||
$file = $reflection->getProperty("file");
|
||||
$file->setAccessible(true);
|
||||
foreach($this->server->getPluginManager()->getPlugins() as $plugin){
|
||||
$filePath = \pocketmine\cleanPath($file->getValue($plugin));
|
||||
$filePath = Utils::cleanPath($file->getValue($plugin));
|
||||
if(strpos($error["file"], $filePath) === 0){
|
||||
$this->data["plugin"] = $plugin->getName();
|
||||
$this->addLine("BAD PLUGIN: " . $plugin->getDescription()->getFullName());
|
||||
|
@ -24,9 +24,9 @@ declare(strict_types=1);
|
||||
namespace pocketmine;
|
||||
|
||||
use pocketmine\event\server\LowMemoryEvent;
|
||||
use pocketmine\event\Timings;
|
||||
use pocketmine\scheduler\DumpWorkerMemoryTask;
|
||||
use pocketmine\scheduler\GarbageCollectionTask;
|
||||
use pocketmine\timings\Timings;
|
||||
use pocketmine\utils\MainLogger;
|
||||
use pocketmine\utils\Utils;
|
||||
|
||||
|
@ -72,7 +72,7 @@ class OfflinePlayer implements IPlayer, Metadatable{
|
||||
return;
|
||||
}
|
||||
|
||||
if($value === true){
|
||||
if($value){
|
||||
$this->server->addOp(strtolower($this->getName()));
|
||||
}else{
|
||||
$this->server->removeOp(strtolower($this->getName()));
|
||||
@ -84,7 +84,7 @@ class OfflinePlayer implements IPlayer, Metadatable{
|
||||
}
|
||||
|
||||
public function setBanned(bool $value){
|
||||
if($value === true){
|
||||
if($value){
|
||||
$this->server->getNameBans()->addBan($this->getName(), null, null, null);
|
||||
}else{
|
||||
$this->server->getNameBans()->remove($this->getName());
|
||||
@ -96,7 +96,7 @@ class OfflinePlayer implements IPlayer, Metadatable{
|
||||
}
|
||||
|
||||
public function setWhitelisted(bool $value){
|
||||
if($value === true){
|
||||
if($value){
|
||||
$this->server->addWhitelist(strtolower($this->getName()));
|
||||
}else{
|
||||
$this->server->removeWhitelist(strtolower($this->getName()));
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -71,37 +71,99 @@ namespace {
|
||||
|
||||
namespace pocketmine {
|
||||
|
||||
use pocketmine\utils\Binary;
|
||||
use pocketmine\utils\MainLogger;
|
||||
use pocketmine\utils\ServerKiller;
|
||||
use pocketmine\utils\Terminal;
|
||||
use pocketmine\utils\Timezone;
|
||||
use pocketmine\utils\Utils;
|
||||
use pocketmine\wizard\SetupWizard;
|
||||
use raklib\RakLib;
|
||||
|
||||
const NAME = "PocketMine-MP";
|
||||
const VERSION = "1.7dev";
|
||||
const API_VERSION = "3.0.0-ALPHA11";
|
||||
const API_VERSION = "3.0.0-ALPHA12";
|
||||
const CODENAME = "[REDACTED]";
|
||||
|
||||
const MIN_PHP_VERSION = "7.2.0RC3";
|
||||
const MIN_PHP_VERSION = "7.2.0";
|
||||
|
||||
function critical_error($message){
|
||||
echo "[ERROR] $message" . PHP_EOL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Startup code. Do not look at it, it may harm you.
|
||||
* Most of them are hacks to fix date-related bugs, or basic functions used after this
|
||||
* This is the only non-class based file on this project.
|
||||
* Enjoy it as much as I did writing it. I don't want to do it again.
|
||||
*/
|
||||
|
||||
if(version_compare(MIN_PHP_VERSION, PHP_VERSION) > 0){
|
||||
echo "[CRITICAL] " . \pocketmine\NAME . " requires PHP >= " . MIN_PHP_VERSION . ", but you have PHP " . PHP_VERSION . "." . PHP_EOL;
|
||||
echo "[CRITICAL] Please use the installer provided on the homepage, or update to a newer PHP version." . PHP_EOL;
|
||||
critical_error(\pocketmine\NAME . " requires PHP >= " . MIN_PHP_VERSION . ", but you have PHP " . PHP_VERSION . ".");
|
||||
critical_error("Please use the installer provided on the homepage, or update to a newer PHP version.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(!extension_loaded("pthreads")){
|
||||
echo "[CRITICAL] Unable to find the pthreads extension." . PHP_EOL;
|
||||
echo "[CRITICAL] Please use the installer provided on the homepage." . PHP_EOL;
|
||||
if(PHP_INT_SIZE < 8){
|
||||
critical_error("Running " . \pocketmine\NAME . " with 32-bit systems/PHP is no longer supported.");
|
||||
critical_error("Please upgrade to a 64-bit system, or use a 64-bit PHP binary if this is a 64-bit system.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Dependencies check */
|
||||
|
||||
$errors = 0;
|
||||
|
||||
if(php_sapi_name() !== "cli"){
|
||||
critical_error("You must run " . \pocketmine\NAME . " using the CLI.");
|
||||
++$errors;
|
||||
}
|
||||
|
||||
$extensions = [
|
||||
"bcmath" => "BC Math",
|
||||
"curl" => "cURL",
|
||||
"json" => "JSON",
|
||||
"mbstring" => "Multibyte String",
|
||||
"openssl" => "OpenSSL",
|
||||
"phar" => "Phar",
|
||||
"pthreads" => "pthreads",
|
||||
"sockets" => "Sockets",
|
||||
"yaml" => "YAML",
|
||||
"zip" => "Zip",
|
||||
"zlib" => "Zlib"
|
||||
];
|
||||
|
||||
foreach($extensions as $ext => $name){
|
||||
if(!extension_loaded($ext)){
|
||||
critical_error("Unable to find the $name ($ext) extension.");
|
||||
++$errors;
|
||||
}
|
||||
}
|
||||
|
||||
if(extension_loaded("pthreads")){
|
||||
$pthreads_version = phpversion("pthreads");
|
||||
if(substr_count($pthreads_version, ".") < 2){
|
||||
$pthreads_version = "0.$pthreads_version";
|
||||
}
|
||||
if(version_compare($pthreads_version, "3.1.7-dev") < 0){
|
||||
critical_error("pthreads >= 3.1.7-dev is required, while you have $pthreads_version.");
|
||||
++$errors;
|
||||
}
|
||||
}
|
||||
|
||||
if(extension_loaded("leveldb")){
|
||||
$leveldb_version = phpversion("leveldb");
|
||||
if(version_compare($leveldb_version, "0.2.1") < 0){
|
||||
critical_error("php-leveldb >= 0.2.1 is required, while you have $leveldb_version");
|
||||
++$errors;
|
||||
}
|
||||
}
|
||||
|
||||
if(extension_loaded("pocketmine")){
|
||||
critical_error("The native PocketMine extension is no longer supported.");
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if($errors > 0){
|
||||
critical_error("Please use the installer provided on the homepage, or recompile PHP again.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -117,12 +179,6 @@ namespace pocketmine {
|
||||
|
||||
set_error_handler('\pocketmine\error_handler');
|
||||
|
||||
if(!extension_loaded("phar")){
|
||||
echo "[CRITICAL] Unable to find the Phar extension." . PHP_EOL;
|
||||
echo "[CRITICAL] Please use the installer provided on the homepage." . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(\Phar::running(true) !== ""){
|
||||
define('pocketmine\PATH', \Phar::running(true) . "/");
|
||||
}else{
|
||||
@ -132,8 +188,8 @@ namespace pocketmine {
|
||||
define('pocketmine\COMPOSER_AUTOLOADER_PATH', \pocketmine\PATH . 'vendor/autoload.php');
|
||||
|
||||
function composer_error_die($message){
|
||||
echo "[CRITICAL] $message" . PHP_EOL;
|
||||
echo "[CRITICAL] Please install/update Composer dependencies or use provided builds." . PHP_EOL;
|
||||
critical_error($message);
|
||||
critical_error("Please install/update Composer dependencies or use provided builds.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -146,8 +202,8 @@ namespace pocketmine {
|
||||
if(!class_exists(RakLib::class)){
|
||||
composer_error_die("Unable to find the RakLib library.");
|
||||
}
|
||||
if(version_compare(RakLib::VERSION, "0.9.0") < 0){ //TODO: remove this check (it's managed by Composer now)
|
||||
composer_error_die("RakLib version 0.9.0 is required, while you have version " . RakLib::VERSION . ".");
|
||||
if(version_compare(RakLib::VERSION, "0.11.0") < 0){ //TODO: remove this check (it's managed by Composer now)
|
||||
composer_error_die("RakLib version 0.11.0 is required, while you have version " . RakLib::VERSION . ".");
|
||||
}
|
||||
if(!class_exists(\BaseClassLoader::class)){
|
||||
composer_error_die("Unable to find the PocketMine-SPL library.");
|
||||
@ -184,176 +240,16 @@ namespace pocketmine {
|
||||
mkdir(\pocketmine\DATA, 0777, true);
|
||||
}
|
||||
|
||||
//Logger has a dependency on timezone, so we'll set it to UTC until we can get the actual timezone.
|
||||
date_default_timezone_set("UTC");
|
||||
//Logger has a dependency on timezone
|
||||
$tzError = Timezone::init();
|
||||
|
||||
$logger = new MainLogger(\pocketmine\DATA . "server.log");
|
||||
$logger->registerStatic();
|
||||
|
||||
do{
|
||||
$timezone = ini_get("date.timezone");
|
||||
if($timezone !== ""){
|
||||
/*
|
||||
* This is here so that people don't come to us complaining and fill up the issue tracker when they put
|
||||
* an incorrect timezone abbreviation in php.ini apparently.
|
||||
*/
|
||||
if(strpos($timezone, "/") === false){
|
||||
$default_timezone = timezone_name_from_abbr($timezone);
|
||||
if($default_timezone !== false){
|
||||
ini_set("date.timezone", $default_timezone);
|
||||
date_default_timezone_set($default_timezone);
|
||||
break;
|
||||
}else{
|
||||
//Bad php.ini value, try another method to detect timezone
|
||||
$logger->warning("Timezone \"$timezone\" could not be parsed as a valid timezone from php.ini, falling back to auto-detection");
|
||||
}
|
||||
}else{
|
||||
date_default_timezone_set($timezone);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(($timezone = detect_system_timezone()) and date_default_timezone_set($timezone)){
|
||||
//Success! Timezone has already been set and validated in the if statement.
|
||||
//This here is just for redundancy just in case some program wants to read timezone data from the ini.
|
||||
ini_set("date.timezone", $timezone);
|
||||
break;
|
||||
}
|
||||
|
||||
if($response = Utils::getURL("http://ip-api.com/json") //If system timezone detection fails or timezone is an invalid value.
|
||||
and $ip_geolocation_data = json_decode($response, true)
|
||||
and $ip_geolocation_data['status'] !== 'fail'
|
||||
and date_default_timezone_set($ip_geolocation_data['timezone'])
|
||||
){
|
||||
//Again, for redundancy.
|
||||
ini_set("date.timezone", $ip_geolocation_data['timezone']);
|
||||
break;
|
||||
}
|
||||
|
||||
ini_set("date.timezone", "UTC");
|
||||
date_default_timezone_set("UTC");
|
||||
$logger->warning("Timezone could not be automatically determined or was set to an invalid value. An incorrect timezone will result in incorrect timestamps on console logs. It has been set to \"UTC\" by default. You can change it on the php.ini file.");
|
||||
}while(false);
|
||||
|
||||
|
||||
function detect_system_timezone(){
|
||||
switch(Utils::getOS()){
|
||||
case 'win':
|
||||
$regex = '/(UTC)(\+*\-*\d*\d*\:*\d*\d*)/';
|
||||
|
||||
/*
|
||||
* wmic timezone get Caption
|
||||
* Get the timezone offset
|
||||
*
|
||||
* Sample Output var_dump
|
||||
* array(3) {
|
||||
* [0] =>
|
||||
* string(7) "Caption"
|
||||
* [1] =>
|
||||
* string(20) "(UTC+09:30) Adelaide"
|
||||
* [2] =>
|
||||
* string(0) ""
|
||||
* }
|
||||
*/
|
||||
exec("wmic timezone get Caption", $output);
|
||||
|
||||
$string = trim(implode("\n", $output));
|
||||
|
||||
//Detect the Time Zone string
|
||||
preg_match($regex, $string, $matches);
|
||||
|
||||
if(!isset($matches[2])){
|
||||
return false;
|
||||
}
|
||||
|
||||
$offset = $matches[2];
|
||||
|
||||
if($offset == ""){
|
||||
return "UTC";
|
||||
}
|
||||
|
||||
return parse_offset($offset);
|
||||
case 'linux':
|
||||
// Ubuntu / Debian.
|
||||
if(file_exists('/etc/timezone')){
|
||||
$data = file_get_contents('/etc/timezone');
|
||||
if($data){
|
||||
return trim($data);
|
||||
}
|
||||
}
|
||||
|
||||
// RHEL / CentOS
|
||||
if(file_exists('/etc/sysconfig/clock')){
|
||||
$data = parse_ini_file('/etc/sysconfig/clock');
|
||||
if(!empty($data['ZONE'])){
|
||||
return trim($data['ZONE']);
|
||||
}
|
||||
}
|
||||
|
||||
//Portable method for incompatible linux distributions.
|
||||
|
||||
$offset = trim(exec('date +%:z'));
|
||||
|
||||
if($offset == "+00:00"){
|
||||
return "UTC";
|
||||
}
|
||||
|
||||
return parse_offset($offset);
|
||||
case 'mac':
|
||||
if(is_link('/etc/localtime')){
|
||||
$filename = readlink('/etc/localtime');
|
||||
if(strpos($filename, '/usr/share/zoneinfo/') === 0){
|
||||
$timezone = substr($filename, 20);
|
||||
return trim($timezone);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $offset In the format of +09:00, +02:00, -04:00 etc.
|
||||
*
|
||||
* @return string|bool
|
||||
*/
|
||||
function parse_offset($offset){
|
||||
//Make signed offsets unsigned for date_parse
|
||||
if(strpos($offset, '-') !== false){
|
||||
$negative_offset = true;
|
||||
$offset = str_replace('-', '', $offset);
|
||||
}else{
|
||||
if(strpos($offset, '+') !== false){
|
||||
$negative_offset = false;
|
||||
$offset = str_replace('+', '', $offset);
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$parsed = date_parse($offset);
|
||||
$offset = $parsed['hour'] * 3600 + $parsed['minute'] * 60 + $parsed['second'];
|
||||
|
||||
//After date_parse is done, put the sign back
|
||||
if($negative_offset == true){
|
||||
$offset = -abs($offset);
|
||||
}
|
||||
|
||||
//And then, look the offset up.
|
||||
//timezone_name_from_abbr is not used because it returns false on some(most) offsets because it's mapping function is weird.
|
||||
//That's been a bug in PHP since 2008!
|
||||
foreach(timezone_abbreviations_list() as $zones){
|
||||
foreach($zones as $timezone){
|
||||
if($timezone['offset'] == $offset){
|
||||
return $timezone['timezone_id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
foreach($tzError as $e){
|
||||
$logger->warning($e);
|
||||
}
|
||||
unset($tzError);
|
||||
|
||||
if(isset($opts["enable-profiler"])){
|
||||
if(function_exists("profiler_enable")){
|
||||
@ -364,155 +260,12 @@ namespace pocketmine {
|
||||
}
|
||||
}
|
||||
|
||||
function kill($pid){
|
||||
global $logger;
|
||||
if($logger instanceof MainLogger){
|
||||
$logger->syncFlushBuffer();
|
||||
}
|
||||
switch(Utils::getOS()){
|
||||
case "win":
|
||||
exec("taskkill.exe /F /PID " . ((int) $pid) . " > NUL");
|
||||
break;
|
||||
case "mac":
|
||||
case "linux":
|
||||
default:
|
||||
if(function_exists("posix_kill")){
|
||||
posix_kill($pid, SIGKILL);
|
||||
}else{
|
||||
exec("kill -9 " . ((int) $pid) . " > /dev/null 2>&1");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $value
|
||||
* @param bool $includeCurrent
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
function getReferenceCount($value, $includeCurrent = true){
|
||||
ob_start();
|
||||
debug_zval_dump($value);
|
||||
$ret = explode("\n", ob_get_contents());
|
||||
ob_end_clean();
|
||||
|
||||
if(count($ret) >= 1 and preg_match('/^.* refcount\\(([0-9]+)\\)\\{$/', trim($ret[0]), $m) > 0){
|
||||
return ((int) $m[1]) - ($includeCurrent ? 3 : 4); //$value + zval call + extra call
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $start
|
||||
* @param array|null $trace
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getTrace($start = 0, $trace = null){
|
||||
if($trace === null){
|
||||
if(function_exists("xdebug_get_function_stack")){
|
||||
$trace = array_reverse(xdebug_get_function_stack());
|
||||
}else{
|
||||
$e = new \Exception();
|
||||
$trace = $e->getTrace();
|
||||
}
|
||||
}
|
||||
|
||||
$messages = [];
|
||||
$j = 0;
|
||||
for($i = (int) $start; isset($trace[$i]); ++$i, ++$j){
|
||||
$params = "";
|
||||
if(isset($trace[$i]["args"]) or isset($trace[$i]["params"])){
|
||||
if(isset($trace[$i]["args"])){
|
||||
$args = $trace[$i]["args"];
|
||||
}else{
|
||||
$args = $trace[$i]["params"];
|
||||
}
|
||||
|
||||
$params = implode(", ", array_map(function($value){
|
||||
return (is_object($value) ? get_class($value) . " object" : gettype($value) . " " . (is_array($value) ? "Array()" : Utils::printable(@strval($value))));
|
||||
}, $args));
|
||||
}
|
||||
$messages[] = "#$j " . (isset($trace[$i]["file"]) ? cleanPath($trace[$i]["file"]) : "") . "(" . (isset($trace[$i]["line"]) ? $trace[$i]["line"] : "") . "): " . (isset($trace[$i]["class"]) ? $trace[$i]["class"] . (($trace[$i]["type"] === "dynamic" or $trace[$i]["type"] === "->") ? "->" : "::") : "") . $trace[$i]["function"] . "(" . Utils::printable($params) . ")";
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
function cleanPath($path){
|
||||
return str_replace(["\\", ".php", "phar://", str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PATH), str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PLUGIN_PATH)], ["/", "", "", "", ""], $path);
|
||||
}
|
||||
|
||||
$exitCode = 0;
|
||||
|
||||
do{
|
||||
$errors = 0;
|
||||
|
||||
if(PHP_INT_SIZE < 8){
|
||||
$logger->critical("Running " . \pocketmine\NAME . " with 32-bit systems/PHP is no longer supported. Please upgrade to a 64-bit system or use a 64-bit PHP binary.");
|
||||
$exitCode = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if(php_sapi_name() !== "cli"){
|
||||
$logger->critical("You must run " . \pocketmine\NAME . " using the CLI.");
|
||||
++$errors;
|
||||
}
|
||||
|
||||
$pthreads_version = phpversion("pthreads");
|
||||
if(substr_count($pthreads_version, ".") < 2){
|
||||
$pthreads_version = "0.$pthreads_version";
|
||||
}
|
||||
if(version_compare($pthreads_version, "3.1.7-dev") < 0){
|
||||
$logger->critical("pthreads >= 3.1.7-dev is required, while you have $pthreads_version.");
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(extension_loaded("leveldb")){
|
||||
$leveldb_version = phpversion("leveldb");
|
||||
if(version_compare($leveldb_version, "0.2.1") < 0){
|
||||
$logger->critical("php-leveldb >= 0.2.1 is required, while you have $leveldb_version");
|
||||
++$errors;
|
||||
}
|
||||
}
|
||||
|
||||
if(extension_loaded("pocketmine")){
|
||||
if(version_compare(phpversion("pocketmine"), "0.0.1") < 0){
|
||||
$logger->critical("You have the native PocketMine extension, but your version is lower than 0.0.1.");
|
||||
++$errors;
|
||||
}elseif(version_compare(phpversion("pocketmine"), "0.0.4") > 0){
|
||||
$logger->critical("You have the native PocketMine extension, but your version is higher than 0.0.4.");
|
||||
++$errors;
|
||||
}
|
||||
}
|
||||
|
||||
if(extension_loaded("xdebug")){
|
||||
$logger->warning(PHP_EOL . PHP_EOL . PHP_EOL . "\tYou are running " . \pocketmine\NAME . " with xdebug enabled. This has a major impact on performance." . PHP_EOL . PHP_EOL);
|
||||
}
|
||||
|
||||
$extensions = [
|
||||
"bcmath" => "BC Math",
|
||||
"curl" => "cURL",
|
||||
"json" => "JSON",
|
||||
"mbstring" => "Multibyte String",
|
||||
"openssl" => "OpenSSL",
|
||||
"sockets" => "Sockets",
|
||||
"yaml" => "YAML",
|
||||
"zip" => "Zip",
|
||||
"zlib" => "Zlib"
|
||||
];
|
||||
|
||||
foreach($extensions as $ext => $name){
|
||||
if(!extension_loaded($ext)){
|
||||
$logger->critical("Unable to find the $name ($ext) extension.");
|
||||
++$errors;
|
||||
}
|
||||
}
|
||||
|
||||
if($errors > 0){
|
||||
$logger->critical("Please use the installer provided on the homepage, or recompile PHP again.");
|
||||
$exitCode = 1;
|
||||
break;
|
||||
if(\Phar::running(true) === ""){
|
||||
$logger->warning("Non-packaged " . \pocketmine\NAME . " installation detected. Consider using a phar in production for better performance.");
|
||||
}
|
||||
|
||||
$gitHash = str_repeat("00", 20);
|
||||
@ -538,7 +291,8 @@ namespace pocketmine {
|
||||
@define("INT32_MASK", is_int(0xffffffff) ? 0xffffffff : -1);
|
||||
@ini_set("opcache.mmap_base", bin2hex(random_bytes(8))); //Fix OPCache address errors
|
||||
|
||||
|
||||
$exitCode = 0;
|
||||
do{
|
||||
if(!file_exists(\pocketmine\DATA . "server.properties") and !isset($opts["no-wizard"])){
|
||||
$installer = new SetupWizard();
|
||||
if(!$installer->run()){
|
||||
@ -547,25 +301,20 @@ namespace pocketmine {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(\Phar::running(true) === ""){
|
||||
$logger->warning("Non-packaged " . \pocketmine\NAME . " installation detected. Consider using a phar in production for better performance.");
|
||||
}
|
||||
|
||||
ThreadManager::init();
|
||||
new Server($autoloader, $logger, \pocketmine\DATA, \pocketmine\PLUGIN_PATH);
|
||||
|
||||
$logger->info("Stopping other threads");
|
||||
|
||||
$killer = new ServerKiller(8);
|
||||
$killer->start();
|
||||
$killer->start(PTHREADS_INHERIT_NONE);
|
||||
usleep(10000); //Fixes ServerKiller not being able to start on single-core machines
|
||||
|
||||
if(ThreadManager::getInstance()->stopAll() > 0){
|
||||
if(\pocketmine\DEBUG > 1){
|
||||
echo "Some threads could not be stopped, performing a force-kill" . PHP_EOL . PHP_EOL;
|
||||
}
|
||||
kill(getmypid());
|
||||
Utils::kill(getmypid());
|
||||
}
|
||||
}while(false);
|
||||
|
||||
|
@ -33,8 +33,6 @@ use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\ConsoleCommandSender;
|
||||
use pocketmine\command\PluginIdentifiableCommand;
|
||||
use pocketmine\command\SimpleCommandMap;
|
||||
use pocketmine\entity\Attribute;
|
||||
use pocketmine\entity\Effect;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\Skin;
|
||||
use pocketmine\event\HandlerList;
|
||||
@ -43,25 +41,16 @@ use pocketmine\event\level\LevelLoadEvent;
|
||||
use pocketmine\event\player\PlayerDataSaveEvent;
|
||||
use pocketmine\event\server\QueryRegenerateEvent;
|
||||
use pocketmine\event\server\ServerCommandEvent;
|
||||
use pocketmine\event\TextContainer;
|
||||
use pocketmine\event\Timings;
|
||||
use pocketmine\event\TimingsHandler;
|
||||
use pocketmine\inventory\CraftingManager;
|
||||
use pocketmine\inventory\Recipe;
|
||||
use pocketmine\item\enchantment\Enchantment;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\lang\BaseLang;
|
||||
use pocketmine\level\format\io\leveldb\LevelDB;
|
||||
use pocketmine\lang\TextContainer;
|
||||
use pocketmine\level\format\io\LevelProvider;
|
||||
use pocketmine\level\format\io\LevelProviderManager;
|
||||
use pocketmine\level\format\io\region\Anvil;
|
||||
use pocketmine\level\format\io\region\McRegion;
|
||||
use pocketmine\level\format\io\region\PMAnvil;
|
||||
use pocketmine\level\generator\biome\Biome;
|
||||
use pocketmine\level\generator\Flat;
|
||||
use pocketmine\level\generator\Generator;
|
||||
use pocketmine\level\generator\hell\Nether;
|
||||
use pocketmine\level\generator\normal\Normal;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\level\LevelException;
|
||||
use pocketmine\metadata\EntityMetadataStore;
|
||||
@ -78,6 +67,7 @@ use pocketmine\nbt\tag\ListTag;
|
||||
use pocketmine\nbt\tag\LongTag;
|
||||
use pocketmine\nbt\tag\ShortTag;
|
||||
use pocketmine\nbt\tag\StringTag;
|
||||
use pocketmine\network\AdvancedSourceInterface;
|
||||
use pocketmine\network\CompressBatchedTask;
|
||||
use pocketmine\network\mcpe\protocol\BatchPacket;
|
||||
use pocketmine\network\mcpe\protocol\DataPacket;
|
||||
@ -101,6 +91,8 @@ use pocketmine\scheduler\FileWriteTask;
|
||||
use pocketmine\scheduler\SendUsageTask;
|
||||
use pocketmine\scheduler\ServerScheduler;
|
||||
use pocketmine\tile\Tile;
|
||||
use pocketmine\timings\Timings;
|
||||
use pocketmine\timings\TimingsHandler;
|
||||
use pocketmine\updater\AutoUpdater;
|
||||
use pocketmine\utils\Binary;
|
||||
use pocketmine\utils\Config;
|
||||
@ -263,9 +255,6 @@ class Server{
|
||||
/** @var Player[] */
|
||||
private $playerList = [];
|
||||
|
||||
/** @var string[] */
|
||||
private $identifiers = [];
|
||||
|
||||
/** @var Level[] */
|
||||
private $levels = [];
|
||||
|
||||
@ -283,7 +272,7 @@ class Server{
|
||||
* @return bool
|
||||
*/
|
||||
public function isRunning() : bool{
|
||||
return $this->isRunning === true;
|
||||
return $this->isRunning;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -521,16 +510,6 @@ class Server{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Moved to {@link Level#getDifficultyFromString}
|
||||
*
|
||||
* @param string $str
|
||||
* @return int
|
||||
*/
|
||||
public static function getDifficultyFromString(string $str) : int{
|
||||
return Level::getDifficultyFromString($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Server global difficulty. Note that this may be overridden in individual Levels.
|
||||
* @return int
|
||||
@ -640,7 +619,7 @@ class Server{
|
||||
/**
|
||||
* @return ResourcePackManager
|
||||
*/
|
||||
public function getResourceManager() : ResourcePackManager{
|
||||
public function getResourcePackManager() : ResourcePackManager{
|
||||
return $this->resourceManager;
|
||||
}
|
||||
|
||||
@ -715,10 +694,6 @@ class Server{
|
||||
return $this->playerList;
|
||||
}
|
||||
|
||||
public function addRecipe(Recipe $recipe){
|
||||
$this->craftingManager->registerRecipe($recipe);
|
||||
}
|
||||
|
||||
public function shouldSavePlayerData() : bool{
|
||||
return (bool) $this->getProperty("player.save-player-data", true);
|
||||
}
|
||||
@ -751,9 +726,12 @@ class Server{
|
||||
if(file_exists($path . "$name.dat")){
|
||||
try{
|
||||
$nbt = new BigEndianNBTStream();
|
||||
$nbt->readCompressed(file_get_contents($path . "$name.dat"));
|
||||
$compound = $nbt->readCompressed(file_get_contents($path . "$name.dat"));
|
||||
if(!($compound instanceof CompoundTag)){
|
||||
throw new \RuntimeException("Invalid data found in \"$name.dat\", expected " . CompoundTag::class . ", got " . (is_object($compound) ? get_class($compound) : gettype($compound)));
|
||||
}
|
||||
|
||||
return $nbt->getData();
|
||||
return $compound;
|
||||
}catch(\Throwable $e){ //zlib decode error / corrupt data
|
||||
rename($path . "$name.dat", $path . "$name.dat.bak");
|
||||
$this->logger->notice($this->getLanguage()->translateString("pocketmine.data.playerCorrupted", [$name]));
|
||||
@ -775,9 +753,9 @@ class Server{
|
||||
], NBT::TAG_Double),
|
||||
new StringTag("Level", $this->getDefaultLevel()->getFolderName()),
|
||||
//new StringTag("SpawnLevel", $this->getDefaultLevel()->getFolderName()),
|
||||
//new IntTag("SpawnX", (int) $spawn->x),
|
||||
//new IntTag("SpawnY", (int) $spawn->y),
|
||||
//new IntTag("SpawnZ", (int) $spawn->z),
|
||||
//new IntTag("SpawnX", $spawn->getFloorX()),
|
||||
//new IntTag("SpawnY", $spawn->getFloorY()),
|
||||
//new IntTag("SpawnZ", $spawn->getFloorZ()),
|
||||
//new ByteTag("SpawnForced", 1), //TODO
|
||||
new ListTag("Inventory", [], NBT::TAG_Compound),
|
||||
new ListTag("EnderChestInventory", [], NBT::TAG_Compound),
|
||||
@ -818,12 +796,10 @@ class Server{
|
||||
if(!$ev->isCancelled()){
|
||||
$nbt = new BigEndianNBTStream();
|
||||
try{
|
||||
$nbt->setData($ev->getSaveData());
|
||||
|
||||
if($async){
|
||||
$this->getScheduler()->scheduleAsyncTask(new FileWriteTask($this->getDataPath() . "players/" . strtolower($name) . ".dat", $nbt->writeCompressed()));
|
||||
$this->getScheduler()->scheduleAsyncTask(new FileWriteTask($this->getDataPath() . "players/" . strtolower($name) . ".dat", $nbt->writeCompressed($ev->getSaveData())));
|
||||
}else{
|
||||
file_put_contents($this->getDataPath() . "players/" . strtolower($name) . ".dat", $nbt->writeCompressed());
|
||||
file_put_contents($this->getDataPath() . "players/" . strtolower($name) . ".dat", $nbt->writeCompressed($ev->getSaveData()));
|
||||
}
|
||||
}catch(\Throwable $e){
|
||||
$this->logger->critical($this->getLanguage()->translateString("pocketmine.data.saveError", [$name, $e->getMessage()]));
|
||||
@ -894,23 +870,25 @@ class Server{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Player $player
|
||||
* Returns the player online with the specified raw UUID, or null if not found
|
||||
*
|
||||
* @param string $rawUUID
|
||||
*
|
||||
* @return null|Player
|
||||
*/
|
||||
public function removePlayer(Player $player){
|
||||
if(isset($this->identifiers[$hash = spl_object_hash($player)])){
|
||||
$identifier = $this->identifiers[$hash];
|
||||
unset($this->players[$identifier]);
|
||||
unset($this->identifiers[$hash]);
|
||||
return;
|
||||
public function getPlayerByRawUUID(string $rawUUID) : ?Player{
|
||||
return $this->playerList[$rawUUID] ?? null;
|
||||
}
|
||||
|
||||
foreach($this->players as $identifier => $p){
|
||||
if($player === $p){
|
||||
unset($this->players[$identifier]);
|
||||
unset($this->identifiers[spl_object_hash($player)]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Returns the player online with a UUID equivalent to the specified UUID object, or null if not found
|
||||
*
|
||||
* @param UUID $uuid
|
||||
*
|
||||
* @return null|Player
|
||||
*/
|
||||
public function getPlayerByUUID(UUID $uuid) : ?Player{
|
||||
return $this->getPlayerByRawUUID($uuid->toBinary());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1025,7 +1003,7 @@ class Server{
|
||||
$provider = LevelProviderManager::getProvider($path);
|
||||
|
||||
if($provider === null){
|
||||
$this->logger->error($this->getLanguage()->translateString("pocketmine.level.loadError", [$name, "Unknown provider"]));
|
||||
$this->logger->error($this->getLanguage()->translateString("pocketmine.level.loadError", [$name, "Cannot identify format of world"]));
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -1051,11 +1029,11 @@ class Server{
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a new level if it does not exists
|
||||
* Generates a new level if it does not exist
|
||||
*
|
||||
* @param string $name
|
||||
* @param int|null $seed
|
||||
* @param string|null $generator Class name that extends pocketmine\level\generator\Noise
|
||||
* @param string|null $generator Class name that extends pocketmine\level\generator\Generator
|
||||
* @param array $options
|
||||
*
|
||||
* @return bool
|
||||
@ -1103,8 +1081,8 @@ class Server{
|
||||
$this->getLogger()->notice($this->getLanguage()->translateString("pocketmine.level.backgroundGeneration", [$name]));
|
||||
|
||||
$spawnLocation = $level->getSpawnLocation();
|
||||
$centerX = $spawnLocation->x >> 4;
|
||||
$centerZ = $spawnLocation->z >> 4;
|
||||
$centerX = $spawnLocation->getFloorX() >> 4;
|
||||
$centerZ = $spawnLocation->getFloorZ() >> 4;
|
||||
|
||||
$order = [];
|
||||
|
||||
@ -1139,10 +1117,9 @@ class Server{
|
||||
}
|
||||
$path = $this->getDataPath() . "worlds/" . $name . "/";
|
||||
if(!($this->getLevelByName($name) instanceof Level)){
|
||||
|
||||
if(LevelProviderManager::getProvider($path) === null){
|
||||
return false;
|
||||
}
|
||||
return is_dir($path) and !empty(array_filter(scandir($path, SCANDIR_SORT_NONE), function($v){
|
||||
return $v !== ".." and $v !== ".";
|
||||
}));
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1266,24 +1243,12 @@ class Server{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*
|
||||
* @param string $variable
|
||||
* @param bool $defaultValue
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getConfigBoolean(string $variable, bool $defaultValue = false) : bool{
|
||||
return $this->getConfigBool($variable, $defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $variable
|
||||
* @param bool $value
|
||||
*/
|
||||
public function setConfigBool(string $variable, bool $value){
|
||||
$this->properties->set($variable, $value == true ? "1" : "0");
|
||||
$this->properties->set($variable, $value ? "1" : "0");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1555,7 +1520,7 @@ class Server{
|
||||
|
||||
$this->scheduler = new ServerScheduler();
|
||||
|
||||
if($this->getConfigBool("enable-rcon", false) === true){
|
||||
if($this->getConfigBool("enable-rcon", false)){
|
||||
try{
|
||||
$this->rcon = new RCON(
|
||||
$this,
|
||||
@ -1591,15 +1556,15 @@ class Server{
|
||||
|
||||
$this->onlineMode = $this->getConfigBool("xbox-auth", true);
|
||||
if($this->onlineMode){
|
||||
$this->logger->notice($this->getLanguage()->translateString("pocketmine.server.auth", ["enabled", "will"]));
|
||||
$this->logger->notice($this->getLanguage()->translateString("pocketmine.server.authProperty", ["disable", "false"]));
|
||||
$this->logger->notice($this->getLanguage()->translateString("pocketmine.server.auth.enabled"));
|
||||
$this->logger->notice($this->getLanguage()->translateString("pocketmine.server.authProperty.enabled"));
|
||||
}else{
|
||||
$this->logger->warning($this->getLanguage()->translateString("pocketmine.server.auth", ["disabled", "will not"]));
|
||||
$this->logger->warning($this->getLanguage()->translateString("pocketmine.server.auth.disabled"));
|
||||
$this->logger->warning($this->getLanguage()->translateString("pocketmine.server.authWarning"));
|
||||
$this->logger->warning($this->getLanguage()->translateString("pocketmine.server.authProperty", ["enable", "true"]));
|
||||
$this->logger->warning($this->getLanguage()->translateString("pocketmine.server.authProperty.disabled"));
|
||||
}
|
||||
|
||||
if($this->getConfigBool("hardcore", false) === true and $this->getDifficulty() < Level::DIFFICULTY_HARD){
|
||||
if($this->getConfigBool("hardcore", false) and $this->getDifficulty() < Level::DIFFICULTY_HARD){
|
||||
$this->setConfigInt("difficulty", Level::DIFFICULTY_HARD);
|
||||
}
|
||||
|
||||
@ -1628,6 +1593,7 @@ class Server{
|
||||
|
||||
|
||||
Timings::init();
|
||||
TimingsHandler::setEnabled((bool) $this->getProperty("settings.enable-profiling", false));
|
||||
|
||||
$this->consoleSender = new ConsoleCommandSender();
|
||||
$this->commandMap = new SimpleCommandMap($this);
|
||||
@ -1637,16 +1603,15 @@ class Server{
|
||||
BlockFactory::init();
|
||||
Enchantment::init();
|
||||
ItemFactory::init();
|
||||
Item::initCreativeItems();
|
||||
Biome::init();
|
||||
Effect::init();
|
||||
Attribute::init();
|
||||
|
||||
$this->craftingManager = new CraftingManager();
|
||||
|
||||
$this->resourceManager = new ResourcePackManager($this->getDataPath() . "resource_packs" . DIRECTORY_SEPARATOR);
|
||||
|
||||
$this->pluginManager = new PluginManager($this, $this->commandMap);
|
||||
$this->pluginManager->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this->consoleSender);
|
||||
$this->pluginManager->setUseTimings($this->getProperty("settings.enable-profiling", false));
|
||||
$this->profilingTickRate = (float) $this->getProperty("settings.profile-report-trigger", 20);
|
||||
$this->pluginManager->registerInterface(PharPluginLoader::class);
|
||||
$this->pluginManager->registerInterface(ScriptPluginLoader::class);
|
||||
@ -1663,26 +1628,18 @@ class Server{
|
||||
|
||||
$this->network->registerInterface(new RakLibInterface($this));
|
||||
|
||||
|
||||
LevelProviderManager::addProvider(Anvil::class);
|
||||
LevelProviderManager::addProvider(McRegion::class);
|
||||
LevelProviderManager::addProvider(PMAnvil::class);
|
||||
LevelProviderManager::addProvider(LevelDB::class);
|
||||
LevelProviderManager::init();
|
||||
if(extension_loaded("leveldb")){
|
||||
$this->logger->debug($this->getLanguage()->translateString("pocketmine.debug.enable"));
|
||||
}
|
||||
|
||||
Generator::addGenerator(Flat::class, "flat");
|
||||
Generator::addGenerator(Normal::class, "normal");
|
||||
Generator::addGenerator(Normal::class, "default");
|
||||
Generator::addGenerator(Nether::class, "hell");
|
||||
Generator::addGenerator(Nether::class, "nether");
|
||||
Generator::registerDefaultGenerators();
|
||||
|
||||
foreach((array) $this->getProperty("worlds", []) as $name => $options){
|
||||
if(!is_array($options)){
|
||||
continue;
|
||||
}
|
||||
if($this->loadLevel($name) === false){
|
||||
if(!$this->loadLevel($name)){
|
||||
$seed = $options["seed"] ?? time();
|
||||
if(is_string($seed) and !is_numeric($seed)){
|
||||
$seed = Utils::javaStringHash($seed);
|
||||
@ -1711,7 +1668,7 @@ class Server{
|
||||
$default = "world";
|
||||
$this->setConfigString("level-name", "world");
|
||||
}
|
||||
if($this->loadLevel($default) === false){
|
||||
if(!$this->loadLevel($default)){
|
||||
$seed = getopt("", ["level-seed::"])["level-seed"] ?? $this->properties->get("level-seed", time());
|
||||
if(!is_numeric($seed) or bccomp($seed, "9223372036854775807") > 0){
|
||||
$seed = Utils::javaStringHash($seed);
|
||||
@ -1891,16 +1848,14 @@ class Server{
|
||||
* @param bool $immediate
|
||||
*/
|
||||
public function batchPackets(array $players, array $packets, bool $forceSync = false, bool $immediate = false){
|
||||
if(empty($packets)){
|
||||
throw new \InvalidArgumentException("Cannot send empty batch");
|
||||
}
|
||||
Timings::$playerNetworkTimer->startTiming();
|
||||
|
||||
$targets = [];
|
||||
foreach($players as $p){
|
||||
if($p->isConnected()){
|
||||
$targets[] = $this->identifiers[spl_object_hash($p)];
|
||||
}
|
||||
}
|
||||
$targets = array_filter($players, function(Player $player) : bool{ return $player->isConnected(); });
|
||||
|
||||
if(count($targets) > 0){
|
||||
if(!empty($targets)){
|
||||
$pk = new BatchPacket();
|
||||
|
||||
foreach($packets as $p){
|
||||
@ -1925,19 +1880,21 @@ class Server{
|
||||
Timings::$playerNetworkTimer->stopTiming();
|
||||
}
|
||||
|
||||
public function broadcastPacketsCallback(BatchPacket $pk, array $identifiers, bool $immediate = false){
|
||||
/**
|
||||
* @param BatchPacket $pk
|
||||
* @param Player[] $players
|
||||
* @param bool $immediate
|
||||
*/
|
||||
public function broadcastPacketsCallback(BatchPacket $pk, array $players, bool $immediate = false){
|
||||
if(!$pk->isEncoded){
|
||||
$pk->encode();
|
||||
}
|
||||
|
||||
foreach($identifiers as $i){
|
||||
if(isset($this->players[$i])){
|
||||
$this->players[$i]->sendDataPacket($pk, false, $immediate);
|
||||
foreach($players as $i){
|
||||
$i->sendDataPacket($pk, false, $immediate);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $type
|
||||
@ -2011,7 +1968,7 @@ class Server{
|
||||
$this->properties->reload();
|
||||
$this->maxPlayers = $this->getConfigInt("max-players", 20);
|
||||
|
||||
if($this->getConfigBool("hardcore", false) === true and $this->getDifficulty() < Level::DIFFICULTY_HARD){
|
||||
if($this->getConfigBool("hardcore", false) and $this->getDifficulty() < Level::DIFFICULTY_HARD){
|
||||
$this->setConfigInt("difficulty", Level::DIFFICULTY_HARD);
|
||||
}
|
||||
|
||||
@ -2056,7 +2013,7 @@ class Server{
|
||||
$this->rcon->stop();
|
||||
}
|
||||
|
||||
if($this->getProperty("network.upnp-forwarding", false) === true){
|
||||
if($this->getProperty("network.upnp-forwarding", false)){
|
||||
$this->logger->info("[UPnP] Removing port forward...");
|
||||
UPnP::RemovePortForward($this->getPort());
|
||||
}
|
||||
@ -2107,7 +2064,7 @@ class Server{
|
||||
}catch(\Throwable $e){
|
||||
$this->logger->logException($e);
|
||||
$this->logger->emergency("Crashed while crashing, killing process");
|
||||
@kill(getmypid());
|
||||
@Utils::kill(getmypid());
|
||||
}
|
||||
|
||||
}
|
||||
@ -2123,7 +2080,7 @@ class Server{
|
||||
* Starts the PocketMine-MP server and starts processing ticks and packets
|
||||
*/
|
||||
private function start(){
|
||||
if($this->getConfigBool("enable-query", true) === true){
|
||||
if($this->getConfigBool("enable-query", true)){
|
||||
$this->queryHandler = new QueryHandler();
|
||||
}
|
||||
|
||||
@ -2139,7 +2096,11 @@ class Server{
|
||||
|
||||
if($this->getProperty("network.upnp-forwarding", false)){
|
||||
$this->logger->info("[UPnP] Trying to port forward...");
|
||||
try{
|
||||
UPnP::PortForward($this->getPort());
|
||||
}catch(\Throwable $e){
|
||||
$this->logger->alert("UPnP portforward failed: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
$this->tickCounter = 0;
|
||||
@ -2182,24 +2143,21 @@ class Server{
|
||||
|
||||
$errstr = $e->getMessage();
|
||||
$errfile = $e->getFile();
|
||||
$errno = $e->getCode();
|
||||
$errline = $e->getLine();
|
||||
|
||||
$type = ($errno === E_ERROR or $errno === E_USER_ERROR) ? \LogLevel::ERROR : (($errno === E_USER_WARNING or $errno === E_WARNING) ? \LogLevel::WARNING : \LogLevel::NOTICE);
|
||||
|
||||
$errstr = preg_replace('/\s+/', ' ', trim($errstr));
|
||||
|
||||
$errfile = cleanPath($errfile);
|
||||
$errfile = Utils::cleanPath($errfile);
|
||||
|
||||
$this->logger->logException($e, $trace);
|
||||
|
||||
$lastError = [
|
||||
"type" => $type,
|
||||
"type" => \get_class($e),
|
||||
"message" => $errstr,
|
||||
"fullFile" => $e->getFile(),
|
||||
"file" => $errfile,
|
||||
"line" => $errline,
|
||||
"trace" => getTrace(0, $trace)
|
||||
"trace" => Utils::getTrace(0, $trace)
|
||||
];
|
||||
|
||||
global $lastExceptionError, $lastError;
|
||||
@ -2208,7 +2166,7 @@ class Server{
|
||||
}
|
||||
|
||||
public function crashDump(){
|
||||
if($this->isRunning === false){
|
||||
if(!$this->isRunning){
|
||||
return;
|
||||
}
|
||||
if($this->sendUsageTicker > 0){
|
||||
@ -2218,8 +2176,8 @@ class Server{
|
||||
|
||||
ini_set("error_reporting", '0');
|
||||
ini_set("memory_limit", '-1'); //Fix error dump not dumped on memory problems
|
||||
$this->logger->emergency($this->getLanguage()->translateString("pocketmine.crash.create"));
|
||||
try{
|
||||
$this->logger->emergency($this->getLanguage()->translateString("pocketmine.crash.create"));
|
||||
$dump = new CrashDump($this);
|
||||
|
||||
$this->logger->emergency($this->getLanguage()->translateString("pocketmine.crash.submit", [$dump->getPath()]));
|
||||
@ -2261,7 +2219,9 @@ class Server{
|
||||
}
|
||||
}catch(\Throwable $e){
|
||||
$this->logger->logException($e);
|
||||
try{
|
||||
$this->logger->critical($this->getLanguage()->translateString("pocketmine.crash.error", [$e->getMessage()]));
|
||||
}catch(\Throwable $e){}
|
||||
}
|
||||
|
||||
//$this->checkMemory();
|
||||
@ -2269,7 +2229,7 @@ class Server{
|
||||
|
||||
$this->forceShutdown();
|
||||
$this->isRunning = false;
|
||||
@kill(getmypid());
|
||||
@Utils::kill(getmypid());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -2300,22 +2260,23 @@ class Server{
|
||||
$this->loggedInPlayers[$player->getRawUniqueId()] = $player;
|
||||
}
|
||||
|
||||
public function onPlayerCompleteLoginSequence(Player $player){
|
||||
$this->sendFullPlayerListData($player);
|
||||
$player->dataPacket($this->craftingManager->getCraftingDataPacket());
|
||||
}
|
||||
|
||||
public function onPlayerLogout(Player $player){
|
||||
unset($this->loggedInPlayers[$player->getRawUniqueId()]);
|
||||
}
|
||||
|
||||
public function addPlayer($identifier, Player $player){
|
||||
$this->players[$identifier] = $player;
|
||||
$this->identifiers[spl_object_hash($player)] = $identifier;
|
||||
public function addPlayer(Player $player){
|
||||
$this->players[spl_object_hash($player)] = $player;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Player $player
|
||||
*/
|
||||
public function removePlayer(Player $player){
|
||||
unset($this->players[spl_object_hash($player)]);
|
||||
}
|
||||
|
||||
public function addOnlinePlayer(Player $player){
|
||||
$this->updatePlayerListData($player->getUniqueId(), $player->getId(), $player->getDisplayName(), $player->getSkin());
|
||||
$this->updatePlayerListData($player->getUniqueId(), $player->getId(), $player->getDisplayName(), $player->getSkin(), $player->getXuid());
|
||||
|
||||
$this->playerList[$player->getRawUniqueId()] = $player;
|
||||
}
|
||||
@ -2333,13 +2294,15 @@ class Server{
|
||||
* @param int $entityId
|
||||
* @param string $name
|
||||
* @param Skin $skin
|
||||
* @param string $xboxUserId
|
||||
* @param Player[]|null $players
|
||||
*/
|
||||
public function updatePlayerListData(UUID $uuid, int $entityId, string $name, Skin $skin, array $players = null){
|
||||
public function updatePlayerListData(UUID $uuid, int $entityId, string $name, Skin $skin, string $xboxUserId = "", array $players = null){
|
||||
$pk = new PlayerListPacket();
|
||||
$pk->type = PlayerListPacket::TYPE_ADD;
|
||||
|
||||
$pk->entries[] = PlayerListEntry::createAdditionEntry($uuid, $entityId, $name, $skin);
|
||||
$pk->entries[] = PlayerListEntry::createAdditionEntry($uuid, $entityId, $name, "", 0, $skin, $xboxUserId);
|
||||
|
||||
$this->broadcastPacket($players ?? $this->playerList, $pk);
|
||||
}
|
||||
|
||||
@ -2361,7 +2324,7 @@ class Server{
|
||||
$pk = new PlayerListPacket();
|
||||
$pk->type = PlayerListPacket::TYPE_ADD;
|
||||
foreach($this->playerList as $player){
|
||||
$pk->entries[] = PlayerListEntry::createAdditionEntry($player->getUniqueId(), $player->getId(), $player->getDisplayName(), $player->getSkin());
|
||||
$pk->entries[] = PlayerListEntry::createAdditionEntry($player->getUniqueId(), $player->getId(), $player->getDisplayName(), "", 0, $player->getSkin(), $player->getXuid());
|
||||
}
|
||||
|
||||
$p->dataPacket($pk);
|
||||
@ -2490,16 +2453,17 @@ class Server{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AdvancedSourceInterface $interface
|
||||
* @param string $address
|
||||
* @param int $port
|
||||
* @param string $payload
|
||||
*
|
||||
* TODO: move this to Network
|
||||
*/
|
||||
public function handlePacket(string $address, int $port, string $payload){
|
||||
public function handlePacket(AdvancedSourceInterface $interface, string $address, int $port, string $payload){
|
||||
try{
|
||||
if(strlen($payload) > 2 and substr($payload, 0, 2) === "\xfe\xfd" and $this->queryHandler instanceof QueryHandler){
|
||||
$this->queryHandler->handle($address, $port, $payload);
|
||||
$this->queryHandler->handle($interface, $address, $port, $payload);
|
||||
}
|
||||
}catch(\Throwable $e){
|
||||
if(\pocketmine\DEBUG > 1){
|
||||
|
@ -112,7 +112,7 @@ class Anvil extends Fallable{
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
ItemFactory::get($this->getItemId(), $this->getDamage() & 0x0c)
|
||||
ItemFactory::get($this->getItemId(), $this->getDamage() >> 2)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -23,9 +23,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
@ -176,7 +176,7 @@ class Bed extends Transparent{
|
||||
if(!$down->isTransparent()){
|
||||
$meta = (($player instanceof Player ? $player->getDirection() : 0) - 1) & 0x03;
|
||||
$next = $this->getSide(self::getOtherHalfSide($meta));
|
||||
if($next->canBeReplaced() === true and !$next->getSide(Vector3::SIDE_DOWN)->isTransparent()){
|
||||
if($next->canBeReplaced() and !$next->getSide(Vector3::SIDE_DOWN)->isTransparent()){
|
||||
$this->getLevel()->setBlock($blockReplace, BlockFactory::get($this->id, $meta), true, true);
|
||||
$this->getLevel()->setBlock($next, BlockFactory::get($this->id, $meta | self::BITFLAG_HEAD), true, true);
|
||||
|
||||
|
@ -30,7 +30,6 @@ use pocketmine\entity\Entity;
|
||||
use pocketmine\item\enchantment\Enchantment;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\level\Position;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\RayTraceResult;
|
||||
@ -278,6 +277,12 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
return $base;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when this block or a block immediately adjacent to it changes state.
|
||||
*/
|
||||
public function onNearbyBlockChange() : void{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether random block updates will be done on this block.
|
||||
@ -289,14 +294,18 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires a block update on the Block
|
||||
*
|
||||
* @param int $type
|
||||
*
|
||||
* @return bool|int
|
||||
* Called when this block is randomly updated due to chunk ticking.
|
||||
* WARNING: This will not be called if ticksRandomly() does not return true!
|
||||
*/
|
||||
public function onUpdate(int $type){
|
||||
return false;
|
||||
public function onRandomTick() : void{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when this block is updated by the delayed blockupdate scheduler in the level.
|
||||
*/
|
||||
public function onScheduledUpdate() : void{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -319,14 +328,6 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
return 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @return float
|
||||
*/
|
||||
public function getResistance() : float{
|
||||
return $this->getBlastResistance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the block's resistance to explosions. Usually 5x hardness.
|
||||
* @return float
|
||||
@ -496,6 +497,50 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the chance that the block will catch fire from nearby fire sources. Higher values lead to faster catching
|
||||
* fire.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getFlameEncouragement() : int{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base flammability of this block. Higher values lead to the block burning away more quickly.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getFlammability() : int{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether fire lit on this block will burn indefinitely.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function burnsForever() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this block can catch fire.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isFlammable() : bool{
|
||||
return $this->getFlammability() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when this block is burned away by being on fire.
|
||||
*/
|
||||
public function onIncinerate() : void{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Block on the side $side, works like Vector3::getSide()
|
||||
*
|
||||
@ -504,7 +549,7 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
*
|
||||
* @return Block
|
||||
*/
|
||||
public function getSide($side, $step = 1){
|
||||
public function getSide(int $side, int $step = 1){
|
||||
if($this->isValid()){
|
||||
return $this->getLevel()->getBlock(Vector3::getSide($side, $step));
|
||||
}
|
||||
@ -566,9 +611,7 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
* @return bool
|
||||
*/
|
||||
public function collidesWithBB(AxisAlignedBB $bb) : bool{
|
||||
$bbs = $this->getCollisionBoxes();
|
||||
|
||||
foreach($bbs as $bb2){
|
||||
foreach($this->getCollisionBoxes() as $bb2){
|
||||
if($bb->intersectsWith($bb2)){
|
||||
return true;
|
||||
}
|
||||
@ -673,30 +716,30 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
}
|
||||
|
||||
public function setMetadata(string $metadataKey, MetadataValue $newMetadataValue){
|
||||
if($this->getLevel() instanceof Level){
|
||||
$this->getLevel()->getBlockMetadata()->setMetadata($this, $metadataKey, $newMetadataValue);
|
||||
if($this->isValid()){
|
||||
$this->level->getBlockMetadata()->setMetadata($this, $metadataKey, $newMetadataValue);
|
||||
}
|
||||
}
|
||||
|
||||
public function getMetadata(string $metadataKey){
|
||||
if($this->getLevel() instanceof Level){
|
||||
return $this->getLevel()->getBlockMetadata()->getMetadata($this, $metadataKey);
|
||||
if($this->isValid()){
|
||||
return $this->level->getBlockMetadata()->getMetadata($this, $metadataKey);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function hasMetadata(string $metadataKey) : bool{
|
||||
if($this->getLevel() instanceof Level){
|
||||
return $this->getLevel()->getBlockMetadata()->hasMetadata($this, $metadataKey);
|
||||
if($this->isValid()){
|
||||
return $this->level->getBlockMetadata()->hasMetadata($this, $metadataKey);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function removeMetadata(string $metadataKey, Plugin $owningPlugin){
|
||||
if($this->getLevel() instanceof Level){
|
||||
$this->getLevel()->getBlockMetadata()->removeMetadata($this, $metadataKey, $owningPlugin);
|
||||
if($this->isValid()){
|
||||
$this->level->getBlockMetadata()->removeMetadata($this, $metadataKey, $owningPlugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Position;
|
||||
use pocketmine\utils\MainLogger;
|
||||
|
||||
/**
|
||||
* Manages block registration and instance creation
|
||||
@ -50,14 +51,20 @@ class BlockFactory{
|
||||
/** @var \SplFixedArray<float> */
|
||||
public static $blastResistance = null;
|
||||
|
||||
/** @var int[] */
|
||||
public static $staticRuntimeIdMap = [];
|
||||
|
||||
/** @var int[] */
|
||||
public static $legacyIdMap = [];
|
||||
|
||||
/** @var int */
|
||||
private static $lastRuntimeId = 0;
|
||||
|
||||
/**
|
||||
* Initializes the block factory. By default this is called only once on server start, however you may wish to use
|
||||
* this if you need to reset the block factory back to its original defaults for whatever reason.
|
||||
*
|
||||
* @param bool $force
|
||||
*/
|
||||
public static function init(bool $force = false) : void{
|
||||
if(self::$list === null or $force){
|
||||
public static function init() : void{
|
||||
self::$list = new \SplFixedArray(256);
|
||||
self::$fullList = new \SplFixedArray(4096);
|
||||
|
||||
@ -325,6 +332,11 @@ class BlockFactory{
|
||||
self::registerBlock(new UnknownBlock($id));
|
||||
}
|
||||
}
|
||||
|
||||
/** @var mixed[] $runtimeIdMap */
|
||||
$runtimeIdMap = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . "runtimeid_table.json"), true);
|
||||
foreach($runtimeIdMap as $obj){
|
||||
self::registerMapping($obj["runtimeID"], $obj["id"], $obj["data"]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -390,9 +402,9 @@ class BlockFactory{
|
||||
}
|
||||
|
||||
if($pos !== null){
|
||||
$block->x = $pos->x;
|
||||
$block->y = $pos->y;
|
||||
$block->z = $pos->z;
|
||||
$block->x = $pos->getFloorX();
|
||||
$block->y = $pos->getFloorY();
|
||||
$block->z = $pos->getFloorZ();
|
||||
$block->level = $pos->level;
|
||||
}
|
||||
|
||||
@ -417,4 +429,46 @@ class BlockFactory{
|
||||
$b = self::$list[$id];
|
||||
return $b !== null and !($b instanceof UnknownBlock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param int $id
|
||||
* @param int $meta
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function toStaticRuntimeId(int $id, int $meta = 0) : int{
|
||||
if($id === Block::AIR){
|
||||
//TODO: HACK! (weird air blocks with non-zero damage values shouldn't turn into update! blocks)
|
||||
$meta = 0;
|
||||
}
|
||||
|
||||
$index = ($id << 4) | $meta;
|
||||
if(!isset(self::$staticRuntimeIdMap[$index])){
|
||||
self::registerMapping($rtId = ++self::$lastRuntimeId, $id, $meta);
|
||||
MainLogger::getLogger()->error("ID $id meta $meta does not have a corresponding block static runtime ID, added a new unknown runtime ID ($rtId)");
|
||||
return $rtId;
|
||||
}
|
||||
|
||||
return self::$staticRuntimeIdMap[$index];
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param int $runtimeId
|
||||
*
|
||||
* @return int[] [id, meta]
|
||||
*/
|
||||
public static function fromStaticRuntimeId(int $runtimeId) : array{
|
||||
$v = self::$legacyIdMap[$runtimeId];
|
||||
return [$v >> 4, $v & 0xf];
|
||||
}
|
||||
|
||||
private static function registerMapping(int $staticRuntimeId, int $legacyId, int $legacyMeta) : void{
|
||||
self::$staticRuntimeIdMap[($legacyId << 4) | $legacyMeta] = $staticRuntimeId;
|
||||
self::$legacyIdMap[$staticRuntimeId] = ($legacyId << 4) | $legacyMeta;
|
||||
self::$lastRuntimeId = max(self::$lastRuntimeId, $staticRuntimeId);
|
||||
}
|
||||
}
|
||||
|
@ -56,4 +56,11 @@ class Bookshelf extends Solid{
|
||||
return 300;
|
||||
}
|
||||
|
||||
public function getFlameEncouragement() : int{
|
||||
return 30;
|
||||
}
|
||||
|
||||
public function getFlammability() : int{
|
||||
return 20;
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,6 @@ use pocketmine\event\block\BlockGrowEvent;
|
||||
use pocketmine\event\entity\EntityDamageByBlockEvent;
|
||||
use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
@ -66,17 +65,12 @@ class Cactus extends Transparent{
|
||||
);
|
||||
}
|
||||
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onEntityCollide(Entity $entity) : void{
|
||||
$ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_CONTACT, 1);
|
||||
$entity->attack($ev);
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
public function onNearbyBlockChange() : void{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() !== self::SAND and $down->getId() !== self::CACTUS){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
@ -85,10 +79,17 @@ class Cactus extends Transparent{
|
||||
$b = $this->getSide($side);
|
||||
if(!$b->canBeFlowedInto()){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
}
|
||||
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onRandomTick() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() !== self::CACTUS){
|
||||
if($this->meta === 0x0f){
|
||||
for($y = 1; $y < 3; ++$y){
|
||||
@ -109,9 +110,6 @@ class Cactus extends Transparent{
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === self::SAND or $down->getId() === self::CACTUS){
|
||||
@ -119,7 +117,7 @@ class Cactus extends Transparent{
|
||||
$block1 = $this->getSide(Vector3::SIDE_SOUTH);
|
||||
$block2 = $this->getSide(Vector3::SIDE_WEST);
|
||||
$block3 = $this->getSide(Vector3::SIDE_EAST);
|
||||
if($block0->isTransparent() === true and $block1->isTransparent() === true and $block2->isTransparent() === true and $block3->isTransparent() === true){
|
||||
if($block0->isTransparent() and $block1->isTransparent() and $block2->isTransparent() and $block3->isTransparent()){
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
|
||||
return true;
|
||||
|
@ -23,11 +23,10 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Effect;
|
||||
use pocketmine\entity\EffectInstance;
|
||||
use pocketmine\entity\Living;
|
||||
use pocketmine\item\FoodSource;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
@ -73,18 +72,12 @@ class Cake extends Transparent implements FoodSource{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() === self::AIR){ //Replace with common break method
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [];
|
||||
}
|
||||
@ -127,7 +120,7 @@ class Cake extends Transparent implements FoodSource{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Effect[]
|
||||
* @return EffectInstance[]
|
||||
*/
|
||||
public function getAdditionalEffects() : array{
|
||||
return [];
|
||||
|
@ -25,7 +25,6 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\ColorBlockMetaHelper;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
@ -73,16 +72,17 @@ class Carpet extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() === self::AIR){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
public function getFlameEncouragement() : int{
|
||||
return 30;
|
||||
}
|
||||
|
||||
public function getFlammability() : int{
|
||||
return 20;
|
||||
}
|
||||
}
|
||||
|
@ -52,4 +52,12 @@ class Coal extends Solid{
|
||||
public function getFuelTime() : int{
|
||||
return 16000;
|
||||
}
|
||||
|
||||
public function getFlameEncouragement() : int{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function getFlammability() : int{
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\ColorBlockMetaHelper;
|
||||
use pocketmine\level\Level;
|
||||
|
||||
class ConcretePowder extends Fallable{
|
||||
|
||||
@ -46,13 +45,12 @@ class ConcretePowder extends Fallable{
|
||||
return BlockToolType::TYPE_SHOVEL;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL and ($block = $this->checkAdjacentWater()) !== null){
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(($block = $this->checkAdjacentWater()) !== null){
|
||||
$this->level->setBlock($this, $block);
|
||||
return $type;
|
||||
}else{
|
||||
parent::onNearbyBlockChange();
|
||||
}
|
||||
|
||||
return parent::onUpdate($type);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\inventory\BigCraftingGrid;
|
||||
use pocketmine\inventory\CraftingGrid;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\Player;
|
||||
|
||||
@ -49,7 +49,7 @@ class CraftingTable extends Solid{
|
||||
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($player instanceof Player){
|
||||
$player->setCraftingGrid(new BigCraftingGrid($player));
|
||||
$player->setCraftingGrid(new CraftingGrid($player, CraftingGrid::SIZE_BIG));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -25,7 +25,6 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\event\block\BlockGrowEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
@ -65,17 +64,17 @@ abstract class Crops extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() !== Block::FARMLAND){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
}
|
||||
}
|
||||
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() !== Block::FARMLAND){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
public function onRandomTick() : void{
|
||||
if(mt_rand(0, 2) === 1){
|
||||
if($this->meta < 0x07){
|
||||
$block = clone $this;
|
||||
@ -84,18 +83,11 @@ abstract class Crops extends Flowable{
|
||||
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($this, $ev->getNewState(), true, true);
|
||||
}else{
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isAffectedBySilkTouch() : bool{
|
||||
return false;
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
@ -52,15 +51,17 @@ class Dandelion extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent() === true){
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
public function getFlameEncouragement() : int{
|
||||
return 60;
|
||||
}
|
||||
|
||||
public function getFlammability() : int{
|
||||
return 100;
|
||||
}
|
||||
}
|
||||
|
@ -25,8 +25,8 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class DeadBush extends Flowable{
|
||||
|
||||
@ -40,18 +40,20 @@ class DeadBush extends Flowable{
|
||||
return "Dead Bush";
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent() === true){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
if(!$this->getSide(Vector3::SIDE_DOWN)->isTransparent()){
|
||||
return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
}
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return BlockToolType::TYPE_SHEARS;
|
||||
}
|
||||
@ -69,4 +71,12 @@ class DeadBush extends Flowable{
|
||||
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
public function getFlameEncouragement() : int{
|
||||
return 60;
|
||||
}
|
||||
|
||||
public function getFlammability() : int{
|
||||
return 100;
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\level\sound\DoorSound;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
@ -201,26 +200,20 @@ abstract class Door extends Transparent{
|
||||
return $bb;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() === self::AIR){ //Replace with common break method
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), false);
|
||||
if($this->getSide(Vector3::SIDE_UP) instanceof Door){
|
||||
$this->getLevel()->setBlock($this->getSide(Vector3::SIDE_UP), BlockFactory::get(Block::AIR), false);
|
||||
}
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
if($face === Vector3::SIDE_UP){
|
||||
$blockUp = $this->getSide(Vector3::SIDE_UP);
|
||||
$blockDown = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($blockUp->canBeReplaced() === false or $blockDown->isTransparent() === true){
|
||||
if(!$blockUp->canBeReplaced() or $blockDown->isTransparent()){
|
||||
return false;
|
||||
}
|
||||
$direction = $player instanceof Player ? $player->getDirection() : 0;
|
||||
@ -233,13 +226,13 @@ abstract class Door extends Transparent{
|
||||
$next = $this->getSide($faces[($direction + 2) % 4]);
|
||||
$next2 = $this->getSide($faces[$direction]);
|
||||
$metaUp = 0x08;
|
||||
if($next->getId() === $this->getId() or ($next2->isTransparent() === false and $next->isTransparent() === true)){ //Door hinge
|
||||
if($next->getId() === $this->getId() or (!$next2->isTransparent() and $next->isTransparent())){ //Door hinge
|
||||
$metaUp |= 0x01;
|
||||
}
|
||||
|
||||
$this->setDamage($player->getDirection() & 0x03);
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true); //Bottom
|
||||
$this->getLevel()->setBlock($blockUp, $b = BlockFactory::get($this->getId(), $metaUp), true); //Top
|
||||
$this->getLevel()->setBlock($blockUp, BlockFactory::get($this->getId(), $metaUp), true); //Top
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,6 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
@ -84,19 +83,12 @@ class DoublePlant extends Flowable{
|
||||
);
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if(!$this->isValidHalfPlant() or (($this->meta & self::BITFLAG_TOP) === 0 and $down->isTransparent())){
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->isValidHalfPlant() or (($this->meta & self::BITFLAG_TOP) === 0 and $this->getSide(Vector3::SIDE_DOWN)->isTransparent())){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getVariantBitmask() : int{
|
||||
return 0x07;
|
||||
}
|
||||
|
@ -38,4 +38,12 @@ class DoubleWoodenSlab extends DoubleSlab{
|
||||
public function getToolType() : int{
|
||||
return BlockToolType::TYPE_AXE;
|
||||
}
|
||||
|
||||
public function getFlameEncouragement() : int{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function getFlammability() : int{
|
||||
return 20;
|
||||
}
|
||||
}
|
||||
|
@ -24,13 +24,11 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
|
||||
abstract class Fallable extends Solid{
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
public function onNearbyBlockChange() : void{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === self::AIR or $down instanceof Liquid or $down instanceof Fire){
|
||||
$this->level->setBlock($this, BlockFactory::get(Block::AIR), true);
|
||||
@ -46,7 +44,6 @@ abstract class Fallable extends Solid{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|Block
|
||||
|
@ -25,7 +25,6 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
|
||||
@ -49,9 +48,6 @@ class Farmland extends Transparent{
|
||||
return BlockToolType::TYPE_SHOVEL;
|
||||
}
|
||||
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox() : ?AxisAlignedBB{
|
||||
return new AxisAlignedBB(
|
||||
@ -64,11 +60,17 @@ class Farmland extends Transparent{
|
||||
);
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL and $this->getSide(Vector3::SIDE_UP)->isSolid()){
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_UP)->isSolid()){
|
||||
$this->level->setBlock($this, BlockFactory::get(Block::DIRT), true);
|
||||
return $type;
|
||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
}
|
||||
}
|
||||
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onRandomTick() : void{
|
||||
if(!$this->canHydrate()){
|
||||
if($this->meta > 0){
|
||||
$this->meta--;
|
||||
@ -76,19 +78,12 @@ class Farmland extends Transparent{
|
||||
}else{
|
||||
$this->level->setBlock($this, BlockFactory::get(Block::DIRT), false, true);
|
||||
}
|
||||
|
||||
return $type;
|
||||
}elseif($this->meta < 7){
|
||||
$this->meta = 7;
|
||||
$this->level->setBlock($this, $this, false, false);
|
||||
|
||||
return $type;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function canHydrate() : bool{
|
||||
//TODO: check rain
|
||||
$start = $this->add(-4, 0, -4);
|
||||
|
@ -94,4 +94,12 @@ class FenceGate extends Transparent{
|
||||
public function getFuelTime() : int{
|
||||
return 300;
|
||||
}
|
||||
|
||||
public function getFlameEncouragement() : int{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function getFlammability() : int{
|
||||
return 20;
|
||||
}
|
||||
}
|
||||
|
@ -25,11 +25,11 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\projectile\Arrow;
|
||||
use pocketmine\event\block\BlockBurnEvent;
|
||||
use pocketmine\event\entity\EntityCombustByBlockEvent;
|
||||
use pocketmine\event\entity\EntityDamageByBlockEvent;
|
||||
use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Server;
|
||||
|
||||
@ -61,10 +61,6 @@ class Fire extends Flowable{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onEntityCollide(Entity $entity) : void{
|
||||
$ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_FIRE, 1);
|
||||
$entity->attack($ev);
|
||||
@ -83,35 +79,90 @@ class Fire extends Flowable{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
for($s = 0; $s <= 5; ++$s){
|
||||
$side = $this->getSide($s);
|
||||
if($side->getId() !== self::AIR and !($side instanceof Liquid)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->getSide(Vector3::SIDE_DOWN)->isSolid() and !$this->hasAdjacentFlammableBlocks()){
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() !== self::NETHERRACK){
|
||||
if(mt_rand(0, 2) === 0){
|
||||
if($this->meta === 0x0F){
|
||||
$this->level->setBlock($this, BlockFactory::get(Block::AIR));
|
||||
}else{
|
||||
$this->meta++;
|
||||
$this->level->setBlock($this, $this);
|
||||
$this->level->scheduleDelayedBlockUpdate($this, mt_rand(30, 40));
|
||||
}
|
||||
}
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onRandomTick() : void{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
|
||||
$result = null;
|
||||
if($this->meta < 15 and mt_rand(0, 2) === 0){
|
||||
$this->meta++;
|
||||
$result = $this;
|
||||
}
|
||||
$canSpread = true;
|
||||
|
||||
if(!$down->burnsForever()){
|
||||
//TODO: check rain
|
||||
if($this->meta === 15){
|
||||
if(!$down->isFlammable() and mt_rand(0, 3) === 3){ //1/4 chance to extinguish
|
||||
$canSpread = false;
|
||||
$result = BlockFactory::get(Block::AIR);
|
||||
}
|
||||
}elseif(!$this->hasAdjacentFlammableBlocks()){
|
||||
$canSpread = false;
|
||||
if(!$down->isSolid() or $this->meta > 3){ //fire older than 3, or without a solid block below
|
||||
$result = BlockFactory::get(Block::AIR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($result !== null){
|
||||
$this->level->setBlock($this, $result);
|
||||
}
|
||||
|
||||
$this->level->scheduleDelayedBlockUpdate($this, mt_rand(30, 40));
|
||||
|
||||
if($canSpread){
|
||||
//TODO: raise upper bound for chance in humid biomes
|
||||
|
||||
foreach($this->getHorizontalSides() as $side){
|
||||
$this->burnBlock($side, 300);
|
||||
}
|
||||
|
||||
//vanilla uses a 250 upper bound here, but I don't think they intended to increase the chance of incineration
|
||||
$this->burnBlock($this->getSide(Vector3::SIDE_UP), 350);
|
||||
$this->burnBlock($this->getSide(Vector3::SIDE_DOWN), 350);
|
||||
|
||||
//TODO: fire spread
|
||||
}
|
||||
}
|
||||
|
||||
public function onScheduledUpdate() : void{
|
||||
$this->onRandomTick();
|
||||
}
|
||||
|
||||
private function hasAdjacentFlammableBlocks() : bool{
|
||||
for($i = 0; $i <= 5; ++$i){
|
||||
if($this->getSide($i)->isFlammable()){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function burnBlock(Block $block, int $chanceBound) : void{
|
||||
if(mt_rand(0, $chanceBound) < $block->getFlammability()){
|
||||
$this->level->getServer()->getPluginManager()->callEvent($ev = new BlockBurnEvent($block, $this));
|
||||
if(!$ev->isCancelled()){
|
||||
$block->onIncinerate();
|
||||
|
||||
if(mt_rand(0, $this->meta + 9) < 5){ //TODO: check rain
|
||||
$this->level->setBlock($block, BlockFactory::get(Block::FIRE, min(15, $this->meta + (mt_rand(0, 4) >> 2))));
|
||||
}else{
|
||||
$this->level->setBlock($block, BlockFactory::get(Block::AIR));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
@ -71,15 +70,17 @@ class Flower extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
public function getFlameEncouragement() : int{
|
||||
return 60;
|
||||
}
|
||||
|
||||
public function getFlammability() : int{
|
||||
return 100;
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
@ -68,18 +67,12 @@ class FlowerPot extends Flowable{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent() === true){
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
$pot = $this->getLevel()->getTile($this);
|
||||
if(!($pot instanceof TileFlowerPot)){
|
||||
|
@ -23,7 +23,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\Player;
|
||||
|
||||
class GlowingRedstoneOre extends RedstoneOre{
|
||||
|
||||
@ -39,13 +40,19 @@ class GlowingRedstoneOre extends RedstoneOre{
|
||||
return 9;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_SCHEDULED or $type === Level::BLOCK_UPDATE_RANDOM){
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::REDSTONE_ORE, $this->meta), false, false);
|
||||
|
||||
return Level::BLOCK_UPDATE_WEAK;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
|
||||
}
|
||||
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onRandomTick() : void{
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::REDSTONE_ORE, $this->meta), false, false);
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ use pocketmine\event\block\BlockSpreadEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\level\generator\object\TallGrass as TallGrassObject;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\utils\Random;
|
||||
@ -62,8 +61,7 @@ class Grass extends Solid{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
public function onRandomTick() : void{
|
||||
$lightAbove = $this->level->getFullLightAt($this->x, $this->y + 1, $this->z);
|
||||
if($lightAbove < 4 and BlockFactory::$lightFilter[$this->level->getBlockIdAt($this->x, $this->y + 1, $this->z)] >= 3){ //2 plus 1 standard filter amount
|
||||
//grass dies
|
||||
@ -71,8 +69,6 @@ class Grass extends Solid{
|
||||
if(!$ev->isCancelled()){
|
||||
$this->level->setBlock($this, $ev->getNewState(), false, false);
|
||||
}
|
||||
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}elseif($lightAbove >= 9){
|
||||
//try grass spread
|
||||
for($i = 0; $i < 4; ++$i){
|
||||
@ -93,14 +89,9 @@ class Grass extends Solid{
|
||||
$this->level->setBlock($b, $ev->getNewState(), false, false);
|
||||
}
|
||||
}
|
||||
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){
|
||||
$item->count--;
|
||||
|
@ -25,7 +25,6 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
|
||||
@ -60,13 +59,10 @@ class GrassPath extends Transparent{
|
||||
return 0.6;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL and $this->getSide(Vector3::SIDE_UP)->isSolid()){
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_UP)->isSolid()){
|
||||
$this->level->setBlock($this, BlockFactory::get(Block::DIRT), true);
|
||||
return $type;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
|
@ -54,4 +54,12 @@ class HayBale extends Solid{
|
||||
public function getVariantBitmask() : int{
|
||||
return 0x03;
|
||||
}
|
||||
|
||||
public function getFlameEncouragement() : int{
|
||||
return 60;
|
||||
}
|
||||
|
||||
public function getFlammability() : int{
|
||||
return 20;
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,6 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\enchantment\Enchantment;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Ice extends Transparent{
|
||||
@ -67,16 +66,11 @@ class Ice extends Transparent{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
public function onRandomTick() : void{
|
||||
if($this->level->getHighestAdjacentBlockLight($this->x, $this->y, $this->z) >= 12){
|
||||
$this->level->useBreakOn($this);
|
||||
|
||||
return $type;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [];
|
||||
|
@ -53,4 +53,3 @@ class IronBars extends Thin{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,6 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\tile\ItemFrame as TileItemFrame;
|
||||
@ -58,8 +57,7 @@ class ItemFrame extends Flowable{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
public function onNearbyBlockChange() : void{
|
||||
$sides = [
|
||||
0 => Vector3::SIDE_WEST,
|
||||
1 => Vector3::SIDE_EAST,
|
||||
@ -68,11 +66,8 @@ class ItemFrame extends Flowable{
|
||||
];
|
||||
if(!$this->getSide($sides[$this->meta])->isSolid()){
|
||||
$this->level->useBreakOn($this);
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
if($face === Vector3::SIDE_DOWN or $face === Vector3::SIDE_UP or !$blockClicked->isSolid()){
|
||||
|
@ -25,7 +25,6 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
@ -91,7 +90,7 @@ class Ladder extends Transparent{
|
||||
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
if($blockClicked->isTransparent() === false){
|
||||
if(!$blockClicked->isTransparent()){
|
||||
$faces = [
|
||||
2 => 2,
|
||||
3 => 3,
|
||||
@ -109,17 +108,12 @@ class Ladder extends Transparent{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->getSide($this->meta ^ 0x01)->isSolid()){ //Replace with common break method
|
||||
$this->level->useBreakOn($this);
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return BlockToolType::TYPE_AXE;
|
||||
}
|
||||
|
@ -26,7 +26,6 @@ namespace pocketmine\block;
|
||||
use pocketmine\event\block\LeavesDecayEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
@ -67,11 +66,8 @@ class Leaves extends Transparent{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function findLog(Block $pos, array $visited, $distance, &$check, $fromSide = null){
|
||||
protected function findLog(Block $pos, array $visited, $distance, &$check, $fromSide = null) : bool{
|
||||
++$check;
|
||||
$index = $pos->x . "." . $pos->y . "." . $pos->z;
|
||||
if(isset($visited[$index])){
|
||||
@ -87,45 +83,45 @@ class Leaves extends Transparent{
|
||||
}
|
||||
if($fromSide === null){
|
||||
for($side = 2; $side <= 5; ++$side){
|
||||
if($this->findLog($pos->getSide($side), $visited, $distance + 1, $check, $side) === true){
|
||||
if($this->findLog($pos->getSide($side), $visited, $distance + 1, $check, $side)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}else{ //No more loops
|
||||
switch($fromSide){
|
||||
case 2:
|
||||
if($this->findLog($pos->getSide(Vector3::SIDE_NORTH), $visited, $distance + 1, $check, $fromSide) === true){
|
||||
if($this->findLog($pos->getSide(Vector3::SIDE_NORTH), $visited, $distance + 1, $check, $fromSide)){
|
||||
return true;
|
||||
}elseif($this->findLog($pos->getSide(Vector3::SIDE_WEST), $visited, $distance + 1, $check, $fromSide) === true){
|
||||
}elseif($this->findLog($pos->getSide(Vector3::SIDE_WEST), $visited, $distance + 1, $check, $fromSide)){
|
||||
return true;
|
||||
}elseif($this->findLog($pos->getSide(Vector3::SIDE_EAST), $visited, $distance + 1, $check, $fromSide) === true){
|
||||
}elseif($this->findLog($pos->getSide(Vector3::SIDE_EAST), $visited, $distance + 1, $check, $fromSide)){
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if($this->findLog($pos->getSide(Vector3::SIDE_SOUTH), $visited, $distance + 1, $check, $fromSide) === true){
|
||||
if($this->findLog($pos->getSide(Vector3::SIDE_SOUTH), $visited, $distance + 1, $check, $fromSide)){
|
||||
return true;
|
||||
}elseif($this->findLog($pos->getSide(Vector3::SIDE_WEST), $visited, $distance + 1, $check, $fromSide) === true){
|
||||
}elseif($this->findLog($pos->getSide(Vector3::SIDE_WEST), $visited, $distance + 1, $check, $fromSide)){
|
||||
return true;
|
||||
}elseif($this->findLog($pos->getSide(Vector3::SIDE_EAST), $visited, $distance + 1, $check, $fromSide) === true){
|
||||
}elseif($this->findLog($pos->getSide(Vector3::SIDE_EAST), $visited, $distance + 1, $check, $fromSide)){
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if($this->findLog($pos->getSide(Vector3::SIDE_NORTH), $visited, $distance + 1, $check, $fromSide) === true){
|
||||
if($this->findLog($pos->getSide(Vector3::SIDE_NORTH), $visited, $distance + 1, $check, $fromSide)){
|
||||
return true;
|
||||
}elseif($this->findLog($pos->getSide(Vector3::SIDE_SOUTH), $visited, $distance + 1, $check, $fromSide) === true){
|
||||
}elseif($this->findLog($pos->getSide(Vector3::SIDE_SOUTH), $visited, $distance + 1, $check, $fromSide)){
|
||||
return true;
|
||||
}elseif($this->findLog($pos->getSide(Vector3::SIDE_WEST), $visited, $distance + 1, $check, $fromSide) === true){
|
||||
}elseif($this->findLog($pos->getSide(Vector3::SIDE_WEST), $visited, $distance + 1, $check, $fromSide)){
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if($this->findLog($pos->getSide(Vector3::SIDE_NORTH), $visited, $distance + 1, $check, $fromSide) === true){
|
||||
if($this->findLog($pos->getSide(Vector3::SIDE_NORTH), $visited, $distance + 1, $check, $fromSide)){
|
||||
return true;
|
||||
}elseif($this->findLog($pos->getSide(Vector3::SIDE_SOUTH), $visited, $distance + 1, $check, $fromSide) === true){
|
||||
}elseif($this->findLog($pos->getSide(Vector3::SIDE_SOUTH), $visited, $distance + 1, $check, $fromSide)){
|
||||
return true;
|
||||
}elseif($this->findLog($pos->getSide(Vector3::SIDE_EAST), $visited, $distance + 1, $check, $fromSide) === true){
|
||||
}elseif($this->findLog($pos->getSide(Vector3::SIDE_EAST), $visited, $distance + 1, $check, $fromSide)){
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
@ -136,13 +132,18 @@ class Leaves extends Transparent{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(($this->meta & 0b00001100) === 0){
|
||||
$this->meta |= 0x08;
|
||||
$this->getLevel()->setBlock($this, $this, true, false);
|
||||
}
|
||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
}
|
||||
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onRandomTick() : void{
|
||||
if(($this->meta & 0b00001100) === 0x08){
|
||||
$this->meta &= 0x03;
|
||||
$visited = [];
|
||||
@ -150,19 +151,14 @@ class Leaves extends Transparent{
|
||||
|
||||
$this->getLevel()->getServer()->getPluginManager()->callEvent($ev = new LeavesDecayEvent($this));
|
||||
|
||||
if($ev->isCancelled() or $this->findLog($this, $visited, 0, $check) === true){
|
||||
if($ev->isCancelled() or $this->findLog($this, $visited, 0, $check)){
|
||||
$this->getLevel()->setBlock($this, $this, false, false);
|
||||
}else{
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
$this->meta |= 0x04;
|
||||
return $this->getLevel()->setBlock($this, $this, true);
|
||||
@ -195,4 +191,12 @@ class Leaves extends Transparent{
|
||||
public function canDropApples() : bool{
|
||||
return $this->meta === self::OAK;
|
||||
}
|
||||
|
||||
public function getFlameEncouragement() : int{
|
||||
return 30;
|
||||
}
|
||||
|
||||
public function getFlammability() : int{
|
||||
return 60;
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
@ -74,8 +73,7 @@ class Lever extends Flowable{
|
||||
return $this->level->setBlock($blockReplace, $this, true, true);
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
public function onNearbyBlockChange() : void{
|
||||
$faces = [
|
||||
0 => Vector3::SIDE_UP,
|
||||
1 => Vector3::SIDE_WEST,
|
||||
@ -88,13 +86,8 @@ class Lever extends Flowable{
|
||||
];
|
||||
if(!$this->getSide($faces[$this->meta & 0x07])->isSolid()){
|
||||
$this->level->useBreakOn($this);
|
||||
|
||||
return $type;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//TODO
|
||||
}
|
||||
|
@ -189,11 +189,13 @@ abstract class Liquid extends Transparent{
|
||||
}
|
||||
|
||||
public function addVelocityToEntity(Entity $entity, Vector3 $vector) : void{
|
||||
if($entity->canBeMovedByCurrents()){
|
||||
$flow = $this->getFlowVector();
|
||||
$vector->x += $flow->x;
|
||||
$vector->y += $flow->y;
|
||||
$vector->z += $flow->z;
|
||||
}
|
||||
}
|
||||
|
||||
abstract public function tickRate() : int;
|
||||
|
||||
@ -206,20 +208,12 @@ abstract class Liquid extends Transparent{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param int $type
|
||||
*
|
||||
* @return bool|int
|
||||
*/
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
public function onNearbyBlockChange() : void{
|
||||
$this->checkForHarden();
|
||||
$this->level->scheduleDelayedBlockUpdate($this, $this->tickRate());
|
||||
}
|
||||
|
||||
return $type;
|
||||
}elseif($type === Level::BLOCK_UPDATE_SCHEDULED){
|
||||
public function onScheduledUpdate() : void{
|
||||
$decay = $this->getFlowDecay($this);
|
||||
$multiplier = $this->getFlowDecayPerBlock();
|
||||
|
||||
@ -296,11 +290,6 @@ abstract class Liquid extends Transparent{
|
||||
|
||||
$this->checkForHarden();
|
||||
}
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function flowIntoBlock(Block $block, int $newFlowDecay) : void{
|
||||
|
@ -66,4 +66,8 @@ class Magma extends Solid{
|
||||
$entity->attack($ev);
|
||||
}
|
||||
}
|
||||
|
||||
public function burnsForever() : bool{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,6 @@ namespace pocketmine\block;
|
||||
use pocketmine\event\block\BlockGrowEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Server;
|
||||
|
||||
@ -42,13 +41,7 @@ class MelonStem extends Crops{
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() !== Block::FARMLAND){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
public function onRandomTick() : void{
|
||||
if(mt_rand(0, 2) === 1){
|
||||
if($this->meta < 0x07){
|
||||
$block = clone $this;
|
||||
@ -57,13 +50,11 @@ class MelonStem extends Crops{
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($this, $ev->getNewState(), true);
|
||||
}
|
||||
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}else{
|
||||
for($side = 2; $side <= 5; ++$side){
|
||||
$b = $this->getSide($side);
|
||||
if($b->getId() === self::MELON_BLOCK){
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
return;
|
||||
}
|
||||
}
|
||||
$side = $this->getSide(mt_rand(2, 5));
|
||||
@ -76,11 +67,6 @@ class MelonStem extends Crops{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
|
@ -26,7 +26,6 @@ namespace pocketmine\block;
|
||||
use pocketmine\event\block\BlockSpreadEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Server;
|
||||
|
||||
@ -60,8 +59,7 @@ class Mycelium extends Solid{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
public function onRandomTick() : void{
|
||||
//TODO: light levels
|
||||
$x = mt_rand($this->x - 1, $this->x + 1);
|
||||
$y = mt_rand($this->y - 2, $this->y + 2);
|
||||
@ -76,5 +74,4 @@ class Mycelium extends Solid{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ namespace pocketmine\block;
|
||||
use pocketmine\event\block\BlockGrowEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
@ -44,10 +43,6 @@ class NetherWartPlant extends Flowable{
|
||||
return "Nether Wart";
|
||||
}
|
||||
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === Block::SOUL_SAND){
|
||||
@ -59,9 +54,17 @@ class NetherWartPlant extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
switch($type){
|
||||
case Level::BLOCK_UPDATE_RANDOM:
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() !== Block::SOUL_SAND){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
}
|
||||
}
|
||||
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onRandomTick() : void{
|
||||
if($this->meta < 3 and mt_rand(0, 10) === 0){ //Still growing
|
||||
$block = clone $this;
|
||||
$block->meta++;
|
||||
@ -69,20 +72,8 @@ class NetherWartPlant extends Flowable{
|
||||
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($this, $ev->getNewState(), false, true);
|
||||
|
||||
return $type;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Level::BLOCK_UPDATE_NORMAL:
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() !== Block::SOUL_SAND){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
return $type;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
|
@ -48,4 +48,8 @@ class Netherrack extends Solid{
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_WOODEN;
|
||||
}
|
||||
|
||||
public function burnsForever() : bool{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -61,4 +61,11 @@ class Planks extends Solid{
|
||||
return 300;
|
||||
}
|
||||
|
||||
public function getFlameEncouragement() : int{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function getFlammability() : int{
|
||||
return 20;
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,6 @@ namespace pocketmine\block;
|
||||
use pocketmine\event\block\BlockGrowEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Server;
|
||||
|
||||
@ -42,13 +41,7 @@ class PumpkinStem extends Crops{
|
||||
return "Pumpkin Stem";
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() !== Block::FARMLAND){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
public function onRandomTick() : void{
|
||||
if(mt_rand(0, 2) === 1){
|
||||
if($this->meta < 0x07){
|
||||
$block = clone $this;
|
||||
@ -57,13 +50,11 @@ class PumpkinStem extends Crops{
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($this, $ev->getNewState(), true);
|
||||
}
|
||||
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}else{
|
||||
for($side = 2; $side <= 5; ++$side){
|
||||
$b = $this->getSide($side);
|
||||
if($b->getId() === self::PUMPKIN){
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
return;
|
||||
}
|
||||
}
|
||||
$side = $this->getSide(mt_rand(2, 5));
|
||||
@ -76,11 +67,6 @@ class PumpkinStem extends Crops{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
|
@ -24,7 +24,6 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
@ -63,19 +62,14 @@ class Rail extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
return $type;
|
||||
}else{
|
||||
//TODO: Update rail connectivity
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
@ -44,21 +43,15 @@ class RedMushroom extends Flowable{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent() === true){
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->isTransparent() === false){
|
||||
if(!$down->isTransparent()){
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
return true;
|
||||
|
@ -26,7 +26,6 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\TieredTool;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
@ -50,14 +49,12 @@ class RedstoneOre extends Solid{
|
||||
return $this->getLevel()->setBlock($this, $this, true, false);
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL or $type === Level::BLOCK_UPDATE_TOUCH){
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::GLOWING_REDSTONE_ORE, $this->meta));
|
||||
|
||||
return Level::BLOCK_UPDATE_WEAK;
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
return $this->getLevel()->setBlock($this, BlockFactory::get(Block::GLOWING_REDSTONE_ORE, $this->meta));
|
||||
}
|
||||
|
||||
return false;
|
||||
public function onNearbyBlockChange() : void{
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::GLOWING_REDSTONE_ORE, $this->meta));
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
|
@ -25,7 +25,6 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\generator\object\Tree;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\utils\Random;
|
||||
@ -56,10 +55,6 @@ class Sapling extends Flowable{
|
||||
return $names[$this->getVariant()] ?? "Unknown";
|
||||
}
|
||||
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === self::GRASS or $down->getId() === self::DIRT or $down->getId() === self::FARMLAND){
|
||||
@ -84,29 +79,25 @@ class Sapling extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent() === true){
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){ //Growth
|
||||
}
|
||||
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onRandomTick() : void{
|
||||
if(mt_rand(1, 7) === 1){
|
||||
if(($this->meta & 0x08) === 0x08){
|
||||
Tree::growTree($this->getLevel(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->getVariant());
|
||||
}else{
|
||||
$this->meta |= 0x08;
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
}else{
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getVariantBitmask() : int{
|
||||
|
@ -24,7 +24,6 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
@ -77,18 +76,12 @@ class SignPost extends Transparent{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() === self::AIR){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return BlockToolType::TYPE_AXE;
|
||||
}
|
||||
|
@ -26,7 +26,6 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\TieredTool;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
@ -58,10 +57,6 @@ class SnowLayer extends Flowable{
|
||||
return TieredTool::TIER_WOODEN;
|
||||
}
|
||||
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
if($blockReplace->getSide(Vector3::SIDE_DOWN)->isSolid()){
|
||||
//TODO: fix placement
|
||||
@ -73,24 +68,22 @@ class SnowLayer extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->getSide(Vector3::SIDE_DOWN)->isSolid()){
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), false, false);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
}
|
||||
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onRandomTick() : void{
|
||||
if($this->level->getBlockLightAt($this->x, $this->y, $this->z) >= 12){
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), false, false);
|
||||
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
ItemFactory::get(Item::SNOWBALL) //TODO: check layer count
|
||||
|
@ -25,7 +25,6 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
@ -75,18 +74,12 @@ class StandingBanner extends Transparent{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() === self::AIR){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return BlockToolType::TYPE_AXE;
|
||||
}
|
||||
@ -99,7 +92,7 @@ class StandingBanner extends Transparent{
|
||||
$tile = $this->level->getTile($this);
|
||||
|
||||
$drop = ItemFactory::get(Item::BANNER, ($tile instanceof TileBanner ? $tile->getBaseColor() : 0));
|
||||
if($tile instanceof TileBanner and ($patterns = $tile->namedtag->getListTag(TileBanner::TAG_PATTERNS)) !== null and $patterns->getCount() > 0){
|
||||
if($tile instanceof TileBanner and ($patterns = $tile->namedtag->getListTag(TileBanner::TAG_PATTERNS)) !== null and !$patterns->empty()){
|
||||
$drop->setNamedTagEntry($patterns);
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,6 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\event\block\BlockGrowEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
@ -44,10 +43,6 @@ class Sugarcane extends Flowable{
|
||||
return "Sugarcane";
|
||||
}
|
||||
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() !== self::SUGARCANE_BLOCK){
|
||||
@ -73,15 +68,18 @@ class Sugarcane extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
public function onNearbyBlockChange() : void{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->isTransparent() === true and $down->getId() !== self::SUGARCANE_BLOCK){
|
||||
if($down->isTransparent() and $down->getId() !== self::SUGARCANE_BLOCK){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
}
|
||||
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onRandomTick() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() !== self::SUGARCANE_BLOCK){
|
||||
if($this->meta === 0x0F){
|
||||
for($y = 1; $y < 3; ++$y){
|
||||
@ -97,14 +95,9 @@ class Sugarcane extends Flowable{
|
||||
++$this->meta;
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
}
|
||||
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === self::SUGARCANE_BLOCK){
|
||||
|
@ -68,4 +68,16 @@ class TNT extends Solid{
|
||||
$tnt->spawnToAll();
|
||||
}
|
||||
}
|
||||
|
||||
public function getFlameEncouragement() : int{
|
||||
return 15;
|
||||
}
|
||||
|
||||
public function getFlammability() : int{
|
||||
return 100;
|
||||
}
|
||||
|
||||
public function onIncinerate() : void{
|
||||
$this->ignite();
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,6 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
@ -61,19 +60,12 @@ class TallGrass extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent() === true){ //Replace with common break method
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){ //Replace with common break method
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true, true);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return BlockToolType::TYPE_SHEARS;
|
||||
}
|
||||
@ -96,4 +88,11 @@ class TallGrass extends Flowable{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getFlameEncouragement() : int{
|
||||
return 60;
|
||||
}
|
||||
|
||||
public function getFlammability() : int{
|
||||
return 100;
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
@ -44,9 +43,7 @@ class Torch extends Flowable{
|
||||
return "Torch";
|
||||
}
|
||||
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
public function onNearbyBlockChange() : void{
|
||||
$below = $this->getSide(Vector3::SIDE_DOWN);
|
||||
$side = $this->getDamage();
|
||||
$faces = [
|
||||
@ -58,20 +55,15 @@ class Torch extends Flowable{
|
||||
5 => Vector3::SIDE_DOWN
|
||||
];
|
||||
|
||||
if($this->getSide($faces[$side])->isTransparent() === true and !($side === Vector3::SIDE_DOWN and ($below->getId() === self::FENCE or $below->getId() === self::COBBLESTONE_WALL))){
|
||||
if($this->getSide($faces[$side])->isTransparent() and !($side === Vector3::SIDE_DOWN and ($below->getId() === self::FENCE or $below->getId() === self::COBBLESTONE_WALL))){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
$below = $this->getSide(Vector3::SIDE_DOWN);
|
||||
|
||||
if($blockClicked->isTransparent() === false and $face !== Vector3::SIDE_DOWN){
|
||||
if(!$blockClicked->isTransparent() and $face !== Vector3::SIDE_DOWN){
|
||||
$faces = [
|
||||
Vector3::SIDE_UP => 5,
|
||||
Vector3::SIDE_NORTH => 4,
|
||||
@ -83,7 +75,7 @@ class Torch extends Flowable{
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
return true;
|
||||
}elseif($below->isTransparent() === false or $below->getId() === self::FENCE or $below->getId() === self::COBBLESTONE_WALL){
|
||||
}elseif(!$below->isTransparent() or $below->getId() === self::FENCE or $below->getId() === self::COBBLESTONE_WALL){
|
||||
$this->meta = 0;
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
|
@ -25,7 +25,6 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
@ -62,10 +61,6 @@ class Vine extends Flowable{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function canBeReplaced() : bool{
|
||||
return true;
|
||||
}
|
||||
@ -157,8 +152,7 @@ class Vine extends Flowable{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
public function onNearbyBlockChange() : void{
|
||||
$sides = [
|
||||
self::FLAG_SOUTH => Vector3::SIDE_SOUTH,
|
||||
self::FLAG_WEST => Vector3::SIDE_WEST,
|
||||
@ -185,16 +179,17 @@ class Vine extends Flowable{
|
||||
$this->meta = $meta;
|
||||
$this->level->setBlock($this, $this);
|
||||
}
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
}
|
||||
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onRandomTick() : void{
|
||||
//TODO: vine growth
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
@ -210,4 +205,12 @@ class Vine extends Flowable{
|
||||
public function getToolType() : int{
|
||||
return BlockToolType::TYPE_AXE;
|
||||
}
|
||||
|
||||
public function getFlameEncouragement() : int{
|
||||
return 15;
|
||||
}
|
||||
|
||||
public function getFlammability() : int{
|
||||
return 100;
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\level\Level;
|
||||
|
||||
class WallBanner extends StandingBanner{
|
||||
|
||||
protected $id = self::WALL_BANNER;
|
||||
@ -33,13 +31,9 @@ class WallBanner extends StandingBanner{
|
||||
return "Wall Banner";
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide($this->meta ^ 0x01)->getId() === self::AIR){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
}
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\level\Level;
|
||||
|
||||
class WallSign extends SignPost{
|
||||
|
||||
protected $id = self::WALL_SIGN;
|
||||
@ -33,13 +31,9 @@ class WallSign extends SignPost{
|
||||
return "Wall Sign";
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide($this->meta ^ 0x01)->getId() === self::AIR){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
}
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
@ -69,17 +68,12 @@ class WaterLily extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!($this->getSide(Vector3::SIDE_DOWN) instanceof Water)){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
|
@ -70,4 +70,12 @@ class Wood extends Solid{
|
||||
public function getFuelTime() : int{
|
||||
return 300;
|
||||
}
|
||||
|
||||
public function getFlameEncouragement() : int{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function getFlammability() : int{
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
@ -56,4 +56,12 @@ class WoodenFence extends Fence{
|
||||
public function getFuelTime() : int{
|
||||
return 300;
|
||||
}
|
||||
|
||||
public function getFlameEncouragement() : int{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function getFlammability() : int{
|
||||
return 20;
|
||||
}
|
||||
}
|
||||
|
@ -54,4 +54,12 @@ class WoodenSlab extends Slab{
|
||||
public function getFuelTime() : int{
|
||||
return 300;
|
||||
}
|
||||
|
||||
public function getFlameEncouragement() : int{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function getFlammability() : int{
|
||||
return 20;
|
||||
}
|
||||
}
|
||||
|
@ -36,4 +36,12 @@ class WoodenStairs extends Stair{
|
||||
public function getToolType() : int{
|
||||
return BlockToolType::TYPE_AXE;
|
||||
}
|
||||
|
||||
public function getFlameEncouragement() : int{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function getFlammability() : int{
|
||||
return 20;
|
||||
}
|
||||
}
|
||||
|
@ -54,4 +54,12 @@ class Wool extends Solid{
|
||||
|
||||
return $time;
|
||||
}
|
||||
|
||||
public function getFlameEncouragement() : int{
|
||||
return 30;
|
||||
}
|
||||
|
||||
public function getFlammability() : int{
|
||||
return 60;
|
||||
}
|
||||
}
|
||||
|
@ -26,18 +26,16 @@ declare(strict_types=1);
|
||||
*/
|
||||
namespace pocketmine\command;
|
||||
|
||||
use pocketmine\event\TextContainer;
|
||||
use pocketmine\event\TimingsHandler;
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\lang\TextContainer;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\timings\TimingsHandler;
|
||||
use pocketmine\utils\TextFormat;
|
||||
|
||||
abstract class Command{
|
||||
|
||||
/** @var string */
|
||||
private $name;
|
||||
/** @var array */
|
||||
protected $commandData = null;
|
||||
|
||||
/** @var string */
|
||||
private $nextLabel;
|
||||
@ -234,9 +232,9 @@ abstract class Command{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @return string|null
|
||||
*/
|
||||
public function getPermissionMessage() : string{
|
||||
public function getPermissionMessage() : ?string{
|
||||
return $this->permissionMessage;
|
||||
}
|
||||
|
||||
@ -308,7 +306,7 @@ abstract class Command{
|
||||
$colored = new TranslationContainer(TextFormat::GRAY . TextFormat::ITALIC . "%chat.type.admin", [$source->getName(), $message]);
|
||||
}
|
||||
|
||||
if($sendToSource === true and !($source instanceof ConsoleCommandSender)){
|
||||
if($sendToSource and !($source instanceof ConsoleCommandSender)){
|
||||
$source->sendMessage($message);
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\command;
|
||||
|
||||
use pocketmine\event\TextContainer;
|
||||
use pocketmine\lang\TextContainer;
|
||||
use pocketmine\permission\Permissible;
|
||||
use pocketmine\Server;
|
||||
|
||||
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\command;
|
||||
|
||||
use pocketmine\event\TextContainer;
|
||||
use pocketmine\lang\TextContainer;
|
||||
use pocketmine\permission\PermissibleBase;
|
||||
use pocketmine\permission\Permission;
|
||||
use pocketmine\permission\PermissionAttachment;
|
||||
@ -92,13 +92,6 @@ class ConsoleCommandSender implements CommandSender{
|
||||
return $this->perm->getEffectivePermissions();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isPlayer() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Server
|
||||
*/
|
||||
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\command;
|
||||
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\utils\TextFormat;
|
||||
|
||||
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\command;
|
||||
|
||||
use pocketmine\event\TextContainer;
|
||||
use pocketmine\lang\TextContainer;
|
||||
|
||||
class RemoteConsoleCommandSender extends ConsoleCommandSender{
|
||||
|
||||
|
@ -65,7 +65,7 @@ use pocketmine\command\defaults\VanillaCommand;
|
||||
use pocketmine\command\defaults\VersionCommand;
|
||||
use pocketmine\command\defaults\WhitelistCommand;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\utils\TextFormat;
|
||||
|
||||
|
@ -26,7 +26,7 @@ namespace pocketmine\command\defaults;
|
||||
use pocketmine\command\Command;
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\Player;
|
||||
|
||||
class BanCommand extends VanillaCommand{
|
||||
|
@ -26,7 +26,7 @@ namespace pocketmine\command\defaults;
|
||||
use pocketmine\command\Command;
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\Player;
|
||||
|
||||
class BanIpCommand extends VanillaCommand{
|
||||
|
@ -25,7 +25,7 @@ namespace pocketmine\command\defaults;
|
||||
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\permission\BanEntry;
|
||||
|
||||
class BanListCommand extends VanillaCommand{
|
||||
|
@ -25,7 +25,7 @@ namespace pocketmine\command\defaults;
|
||||
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\Server;
|
||||
|
||||
class DefaultGamemodeCommand extends VanillaCommand{
|
||||
|
@ -26,7 +26,7 @@ namespace pocketmine\command\defaults;
|
||||
use pocketmine\command\Command;
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\utils\TextFormat;
|
||||
|
||||
|
@ -26,7 +26,7 @@ namespace pocketmine\command\defaults;
|
||||
use pocketmine\command\Command;
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\level\Level;
|
||||
|
||||
class DifficultyCommand extends VanillaCommand{
|
||||
|
@ -27,13 +27,11 @@ use pocketmine\command\CommandSender;
|
||||
|
||||
class DumpMemoryCommand extends VanillaCommand{
|
||||
|
||||
private static $executions = 0;
|
||||
|
||||
public function __construct(string $name){
|
||||
parent::__construct(
|
||||
$name,
|
||||
"Dumps the memory",
|
||||
"/$name <TOKEN (run once to get it)> [path]"
|
||||
"/$name [path]"
|
||||
);
|
||||
$this->setPermission("pocketmine.command.dumpmemory");
|
||||
}
|
||||
@ -43,16 +41,7 @@ class DumpMemoryCommand extends VanillaCommand{
|
||||
return true;
|
||||
}
|
||||
|
||||
$token = strtoupper(substr(sha1(BOOTUP_RANDOM . ":" . $sender->getServer()->getServerUniqueId() . ":" . self::$executions), 6, 6));
|
||||
|
||||
if(count($args) < 1 or strtoupper($args[0]) !== $token){
|
||||
$sender->sendMessage("Usage: /" . $this->getName() . " " . $token);
|
||||
return true;
|
||||
}
|
||||
|
||||
++self::$executions;
|
||||
|
||||
$sender->getServer()->getMemoryManager()->dumpServerMemory($args[1] ?? ($sender->getServer()->getDataPath() . "/memoryDump_$token"), 48, 80);
|
||||
$sender->getServer()->getMemoryManager()->dumpServerMemory($args[0] ?? ($sender->getServer()->getDataPath() . "/memory_dumps/" . date("D_M_j-H.i.s-T_Y")), 48, 80);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,8 @@ namespace pocketmine\command\defaults;
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\entity\Effect;
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\entity\EffectInstance;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\utils\TextFormat;
|
||||
|
||||
class EffectCommand extends VanillaCommand{
|
||||
@ -79,26 +80,26 @@ class EffectCommand extends VanillaCommand{
|
||||
$amplification = 0;
|
||||
|
||||
if(count($args) >= 3){
|
||||
$duration = ((int) $args[2]) * 20; //ticks
|
||||
if(($d = $this->getBoundedInt($sender, $args[2], 0, INT32_MAX)) === null){
|
||||
return false;
|
||||
}
|
||||
$duration = $d * 20; //ticks
|
||||
}else{
|
||||
$duration = $effect->getDefaultDuration();
|
||||
$duration = null;
|
||||
}
|
||||
|
||||
if(count($args) >= 4){
|
||||
$amplification = (int) $args[3];
|
||||
if($amplification > 255){
|
||||
$sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.num.tooBig", [(string) $args[3], "255"]));
|
||||
return true;
|
||||
}elseif($amplification < 0){
|
||||
$sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.num.tooSmall", [(string) $args[3], "0"]));
|
||||
return true;
|
||||
$amplification = $this->getBoundedInt($sender, $args[3], 0, 255);
|
||||
if($amplification === null){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$visible = true;
|
||||
if(count($args) >= 5){
|
||||
$v = strtolower($args[4]);
|
||||
if($v === "on" or $v === "true" or $v === "t" or $v === "1"){
|
||||
$effect->setVisible(false);
|
||||
$visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,10 +116,9 @@ class EffectCommand extends VanillaCommand{
|
||||
$player->removeEffect($effect->getId());
|
||||
$sender->sendMessage(new TranslationContainer("commands.effect.success.removed", [$effect->getName(), $player->getDisplayName()]));
|
||||
}else{
|
||||
$effect->setDuration($duration)->setAmplifier($amplification);
|
||||
|
||||
$player->addEffect($effect);
|
||||
self::broadcastCommandMessage($sender, new TranslationContainer("%commands.effect.success", [$effect->getName(), $effect->getAmplifier(), $player->getDisplayName(), $effect->getDuration() / 20, $effect->getId()]));
|
||||
$instance = new EffectInstance($effect, $duration, $amplification, $visible);
|
||||
$player->addEffect($instance);
|
||||
self::broadcastCommandMessage($sender, new TranslationContainer("%commands.effect.success", [$effect->getName(), $instance->getAmplifier(), $player->getDisplayName(), $instance->getDuration() / 20, $effect->getId()]));
|
||||
}
|
||||
|
||||
|
||||
|
@ -25,9 +25,9 @@ namespace pocketmine\command\defaults;
|
||||
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\item\enchantment\Enchantment;
|
||||
use pocketmine\item\enchantment\EnchantmentInstance;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\utils\TextFormat;
|
||||
|
||||
class EnchantCommand extends VanillaCommand{
|
||||
|
@ -26,7 +26,7 @@ namespace pocketmine\command\defaults;
|
||||
use pocketmine\command\Command;
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\utils\TextFormat;
|
||||
|
@ -26,11 +26,10 @@ namespace pocketmine\command\defaults;
|
||||
use pocketmine\command\Command;
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\nbt\JsonNBTParser;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\nbt\JsonNbtParser;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\utils\TextFormat;
|
||||
|
||||
class GiveCommand extends VanillaCommand{
|
||||
@ -54,7 +53,17 @@ class GiveCommand extends VanillaCommand{
|
||||
}
|
||||
|
||||
$player = $sender->getServer()->getPlayer($args[0]);
|
||||
if($player === null){
|
||||
$sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound"));
|
||||
return true;
|
||||
}
|
||||
|
||||
try{
|
||||
$item = ItemFactory::fromString($args[1]);
|
||||
}catch(\InvalidArgumentException $e){
|
||||
$sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.give.item.notFound", [$args[1]]));
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!isset($args[2])){
|
||||
$item->setCount($item->getMaxStackSize());
|
||||
@ -66,8 +75,8 @@ class GiveCommand extends VanillaCommand{
|
||||
$tags = $exception = null;
|
||||
$data = implode(" ", array_slice($args, 3));
|
||||
try{
|
||||
$tags = JsonNBTParser::parseJSON($data);
|
||||
}catch(\Throwable $ex){
|
||||
$tags = JsonNbtParser::parseJson($data);
|
||||
}catch(\Exception $ex){
|
||||
$exception = $ex;
|
||||
}
|
||||
|
||||
@ -79,20 +88,8 @@ class GiveCommand extends VanillaCommand{
|
||||
$item->setNamedTag($tags);
|
||||
}
|
||||
|
||||
if($player instanceof Player){
|
||||
if($item->getId() === 0){
|
||||
$sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.give.item.notFound", [$args[1]]));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//TODO: overflow
|
||||
$player->getInventory()->addItem(clone $item);
|
||||
}else{
|
||||
$sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Command::broadcastCommandMessage($sender, new TranslationContainer("%commands.give.success", [
|
||||
$item->getName() . " (" . $item->getId() . ":" . $item->getDamage() . ")",
|
||||
|
@ -25,7 +25,7 @@ namespace pocketmine\command\defaults;
|
||||
|
||||
use pocketmine\command\Command;
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\utils\TextFormat;
|
||||
|
||||
class HelpCommand extends VanillaCommand{
|
||||
|
@ -26,7 +26,7 @@ namespace pocketmine\command\defaults;
|
||||
use pocketmine\command\Command;
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\utils\TextFormat;
|
||||
|
||||
|
@ -27,7 +27,7 @@ use pocketmine\command\Command;
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\utils\TextFormat;
|
||||
|
||||
|
@ -24,7 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\command\defaults;
|
||||
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\Player;
|
||||
|
||||
class ListCommand extends VanillaCommand{
|
||||
|
@ -25,7 +25,7 @@ namespace pocketmine\command\defaults;
|
||||
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\utils\TextFormat;
|
||||
|
||||
|
@ -26,7 +26,7 @@ namespace pocketmine\command\defaults;
|
||||
use pocketmine\command\Command;
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\utils\TextFormat;
|
||||
|
||||
|
@ -26,7 +26,7 @@ namespace pocketmine\command\defaults;
|
||||
use pocketmine\command\Command;
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
|
||||
class PardonCommand extends VanillaCommand{
|
||||
|
||||
|
@ -26,7 +26,7 @@ namespace pocketmine\command\defaults;
|
||||
use pocketmine\command\Command;
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
|
||||
class PardonIpCommand extends VanillaCommand{
|
||||
|
||||
|
@ -26,9 +26,9 @@ namespace pocketmine\command\defaults;
|
||||
use pocketmine\block\BlockFactory;
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\level\particle\AngryVillagerParticle;
|
||||
use pocketmine\level\particle\BlockForceFieldParticle;
|
||||
use pocketmine\level\particle\BubbleParticle;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user