mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-15 13:55:12 +00:00
Compare commits
501 Commits
before-fix
...
Alpha_1.4d
Author | SHA1 | Date | |
---|---|---|---|
0db009b08f | |||
7cdf5a73eb | |||
6c442551f7 | |||
eccd82ca4b | |||
6fbfa1836f | |||
5dfb1fb9d5 | |||
4a615f03b5 | |||
47503d84c2 | |||
fdb7fa36b8 | |||
e29ddadd2f | |||
d2ed0aa9f0 | |||
a7944502cd | |||
063d14ba63 | |||
35ea9708a5 | |||
9a4ead54e3 | |||
0d55d5c653 | |||
94bc817756 | |||
52b0e8b1ee | |||
9bdd294a66 | |||
0bfa9506d1 | |||
67b0c4bc2e | |||
dd729ced68 | |||
a6e22de6a3 | |||
7624eda7b1 | |||
5e47dda0a8 | |||
61043d2e0d | |||
3e882ef40d | |||
a8359f29a8 | |||
167ee97569 | |||
53214005cd | |||
6e74bb7faf | |||
f60fdb5e61 | |||
4bd2f3aea8 | |||
dcba580115 | |||
63008c4ebb | |||
c16f45ce39 | |||
f2fa13119a | |||
756a8fead6 | |||
7ed6ac2341 | |||
4a072b4163 | |||
91b2f81f3c | |||
5c826cb9ab | |||
20b0df4b57 | |||
1fab6bd589 | |||
7dd4a843c6 | |||
828f7f1590 | |||
c9535162bd | |||
99c5ad789b | |||
e6c510e7fd | |||
d3789d4fed | |||
8fbc63c14e | |||
4d0b184ca4 | |||
589fde27c0 | |||
6cb55da9c7 | |||
0251ae93d8 | |||
5b69f07a55 | |||
9604907566 | |||
1f882f42d3 | |||
981796fd4c | |||
3e53ecdfb3 | |||
cd324c3247 | |||
99d4ff5bdb | |||
88bcaea292 | |||
ff90b83a9f | |||
f3079f8444 | |||
65523972c2 | |||
25ecdcf6e2 | |||
6b361389ad | |||
643a4c1ef5 | |||
0503adc08c | |||
892119f791 | |||
1b6fcf7942 | |||
cbbdb42092 | |||
81492acb0c | |||
6576c88a08 | |||
637d9da5a6 | |||
22552cdd72 | |||
417cb94ea3 | |||
4db97a007c | |||
519922b550 | |||
962847ffdf | |||
b18783a0e7 | |||
5a8e6619e9 | |||
6b45c16a38 | |||
8b2440ff96 | |||
32f67d7187 | |||
43635b501a | |||
aa85993634 | |||
2f4fe4751c | |||
c8dd8f02eb | |||
6c116678d7 | |||
75d2409a7c | |||
f7c23e89f0 | |||
f5a74a87e3 | |||
d4881260da | |||
6d6059b61f | |||
75bf3023a7 | |||
f62cbcbcfa | |||
e5d8993d67 | |||
7bcc6d10b8 | |||
308430c28d | |||
692a4fb57b | |||
3fd18ca4af | |||
ca3fc33708 | |||
e4bc9611f6 | |||
3184a8e7d5 | |||
ff91113b81 | |||
f02fc664ba | |||
e504421515 | |||
b80bae3352 | |||
311961f3aa | |||
1aa45500c0 | |||
58df00fa86 | |||
67baaf5308 | |||
f20c862123 | |||
a321aeca96 | |||
487015d332 | |||
b064f1e71a | |||
2ec0d86126 | |||
cc36f8f997 | |||
44f8541331 | |||
87308d1c51 | |||
84f9516f24 | |||
fadf1a5d40 | |||
401d7342dd | |||
7067c09228 | |||
3abec0a3c0 | |||
c2d760e6d9 | |||
de5e9df82b | |||
b506ab349f | |||
e2f7cf61e3 | |||
03b1385f26 | |||
2302a37311 | |||
9877271d70 | |||
873e35f416 | |||
80aebf2932 | |||
f9d9d2b0e5 | |||
c8ee1da262 | |||
79cc6ca559 | |||
a299b5f904 | |||
fd9fdc30cb | |||
ecbfff9b0f | |||
0e679139d2 | |||
f30922f439 | |||
c775c3905d | |||
a4593d4668 | |||
df68853c76 | |||
88157d6e99 | |||
22533458ed | |||
38a958ed08 | |||
396a3ff225 | |||
bcb401c0c3 | |||
4b3addb8a0 | |||
7cfeeae413 | |||
31a7410acd | |||
6c8f189499 | |||
2e50fbbda4 | |||
fd4fc4ff94 | |||
496c004efc | |||
6f9becdbb3 | |||
36cdfd969d | |||
0be2bd911f | |||
0e36107878 | |||
279a438ae6 | |||
0d5eb149ab | |||
557618c87d | |||
e0dda934ec | |||
21f764590b | |||
bf49cafeae | |||
7f795bc041 | |||
e381313747 | |||
be0a31697a | |||
14c558163e | |||
57437d3a06 | |||
a0ce4b1d01 | |||
a0ac660d57 | |||
825656feed | |||
89a90c00fd | |||
83081456f2 | |||
20e419a9c4 | |||
dda57f7b0f | |||
85007a9dfe | |||
f073a5b837 | |||
9e8f015dc0 | |||
f14fecbb5f | |||
b27637c926 | |||
552c934486 | |||
f202c9902a | |||
3bd33a129f | |||
79bc42c995 | |||
032710a2de | |||
e8cc52f99e | |||
266b78aa31 | |||
8a89aee75d | |||
169c55443a | |||
77e914238c | |||
73b9b2491f | |||
89c61bb05e | |||
6983ddf509 | |||
8bc3ff5726 | |||
b4e502be13 | |||
778ec96d72 | |||
28926832df | |||
b3820bedbc | |||
6722540bdc | |||
2d5e98b6a3 | |||
bbb69429f3 | |||
e47198deaf | |||
36ddbc6cb4 | |||
a371890962 | |||
e1c0976927 | |||
40bf7fd22a | |||
214de28808 | |||
530b81674b | |||
e6224be46f | |||
ed5325c069 | |||
a5e78d775b | |||
c4673addf7 | |||
cb1c4da4ea | |||
6f36e9af24 | |||
6977833b1a | |||
30318569e1 | |||
429f7ffe8d | |||
4354d76cae | |||
f3e6c726b0 | |||
694ccf2bc5 | |||
392f0110bb | |||
b0775e3e0c | |||
ab2fb24fe5 | |||
cbaeec54ff | |||
20759dcf07 | |||
189accc0d6 | |||
4e075987ab | |||
303c947d2a | |||
b6ef52e89c | |||
109b6dbf44 | |||
fa50cbf4b3 | |||
392eb74901 | |||
5f163133ee | |||
9be231fbca | |||
b6caad289d | |||
3fbc411e17 | |||
fb46faa320 | |||
c180534f21 | |||
926e7ac0b1 | |||
409efcbb03 | |||
115b4cf4ac | |||
920e2a7c7e | |||
2566f2c4cb | |||
d8f9f9231f | |||
93b236811a | |||
e4c7564e3e | |||
41fe4a527a | |||
1c20fcc8c7 | |||
5355a95d1d | |||
e37b731e88 | |||
370a1a0041 | |||
310ebb9817 | |||
fdc2edc421 | |||
c434961dfc | |||
ddf3e149c9 | |||
3c4e35ff8d | |||
2674902eaa | |||
596f4ddb0e | |||
2b73da5412 | |||
9884fe6473 | |||
2877f026ec | |||
99a0117a33 | |||
cce9499a61 | |||
905d572d42 | |||
e4cdfdf6e9 | |||
ea9e0b917b | |||
a76f56d0a9 | |||
ee0ab63202 | |||
2f6f851715 | |||
97f3959e83 | |||
ff48b0be53 | |||
24d95fb7fd | |||
a17d847a82 | |||
857c79cc05 | |||
35551246d2 | |||
5117bbf7f4 | |||
0925898d8d | |||
325bcc367d | |||
97a687c03a | |||
c6632da159 | |||
96445c4613 | |||
a45f8782b1 | |||
61ce7f11d6 | |||
49370c21d1 | |||
441b47e744 | |||
8d40f843cf | |||
7bd6f2ed91 | |||
9df56295f6 | |||
dafa4f1b1c | |||
f66560ccd4 | |||
f795a3f565 | |||
130b2c4910 | |||
c778e0467e | |||
70e340086d | |||
b9ec63f016 | |||
9aed430fda | |||
d5f160ea3d | |||
3ac60f9860 | |||
6746987ce5 | |||
3fc1be1262 | |||
96b1831229 | |||
a669797ccb | |||
5e97da2e11 | |||
d92c5332da | |||
e1ccd7f9ea | |||
6fcd5322d0 | |||
160c633c08 | |||
ffa3e8a0aa | |||
274f972b58 | |||
03d7127e33 | |||
933a28537b | |||
4f2856dc09 | |||
ec055fd8d1 | |||
f2dc9cdff7 | |||
d8ea2e744f | |||
f9353a0ecd | |||
abff932d8f | |||
ef6ca9d2cd | |||
1fd7e0431b | |||
f9103772c3 | |||
5460ccf41c | |||
a2b3a4bb90 | |||
683ab8d2cd | |||
53749483c3 | |||
27e82ea60a | |||
48af130269 | |||
98e9b5594c | |||
9b950a98c7 | |||
34c2510f0f | |||
6cbd39de9b | |||
0be679c9d5 | |||
387677e957 | |||
c1546aac9c | |||
6328834681 | |||
99818a26f5 | |||
88f9347093 | |||
1fc475860d | |||
e45bcf06fe | |||
29caf1363f | |||
c15f05622e | |||
b9502b9c2c | |||
3e575ad505 | |||
f668a41f57 | |||
dcd4af9dd0 | |||
d01a82cf9f | |||
92169f4288 | |||
c455c84d15 | |||
15c5dacab3 | |||
1001a47cd6 | |||
46464eb504 | |||
1fd773486e | |||
50c0bf424a | |||
9644088b5d | |||
25b98a5480 | |||
3729c5b603 | |||
59392ac4e9 | |||
346d267e4e | |||
e9aba34e6b | |||
1dc3d42b78 | |||
f23a05d42e | |||
a1a1f1b8e4 | |||
aa1de79337 | |||
abccfeac37 | |||
9859333aae | |||
5ca4f50703 | |||
96e36dbcb3 | |||
8da3aced07 | |||
ab84be7f6a | |||
88fb84edc5 | |||
5e8ea04e52 | |||
3136c23795 | |||
366fa0e05d | |||
42b34d55e0 | |||
5070866fe0 | |||
db15ae49a1 | |||
71737c3e53 | |||
9fcbe2698a | |||
da5853083c | |||
1d40399b9c | |||
d6f4e77b6c | |||
cb32a95e60 | |||
731fbbc8d1 | |||
29ab53a46f | |||
4c973ce625 | |||
9d8e6d5f8c | |||
5abe5bd43d | |||
89138ae4ce | |||
8d14c98da9 | |||
669401afd4 | |||
8dbdffa517 | |||
efeaadf0ba | |||
999990756c | |||
c0de004472 | |||
62313d4a84 | |||
ac02185ad0 | |||
d83b5c3a60 | |||
e405c2bf1c | |||
039151c136 | |||
40b290739e | |||
93c82d5267 | |||
0000000bab | |||
4098252ec7 | |||
711519d4ff | |||
0b9896ff5e | |||
41c4c15549 | |||
1a8cbdd6c7 | |||
7be9ea68c7 | |||
e390374c74 | |||
6d58f32c91 | |||
0d91be62cf | |||
adcbc67a71 | |||
ddf59b8bee | |||
5c8747cb87 | |||
5065fce415 | |||
e63f8b93a7 | |||
848b4bc113 | |||
648b23d08f | |||
0f0b866788 | |||
c6f189f93f | |||
076bf2f2fe | |||
fb6cd22c83 | |||
327d183bed | |||
7a163f9ea5 | |||
0a7d9f1c87 | |||
08c9321a55 | |||
cbf1f7a2e8 | |||
85f7cdb123 | |||
d3a912b2ef | |||
5173781725 | |||
ab1fbae2f2 | |||
febc6af323 | |||
d972d38b41 | |||
80f9093875 | |||
ee6dc989ce | |||
5da68059ee | |||
5052e58bd0 | |||
2ad9e1fe29 | |||
908210969e | |||
0865381881 | |||
b50d58e46f | |||
4841e105d3 | |||
6c938944e6 | |||
04917ecd5a | |||
3d80362560 | |||
48f2927e08 | |||
27fcf0286e | |||
2ab1997f21 | |||
61192b172b | |||
f71f10da0b | |||
a2536ed308 | |||
83eb032393 | |||
36027f1073 | |||
95628227b0 | |||
0f42cd9243 | |||
11356b68ba | |||
379b70eca7 | |||
c81266d1da | |||
8c4afcd21a | |||
5cadc665d1 | |||
bec642310a | |||
df3e456162 | |||
7cd29f0fcf | |||
a4630372fa | |||
9a5ffbe56c | |||
ee23b42e23 | |||
502c27273d | |||
5865f17c75 | |||
7e9304a0c9 | |||
b4cc3bbd43 | |||
e60ea2eb15 | |||
a38d300616 | |||
e3ee317924 | |||
c688039047 | |||
dd17652aca | |||
03d46020ec | |||
19efa5e8d9 | |||
08c6265762 | |||
4098e5e3b8 | |||
829069b0c8 | |||
66cea2f8ea | |||
9cab86540b | |||
d9ce4f119f | |||
35511aa30e | |||
5ce7b57cac | |||
fc053d9d75 | |||
cb1b8c6c68 | |||
86f9d3e233 | |||
c266cb991c | |||
b28bc3ae9b | |||
e0705c80e2 | |||
5d2884716d | |||
45ee209c58 | |||
564a504ef7 | |||
ba21d7f661 | |||
d5ff5d0066 |
7
.gitignore
vendored
7
.gitignore
vendored
@ -2,11 +2,15 @@ players/*
|
||||
worlds/*
|
||||
plugins/*
|
||||
bin/*
|
||||
.idea/*
|
||||
*.log
|
||||
*.txt
|
||||
*.phar
|
||||
server.properties
|
||||
pocketmine.yml
|
||||
|
||||
# Common IDEs
|
||||
.idea/*
|
||||
nbproject/*
|
||||
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
@ -16,3 +20,4 @@ Desktop.ini
|
||||
|
||||
# Mac crap
|
||||
.DS_Store
|
||||
/nbproject/private/
|
8
.gitmodules
vendored
Normal file
8
.gitmodules
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
[submodule "src/pocketmine/gui"]
|
||||
path = src/pocketmine/gui
|
||||
url = https://github.com/PocketMine/PocketMine-MP-GUI.git
|
||||
branch = master
|
||||
[submodule "src/raklib"]
|
||||
path = src/raklib
|
||||
url = https://github.com/PocketMine/RakLib.git
|
||||
branch = master
|
@ -8,6 +8,8 @@ php:
|
||||
branches:
|
||||
except:
|
||||
- Core-Rewrite
|
||||
- master
|
||||
- 0.9.0
|
||||
|
||||
before_script:
|
||||
- pecl install channel://pecl.php.net/pthreads-2.0.4
|
||||
|
@ -5,7 +5,7 @@
|
||||
Before contributing to PocketMine-MP, please read this. Also, take a look if your contribution fits the PocketMine-MP goals below.
|
||||
|
||||
|
||||
## I've a question
|
||||
## I have a question
|
||||
* For questions, please refer to the _#pocketmine_ or _#mcpedevs_ IRC channel on Freenode. There is a [WebIRC](http://webchat.freenode.net?channels=pocketmine,mcpedevs&uio=d4) if you want.
|
||||
* You can ask directly to _[@PocketMine](https://twitter.com/PocketMine)_ in Twitter, but don't expect an inmediate reply.
|
||||
|
||||
@ -16,7 +16,7 @@ Before contributing to PocketMine-MP, please read this. Also, take a look if you
|
||||
* When reporting, give as much info as you can, and if the Issue is a crash, give the Crash Dump.
|
||||
* Issues should be written in English.
|
||||
|
||||
## I want to contribute code
|
||||
## I want a new feature / I want to contribute code
|
||||
* Use the [Pull Request](https://github.com/PocketMine/PocketMine-MP/pull/new) system, your request will be checked and discussed.
|
||||
* __Create a single branch for that pull request__
|
||||
* If you want to be part of PocketMine-MP, we will ask you to.
|
||||
@ -40,7 +40,6 @@ It is mainly [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accept
|
||||
* Files MUST NOT have an ending `?>` tag.
|
||||
* Code MUST use namespaces.
|
||||
* Strings SHOULD use the double quote `"` except when the single quote is required.
|
||||
* Arrays SHOULD be declared using `array()`, not the `[]` shortcut.
|
||||
* Argument lists MAY NOT be split across multiple lines, except long arrays.
|
||||
|
||||
```php
|
||||
@ -58,14 +57,14 @@ class ExampleClass{
|
||||
//do things
|
||||
}elseif($firstArgument === "otherValue"){
|
||||
$secondArgument = function(){
|
||||
return array(
|
||||
return [
|
||||
0 => "value1",
|
||||
1 => "value2",
|
||||
2 => "value3",
|
||||
3 => "value4",
|
||||
4 => "value5",
|
||||
5 => "value6",
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
20
README.md
20
README.md
@ -15,27 +15,30 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
__PocketMine-MP is a Minecraft: PE server software.__
|
||||
|
||||
The entire server is written in PHP, and has been tested, profiled and optimized to run smoothly.
|
||||
__PocketMine-MP is a free, open-source software that creates Minecraft: Pocket Edition servers and allows extending its functionalities__
|
||||
|
||||
### [Homepage](http://www.pocketmine.net/)
|
||||
|
||||
### [Forums](http://forums.pocketmine.net/)
|
||||
|
||||
### [Wiki](https://github.com/PocketMine/PocketMine-MP/wiki/)
|
||||
### [Plugin Repository](http://plugins.pocketmine.net/)
|
||||
|
||||
### [FAQ: Frequently Asked Questions](https://github.com/PocketMine/PocketMine-MP/wiki/Frequently-Asked-Questions)
|
||||
<!--## [FAQ: Frequently Asked Questions](https://github.com/PocketMine/PocketMine-MP/wiki/Frequently-Asked-Questions)-->
|
||||
|
||||
### [Official Jenkins server](http://jenkins.pocketmine.net/)
|
||||
|
||||
### API Documentation
|
||||
* [Doxygen generated](http://docs.pocketmine.net/)
|
||||
* [PHPDoc generated](http://docs.pocketmine.net/phpdoc/)
|
||||
* [Official Doxygen-generated documentation](http://docs.pocketmine.net/)
|
||||
* [Latest Doxygen generated from development](http://jenkins.pocketmine.net/job/PocketMine-MP-doc/doxygen/)
|
||||
|
||||
### [Twitter @PocketMine](https://twitter.com/PocketMine)
|
||||
|
||||
## IRC Chat #pocketmine (or #mcpedevs) @ irc.freenode.net
|
||||
### IRC Chat #pocketmine (or #mcpedevs) @ irc.freenode.net
|
||||
[#pocketmine + #mcpedevs channel WebIRC](http://webchat.freenode.net/?channels=pocketmine,mcpedevs)
|
||||
|
||||
### Want to contribute?
|
||||
* Check the [Contributing Guidelines](CONTRIBUTING.md)
|
||||
|
||||
|
||||
## Third-party Libraries/Protocols Used
|
||||
* __[PHP Sockets](http://php.net/manual/en/book.sockets.php)__
|
||||
@ -44,7 +47,6 @@ The entire server is written in PHP, and has been tested, profiled and optimized
|
||||
* __[PHP pthreads](http://pthreads.org/)__ by _[krakjoe](https://github.com/krakjoe)_: Threading for PHP - Share Nothing, Do Everything.
|
||||
* __[PHP YAML](https://code.google.com/p/php-yaml/)__ by _Bryan Davis_: The Yaml PHP Extension provides a wrapper to the LibYAML library.
|
||||
* __[LibYAML](http://pyyaml.org/wiki/LibYAML)__ by _Kirill Simonov_: A YAML 1.1 parser and emitter written in C.
|
||||
* __[mintty](https://code.google.com/p/mintty/)__ : xterm Terminal Emulator
|
||||
* __[cURL](http://curl.haxx.se/)__: cURL is a command line tool for transferring data with URL syntax
|
||||
* __[Zlib](http://www.zlib.net/)__: A Massively Spiffy Yet Delicately Unobtrusive Compression Library
|
||||
* __[Source RCON Protocol](https://developer.valvesoftware.com/wiki/Source_RCON_Protocol)__
|
||||
|
1063
src/EntityOLD.php
1063
src/EntityOLD.php
File diff suppressed because it is too large
Load Diff
@ -1,411 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector2;
|
||||
use pocketmine\utils\Config;
|
||||
|
||||
class BanAPI{
|
||||
private $server;
|
||||
/*
|
||||
* I would use PHPDoc Template here but PHPStorm does not recognise it. - @sekjun9878
|
||||
*/
|
||||
/** @var Config */
|
||||
private $whitelist;
|
||||
/** @var Config */
|
||||
private $banned;
|
||||
/** @var Config */
|
||||
private $ops;
|
||||
/** @var Config */
|
||||
private $bannedIPs;
|
||||
private $cmdWhitelist = array(); //Command WhiteList
|
||||
function __construct(){
|
||||
$this->server = Server::getInstance();
|
||||
}
|
||||
|
||||
public function init(){
|
||||
$this->whitelist = new Config(\pocketmine\DATA . "white-list.txt", Config::ENUM); //Open whitelist list file
|
||||
$this->bannedIPs = new Config(\pocketmine\DATA . "banned-ips.txt", Config::ENUM); //Open Banned IPs list file
|
||||
$this->banned = new Config(\pocketmine\DATA . "banned.txt", Config::ENUM); //Open Banned Usernames list file
|
||||
$this->ops = new Config(\pocketmine\DATA . "ops.txt", Config::ENUM); //Open list of OPs
|
||||
$this->server->api->console->register("banip", "<add|remove|list|reload> [IP|player]", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("ban", "<add|remove|list|reload> [username]", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("kick", "<player> [reason ...]", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("whitelist", "<on|off|list|add|remove|reload> [username]", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("op", "<player>", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("deop", "<player>", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("sudo", "<player> <command>", array($this, "commandHandler"));
|
||||
$this->server->api->console->alias("ban-ip", "banip add");
|
||||
$this->server->api->console->alias("banlist", "ban list");
|
||||
$this->server->api->console->alias("pardon", "ban remove");
|
||||
$this->server->api->console->alias("pardon-ip", "banip remove");
|
||||
$this->server->addHandler("console.command", array($this, "permissionsCheck"), 1); //Event handler when commands are issued. Used to check permissions of commands that go through the server.
|
||||
$this->server->addHandler("player.block.break", array($this, "permissionsCheck"), 1); //Event handler for blocks
|
||||
$this->server->addHandler("player.block.place", array($this, "permissionsCheck"), 1); //Event handler for blocks
|
||||
$this->server->addHandler("player.flying", array($this, "permissionsCheck"), 1); //Flying Event
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $cmd Command to Whitelist
|
||||
*/
|
||||
public function cmdWhitelist($cmd){ //Whitelists a CMD so everyone can issue it - Even non OPs.
|
||||
$this->cmdWhitelist[strtolower(trim($cmd))] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $username
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isOp($username){ //Is a player op?
|
||||
$username = strtolower($username);
|
||||
if($this->server->api->dhandle("op.check", $username) === true){
|
||||
return true;
|
||||
}elseif($this->ops->exists($username)){
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $data
|
||||
* @param string $event
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function permissionsCheck($data, $event){
|
||||
switch($event){
|
||||
case "player.flying": //OPs can fly around the server.
|
||||
if($this->isOp($data->getName())){
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case "player.block.break":
|
||||
case "player.block.place": //Spawn protection detection. Allows OPs to place/break blocks in the spawn area.
|
||||
if(!$this->isOp($data["player"]->getName())){
|
||||
$t = new Vector2($data["target"]->x, $data["target"]->z);
|
||||
$s = new Vector2(Level::getDefault()->getSpawn()->x, Level::getDefault()->getSpawn()->z);
|
||||
if($t->distance($s) <= $this->server->api->getProperty("spawn-protection") and $this->server->api->dhandle($event . ".spawn", $data) !== true){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
case "console.command": //Checks if a command is allowed with the current user permissions.
|
||||
if(isset($this->cmdWhitelist[$data["cmd"]])){
|
||||
return;
|
||||
}
|
||||
|
||||
if($data["issuer"] instanceof Player){
|
||||
if($this->server->api->handle("console.check", $data) === true or $this->isOp($data["issuer"]->getName())){
|
||||
return;
|
||||
}
|
||||
}elseif($data["issuer"] === "console" or $data["issuer"] === "rcon"){
|
||||
return;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $cmd
|
||||
* @param array $params
|
||||
* @param string $issuer
|
||||
* @param string $alias
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function commandHandler($cmd, $params, $issuer, $alias){
|
||||
$output = "";
|
||||
switch($cmd){
|
||||
case "sudo":
|
||||
$target = strtolower(array_shift($params));
|
||||
$player = Player::get($target);
|
||||
if(!($player instanceof Player)){
|
||||
$output .= "Player not connected.\n";
|
||||
break;
|
||||
}
|
||||
$this->server->api->console->run(implode(" ", $params), $player);
|
||||
$output .= "Command ran as " . $player->getName() . ".\n";
|
||||
break;
|
||||
case "op":
|
||||
$user = strtolower($params[0]);
|
||||
if($user == null){
|
||||
$output .= "Usage: /op <player>\n";
|
||||
break;
|
||||
}
|
||||
$player = Player::get($user);
|
||||
if(!($player instanceof Player)){
|
||||
$this->ops->set($user);
|
||||
$this->ops->save();
|
||||
$output .= $user . " is now op\n";
|
||||
break;
|
||||
}
|
||||
$this->ops->set(strtolower($player->getName()));
|
||||
$this->ops->save();
|
||||
$output .= $player->getName() . " is now op\n";
|
||||
$player->sendMessage("You are now op.");
|
||||
break;
|
||||
case "deop":
|
||||
$user = strtolower($params[0]);
|
||||
$player = Player::get($user);
|
||||
if(!($player instanceof Player)){
|
||||
$this->ops->remove($user);
|
||||
$this->ops->save();
|
||||
$output .= $user . " is no longer op\n";
|
||||
break;
|
||||
}
|
||||
$this->ops->remove(strtolower($player->getName()));
|
||||
$this->ops->save();
|
||||
$output .= $player->getName() . " is no longer op\n";
|
||||
$player->sendMessage("You are no longer op.");
|
||||
break;
|
||||
case "kick":
|
||||
if(!isset($params[0])){
|
||||
$output .= "Usage: /kick <player> [reason ...]\n";
|
||||
}else{
|
||||
$name = strtolower(array_shift($params));
|
||||
$player = Player::get($name);
|
||||
if($player === false){
|
||||
$output .= "Player \"" . $name . "\" does not exist\n";
|
||||
}else{
|
||||
$reason = implode(" ", $params);
|
||||
$reason = $reason == "" ? "No reason" : $reason;
|
||||
|
||||
$this->server->schedule(60, array($player, "close"), "You have been kicked: " . $reason); //Forces a kick
|
||||
$player->blocked = true;
|
||||
if($issuer instanceof Player){
|
||||
Player::broadcastMessage($player->getName() . " has been kicked by " . $issuer->getName() . ": $reason\n");
|
||||
}else{
|
||||
Player::broadcastMessage($player->getName() . " has been kicked: $reason\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "whitelist":
|
||||
$p = strtolower(array_shift($params));
|
||||
switch($p){
|
||||
case "remove":
|
||||
$user = strtolower($params[0]);
|
||||
$this->whitelist->remove($user);
|
||||
$this->whitelist->save();
|
||||
$output .= "Player \"$user\" removed from white-list\n";
|
||||
break;
|
||||
case "add":
|
||||
$user = strtolower($params[0]);
|
||||
$this->whitelist->set($user);
|
||||
$this->whitelist->save();
|
||||
$output .= "Player \"$user\" added to white-list\n";
|
||||
break;
|
||||
case "reload":
|
||||
$this->whitelist = new Config(\pocketmine\DATA . "white-list.txt", Config::ENUM);
|
||||
break;
|
||||
case "list":
|
||||
$output .= "White-list: " . implode(", ", $this->whitelist->getAll(true)) . "\n";
|
||||
break;
|
||||
case "on":
|
||||
case "true":
|
||||
case "1":
|
||||
$output .= "White-list turned on\n";
|
||||
$this->server->api->setProperty("white-list", true);
|
||||
break;
|
||||
case "off":
|
||||
case "false":
|
||||
case "0":
|
||||
$output .= "White-list turned off\n";
|
||||
$this->server->api->setProperty("white-list", false);
|
||||
break;
|
||||
default:
|
||||
$output .= "Usage: /whitelist <on|off|list|add|remove|reload> [username]\n";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "banip":
|
||||
$p = strtolower(array_shift($params));
|
||||
switch($p){
|
||||
case "pardon":
|
||||
case "remove":
|
||||
$ip = strtolower($params[0]);
|
||||
$this->bannedIPs->remove($ip);
|
||||
$this->bannedIPs->save();
|
||||
$output .= "IP \"$ip\" removed from ban list\n";
|
||||
break;
|
||||
case "add":
|
||||
case "ban":
|
||||
$ip = strtolower($params[0]);
|
||||
$player = Player::get($ip);
|
||||
if($player instanceof Player){
|
||||
$ip = $player->getIP();
|
||||
$player->kick("You are banned");
|
||||
}
|
||||
$this->bannedIPs->set($ip);
|
||||
$this->bannedIPs->save();
|
||||
$output .= "IP \"$ip\" added to ban list\n";
|
||||
break;
|
||||
case "reload":
|
||||
$this->bannedIPs = new Config(\pocketmine\DATA . "banned-ips.txt", Config::ENUM);
|
||||
break;
|
||||
case "list":
|
||||
$output .= "IP ban list: " . implode(", ", $this->bannedIPs->getAll(true)) . "\n";
|
||||
break;
|
||||
default:
|
||||
$output .= "Usage: /banip <add|remove|list|reload> [IP|player]\n";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "ban":
|
||||
$p = strtolower(array_shift($params));
|
||||
switch($p){
|
||||
case "pardon":
|
||||
case "remove":
|
||||
$user = strtolower($params[0]);
|
||||
$this->banned->remove($user);
|
||||
$this->banned->save();
|
||||
$output .= "Player \"$user\" removed from ban list\n";
|
||||
break;
|
||||
case "add":
|
||||
case "ban":
|
||||
$user = strtolower($params[0]);
|
||||
$this->banned->set($user);
|
||||
$this->banned->save();
|
||||
$player = Player::get($user);
|
||||
if($player !== false){
|
||||
$player->kick("You are banned");
|
||||
}
|
||||
if($issuer instanceof Player){
|
||||
Player::broadcastMessage($user . " has been banned by " . $issuer->getName() . "\n");
|
||||
}else{
|
||||
Player::broadcastMessage($user . " has been banned\n");
|
||||
}
|
||||
$this->kick($user, "Banned");
|
||||
$output .= "Player \"$user\" added to ban list\n";
|
||||
break;
|
||||
case "reload":
|
||||
$this->banned = new Config(\pocketmine\DATA . "banned.txt", Config::ENUM);
|
||||
break;
|
||||
case "list":
|
||||
$output .= "Ban list: " . implode(", ", $this->banned->getAll(true)) . "\n";
|
||||
break;
|
||||
default:
|
||||
$output .= "Usage: /ban <add|remove|list|reload> [username]\n";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $username
|
||||
*/
|
||||
public function ban($username){
|
||||
$this->commandHandler("ban", array("add", $username), "console", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $username
|
||||
*/
|
||||
public function pardon($username){
|
||||
$this->commandHandler("ban", array("pardon", $username), "console", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $ip
|
||||
*/
|
||||
public function banIP($ip){
|
||||
$this->commandHandler("banip", array("add", $ip), "console", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $ip
|
||||
*/
|
||||
public function pardonIP($ip){
|
||||
$this->commandHandler("banip", array("pardon", $ip), "console", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $username
|
||||
* @param string $reason
|
||||
*/
|
||||
public function kick($username, $reason = "No Reason"){
|
||||
$this->commandHandler("kick", array($username, $reason), "console", "");
|
||||
}
|
||||
|
||||
public function reload(){
|
||||
$this->commandHandler("ban", array("reload"), "console", "");
|
||||
$this->commandHandler("banip", array("reload"), "console", "");
|
||||
$this->commandHandler("whitelist", array("reload"), "console", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $ip
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isIPBanned($ip){
|
||||
if($this->server->api->dhandle("api.ban.ip.check", $ip) === false){
|
||||
return true;
|
||||
}elseif($this->bannedIPs->exists($ip, true)){
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $username
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isBanned($username){
|
||||
$username = strtolower($username);
|
||||
if($this->server->api->dhandle("api.ban.check", $username) === false){
|
||||
return true;
|
||||
}elseif($this->banned->exists($username, true)){
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $username
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function inWhitelist($username){
|
||||
$username = strtolower($username);
|
||||
if($this->isOp($username)){
|
||||
return true;
|
||||
}elseif($this->server->api->dhandle("api.ban.whitelist.check", $username) === false){
|
||||
return true;
|
||||
}elseif($this->whitelist->exists($username, true)){
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,352 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
use pocketmine\Block;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\level\Position;
|
||||
|
||||
class BlockAPI{
|
||||
private $server;
|
||||
private $scheduledUpdates = array();
|
||||
public static $creative = array(
|
||||
//Building
|
||||
[Item::STONE, 0],
|
||||
[Item::COBBLESTONE, 0],
|
||||
[Item::STONE_BRICKS, 0],
|
||||
[Item::STONE_BRICKS, 1],
|
||||
[Item::STONE_BRICKS, 2],
|
||||
[Item::MOSS_STONE, 0],
|
||||
[Item::WOODEN_PLANKS, 0],
|
||||
[Item::WOODEN_PLANKS, 1],
|
||||
[Item::WOODEN_PLANKS, 2],
|
||||
[Item::WOODEN_PLANKS, 3],
|
||||
[Item::BRICKS, 0],
|
||||
|
||||
[Item::DIRT, 0],
|
||||
[Item::GRASS, 0],
|
||||
[Item::CLAY_BLOCK, 0],
|
||||
[Item::SANDSTONE, 0],
|
||||
[Item::SANDSTONE, 1],
|
||||
[Item::SANDSTONE, 2],
|
||||
[Item::SAND, 0],
|
||||
[Item::GRAVEL, 0],
|
||||
[Item::TRUNK, 0],
|
||||
[Item::TRUNK, 1],
|
||||
[Item::TRUNK, 2],
|
||||
[Item::TRUNK, 3],
|
||||
[Item::NETHER_BRICKS, 0],
|
||||
[Item::NETHERRACK, 0],
|
||||
[Item::BEDROCK, 0],
|
||||
[Item::COBBLESTONE_STAIRS, 0],
|
||||
[Item::OAK_WOODEN_STAIRS, 0],
|
||||
[Item::SPRUCE_WOODEN_STAIRS, 0],
|
||||
[Item::BIRCH_WOODEN_STAIRS, 0],
|
||||
[Item::JUNGLE_WOODEN_STAIRS, 0],
|
||||
[Item::BRICK_STAIRS, 0],
|
||||
[Item::SANDSTONE_STAIRS, 0],
|
||||
[Item::STONE_BRICK_STAIRS, 0],
|
||||
[Item::NETHER_BRICKS_STAIRS, 0],
|
||||
[Item::QUARTZ_STAIRS, 0],
|
||||
[Item::SLAB, 0],
|
||||
[Item::SLAB, 1],
|
||||
[Item::WOODEN_SLAB, 0],
|
||||
[Item::WOODEN_SLAB, 1],
|
||||
[Item::WOODEN_SLAB, 2],
|
||||
[Item::WOODEN_SLAB, 3],
|
||||
[Item::SLAB, 3],
|
||||
[Item::SLAB, 4],
|
||||
[Item::SLAB, 5],
|
||||
[Item::SLAB, 6],
|
||||
[Item::QUARTZ_BLOCK, 0],
|
||||
[Item::QUARTZ_BLOCK, 1],
|
||||
[Item::QUARTZ_BLOCK, 2],
|
||||
[Item::COAL_ORE, 0],
|
||||
[Item::IRON_ORE, 0],
|
||||
[Item::GOLD_ORE, 0],
|
||||
[Item::DIAMOND_ORE, 0],
|
||||
[Item::LAPIS_ORE, 0],
|
||||
[Item::REDSTONE_ORE, 0],
|
||||
[Item::OBSIDIAN, 0],
|
||||
[Item::ICE, 0],
|
||||
[Item::SNOW_BLOCK, 0],
|
||||
|
||||
//Decoration
|
||||
[Item::COBBLESTONE_WALL, 0],
|
||||
[Item::COBBLESTONE_WALL, 1],
|
||||
[Item::GOLD_BLOCK, 0],
|
||||
[Item::IRON_BLOCK, 0],
|
||||
[Item::DIAMOND_BLOCK, 0],
|
||||
[Item::LAPIS_BLOCK, 0],
|
||||
[Item::COAL_BLOCK, 0],
|
||||
[Item::SNOW_LAYER, 0],
|
||||
[Item::GLASS, 0],
|
||||
[Item::GLOWSTONE_BLOCK, 0],
|
||||
[Item::NETHER_REACTOR, 0],
|
||||
[Item::WOOL, 0],
|
||||
[Item::WOOL, 7],
|
||||
[Item::WOOL, 6],
|
||||
[Item::WOOL, 5],
|
||||
[Item::WOOL, 4],
|
||||
[Item::WOOL, 3],
|
||||
[Item::WOOL, 2],
|
||||
[Item::WOOL, 1],
|
||||
[Item::WOOL, 15],
|
||||
[Item::WOOL, 14],
|
||||
[Item::WOOL, 13],
|
||||
[Item::WOOL, 12],
|
||||
[Item::WOOL, 11],
|
||||
[Item::WOOL, 10],
|
||||
[Item::WOOL, 9],
|
||||
[Item::WOOL, 8],
|
||||
[Item::LADDER, 0],
|
||||
[Item::SPONGE, 0],
|
||||
[Item::GLASS_PANE, 0],
|
||||
[Item::WOODEN_DOOR, 0],
|
||||
[Item::TRAPDOOR, 0],
|
||||
[Item::FENCE, 0],
|
||||
[Item::FENCE_GATE, 0],
|
||||
[Item::IRON_BARS, 0],
|
||||
[Item::BED, 0],
|
||||
[Item::BOOKSHELF, 0],
|
||||
[Item::PAINTING, 0],
|
||||
[Item::WORKBENCH, 0],
|
||||
[Item::STONECUTTER, 0],
|
||||
[Item::CHEST, 0],
|
||||
[Item::FURNACE, 0],
|
||||
[Item::DANDELION, 0],
|
||||
[Item::CYAN_FLOWER, 0],
|
||||
[Item::BROWN_MUSHROOM, 0],
|
||||
[Item::RED_MUSHROOM, 0],
|
||||
[Item::CACTUS, 0],
|
||||
[Item::MELON_BLOCK, 0],
|
||||
[Item::PUMPKIN, 0],
|
||||
[Item::LIT_PUMPKIN, 0],
|
||||
[Item::COBWEB, 0],
|
||||
[Item::HAY_BALE, 0],
|
||||
[Item::TALL_GRASS, 1],
|
||||
[Item::TALL_GRASS, 2],
|
||||
[Item::DEAD_BUSH, 0],
|
||||
[Item::SAPLING, 0],
|
||||
[Item::SAPLING, 1],
|
||||
[Item::SAPLING, 2],
|
||||
[Item::SAPLING, 3],
|
||||
[Item::LEAVES, 0],
|
||||
[Item::LEAVES, 1],
|
||||
[Item::LEAVES, 2],
|
||||
[Item::LEAVES, 3],
|
||||
[Item::CAKE, 0],
|
||||
[Item::SIGN, 0],
|
||||
[Item::CARPET, 0],
|
||||
[Item::CARPET, 7],
|
||||
[Item::CARPET, 6],
|
||||
[Item::CARPET, 5],
|
||||
[Item::CARPET, 4],
|
||||
[Item::CARPET, 3],
|
||||
[Item::CARPET, 2],
|
||||
[Item::CARPET, 1],
|
||||
[Item::CARPET, 15],
|
||||
[Item::CARPET, 14],
|
||||
[Item::CARPET, 13],
|
||||
[Item::CARPET, 12],
|
||||
[Item::CARPET, 11],
|
||||
[Item::CARPET, 10],
|
||||
[Item::CARPET, 9],
|
||||
[Item::CARPET, 8],
|
||||
|
||||
//Tools
|
||||
//[Item::RAILS, 0],
|
||||
//[Item::POWERED_RAILS, 0],
|
||||
[Item::TORCH, 0],
|
||||
[Item::BUCKET, 0],
|
||||
[Item::BUCKET, 8],
|
||||
[Item::BUCKET, 10],
|
||||
[Item::TNT, 0],
|
||||
[Item::IRON_HOE, 0],
|
||||
[Item::IRON_SWORD, 0],
|
||||
[Item::BOW, 0],
|
||||
[Item::SHEARS, 0],
|
||||
[Item::FLINT_AND_STEEL, 0],
|
||||
[Item::CLOCK, 0],
|
||||
[Item::COMPASS, 0],
|
||||
[Item::MINECART, 0],
|
||||
[Item::SPAWN_EGG, 10], //Chicken
|
||||
[Item::SPAWN_EGG, 11], //Cow
|
||||
[Item::SPAWN_EGG, 12], //Pig
|
||||
[Item::SPAWN_EGG, 13], //Sheep
|
||||
//TODO: Replace with Entity constants
|
||||
|
||||
|
||||
//Seeds
|
||||
[Item::SUGARCANE, 0],
|
||||
[Item::WHEAT, 0],
|
||||
[Item::SEEDS, 0],
|
||||
[Item::MELON_SEEDS, 0],
|
||||
[Item::PUMPKIN_SEEDS, 0],
|
||||
[Item::CARROT, 0],
|
||||
[Item::POTATO, 0],
|
||||
[Item::BEETROOT_SEEDS, 0],
|
||||
[Item::EGG, 0],
|
||||
[Item::DYE, 0],
|
||||
[Item::DYE, 7],
|
||||
[Item::DYE, 6],
|
||||
[Item::DYE, 5],
|
||||
[Item::DYE, 4],
|
||||
[Item::DYE, 3],
|
||||
[Item::DYE, 2],
|
||||
[Item::DYE, 1],
|
||||
[Item::DYE, 15],
|
||||
[Item::DYE, 14],
|
||||
[Item::DYE, 13],
|
||||
[Item::DYE, 12],
|
||||
[Item::DYE, 11],
|
||||
[Item::DYE, 10],
|
||||
[Item::DYE, 9],
|
||||
[Item::DYE, 8],
|
||||
|
||||
);
|
||||
|
||||
function __construct(){
|
||||
$this->server = Server::getInstance();
|
||||
}
|
||||
|
||||
public function init(){
|
||||
$this->server->schedule(1, array($this, "blockUpdateTick"), array(), true);
|
||||
$this->server->api->console->register("give", "<player> <item[:damage]> [amount]", array($this, "commandHandler"));
|
||||
}
|
||||
|
||||
public function commandHandler($cmd, $params, $issuer, $alias){
|
||||
$output = "";
|
||||
switch($cmd){
|
||||
case "give":
|
||||
if(!isset($params[0]) or !isset($params[1])){
|
||||
$output .= "Usage: /give <player> <item[:damage]> [amount]\n";
|
||||
break;
|
||||
}
|
||||
$player = Player::get($params[0]);
|
||||
$item = Item::fromString($params[1]);
|
||||
|
||||
if(!isset($params[2])){
|
||||
$item->setCount($item->getMaxStackSize());
|
||||
}else{
|
||||
$item->setCount((int) $params[2]);
|
||||
}
|
||||
|
||||
if($player instanceof Player){
|
||||
if(($player->gamemode & 0x01) === 0x01){
|
||||
$output .= "Player is in creative mode.\n";
|
||||
break;
|
||||
}
|
||||
if($item->getID() == 0){
|
||||
$output .= "You cannot give an air block to a player.\n";
|
||||
break;
|
||||
}
|
||||
$player->addItem(clone $item);
|
||||
$output .= "Giving " . $item->getCount() . " of " . $item->getName() . " (" . $item->getID() . ":" . $item->getMetadata() . ") to " . $player->getName() . "\n";
|
||||
}else{
|
||||
$output .= "Unknown player.\n";
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function blockUpdateAround(Position $pos, $type = Level::BLOCK_UPDATE_NORMAL, $delay = false){
|
||||
if($delay !== false){
|
||||
$this->scheduleBlockUpdate($pos->getSide(0), $delay, $type);
|
||||
$this->scheduleBlockUpdate($pos->getSide(1), $delay, $type);
|
||||
$this->scheduleBlockUpdate($pos->getSide(2), $delay, $type);
|
||||
$this->scheduleBlockUpdate($pos->getSide(3), $delay, $type);
|
||||
$this->scheduleBlockUpdate($pos->getSide(4), $delay, $type);
|
||||
$this->scheduleBlockUpdate($pos->getSide(5), $delay, $type);
|
||||
}else{
|
||||
$this->blockUpdate($pos->getSide(0), $type);
|
||||
$this->blockUpdate($pos->getSide(1), $type);
|
||||
$this->blockUpdate($pos->getSide(2), $type);
|
||||
$this->blockUpdate($pos->getSide(3), $type);
|
||||
$this->blockUpdate($pos->getSide(4), $type);
|
||||
$this->blockUpdate($pos->getSide(5), $type);
|
||||
}
|
||||
}
|
||||
|
||||
public function blockUpdate(Position $pos, $type = Level::BLOCK_UPDATE_NORMAL){
|
||||
if(!($pos instanceof block\Block)){
|
||||
$block = $pos->level->getBlock($pos);
|
||||
}else{
|
||||
$pos = new Position($pos->x, $pos->y, $pos->z, $pos->level);
|
||||
$block = $pos->level->getBlock($pos);
|
||||
}
|
||||
if($block === false){
|
||||
return false;
|
||||
}
|
||||
|
||||
$level = $block->onUpdate($type);
|
||||
if($level === Level::BLOCK_UPDATE_NORMAL){
|
||||
$this->blockUpdateAround($block, $level);
|
||||
}
|
||||
|
||||
return $level;
|
||||
}
|
||||
|
||||
public function scheduleBlockUpdate(Position $pos, $delay, $type = Level::BLOCK_UPDATE_SCHEDULED){
|
||||
$type = (int) $type;
|
||||
if($delay < 0){
|
||||
return false;
|
||||
}
|
||||
|
||||
$index = $pos->x . "." . $pos->y . "." . $pos->z . "." . $pos->level->getName() . "." . $type;
|
||||
$delay = microtime(true) + $delay * 0.05;
|
||||
if(!isset($this->scheduledUpdates[$index])){
|
||||
$this->scheduledUpdates[$index] = $pos;
|
||||
$this->server->query("INSERT INTO blockUpdates (x, y, z, level, type, delay) VALUES (" . $pos->x . ", " . $pos->y . ", " . $pos->z . ", '" . $pos->level->getName() . "', " . $type . ", " . $delay . ");");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function blockUpdateTick(){
|
||||
$time = microtime(true);
|
||||
if(count($this->scheduledUpdates) > 0){
|
||||
$update = $this->server->query("SELECT x,y,z,level,type FROM blockUpdates WHERE delay <= " . $time . ";");
|
||||
if($update instanceof \SQLite3Result){
|
||||
$upp = array();
|
||||
while(($up = $update->fetchArray(SQLITE3_ASSOC)) !== false){
|
||||
$index = $up["x"] . "." . $up["y"] . "." . $up["z"] . "." . $up["level"] . "." . $up["type"];
|
||||
if(isset($this->scheduledUpdates[$index])){
|
||||
$upp[] = array((int) $up["type"], $this->scheduledUpdates[$index]);
|
||||
unset($this->scheduledUpdates[$index]);
|
||||
}
|
||||
}
|
||||
$this->server->query("DELETE FROM blockUpdates WHERE delay <= " . $time . ";");
|
||||
foreach($upp as $b){
|
||||
$this->blockUpdate($b[1], $b[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
use pocketmine\level\Level;
|
||||
|
||||
class LevelAPI{
|
||||
private $server;
|
||||
|
||||
public function __construct(){
|
||||
$this->server = Server::getInstance();
|
||||
}
|
||||
|
||||
public function init(){
|
||||
$this->server->api->console->register("save-all", "", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("save-on", "", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("save-off", "", array($this, "commandHandler"));
|
||||
}
|
||||
|
||||
public function commandHandler($cmd, $params, $issuer, $alias){
|
||||
$output = "";
|
||||
switch($cmd){
|
||||
case "save-all":
|
||||
$save = $this->server->saveEnabled;
|
||||
$this->server->saveEnabled = true;
|
||||
Level::saveAll();
|
||||
$this->server->saveEnabled = $save;
|
||||
break;
|
||||
case "save-on":
|
||||
$this->server->saveEnabled = true;
|
||||
break;
|
||||
case "save-off":
|
||||
$this->server->saveEnabled = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function __destruct(){
|
||||
Level::saveAll();
|
||||
foreach(Level::getAll() as $level){
|
||||
$level->unload(true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,345 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\level\Position;
|
||||
use pocketmine\math\Vector3 as Vector3;
|
||||
|
||||
class PlayerAPI{
|
||||
private $server;
|
||||
|
||||
function __construct(){
|
||||
$this->server = Server::getInstance();
|
||||
}
|
||||
|
||||
public function init(){
|
||||
$this->server->schedule(20 * 15, array($this, "handle"), 1, true, "server.regeneration");
|
||||
$this->server->addHandler("player.death", array($this, "handle"), 1);
|
||||
$this->server->api->console->register("list", "", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("kill", "<player>", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("gamemode", "<mode> [player]", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("tp", "[target player] <destination player | w:world> OR /tp [target player] <x> <y> <z>", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("spawnpoint", "[player | w:world] [x] [y] [z]", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("spawn", "", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("ping", "", array($this, "commandHandler"));
|
||||
$this->server->api->console->alias("lag", "ping");
|
||||
$this->server->api->console->alias("suicide", "kill");
|
||||
$this->server->api->console->alias("tppos", "tp");
|
||||
$this->server->api->ban->cmdWhitelist("list");
|
||||
$this->server->api->ban->cmdWhitelist("ping");
|
||||
$this->server->api->ban->cmdWhitelist("spawn");
|
||||
}
|
||||
|
||||
public function handle($data, $event){
|
||||
switch($event){
|
||||
case "server.regeneration":
|
||||
/*if($this->server->difficulty === 0){
|
||||
$result = $this->server->preparedSQL->selectPlayersToHeal->execute();
|
||||
if($result !== false){
|
||||
while(($player = $result->fetchArray()) !== false){
|
||||
if(($player = Entity::get($player["EID"])) !== false){
|
||||
if($player->getHealth() <= 0){
|
||||
continue;
|
||||
}
|
||||
$player->setHealth(min(20, $player->getHealth() + $data), "regeneration");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}*/
|
||||
break;
|
||||
case "player.death":
|
||||
if(is_numeric($data["cause"])){
|
||||
$e = Entity::get($data["cause"]);
|
||||
if($e instanceof Entity){
|
||||
switch($e->class){
|
||||
case ENTITY_PLAYER:
|
||||
$message = " was killed by " . $e->name;
|
||||
break;
|
||||
default:
|
||||
$message = " was killed";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
switch($data["cause"]){
|
||||
case "cactus":
|
||||
$message = " was pricked to death";
|
||||
break;
|
||||
case "lava":
|
||||
$message = " tried to swim in lava";
|
||||
break;
|
||||
case "fire":
|
||||
$message = " went up in flames";
|
||||
break;
|
||||
case "burning":
|
||||
$message = " burned to death";
|
||||
break;
|
||||
case "suffocation":
|
||||
$message = " suffocated in a wall";
|
||||
break;
|
||||
case "water":
|
||||
$message = " drowned";
|
||||
break;
|
||||
case "void":
|
||||
$message = " fell out of the world";
|
||||
break;
|
||||
case "fall":
|
||||
$message = " hit the ground too hard";
|
||||
break;
|
||||
case "explosion":
|
||||
$message = " blew up";
|
||||
break;
|
||||
default:
|
||||
$message = " died";
|
||||
break;
|
||||
}
|
||||
}
|
||||
Player::broadcastMessage($data["player"]->getName() . $message);
|
||||
|
||||
return true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
public function commandHandler($cmd, $params, $issuer, $alias){
|
||||
$output = "";
|
||||
switch($cmd){
|
||||
case "spawnpoint":
|
||||
if(count($params) === 0){
|
||||
$output .= "Usage: /$cmd [player | w:world] [x] [y] [z]\n";
|
||||
break;
|
||||
}
|
||||
if(!($issuer instanceof Player) and count($params) < 4){
|
||||
$output .= "Please run this command in-game.\n";
|
||||
break;
|
||||
}
|
||||
|
||||
if(count($params) === 1 or count($params) === 4){
|
||||
$tg = array_shift($params);
|
||||
if(count($params) === 3 and substr($tg, 0, 2) === "w:"){
|
||||
$target = Level::get(substr($tg, 2));
|
||||
}else{
|
||||
$target = Player::get($tg);
|
||||
}
|
||||
}else{
|
||||
$target = $issuer;
|
||||
}
|
||||
|
||||
if(!($target instanceof Player) and !($target instanceof Level)){
|
||||
$output .= "That player cannot be found.\n";
|
||||
break;
|
||||
}
|
||||
|
||||
if(count($params) === 3){
|
||||
if($target instanceof Level){
|
||||
$spawn = new Vector3(floatval(array_shift($params)), floatval(array_shift($params)), floatval(array_shift($params)));
|
||||
}else{
|
||||
$spawn = new Position(floatval(array_shift($params)), floatval(array_shift($params)), floatval(array_shift($params)), $issuer->level);
|
||||
}
|
||||
}else{
|
||||
$spawn = new Position($issuer->entity->x, $issuer->entity->y, $issuer->entity->z, $issuer->entity->level);
|
||||
}
|
||||
|
||||
$target->setSpawn($spawn);
|
||||
if($target instanceof Level){
|
||||
$output .= "Spawnpoint of world " . $target->getName() . " set correctly!\n";
|
||||
}elseif($target !== $issuer){
|
||||
$output .= "Spawnpoint of " . $target->getName() . " set correctly!\n";
|
||||
}else{
|
||||
$output .= "Spawnpoint set correctly!\n";
|
||||
}
|
||||
break;
|
||||
case "spawn":
|
||||
if(!($issuer instanceof Player)){
|
||||
$output .= "Please run this command in-game.\n";
|
||||
break;
|
||||
}
|
||||
$issuer->teleport(Level::getDefault()->getSafeSpawn());
|
||||
break;
|
||||
case "ping":
|
||||
if(!($issuer instanceof Player)){
|
||||
$output .= "Please run this command in-game.\n";
|
||||
break;
|
||||
}
|
||||
$output .= "ping " . round($issuer->getLag(), 2) . "ms, packet loss " . round($issuer->getPacketLoss() * 100, 2) . "%, " . round($issuer->getBandwidth() / 1024, 2) . " KB/s\n";
|
||||
break;
|
||||
case "gamemode":
|
||||
$player = false;
|
||||
$setgm = false;
|
||||
$gms = array(
|
||||
"0" => 0,
|
||||
"survival" => 0,
|
||||
"s" => 0,
|
||||
"1" => 1,
|
||||
"creative" => 1,
|
||||
"c" => 1,
|
||||
"2" => 2,
|
||||
"adventure" => 2,
|
||||
"a" => 2,
|
||||
"3" => 3,
|
||||
"view" => 3,
|
||||
"viewer" => 3,
|
||||
"spectator" => 3,
|
||||
"v" => 3,
|
||||
);
|
||||
if(isset($params[1])){
|
||||
if(Player::get($params[1]) instanceof Player){
|
||||
$player = Player::get($params[1]);
|
||||
$setgm = $params[0];
|
||||
}elseif(Player::get($params[0]) instanceof Player){
|
||||
$player = Player::get($params[0]);
|
||||
$setgm = $params[1];
|
||||
}else{
|
||||
$output .= "Usage: /$cmd <mode> [player] or /$cmd [player] <mode>\n";
|
||||
break;
|
||||
}
|
||||
}elseif(isset($params[0])){
|
||||
if(!(Player::get($params[0]) instanceof Player)){
|
||||
if($issuer instanceof Player){
|
||||
$setgm = $params[0];
|
||||
$player = $issuer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!($player instanceof Player) or !isset($gms[strtolower($setgm)])){
|
||||
$output .= "Usage: /$cmd <mode> [player] or /$cmd [player] <mode>\n";
|
||||
break;
|
||||
}
|
||||
if($player->setGamemode($gms[strtolower($setgm)])){
|
||||
$output .= "Gamemode of " . $player->getName() . " changed to " . $player->getGamemode() . "\n";
|
||||
}
|
||||
break;
|
||||
case "tp":
|
||||
if(count($params) <= 2 or substr($params[0], 0, 2) === "w:" or substr($params[1], 0, 2) === "w:"){
|
||||
if((!isset($params[1]) or substr($params[0], 0, 2) === "w:") and isset($params[0]) and ($issuer instanceof Player)){
|
||||
$name = $issuer->getName();
|
||||
$target = implode(" ", $params);
|
||||
}elseif(isset($params[1]) and isset($params[0])){
|
||||
$name = array_shift($params);
|
||||
$target = implode(" ", $params);
|
||||
}else{
|
||||
$output .= "Usage: /$cmd [target player] <destination player | w:world>\n";
|
||||
break;
|
||||
}
|
||||
if($this->teleport($name, $target) !== false){
|
||||
$output .= "\"$name\" teleported to \"$target\"\n";
|
||||
}else{
|
||||
$output .= "Couldn't teleport.\n";
|
||||
}
|
||||
}else{
|
||||
if(!isset($params[3]) and isset($params[2]) and isset($params[1]) and isset($params[0]) and ($issuer instanceof Player)){
|
||||
$name = $issuer->getName();
|
||||
$x = $params[0];
|
||||
$y = $params[1];
|
||||
$z = $params[2];
|
||||
}elseif(isset($params[3]) and isset($params[2]) and isset($params[1]) and isset($params[0])){
|
||||
$name = $params[0];
|
||||
$x = $params[1];
|
||||
$y = $params[2];
|
||||
$z = $params[3];
|
||||
}else{
|
||||
$output .= "Usage: /$cmd [player] <x> <y> <z>\n";
|
||||
break;
|
||||
}
|
||||
if($this->tppos($name, $x, $y, $z)){
|
||||
$output .= "\"$name\" teleported to ($x, $y, $z)\n";
|
||||
}else{
|
||||
$output .= "Couldn't teleport.\n";
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "kill":
|
||||
case "suicide":
|
||||
if(!isset($params[0]) and ($issuer instanceof Player)){
|
||||
$player = $issuer;
|
||||
}else{
|
||||
$player = Player::get($params[0]);
|
||||
}
|
||||
if($player instanceof Player){
|
||||
$player->harm(1000, "console", true);
|
||||
$player->sendMessage("Ouch. That looks like it hurt.\n");
|
||||
}else{
|
||||
$output .= "Usage: /$cmd [player]\n";
|
||||
}
|
||||
break;
|
||||
case "list":
|
||||
$output .= "There are " . count(Player::$list) . "/" . $this->server->maxClients . " players online:\n";
|
||||
if(count(Player::$list) == 0){
|
||||
break;
|
||||
}
|
||||
foreach(Player::$list as $c){
|
||||
$output .= $c->getName() . ", ";
|
||||
}
|
||||
$output = substr($output, 0, -2) . "\n";
|
||||
break;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function teleport(&$name, &$target){
|
||||
if(substr($target, 0, 2) === "w:"){
|
||||
$lv = Level::get(substr($target, 2));
|
||||
if($lv instanceof Level){
|
||||
$origin = Player::get($name);
|
||||
if($origin instanceof Player){
|
||||
$name = $origin->getName();
|
||||
|
||||
return $origin->teleport($lv->getSafeSpawn());
|
||||
}
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$player = Player::get($target);
|
||||
if($player instanceof Player and $player->spawned === true){
|
||||
$target = $player->getName();
|
||||
$origin = Player::get($name);
|
||||
if($origin instanceof Player){
|
||||
$name = $origin->getName();
|
||||
|
||||
return $origin->teleport($player->entity);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function tppos(&$name, &$x, &$y, &$z){
|
||||
$player = Player::get($name);
|
||||
if($player instanceof Player and $player->spawned === true){
|
||||
$name = $player->getName();
|
||||
$x = $x{0} === "~" ? $player->x + floatval(substr($x, 1)) : floatval($x);
|
||||
$y = $y{0} === "~" ? $player->y + floatval(substr($y, 1)) : floatval($y);
|
||||
$z = $z{0} === "~" ? $player->z + floatval(substr($z, 1)) : floatval($z);
|
||||
$player->teleport(new Vector3($x, $y, $z));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,363 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
use pocketmine\network\query\QueryHandler;
|
||||
use pocketmine\network\rcon\RCON;
|
||||
use pocketmine\network\upnp\UPnP;
|
||||
use pocketmine\plugin\PluginManager;
|
||||
use pocketmine\utils\Config;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use pocketmine\utils\Utils;
|
||||
use pocketmine\utils\VersionString;
|
||||
|
||||
class ServerAPI{
|
||||
public $restart = false;
|
||||
private static $serverRequest = false;
|
||||
private $asyncCalls = array();
|
||||
private $server;
|
||||
private $config;
|
||||
private $apiList = array();
|
||||
private $asyncCnt = 0;
|
||||
private $rcon;
|
||||
|
||||
public $query;
|
||||
|
||||
//TODO: Instead of hard-coding functions, use PHPDoc-compatible methods to load APIs.
|
||||
|
||||
/** @var ConsoleAPI */
|
||||
public $console;
|
||||
|
||||
/** @var LevelAPI */
|
||||
public $level;
|
||||
|
||||
/** @var BlockAPI */
|
||||
public $block;
|
||||
|
||||
/** @var ChatAPI */
|
||||
public $chat;
|
||||
|
||||
/** @var BanAPI */
|
||||
public $ban;
|
||||
|
||||
/** @var TimeAPI */
|
||||
public $time;
|
||||
|
||||
/** @var PlayerAPI */
|
||||
public $player;
|
||||
|
||||
/**
|
||||
* @return Server
|
||||
*/
|
||||
public static function request(){
|
||||
return self::$serverRequest;
|
||||
}
|
||||
|
||||
public function start(){
|
||||
return $this->run();
|
||||
}
|
||||
|
||||
public function run(){
|
||||
$this->load();
|
||||
|
||||
return $this->init();
|
||||
}
|
||||
|
||||
public function load(){
|
||||
@mkdir(\pocketmine\DATA . "players/", 0755);
|
||||
@mkdir(\pocketmine\DATA . "worlds/", 0755);
|
||||
@mkdir(\pocketmine\DATA . "plugins/", 0755);
|
||||
|
||||
$version = new VersionString();
|
||||
console("[INFO] Starting Minecraft: PE server version " . TextFormat::AQUA . MINECRAFT_VERSION);
|
||||
|
||||
console("[INFO] Loading properties...");
|
||||
$this->config = new Config(\pocketmine\DATA . "server.properties", Config::PROPERTIES, array(
|
||||
"server-name" => "Minecraft: PE Server",
|
||||
"description" => "Server made using PocketMine-MP",
|
||||
"motd" => "Welcome @player to this server!",
|
||||
"server-port" => 19132,
|
||||
"server-type" => "normal",
|
||||
"memory-limit" => "128M",
|
||||
"last-update" => false,
|
||||
"white-list" => false,
|
||||
"announce-player-achievements" => true,
|
||||
"spawn-protection" => 16,
|
||||
"view-distance" => 8,
|
||||
"max-players" => 20,
|
||||
"allow-flight" => false,
|
||||
"spawn-animals" => true,
|
||||
"spawn-mobs" => true,
|
||||
"gamemode" => 0,
|
||||
"hardcore" => false,
|
||||
"pvp" => true,
|
||||
"difficulty" => 1,
|
||||
"generator-settings" => "",
|
||||
"level-name" => "world",
|
||||
"level-seed" => "",
|
||||
"level-type" => "DEFAULT",
|
||||
"enable-query" => true,
|
||||
"enable-rcon" => false,
|
||||
"rcon.password" => substr(base64_encode(Utils::getRandomBytes(20, false)), 3, 10),
|
||||
"auto-save" => true,
|
||||
));
|
||||
|
||||
$this->parseProperties();
|
||||
|
||||
//Load advanced properties
|
||||
define("pocketmine\\DEBUG", $this->getProperty("debug", 1));
|
||||
define("ADVANCED_CACHE", $this->getProperty("enable-advanced-cache", false));
|
||||
define("MAX_CHUNK_RATE", 20 / $this->getProperty("max-chunks-per-second", 7)); //Default rate ~448 kB/s
|
||||
if(ADVANCED_CACHE == true){
|
||||
console("[INFO] Advanced cache enabled");
|
||||
}
|
||||
if($this->getProperty("upnp-forwarding") == true){
|
||||
console("[INFO] [UPnP] Trying to port forward...");
|
||||
UPnP::PortForward($this->getProperty("server-port"));
|
||||
}
|
||||
$this->server = new Server($this->getProperty("server-name"), $this->getProperty("gamemode"), ($seed = $this->getProperty("level-seed")) != "" ? (int) $seed : false, $this->getProperty("server-port"), ($ip = $this->getProperty("server-ip")) != "" ? $ip : "0.0.0.0");
|
||||
$this->server->api = $this;
|
||||
self::$serverRequest = $this->server;
|
||||
console("[INFO] This server is running PocketMine-MP version " . ($version->isDev() ? TextFormat::YELLOW : "") . VERSION . TextFormat::RESET . " \"" . CODENAME . "\" (API " . API_VERSION . ")", true, true, 0);
|
||||
console("[INFO] PocketMine-MP is distributed under the LGPL License", true, true, 0);
|
||||
|
||||
if($this->getProperty("last-update") === false or ($this->getProperty("last-update") + 3600) < time()){
|
||||
console("[INFO] Checking for new server version");
|
||||
console("[INFO] Last check: " . TextFormat::AQUA . date("Y-m-d H:i:s", $this->getProperty("last-update")) . "\x1b[0m");
|
||||
if($this->server->version->isDev()){
|
||||
$info = json_decode(Utils::getURL("https://api.github.com/repos/PocketMine/PocketMine-MP/commits"), true);
|
||||
if($info === false or !isset($info[0])){
|
||||
console("[ERROR] Github API error");
|
||||
}else{
|
||||
$last = new \DateTime($info[0]["commit"]["committer"]["date"]);
|
||||
$last = $last->getTimestamp();
|
||||
if($last >= $this->getProperty("last-update") and $this->getProperty("last-update") !== false and \pocketmine\GIT_COMMIT != $info[0]["sha"]){
|
||||
console("[NOTICE] " . TextFormat::YELLOW . "A new DEVELOPMENT version of PocketMine-MP has been released!");
|
||||
console("[NOTICE] " . TextFormat::YELLOW . "Commit \"" . $info[0]["commit"]["message"] . "\" [" . substr($info[0]["sha"], 0, 10) . "] by " . $info[0]["commit"]["committer"]["name"]);
|
||||
console("[NOTICE] " . TextFormat::YELLOW . "Get it at PocketMine.net or at https://github.com/PocketMine/PocketMine-MP/archive/" . $info[0]["sha"] . ".zip");
|
||||
console("[NOTICE] This message will disappear after issuing the command \"/update-done\"");
|
||||
}else{
|
||||
$this->setProperty("last-update", time());
|
||||
console("[INFO] " . TextFormat::AQUA . "This is the latest DEVELOPMENT version");
|
||||
}
|
||||
}
|
||||
}else{
|
||||
$info = json_decode(Utils::getURL("https://api.github.com/repos/PocketMine/PocketMine-MP/tags"), true);
|
||||
if($info === false or !isset($info[0])){
|
||||
console("[ERROR] Github API error");
|
||||
}else{
|
||||
$newest = new VersionString(VERSION);
|
||||
$newestN = $newest->getNumber();
|
||||
$update = new VersionString($info[0]["name"]);
|
||||
$updateN = $update->getNumber();
|
||||
if($updateN > $newestN){
|
||||
console("[NOTICE] " . TextFormat::GREEN . "A new STABLE version of PocketMine-MP has been released!");
|
||||
console("[NOTICE] " . TextFormat::GREEN . "Version \"" . $info[0]["name"] . "\" #" . $updateN);
|
||||
console("[NOTICE] Get it at PocketMine.net or at " . $info[0]["zipball_url"]);
|
||||
console("[NOTICE] This message will disappear as soon as you update");
|
||||
}else{
|
||||
$this->setProperty("last-update", time());
|
||||
console("[INFO] " . TextFormat::AQUA . "This is the latest STABLE version");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->loadProperties();
|
||||
|
||||
|
||||
$this->apiList[] = $this->console = new ConsoleAPI();
|
||||
$this->apiList[] = $this->level = new LevelAPI();
|
||||
|
||||
$this->apiList[] = $this->block = new BlockAPI();
|
||||
$this->apiList[] = $this->chat = new ChatAPI();
|
||||
$this->apiList[] = $this->ban = new BanAPI();
|
||||
$this->apiList[] = $this->player = new PlayerAPI();
|
||||
$this->apiList[] = $this->time = new TimeAPI();
|
||||
|
||||
foreach($this->apiList as $ob){
|
||||
if(is_callable(array($ob, "init"))){
|
||||
$ob->init(); //Fails sometimes!!!
|
||||
}
|
||||
}
|
||||
|
||||
console("[INFO] Loaded " . count(PluginManager::loadPlugins(\pocketmine\DATA . "plugins/")) . " plugin(s).");
|
||||
|
||||
}
|
||||
|
||||
public function async(callable $callable, $params = array(), $remove = false){
|
||||
$cnt = $this->asyncCnt++;
|
||||
$this->asyncCalls[$cnt] = new \Async($callable, $params);
|
||||
|
||||
return $remove === true ? $this->getAsync($cnt) : $cnt;
|
||||
}
|
||||
|
||||
public function getAsync($id){
|
||||
if(!isset($this->asyncCalls[$id])){
|
||||
return false;
|
||||
}
|
||||
$ob = $this->asyncCalls[$id];
|
||||
unset($this->asyncCalls[$id]);
|
||||
|
||||
return $ob;
|
||||
}
|
||||
|
||||
public function __destruct(){
|
||||
foreach($this->apiList as $i => $ob){
|
||||
if(method_exists($ob, "__destruct")){
|
||||
$ob->__destruct();
|
||||
unset($this->apiList[$i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function writeProperties(){
|
||||
$this->config->save();
|
||||
}
|
||||
|
||||
public function init(){
|
||||
if(!(self::$serverRequest instanceof Server)){
|
||||
self::$serverRequest = $this->server;
|
||||
}
|
||||
|
||||
|
||||
if($this->getProperty("send-usage", true) !== false){
|
||||
$this->server->schedule(6000, array($this, "sendUsage"), array(), true); //Send the info after 5 minutes have passed
|
||||
$this->sendUsage();
|
||||
}
|
||||
if($this->getProperty("auto-save") === true){
|
||||
$this->server->schedule(18000, array($this, "autoSave"), array(), true);
|
||||
}
|
||||
if(!defined("NO_THREADS") and $this->getProperty("enable-rcon") === true){
|
||||
$this->rcon = new RCON($this->getProperty("rcon.password", ""), $this->getProperty("rcon.port", $this->getProperty("server-port")), ($ip = $this->getProperty("server-ip")) != "" ? $ip : "0.0.0.0", $this->getProperty("rcon.threads", 1), $this->getProperty("rcon.clients-per-thread", 50));
|
||||
}
|
||||
|
||||
if($this->getProperty("enable-query") === true){
|
||||
$this->query = new QueryHandler();
|
||||
}
|
||||
|
||||
$this->schedule(2, array($this, "checkTickUpdates"), array(), true);
|
||||
$this->server->init();
|
||||
unregister_tick_function(array($this->server, "tick"));
|
||||
$this->console->__destruct();
|
||||
if($this->rcon instanceof RCON){
|
||||
$this->rcon->stop();
|
||||
}
|
||||
$this->__destruct();
|
||||
if($this->getProperty("upnp-forwarding") === true){
|
||||
console("[INFO] [UPnP] Removing port forward...");
|
||||
UPnP::RemovePortForward($this->getProperty("server-port"));
|
||||
}
|
||||
|
||||
return $this->restart;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
public function asyncOperation($t, $d, $c = null){
|
||||
return $this->server->asyncOperation($t, $d, $c);
|
||||
}
|
||||
|
||||
public function addHandler($e, $c, $p = 5){
|
||||
return $this->server->addHandler($e, $c, $p);
|
||||
}
|
||||
|
||||
public function dhandle($e, $d){
|
||||
return $this->server->handle($e, $d);
|
||||
}
|
||||
|
||||
public function handle($e, &$d){
|
||||
return $this->server->handle($e, $d);
|
||||
}
|
||||
|
||||
public function schedule($t, $c, $d, $r = false, $e = "server.schedule"){
|
||||
return $this->server->schedule($t, $c, $d, $r, $e);
|
||||
}
|
||||
|
||||
public function event($e, $d){
|
||||
return $this->server->event($e, $d);
|
||||
}
|
||||
|
||||
public function trigger($e, $d){
|
||||
return $this->server->trigger($e, $d);
|
||||
}
|
||||
|
||||
public function deleteEvent($id){
|
||||
return $this->server->deleteEvent($id);
|
||||
}
|
||||
|
||||
public function getProperties(){
|
||||
return $this->config->getAll();
|
||||
}
|
||||
|
||||
public function getProperty($name, $default = false){
|
||||
$v = getopt("", array("$name::"));
|
||||
if(isset($v[$name]) !== false){ //Allow for command-line arguments
|
||||
$v = $v[$name];
|
||||
switch(strtolower(trim($v))){
|
||||
case "":
|
||||
case "on":
|
||||
case "true":
|
||||
case "yes":
|
||||
$v = true;
|
||||
break;
|
||||
case "off":
|
||||
case "false":
|
||||
case "no":
|
||||
$v = false;
|
||||
break;
|
||||
}
|
||||
switch($name){
|
||||
case "last-update":
|
||||
if($v === false){
|
||||
$v = time();
|
||||
}else{
|
||||
$v = (int) $v;
|
||||
}
|
||||
break;
|
||||
case "gamemode":
|
||||
case "max-players":
|
||||
case "server-port":
|
||||
case "debug":
|
||||
case "difficulty":
|
||||
$v = (int) $v;
|
||||
break;
|
||||
}
|
||||
|
||||
return $v;
|
||||
}
|
||||
|
||||
return ($this->config->exists($name) ? $this->config->get($name) : $default);
|
||||
}
|
||||
|
||||
public function setProperty($name, $value, $save = true){
|
||||
$this->config->set($name, $value);
|
||||
if($save == true){
|
||||
$this->writeProperties();
|
||||
}
|
||||
$this->loadProperties();
|
||||
}
|
||||
|
||||
public function getList(){
|
||||
return $this->apiList;
|
||||
}
|
||||
}
|
@ -1,735 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* PocketMine-MP is the Minecraft: PE multiplayer server software
|
||||
* Homepage: http://www.pocketmine.net/
|
||||
*/
|
||||
namespace pocketmine;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\network\Packet;
|
||||
use pocketmine\network\protocol\Info;
|
||||
use pocketmine\network\raknet\Info as RakNetInfo;
|
||||
use pocketmine\network\raknet\Packet as RakNetPacket;
|
||||
use pocketmine\plugin\PluginManager;
|
||||
use pocketmine\utils\Utils;
|
||||
use pocketmine\utils\VersionString;
|
||||
|
||||
class ServerOld{
|
||||
/** @var Server */
|
||||
private static $instance;
|
||||
|
||||
public $tCnt;
|
||||
public $serverID;
|
||||
public $interface;
|
||||
public $database;
|
||||
public $version;
|
||||
public $invisible;
|
||||
public $tickMeasure;
|
||||
public $preparedSQL;
|
||||
public $spawn;
|
||||
public $whitelist;
|
||||
public $seed;
|
||||
public $stop;
|
||||
public $gamemode;
|
||||
public $difficulty;
|
||||
public $name;
|
||||
public $maxClients;
|
||||
public $eidCnt;
|
||||
public $custom;
|
||||
public $description;
|
||||
public $motd;
|
||||
public $port;
|
||||
public $saveEnabled;
|
||||
|
||||
private $rcon;
|
||||
private $query;
|
||||
|
||||
private $serverip;
|
||||
private $evCnt;
|
||||
private $handCnt;
|
||||
private $events;
|
||||
private $eventsID;
|
||||
private $handlers;
|
||||
private $serverType;
|
||||
private $lastTick;
|
||||
private $doTick;
|
||||
private $ticks;
|
||||
private $memoryStats;
|
||||
private $schedule;
|
||||
private $asyncThread;
|
||||
private $async = array();
|
||||
private $asyncID = 0;
|
||||
|
||||
/**
|
||||
* @return Server
|
||||
*/
|
||||
public static function getInstance(){
|
||||
if(isset(self::$instance)){
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function load(){
|
||||
$this->version = new VersionString();
|
||||
if(defined("pocketmine\\DEBUG") and \pocketmine\DEBUG >= 0 and function_exists("cli_set_process_title")){
|
||||
@cli_set_process_title("PocketMine-MP " . \pocketmine\VERSION);
|
||||
}
|
||||
console("[INFO] Starting Minecraft PE server on " . ($this->serverip === "0.0.0.0" ? "*" : $this->serverip) . ":" . $this->port);
|
||||
define("BOOTUP_RANDOM", Utils::getRandomBytes(16));
|
||||
$this->serverID = $this->serverID === false ? Utils::readLong(substr(Utils::getUniqueID(true, $this->serverip . $this->port), 8)) : $this->serverID;
|
||||
$this->seed = $this->seed === false ? Utils::readInt(Utils::getRandomBytes(4, false)) : $this->seed;
|
||||
$this->startDatabase();
|
||||
$this->api = false;
|
||||
$this->tCnt = 1;
|
||||
$this->events = array();
|
||||
$this->eventsID = array();
|
||||
$this->handlers = array();
|
||||
$this->invisible = false;
|
||||
$this->difficulty = 1;
|
||||
$this->custom = array();
|
||||
$this->evCnt = 1;
|
||||
$this->handCnt = 1;
|
||||
$this->eidCnt = 1;
|
||||
$this->maxClients = 20;
|
||||
$this->schedule = array();
|
||||
$this->scheduleCnt = 1;
|
||||
$this->description = "";
|
||||
$this->memoryStats = array();
|
||||
$this->spawn = false;
|
||||
$this->saveEnabled = true;
|
||||
$this->whitelist = false;
|
||||
$this->tickMeasure = array_fill(0, 40, 0);
|
||||
$this->setType("normal");
|
||||
$this->interface = new Handler("255.255.255.255", $this->port, $this->serverip);
|
||||
$this->stop = false;
|
||||
$this->ticks = 0;
|
||||
if(!defined("NO_THREADS")){
|
||||
$this->asyncThread = new \AsyncMultipleQueue();
|
||||
}
|
||||
}
|
||||
|
||||
function __construct($name, $gamemode = 0, $seed = false, $port = 19132, $serverip = "0.0.0.0"){
|
||||
$this->port = (int) $port;
|
||||
$this->doTick = true;
|
||||
$this->gamemode = (int) $gamemode;
|
||||
$this->name = $name;
|
||||
$this->motd = "Welcome to " . $name;
|
||||
$this->serverID = false;
|
||||
$this->seed = $seed;
|
||||
$this->serverip = $serverip;
|
||||
self::$instance = $this;
|
||||
$this->load();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getTPS(){
|
||||
$v = array_values($this->tickMeasure);
|
||||
$tps = 40 / ($v[39] - $v[0]);
|
||||
|
||||
return round($tps, 4);
|
||||
}
|
||||
|
||||
public function titleTick(){
|
||||
$time = microtime(true);
|
||||
if(defined("pocketmine\\DEBUG") and \pocketmine\DEBUG >= 0 and \pocketmine\ANSI === true){
|
||||
echo "\x1b]0;PocketMine-MP " . VERSION . " | Online " . count(Player::$list) . "/" . $this->maxClients . " | RAM " . round((memory_get_usage() / 1024) / 1024, 2) . "MB | U " . round(($this->interface->bandwidth[1] / max(1, $time - $this->interface->bandwidth[2])) / 1024, 2) . " D " . round(($this->interface->bandwidth[0] / max(1, $time - $this->interface->bandwidth[2])) / 1024, 2) . " kB/s | TPS " . $this->getTPS() . "\x07";
|
||||
}
|
||||
$this->interface->bandwidth = array(0, 0, $time);
|
||||
}
|
||||
|
||||
public function loadEvents(){
|
||||
if(\pocketmine\ANSI === true){
|
||||
$this->schedule(30, array($this, "titleTick"), array(), true);
|
||||
}
|
||||
$this->schedule(20 * 15, array($this, "checkTicks"), array(), true);
|
||||
$this->schedule(20 * 60, array($this, "checkMemory"), array(), true);
|
||||
$this->schedule(20 * 45, "pocketmine\\utils\\Cache::cleanup", array(), true);
|
||||
$this->schedule(20, array($this, "asyncOperationChecker"), array(), true);
|
||||
}
|
||||
|
||||
public function checkTicks(){
|
||||
if($this->getTPS() < 12){
|
||||
console("[WARNING] Can't keep up! Is the server overloaded?");
|
||||
}
|
||||
}
|
||||
|
||||
public function checkMemory(){
|
||||
$info = $this->debugInfo();
|
||||
$data = $info["memory_usage"] . "," . $info["players"] . "," . $info["entities"];
|
||||
$i = count($this->memoryStats) - 1;
|
||||
if($i < 0 or $this->memoryStats[$i] !== $data){
|
||||
$this->memoryStats[] = $data;
|
||||
}
|
||||
}
|
||||
|
||||
public function startDatabase(){
|
||||
$this->preparedSQL = new \stdClass();
|
||||
$this->preparedSQL->entity = new \stdClass();
|
||||
$this->database = new \SQLite3(":memory:", SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE);
|
||||
$this->query("PRAGMA journal_mode = OFF;");
|
||||
$this->query("PRAGMA encoding = \"UTF-8\";");
|
||||
$this->query("PRAGMA secure_delete = OFF;");
|
||||
$this->query("CREATE TABLE actions (ID INTEGER PRIMARY KEY, interval NUMERIC, last NUMERIC, code TEXT, repeat NUMERIC);");
|
||||
$this->query("CREATE TABLE handlers (ID INTEGER PRIMARY KEY, name TEXT, priority NUMERIC);");
|
||||
$this->query("CREATE TABLE blockUpdates (level TEXT, x INTEGER, y INTEGER, z INTEGER, type INTEGER, delay NUMERIC);");
|
||||
$this->query("CREATE TABLE recipes (id INTEGER PRIMARY KEY, type NUMERIC, recipe TEXT);");
|
||||
$this->query("PRAGMA synchronous = OFF;");
|
||||
$this->preparedSQL->selectHandlers = $this->database->prepare("SELECT DISTINCT ID FROM handlers WHERE name = :name ORDER BY priority DESC;");
|
||||
$this->preparedSQL->selectActions = $this->database->prepare("SELECT ID,code,repeat FROM actions WHERE last <= (:time - interval);");
|
||||
$this->preparedSQL->updateAction = $this->database->prepare("UPDATE actions SET last = :time WHERE ID = :id;");
|
||||
}
|
||||
|
||||
public function query($sql, $fetch = false){
|
||||
$result = $this->database->query($sql) or console("[ERROR] [SQL Error] " . $this->database->lastErrorMsg() . ". Query: " . $sql, true, true, 0);
|
||||
if($fetch === true and ($result instanceof \SQLite3Result)){
|
||||
$result = $result->fetchArray(SQLITE3_ASSOC);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function debugInfo($console = false){
|
||||
$info = array();
|
||||
$info["tps"] = $this->getTPS();
|
||||
$info["memory_usage"] = round((memory_get_usage() / 1024) / 1024, 2) . "MB";
|
||||
$info["memory_peak_usage"] = round((memory_get_peak_usage() / 1024) / 1024, 2) . "MB";
|
||||
$info["entities"] = count(Entity::$list);
|
||||
$info["players"] = count(Player::$list);
|
||||
$info["events"] = count($this->eventsID);
|
||||
$info["handlers"] = $this->query("SELECT count(ID) as count FROM handlers;", true);
|
||||
$info["handlers"] = $info["handlers"]["count"];
|
||||
$info["actions"] = $this->query("SELECT count(ID) as count FROM actions;", true);
|
||||
$info["actions"] = $info["actions"]["count"];
|
||||
$info["garbage"] = gc_collect_cycles();
|
||||
$this->handle("server.debug", $info);
|
||||
if($console === true){
|
||||
console("[DEBUG] TPS: " . $info["tps"] . ", Memory usage: " . $info["memory_usage"] . " (Peak " . $info["memory_peak_usage"] . "), Entities: " . $info["entities"] . ", Events: " . $info["events"] . ", Handlers: " . $info["handlers"] . ", Actions: " . $info["actions"] . ", Garbage: " . $info["garbage"], true, true, 2);
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $reason
|
||||
*/
|
||||
public function close($reason = "server stop"){
|
||||
if($this->stop !== true){
|
||||
if(is_int($reason)){
|
||||
$reason = "signal stop";
|
||||
}
|
||||
if(($this->api instanceof ServerAPI) === true){
|
||||
if(($this->api->chat instanceof ChatAPI) === true){
|
||||
Player::broadcastMessage("Stopping server...");
|
||||
}
|
||||
}
|
||||
$this->stop = true;
|
||||
$this->trigger("server.close", $reason);
|
||||
$this->interface->close();
|
||||
|
||||
if(!defined("NO_THREADS")){
|
||||
@$this->asyncThread->stop = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function setType($type = "normal"){
|
||||
switch(trim(strtolower($type))){
|
||||
case "normal":
|
||||
case "demo":
|
||||
$this->serverType = "MCCPP;Demo;";
|
||||
break;
|
||||
case "minecon":
|
||||
$this->serverType = "MCCPP;MINECON;";
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function asyncOperation($type, array $data, callable $callable = null){
|
||||
if(defined("NO_THREADS")){
|
||||
return false;
|
||||
}
|
||||
$d = "";
|
||||
$type = (int) $type;
|
||||
switch($type){
|
||||
case ASYNC_CURL_GET:
|
||||
$d .= Utils::writeShort(strlen($data["url"])) . $data["url"] . (isset($data["timeout"]) ? Utils::writeShort($data["timeout"]) : Utils::writeShort(10));
|
||||
break;
|
||||
case ASYNC_CURL_POST:
|
||||
$d .= Utils::writeShort(strlen($data["url"])) . $data["url"] . (isset($data["timeout"]) ? Utils::writeShort($data["timeout"]) : Utils::writeShort(10));
|
||||
$d .= Utils::writeShort(count($data["data"]));
|
||||
foreach($data["data"] as $key => $value){
|
||||
$d .= Utils::writeShort(strlen($key)) . $key . Utils::writeInt(strlen($value)) . $value;
|
||||
}
|
||||
break;
|
||||
case ASYNC_FUNCTION:
|
||||
$params = serialize($data["arguments"]);
|
||||
$d .= Utils::writeShort(strlen($data["function"])) . $data["function"] . Utils::writeInt(strlen($params)) . $params;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
$ID = $this->asyncID++;
|
||||
$this->async[$ID] = $callable;
|
||||
$this->asyncThread->input .= Utils::writeInt($ID) . Utils::writeShort($type) . $d;
|
||||
|
||||
return $ID;
|
||||
}
|
||||
|
||||
public function asyncOperationChecker(){
|
||||
if(defined("NO_THREADS")){
|
||||
return false;
|
||||
}
|
||||
if(isset($this->asyncThread->output{5})){
|
||||
$offset = 0;
|
||||
$ID = Utils::readInt(substr($this->asyncThread->output, $offset, 4));
|
||||
$offset += 4;
|
||||
$type = Utils::readShort(substr($this->asyncThread->output, $offset, 2));
|
||||
$offset += 2;
|
||||
$data = array();
|
||||
switch($type){
|
||||
case ASYNC_CURL_GET:
|
||||
case ASYNC_CURL_POST:
|
||||
$len = Utils::readInt(substr($this->asyncThread->output, $offset, 4));
|
||||
$offset += 4;
|
||||
$data["result"] = substr($this->asyncThread->output, $offset, $len);
|
||||
$offset += $len;
|
||||
break;
|
||||
case ASYNC_FUNCTION:
|
||||
$len = Utils::readInt(substr($this->asyncThread->output, $offset, 4));
|
||||
$offset += 4;
|
||||
$data["result"] = unserialize(substr($this->asyncThread->output, $offset, $len));
|
||||
$offset += $len;
|
||||
break;
|
||||
}
|
||||
$this->asyncThread->output = substr($this->asyncThread->output, $offset);
|
||||
if(isset($this->async[$ID]) and $this->async[$ID] !== null and is_callable($this->async[$ID])){
|
||||
if(is_array($this->async[$ID])){
|
||||
$method = $this->async[$ID][1];
|
||||
$result = $this->async[$ID][0]->$method($data, $type, $ID);
|
||||
}else{
|
||||
$result = $this->async[$ID]($data, $type, $ID);
|
||||
}
|
||||
}
|
||||
unset($this->async[$ID]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $event
|
||||
* @param callable $callable
|
||||
* @param integer $priority
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function addHandler($event, callable $callable, $priority = 5){
|
||||
if(!is_callable($callable)){
|
||||
return false;
|
||||
}
|
||||
$priority = (int) $priority;
|
||||
$hnid = $this->handCnt++;
|
||||
$this->handlers[$hnid] = $callable;
|
||||
$this->query("INSERT INTO handlers (ID, name, priority) VALUES (" . $hnid . ", '" . str_replace("'", "\\'", $event) . "', " . $priority . ");");
|
||||
console("[INTERNAL] New handler " . (is_array($callable) ? get_class($callable[0]) . "::" . $callable[1] : $callable) . " to special event " . $event . " (ID " . $hnid . ")", true, true, 3);
|
||||
|
||||
return $hnid;
|
||||
}
|
||||
|
||||
public function dhandle($e, $d){
|
||||
return $this->handle($e, $d);
|
||||
}
|
||||
|
||||
public function handle($event, &$data){
|
||||
$this->preparedSQL->selectHandlers->reset();
|
||||
$this->preparedSQL->selectHandlers->clear();
|
||||
$this->preparedSQL->selectHandlers->bindValue(":name", $event, SQLITE3_TEXT);
|
||||
$handlers = $this->preparedSQL->selectHandlers->execute();
|
||||
$result = null;
|
||||
if($handlers instanceof \SQLite3Result){
|
||||
$call = array();
|
||||
while(($hn = $handlers->fetchArray(SQLITE3_ASSOC)) !== false){
|
||||
$call[(int) $hn["ID"]] = true;
|
||||
}
|
||||
$handlers->finalize();
|
||||
foreach($call as $hnid => $boolean){
|
||||
if($result !== false and $result !== true){
|
||||
$handler = $this->handlers[$hnid];
|
||||
if(is_array($handler)){
|
||||
$method = $handler[1];
|
||||
$result = $handler[0]->$method($data, $event);
|
||||
}else{
|
||||
$result = $handler($data, $event);
|
||||
}
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($result !== false){
|
||||
$this->trigger($event, $data);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function eventHandler($data, $event){
|
||||
switch($event){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @return string
|
||||
*/
|
||||
public function getGamemode(){
|
||||
switch($this->gamemode){
|
||||
case 0:
|
||||
return "survival";
|
||||
case 1:
|
||||
return "creative";
|
||||
case 2:
|
||||
return "adventure";
|
||||
case 3:
|
||||
return "view";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function init(){
|
||||
register_tick_function(array($this, "tick"));
|
||||
declare(ticks = 5000); //Minimum TPS for main thread locks
|
||||
|
||||
$this->loadEvents();
|
||||
register_shutdown_function(array($this, "dumpError"));
|
||||
register_shutdown_function(array($this, "close"));
|
||||
if(function_exists("pcntl_signal")){
|
||||
pcntl_signal(SIGTERM, array($this, "close"));
|
||||
pcntl_signal(SIGINT, array($this, "close"));
|
||||
pcntl_signal(SIGHUP, array($this, "close"));
|
||||
}
|
||||
console("[INFO] Default game type: " . strtoupper($this->getGamemode()));
|
||||
$this->trigger("server.start", microtime(true));
|
||||
console('[INFO] Done (' . round(microtime(true) - \pocketmine\START_TIME, 3) . 's)! For help, type "help" or "?"');
|
||||
$this->process();
|
||||
}
|
||||
|
||||
public function dumpError(){
|
||||
if($this->stop === true){
|
||||
return;
|
||||
}
|
||||
ini_set("memory_limit", "-1"); //Fix error dump not dumped on memory problems
|
||||
console("[SEVERE] An unrecovereable has ocurred and the server has crashed. Creating an error dump");
|
||||
$dump = "```\r\n# PocketMine-MP Error Dump " . date("D M j H:i:s T Y") . "\r\n";
|
||||
$er = error_get_last();
|
||||
$errorConversion = array(
|
||||
E_ERROR => "E_ERROR",
|
||||
E_WARNING => "E_WARNING",
|
||||
E_PARSE => "E_PARSE",
|
||||
E_NOTICE => "E_NOTICE",
|
||||
E_CORE_ERROR => "E_CORE_ERROR",
|
||||
E_CORE_WARNING => "E_CORE_WARNING",
|
||||
E_COMPILE_ERROR => "E_COMPILE_ERROR",
|
||||
E_COMPILE_WARNING => "E_COMPILE_WARNING",
|
||||
E_USER_ERROR => "E_USER_ERROR",
|
||||
E_USER_WARNING => "E_USER_WARNING",
|
||||
E_USER_NOTICE => "E_USER_NOTICE",
|
||||
E_STRICT => "E_STRICT",
|
||||
E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR",
|
||||
E_DEPRECATED => "E_DEPRECATED",
|
||||
E_USER_DEPRECATED => "E_USER_DEPRECATED",
|
||||
);
|
||||
$er["type"] = isset($errorConversion[$er["type"]]) ? $errorConversion[$er["type"]] : $er["type"];
|
||||
$dump .= "Error: " . var_export($er, true) . "\r\n\r\n";
|
||||
if(stripos($er["file"], "plugin") !== false){
|
||||
$dump .= "THIS ERROR WAS CAUSED BY A PLUGIN. REPORT IT TO THE PLUGIN DEVELOPER.\r\n";
|
||||
}
|
||||
|
||||
$dump .= "Code: \r\n";
|
||||
$file = @file($er["file"], FILE_IGNORE_NEW_LINES);
|
||||
for($l = max(0, $er["line"] - 10); $l < $er["line"] + 10; ++$l){
|
||||
$dump .= "[" . ($l + 1) . "] " . @$file[$l] . "\r\n";
|
||||
}
|
||||
$dump .= "\r\n\r\n";
|
||||
$dump .= "Backtrace: \r\n";
|
||||
foreach(getTrace() as $line){
|
||||
$dump .= "$line\r\n";
|
||||
}
|
||||
$dump .= "\r\n\r\n";
|
||||
$version = new VersionString();
|
||||
$dump .= "PocketMine-MP version: " . $version . " #" . $version->getNumber() . " [Protocol " . Info::CURRENT_PROTOCOL . "; API " . API_VERSION . "]\r\n";
|
||||
$dump .= "Git commit: " . GIT_COMMIT . "\r\n";
|
||||
$dump .= "uname -a: " . php_uname("a") . "\r\n";
|
||||
$dump .= "PHP Version: " . phpversion() . "\r\n";
|
||||
$dump .= "Zend version: " . zend_version() . "\r\n";
|
||||
$dump .= "OS : " . PHP_OS . ", " . Utils::getOS() . "\r\n";
|
||||
$dump .= "Debug Info: " . var_export($this->debugInfo(false), true) . "\r\n\r\n\r\n";
|
||||
global $arguments;
|
||||
$dump .= "Parameters: " . var_export($arguments, true) . "\r\n\r\n\r\n";
|
||||
$p = $this->api->getProperties();
|
||||
if($p["rcon.password"] != ""){
|
||||
$p["rcon.password"] = "******";
|
||||
}
|
||||
$dump .= "server.properties: " . var_export($p, true) . "\r\n\r\n\r\n";
|
||||
if(class_exists("pocketmine\\plugin\\PluginManager", false)){
|
||||
$dump .= "Loaded plugins:\r\n";
|
||||
foreach(PluginManager::getPlugins() as $p){
|
||||
$d = $p->getDescription();
|
||||
$dump .= $d->getName() . " " . $d->getVersion() . " by " . implode(", ", $d->getAuthors()) . "\r\n";
|
||||
}
|
||||
$dump .= "\r\n\r\n";
|
||||
}
|
||||
|
||||
$extensions = array();
|
||||
foreach(get_loaded_extensions() as $ext){
|
||||
$extensions[$ext] = phpversion($ext);
|
||||
}
|
||||
|
||||
$dump .= "Loaded Modules: " . var_export($extensions, true) . "\r\n";
|
||||
$this->checkMemory();
|
||||
$dump .= "Memory Usage Tracking: \r\n" . chunk_split(base64_encode(gzdeflate(implode(";", $this->memoryStats), 9))) . "\r\n";
|
||||
ob_start();
|
||||
phpinfo();
|
||||
$dump .= "\r\nphpinfo(): \r\n" . chunk_split(base64_encode(gzdeflate(ob_get_contents(), 9))) . "\r\n";
|
||||
ob_end_clean();
|
||||
$dump .= "\r\n```";
|
||||
$name = "Error_Dump_" . date("D_M_j-H.i.s-T_Y");
|
||||
log($dump, $name, true, 0, true);
|
||||
console("[SEVERE] Please submit the \"{$name}.log\" file to the Bug Reporting page. Give as much info as you can.", true, true, 0);
|
||||
}
|
||||
|
||||
public function tick(){
|
||||
$time = microtime(true);
|
||||
if($this->lastTick <= ($time - 0.05)){
|
||||
$this->tickMeasure[] = $this->lastTick = $time;
|
||||
unset($this->tickMeasure[key($this->tickMeasure)]);
|
||||
++$this->ticks;
|
||||
|
||||
return $this->tickerFunction($time);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static function clientID($ip, $port){
|
||||
return crc32($ip . $port) ^ crc32($port . $ip . BOOTUP_RANDOM);
|
||||
//return $ip . ":" . $port;
|
||||
}
|
||||
|
||||
public function packetHandler(Packet $packet){
|
||||
$data =& $packet;
|
||||
$CID = Server::clientID($packet->ip, $packet->port);
|
||||
if(isset(Player::$list[$CID])){
|
||||
if($packet instanceof RakNetPacket){
|
||||
Player::$list[$CID]->handlePacket($packet);
|
||||
}
|
||||
}else{
|
||||
switch($packet->pid()){
|
||||
case RakNetInfo::UNCONNECTED_PING:
|
||||
case RakNetInfo::UNCONNECTED_PING_OPEN_CONNECTIONS:
|
||||
if($this->invisible === true){
|
||||
$pk = new RakNetPacket(RakNetInfo::UNCONNECTED_PONG);
|
||||
$pk->pingID = $packet->pingID;
|
||||
$pk->serverID = $this->serverID;
|
||||
$pk->serverType = $this->serverType;
|
||||
$pk->ip = $packet->ip;
|
||||
$pk->port = $packet->port;
|
||||
$this->send($pk);
|
||||
break;
|
||||
}
|
||||
if(!isset($this->custom["times_" . $CID])){
|
||||
$this->custom["times_" . $CID] = 0;
|
||||
}
|
||||
$ln = 15;
|
||||
if($this->description == "" or substr($this->description, -1) != " "){
|
||||
$this->description .= " ";
|
||||
}
|
||||
$txt = substr($this->description, $this->custom["times_" . $CID], $ln);
|
||||
$txt .= substr($this->description, 0, $ln - strlen($txt));
|
||||
$pk = new RakNetPacket(RakNetInfo::UNCONNECTED_PONG);
|
||||
$pk->pingID = $packet->pingID;
|
||||
$pk->serverID = $this->serverID;
|
||||
$pk->serverType = $this->serverType . $this->name . " [" . count(Player::$list) . "/" . $this->maxClients . "] " . $txt;
|
||||
$pk->ip = $packet->ip;
|
||||
$pk->port = $packet->port;
|
||||
$this->send($pk);
|
||||
$this->custom["times_" . $CID] = ($this->custom["times_" . $CID] + 1) % strlen($this->description);
|
||||
break;
|
||||
case RakNetInfo::OPEN_CONNECTION_REQUEST_1:
|
||||
if($packet->structure !== RakNetInfo::STRUCTURE){
|
||||
console("[DEBUG] Incorrect structure #" . $packet->structure . " from " . $packet->ip . ":" . $packet->port, true, true, 2);
|
||||
$pk = new RakNetPacket(RakNetInfo::INCOMPATIBLE_PROTOCOL_VERSION);
|
||||
$pk->serverID = $this->serverID;
|
||||
$pk->ip = $packet->ip;
|
||||
$pk->port = $packet->port;
|
||||
$this->send($pk);
|
||||
}else{
|
||||
$pk = new RakNetPacket(RakNetInfo::OPEN_CONNECTION_REPLY_1);
|
||||
$pk->serverID = $this->serverID;
|
||||
$pk->mtuSize = strlen($packet->buffer);
|
||||
$pk->ip = $packet->ip;
|
||||
$pk->port = $packet->port;
|
||||
$this->send($pk);
|
||||
}
|
||||
break;
|
||||
case RakNetInfo::OPEN_CONNECTION_REQUEST_2:
|
||||
if($this->invisible === true){
|
||||
break;
|
||||
}
|
||||
|
||||
new Player($packet->clientID, $packet->ip, $packet->port, $packet->mtuSize); //New Session!
|
||||
$pk = new RakNetPacket(RakNetInfo::OPEN_CONNECTION_REPLY_2);
|
||||
$pk->serverID = $this->serverID;
|
||||
$pk->serverPort = $this->port;
|
||||
$pk->mtuSize = $packet->mtuSize;
|
||||
$pk->ip = $packet->ip;
|
||||
$pk->port = $packet->port;
|
||||
$this->send($pk);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function send(Packet $packet){
|
||||
return $this->interface->writePacket($packet);
|
||||
}
|
||||
|
||||
public function process(){
|
||||
$lastLoop = 0;
|
||||
while($this->stop === false){
|
||||
$packet = $this->interface->readPacket();
|
||||
if($packet instanceof Packet){
|
||||
$this->packetHandler($packet);
|
||||
$lastLoop = 0;
|
||||
}
|
||||
if(($ticks = $this->tick()) === 0){
|
||||
++$lastLoop;
|
||||
if($lastLoop < 16){
|
||||
usleep(1);
|
||||
}elseif($lastLoop < 128){
|
||||
usleep(1000);
|
||||
}elseif($lastLoop < 256){
|
||||
usleep(2000);
|
||||
}else{
|
||||
usleep(4000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function trigger($event, $data = ""){
|
||||
if(isset($this->events[$event])){
|
||||
foreach($this->events[$event] as $evid => $ev){
|
||||
if(!is_callable($ev)){
|
||||
$this->deleteEvent($evid);
|
||||
continue;
|
||||
}
|
||||
if(is_array($ev)){
|
||||
$method = $ev[1];
|
||||
$ev[0]->$method($data, $event);
|
||||
}else{
|
||||
$ev($data, $event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function schedule($ticks, callable $callback, $data = array(), $repeat = false, $eventName = "server.schedule"){
|
||||
if(!is_callable($callback)){
|
||||
return false;
|
||||
}
|
||||
$chcnt = $this->scheduleCnt++;
|
||||
$this->schedule[$chcnt] = array($callback, $data, $eventName);
|
||||
$this->query("INSERT INTO actions (ID, interval, last, repeat) VALUES(" . $chcnt . ", " . ($ticks / 20) . ", " . microtime(true) . ", " . (((bool) $repeat) === true ? 1 : 0) . ");");
|
||||
|
||||
return $chcnt;
|
||||
}
|
||||
|
||||
public function tickerFunction($time){
|
||||
//actions that repeat every x time will go here
|
||||
$this->preparedSQL->selectActions->reset();
|
||||
$this->preparedSQL->selectActions->bindValue(":time", $time, SQLITE3_FLOAT);
|
||||
$actions = $this->preparedSQL->selectActions->execute();
|
||||
|
||||
$actionCount = 0;
|
||||
if($actions instanceof \SQLite3Result){
|
||||
while(($action = $actions->fetchArray(SQLITE3_ASSOC)) !== false){
|
||||
$cid = $action["ID"];
|
||||
$this->preparedSQL->updateAction->reset();
|
||||
$this->preparedSQL->updateAction->bindValue(":time", $time, SQLITE3_FLOAT);
|
||||
$this->preparedSQL->updateAction->bindValue(":id", $cid, SQLITE3_INTEGER);
|
||||
$this->preparedSQL->updateAction->execute();
|
||||
if(!@is_callable($this->schedule[$cid][0])){
|
||||
$return = false;
|
||||
}else{
|
||||
++$actionCount;
|
||||
$return = call_user_func($this->schedule[$cid][0], $this->schedule[$cid][1], $this->schedule[$cid][2]);
|
||||
}
|
||||
|
||||
if($action["repeat"] == 0 or $return === false){
|
||||
$this->query("DELETE FROM actions WHERE ID = " . $action["ID"] . ";");
|
||||
$this->schedule[$cid] = null;
|
||||
unset($this->schedule[$cid]);
|
||||
}
|
||||
}
|
||||
$actions->finalize();
|
||||
}
|
||||
|
||||
return $actionCount;
|
||||
}
|
||||
|
||||
public function event($event, callable $func){
|
||||
if(!is_callable($func)){
|
||||
return false;
|
||||
}
|
||||
$evid = $this->evCnt++;
|
||||
if(!isset($this->events[$event])){
|
||||
$this->events[$event] = array();
|
||||
}
|
||||
$this->events[$event][$evid] = $func;
|
||||
$this->eventsID[$evid] = $event;
|
||||
console("[INTERNAL] Attached " . (is_array($func) ? get_class($func[0]) . "::" . $func[1] : $func) . " to event " . $event . " (ID " . $evid . ")", true, true, 3);
|
||||
|
||||
return $evid;
|
||||
}
|
||||
|
||||
public function deleteEvent($id){
|
||||
$id = (int) $id;
|
||||
if(isset($this->eventsID[$id])){
|
||||
$ev = $this->eventsID[$id];
|
||||
$this->eventsID[$id] = null;
|
||||
unset($this->eventsID[$id]);
|
||||
$this->events[$ev][$id] = null;
|
||||
unset($this->events[$ev][$id]);
|
||||
if(count($this->events[$ev]) === 0){
|
||||
unset($this->events[$ev]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,144 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
use pocketmine\level\Level;
|
||||
|
||||
class TimeAPI{
|
||||
public static $phases = array(
|
||||
"day" => 0,
|
||||
"sunset" => 9500,
|
||||
"night" => 10900,
|
||||
"sunrise" => 17800,
|
||||
);
|
||||
private $server;
|
||||
|
||||
function __construct(){
|
||||
$this->server = Server::getInstance();
|
||||
}
|
||||
|
||||
public function init(){
|
||||
$this->server->api->console->register("time", "<check|set|add> [time]", array($this, "commandHandler"));
|
||||
}
|
||||
|
||||
public function commandHandler($cmd, $params, $issuer, $alias){
|
||||
$output = "";
|
||||
switch($cmd){
|
||||
case "time":
|
||||
$level = false;
|
||||
if($issuer instanceof Player){
|
||||
$level = $issuer->level;
|
||||
}
|
||||
$p = strtolower(array_shift($params));
|
||||
switch($p){
|
||||
case "check":
|
||||
$output .= "Time: " . $this->getDate($level) . ", " . $this->getPhase($level) . " (" . $this->get(true, $level) . ")\n";
|
||||
break;
|
||||
case "add":
|
||||
$output .= "Set the time to " . $this->add(array_shift($params), $level) . "\n";
|
||||
break;
|
||||
case "set":
|
||||
$output .= "Set the time to " . $this->set(array_shift($params), $level) . "\n";
|
||||
break;
|
||||
case "sunrise":
|
||||
case "day":
|
||||
case "sunset":
|
||||
case "night":
|
||||
$output .= "Set the time to " . $this->set($p, $level) . "\n";
|
||||
break;
|
||||
default:
|
||||
$output .= "Usage: /time <check|set|add> [time]\n";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function night(){
|
||||
return $this->set("night");
|
||||
}
|
||||
|
||||
public function day(){
|
||||
return $this->set("day");
|
||||
}
|
||||
|
||||
public function sunrise(){
|
||||
return $this->set("sunrise");
|
||||
}
|
||||
|
||||
public function sunset(){
|
||||
return $this->set("sunset");
|
||||
}
|
||||
|
||||
public function get($raw = false, $level = false){
|
||||
if(!($level instanceof Level)){
|
||||
$level = Level::getDefault();
|
||||
}
|
||||
|
||||
return $raw === true ? $level->getTime() : abs($level->getTime()) % 19200;
|
||||
}
|
||||
|
||||
public function add($time, $level = false){
|
||||
if(!($level instanceof Level)){
|
||||
$level = Level::getDefault();
|
||||
}
|
||||
$level->setTime($level->getTime() + (int) $time);
|
||||
}
|
||||
|
||||
public function getDate($time = false){
|
||||
$time = !is_integer($time) ? $this->get(false, $time) : $time;
|
||||
|
||||
return str_pad(strval((floor($time / 800) + 6) % 24), 2, "0", STR_PAD_LEFT) . ":" . str_pad(strval(floor(($time % 800) / 13.33)), 2, "0", STR_PAD_LEFT);
|
||||
}
|
||||
|
||||
public function getPhase($time = false){
|
||||
$time = !is_integer($time) ? $this->get(false, $time) : $time;
|
||||
if($time < TimeAPI::$phases["sunset"]){
|
||||
$time = "day";
|
||||
}elseif($time < TimeAPI::$phases["night"]){
|
||||
$time = "sunset";
|
||||
}elseif($time < TimeAPI::$phases["sunrise"]){
|
||||
$time = "night";
|
||||
}else{
|
||||
$time = "sunrise";
|
||||
}
|
||||
|
||||
return $time;
|
||||
}
|
||||
|
||||
public function set($time, $level = false){
|
||||
if(!($level instanceof Level)){
|
||||
$level = Level::getDefault();
|
||||
}
|
||||
if(is_string($time) and isset(TimeAPI::$phases[$time])){
|
||||
$level->setTime(TimeAPI::$phases[$time]);
|
||||
}else{
|
||||
$level->setTime((int) $time);
|
||||
}
|
||||
|
||||
return $level->getTime();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
//Entities
|
||||
const ENTITY_PLAYER = 1;
|
||||
|
||||
const ENTITY_MOB = 2;
|
||||
const MOB_CHICKEN = 10;
|
||||
const MOB_COW = 11;
|
||||
const MOB_PIG = 12;
|
||||
const MOB_SHEEP = 13;
|
||||
|
||||
const MOB_ZOMBIE = 32;
|
||||
const MOB_CREEPER = 33;
|
||||
const MOB_SKELETON = 34;
|
||||
const MOB_SPIDER = 35;
|
||||
const MOB_PIGMAN = 36;
|
||||
|
||||
const ENTITY_OBJECT = 3;
|
||||
const OBJECT_PRIMEDTNT = 65;
|
||||
const OBJECT_ARROW = 80;
|
||||
const OBJECT_PAINTING = 83;
|
||||
|
||||
const ENTITY_ITEM = 4;
|
||||
|
||||
const ENTITY_FALLING = 5;
|
||||
const FALLING_SAND = 66;
|
@ -1,552 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* All the entity classes
|
||||
*/
|
||||
namespace pocketmine\entity;
|
||||
|
||||
use pocketmine\event\entity\EntityDespawnEvent;
|
||||
use pocketmine\event\entity\EntityLevelChangeEvent;
|
||||
use pocketmine\event\entity\EntityMotionEvent;
|
||||
use pocketmine\event\entity\EntityMoveEvent;
|
||||
use pocketmine\event\entity\EntitySpawnEvent;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\level\Position;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3 as Vector3;
|
||||
use pocketmine\nbt\tag\Compound;
|
||||
use pocketmine\network\protocol\MoveEntityPacket_PosRot;
|
||||
use pocketmine\network\protocol\MovePlayerPacket;
|
||||
use pocketmine\network\protocol\RemoveEntityPacket;
|
||||
use pocketmine\network\protocol\SetEntityMotionPacket;
|
||||
use pocketmine\Network;
|
||||
use pocketmine\network\protocol\SetTimePacket;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\pmf\LevelFormat;
|
||||
use pocketmine\Server;
|
||||
|
||||
abstract class Entity extends Position{
|
||||
public static $entityCount = 1;
|
||||
|
||||
/**
|
||||
* @var Entity[]
|
||||
*/
|
||||
public static $list = array();
|
||||
|
||||
/**
|
||||
* @var Entity[]
|
||||
*/
|
||||
public static $needUpdate = array();
|
||||
|
||||
/**
|
||||
* @var Player[]
|
||||
*/
|
||||
protected $hasSpawned = array();
|
||||
|
||||
protected $id;
|
||||
|
||||
public $passenger = null;
|
||||
public $vehicle = null;
|
||||
|
||||
public $chunkIndex;
|
||||
|
||||
public $lastX;
|
||||
public $lastY;
|
||||
public $lastZ;
|
||||
|
||||
public $motionX;
|
||||
public $motionY;
|
||||
public $motionZ;
|
||||
|
||||
public $yaw;
|
||||
public $pitch;
|
||||
public $lastYaw;
|
||||
public $lastPitch;
|
||||
|
||||
public $boundingBox;
|
||||
public $onGround;
|
||||
public $positionChanged;
|
||||
public $motionChanged;
|
||||
public $dead;
|
||||
|
||||
public $height;
|
||||
public $width;
|
||||
public $length;
|
||||
|
||||
public $fallDistance;
|
||||
public $ticksLived;
|
||||
public $lastUpdate;
|
||||
public $maxFireTicks;
|
||||
public $fireTicks;
|
||||
public $airTicks;
|
||||
public $namedtag;
|
||||
|
||||
protected $inWater;
|
||||
public $noDamageTicks;
|
||||
private $justCreated;
|
||||
protected $fireProof;
|
||||
private $invulnerable;
|
||||
|
||||
public $closed;
|
||||
|
||||
public static function get($entityID){
|
||||
return isset(Entity::$list[$entityID]) ? Entity::$list[$entityID] : false;
|
||||
}
|
||||
|
||||
public static function getAll(){
|
||||
return Entity::$list;
|
||||
}
|
||||
|
||||
|
||||
public function __construct(Level $level, Compound $nbt){
|
||||
$this->id = Entity::$entityCount++;
|
||||
$this->justCreated = true;
|
||||
$this->closed = false;
|
||||
$this->namedtag = $nbt;
|
||||
$this->level = $level;
|
||||
|
||||
$this->boundingBox = new AxisAlignedBB(0, 0, 0, 0, 0, 0);
|
||||
$this->setPositionAndRotation(new Vector3($this->namedtag["Pos"][0], $this->namedtag["Pos"][1], $this->namedtag["Pos"][2]), $this->namedtag->Rotation[0], $this->namedtag->Rotation[1]);
|
||||
$this->setMotion(new Vector3($this->namedtag["Motion"][0], $this->namedtag["Motion"][1], $this->namedtag["Motion"][2]));
|
||||
|
||||
$this->fallDistance = $this->namedtag["FallDistance"];
|
||||
$this->fireTicks = $this->namedtag["Fire"];
|
||||
$this->airTicks = $this->namedtag["Air"];
|
||||
$this->onGround = $this->namedtag["OnGround"] > 0 ? true : false;
|
||||
$this->invulnerable = $this->namedtag["Invulnerable"] > 0 ? true : false;
|
||||
|
||||
$index = LevelFormat::getIndex($this->x >> 4, $this->z >> 4);
|
||||
$this->chunkIndex = $index;
|
||||
Entity::$list[$this->id] = $this;
|
||||
$this->level->entities[$this->id] = $this;
|
||||
$this->level->chunkEntities[$this->chunkIndex][$this->id] = $this;
|
||||
$this->lastUpdate = microtime(true);
|
||||
$this->initEntity();
|
||||
Server::getInstance()->getPluginManager()->callEvent(new EntitySpawnEvent($this));
|
||||
}
|
||||
|
||||
public function saveNBT(){
|
||||
$this->namedtag["Pos"][0] = $this->x;
|
||||
$this->namedtag["Pos"][1] = $this->y;
|
||||
$this->namedtag["Pos"][2] = $this->z;
|
||||
|
||||
$this->namedtag["Motion"][0] = $this->motionX;
|
||||
$this->namedtag["Motion"][1] = $this->motionY;
|
||||
$this->namedtag["Motion"][2] = $this->motionZ;
|
||||
|
||||
$this->namedtag["Rotation"][0] = $this->yaw;
|
||||
$this->namedtag["Rotation"][1] = $this->pitch;
|
||||
|
||||
$this->namedtag["FallDistance"] = $this->fallDistance;
|
||||
$this->namedtag["Fire"] = $this->fireTicks;
|
||||
$this->namedtag["Air"] = $this->airTicks;
|
||||
$this->namedtag["OnGround"] = $this->onGround == true ? 1 : 0;
|
||||
$this->namedtag["Invulnerable"] = $this->invulnerable == true ? 1 : 0;
|
||||
}
|
||||
|
||||
protected abstract function initEntity();
|
||||
|
||||
public function spawnTo(Player $player){
|
||||
if(!isset($this->hasSpawned[$player->getID()]) and $player->chunksLoaded[$this->chunkIndex] !== 0xff){
|
||||
$this->hasSpawned[$player->getID()] = $player;
|
||||
}
|
||||
}
|
||||
|
||||
public function despawnFrom(Player $player){
|
||||
if(isset($this->hasSpawned[$player->getID()])){
|
||||
$pk = new RemoveEntityPacket;
|
||||
$pk->eid = $this->id;
|
||||
$player->dataPacket($pk);
|
||||
unset($this->hasSpawned[$player->getID()]);
|
||||
}
|
||||
}
|
||||
|
||||
abstract function attack($damage, $source = "generic");
|
||||
|
||||
abstract function heal($amount, $source = "generic");
|
||||
|
||||
public function onUpdate(){
|
||||
if($this->closed !== false){
|
||||
return false;
|
||||
}
|
||||
|
||||
$timeNow = microtime(true);
|
||||
$this->ticksLived += ($timeNow - $this->lastUpdate) * 20;
|
||||
|
||||
if($this->handleWaterMovement()){
|
||||
$this->fallDistance = 0;
|
||||
$this->inWater = true;
|
||||
$this->extinguish();
|
||||
}else{
|
||||
$this->inWater = false;
|
||||
}
|
||||
|
||||
if($this->fireTicks > 0){
|
||||
if($this->fireProof === true){
|
||||
$this->fireTicks -= 4;
|
||||
if($this->fireTicks < 0){
|
||||
$this->fireTicks = 0;
|
||||
}
|
||||
}else{
|
||||
if(($this->fireTicks % 20) === 0){
|
||||
$this->attackEntity(1, "onFire");
|
||||
}
|
||||
--$this->fireTicks;
|
||||
}
|
||||
}
|
||||
|
||||
if($this->handleLavaMovement()){
|
||||
$this->attackEntity(4, "lava");
|
||||
$this->setOnFire(15);
|
||||
$this->fallDistance *= 0.5;
|
||||
}
|
||||
|
||||
if($this->y < -64){
|
||||
$this->kill();
|
||||
}
|
||||
|
||||
if($this->x !== $this->lastX or $this->y !== $this->lastY or $this->z !== $this->lastZ or $this->yaw !== $this->lastYaw or $this->pitch !== $this->lastPitch){
|
||||
$this->lastX = $this->x;
|
||||
$this->lastY = $this->y;
|
||||
$this->lastZ = $this->z;
|
||||
|
||||
$this->lastYaw = $this->yaw;
|
||||
$this->lastPitch = $this->pitch;
|
||||
|
||||
if($this instanceof Human){
|
||||
$pk = new MovePlayerPacket;
|
||||
$pk->eid = $this->id;
|
||||
$pk->x = $this->x;
|
||||
$pk->y = $this->y;
|
||||
$pk->z = $this->z;
|
||||
$pk->yaw = $this->yaw;
|
||||
$pk->pitch = $this->pitch;
|
||||
$pk->bodyYaw = $this->yaw;
|
||||
}else{
|
||||
$pk = new MoveEntityPacket_PosRot;
|
||||
$pk->eid = $this->id;
|
||||
$pk->x = $this->x;
|
||||
$pk->y = $this->y;
|
||||
$pk->z = $this->z;
|
||||
$pk->yaw = $this->yaw;
|
||||
$pk->pitch = $this->pitch;
|
||||
}
|
||||
Player::broadcastPacket($this->hasSpawned, $pk);
|
||||
}
|
||||
|
||||
if($this->motionChanged === true){
|
||||
$this->motionChanged = false;
|
||||
|
||||
$pk = new SetEntityMotionPacket;
|
||||
$pk->eid = $this->id;
|
||||
$pk->speedX = $this->motionX;
|
||||
$pk->speedY = $this->motionY;
|
||||
$pk->speedZ = $this->motionZ;
|
||||
Player::broadcastPacket($this->hasSpawned, $pk);
|
||||
}
|
||||
|
||||
$this->lastUpdate = $timeNow;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public final function scheduleUpdate(){
|
||||
Entity::$needUpdate[$this->id] = $this;
|
||||
}
|
||||
|
||||
public abstract function getMetadata();
|
||||
|
||||
public function setOnFire($seconds){
|
||||
$ticks = $seconds * 20;
|
||||
if($ticks > $this->fireTicks){
|
||||
$this->fireTicks = $ticks;
|
||||
}
|
||||
}
|
||||
|
||||
public function getDirection(){
|
||||
$rotation = ($this->yaw - 90) % 360;
|
||||
if($rotation < 0){
|
||||
$rotation += 360.0;
|
||||
}
|
||||
if((0 <= $rotation and $rotation < 45) or (315 <= $rotation and $rotation < 360)){
|
||||
return 2; //North
|
||||
}elseif(45 <= $rotation and $rotation < 135){
|
||||
return 3; //East
|
||||
}elseif(135 <= $rotation and $rotation < 225){
|
||||
return 0; //South
|
||||
}elseif(225 <= $rotation and $rotation < 315){
|
||||
return 1; //West
|
||||
}else{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function extinguish(){
|
||||
$this->fireTicks = 0;
|
||||
}
|
||||
|
||||
public function canTriggerWalking(){
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function updateFallState($distanceThisTick, $onGround){
|
||||
if($onGround === true){
|
||||
if($this->fallDistance > 0){
|
||||
if($this instanceof Living){
|
||||
//TODO
|
||||
}
|
||||
|
||||
$this->fall($this->fallDistance);
|
||||
$this->fallDistance = 0;
|
||||
}
|
||||
}elseif($distanceThisTick < 0){
|
||||
$this->fallDistance -= $distanceThisTick;
|
||||
}
|
||||
}
|
||||
|
||||
public function getBoundingBox(){
|
||||
return $this->boundingBox;
|
||||
}
|
||||
|
||||
public function fall($fallDistance){ //TODO
|
||||
|
||||
}
|
||||
|
||||
public function handleWaterMovement(){ //TODO
|
||||
|
||||
}
|
||||
|
||||
public function handleLavaMovement(){ //TODO
|
||||
|
||||
}
|
||||
|
||||
public function getEyeHeight(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function moveFlying(){ //TODO
|
||||
|
||||
}
|
||||
|
||||
public function onCollideWithPlayer(Human $entityPlayer){
|
||||
|
||||
}
|
||||
|
||||
protected function switchLevel(Level $targetLevel){
|
||||
if($this->level instanceof Level){
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new EntityLevelChangeEvent($this, $this->level, $targetLevel));
|
||||
if($ev->isCancelled()){
|
||||
return false;
|
||||
}
|
||||
unset($this->level->entities[$this->id]);
|
||||
unset($this->level->chunkEntities[$this->chunkIndex][$this->id]);
|
||||
$this->despawnFromAll();
|
||||
if($this instanceof Player){
|
||||
foreach($this->chunksLoaded as $index => $Yndex){
|
||||
if($Yndex !== 0xff){
|
||||
$X = null;
|
||||
$Z = null;
|
||||
LevelFormat::getXZ($index, $X, $Z);
|
||||
foreach($this->level->getChunkEntities($X, $Z) as $entity){
|
||||
$entity->despawnFrom($this);
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->level->freeAllChunks($this);
|
||||
}
|
||||
}
|
||||
$this->level = $targetLevel;
|
||||
$this->level->entities[$this->id] = $this;
|
||||
if($this instanceof Player){
|
||||
$this->chunksLoaded = array();
|
||||
$pk = new SetTimePacket();
|
||||
$pk->time = $this->level->getTime();
|
||||
$pk->started = $this->level->stopTime == false;
|
||||
$this->dataPacket($pk);
|
||||
}
|
||||
$this->spawnToAll();
|
||||
$this->chunkIndex = false;
|
||||
}
|
||||
|
||||
public function getPosition(){
|
||||
return new Position($this->x, $this->y, $this->z, $this->level);
|
||||
}
|
||||
|
||||
public function move(Vector3 $displacement){
|
||||
if($displacement->x == 0 and $displacement->y == 0 and $displacement->z == 0){
|
||||
return;
|
||||
}
|
||||
|
||||
$x = $this->x;
|
||||
$y = $this->y;
|
||||
$z = $this->z;
|
||||
$this->scheduleUpdate();
|
||||
}
|
||||
|
||||
public function setPositionAndRotation(Vector3 $pos, $yaw, $pitch){
|
||||
if($this->setPosition($pos) === true){
|
||||
$this->setRotation($yaw, $pitch);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function setRotation($yaw, $pitch){
|
||||
$this->yaw = $yaw;
|
||||
$this->pitch = $pitch;
|
||||
$this->scheduleUpdate();
|
||||
}
|
||||
|
||||
public function setPosition(Vector3 $pos){
|
||||
if($pos instanceof Position and $pos->level instanceof Level and $pos->level !== $this->level){
|
||||
if($this->switchLevel($pos->level) === false){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new EntityMoveEvent($this, $pos));
|
||||
if($ev->isCancelled()){
|
||||
return false;
|
||||
}
|
||||
$this->x = $pos->x;
|
||||
$this->y = $pos->y;
|
||||
$this->z = $pos->z;
|
||||
|
||||
$radius = $this->width / 2;
|
||||
if(($index = LevelFormat::getIndex($this->x >> 4, $this->z >> 4)) !== $this->chunkIndex){
|
||||
if($this->chunkIndex !== false){
|
||||
unset($this->level->chunkEntities[$this->chunkIndex][$this->id]);
|
||||
}
|
||||
$this->chunkIndex = $index;
|
||||
$this->level->loadChunk($this->x >> 4, $this->z >> 4);
|
||||
|
||||
$newChunk = $this->level->getUsingChunk($this->x >> 4, $this->z >> 4);
|
||||
foreach($this->hasSpawned as $player){
|
||||
if(!isset($newChunk[$player->CID])){
|
||||
$this->despawnFrom($player);
|
||||
}else{
|
||||
unset($newChunk[$player->CID]);
|
||||
}
|
||||
}
|
||||
foreach($newChunk as $player){
|
||||
$this->spawnTo($player);
|
||||
}
|
||||
|
||||
$this->level->chunkEntities[$this->chunkIndex][$this->id] = $this;
|
||||
}
|
||||
$this->boundingBox->setBounds($pos->x - $radius, $pos->y, $pos->z - $radius, $pos->x + $radius, $pos->y + $this->height, $pos->z + $radius);
|
||||
|
||||
$this->scheduleUpdate();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getMotion(){
|
||||
return new Vector3($this->motionX, $this->motionY, $this->motionZ);
|
||||
}
|
||||
|
||||
public function setMotion(Vector3 $motion){
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new EntityMotionEvent($this, $motion));
|
||||
if($ev->isCancelled()){
|
||||
return false;
|
||||
}
|
||||
$this->motionX = $motion->x;
|
||||
$this->motionY = $motion->y;
|
||||
$this->motionZ = $motion->z;
|
||||
$this->scheduleUpdate();
|
||||
}
|
||||
|
||||
public function isOnGround(){
|
||||
return $this->onGround === true;
|
||||
}
|
||||
|
||||
public function kill(){
|
||||
$this->dead = true;
|
||||
}
|
||||
|
||||
public function getLevel(){
|
||||
return $this->level;
|
||||
}
|
||||
|
||||
public function teleport(Vector3 $pos, $yaw = false, $pitch = false){
|
||||
$this->setMotion(new Vector3(0, 0, 0));
|
||||
if($this->setPositionAndRotation($pos, $yaw === false ? $this->yaw : $yaw, $pitch === false ? $this->pitch : $pitch) !== false){
|
||||
if($this instanceof Player){
|
||||
$this->airTicks = 300;
|
||||
$this->fallDistance = 0;
|
||||
$this->orderChunks();
|
||||
$this->getNextChunk(true);
|
||||
$this->forceMovement = $pos;
|
||||
|
||||
$pk = new MovePlayerPacket;
|
||||
$pk->eid = 0;
|
||||
$pk->x = $this->x;
|
||||
$pk->y = $this->y;
|
||||
$pk->z = $this->z;
|
||||
$pk->bodyYaw = $this->yaw;
|
||||
$pk->pitch = $this->pitch;
|
||||
$pk->yaw = $this->yaw;
|
||||
$this->dataPacket($pk);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getID(){
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function spawnToAll(){
|
||||
foreach($this->level->getPlayers() as $player){
|
||||
if(isset($player->id) and $player->spawned === true){
|
||||
$this->spawnTo($player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function despawnFromAll(){
|
||||
foreach($this->hasSpawned as $player){
|
||||
$this->despawnFrom($player);
|
||||
}
|
||||
}
|
||||
|
||||
public function close(){
|
||||
if($this->closed === false){
|
||||
$this->closed = true;
|
||||
unset(Entity::$needUpdate[$this->id]);
|
||||
unset($this->level->entities[$this->id]);
|
||||
unset($this->level->chunkEntities[$this->chunkIndex][$this->id]);
|
||||
unset(Entity::$list[$this->id]);
|
||||
$this->despawnFromAll();
|
||||
Server::getInstance()->getPluginManager()->callEvent(new EntityDespawnEvent($this));
|
||||
}
|
||||
}
|
||||
|
||||
public function __destruct(){
|
||||
$this->close();
|
||||
}
|
||||
|
||||
}
|
@ -1,413 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\entity;
|
||||
|
||||
use pocketmine\event\entity\EntityArmorChangeEvent;
|
||||
use pocketmine\event\entity\EntityInventoryChangeEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\nbt\NBT;
|
||||
use pocketmine\nbt\tag\Byte;
|
||||
use pocketmine\nbt\tag\Compound;
|
||||
use pocketmine\nbt\tag\Enum;
|
||||
use pocketmine\nbt\tag\Short;
|
||||
use pocketmine\network\protocol\AddPlayerPacket;
|
||||
use pocketmine\network\protocol\ContainerSetContentPacket;
|
||||
use pocketmine\network\protocol\PlayerArmorEquipmentPacket;
|
||||
use pocketmine\network\protocol\PlayerEquipmentPacket;
|
||||
use pocketmine\network\protocol\RemovePlayerPacket;
|
||||
use pocketmine\network\protocol\SetEntityMotionPacket;
|
||||
use pocketmine\Network;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
|
||||
class Human extends Creature implements ProjectileSource, InventorySource{
|
||||
|
||||
protected $nameTag = "TESTIFICATE";
|
||||
protected $inventory = array();
|
||||
public $slot;
|
||||
protected $hotbar = array();
|
||||
protected $armor = array();
|
||||
|
||||
protected function initEntity(){
|
||||
if(isset($this->namedtag->NameTag)){
|
||||
$this->nameTag = $this->namedtag["NameTag"];
|
||||
}
|
||||
$this->hotbar = array(-1, -1, -1, -1, -1, -1, -1, -1, -1);
|
||||
$this->armor = array(
|
||||
0 => Item::get(Item::AIR, 0, 0),
|
||||
1 => Item::get(Item::AIR, 0, 0),
|
||||
2 => Item::get(Item::AIR, 0, 0),
|
||||
3 => Item::get(Item::AIR, 0, 0)
|
||||
);
|
||||
|
||||
foreach($this->namedtag->Inventory as $item){
|
||||
if($item["Slot"] >= 0 and $item["Slot"] < 9){ //Hotbar
|
||||
$this->hotbar[$item["Slot"]] = isset($item["TrueSlot"]) ? $item["TrueSlot"] : -1;
|
||||
}elseif($item["Slot"] >= 100 and $item["Slot"] < 104){ //Armor
|
||||
$this->armor[$item["Slot"] - 100] = Item::get($item["id"], $item["Damage"], $item["Count"]);
|
||||
}else{
|
||||
$this->inventory[$item["Slot"] - 9] = Item::get($item["id"], $item["Damage"], $item["Count"]);
|
||||
}
|
||||
}
|
||||
$this->slot = $this->hotbar[0];
|
||||
|
||||
$this->height = 1.8; //Or 1.62?
|
||||
$this->width = 0.6;
|
||||
}
|
||||
|
||||
public function saveNBT(){
|
||||
parent::saveNBT();
|
||||
$this->namedtag->Inventory = new Enum("Inventory", array());
|
||||
$this->namedtag->Inventory->setTagType(NBT::TAG_Compound);
|
||||
for($slot = 0; $slot < 9; ++$slot){
|
||||
if(isset($this->hotbar[$slot]) and $this->hotbar[$slot] !== -1){
|
||||
$item = $this->getSlot($this->hotbar[$slot]);
|
||||
if($item->getID() !== 0 and $item->getCount() > 0){
|
||||
$this->namedtag->Inventory[$slot] = new Compound(false, array(
|
||||
new Byte("Count", $item->getCount()),
|
||||
new Short("Damage", $item->getMetadata()),
|
||||
new Byte("Slot", $slot),
|
||||
new Byte("TrueSlot", $this->hotbar[$slot]),
|
||||
new Short("id", $item->getID()),
|
||||
));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$this->namedtag->Inventory[$slot] = new Compound(false, array(
|
||||
new Byte("Count", 0),
|
||||
new Short("Damage", 0),
|
||||
new Byte("Slot", $slot),
|
||||
new Byte("TrueSlot", -1),
|
||||
new Short("id", 0),
|
||||
));
|
||||
}
|
||||
|
||||
//Normal inventory
|
||||
$slotCount = Player::SURVIVAL_SLOTS + 9;
|
||||
//$slotCount = (($this instanceof Player and ($this->gamemode & 0x01) === 1) ? Player::CREATIVE_SLOTS : Player::SURVIVAL_SLOTS) + 9;
|
||||
for($slot = 9; $slot < $slotCount; ++$slot){
|
||||
$item = $this->getSlot($slot - 9);
|
||||
$this->namedtag->Inventory[$slot] = new Compound(false, array(
|
||||
new Byte("Count", $item->getCount()),
|
||||
new Short("Damage", $item->getMetadata()),
|
||||
new Byte("Slot", $slot),
|
||||
new Short("id", $item->getID()),
|
||||
));
|
||||
}
|
||||
|
||||
//Armor
|
||||
for($slot = 100; $slot < 104; ++$slot){
|
||||
$item = $this->armor[$slot - 100];
|
||||
if($item instanceof Item){
|
||||
$this->namedtag->Inventory[$slot] = new Compound(false, array(
|
||||
new Byte("Count", $item->getCount()),
|
||||
new Short("Damage", $item->getMetadata()),
|
||||
new Byte("Slot", $slot),
|
||||
new Short("id", $item->getID()),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function spawnTo(Player $player){
|
||||
if($player !== $this and !isset($this->hasSpawned[$player->getID()])){
|
||||
$this->hasSpawned[$player->getID()] = $player;
|
||||
|
||||
$pk = new AddPlayerPacket;
|
||||
$pk->clientID = 0;
|
||||
$pk->username = $this->nameTag;
|
||||
$pk->eid = $this->id;
|
||||
$pk->x = $this->x;
|
||||
$pk->y = $this->y;
|
||||
$pk->z = $this->z;
|
||||
$pk->yaw = 0;
|
||||
$pk->pitch = 0;
|
||||
$pk->unknown1 = 0;
|
||||
$pk->unknown2 = 0;
|
||||
$pk->metadata = $this->getMetadata();
|
||||
$player->dataPacket($pk);
|
||||
|
||||
$pk = new SetEntityMotionPacket;
|
||||
$pk->eid = $this->id;
|
||||
$pk->speedX = $this->motionX;
|
||||
$pk->speedY = $this->motionY;
|
||||
$pk->speedZ = $this->motionZ;
|
||||
$player->dataPacket($pk);
|
||||
|
||||
$this->sendCurrentEquipmentSlot($player);
|
||||
|
||||
$this->sendArmor($player);
|
||||
}
|
||||
}
|
||||
|
||||
public function despawnFrom(Player $player){
|
||||
if(isset($this->hasSpawned[$player->getID()])){
|
||||
$pk = new RemovePlayerPacket;
|
||||
$pk->eid = $this->id;
|
||||
$pk->clientID = 0;
|
||||
$player->dataPacket($pk);
|
||||
unset($this->hasSpawned[$player->getID()]);
|
||||
}
|
||||
}
|
||||
|
||||
public function setEquipmentSlot($equipmentSlot, $inventorySlot){
|
||||
$this->hotbar[$equipmentSlot] = $inventorySlot;
|
||||
if($equipmentSlot === $this->slot){
|
||||
foreach($this->hasSpawned as $p){
|
||||
$this->sendEquipmentSlot($p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function setCurrentEquipmentSlot($slot){
|
||||
if(isset($this->hotbar[$slot])){
|
||||
$this->slot = (int) $slot;
|
||||
foreach($this->hasSpawned as $p){
|
||||
$this->sendEquipmentSlot($p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function sendCurrentEquipmentSlot(Player $player){
|
||||
$pk = new PlayerEquipmentPacket;
|
||||
$pk->eid = $this->id;
|
||||
$pk->item = $this->getSlot($this->slot)->getID();
|
||||
$pk->meta = $this->getSlot($this->slot)->getMetadata();
|
||||
$pk->slot = 0;
|
||||
$player->dataPacket($pk);
|
||||
}
|
||||
|
||||
public function setArmorSlot($slot, Item $item){
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new EntityArmorChangeEvent($this, $this->getArmorSlot($slot), $item, $slot));
|
||||
if($ev->isCancelled()){
|
||||
return false;
|
||||
}
|
||||
$this->armor[(int) $slot] = $ev->getNewItem();
|
||||
foreach($this->hasSpawned as $p){
|
||||
$this->sendArmor($p);
|
||||
}
|
||||
if($this instanceof Player){
|
||||
$this->sendArmor();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getArmorSlot($slot){
|
||||
$slot = (int) $slot;
|
||||
if(!isset($this->armor[$slot])){
|
||||
$this->armor[$slot] = Item::get(Item::AIR, 0, 0);
|
||||
}
|
||||
|
||||
return $this->armor[$slot];
|
||||
}
|
||||
|
||||
public function sendArmor($player = null){
|
||||
$slots = array();
|
||||
for($i = 0; $i < 4; ++$i){
|
||||
if(isset($this->armor[$i]) and ($this->armor[$i] instanceof Item) and $this->armor[$i]->getID() > Item::AIR){
|
||||
$slots[$i] = $this->armor[$i]->getID() !== Item::AIR ? $this->armor[$i]->getID() - 256 : 0;
|
||||
}else{
|
||||
$this->armor[$i] = Item::get(Item::AIR, 0, 0);
|
||||
$slots[$i] = 255;
|
||||
}
|
||||
}
|
||||
if($player instanceof Player){
|
||||
$pk = new PlayerArmorEquipmentPacket();
|
||||
$pk->eid = $this->id;
|
||||
$pk->slots = $slots;
|
||||
$player->dataPacket($pk);
|
||||
}elseif($this instanceof Player){
|
||||
$pk = new ContainerSetContentPacket;
|
||||
$pk->windowid = 0x78; //Armor window id
|
||||
$pk->slots = $this->armor;
|
||||
$this->dataPacket($pk);
|
||||
}
|
||||
}
|
||||
|
||||
public function getMetadata(){ //TODO
|
||||
$flags = 0;
|
||||
$flags |= $this->fireTicks > 0 ? 1 : 0;
|
||||
//$flags |= ($this->crouched === true ? 0b10:0) << 1;
|
||||
//$flags |= ($this->inAction === true ? 0b10000:0);
|
||||
$d = array(
|
||||
0 => array("type" => 0, "value" => $flags),
|
||||
1 => array("type" => 1, "value" => $this->airTicks),
|
||||
16 => array("type" => 0, "value" => 0),
|
||||
17 => array("type" => 6, "value" => array(0, 0, 0)),
|
||||
);
|
||||
|
||||
/*if($this->class === ENTITY_MOB and $this->type === MOB_SHEEP){
|
||||
if(!isset($this->data["Sheared"])){
|
||||
$this->data["Sheared"] = 0;
|
||||
$this->data["Color"] = mt_rand(0,15);
|
||||
}
|
||||
$d[16]["value"] = (($this->data["Sheared"] == 1 ? 1:0) << 4) | ($this->data["Color"] & 0x0F);
|
||||
}elseif($this->type === OBJECT_PRIMEDTNT){
|
||||
$d[16]["value"] = (int) max(0, $this->data["fuse"] - (microtime(true) - $this->spawntime) * 20);
|
||||
}elseif($this->class === ENTITY_PLAYER){
|
||||
if($this->player->sleeping !== false){
|
||||
$d[16]["value"] = 2;
|
||||
$d[17]["value"] = array($this->player->sleeping->x, $this->player->sleeping->y, $this->player->sleeping->z);
|
||||
}
|
||||
}*/
|
||||
|
||||
return $d;
|
||||
}
|
||||
|
||||
public function attack($damage, $source = "generic"){
|
||||
|
||||
}
|
||||
|
||||
public function heal($amount, $source = "generic"){
|
||||
|
||||
}
|
||||
|
||||
public function hasItem(Item $item, $checkDamage = true){
|
||||
foreach($this->inventory as $s => $i){
|
||||
if($i->equals($item, $checkDamage)){
|
||||
return $i;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function canAddItem(Item $item){
|
||||
$inv = $this->inventory;
|
||||
while($item->getCount() > 0){
|
||||
$add = 0;
|
||||
foreach($inv as $s => $i){
|
||||
if($i->getID() === Item::AIR){
|
||||
$add = min($i->getMaxStackSize(), $item->getCount());
|
||||
$inv[$s] = clone $item;
|
||||
$inv[$s]->setCount($add);
|
||||
break;
|
||||
}elseif($i->equals($item)){
|
||||
$add = min($i->getMaxStackSize() - $i->getCount(), $item->getCount());
|
||||
if($add <= 0){
|
||||
continue;
|
||||
}
|
||||
$inv[$s] = clone $item;
|
||||
$inv[$s]->setCount($i->getCount() + $add);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if($add <= 0){
|
||||
return false;
|
||||
}
|
||||
$item->setCount($item->getCount() - $add);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function addItem(Item $item){
|
||||
while($item->getCount() > 0){
|
||||
$add = 0;
|
||||
foreach($this->inventory as $s => $i){
|
||||
if($i->getID() === Item::AIR){
|
||||
$add = min($i->getMaxStackSize(), $item->getCount());
|
||||
$i2 = clone $item;
|
||||
$i2->setCount($add);
|
||||
$this->setSlot($s, $i2);
|
||||
break;
|
||||
}elseif($i->equals($item)){
|
||||
$add = min($i->getMaxStackSize() - $i->getCount(), $item->getCount());
|
||||
if($add <= 0){
|
||||
continue;
|
||||
}
|
||||
$i2 = clone $item;
|
||||
$i2->setCount($i->getCount() + $add);
|
||||
$this->setSlot($s, $i2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if($add <= 0){
|
||||
return false;
|
||||
}
|
||||
$item->setCount($item->getCount() - $add);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function canRemoveItem(Item $item, $checkDamage = true){
|
||||
return $this->hasItem($item, $checkDamage);
|
||||
}
|
||||
|
||||
public function removeItem(Item $item, $checkDamage = true){
|
||||
while($item->getCount() > 0){
|
||||
$remove = 0;
|
||||
foreach($this->inventory as $s => $i){
|
||||
if($i->equals($item, $checkDamage)){
|
||||
$remove = min($item->getCount(), $i->getCount());
|
||||
if($item->getCount() < $i->getCount()){
|
||||
$i->setCount($i->getCount() - $item->getCount());
|
||||
$this->setSlot($s, $i);
|
||||
}else{
|
||||
$this->setSlot($s, Item::get(Item::AIR, 0, 0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if($remove <= 0){
|
||||
return false;
|
||||
}
|
||||
$item->setCount($item->getCount() - $remove);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function setSlot($slot, Item $item){
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new EntityInventoryChangeEvent($this, $this->getSlot($slot), $item, $slot));
|
||||
if($ev->isCancelled()){
|
||||
return false;
|
||||
}
|
||||
$this->inventory[(int) $slot] = $ev->getNewItem();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $slot
|
||||
*
|
||||
* @return Item
|
||||
*/
|
||||
public function getSlot($slot){
|
||||
$slot = (int) $slot;
|
||||
if(!isset($this->inventory[$slot])){
|
||||
$this->inventory[$slot] = Item::get(Item::AIR, 0, 0);
|
||||
}
|
||||
|
||||
return $this->inventory[$slot];
|
||||
}
|
||||
|
||||
public function getAllSlots(){
|
||||
return $this->inventory;
|
||||
}
|
||||
|
||||
public function getSlotCount(){
|
||||
return count($this->inventory);
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\entity;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
|
||||
interface InventorySource{
|
||||
|
||||
public function hasItem(Item $item, $checkDamage = true);
|
||||
|
||||
public function canAddItem(Item $item);
|
||||
|
||||
/**
|
||||
* @param Item $item
|
||||
*
|
||||
* @return boolean hasBeenAdded
|
||||
*/
|
||||
public function addItem(Item $item);
|
||||
|
||||
public function canRemoveItem(Item $item, $checkDamage = true);
|
||||
|
||||
/**
|
||||
* @param Item $item
|
||||
* @param boolean $checkDamage
|
||||
*
|
||||
* @return boolean hasBeenRemoved
|
||||
*/
|
||||
public function removeItem(Item $item, $checkDamage = true);
|
||||
|
||||
public function getSlotCount();
|
||||
|
||||
public function getAllSlots();
|
||||
|
||||
public function getSlot($slot);
|
||||
|
||||
public function setSlot($slot, Item $item);
|
||||
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,78 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\level;
|
||||
|
||||
use pocketmine\math\Vector3 as Vector3;
|
||||
|
||||
class Position extends Vector3{
|
||||
|
||||
/** @var Level */
|
||||
public $level = null;
|
||||
|
||||
/**
|
||||
* @param int $x
|
||||
* @param int $y
|
||||
* @param int $z
|
||||
* @param Level $level
|
||||
*/
|
||||
public function __construct($x = 0, $y = 0, $z = 0, Level $level){
|
||||
$this->x = $x;
|
||||
$this->y = $y;
|
||||
$this->z = $z;
|
||||
$this->level = $level;
|
||||
}
|
||||
|
||||
public static function fromObject(Vector3 $pos, Level $level){
|
||||
return new Position($pos->x, $pos->y, $pos->z, $level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a side Vector
|
||||
*
|
||||
* @param $side
|
||||
*
|
||||
* @return Position
|
||||
*/
|
||||
public function getSide($side){
|
||||
return Position::fromObject(parent::getSide($side), $this->level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the distance between two points or objects
|
||||
*
|
||||
* @param Vector3 $pos
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function distance(Vector3 $pos){
|
||||
if(($pos instanceof Position) and $pos->level !== $this->level){
|
||||
return PHP_INT_MAX;
|
||||
}
|
||||
|
||||
return parent::distance($pos);
|
||||
}
|
||||
|
||||
public function __toString(){
|
||||
return "Position(level=" . $this->level->getName() . ",x=" . $this->x . ",y=" . $this->y . ",z=" . $this->z . ")";
|
||||
}
|
||||
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\level;
|
||||
|
||||
use pocketmine\level\generator\Generator;
|
||||
use pocketmine\pmf\LevelFormat;
|
||||
use pocketmine\utils\Config;
|
||||
use pocketmine\utils\Random;
|
||||
use pocketmine\utils\Utils;
|
||||
|
||||
class WorldGenerator{
|
||||
private $seed, $level, $path, $random, $generator, $height;
|
||||
|
||||
public function __construct(Generator $generator, $name, $seed = false, $height = 8){
|
||||
$this->seed = $seed !== false ? (int) $seed : Utils::readInt(Utils::getRandomBytes(4, false));
|
||||
$this->random = new Random($this->seed);
|
||||
$this->height = (int) $height;
|
||||
$this->path = \pocketmine\DATA . "worlds/" . $name . "/";
|
||||
$this->generator = $generator;
|
||||
$level = new LevelFormat($this->path . "level.pmf", array(
|
||||
"name" => $name,
|
||||
"seed" => $this->seed,
|
||||
"time" => 0,
|
||||
"spawnX" => 128,
|
||||
"spawnY" => 128,
|
||||
"spawnZ" => 128,
|
||||
"height" => $this->height,
|
||||
"generator" => $this->generator->getName(),
|
||||
"generatorSettings" => $this->generator->getSettings(),
|
||||
"extra" => ""
|
||||
));
|
||||
$blockUpdates = new Config($this->path . "bupdates.yml", Config::YAML);
|
||||
$this->level = new Level($level, $name);
|
||||
}
|
||||
|
||||
public function generate(){
|
||||
$this->generator->init($this->level, $this->random);
|
||||
|
||||
for($Z = 7; $Z <= 9; ++$Z){
|
||||
for($X = 7; $X <= 9; ++$X){
|
||||
$this->level->level->loadChunk($X, $Z);
|
||||
}
|
||||
}
|
||||
|
||||
$this->level->setSpawn($this->generator->getSpawn());
|
||||
}
|
||||
|
||||
public function close(){
|
||||
$this->level->close();
|
||||
}
|
||||
|
||||
}
|
@ -1,187 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Network-related classes
|
||||
*/
|
||||
namespace pocketmine\network;
|
||||
|
||||
use pocketmine\network\query\QueryPacket;
|
||||
use pocketmine\network\raknet\Info;
|
||||
use pocketmine\network\raknet\Packet as RakNetPacket;
|
||||
|
||||
class ThreadedHandler extends \Thread{
|
||||
protected $bandwidthUp;
|
||||
protected $bandwidthDown;
|
||||
protected $bandwidthTime;
|
||||
private $socket;
|
||||
protected $packets;
|
||||
protected $queue;
|
||||
protected $stop;
|
||||
protected $server;
|
||||
protected $port;
|
||||
protected $serverip;
|
||||
|
||||
function __construct($server, $port = 19132, $serverip = "0.0.0.0"){
|
||||
$this->server = $server;
|
||||
$this->port = $port;
|
||||
$this->serverip = $serverip;
|
||||
$this->bandwidthUp = 0;
|
||||
$this->bandwidthDown = 0;
|
||||
$this->bandwidthTime = microtime(true);
|
||||
$this->packets = new \Threaded();
|
||||
$this->queue = new \Threaded();
|
||||
$this->stop = false;
|
||||
|
||||
//Load the classes so the Thread gets them
|
||||
Info::isValid(0);
|
||||
new Packet(0);
|
||||
new QueryPacket();
|
||||
new RakNetPacket(0);
|
||||
|
||||
$this->start(PTHREADS_INHERIT_ALL);
|
||||
}
|
||||
|
||||
public function close(){
|
||||
$this->synchronized(function (){
|
||||
$this->stop = true;
|
||||
socket_close($this->socket);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload speed in bytes/s
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getUploadSpeed(){
|
||||
return $this->bandwidthUp / max(1, microtime(true) - $this->bandwidthTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Download speed in bytes/s
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getDownloadSpeed(){
|
||||
return $this->bandwidthDown / max(1, microtime(true) - $this->bandwidthTime);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Packet
|
||||
*/
|
||||
public function readPacket(){
|
||||
return $this->packets->shift();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Packet $packet
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function writePacket(Packet $packet){
|
||||
$this->queue[] = $packet;
|
||||
|
||||
return strlen($packet->buffer);
|
||||
}
|
||||
|
||||
public function run(){
|
||||
$autoloader = new \SplClassLoader();
|
||||
$autoloader->add("pocketmine", array(
|
||||
\pocketmine\PATH . "src"
|
||||
));
|
||||
$autoloader->register(true);
|
||||
|
||||
$this->socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
|
||||
socket_set_option($this->socket, SOL_SOCKET, SO_BROADCAST, 1); //Allow sending broadcast messages
|
||||
if(@socket_bind($this->socket, $this->serverip, $this->port) === true){
|
||||
socket_set_option($this->socket, SOL_SOCKET, SO_REUSEADDR, 0);
|
||||
@socket_set_option($this->socket, SOL_SOCKET, SO_SNDBUF, 1024 * 1024 * 2); //2MB
|
||||
@socket_set_option($this->socket, SOL_SOCKET, SO_RCVBUF, 1024 * 1024); //1MB
|
||||
}else{
|
||||
console("[SEVERE] **** FAILED TO BIND TO " . $this->serverip . ":" . $this->port . "!", true, true, 0);
|
||||
console("[SEVERE] Perhaps a server is already running on that port?", true, true, 0);
|
||||
exit(1);
|
||||
}
|
||||
socket_set_nonblock($this->socket);
|
||||
|
||||
$count = 0;
|
||||
while($this->stop === false){
|
||||
if($this->getPacket() === false and $this->putPacket() === false){
|
||||
++$count;
|
||||
}else{
|
||||
$count = 0;
|
||||
}
|
||||
if($count > 128){
|
||||
$this->wait(100000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function putPacket(){
|
||||
if(($packet = $this->queue->shift()) instanceof Packet){
|
||||
if($packet instanceof RakNetPacket){
|
||||
$packet->encode();
|
||||
}
|
||||
$this->bandwidthUp += @socket_sendto($this->socket, $packet->buffer, strlen($packet->buffer), 0, $packet->ip, $packet->port);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function getPacket(){
|
||||
$buffer = null;
|
||||
$source = null;
|
||||
$port = null;
|
||||
$len = @socket_recvfrom($this->socket, $buffer, 65535, 0, $source, $port);
|
||||
if($len === false or $len == 0){
|
||||
return false;
|
||||
}
|
||||
$this->bandwidthDown += $len;
|
||||
$pid = ord($buffer{0});
|
||||
if(Info::isValid($pid)){
|
||||
$packet = new RakNetPacket($pid);
|
||||
$packet->buffer =& $buffer;
|
||||
$packet->ip = $source;
|
||||
$packet->port = $port;
|
||||
$packet->decode();
|
||||
}elseif($pid === 0xfe and $buffer{1} === "\xfd"){
|
||||
$packet = new QueryPacket;
|
||||
$packet->ip = $source;
|
||||
$packet->port = $port;
|
||||
$packet->buffer =& $buffer;
|
||||
}else{
|
||||
$packet = new Packet($pid);
|
||||
$packet->ip = $source;
|
||||
$packet->port = $port;
|
||||
$packet->buffer =& $buffer;
|
||||
}
|
||||
$this->packets[] = $packet;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
@ -1,54 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
|
||||
|
||||
class ClientHandshakePacket extends DataPacket{
|
||||
public $cookie;
|
||||
public $security;
|
||||
public $port;
|
||||
public $dataArray0;
|
||||
public $dataArray;
|
||||
public $timestamp;
|
||||
public $session2;
|
||||
public $session;
|
||||
|
||||
public function pid(){
|
||||
return Info::CLIENT_HANDSHAKE_PACKET;
|
||||
}
|
||||
|
||||
public function decode(){
|
||||
$this->cookie = $this->get(4);
|
||||
$this->security = $this->get(1);
|
||||
$this->port = $this->getShort(true);
|
||||
$this->dataArray0 = $this->get($this->getByte());
|
||||
$this->dataArray = $this->getDataArray(9);
|
||||
$this->timestamp = $this->get(2);
|
||||
$this->session2 = $this->getLong();
|
||||
$this->session = $this->getLong();
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
|
||||
|
||||
class PongPacket extends DataPacket{
|
||||
public $time = 0;
|
||||
public $ptime = 0;
|
||||
|
||||
public function pid(){
|
||||
return Info::PONG_PACKET;
|
||||
}
|
||||
|
||||
public function decode(){
|
||||
$this->ptime = $this->getLong();
|
||||
$this->time = $this->getLong();
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putLong($this->ptime);
|
||||
$this->putLong($this->time);
|
||||
}
|
||||
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
|
||||
|
||||
class ServerHandshakePacket extends DataPacket{
|
||||
public $port;
|
||||
public $session;
|
||||
public $session2;
|
||||
|
||||
public function pid(){
|
||||
return Info::SERVER_HANDSHAKE_PACKET;
|
||||
}
|
||||
|
||||
public function decode(){
|
||||
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->put("\x04\x3f\x57\xfe"); //cookie
|
||||
$this->put("\xcd"); //Security flags
|
||||
$this->putShort($this->port);
|
||||
$this->putDataArray(array(
|
||||
"\xf5\xff\xff\xf5",
|
||||
"\xff\xff\xff\xff",
|
||||
"\xff\xff\xff\xff",
|
||||
"\xff\xff\xff\xff",
|
||||
"\xff\xff\xff\xff",
|
||||
"\xff\xff\xff\xff",
|
||||
"\xff\xff\xff\xff",
|
||||
"\xff\xff\xff\xff",
|
||||
"\xff\xff\xff\xff",
|
||||
"\xff\xff\xff\xff",
|
||||
));
|
||||
$this->put("\x00\x00");
|
||||
$this->putLong($this->session);
|
||||
$this->putLong($this->session2);
|
||||
}
|
||||
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\query;
|
||||
|
||||
use pocketmine\network\Packet;
|
||||
use pocketmine\utils\Utils;
|
||||
|
||||
class QueryPacket extends Packet{
|
||||
const HANDSHAKE = 9;
|
||||
const STATISTICS = 0;
|
||||
|
||||
public $packetType;
|
||||
public $sessionID;
|
||||
public $payload;
|
||||
|
||||
public function decode(){
|
||||
$this->packetType = ord($this->buffer{2});
|
||||
$this->sessionID = Utils::readInt(substr($this->buffer, 3, 4));
|
||||
$this->payload = substr($this->buffer, 7);
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->buffer .= chr($this->packetType);
|
||||
$this->buffer .= Utils::writeInt($this->sessionID);
|
||||
$this->buffer .= $this->payload;
|
||||
}
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* RakNet UDP library implementation
|
||||
*/
|
||||
namespace pocketmine\network\raknet;
|
||||
|
||||
|
||||
abstract class Info{
|
||||
const STRUCTURE = 5;
|
||||
const MAGIC = "\x00\xff\xff\x00\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\x12\x34\x56\x78";
|
||||
const UNCONNECTED_PING = 0x01;
|
||||
const UNCONNECTED_PING_OPEN_CONNECTIONS = 0x02;
|
||||
|
||||
const OPEN_CONNECTION_REQUEST_1 = 0x05;
|
||||
const OPEN_CONNECTION_REPLY_1 = 0x06;
|
||||
const OPEN_CONNECTION_REQUEST_2 = 0x07;
|
||||
const OPEN_CONNECTION_REPLY_2 = 0x08;
|
||||
|
||||
const INCOMPATIBLE_PROTOCOL_VERSION = 0x1a; //CHECK THIS
|
||||
|
||||
const UNCONNECTED_PONG = 0x1c;
|
||||
const ADVERTISE_SYSTEM = 0x1d;
|
||||
|
||||
const DATA_PACKET_0 = 0x80;
|
||||
const DATA_PACKET_1 = 0x81;
|
||||
const DATA_PACKET_2 = 0x82;
|
||||
const DATA_PACKET_3 = 0x83;
|
||||
const DATA_PACKET_4 = 0x84;
|
||||
const DATA_PACKET_5 = 0x85;
|
||||
const DATA_PACKET_6 = 0x86;
|
||||
const DATA_PACKET_7 = 0x87;
|
||||
const DATA_PACKET_8 = 0x88;
|
||||
const DATA_PACKET_9 = 0x89;
|
||||
const DATA_PACKET_A = 0x8a;
|
||||
const DATA_PACKET_B = 0x8b;
|
||||
const DATA_PACKET_C = 0x8c;
|
||||
const DATA_PACKET_D = 0x8d;
|
||||
const DATA_PACKET_E = 0x8e;
|
||||
const DATA_PACKET_F = 0x8f;
|
||||
|
||||
const NACK = 0xa0;
|
||||
const ACK = 0xc0;
|
||||
|
||||
|
||||
public static function isValid($pid){
|
||||
switch((int) $pid){
|
||||
case self::UNCONNECTED_PING:
|
||||
case self::UNCONNECTED_PING_OPEN_CONNECTIONS:
|
||||
case self::OPEN_CONNECTION_REQUEST_1:
|
||||
case self::OPEN_CONNECTION_REPLY_1:
|
||||
case self::OPEN_CONNECTION_REQUEST_2:
|
||||
case self::OPEN_CONNECTION_REPLY_2:
|
||||
case self::INCOMPATIBLE_PROTOCOL_VERSION:
|
||||
case self::UNCONNECTED_PONG:
|
||||
case self::ADVERTISE_SYSTEM:
|
||||
case self::DATA_PACKET_0:
|
||||
case self::DATA_PACKET_1:
|
||||
case self::DATA_PACKET_2:
|
||||
case self::DATA_PACKET_3:
|
||||
case self::DATA_PACKET_4:
|
||||
case self::DATA_PACKET_5:
|
||||
case self::DATA_PACKET_6:
|
||||
case self::DATA_PACKET_7:
|
||||
case self::DATA_PACKET_8:
|
||||
case self::DATA_PACKET_9:
|
||||
case self::DATA_PACKET_A:
|
||||
case self::DATA_PACKET_B:
|
||||
case self::DATA_PACKET_C:
|
||||
case self::DATA_PACKET_D:
|
||||
case self::DATA_PACKET_E:
|
||||
case self::DATA_PACKET_F:
|
||||
case self::NACK:
|
||||
case self::ACK:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,591 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\raknet;
|
||||
|
||||
use pocketmine\network\Packet as NetworkPacket;
|
||||
use pocketmine\network\protocol\AddEntityPacket;
|
||||
use pocketmine\network\protocol\AddItemEntityPacket;
|
||||
use pocketmine\network\protocol\AddMobPacket;
|
||||
use pocketmine\network\protocol\AddPaintingPacket;
|
||||
use pocketmine\network\protocol\AddPlayerPacket;
|
||||
use pocketmine\network\protocol\AdventureSettingsPacket;
|
||||
use pocketmine\network\protocol\AnimatePacket;
|
||||
use pocketmine\network\protocol\ChatPacket;
|
||||
use pocketmine\network\protocol\ChunkDataPacket;
|
||||
use pocketmine\network\protocol\ClientConnectPacket;
|
||||
use pocketmine\network\protocol\ContainerClosePacket;
|
||||
use pocketmine\network\protocol\ContainerOpenPacket;
|
||||
use pocketmine\network\protocol\ContainerSetContentPacket;
|
||||
use pocketmine\network\protocol\ContainerSetDataPacket;
|
||||
use pocketmine\network\protocol\ContainerSetSlotPacket;
|
||||
use pocketmine\network\protocol\DataPacket;
|
||||
use pocketmine\network\protocol\DisconnectPacket;
|
||||
use pocketmine\network\protocol\DropItemPacket;
|
||||
use pocketmine\network\protocol\EntityDataPacket;
|
||||
use pocketmine\network\protocol\EntityEventPacket;
|
||||
use pocketmine\network\protocol\ExplodePacket;
|
||||
use pocketmine\network\protocol\HurtArmorPacket;
|
||||
use pocketmine\network\protocol\Info as ProtocolInfo;
|
||||
use pocketmine\network\protocol\InteractPacket;
|
||||
use pocketmine\network\protocol\LevelEventPacket;
|
||||
use pocketmine\network\protocol\LoginPacket;
|
||||
use pocketmine\network\protocol\LoginStatusPacket;
|
||||
use pocketmine\network\protocol\MessagePacket;
|
||||
use pocketmine\network\protocol\MoveEntityPacket;
|
||||
use pocketmine\network\protocol\MoveEntityPacket_PosRot;
|
||||
use pocketmine\network\protocol\MovePlayerPacket;
|
||||
use pocketmine\network\protocol\PingPacket;
|
||||
use pocketmine\network\protocol\PlayerActionPacket;
|
||||
use pocketmine\network\protocol\PlayerArmorEquipmentPacket;
|
||||
use pocketmine\network\protocol\PlayerEquipmentPacket;
|
||||
use pocketmine\network\protocol\PongPacket;
|
||||
use pocketmine\network\protocol\ReadyPacket;
|
||||
use pocketmine\network\protocol\RemoveBlockPacket;
|
||||
use pocketmine\network\protocol\RemoveEntityPacket;
|
||||
use pocketmine\network\protocol\RemovePlayerPacket;
|
||||
use pocketmine\network\protocol\RequestChunkPacket;
|
||||
use pocketmine\network\protocol\RespawnPacket;
|
||||
use pocketmine\network\protocol\RotateHeadPacket;
|
||||
use pocketmine\network\protocol\SendInventoryPacket;
|
||||
use pocketmine\network\protocol\ServerHandshakePacket;
|
||||
use pocketmine\network\protocol\SetEntityDataPacket;
|
||||
use pocketmine\network\protocol\SetEntityMotionPacket;
|
||||
use pocketmine\network\protocol\SetHealthPacket;
|
||||
use pocketmine\network\protocol\SetSpawnPositionPacket;
|
||||
use pocketmine\network\protocol\SetTimePacket;
|
||||
use pocketmine\network\protocol\StartGamePacket;
|
||||
use pocketmine\network\protocol\TakeItemEntityPacket;
|
||||
use pocketmine\network\protocol\TileEventPacket;
|
||||
use pocketmine\network\protocol\UnknownPacket;
|
||||
use pocketmine\network\protocol\UpdateBlockPacket;
|
||||
use pocketmine\network\protocol\UseItemPacket;
|
||||
use pocketmine\utils\Utils;
|
||||
|
||||
class Packet extends NetworkPacket{
|
||||
private $packetID;
|
||||
private $offset = 1;
|
||||
public $data = array();
|
||||
|
||||
public function __construct($packetID){
|
||||
$this->packetID = (int) $packetID;
|
||||
}
|
||||
|
||||
public function pid(){
|
||||
return $this->packetID;
|
||||
}
|
||||
|
||||
protected function get($len){
|
||||
if($len <= 0){
|
||||
$this->offset = strlen($this->buffer) - 1;
|
||||
|
||||
return "";
|
||||
}elseif($len === true){
|
||||
return substr($this->buffer, $this->offset);
|
||||
}
|
||||
|
||||
$buffer = "";
|
||||
for(; $len > 0; --$len, ++$this->offset){
|
||||
$buffer .= @$this->buffer{$this->offset};
|
||||
}
|
||||
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
private function getLong($unsigned = false){
|
||||
return Utils::readLong($this->get(8), $unsigned);
|
||||
}
|
||||
|
||||
private function getInt(){
|
||||
return Utils::readInt($this->get(4));
|
||||
}
|
||||
|
||||
private function getShort($unsigned = false){
|
||||
return Utils::readShort($this->get(2), $unsigned);
|
||||
}
|
||||
|
||||
private function getLTriad(){
|
||||
return Utils::readTriad(strrev($this->get(3)));
|
||||
}
|
||||
|
||||
private function getByte(){
|
||||
return ord($this->buffer{$this->offset++});
|
||||
}
|
||||
|
||||
private function feof(){
|
||||
return !isset($this->buffer{$this->offset});
|
||||
}
|
||||
|
||||
public function decode(){
|
||||
$this->offset = 1;
|
||||
switch($this->packetID){
|
||||
case Info::UNCONNECTED_PING:
|
||||
case Info::UNCONNECTED_PING_OPEN_CONNECTIONS:
|
||||
$this->pingID = $this->getLong();
|
||||
$this->offset += 16; //Magic
|
||||
break;
|
||||
case Info::OPEN_CONNECTION_REQUEST_1:
|
||||
$this->offset += 16; //Magic
|
||||
$this->structure = $this->getByte();
|
||||
$this->mtuSize = strlen($this->get(true));
|
||||
break;
|
||||
case Info::OPEN_CONNECTION_REQUEST_2:
|
||||
$this->offset += 16; //Magic
|
||||
$this->security = $this->get(5);
|
||||
$this->clientPort = $this->getShort(false);
|
||||
$this->mtuSize = $this->getShort(false);
|
||||
$this->clientID = $this->getLong();
|
||||
break;
|
||||
case Info::DATA_PACKET_0:
|
||||
case Info::DATA_PACKET_1:
|
||||
case Info::DATA_PACKET_2:
|
||||
case Info::DATA_PACKET_3:
|
||||
case Info::DATA_PACKET_4:
|
||||
case Info::DATA_PACKET_5:
|
||||
case Info::DATA_PACKET_6:
|
||||
case Info::DATA_PACKET_7:
|
||||
case Info::DATA_PACKET_8:
|
||||
case Info::DATA_PACKET_9:
|
||||
case Info::DATA_PACKET_A:
|
||||
case Info::DATA_PACKET_B:
|
||||
case Info::DATA_PACKET_C:
|
||||
case Info::DATA_PACKET_D:
|
||||
case Info::DATA_PACKET_E:
|
||||
case Info::DATA_PACKET_F:
|
||||
$this->seqNumber = $this->getLTriad();
|
||||
$this->data = array();
|
||||
while(!$this->feof() and $this->parseDataPacket() !== false){
|
||||
|
||||
}
|
||||
break;
|
||||
case Info::NACK:
|
||||
case Info::ACK:
|
||||
$count = $this->getShort();
|
||||
$this->packets = array();
|
||||
for($i = 0; $i < $count and !$this->feof(); ++$i){
|
||||
if($this->getByte() === 0){
|
||||
$start = $this->getLTriad();
|
||||
$end = $this->getLTriad();
|
||||
if(($end - $start) > 4096){
|
||||
$end = $start + 4096;
|
||||
}
|
||||
for($c = $start; $c <= $end; ++$c){
|
||||
$this->packets[] = $c;
|
||||
}
|
||||
}else{
|
||||
$this->packets[] = $this->getLTriad();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function parseDataPacket(){
|
||||
$packetFlags = $this->getByte();
|
||||
$reliability = ($packetFlags & 0b11100000) >> 5;
|
||||
$hasSplit = ($packetFlags & 0b00010000) > 0;
|
||||
$length = (int) ceil($this->getShort() / 8);
|
||||
if($reliability === 2
|
||||
or $reliability === 3
|
||||
or $reliability === 4
|
||||
or $reliability === 6
|
||||
or $reliability === 7
|
||||
){
|
||||
$messageIndex = $this->getLTriad();
|
||||
}else{
|
||||
$messageIndex = false;
|
||||
}
|
||||
|
||||
if($reliability === 1
|
||||
or $reliability === 3
|
||||
or $reliability === 4
|
||||
or $reliability === 7
|
||||
){
|
||||
$orderIndex = $this->getLTriad();
|
||||
$orderChannel = $this->getByte();
|
||||
}else{
|
||||
$orderIndex = false;
|
||||
$orderChannel = false;
|
||||
}
|
||||
|
||||
if($hasSplit == true){
|
||||
$splitCount = $this->getInt();
|
||||
$splitID = $this->getShort();
|
||||
$splitIndex = $this->getInt();
|
||||
}else{
|
||||
$splitCount = false;
|
||||
$splitID = false;
|
||||
$splitIndex = false;
|
||||
}
|
||||
|
||||
if($length <= 0
|
||||
or $orderChannel >= 32
|
||||
or ($hasSplit === true and $splitIndex >= $splitCount)
|
||||
){
|
||||
return false;
|
||||
}else{
|
||||
$pid = $this->getByte();
|
||||
$buffer = $this->get($length - 1);
|
||||
if(strlen($buffer) < ($length - 1)){
|
||||
return false;
|
||||
}
|
||||
switch($pid){
|
||||
case ProtocolInfo::PING_PACKET:
|
||||
$data = new PingPacket();
|
||||
break;
|
||||
case ProtocolInfo::PONG_PACKET:
|
||||
$data = new PongPacket();
|
||||
break;
|
||||
case ProtocolInfo::CLIENT_CONNECT_PACKET:
|
||||
$data = new ClientConnectPacket();
|
||||
break;
|
||||
case ProtocolInfo::SERVER_HANDSHAKE_PACKET:
|
||||
$data = new ServerHandshakePacket();
|
||||
break;
|
||||
case ProtocolInfo::DISCONNECT_PACKET:
|
||||
$data = new DisconnectPacket();
|
||||
break;
|
||||
case ProtocolInfo::LOGIN_PACKET:
|
||||
$data = new LoginPacket();
|
||||
break;
|
||||
case ProtocolInfo::LOGIN_STATUS_PACKET:
|
||||
$data = new LoginStatusPacket();
|
||||
break;
|
||||
case ProtocolInfo::READY_PACKET:
|
||||
$data = new ReadyPacket();
|
||||
break;
|
||||
case ProtocolInfo::MESSAGE_PACKET:
|
||||
$data = new MessagePacket();
|
||||
break;
|
||||
case ProtocolInfo::SET_TIME_PACKET:
|
||||
$data = new SetTimePacket();
|
||||
break;
|
||||
case ProtocolInfo::START_GAME_PACKET:
|
||||
$data = new StartGamePacket();
|
||||
break;
|
||||
case ProtocolInfo::ADD_MOB_PACKET:
|
||||
$data = new AddMobPacket();
|
||||
break;
|
||||
case ProtocolInfo::ADD_PLAYER_PACKET:
|
||||
$data = new AddPlayerPacket();
|
||||
break;
|
||||
case ProtocolInfo::REMOVE_PLAYER_PACKET:
|
||||
$data = new RemovePlayerPacket();
|
||||
break;
|
||||
case ProtocolInfo::ADD_ENTITY_PACKET:
|
||||
$data = new AddEntityPacket();
|
||||
break;
|
||||
case ProtocolInfo::REMOVE_ENTITY_PACKET:
|
||||
$data = new RemoveEntityPacket();
|
||||
break;
|
||||
case ProtocolInfo::ADD_ITEM_ENTITY_PACKET:
|
||||
$data = new AddItemEntityPacket();
|
||||
break;
|
||||
case ProtocolInfo::TAKE_ITEM_ENTITY_PACKET:
|
||||
$data = new TakeItemEntityPacket();
|
||||
break;
|
||||
case ProtocolInfo::MOVE_ENTITY_PACKET:
|
||||
$data = new MoveEntityPacket();
|
||||
break;
|
||||
case ProtocolInfo::MOVE_ENTITY_PACKET_POSROT:
|
||||
$data = new MoveEntityPacket_PosRot();
|
||||
break;
|
||||
case ProtocolInfo::ROTATE_HEAD_PACKET:
|
||||
$data = new RotateHeadPacket();
|
||||
break;
|
||||
case ProtocolInfo::MOVE_PLAYER_PACKET:
|
||||
$data = new MovePlayerPacket();
|
||||
break;
|
||||
case ProtocolInfo::REMOVE_BLOCK_PACKET:
|
||||
$data = new RemoveBlockPacket();
|
||||
break;
|
||||
case ProtocolInfo::UPDATE_BLOCK_PACKET:
|
||||
$data = new UpdateBlockPacket();
|
||||
break;
|
||||
case ProtocolInfo::ADD_PAINTING_PACKET:
|
||||
$data = new AddPaintingPacket();
|
||||
break;
|
||||
case ProtocolInfo::EXPLODE_PACKET:
|
||||
$data = new ExplodePacket();
|
||||
break;
|
||||
case ProtocolInfo::LEVEL_EVENT_PACKET:
|
||||
$data = new LevelEventPacket();
|
||||
break;
|
||||
case ProtocolInfo::TILE_EVENT_PACKET:
|
||||
$data = new TileEventPacket();
|
||||
break;
|
||||
case ProtocolInfo::ENTITY_EVENT_PACKET:
|
||||
$data = new EntityEventPacket();
|
||||
break;
|
||||
case ProtocolInfo::REQUEST_CHUNK_PACKET:
|
||||
$data = new RequestChunkPacket();
|
||||
break;
|
||||
case ProtocolInfo::CHUNK_DATA_PACKET:
|
||||
$data = new ChunkDataPacket();
|
||||
break;
|
||||
case ProtocolInfo::PLAYER_EQUIPMENT_PACKET:
|
||||
$data = new PlayerEquipmentPacket();
|
||||
break;
|
||||
case ProtocolInfo::PLAYER_ARMOR_EQUIPMENT_PACKET:
|
||||
$data = new PlayerArmorEquipmentPacket();
|
||||
break;
|
||||
case ProtocolInfo::INTERACT_PACKET:
|
||||
$data = new InteractPacket();
|
||||
break;
|
||||
case ProtocolInfo::USE_ITEM_PACKET:
|
||||
$data = new UseItemPacket();
|
||||
break;
|
||||
case ProtocolInfo::PLAYER_ACTION_PACKET:
|
||||
$data = new PlayerActionPacket();
|
||||
break;
|
||||
case ProtocolInfo::HURT_ARMOR_PACKET:
|
||||
$data = new HurtArmorPacket();
|
||||
break;
|
||||
case ProtocolInfo::SET_ENTITY_DATA_PACKET:
|
||||
$data = new SetEntityDataPacket();
|
||||
break;
|
||||
case ProtocolInfo::SET_ENTITY_MOTION_PACKET:
|
||||
$data = new SetEntityMotionPacket();
|
||||
break;
|
||||
case ProtocolInfo::SET_HEALTH_PACKET:
|
||||
$data = new SetHealthPacket();
|
||||
break;
|
||||
case ProtocolInfo::SET_SPAWN_POSITION_PACKET:
|
||||
$data = new SetSpawnPositionPacket();
|
||||
break;
|
||||
case ProtocolInfo::ANIMATE_PACKET:
|
||||
$data = new AnimatePacket();
|
||||
break;
|
||||
case ProtocolInfo::RESPAWN_PACKET:
|
||||
$data = new RespawnPacket();
|
||||
break;
|
||||
case ProtocolInfo::SEND_INVENTORY_PACKET:
|
||||
$data = new SendInventoryPacket();
|
||||
break;
|
||||
case ProtocolInfo::DROP_ITEM_PACKET:
|
||||
$data = new DropItemPacket();
|
||||
break;
|
||||
case ProtocolInfo::CONTAINER_OPEN_PACKET:
|
||||
$data = new ContainerOpenPacket();
|
||||
break;
|
||||
case ProtocolInfo::CONTAINER_CLOSE_PACKET:
|
||||
$data = new ContainerClosePacket();
|
||||
break;
|
||||
case ProtocolInfo::CONTAINER_SET_SLOT_PACKET:
|
||||
$data = new ContainerSetSlotPacket();
|
||||
break;
|
||||
case ProtocolInfo::CONTAINER_SET_DATA_PACKET:
|
||||
$data = new ContainerSetDataPacket();
|
||||
break;
|
||||
case ProtocolInfo::CONTAINER_SET_CONTENT_PACKET:
|
||||
$data = new ContainerSetContentPacket();
|
||||
break;
|
||||
case ProtocolInfo::CHAT_PACKET:
|
||||
$data = new ChatPacket();
|
||||
break;
|
||||
case ProtocolInfo::ADVENTURE_SETTINGS_PACKET:
|
||||
$data = new AdventureSettingsPacket();
|
||||
break;
|
||||
case ProtocolInfo::ENTITY_DATA_PACKET:
|
||||
$data = new EntityDataPacket();
|
||||
break;
|
||||
default:
|
||||
$data = new UnknownPacket();
|
||||
$data->packetID = $pid;
|
||||
break;
|
||||
}
|
||||
$data->reliability = $reliability;
|
||||
$data->hasSplit = $hasSplit;
|
||||
$data->messageIndex = $messageIndex;
|
||||
$data->orderIndex = $orderIndex;
|
||||
$data->orderChannel = $orderChannel;
|
||||
$data->splitCount = $splitCount;
|
||||
$data->splitID = $splitID;
|
||||
$data->splitIndex = $splitIndex;
|
||||
$data->setBuffer($buffer);
|
||||
$this->data[] = $data;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
if(strlen($this->buffer) > 0){
|
||||
return;
|
||||
}
|
||||
$this->buffer = chr($this->packetID);
|
||||
|
||||
switch($this->packetID){
|
||||
case Info::OPEN_CONNECTION_REPLY_1:
|
||||
$this->buffer .= Info::MAGIC;
|
||||
$this->putLong($this->serverID);
|
||||
$this->putByte(0); //server security
|
||||
$this->putShort($this->mtuSize);
|
||||
break;
|
||||
case Info::OPEN_CONNECTION_REPLY_2:
|
||||
$this->buffer .= Info::MAGIC;
|
||||
$this->putLong($this->serverID);
|
||||
$this->putShort($this->serverPort);
|
||||
$this->putShort($this->mtuSize);
|
||||
$this->putByte(0); //Server security
|
||||
break;
|
||||
case Info::INCOMPATIBLE_PROTOCOL_VERSION:
|
||||
$this->putByte(Info::STRUCTURE);
|
||||
$this->buffer .= Info::MAGIC;
|
||||
$this->putLong($this->serverID);
|
||||
break;
|
||||
case Info::UNCONNECTED_PONG:
|
||||
case Info::ADVERTISE_SYSTEM:
|
||||
$this->putLong($this->pingID);
|
||||
$this->putLong($this->serverID);
|
||||
$this->buffer .= Info::MAGIC;
|
||||
$this->putString($this->serverType);
|
||||
break;
|
||||
case Info::DATA_PACKET_0:
|
||||
case Info::DATA_PACKET_1:
|
||||
case Info::DATA_PACKET_2:
|
||||
case Info::DATA_PACKET_3:
|
||||
case Info::DATA_PACKET_4:
|
||||
case Info::DATA_PACKET_5:
|
||||
case Info::DATA_PACKET_6:
|
||||
case Info::DATA_PACKET_7:
|
||||
case Info::DATA_PACKET_8:
|
||||
case Info::DATA_PACKET_9:
|
||||
case Info::DATA_PACKET_A:
|
||||
case Info::DATA_PACKET_B:
|
||||
case Info::DATA_PACKET_C:
|
||||
case Info::DATA_PACKET_D:
|
||||
case Info::DATA_PACKET_E:
|
||||
case Info::DATA_PACKET_F:
|
||||
$this->putLTriad($this->seqNumber);
|
||||
foreach($this->data as $pk){
|
||||
$this->encodeDataPacket($pk);
|
||||
}
|
||||
break;
|
||||
case Info::NACK:
|
||||
case Info::ACK:
|
||||
$payload = "";
|
||||
$records = 0;
|
||||
$pointer = 0;
|
||||
sort($this->packets, SORT_NUMERIC);
|
||||
$max = count($this->packets);
|
||||
|
||||
while($pointer < $max){
|
||||
$type = true;
|
||||
$curr = $start = $this->packets[$pointer];
|
||||
for($i = $start + 1; $i < $max; ++$i){
|
||||
$n = $this->packets[$i];
|
||||
if(($n - $curr) === 1){
|
||||
$curr = $end = $n;
|
||||
$type = false;
|
||||
$pointer = $i + 1;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
++$pointer;
|
||||
if($type === false){
|
||||
$payload .= "\x00";
|
||||
$payload .= strrev(Utils::writeTriad($start));
|
||||
$payload .= strrev(Utils::writeTriad($end));
|
||||
}else{
|
||||
$payload .= Utils::writeBool(true);
|
||||
$payload .= strrev(Utils::writeTriad($start));
|
||||
}
|
||||
++$records;
|
||||
}
|
||||
$this->putShort($records);
|
||||
$this->buffer .= $payload;
|
||||
break;
|
||||
default:
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function encodeDataPacket(DataPacket $pk){
|
||||
$this->putByte(($pk->reliability << 5) | ($pk->hasSplit > 0 ? 0b00010000 : 0));
|
||||
$this->putShort(strlen($pk->buffer) << 3);
|
||||
if($pk->reliability === 2
|
||||
or $pk->reliability === 3
|
||||
or $pk->reliability === 4
|
||||
or $pk->reliability === 6
|
||||
or $pk->reliability === 7
|
||||
){
|
||||
$this->putLTriad($pk->messageIndex);
|
||||
}
|
||||
|
||||
if($pk->reliability === 1
|
||||
or $pk->reliability === 3
|
||||
or $pk->reliability === 4
|
||||
or $pk->reliability === 7
|
||||
){
|
||||
$this->putLTriad($pk->orderIndex);
|
||||
$this->putByte($pk->orderChannel);
|
||||
}
|
||||
|
||||
if($pk->hasSplit === true){
|
||||
$this->putInt($pk->splitCount);
|
||||
$this->putShort($pk->splitID);
|
||||
$this->putInt($pk->splitIndex);
|
||||
}
|
||||
|
||||
$this->buffer .= $pk->buffer;
|
||||
}
|
||||
|
||||
protected function put($str){
|
||||
$this->buffer .= $str;
|
||||
}
|
||||
|
||||
protected function putLong($v){
|
||||
$this->buffer .= Utils::writeLong($v);
|
||||
}
|
||||
|
||||
protected function putInt($v){
|
||||
$this->buffer .= Utils::writeInt($v);
|
||||
}
|
||||
|
||||
protected function putShort($v){
|
||||
$this->buffer .= Utils::writeShort($v);
|
||||
}
|
||||
|
||||
protected function putTriad($v){
|
||||
$this->buffer .= Utils::writeTriad($v);
|
||||
}
|
||||
|
||||
protected function putLTriad($v){
|
||||
$this->buffer .= strrev(Utils::writeTriad($v));
|
||||
}
|
||||
|
||||
protected function putByte($v){
|
||||
$this->buffer .= chr($v);
|
||||
}
|
||||
|
||||
protected function putString($v){
|
||||
$this->putShort(strlen($v));
|
||||
$this->put($v);
|
||||
}
|
||||
|
||||
public function __destruct(){
|
||||
}
|
||||
}
|
@ -1,147 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\plugin;
|
||||
|
||||
use pocketmine\event\plugin\PluginDisableEvent;
|
||||
use pocketmine\event\plugin\PluginEnableEvent;
|
||||
use pocketmine\Server;
|
||||
|
||||
/**
|
||||
* Handles different types of plugins
|
||||
*/
|
||||
class FolderPluginLoader implements PluginLoader{
|
||||
|
||||
/** @var Server */
|
||||
private $server;
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
*/
|
||||
public function __construct(Server $server){
|
||||
$this->server = $server;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the plugin contained in $file
|
||||
*
|
||||
* @param string $file
|
||||
*
|
||||
* @return Plugin
|
||||
*/
|
||||
public function loadPlugin($file){
|
||||
if(is_dir($file) and file_exists($file . "/plugin.yml") and file_exists($file . "/src/")){
|
||||
if(($description = $this->getPluginDescription($file)) instanceof PluginDescription){
|
||||
console("[INFO] Loading " . $description->getFullName());
|
||||
console("[WARNING] Non-packaged plugin ".$description->getName() ." detected, do not use on production.");
|
||||
$dataFolder = dirname($file) . DIRECTORY_SEPARATOR . $description->getName();
|
||||
if(file_exists($dataFolder) and !is_dir($dataFolder)){
|
||||
trigger_error("Projected dataFolder '" . $dataFolder . "' for " . $description->getName() . " exists and is not a directory", E_USER_WARNING);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
$className = $description->getMain();
|
||||
$this->server->getLoader()->add(substr($className, 0, strpos($className, "\\")), array(
|
||||
$file . "/src"
|
||||
));
|
||||
|
||||
if(class_exists($className, true)){
|
||||
$plugin = new $className();
|
||||
$this->initPlugin($plugin, $description, $dataFolder, $file);
|
||||
|
||||
return $plugin;
|
||||
}else{
|
||||
trigger_error("Couldn't load plugin " . $description->getName() . ": main class not found", E_USER_WARNING);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the PluginDescription from the file
|
||||
*
|
||||
* @param string $file
|
||||
*
|
||||
* @return PluginDescription
|
||||
*/
|
||||
public function getPluginDescription($file){
|
||||
if(is_dir($file) and file_exists($file . "/plugin.yml")){
|
||||
$yaml = @file_get_contents($file . "/plugin.yml");
|
||||
if($yaml != ""){
|
||||
return new PluginDescription($yaml);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the filename patterns that this loader accepts
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPluginFilters(){
|
||||
return "/[^\\.]/";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PluginBase $plugin
|
||||
* @param PluginDescription $description
|
||||
* @param string $dataFolder
|
||||
* @param string $file
|
||||
*/
|
||||
private function initPlugin(PluginBase $plugin, PluginDescription $description, $dataFolder, $file){
|
||||
$plugin->init($this, $this->server, $description, $dataFolder, $file);
|
||||
$plugin->onLoad();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Plugin $plugin
|
||||
*/
|
||||
public function enablePlugin(Plugin $plugin){
|
||||
if($plugin instanceof PluginBase and !$plugin->isEnabled()){
|
||||
console("[INFO] Enabling " . $plugin->getDescription()->getFullName());
|
||||
|
||||
$plugin->setEnabled(true);
|
||||
|
||||
Server::getInstance()->getPluginManager()->callEvent(new PluginEnableEvent($plugin));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Plugin $plugin
|
||||
*/
|
||||
public function disablePlugin(Plugin $plugin){
|
||||
if($plugin instanceof PluginBase and $plugin->isEnabled()){
|
||||
console("[INFO] Disabling " . $plugin->getDescription()->getFullName());
|
||||
|
||||
Server::getInstance()->getPluginManager()->callEvent(new PluginDisableEvent($plugin));
|
||||
|
||||
$plugin->setEnabled(false);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,334 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Crafting / Smelting / Fuel data and fast search databases
|
||||
*/
|
||||
namespace pocketmine\recipes;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
|
||||
abstract class Crafting{
|
||||
|
||||
private static $lookupTable = array();
|
||||
|
||||
private static $small = array( //Probably means craftable on crafting bench and in inventory. Name it better!
|
||||
//Building
|
||||
"CLAY:?x4=>CLAY_BLOCK:0x1",
|
||||
"WOODEN_PLANKS:?x4=>WORKBENCH:0x1",
|
||||
"GLOWSTONE_DUST:?x4=>GLOWSTONE_BLOCK:0x1",
|
||||
"PUMPKIN:?x1,TORCH:?x1=>LIT_PUMPKIN:0x1",
|
||||
"SNOWBALL:?x4=>SNOW_BLOCK:0x1",
|
||||
"WOODEN_PLANKS:?x2=>STICK:0x4",
|
||||
"COBBLESTONE:?x4=>STONECUTTER:0x1",
|
||||
"WOOD:0x1=>WOODEN_PLANKS:0x4",
|
||||
"WOOD:1x1=>WOODEN_PLANKS:1x4",
|
||||
"WOOD:2x1=>WOODEN_PLANKS:2x4",
|
||||
"WOOD:3x1=>WOODEN_PLANKS:3x4",
|
||||
"WOOL:0x1,DYE:0x1=>WOOL:15x1",
|
||||
"WOOL:0x1,DYE:1x1=>WOOL:14x1",
|
||||
"WOOL:0x1,DYE:2x1=>WOOL:13x1",
|
||||
"WOOL:0x1,DYE:3x1=>WOOL:12x1",
|
||||
"WOOL:0x1,DYE:4x1=>WOOL:11x1",
|
||||
"WOOL:0x1,DYE:5x1=>WOOL:10x1",
|
||||
"WOOL:0x1,DYE:6x1=>WOOL:9x1",
|
||||
"WOOL:0x1,DYE:7x1=>WOOL:8x1",
|
||||
"WOOL:0x1,DYE:8x1=>WOOL:7x1",
|
||||
"WOOL:0x1,DYE:9x1=>WOOL:6x1",
|
||||
"WOOL:0x1,DYE:10x1=>WOOL:5x1",
|
||||
"WOOL:0x1,DYE:11x1=>WOOL:4x1",
|
||||
"WOOL:0x1,DYE:12x1=>WOOL:3x1",
|
||||
"WOOL:0x1,DYE:13x1=>WOOL:2x1",
|
||||
"WOOL:0x1,DYE:14x1=>WOOL:1x1",
|
||||
"STRING:?x4=>WOOL:0x1",
|
||||
|
||||
//Tools
|
||||
"IRON_INGOT:?x1,FLINT:?x1=>FLINT_STEEL:0x1",
|
||||
"IRON_INGOT:?x2=>SHEARS:0x1",
|
||||
"COAL:0x1,STICK:?x1=>TORCH:0x4",
|
||||
"COAL:1x1,STICK:?x1=>TORCH:0x4",
|
||||
|
||||
//Food & protection
|
||||
"MELON_SLICE:?x1=>MELON_SEEDS:0x1",
|
||||
"PUMPKIN:?x1=>PUMPKIN_SEEDS:0x4",
|
||||
"PUMPKIN:?x1,EGG:?x1,SUGAR:?x1=>PUMPKIN_PIE:0x1",
|
||||
"BROWN_MUSHROOM:?x1,RED_MUSHROOM:?x1,BOWL:?x1=>MUSHROOM_STEW:0x1",
|
||||
"SUGARCANE:?x1=>SUGAR:0x1",
|
||||
"MELON_SLICE:?x1=>MELON_SEEDS:0x1",
|
||||
"HAY_BALE:?x1=>WHEAT:0x9",
|
||||
|
||||
//Items
|
||||
"DIAMOND_BLOCK:?x1=>DIAMOND:0x9",
|
||||
"GOLD_BLOCK:?x1=>GOLD_INGOT:0x9",
|
||||
"IRON_BLOCK:?x1=>IRON_INGOT:0x9",
|
||||
"LAPIS_BLOCK:?x1=>DYE:4x9",
|
||||
"DANDELION:?x1=>DYE:11x2",
|
||||
"BONE:?x1=>DYE:15x3",
|
||||
"DYE:0x1,DYE:14x1=>DYE:3x2",
|
||||
"DYE:0x1,DYE:1x1,DYE:11x1=>DYE:3x3",
|
||||
"DYE:1x1,DYE:15x1=>DYE:9x2",
|
||||
"DYE:1x1,DYE:11x1=>DYE:14x2",
|
||||
"DYE:2x1,DYE:15x1=>DYE:10x2",
|
||||
"DYE:4x1,DYE:15x1=>DYE:12x2",
|
||||
"DYE:2x1,DYE:4x1=>DYE:6x2",
|
||||
"DYE:1x1,DYE:4x1=>DYE:5x2",
|
||||
"DYE:1x1,DYE:4x1,DYE:15x1=>DYE:13x3",
|
||||
"BEETROOT:?x1=>DYE:1x1",
|
||||
"DYE:15x1,DYE:1x2,DYE:4x1=>DYE:13x4", //
|
||||
"DYE:5x1,DYE:9x1=>DYE:13x2", //
|
||||
"DYE:0x1,DYE:15x1=>DYE:8x2", //
|
||||
"DYE:0x1,DYE:15x2=>DYE:7x3", //
|
||||
"DYE:0x1,DYE:8x1=>DYE:7x2", //
|
||||
);
|
||||
|
||||
private static $big = array( //Probably means only craftable on crafting bench. Name it better!
|
||||
//Building
|
||||
"WOOL:?x3,WOODEN_PLANKS:?x3=>BED:0x1",
|
||||
"WOODEN_PLANKS:?x8=>CHEST:0x1",
|
||||
"STICK:?x6=>FENCE:0x2",
|
||||
"STICK:?x4,WOODEN_PLANKS:?x2=>FENCE_GATE:0x1",
|
||||
"COBBLESTONE:?x8=>FURNACE:0x1",
|
||||
"GLASS:?x6=>GLASS_PANE:0x16",
|
||||
"STICK:?x7=>LADDER:0x2",
|
||||
"DIAMOND:?x3,IRON_INGOT:?x6=>NETHER_REACTOR:0x1",
|
||||
"WOODEN_PLANKS:?x6=>TRAPDOOR:0x2",
|
||||
"WOODEN_PLANKS:?x6=>WOODEN_DOOR:0x1",
|
||||
"WOODEN_PLANKS:0x6=>WOODEN_STAIRS:0x4",
|
||||
"WOODEN_PLANKS:0x3=>WOOD_SLAB:0x6",
|
||||
"WOODEN_PLANKS:1x6=>SPRUCE_WOOD_STAIRS:0x4",
|
||||
"WOODEN_PLANKS:1x3=>WOOD_SLAB:1x6",
|
||||
"WOODEN_PLANKS:2x6=>BIRCH_WOOD_STAIRS:0x4",
|
||||
"WOODEN_PLANKS:2x3=>BIRCH_WOOD_SLAB:2x6",
|
||||
"WOODEN_PLANKS:3x6=>JUNGLE_WOOD_STAIRS:0x4",
|
||||
"WOODEN_PLANKS:3x3=>JUNGLE_WOOD_SLAB:3x6",
|
||||
|
||||
//Tools
|
||||
"STICK:?x1,FEATHER:?x1,FLINT:?x1=>ARROW:0x4",
|
||||
"STICK:?x3,STRING:?x3=>BOW:0x1",
|
||||
"IRON_INGOT:?x3=>BUCKET:0x1",
|
||||
"GOLD_INGOT:?x4,REDSTONE_DUST:?x1=>CLOCK:0x1",
|
||||
"IRON_INGOT:?x4,REDSTONE_DUST:?x1=>COMPASS:0x1",
|
||||
"DIAMOND:?x3,STICK:?x2=>DIAMOND_AXE:0x1",
|
||||
"DIAMOND:?x2,STICK:?x2=>DIAMOND_HOE:0x1",
|
||||
"DIAMOND:?x3,STICK:?x2=>DIAMOND_PICKAXE:0x1",
|
||||
"DIAMOND:?x1,STICK:?x2=>DIAMOND_SHOVEL:0x1",
|
||||
"DIAMOND:?x2,STICK:?x1=>DIAMOND_SWORD:0x1",
|
||||
"GOLD_INGOT:?x3,STICK:?x2=>GOLD_AXE:0x1",
|
||||
"GOLD_INGOT:?x2,STICK:?x2=>GOLD_HOE:0x1",
|
||||
"GOLD_INGOT:?x3,STICK:?x2=>GOLD_PICKAXE:0x1",
|
||||
"GOLD_INGOT:?x1,STICK:?x2=>GOLD_SHOVEL:0x1",
|
||||
"GOLD_INGOT:?x2,STICK:?x1=>GOLD_SWORD:0x1",
|
||||
"IRON_INGOT:?x3,STICK:?x2=>IRON_AXE:0x1",
|
||||
"IRON_INGOT:?x2,STICK:?x2=>IRON_HOE:0x1",
|
||||
"IRON_INGOT:?x3,STICK:?x2=>IRON_PICKAXE:0x1",
|
||||
"IRON_INGOT:?x1,STICK:?x2=>IRON_SHOVEL:0x1",
|
||||
"IRON_INGOT:?x2,STICK:?x1=>IRON_SWORD:0x1",
|
||||
"COBBLESTONE:?x3,STICK:?x2=>STONE_AXE:0x1",
|
||||
"COBBLESTONE:?x2,STICK:?x2=>STONE_HOE:0x1",
|
||||
"COBBLESTONE:?x3,STICK:?x2=>STONE_PICKAXE:0x1",
|
||||
"COBBLESTONE:?x1,STICK:?x2=>STONE_SHOVEL:0x1",
|
||||
"COBBLESTONE:?x2,STICK:?x1=>STONE_SWORD:0x1",
|
||||
"SAND:?x4,GUNPOWDER:?x5=>TNT:0x1",
|
||||
"WOODEN_PLANKS:?x3,STICK:?x2=>WOODEN_AXE:0x1",
|
||||
"WOODEN_PLANKS:?x2,STICK:?x2=>WOODEN_HOE:0x1",
|
||||
"WOODEN_PLANKS:?x3,STICK:?x2=>WOODEN_PICKAXE:0x1",
|
||||
"WOODEN_PLANKS:?x1,STICK:?x2=>WOODEN_SHOVEL:0x1",
|
||||
"WOODEN_PLANKS:?x2,STICK:?x1=>WOODEN_SWORD:0x1",
|
||||
|
||||
//Food & protection
|
||||
"BEETROOT:?x4,BOWL:?x1=>BEETROOT_SOUP:0x1",
|
||||
"WOODEN_PLANKS:?x3=>BOWL:0x1",
|
||||
"WHEAT:?x3=>BREAD:0x1",
|
||||
"WHEAT:?x3,BUCKET:1x3,EGG:?x1,SUGAR:?x2=>CAKE:0x1",
|
||||
"DIAMOND:?x4=>DIAMOND_BOOTS:0x1",
|
||||
"DIAMOND:?x8=>DIAMOND_CHESTPLATE:0x1",
|
||||
"DIAMOND:?x5=>DIAMOND_HELMET:0x1",
|
||||
"DIAMOND:?x7=>DIAMOND_LEGGINGS:0x1",
|
||||
"GOLD_INGOT:?x4=>GOLD_BOOTS:0x1",
|
||||
"GOLD_INGOT:?x8=>GOLD_CHESTPLATE:0x1",
|
||||
"GOLD_INGOT:?x5=>GOLD_HELMET:0x1",
|
||||
"GOLD_INGOT:?x7=>GOLD_LEGGINGS:0x1",
|
||||
"IRON_INGOT:?x4=>IRON_BOOTS:0x1",
|
||||
"IRON_INGOT:?x8=>IRON_CHESTPLATE:0x1",
|
||||
"IRON_INGOT:?x5=>IRON_HELMET:0x1",
|
||||
"IRON_INGOT:?x7=>IRON_LEGGINGS:0x1",
|
||||
"LEATHER:?x4=>LEATHER_BOOTS:0x1",
|
||||
"LEATHER:?x8=>LEATHER_TUNIC:0x1",
|
||||
"LEATHER:?x5=>LEATHER_CAP:0x1",
|
||||
"LEATHER:?x7=>LEATHER_PANTS:0x1",
|
||||
"FIRE:?x4=>CHAIN_BOOTS:0x1",
|
||||
"FIRE:?x8=>CHAIN_CHESTPLATE:0x1",
|
||||
"FIRE:?x5=>CHAIN_HELMET:0x1",
|
||||
"FIRE:?x7=>CHAIN_LEGGINGS:0x1",
|
||||
|
||||
//Items
|
||||
"DIAMOND:?x9=>DIAMOND_BLOCK:0x1",
|
||||
"GOLD_INGOT:?x9=>GOLD_BLOCK:0x1",
|
||||
"IRON_INGOT:?x9=>IRON_BLOCK:0x1",
|
||||
"IRON_INGOT:?x5=>MINECART:0x1",
|
||||
"WHEAT:?x9=>HAY_BALE:0x1",
|
||||
"PAPER:?x3=>BOOK:0x1",
|
||||
"WOODEN_PLANKS:?x6,BOOK:?x3=>BOOKSHELF:0x1",
|
||||
"DYE:4x9=>LAPIS_BLOCK:0x1",
|
||||
"WOOL:?x1,STICK:?x8=>PAINTING:0x1",
|
||||
"SUGARCANE:?x3=>PAPER:0x1",
|
||||
"WOODEN_PLANKS:?x6,STICK:?x1=>SIGN:0x1",
|
||||
"IRON_INGOT:?x6=>IRON_BARS:0x16",
|
||||
"COAL:0x9=>COAL_BLOCK:0x1",
|
||||
"COAL_BLOCK:?x1=>COAL:0x9",
|
||||
);
|
||||
|
||||
private static $stone = array(
|
||||
"QUARTZ:?x4=>QUARTZ_BLOCK:0x1",
|
||||
"BRICKS_BLOCK:?x6=>BRICK_STAIRS:0x4",
|
||||
"BRICK:?x4=>BRICKS_BLOCK:0x1",
|
||||
"BRICKS_BLOCK:?x3=>SLAB:4x6",
|
||||
"SLAB:6x2=>QUARTZ_BLOCK:1x1",
|
||||
"COBBLESTONE:?x3=>SLAB:3x6",
|
||||
"COBBLESTONE:0x6=>STONE_WALL:0x6",
|
||||
"MOSSY_STONE:0x6=>STONE_WALL:1x6",
|
||||
"NETHER_BRICK:?x4=>NETHER_BRICKS:0x1",
|
||||
"NETHER_BRICKS:?x6=>NETHER_BRICKS_STAIRS:0x4",
|
||||
"QUARTZ_BLOCK:0x2=>QUARTZ_BLOCK:2x2",
|
||||
"QUARTZ_BLOCK:?x3=>SLAB:6x6",
|
||||
"SANDSTONE:0x6=>SANDSTONE_STAIRS:0x4",
|
||||
"SAND:?x4=>SANDSTONE:0x1",
|
||||
"SANDSTONE:0x4=>SANDSTONE:2x4",
|
||||
"SLAB:1x2=>SANDSTONE:1x1",
|
||||
"SANDSTONE:0x3=>SLAB:1x6",
|
||||
"STONE_BRICK:?x6=>STONE_BRICK_STAIRS:0x4",
|
||||
"STONE:?x4=>STONE_BRICK:0x4",
|
||||
"STONE_BRICKS:?x3=>SLAB:5x6",
|
||||
"STONE:?x3=>SLAB:0x6",
|
||||
"COBBLESTONE:?x6=>COBBLESTONE_STAIRS:0x4",
|
||||
);
|
||||
|
||||
private static $recipes = array();
|
||||
|
||||
private static function parseRecipe($recipe){
|
||||
$recipe = explode("=>", $recipe);
|
||||
$recipeItems = array();
|
||||
foreach(explode(",", $recipe[0]) as $item){
|
||||
$item = explode("x", $item);
|
||||
$id = explode(":", $item[0]);
|
||||
$meta = array_pop($id);
|
||||
$id = $id[0];
|
||||
|
||||
$it = Item::fromString($id);
|
||||
$recipeItems[$it->getID()] = array($it->getID(), $meta === "?" ? false : intval($meta) & 0xFFFF, intval($item[1]));
|
||||
}
|
||||
ksort($recipeItems);
|
||||
$item = explode("x", $recipe[1]);
|
||||
$id = explode(":", $item[0]);
|
||||
$meta = array_pop($id);
|
||||
$id = $id[0];
|
||||
|
||||
$it = Item::fromString($id);
|
||||
|
||||
$craftItem = array($it->getID(), intval($meta) & 0xFFFF, intval($item[1]));
|
||||
|
||||
$recipeString = "";
|
||||
foreach($recipeItems as $item){
|
||||
$recipeString .= $item[0] . "x" . $item[2] . ",";
|
||||
}
|
||||
$recipeString = substr($recipeString, 0, -1) . "=>" . $craftItem[0] . "x" . $craftItem[2];
|
||||
|
||||
return array($recipeItems, $craftItem, $recipeString);
|
||||
}
|
||||
|
||||
public static function init(){
|
||||
$id = 1;
|
||||
|
||||
self::$lookupTable[0] = array();
|
||||
foreach(self::$small as $recipe){
|
||||
$recipe = self::parseRecipe($recipe);
|
||||
self::$recipes[$id] = $recipe;
|
||||
if(!isset(self::$lookupTable[0][$recipe[2]])){
|
||||
self::$lookupTable[0][$recipe[2]] = array();
|
||||
}
|
||||
self::$lookupTable[0][$recipe[2]][] = $id;
|
||||
++$id;
|
||||
}
|
||||
|
||||
self::$lookupTable[1] = array();
|
||||
foreach(self::$big as $recipe){
|
||||
$recipe = self::parseRecipe($recipe);
|
||||
self::$recipes[$id] = $recipe;
|
||||
if(!isset(self::$lookupTable[1][$recipe[2]])){
|
||||
self::$lookupTable[1][$recipe[2]] = array();
|
||||
}
|
||||
self::$lookupTable[1][$recipe[2]][] = $id;
|
||||
++$id;
|
||||
}
|
||||
|
||||
self::$lookupTable[2] = array();
|
||||
foreach(self::$stone as $recipe){
|
||||
$recipe = self::parseRecipe($recipe);
|
||||
self::$recipes[$id] = $recipe;
|
||||
if(!isset(self::$lookupTable[2][$recipe[2]])){
|
||||
self::$lookupTable[2][$recipe[2]] = array();
|
||||
}
|
||||
self::$lookupTable[2][$recipe[2]][] = $id;
|
||||
++$id;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static function canCraft(array $craftItem, array $recipeItems, $type){
|
||||
ksort($recipeItems);
|
||||
$recipeString = "";
|
||||
foreach($recipeItems as $item){
|
||||
$recipeString .= $item[0] . "x" . $item[2] . ",";
|
||||
}
|
||||
$recipeString = substr($recipeString, 0, -1) . "=>" . $craftItem[0] . "x" . $craftItem[2];
|
||||
|
||||
$continue = true;
|
||||
|
||||
if(isset(self::$lookupTable[$type][$recipeString])){
|
||||
foreach(self::$lookupTable[$type][$recipeString] as $id){
|
||||
$continue = true;
|
||||
$recipe = self::$recipes[$id];
|
||||
foreach($recipe[0] as $item){
|
||||
if(!isset($recipeItems[$item[0]])){
|
||||
$continue = false;
|
||||
break;
|
||||
}
|
||||
$oitem = $recipeItems[$item[0]];
|
||||
if(($oitem[1] !== $item[1] and $item[1] !== false) or $oitem[2] !== $item[2]){
|
||||
$continue = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if($continue === false or $craftItem[0] !== $recipe[1][0] or $recipe[1][1] !== $recipe[1][1] or $recipe[1][2] !== $recipe[1][2]){
|
||||
$continue = false;
|
||||
continue;
|
||||
}
|
||||
$continue = $recipe;
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
return true;
|
||||
}
|
||||
|
||||
return $continue;
|
||||
}
|
||||
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\recipes;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class Smelt{
|
||||
public static $product = array(
|
||||
Item::COBBLESTONE => array(Item::STONE, 0),
|
||||
Item::SAND => array(Item::GLASS, 0),
|
||||
Item::TRUNK => array(Item::COAL, 1), //Charcoal
|
||||
Item::GOLD_ORE => array(Item::GOLD_INGOT, 0),
|
||||
Item::IRON_ORE => array(Item::IRON_INGOT, 0),
|
||||
Item::NETHERRACK => array(Item::NETHER_BRICK, 0),
|
||||
Item::RAW_PORKCHOP => array(Item::COOKED_PORKCHOP, 0),
|
||||
Item::CLAY => array(Item::BRICK, 0),
|
||||
//Item::RAW_FISH => array(Item::COOKED_FISH, 0),
|
||||
Item::CACTUS => array(Item::DYE, 2),
|
||||
Item::RED_MUSHROOM => array(Item::DYE, 1),
|
||||
Item::RAW_BEEF => array(Item::STEAK, 0),
|
||||
Item::RAW_CHICKEN => array(Item::COOKED_CHICKEN, 0),
|
||||
Item::RED_MUSHROOM => array(Item::DYE, 1),
|
||||
Item::POTATO => array(Item::BAKED_POTATO, 0),
|
||||
);
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\scheduler;
|
||||
|
||||
class TickScheduler extends \Thread{
|
||||
protected $sleepTime;
|
||||
protected $ticksPerSecond;
|
||||
protected $tickMeasure;
|
||||
public $hasTick;
|
||||
|
||||
public function __construct($ticksPerSecond = 20){
|
||||
$this->ticksPerSecond = (int) $ticksPerSecond;
|
||||
$this->sleepTime = (int) (1000000 / $this->ticksPerSecond);
|
||||
$this->tickMeasure = $this->sleepTime;
|
||||
$this->start(PTHREADS_INHERIT_ALL & ~PTHREADS_INHERIT_CLASSES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if clear to run tick
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasTick(){
|
||||
return $this->synchronized(function (){
|
||||
$hasTick = $this->hasTick;
|
||||
$this->hasTick = false;
|
||||
|
||||
return $hasTick === true;
|
||||
});
|
||||
}
|
||||
|
||||
public function doTick(){
|
||||
$this->notify();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getTPS(){
|
||||
return $this->synchronized(function (){
|
||||
return round(($this->sleepTime / $this->tickMeasure) * $this->ticksPerSecond, 2);
|
||||
});
|
||||
}
|
||||
|
||||
public function run(){
|
||||
$tickTime = microtime(true);
|
||||
$this->hasTick = true;
|
||||
while(true){
|
||||
$this->synchronized(function (){
|
||||
$this->hasTick = true;
|
||||
$this->wait();
|
||||
$this->hasTick = false;
|
||||
});
|
||||
|
||||
$this->tickMeasure = (int) ((($time = microtime(true)) - $tickTime) * 1000000);
|
||||
$tickTime = $time;
|
||||
usleep($this->sleepTime - 100); //Remove a few ms for processing
|
||||
}
|
||||
}
|
||||
}
|
@ -1,129 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\tile;
|
||||
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3 as Vector3;
|
||||
use pocketmine\nbt\NBT;
|
||||
use pocketmine\nbt\tag\Compound;
|
||||
use pocketmine\nbt\tag\Int;
|
||||
use pocketmine\nbt\tag\String;
|
||||
use pocketmine\network\protocol\EntityDataPacket;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Chest extends Spawnable{
|
||||
use Container;
|
||||
|
||||
const SLOTS = 27;
|
||||
|
||||
public function __construct(Level $level, Compound $nbt){
|
||||
$nbt["id"] = Tile::CHEST;
|
||||
parent::__construct($level, $nbt);
|
||||
}
|
||||
|
||||
public function isPaired(){
|
||||
if(!isset($this->namedtag->pairx) or !isset($this->namedtag->pairz)){
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getPair(){
|
||||
if($this->isPaired()){
|
||||
return $this->level->getTile(new Vector3((int) $this->namedtag->pairx, $this->y, (int) $this->namedtag->pairz));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function pairWith(Tile $tile){
|
||||
if($this->isPaired() or $tile->isPaired()){
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->namedtag->pairx = $tile->x;
|
||||
$this->namedtag->pairz = $tile->z;
|
||||
|
||||
$tile->namedtag->pairx = $this->x;
|
||||
$tile->namedtag->pairz = $this->z;
|
||||
|
||||
$this->spawnToAll();
|
||||
$tile->spawnToAll();
|
||||
$this->server->handle("tile.update", $this);
|
||||
$this->server->handle("tile.update", $tile);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function unpair(){
|
||||
if(!$this->isPaired()){
|
||||
return false;
|
||||
}
|
||||
|
||||
$tile = $this->getPair();
|
||||
unset($this->namedtag->pairx, $this->namedtag->pairz, $tile->namedtag->pairx, $tile->namedtag->pairz);
|
||||
|
||||
$this->spawnToAll();
|
||||
$this->server->handle("tile.update", $this);
|
||||
if($tile instanceof Chest){
|
||||
$tile->spawnToAll();
|
||||
$this->server->handle("tile.update", $tile);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function spawnTo(Player $player){
|
||||
if($this->closed){
|
||||
return false;
|
||||
}
|
||||
|
||||
$nbt = new NBT(NBT::LITTLE_ENDIAN);
|
||||
if($this->isPaired()){
|
||||
$nbt->setData(new Compound("", array(
|
||||
new String("id", Tile::CHEST),
|
||||
new Int("x", (int) $this->x),
|
||||
new Int("y", (int) $this->y),
|
||||
new Int("z", (int) $this->z),
|
||||
new Int("pairx", (int) $this->namedtag->pairx),
|
||||
new Int("pairz", (int) $this->namedtag->pairz)
|
||||
)));
|
||||
}else{
|
||||
$nbt->setData(new Compound("", array(
|
||||
new String("id", Tile::CHEST),
|
||||
new Int("x", (int) $this->x),
|
||||
new Int("y", (int) $this->y),
|
||||
new Int("z", (int) $this->z)
|
||||
)));
|
||||
}
|
||||
|
||||
$pk = new EntityDataPacket;
|
||||
$pk->x = $this->x;
|
||||
$pk->y = $this->y;
|
||||
$pk->z = $this->z;
|
||||
$pk->namedtag = $nbt->write();
|
||||
$player->dataPacket($pk);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,195 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\tile;
|
||||
|
||||
use pocketmine\event\tile\TileInventoryChangeEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\nbt\tag\Byte;
|
||||
use pocketmine\nbt\tag\Compound;
|
||||
use pocketmine\nbt\tag\Short;
|
||||
use pocketmine\Network;
|
||||
use pocketmine\network\protocol\ContainerOpenPacket;
|
||||
use pocketmine\network\protocol\ContainerSetContentPacket;
|
||||
use pocketmine\network\protocol\TileEventPacket;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
|
||||
trait Container{
|
||||
public function openInventory(Player $player){
|
||||
if($this instanceof Chest){
|
||||
$player->windowCnt++;
|
||||
$player->windowCnt = $id = max(2, $player->windowCnt % 99);
|
||||
if(($pair = $this->getPair()) !== false){
|
||||
if(($pair->x + ($pair->z << 13)) > ($this->x + ($this->z << 13))){ //Order them correctly
|
||||
$player->windows[$id] = array(
|
||||
$pair,
|
||||
$this
|
||||
);
|
||||
}else{
|
||||
$player->windows[$id] = array(
|
||||
$this,
|
||||
$pair
|
||||
);
|
||||
}
|
||||
}else{
|
||||
$player->windows[$id] = $this;
|
||||
}
|
||||
|
||||
$pk = new ContainerOpenPacket();
|
||||
$pk->windowid = $id;
|
||||
$pk->type = 0;
|
||||
$pk->slots = is_array($player->windows[$id]) ? Chest::SLOTS << 1 : Chest::SLOTS;
|
||||
$pk->x = $this->x;
|
||||
$pk->y = $this->y;
|
||||
$pk->z = $this->z;
|
||||
$player->dataPacket($pk);
|
||||
$slots = array();
|
||||
|
||||
if(is_array($player->windows[$id])){
|
||||
$all = $this->level->getPlayers();
|
||||
foreach($player->windows[$id] as $ob){
|
||||
$pk = new TileEventPacket();
|
||||
$pk->x = $ob->x;
|
||||
$pk->y = $ob->y;
|
||||
$pk->z = $ob->z;
|
||||
$pk->case1 = 1;
|
||||
$pk->case2 = 2;
|
||||
Player::broadcastPacket($all, $pk);
|
||||
for($s = 0; $s < Chest::SLOTS; ++$s){
|
||||
$slot = $ob->getSlot($s);
|
||||
if($slot->getID() > Item::AIR and $slot->getCount() > 0){
|
||||
$slots[] = $slot;
|
||||
}else{
|
||||
$slots[] = Item::get(Item::AIR, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
$pk = new TileEventPacket();
|
||||
$pk->x = $this->x;
|
||||
$pk->y = $this->y;
|
||||
$pk->z = $this->z;
|
||||
$pk->case1 = 1;
|
||||
$pk->case2 = 2;
|
||||
Player::broadcastPacket($this->level->getPlayers(), $pk);
|
||||
for($s = 0; $s < Chest::SLOTS; ++$s){
|
||||
$slot = $this->getSlot($s);
|
||||
if($slot->getID() > Item::AIR and $slot->getCount() > 0){
|
||||
$slots[] = $slot;
|
||||
}else{
|
||||
$slots[] = Item::get(Item::AIR, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$pk = new ContainerSetContentPacket();
|
||||
$pk->windowid = $id;
|
||||
$pk->slots = $slots;
|
||||
$player->dataPacket($pk);
|
||||
|
||||
return true;
|
||||
}elseif($this instanceof Furnace){
|
||||
$player->windowCnt++;
|
||||
$player->windowCnt = $id = max(2, $player->windowCnt % 99);
|
||||
$player->windows[$id] = $this;
|
||||
|
||||
$pk = new ContainerOpenPacket();
|
||||
$pk->windowid = $id;
|
||||
$pk->type = 2;
|
||||
$pk->slots = Furnace::SLOTS;
|
||||
$pk->x = $this->x;
|
||||
$pk->y = $this->y;
|
||||
$pk->z = $this->z;
|
||||
$player->dataPacket($pk);
|
||||
|
||||
$slots = array();
|
||||
for($s = 0; $s < Furnace::SLOTS; ++$s){
|
||||
$slot = $this->getSlot($s);
|
||||
if($slot->getID() > Item::AIR and $slot->getCount() > 0){
|
||||
$slots[] = $slot;
|
||||
}else{
|
||||
$slots[] = Item::get(Item::AIR, 0, 0);
|
||||
}
|
||||
}
|
||||
$pk = new ContainerSetContentPacket();
|
||||
$pk->windowid = $id;
|
||||
$pk->slots = $slots;
|
||||
$player->dataPacket($pk);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public function getSlotIndex($s){
|
||||
foreach($this->namedtag->Items as $i => $slot){
|
||||
if($slot["Slot"] === $s){
|
||||
return $i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public function getSlot($s){
|
||||
$i = $this->getSlotIndex($s);
|
||||
if($i === false or $i < 0){
|
||||
return Item::get(Item::AIR, 0, 0);
|
||||
}else{
|
||||
return Item::get($this->namedtag->Items[$i]["id"], $this->namedtag->Items[$i]["Damage"], $this->namedtag->Items[$i]["Count"]);
|
||||
}
|
||||
}
|
||||
|
||||
public function setSlot($s, Item $item, $update = true, $offset = 0){
|
||||
$i = $this->getSlotIndex($s);
|
||||
if($i === false){
|
||||
return false;
|
||||
}
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new TileInventoryChangeEvent($this, $this->getSlot($s), $item, $s, $offset));
|
||||
if($ev->isCancelled()){
|
||||
return false;
|
||||
}
|
||||
|
||||
$item = $ev->getNewItem();
|
||||
$d = new Compound(false, array(
|
||||
new Byte("Count", $item->getCount()),
|
||||
new Byte("Slot", $s),
|
||||
new Short("id", $item->getID()),
|
||||
new Short("Damage", $item->getMetadata()),
|
||||
));
|
||||
|
||||
if($item->getID() === Item::AIR or $item->getCount() <= 0){
|
||||
if($i >= 0){
|
||||
unset($this->namedtag->Items[$i]);
|
||||
}
|
||||
}elseif($i < 0){
|
||||
$this->namedtag->Items[] = $d;
|
||||
}else{
|
||||
$this->namedtag->Items[$i] = $d;
|
||||
}
|
||||
|
||||
if($update === true){
|
||||
$this->scheduleUpdate();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,118 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\tile;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\nbt\tag\Compound;
|
||||
|
||||
class Furnace extends Tile{
|
||||
use Container;
|
||||
|
||||
const SLOTS = 3;
|
||||
|
||||
public function __construct(Level $level, Compound $nbt){
|
||||
$nbt["id"] = Tile::FURNACE;
|
||||
parent::__construct($level, $nbt);
|
||||
if(!isset($this->namedtag->BurnTime) or $this->namedtag->BurnTime < 0){
|
||||
$this->namedtag->BurnTime = 0;
|
||||
}
|
||||
if(!isset($this->namedtag->CookTime) or $this->namedtag->CookTime < 0 or ($this->namedtag->BurnTime === 0 and $this->namedtag->CookTime > 0)){
|
||||
$this->namedtag->CookTime = 0;
|
||||
}
|
||||
if(!isset($this->namedtag->MaxTime)){
|
||||
$this->namedtag->MaxTime = $this->namedtag->BurnTime;
|
||||
$this->namedtag->BurnTicks = 0;
|
||||
}
|
||||
if($this->namedtag->BurnTime > 0){
|
||||
$this->scheduleUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public function onUpdate(){
|
||||
if($this->closed === true){
|
||||
return false;
|
||||
}
|
||||
|
||||
$ret = false;
|
||||
|
||||
$fuel = $this->getSlot(1);
|
||||
$raw = $this->getSlot(0);
|
||||
$product = $this->getSlot(2);
|
||||
$smelt = $raw->getSmeltItem();
|
||||
$canSmelt = ($smelt !== false and $raw->getCount() > 0 and (($product->getID() === $smelt->getID() and $product->getMetadata() === $smelt->getMetadata() and $product->getCount() < $product->getMaxStackSize()) or $product->getID() === Item::AIR));
|
||||
if($this->namedtag->BurnTime <= 0 and $canSmelt and $fuel->getFuelTime() !== false and $fuel->getCount() > 0){
|
||||
$this->lastUpdate = microtime(true);
|
||||
$this->namedtag->MaxTime = $this->namedtag->BurnTime = floor($fuel->getFuelTime() * 20);
|
||||
$this->namedtag->BurnTicks = 0;
|
||||
$fuel->setCount($fuel->getCount() - 1);
|
||||
if($fuel->getCount() === 0){
|
||||
$fuel = Item::get(Item::AIR, 0, 0);
|
||||
}
|
||||
$this->setSlot(1, $fuel, false);
|
||||
$current = $this->level->getBlock($this);
|
||||
if($current->getID() === Item::FURNACE){
|
||||
$this->level->setBlock($this, Block::get(Item::BURNING_FURNACE, $current->getMetadata()), true, false, true);
|
||||
}
|
||||
}
|
||||
if($this->namedtag->BurnTime > 0){
|
||||
$ticks = (microtime(true) - $this->lastUpdate) * 20;
|
||||
$this->namedtag->BurnTime -= $ticks;
|
||||
$this->namedtag->BurnTicks = ceil(($this->namedtag->BurnTime / $this->namedtag->MaxTime) * 200);
|
||||
if($smelt !== false and $canSmelt){
|
||||
$this->namedtag->CookTime += $ticks;
|
||||
if($this->namedtag->CookTime >= 200){ //10 seconds
|
||||
$product = Item::get($smelt->getID(), $smelt->getMetadata(), $product->getCount() + 1);
|
||||
$this->setSlot(2, $product, false);
|
||||
$raw->setCount($raw->getCount() - 1);
|
||||
if($raw->getCount() === 0){
|
||||
$raw = Item::get(Item::AIR, 0, 0);
|
||||
}
|
||||
$this->setSlot(0, $raw, false);
|
||||
$this->namedtag->CookTime -= 200;
|
||||
}
|
||||
}elseif($this->namedtag->BurnTime <= 0){
|
||||
$this->namedtag->BurnTime = 0;
|
||||
$this->namedtag->CookTime = 0;
|
||||
$this->namedtag->BurnTicks = 0;
|
||||
}else{
|
||||
$this->namedtag->CookTime = 0;
|
||||
}
|
||||
$ret = true;
|
||||
}else{
|
||||
$current = $this->level->getBlock($this);
|
||||
if($current->getID() === Item::BURNING_FURNACE){
|
||||
$this->level->setBlock($this, Block::get(Item::FURNACE, $current->getMetadata()), true, false, true);
|
||||
}
|
||||
$this->namedtag->CookTime = 0;
|
||||
$this->namedtag->BurnTime = 0;
|
||||
$this->namedtag->BurnTicks = 0;
|
||||
}
|
||||
|
||||
|
||||
$this->server->handle("tile.update", $this);
|
||||
$this->lastUpdate = microtime(true);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
@ -1,732 +0,0 @@
|
||||
#!/bin/bash
|
||||
PHP_VERSION="5.5.10"
|
||||
ZEND_VM="GOTO"
|
||||
|
||||
ZLIB_VERSION="1.2.8"
|
||||
OPENSSL_VERSION="1.0.0l"
|
||||
CURL_VERSION="curl-7_35_0"
|
||||
READLINE_VERSION="6.3"
|
||||
NCURSES_VERSION="5.9"
|
||||
PHPNCURSES_VERSION="1.0.2"
|
||||
PTHREADS_VERSION="2.0.4"
|
||||
WEAKREF_VERSION="0.2.2"
|
||||
PHPYAML_VERSION="1.1.1"
|
||||
YAML_VERSION="0.1.4"
|
||||
LIBXML_VERSION="2.9.1"
|
||||
BCOMPILER_VERSION="1.0.2"
|
||||
|
||||
echo "[PocketMine] PHP compiler for Linux, MacOS and Android"
|
||||
DIR="$(pwd)"
|
||||
date > "$DIR/install.log" 2>&1
|
||||
trap "echo \"# \$(eval echo \$BASH_COMMAND)\" >> \"$DIR/install.log\" 2>&1" DEBUG
|
||||
uname -a >> "$DIR/install.log" 2>&1
|
||||
echo "[INFO] Checking dependecies"
|
||||
type make >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"make\""; read -p "Press [Enter] to continue..."; exit 1; }
|
||||
type autoconf >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"autoconf\""; read -p "Press [Enter] to continue..."; exit 1; }
|
||||
type automake >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"automake\""; read -p "Press [Enter] to continue..."; exit 1; }
|
||||
type libtool >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"libtool\""; read -p "Press [Enter] to continue..."; exit 1; }
|
||||
type m4 >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"m4\""; read -p "Press [Enter] to continue..."; exit 1; }
|
||||
type wget >> "$DIR/install.log" 2>&1 || type curl >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"wget\" or \"curl\""; read -p "Press [Enter] to continue..."; exit 1; }
|
||||
type getconf >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"getconf\""; read -p "Press [Enter] to continue..."; exit 1; }
|
||||
|
||||
#Needed to use aliases
|
||||
shopt -s expand_aliases
|
||||
type wget >> "$DIR/install.log" 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
alias download_file="wget --no-check-certificate -q -O -"
|
||||
else
|
||||
type curl >> "$DIR/install.log" 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
alias download_file="curl --insecure --silent --location"
|
||||
else
|
||||
echo "error, curl or wget not found"
|
||||
fi
|
||||
fi
|
||||
|
||||
export CC="gcc"
|
||||
COMPILE_FOR_ANDROID=no
|
||||
RANLIB=ranlib
|
||||
HAVE_MYSQLI="--enable-embedded-mysqli --enable-mysqlnd --with-mysqli=mysqlnd"
|
||||
COMPILE_TARGET=""
|
||||
COMPILE_OPENSSL="no"
|
||||
COMPILE_CURL="default"
|
||||
COMPILE_FANCY="no"
|
||||
IS_CROSSCOMPILE="no"
|
||||
IS_WINDOWS="no"
|
||||
DO_OPTIMIZE="no"
|
||||
DO_STATIC="no"
|
||||
while getopts "::t:oj:srcxff:" OPTION; do
|
||||
case $OPTION in
|
||||
t)
|
||||
echo "[opt] Set target to $OPTARG"
|
||||
COMPILE_TARGET="$OPTARG"
|
||||
;;
|
||||
j)
|
||||
echo "[opt] Set make threads to $OPTARG"
|
||||
THREADS="$OPTARG"
|
||||
;;
|
||||
o)
|
||||
echo "[opt] Will compile OpenSSL"
|
||||
COMPILE_OPENSSL="yes"
|
||||
;;
|
||||
r)
|
||||
echo "[opt] Will compile readline and ncurses"
|
||||
COMPILE_FANCY="yes"
|
||||
;;
|
||||
c)
|
||||
echo "[opt] Will force compile cURL"
|
||||
COMPILE_CURL="yes"
|
||||
;;
|
||||
x)
|
||||
echo "[opt] Doing cross-compile"
|
||||
IS_CROSSCOMPILE="yes"
|
||||
;;
|
||||
s)
|
||||
echo "[opt] Will compile everything statically"
|
||||
DO_STATIC="yes"
|
||||
;;
|
||||
f)
|
||||
echo "[opt] Enabling abusive optimizations..."
|
||||
DO_OPTIMIZE="yes"
|
||||
ffast_math="-fno-math-errno -funsafe-math-optimizations -fno-trapping-math -ffinite-math-only -fno-rounding-math -fno-signaling-nans -fcx-limited-range" #workaround SQLite3 fail
|
||||
CFLAGS="$CFLAGS -O2 -DSQLITE_HAVE_ISNAN $ffast_math -fno-signed-zeros -funsafe-loop-optimizations -fomit-frame-pointer -frename-registers -funroll-loops -funswitch-loops -fpredictive-commoning -fgcse-after-reload -ftree-vectorize -ftracer -ftree-loop-im -fivopts -ftree-parallelize-loops=4"
|
||||
if [ "$OPTARG" == "arm" ]; then
|
||||
CFLAGS="$CFLAGS -mfloat-abi=softfp -mfpu=vfp"
|
||||
elif [ "$OPTARG" == "x86_64" ]; then
|
||||
CFLAGS="$CFLAGS -mmx -msse -msse2 -msse3 -mfpmath=sse -free -msahf"
|
||||
elif [ "$OPTARG" == "x86" ]; then
|
||||
CFLAGS="$CFLAGS -mmx -msse -msse2 -mfpmath=sse -m128bit-long-double -malign-double"
|
||||
fi
|
||||
;;
|
||||
\?)
|
||||
echo "Invalid option: -$OPTION$OPTARG" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "$IS_CROSSCOMPILE" == "yes" ]; then
|
||||
if [ "$COMPILE_TARGET" == "win" ] || [ "$COMPILE_TARGET" == "win32" ]; then
|
||||
TOOLCHAIN_PREFIX="i686-w64-mingw32"
|
||||
[ -z "$march" ] && march=i686;
|
||||
[ -z "$mtune" ] && mtune=pentium4;
|
||||
CFLAGS="$CFLAGS -mconsole"
|
||||
export CC="$TOOLCHAIN_PREFIX-gcc"
|
||||
CONFIGURE_FLAGS="--host=$TOOLCHAIN_PREFIX --target=$TOOLCHAIN_PREFIX --build=$TOOLCHAIN_PREFIX"
|
||||
OPENSSL_TARGET="mingw"
|
||||
IS_WINDOWS="yes"
|
||||
echo "[INFO] Cross-compiling for Windows 32-bit"
|
||||
elif [ "$COMPILE_TARGET" == "win64" ]; then
|
||||
TOOLCHAIN_PREFIX="x86_64-w64-mingw32"
|
||||
[ -z "$march" ] && march=x86_64;
|
||||
[ -z "$mtune" ] && mtune=nocona;
|
||||
CFLAGS="$CFLAGS -mconsole"
|
||||
export CC="$TOOLCHAIN_PREFIX-gcc"
|
||||
CONFIGURE_FLAGS="--host=$TOOLCHAIN_PREFIX --target=$TOOLCHAIN_PREFIX --build=$TOOLCHAIN_PREFIX"
|
||||
OPENSSL_TARGET="mingw"
|
||||
IS_WINDOWS="yes"
|
||||
echo "[INFO] Cross-compiling for Windows 64-bit"
|
||||
elif [ "$COMPILE_TARGET" == "android" ] || [ "$COMPILE_TARGET" == "android-armv6" ]; then
|
||||
COMPILE_FOR_ANDROID=yes
|
||||
[ -z "$march" ] && march=armv6;
|
||||
[ -z "$mtune" ] && mtune=arm1136jf-s;
|
||||
TOOLCHAIN_PREFIX="arm-unknown-linux-uclibcgnueabi"
|
||||
export CC="$TOOLCHAIN_PREFIX-gcc"
|
||||
CONFIGURE_FLAGS="--host=$TOOLCHAIN_PREFIX --enable-static-link --disable-ipv6"
|
||||
CFLAGS="-static -uclibc -Wl,-Bdynamic $CFLAGS"
|
||||
echo "[INFO] Cross-compiling for Android ARMv6"
|
||||
OPENSSL_TARGET="android"
|
||||
HAVE_MYSQLI="--without-mysqli"
|
||||
elif [ "$COMPILE_TARGET" == "android-armv7" ]; then
|
||||
COMPILE_FOR_ANDROID=yes
|
||||
[ -z "$march" ] && march=armv7-a;
|
||||
[ -z "$mtune" ] && mtune=cortex-a8;
|
||||
TOOLCHAIN_PREFIX="arm-unknown-linux-uclibcgnueabi"
|
||||
export CC="$TOOLCHAIN_PREFIX-gcc"
|
||||
CONFIGURE_FLAGS="--host=$TOOLCHAIN_PREFIX --enable-static-link --disable-ipv6"
|
||||
CFLAGS="-static -uclibc -Wl,-Bdynamic $CFLAGS"
|
||||
echo "[INFO] Cross-compiling for Android ARMv7"
|
||||
OPENSSL_TARGET="android-armv7"
|
||||
HAVE_MYSQLI="--without-mysqli"
|
||||
elif [ "$COMPILE_TARGET" == "rpi" ]; then
|
||||
TOOLCHAIN_PREFIX="arm-linux-gnueabihf"
|
||||
[ -z "$march" ] && march=armv6zk;
|
||||
[ -z "$mtune" ] && mtune=arm1176jzf-s;
|
||||
CFLAGS="$CFLAGS -mfloat-abi=hard -mfpu=vfp";
|
||||
if [ "$DO_OPTIMIZE" == "yes" ]; then
|
||||
CFLAGS="$CFLAGS -mfloat-abi=hard -mfpu=vfp"
|
||||
fi
|
||||
export CC="$TOOLCHAIN_PREFIX-gcc"
|
||||
CONFIGURE_FLAGS="--host=$TOOLCHAIN_PREFIX"
|
||||
[ -z "$CFLAGS" ] && CFLAGS="-uclibc";
|
||||
OPENSSL_TARGET="linux-armv4"
|
||||
echo "[INFO] Cross-compiling for Raspberry Pi ARMv6zk hard float"
|
||||
elif [ "$COMPILE_TARGET" == "mac" ]; then
|
||||
[ -z "$march" ] && march=prescott;
|
||||
[ -z "$mtune" ] && mtune=generic;
|
||||
CFLAGS="$CFLAGS -fomit-frame-pointer";
|
||||
TOOLCHAIN_PREFIX="i686-apple-darwin10"
|
||||
export CC="$TOOLCHAIN_PREFIX-gcc"
|
||||
CONFIGURE_FLAGS="--host=$TOOLCHAIN_PREFIX"
|
||||
#zlib doesn't use the correct ranlib
|
||||
RANLIB=$TOOLCHAIN_PREFIX-ranlib
|
||||
OPENSSL_TARGET="darwin64-x86_64-cc"
|
||||
CFLAGS="$CFLAGS -Qunused-arguments -Wno-error=unused-command-line-argument-hard-error-in-future"
|
||||
ARCHFLAGS="-Wno-error=unused-command-line-argument-hard-error-in-future"
|
||||
echo "[INFO] Cross-compiling for Intel MacOS"
|
||||
elif [ "$COMPILE_TARGET" == "ios" ] || [ "$COMPILE_TARGET" == "ios-armv6" ]; then
|
||||
[ -z "$march" ] && march=armv6;
|
||||
[ -z "$mtune" ] && mtune=arm1176jzf-s;
|
||||
TOOLCHAIN_PREFIX="arm-apple-darwin10"
|
||||
export CC="$TOOLCHAIN_PREFIX-gcc"
|
||||
CONFIGURE_FLAGS="--host=$TOOLCHAIN_PREFIX --target=$TOOLCHAIN_PREFIX -miphoneos-version-min=4.2"
|
||||
OPENSSL_TARGET="BSD-generic32"
|
||||
HAVE_MYSQLI="--without-mysqli"
|
||||
elif [ "$COMPILE_TARGET" == "ios-armv7" ]; then
|
||||
[ -z "$march" ] && march=armv7-a;
|
||||
[ -z "$mtune" ] && mtune=cortex-a8;
|
||||
TOOLCHAIN_PREFIX="arm-apple-darwin10"
|
||||
export CC="$TOOLCHAIN_PREFIX-gcc"
|
||||
CONFIGURE_FLAGS="--host=$TOOLCHAIN_PREFIX --target=$TOOLCHAIN_PREFIX -miphoneos-version-min=4.2"
|
||||
OPENSSL_TARGET="BSD-generic32"
|
||||
HAVE_MYSQLI="--without-mysqli"
|
||||
if [ "$DO_OPTIMIZE" == "yes" ]; then
|
||||
CFLAGS="$CFLAGS -mfpu=neon"
|
||||
fi
|
||||
else
|
||||
echo "Please supply a proper platform [android android-armv6 android-armv7 rpi mac ios ios-armv6 ios-armv7 win win32 win64] to cross-compile"
|
||||
exit 1
|
||||
fi
|
||||
elif [ "$COMPILE_TARGET" == "linux" ] || [ "$COMPILE_TARGET" == "linux32" ]; then
|
||||
[ -z "$march" ] && march=i686;
|
||||
[ -z "$mtune" ] && mtune=pentium4;
|
||||
CFLAGS="$CFLAGS -m32";
|
||||
OPENSSL_TARGET="linux-generic32"
|
||||
echo "[INFO] Compiling for Linux x86"
|
||||
elif [ "$COMPILE_TARGET" == "linux64" ]; then
|
||||
[ -z "$march" ] && march=x86-64;
|
||||
[ -z "$mtune" ] && mtune=nocona;
|
||||
CFLAGS="$CFLAGS -m64"
|
||||
OPENSSL_TARGET="linux-x86_64"
|
||||
echo "[INFO] Compiling for Linux x86_64"
|
||||
elif [ "$COMPILE_TARGET" == "rpi" ]; then
|
||||
[ -z "$march" ] && march=armv6zk;
|
||||
[ -z "$mtune" ] && mtune=arm1176jzf-s;
|
||||
CFLAGS="$CFLAGS -mfloat-abi=hard -mfpu=vfp";
|
||||
OPENSSL_TARGET="linux-armv4"
|
||||
echo "[INFO] Compiling for Raspberry Pi ARMv6zk hard float"
|
||||
elif [ "$COMPILE_TARGET" == "mac" ] || [ "$COMPILE_TARGET" == "mac32" ]; then
|
||||
[ -z "$march" ] && march=prescott;
|
||||
[ -z "$mtune" ] && mtune=generic;
|
||||
CFLAGS="$CFLAGS -m32 -arch i386 -fomit-frame-pointer -mmacosx-version-min=10.5";
|
||||
LDFLAGS="$LDFLAGS -Wl,-rpath,@loader_path/../lib";
|
||||
export DYLD_LIBRARY_PATH="@loader_path/../lib"
|
||||
OPENSSL_TARGET="darwin-i386-cc"
|
||||
CFLAGS="$CFLAGS -Qunused-arguments -Wno-error=unused-command-line-argument-hard-error-in-future"
|
||||
ARCHFLAGS="-Wno-error=unused-command-line-argument-hard-error-in-future"
|
||||
echo "[INFO] Compiling for Intel MacOS x86"
|
||||
elif [ "$COMPILE_TARGET" == "mac64" ]; then
|
||||
[ -z "$march" ] && march=core2;
|
||||
[ -z "$mtune" ] && mtune=generic;
|
||||
CFLAGS="$CFLAGS -m64 -arch x86_64 -fomit-frame-pointer -mmacosx-version-min=10.5";
|
||||
LDFLAGS="$LDFLAGS -Wl,-rpath,@loader_path/../lib";
|
||||
export DYLD_LIBRARY_PATH="@loader_path/../lib"
|
||||
OPENSSL_TARGET="darwin64-x86_64-cc"
|
||||
CFLAGS="$CFLAGS -Qunused-arguments -Wno-error=unused-command-line-argument-hard-error-in-future"
|
||||
ARCHFLAGS="-Wno-error=unused-command-line-argument-hard-error-in-future"
|
||||
echo "[INFO] Compiling for Intel MacOS x86_64"
|
||||
elif [ "$COMPILE_TARGET" == "ios" ]; then
|
||||
[ -z "$march" ] && march=armv7-a;
|
||||
[ -z "$mtune" ] && mtune=cortex-a8;
|
||||
echo "[INFO] Compiling for iOS ARMv7"
|
||||
OPENSSL_TARGET="linux-armv4"
|
||||
elif [ -z "$CFLAGS" ]; then
|
||||
if [ `getconf LONG_BIT` == "64" ]; then
|
||||
echo "[INFO] Compiling for current machine using 64-bit"
|
||||
CFLAGS="-m64 $CFLAGS"
|
||||
OPENSSL_TARGET="linux-x86_64"
|
||||
else
|
||||
echo "[INFO] Compiling for current machine using 32-bit"
|
||||
CFLAGS="-m32 $CFLAGS"
|
||||
OPENSSL_TARGET="linux-generic32"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "#include <stdio.h> \
|
||||
int main(void){ \
|
||||
printf("Hello world\n"); \
|
||||
return 0; \
|
||||
}" > test.c
|
||||
|
||||
|
||||
type $CC >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"$CC\""; read -p "Press [Enter] to continue..."; exit 1; }
|
||||
|
||||
[ -z "$THREADS" ] && THREADS=1;
|
||||
[ -z "$march" ] && march=native;
|
||||
[ -z "$mtune" ] && mtune=native;
|
||||
[ -z "$CFLAGS" ] && CFLAGS="";
|
||||
[ -z "$LDFLAGS" ] && LDFLAGS="-Wl,-rpath='\$\$ORIGIN/../lib'";
|
||||
[ -z "$CONFIGURE_FLAGS" ] && CONFIGURE_FLAGS="";
|
||||
|
||||
|
||||
if [ "$mtune" != "none" ]; then
|
||||
$CC -march=$march -mtune=$mtune $CFLAGS -o test test.c >> "$DIR/install.log" 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
CFLAGS="-march=$march -mtune=$mtune -fno-gcse $CFLAGS"
|
||||
fi
|
||||
else
|
||||
$CC -march=$march $CFLAGS -o test test.c >> "$DIR/install.log" 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
CFLAGS="-march=$march -fno-gcse $CFLAGS"
|
||||
fi
|
||||
fi
|
||||
|
||||
rm test.* >> "$DIR/install.log" 2>&1
|
||||
rm test >> "$DIR/install.log" 2>&1
|
||||
|
||||
export CFLAGS="-O2 -fPIC $CFLAGS"
|
||||
export LDFLAGS="$LDFLAGS"
|
||||
|
||||
rm -r -f install_data/ >> "$DIR/install.log" 2>&1
|
||||
rm -r -f bin/ >> "$DIR/install.log" 2>&1
|
||||
mkdir -m 0755 install_data >> "$DIR/install.log" 2>&1
|
||||
mkdir -m 0755 bin >> "$DIR/install.log" 2>&1
|
||||
mkdir -m 0755 bin/php5 >> "$DIR/install.log" 2>&1
|
||||
cd install_data
|
||||
set -e
|
||||
|
||||
#PHP 5
|
||||
echo -n "[PHP] downloading $PHP_VERSION..."
|
||||
download_file "http://php.net/get/php-$PHP_VERSION.tar.gz/from/this/mirror" | tar -zx >> "$DIR/install.log" 2>&1
|
||||
mv php-$PHP_VERSION php
|
||||
echo " done!"
|
||||
|
||||
if [ "$COMPILE_FANCY" == "yes" ]; then
|
||||
if [ "$DO_STATIC" == "yes" ]; then
|
||||
EXTRA_FLAGS="--without-shared --with-static"
|
||||
else
|
||||
EXTRA_FLAGS="--with-shared --without-static"
|
||||
fi
|
||||
#ncurses
|
||||
echo -n "[ncurses] downloading $NCURSES_VERSION..."
|
||||
download_file "http://ftp.gnu.org/gnu/ncurses/ncurses-$NCURSES_VERSION.tar.gz" | tar -zx >> "$DIR/install.log" 2>&1
|
||||
mv ncurses-$NCURSES_VERSION ncurses
|
||||
echo -n " checking..."
|
||||
cd ncurses
|
||||
./configure --prefix="$DIR/bin/php5" \
|
||||
--without-ada \
|
||||
--without-manpages \
|
||||
--without-progs \
|
||||
--without-tests \
|
||||
--with-normal \
|
||||
--with-pthread \
|
||||
--without-debug \
|
||||
$EXTRA_FLAGS \
|
||||
$CONFIGURE_FLAGS >> "$DIR/install.log" 2>&1
|
||||
echo -n " compiling..."
|
||||
make -j $THREADS >> "$DIR/install.log" 2>&1
|
||||
echo -n " installing..."
|
||||
make install >> "$DIR/install.log" 2>&1
|
||||
echo -n " cleaning..."
|
||||
cd ..
|
||||
rm -r -f ./ncurses
|
||||
echo " done!"
|
||||
HAVE_NCURSES="--with-ncurses=$DIR/bin/php5"
|
||||
|
||||
if [ "$DO_STATIC" == "yes" ]; then
|
||||
EXTRA_FLAGS="--enable-shared=no --enable-static=yes"
|
||||
else
|
||||
EXTRA_FLAGS="--enable-shared=yes --enable-static=no"
|
||||
fi
|
||||
#readline
|
||||
set +e
|
||||
echo -n "[readline] downloading $READLINE_VERSION..."
|
||||
download_file "http://ftp.gnu.org/gnu/readline/readline-$READLINE_VERSION.tar.gz" | tar -zx >> "$DIR/install.log" 2>&1
|
||||
mv readline-$READLINE_VERSION readline
|
||||
echo -n " checking..."
|
||||
cd readline
|
||||
./configure --prefix="$DIR/bin/php5" \
|
||||
--with-curses="$DIR/bin/php5" \
|
||||
--enable-multibyte \
|
||||
$EXTRA_FLAGS \
|
||||
$CONFIGURE_FLAGS >> "$DIR/install.log" 2>&1
|
||||
echo -n " compiling..."
|
||||
if make -j $THREADS >> "$DIR/install.log" 2>&1; then
|
||||
echo -n " installing..."
|
||||
make install >> "$DIR/install.log" 2>&1
|
||||
HAVE_READLINE="--with-readline=$DIR/bin/php5"
|
||||
else
|
||||
echo -n " disabling..."
|
||||
HAVE_READLINE="--without-readline"
|
||||
fi
|
||||
echo -n " cleaning..."
|
||||
cd ..
|
||||
rm -r -f ./readline
|
||||
echo " done!"
|
||||
set -e
|
||||
else
|
||||
HAVE_NCURSES="--without-ncurses"
|
||||
HAVE_READLINE="--without-readline"
|
||||
fi
|
||||
|
||||
|
||||
if [ "$DO_STATIC" == "yes" ]; then
|
||||
EXTRA_FLAGS="--static"
|
||||
else
|
||||
EXTRA_FLAGS="--shared"
|
||||
fi
|
||||
|
||||
#zlib
|
||||
download_file "https://github.com/madler/zlib/archive/v$ZLIB_VERSION.tar.gz" | tar -zx >> "$DIR/install.log" 2>&1
|
||||
echo -n "[zlib] downloading $ZLIB_VERSION..."
|
||||
mv zlib-$ZLIB_VERSION zlib
|
||||
echo -n " checking..."
|
||||
cd zlib
|
||||
RANLIB=$RANLIB ./configure --prefix="$DIR/bin/php5" \
|
||||
$EXTRA_FLAGS >> "$DIR/install.log" 2>&1
|
||||
echo -n " compiling..."
|
||||
make -j $THREADS >> "$DIR/install.log" 2>&1
|
||||
echo -n " installing..."
|
||||
make install >> "$DIR/install.log" 2>&1
|
||||
echo -n " cleaning..."
|
||||
cd ..
|
||||
rm -r -f ./zlib
|
||||
if [ "$DO_STATIC" != "yes" ]; then
|
||||
rm -f "$DIR/bin/php5/lib/libz.a"
|
||||
fi
|
||||
echo " done!"
|
||||
|
||||
if [ "$COMPILE_OPENSSL" == "yes" ] || [ "$COMPILE_CURL" != "no" ] && [ "$IS_CROSSCOMPILE" != "yes" ]; then
|
||||
#if [ "$DO_STATIC" == "yes" ]; then
|
||||
# EXTRA_FLAGS=""
|
||||
#else
|
||||
# EXTRA_FLAGS="shared no-static"
|
||||
#fi
|
||||
EXTRA_FLAGS="shared no-static"
|
||||
|
||||
|
||||
#OpenSSL
|
||||
WITH_SSL="--with-ssl=$DIR/bin/php5"
|
||||
WITH_OPENSSL="--with-openssl=$DIR/bin/php5"
|
||||
echo -n "[OpenSSL] downloading $OPENSSL_VERSION..."
|
||||
download_file "http://www.openssl.org/source/openssl-$OPENSSL_VERSION.tar.gz" | tar -zx >> "$DIR/install.log" 2>&1
|
||||
mv openssl-$OPENSSL_VERSION openssl
|
||||
echo -n " checking..."
|
||||
cd openssl
|
||||
RANLIB=$RANLIB ./Configure \
|
||||
$OPENSSL_TARGET \
|
||||
--prefix="$DIR/bin/php5" \
|
||||
--openssldir="$DIR/bin/php5" \
|
||||
zlib \
|
||||
zlib-dynamic \
|
||||
--with-zlib-lib="$DIR/bin/php5/lib" \
|
||||
--with-zlib-include="$DIR/bin/php5/include" \
|
||||
$EXTRA_FLAGS \
|
||||
no-ssl2 \
|
||||
no-asm \
|
||||
no-hw \
|
||||
no-engines \
|
||||
$CONFIGURE_FLAGS >> "$DIR/install.log" 2>&1
|
||||
echo -n " compiling..."
|
||||
make depend >> "$DIR/install.log" 2>&1
|
||||
make >> "$DIR/install.log" 2>&1
|
||||
echo -n " installing..."
|
||||
make install >> "$DIR/install.log" 2>&1
|
||||
echo -n " cleaning..."
|
||||
cd ..
|
||||
rm -r -f ./openssh
|
||||
if [ "$DO_STATIC" != "yes" ]; then
|
||||
rm -f "$DIR/bin/php5/lib/libcrypto.a" "$DIR/bin/php5/lib/libssl.a"
|
||||
fi
|
||||
echo " done!"
|
||||
else
|
||||
WITH_SSL="--with-ssl"
|
||||
WITH_OPENSSL="--without-ssl"
|
||||
if [ "$(uname -s)" == "Darwin" ] && [ "$COMPILE_TARGET" != "crosscompile" ]; then
|
||||
WITH_SSL="--with-darwinssl"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$(uname -s)" == "Darwin" ] && [ "$IS_CROSSCOMPILE" != "yes" ] && [ "$COMPILE_CURL" != "yes" ]; then
|
||||
HAVE_CURL="shared,/usr"
|
||||
else
|
||||
if [ "$DO_STATIC" == "yes" ]; then
|
||||
EXTRA_FLAGS="--enable-static --disable-shared"
|
||||
else
|
||||
EXTRA_FLAGS="--disable-static --enable-shared"
|
||||
fi
|
||||
|
||||
#curl
|
||||
echo -n "[cURL] downloading $CURL_VERSION..."
|
||||
download_file "https://github.com/bagder/curl/archive/$CURL_VERSION.tar.gz" | tar -zx >> "$DIR/install.log" 2>&1
|
||||
mv curl-$CURL_VERSION curl
|
||||
echo -n " checking..."
|
||||
cd curl
|
||||
if [ ! -f ./configure ]; then
|
||||
./buildconf --force >> "$DIR/install.log" 2>&1
|
||||
fi
|
||||
RANLIB=$RANLIB ./configure --disable-dependency-tracking \
|
||||
--enable-ipv6 \
|
||||
--enable-optimize \
|
||||
--enable-http \
|
||||
--enable-ftp \
|
||||
--disable-dict \
|
||||
--enable-file \
|
||||
--without-librtmp \
|
||||
--disable-gopher \
|
||||
--disable-imap \
|
||||
--disable-pop3 \
|
||||
--disable-rtsp \
|
||||
--disable-smtp \
|
||||
--disable-telnet \
|
||||
--disable-tftp \
|
||||
--disable-ldap \
|
||||
--disable-ldaps \
|
||||
--without-libidn \
|
||||
--with-zlib="$DIR/bin/php5" \
|
||||
$WITH_SSL \
|
||||
--enable-threaded-resolver \
|
||||
--prefix="$DIR/bin/php5" \
|
||||
$EXTRA_FLAGS \
|
||||
$CONFIGURE_FLAGS >> "$DIR/install.log" 2>&1
|
||||
echo -n " compiling..."
|
||||
make -j $THREADS >> "$DIR/install.log" 2>&1
|
||||
echo -n " installing..."
|
||||
make install >> "$DIR/install.log" 2>&1
|
||||
echo -n " cleaning..."
|
||||
cd ..
|
||||
rm -r -f ./curl
|
||||
echo " done!"
|
||||
HAVE_CURL="$DIR/bin/php5"
|
||||
fi
|
||||
|
||||
# PECL libraries
|
||||
|
||||
#pthreads
|
||||
echo -n "[PHP pthreads] downloading $PTHREADS_VERSION..."
|
||||
download_file "http://pecl.php.net/get/pthreads-$PTHREADS_VERSION.tgz" | tar -zx >> "$DIR/install.log" 2>&1
|
||||
mv pthreads-$PTHREADS_VERSION "$DIR/install_data/php/ext/pthreads"
|
||||
echo " done!"
|
||||
|
||||
#WeakRef
|
||||
#echo -n "[PHP WeakRef] downloading $WEAKREF_VERSION..."
|
||||
#download_file "http://pecl.php.net/get/Weakref-$WEAKREF_VERSION.tgz" | tar -zx >> "$DIR/install.log" 2>&1
|
||||
#mv Weakref-$WEAKREF_VERSION "$DIR/install_data/php/ext/weakref"
|
||||
#echo " done!"
|
||||
|
||||
#PHP YAML
|
||||
echo -n "[PHP YAML] downloading $PHPYAML_VERSION..."
|
||||
download_file "http://pecl.php.net/get/yaml-$PHPYAML_VERSION.tgz" | tar -zx >> "$DIR/install.log" 2>&1
|
||||
mv yaml-$PHPYAML_VERSION "$DIR/install_data/php/ext/yaml"
|
||||
echo " done!"
|
||||
|
||||
#bcompiler
|
||||
#echo -n "[bcompiler] downloading $BCOMPILER_VERSION..."
|
||||
#download_file "http://pecl.php.net/get/bcompiler-$BCOMPILER_VERSION.tgz" | tar -zx >> "$DIR/install.log" 2>&1
|
||||
#mv bcompiler-$BCOMPILER_VERSION "$DIR/install_data/php/ext/bcompiler"
|
||||
#echo " done!"
|
||||
|
||||
#PHP ncurses
|
||||
#echo -n "[PHP ncurses] downloading $PHPNCURSES_VERSION..."
|
||||
#download_file "http://pecl.php.net/get/ncurses-$PHPNCURSES_VERSION.tgz" | tar -zx >> "$DIR/install.log" 2>&1
|
||||
#mv ncurses-$PHPNCURSES_VERSION "$DIR/install_data/php/ext/ncurses"
|
||||
#echo " done!"
|
||||
|
||||
|
||||
if [ "$DO_STATIC" == "yes" ]; then
|
||||
EXTRA_FLAGS="--disable-shared --enable-static"
|
||||
else
|
||||
EXTRA_FLAGS="--enable-shared --disable-static"
|
||||
fi
|
||||
#YAML
|
||||
echo -n "[YAML] downloading $YAML_VERSION..."
|
||||
download_file "http://pyyaml.org/download/libyaml/yaml-$YAML_VERSION.tar.gz" | tar -zx >> "$DIR/install.log" 2>&1
|
||||
mv yaml-$YAML_VERSION yaml
|
||||
echo -n " checking..."
|
||||
cd yaml
|
||||
RANLIB=$RANLIB ./configure \
|
||||
--prefix="$DIR/bin/php5" \
|
||||
$EXTRA_FLAGS \
|
||||
$CONFIGURE_FLAGS >> "$DIR/install.log" 2>&1
|
||||
sed -i=".backup" 's/ tests win32/ win32/g' Makefile
|
||||
echo -n " compiling..."
|
||||
make -j $THREADS >> "$DIR/install.log" 2>&1
|
||||
echo -n " installing..."
|
||||
make install >> "$DIR/install.log" 2>&1
|
||||
echo -n " cleaning..."
|
||||
cd ..
|
||||
rm -r -f ./yaml
|
||||
echo " done!"
|
||||
|
||||
if [ "$DO_STATIC" == "yes" ]; then
|
||||
EXTRA_FLAGS="--enable-shared=no --enable-static=yes"
|
||||
else
|
||||
EXTRA_FLAGS="--enable-shared=yes --enable-static=no"
|
||||
fi
|
||||
|
||||
#libxml2
|
||||
#echo -n "[libxml2] downloading $LIBXML_VERSION..."
|
||||
#download_file "ftp://xmlsoft.org/libxml2/libxml2-$LIBXML_VERSION.tar.gz" | tar -zx >> "$DIR/install.log" 2>&1
|
||||
#mv libxml2-$LIBXML_VERSION yaml
|
||||
#echo -n " checking..."
|
||||
#cd libxml2
|
||||
#RANLIB=$RANLIB ./configure \
|
||||
#--disable-ipv6 \
|
||||
#--with-libz="$DIR/bin/php5" \
|
||||
#--prefix="$DIR/bin/php5" \
|
||||
#$EXTRA_FLAGS \
|
||||
#$CONFIGURE_FLAGS >> "$DIR/install.log" 2>&1
|
||||
#echo -n " compiling..."
|
||||
#make -j $THREADS >> "$DIR/install.log" 2>&1
|
||||
#echo -n " installing..."
|
||||
#make install >> "$DIR/install.log" 2>&1
|
||||
#echo -n " cleaning..."
|
||||
#cd ..
|
||||
#rm -r -f ./libxml2
|
||||
#echo " done!"
|
||||
|
||||
echo -n "[PHP]"
|
||||
|
||||
if [ "$DO_OPTIMIZE" != "no" ]; then
|
||||
echo -n " enabling optimizations..."
|
||||
PHP_OPTIMIZATION="--enable-inline-optimization "
|
||||
else
|
||||
PHP_OPTIMIZATION="--disable-inline-optimization "
|
||||
fi
|
||||
echo -n " checking..."
|
||||
cd php
|
||||
rm -f ./aclocal.m4 >> "$DIR/install.log" 2>&1
|
||||
rm -rf ./autom4te.cache/ >> "$DIR/install.log" 2>&1
|
||||
rm -f ./configure >> "$DIR/install.log" 2>&1
|
||||
./buildconf --force >> "$DIR/install.log" 2>&1
|
||||
if [ "$IS_CROSSCOMPILE" == "yes" ]; then
|
||||
sed -i=".backup" 's/pthreads_working=no/pthreads_working=yes/' ./configure
|
||||
if [ "$IS_WINDOWS" != "yes" ]; then
|
||||
export LIBS="$LIBS -lpthread -ldl -lresolv"
|
||||
else
|
||||
export LIBS="$LIBS -lpthread"
|
||||
fi
|
||||
CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-opcache=no"
|
||||
fi
|
||||
|
||||
if [ "$IS_WINDOWS" != "yes" ]; then
|
||||
HAVE_PCNTL="--enable-pcntl"
|
||||
else
|
||||
HAVE_PCNTL="--disable-pcntl"
|
||||
cp -f ./win32/build/config.* ./main >> "$DIR/install.log" 2>&1
|
||||
sed 's:@PREFIX@:$DIR/bin/php5:' ./main/config.w32.h.in > ./wmain/config.w32.h 2>> "$DIR/install.log"
|
||||
fi
|
||||
|
||||
RANLIB=$RANLIB ./configure $PHP_OPTIMIZATION --prefix="$DIR/bin/php5" \
|
||||
--exec-prefix="$DIR/bin/php5" \
|
||||
--with-curl="$HAVE_CURL" \
|
||||
--with-zlib="$DIR/bin/php5" \
|
||||
--with-zlib-dir="$DIR/bin/php5" \
|
||||
--with-yaml="$DIR/bin/php5" \
|
||||
$HAVE_NCURSES \
|
||||
$HAVE_READLINE \
|
||||
--enable-mbstring \
|
||||
--enable-calendar \
|
||||
--enable-pthreads \
|
||||
--enable-pthreads-pedantic \
|
||||
--disable-libxml \
|
||||
--disable-xml \
|
||||
--disable-dom \
|
||||
--disable-simplexml \
|
||||
--disable-xmlreader \
|
||||
--disable-xmlwriter \
|
||||
--disable-cgi \
|
||||
--disable-session \
|
||||
--disable-debug \
|
||||
--disable-pdo \
|
||||
--without-pear \
|
||||
--without-iconv \
|
||||
--without-pdo-sqlite \
|
||||
--with-pic \
|
||||
--enable-phar \
|
||||
--enable-ctype \
|
||||
--enable-sockets \
|
||||
--enable-shared=no \
|
||||
--enable-static=yes \
|
||||
--enable-shmop \
|
||||
--enable-maintainer-zts \
|
||||
--disable-short-tags \
|
||||
--enable-zend-signals \
|
||||
$HAVE_PCNTL \
|
||||
$HAVE_MYSQLI \
|
||||
--enable-bcmath \
|
||||
--enable-cli \
|
||||
--enable-zip \
|
||||
--enable-ftp \
|
||||
--with-zend-vm=$ZEND_VM \
|
||||
$CONFIGURE_FLAGS >> "$DIR/install.log" 2>&1
|
||||
echo -n " compiling..."
|
||||
if [ "$COMPILE_FOR_ANDROID" == "yes" ]; then
|
||||
sed -i=".backup" 's/-export-dynamic/-all-static/g' Makefile
|
||||
fi
|
||||
sed -i=".backup" 's/PHP_BINARIES. pharcmd$/PHP_BINARIES)/g' Makefile
|
||||
sed -i=".backup" 's/install-programs install-pharcmd$/install-programs/g' Makefile
|
||||
make -j $THREADS >> "$DIR/install.log" 2>&1
|
||||
echo -n " installing..."
|
||||
make install >> "$DIR/install.log" 2>&1
|
||||
|
||||
if [ "$(uname -s)" == "Darwin" ] && [ "$IS_CROSSCOMPILE" != "yes" ]; then
|
||||
set +e
|
||||
install_name_tool -delete_rpath "$DIR/bin/php5/lib" "$DIR/bin/php5/bin/php" >> "$DIR/install.log" 2>&1
|
||||
install_name_tool -change "$DIR/bin/php5/lib/libz.1.dylib" "@loader_path/../lib/libz.1.dylib" "$DIR/bin/php5/bin/php" >> "$DIR/install.log" 2>&1
|
||||
install_name_tool -change "$DIR/bin/php5/lib/libcurl.4.dylib" "@loader_path/../lib/libcurl.4.dylib" "$DIR/bin/php5/bin/php" >> "$DIR/install.log" 2>&1
|
||||
install_name_tool -change "$DIR/bin/php5/lib/libyaml-0.2.dylib" "@loader_path/../lib/libyaml-0.2.dylib" "$DIR/bin/php5/bin/php" >> "$DIR/install.log" 2>&1
|
||||
install_name_tool -change "$DIR/bin/php5/lib/libreadline.$READLINE_VERSION.dylib" "@loader_path/../lib/libreadline.$READLINE_VERSION.dylib" "$DIR/bin/php5/bin/php" >> "$DIR/install.log" 2>&1
|
||||
install_name_tool -change "$DIR/bin/php5/lib/libhistory.$READLINE_VERSION.dylib" "@loader_path/../lib/libhistory.$READLINE_VERSION.dylib" "$DIR/bin/php5/bin/php" >> "$DIR/install.log" 2>&1
|
||||
install_name_tool -change "$DIR/bin/php5/lib/libform.6.0.dylib" "@loader_path/../lib/libform.6.0.dylib" "$DIR/bin/php5/bin/php" >> "$DIR/install.log" 2>&1
|
||||
install_name_tool -change "$DIR/bin/php5/lib/libmenu.6.0.dylib" "@loader_path/../lib/libmenu.6.0.dylib" "$DIR/bin/php5/bin/php" >> "$DIR/install.log" 2>&1
|
||||
install_name_tool -change "$DIR/bin/php5/lib/libncurses.6.0.dylib" "@loader_path/../lib/libncurses.6.0.dylib" "$DIR/bin/php5/bin/php" >> "$DIR/install.log" 2>&1
|
||||
install_name_tool -change "$DIR/bin/php5/lib/libpanel.6.0.dylib" "@loader_path/../lib/libpanel.6.0.dylib" "$DIR/bin/php5/bin/php" >> "$DIR/install.log" 2>&1
|
||||
install_name_tool -change "$DIR/bin/php5/lib/libssl.1.0.0.dylib" "@loader_path/../lib/libssl.1.0.0.dylib" "$DIR/bin/php5/bin/php" >> "$DIR/install.log" 2>&1
|
||||
install_name_tool -change "$DIR/bin/php5/lib/libssl.1.0.0.dylib" "@loader_path/../lib/libssl.1.0.0.dylib" "$DIR/bin/php5/lib/libcurl.4.dylib" >> "$DIR/install.log" 2>&1
|
||||
install_name_tool -change "$DIR/bin/php5/lib/libcrypto.1.0.0.dylib" "@loader_path/../lib/libcrypto.1.0.0.dylib" "$DIR/bin/php5/bin/php" >> "$DIR/install.log" 2>&1
|
||||
install_name_tool -change "$DIR/bin/php5/lib/libcrypto.1.0.0.dylib" "@loader_path/../lib/libcrypto.1.0.0.dylib" "$DIR/bin/php5/lib/libcurl.4.dylib" >> "$DIR/install.log" 2>&1
|
||||
chmod 0777 "$DIR/bin/php5/lib/libssl.1.0.0.dylib" >> "$DIR/install.log" 2>&1
|
||||
install_name_tool -change "$DIR/bin/php5/lib/libcrypto.1.0.0.dylib" "@loader_path/libcrypto.1.0.0.dylib" "$DIR/bin/php5/lib/libssl.1.0.0.dylib" >> "$DIR/install.log" 2>&1
|
||||
chmod 0755 "$DIR/bin/php5/lib/libssl.1.0.0.dylib" >> "$DIR/install.log" 2>&1
|
||||
set -e
|
||||
fi
|
||||
|
||||
echo -n " generating php.ini..."
|
||||
trap - DEBUG
|
||||
TIMEZONE=$(date +%Z)
|
||||
echo "date.timezone=$TIMEZONE" > "$DIR/bin/php5/bin/php.ini"
|
||||
echo "short_open_tag=0" >> "$DIR/bin/php5/bin/php.ini"
|
||||
echo "asp_tags=0" >> "$DIR/bin/php5/bin/php.ini"
|
||||
echo "phar.readonly=0" >> "$DIR/bin/php5/bin/php.ini"
|
||||
echo "phar.require_hash=1" >> "$DIR/bin/php5/bin/php.ini"
|
||||
if [ "$IS_CROSSCOMPILE" != "crosscompile" ]; then
|
||||
echo "zend_extension=opcache.so" >> "$DIR/bin/php5/bin/php.ini"
|
||||
echo "opcache.enable=1" >> "$DIR/bin/php5/bin/php.ini"
|
||||
echo "opcache.enable_cli=1" >> "$DIR/bin/php5/bin/php.ini"
|
||||
echo "opcache.save_comments=0" >> "$DIR/bin/php5/bin/php.ini"
|
||||
echo "opcache.fast_shutdown=1" >> "$DIR/bin/php5/bin/php.ini"
|
||||
echo "opcache.max_accelerated_files=4096" >> "$DIR/bin/php5/bin/php.ini"
|
||||
echo "opcache.interned_strings_buffer=8" >> "$DIR/bin/php5/bin/php.ini"
|
||||
echo "opcache.memory_consumption=128" >> "$DIR/bin/php5/bin/php.ini"
|
||||
echo "opcache.optimization_level=0xffffffff" >> "$DIR/bin/php5/bin/php.ini"
|
||||
fi
|
||||
if [ "$HAVE_CURL" == "shared,/usr" ]; then
|
||||
echo "extension=curl.so" >> "$DIR/bin/php5/bin/php.ini"
|
||||
fi
|
||||
|
||||
echo " done!"
|
||||
cd "$DIR"
|
||||
echo -n "[INFO] Cleaning up..."
|
||||
rm -r -f install_data/ >> "$DIR/install.log" 2>&1
|
||||
rm -f bin/php5/bin/curl* >> "$DIR/install.log" 2>&1
|
||||
rm -f bin/php5/bin/curl-config* >> "$DIR/install.log" 2>&1
|
||||
rm -f bin/php5/bin/c_rehash* >> "$DIR/install.log" 2>&1
|
||||
rm -f bin/php5/bin/openssl* >> "$DIR/install.log" 2>&1
|
||||
rm -r -f bin/php5/man >> "$DIR/install.log" 2>&1
|
||||
rm -r -f bin/php5/php >> "$DIR/install.log" 2>&1
|
||||
rm -r -f bin/php5/misc >> "$DIR/install.log" 2>&1
|
||||
date >> "$DIR/install.log" 2>&1
|
||||
echo " done!"
|
||||
echo "[PocketMine] You should start the server now using \"./start.sh.\""
|
||||
echo "[PocketMine] If it doesn't work, please send the \"install.log\" file to the Bug Tracker."
|
@ -1,247 +0,0 @@
|
||||
#!/bin/bash
|
||||
PMMP_VERSION=""
|
||||
LINUX_32_BUILD="PHP_5.5.10_x86_Linux"
|
||||
LINUX_64_BUILD="PHP_5.5.10_x86-64_Linux"
|
||||
MAC_32_BUILD="PHP_5.5.10_x86_MacOS"
|
||||
MAC_64_BUILD="PHP_5.5.10_x86-64_MacOS"
|
||||
RPI_BUILD="PHP_5.5.9_ARM_Raspbian_hard"
|
||||
# Temporal build
|
||||
ODROID_BUILD="PHP_5.5.9_ARM_Raspbian_hard"
|
||||
AND_BUILD="PHP_5.5.9_ARMv7_Android"
|
||||
IOS_BUILD="PHP_5.5.9_ARMv6_iOS"
|
||||
update=off
|
||||
forcecompile=off
|
||||
alldone=no
|
||||
|
||||
#Needed to use aliases
|
||||
shopt -s expand_aliases
|
||||
type wget > /dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
alias download_file="wget --no-check-certificate -q -O -"
|
||||
else
|
||||
type curl >> /dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
alias download_file="curl --insecure --silent --location"
|
||||
else
|
||||
echo "error, curl or wget not found"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
while getopts "ucdv:" opt; do
|
||||
case $opt in
|
||||
u)
|
||||
update=on
|
||||
;;
|
||||
c)
|
||||
forcecompile=on
|
||||
;;
|
||||
d)
|
||||
PMMP_VERSION="master"
|
||||
;;
|
||||
v)
|
||||
PMMP_VERSION="$OPTARG"
|
||||
;;
|
||||
\?)
|
||||
echo "Invalid option: -$OPTARG" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "$PMMP_VERSION" == "" ]; then
|
||||
PMMP_VERSION=$(download_file "https://api.github.com/repos/PocketMine/PocketMine-MP/tags" | grep '"name": "[A-Za-z0-9_\.]*",' | head -1 | sed -r 's/[ ]*"name": "([A-Za-z0-9_\.]*)",[ ]*/\1/')
|
||||
if [ "$PMMP_VERSION" == "" ]; then
|
||||
echo "[ERROR] Couldn't get the latest PocketMine-MP version"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "[INFO] PocketMine-MP $PMMP_VERSION downloader & installer for Linux & Mac"
|
||||
|
||||
echo "[0/3] Cleaning..."
|
||||
rm -r -f src/
|
||||
rm -f PocketMine-MP.php
|
||||
rm -f README.md
|
||||
rm -f CONTRIBUTING.md
|
||||
rm -f LICENSE
|
||||
rm -f start.sh
|
||||
rm -f start.bat
|
||||
echo "[1/3] Downloading PocketMine-MP $PMMP_VERSION..."
|
||||
download_file "https://github.com/PocketMine/PocketMine-MP/archive/$PMMP_VERSION.tar.gz" | tar -zx > /dev/null
|
||||
mv -f PocketMine-MP-$PMMP_VERSION/* ./
|
||||
rm -f -r PocketMine-MP-$PMMP_VERSION/
|
||||
rm -f ./start.cmd
|
||||
chmod +x ./start.sh
|
||||
chmod +x ./src/build/compile.sh
|
||||
if [ "$update" == "on" ]; then
|
||||
echo "[3/3] Skipping PHP recompilation due to user request"
|
||||
else
|
||||
echo -n "[3/3] Obtaining PHP:"
|
||||
echo " detecting if build is available..."
|
||||
if [ "$forcecompile" == "off" ] && [ "$(uname -s)" == "Darwin" ]; then
|
||||
set +e
|
||||
UNAME_M=$(uname -m)
|
||||
IS_IOS=$(expr match $UNAME_M 'iP[a-zA-Z0-9,]*' 2> /dev/null)
|
||||
set -e
|
||||
if [[ "$IS_IOS" -gt 0 ]]; then
|
||||
rm -r -f bin/ >> /dev/null 2>&1
|
||||
echo -n "[3/3] iOS PHP build available, downloading $IOS_BUILD.tar.gz..."
|
||||
download_file "http://sourceforge.net/projects/pocketmine/files/builds/$IOS_BUILD.tar.gz" | tar -zx > /dev/null 2>&1
|
||||
chmod +x ./bin/php5/bin/*
|
||||
echo -n " checking..."
|
||||
if [ $(./bin/php5/bin/php -r 'echo "yes";' 2>/dev/null) == "yes" ]; then
|
||||
echo -n " regenerating php.ini..."
|
||||
TIMEZONE=$(date +%Z)
|
||||
echo "date.timezone=$TIMEZONE" >> "./bin/php5/bin/php.ini"
|
||||
echo "short_open_tag=0" >> "./bin/php5/bin/php.ini"
|
||||
echo "asp_tags=0" >> "./bin/php5/bin/php.ini"
|
||||
echo "phar.readonly=0" >> "./bin/php5/bin/php.ini"
|
||||
echo "phar.require_hash=1" >> "./bin/php5/bin/php.ini"
|
||||
echo " done"
|
||||
alldone=yes
|
||||
else
|
||||
echo " invalid build detected"
|
||||
fi
|
||||
else
|
||||
rm -r -f bin/ >> /dev/null 2>&1
|
||||
if [ `getconf LONG_BIT` == "64" ]; then
|
||||
echo -n "[3/3] MacOS 64-bit PHP build available, downloading $MAC_64_BUILD.tar.gz..."
|
||||
MAC_BUILD="$MAC_64_BUILD"
|
||||
else
|
||||
echo -n "[3/3] MacOS 32-bit PHP build available, downloading $MAC_32_BUILD.tar.gz..."
|
||||
MAC_BUILD="$MAC_32_BUILD"
|
||||
fi
|
||||
download_file "http://sourceforge.net/projects/pocketmine/files/builds/$MAC_BUILD.tar.gz" | tar -zx > /dev/null 2>&1
|
||||
chmod +x ./bin/php5/bin/*
|
||||
echo -n " checking..."
|
||||
if [ $(./bin/php5/bin/php -r 'echo "yes";' 2>/dev/null) == "yes" ]; then
|
||||
echo -n " regenerating php.ini..."
|
||||
TIMEZONE=$(date +%Z)
|
||||
OPCACHE_PATH="$(find $(pwd) -name opcache.so)"
|
||||
echo "zend_extension=\"$OPCACHE_PATH\"" > "./bin/php5/bin/php.ini"
|
||||
echo "opcache.enable=1" >> "./bin/php5/bin/php.ini"
|
||||
echo "opcache.enable_cli=1" >> "./bin/php5/bin/php.ini"
|
||||
echo "opcache.save_comments=0" >> "./bin/php5/bin/php.ini"
|
||||
echo "opcache.fast_shutdown=1" >> "./bin/php5/bin/php.ini"
|
||||
echo "opcache.max_accelerated_files=4096" >> "./bin/php5/bin/php.ini"
|
||||
echo "opcache.interned_strings_buffer=8" >> "./bin/php5/bin/php.ini"
|
||||
echo "opcache.memory_consumption=128" >> "./bin/php5/bin/php.ini"
|
||||
echo "opcache.optimization_level=0xffffffff" >> "./bin/php5/bin/php.ini"
|
||||
echo "date.timezone=$TIMEZONE" >> "./bin/php5/bin/php.ini"
|
||||
echo "short_open_tag=0" >> "./bin/php5/bin/php.ini"
|
||||
echo "asp_tags=0" >> "./bin/php5/bin/php.ini"
|
||||
echo "phar.readonly=0" >> "./bin/php5/bin/php.ini"
|
||||
echo "phar.require_hash=1" >> "./bin/php5/bin/php.ini"
|
||||
echo " done"
|
||||
alldone=yes
|
||||
else
|
||||
echo " invalid build detected"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
grep -q BCM2708 /proc/cpuinfo > /dev/null 2>&1
|
||||
IS_RPI=$?
|
||||
grep -q ODROID /proc/cpuinfo > /dev/null 2>&1
|
||||
IS_ODROID=$?
|
||||
if [ "$IS_RPI" -eq 0 ] && [ "$forcecompile" == "off" ]; then
|
||||
rm -r -f bin/ >> /dev/null 2>&1
|
||||
echo -n "[3/3] Raspberry Pi PHP build available, downloading $RPI_BUILD.tar.gz..."
|
||||
download_file "http://sourceforge.net/projects/pocketmine/files/builds/$RPI_BUILD.tar.gz" | tar -zx > /dev/null 2>&1
|
||||
chmod +x ./bin/php5/bin/*
|
||||
echo -n " checking..."
|
||||
if [ $(./bin/php5/bin/php -r 'echo "yes";' 2>/dev/null) == "yes" ]; then
|
||||
echo -n " regenerating php.ini..."
|
||||
TIMEZONE=$(date +%Z)
|
||||
OPCACHE_PATH="$(find $(pwd) -name opcache.so)"
|
||||
echo "zend_extension=\"$OPCACHE_PATH\"" > "./bin/php5/bin/php.ini"
|
||||
echo "opcache.enable=1" >> "./bin/php5/bin/php.ini"
|
||||
echo "opcache.enable_cli=1" >> "./bin/php5/bin/php.ini"
|
||||
echo "opcache.save_comments=0" >> "./bin/php5/bin/php.ini"
|
||||
echo "opcache.fast_shutdown=1" >> "./bin/php5/bin/php.ini"
|
||||
echo "opcache.max_accelerated_files=4096" >> "./bin/php5/bin/php.ini"
|
||||
echo "opcache.interned_strings_buffer=8" >> "./bin/php5/bin/php.ini"
|
||||
echo "opcache.memory_consumption=128" >> "./bin/php5/bin/php.ini"
|
||||
echo "opcache.optimization_level=0xffffffff" >> "./bin/php5/bin/php.ini"
|
||||
echo "date.timezone=$TIMEZONE" >> "./bin/php5/bin/php.ini"
|
||||
echo "short_open_tag=0" >> "./bin/php5/bin/php.ini"
|
||||
echo "asp_tags=0" >> "./bin/php5/bin/php.ini"
|
||||
echo "phar.readonly=0" >> "./bin/php5/bin/php.ini"
|
||||
echo "phar.require_hash=1" >> "./bin/php5/bin/php.ini"
|
||||
echo " done"
|
||||
alldone=yes
|
||||
else
|
||||
echo " invalid build detected"
|
||||
fi
|
||||
elif [ "$IS_ODROID" -eq 0 ] && [ "$forcecompile" == "off" ]; then
|
||||
rm -r -f bin/ >> /dev/null 2>&1
|
||||
echo -n "[3/3] ODROID PHP build available, downloading $ODROID_BUILD.tar.gz..."
|
||||
download_file "http://sourceforge.net/projects/pocketmine/files/builds/$ODROID_BUILD.tar.gz" | tar -zx > /dev/null 2>&1
|
||||
chmod +x ./bin/php5/bin/*
|
||||
echo -n " checking..."
|
||||
if [ $(./bin/php5/bin/php -r 'echo "yes";' 2>/dev/null) == "yes" ]; then
|
||||
echo -n " regenerating php.ini..."
|
||||
OPCACHE_PATH="$(find $(pwd) -name opcache.so)"
|
||||
echo "zend_extension=\"$OPCACHE_PATH\"" > "./bin/php5/bin/php.ini"
|
||||
echo "opcache.enable=1" >> "./bin/php5/bin/php.ini"
|
||||
echo "opcache.enable_cli=1" >> "./bin/php5/bin/php.ini"
|
||||
echo "opcache.save_comments=0" >> "./bin/php5/bin/php.ini"
|
||||
echo "opcache.fast_shutdown=1" >> "./bin/php5/bin/php.ini"
|
||||
echo "opcache.max_accelerated_files=4096" >> "./bin/php5/bin/php.ini"
|
||||
echo "opcache.interned_strings_buffer=8" >> "./bin/php5/bin/php.ini"
|
||||
echo "opcache.memory_consumption=128" >> "./bin/php5/bin/php.ini"
|
||||
echo "opcache.optimization_level=0xffffffff" >> "./bin/php5/bin/php.ini"
|
||||
echo "date.timezone=$TIMEZONE" >> "./bin/php5/bin/php.ini"
|
||||
echo "short_open_tag=0" >> "./bin/php5/bin/php.ini"
|
||||
echo "asp_tags=0" >> "./bin/php5/bin/php.ini"
|
||||
echo "phar.readonly=0" >> "./bin/php5/bin/php.ini"
|
||||
echo "phar.require_hash=1" >> "./bin/php5/bin/php.ini"
|
||||
echo " done"
|
||||
alldone=yes
|
||||
else
|
||||
echo " invalid build detected"
|
||||
fi
|
||||
elif [ "$forcecompile" == "off" ] && [ "$(uname -s)" == "Linux" ]; then
|
||||
rm -r -f bin/ >> /dev/null 2>&1
|
||||
if [ `getconf LONG_BIT` = "64" ]; then
|
||||
echo -n "[3/3] Linux 64-bit PHP build available, downloading $LINUX_64_BUILD.tar.gz..."
|
||||
LINUX_BUILD="$LINUX_64_BUILD"
|
||||
else
|
||||
echo -n "[3/3] Linux 32-bit PHP build available, downloading $LINUX_32_BUILD.tar.gz..."
|
||||
LINUX_BUILD="$LINUX_32_BUILD"
|
||||
fi
|
||||
download_file "http://sourceforge.net/projects/pocketmine/files/builds/$LINUX_BUILD.tar.gz" | tar -zx > /dev/null 2>&1
|
||||
chmod +x ./bin/php5/bin/*
|
||||
echo -n " checking..."
|
||||
if [ $(./bin/php5/bin/php -r 'echo "yes";' 2>/dev/null) == "yes" ]; then
|
||||
echo -n " regenerating php.ini..."
|
||||
OPCACHE_PATH="$(find $(pwd) -name opcache.so)"
|
||||
echo "zend_extension=\"$OPCACHE_PATH\"" > "./bin/php5/bin/php.ini"
|
||||
echo "opcache.enable=1" >> "./bin/php5/bin/php.ini"
|
||||
echo "opcache.enable_cli=1" >> "./bin/php5/bin/php.ini"
|
||||
echo "opcache.save_comments=0" >> "./bin/php5/bin/php.ini"
|
||||
echo "opcache.fast_shutdown=1" >> "./bin/php5/bin/php.ini"
|
||||
echo "opcache.max_accelerated_files=4096" >> "./bin/php5/bin/php.ini"
|
||||
echo "opcache.interned_strings_buffer=8" >> "./bin/php5/bin/php.ini"
|
||||
echo "opcache.memory_consumption=128" >> "./bin/php5/bin/php.ini"
|
||||
echo "opcache.optimization_level=0xffffffff" >> "./bin/php5/bin/php.ini"
|
||||
echo "date.timezone=$TIMEZONE" >> "./bin/php5/bin/php.ini"
|
||||
echo "short_open_tag=0" >> "./bin/php5/bin/php.ini"
|
||||
echo "asp_tags=0" >> "./bin/php5/bin/php.ini"
|
||||
echo "phar.readonly=0" >> "./bin/php5/bin/php.ini"
|
||||
echo "phar.require_hash=1" >> "./bin/php5/bin/php.ini"
|
||||
echo " done"
|
||||
alldone=yes
|
||||
else
|
||||
echo " invalid build detected"
|
||||
fi
|
||||
fi
|
||||
if [ "$alldone" == "no" ]; then
|
||||
set -e
|
||||
echo "[3/3] no build found, compiling PHP"
|
||||
exec ./src/build/compile.sh
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
echo "[INFO] Everything done! Run ./start.sh to start PocketMine-MP"
|
||||
exit 0
|
@ -1,213 +0,0 @@
|
||||
#!/bin/bash -x
|
||||
export PATH="/opt/arm-2013.05/bin:/opt/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin:/opt/arm-unknown-linux-uclibcgnueabi/bin:$PATH"
|
||||
export THREADS=2
|
||||
PHP_VERSION="5.5.10"
|
||||
|
||||
#Needed to use aliases
|
||||
shopt -s expand_aliases
|
||||
type wget > /dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
alias download_file="wget --no-check-certificate -q -O -"
|
||||
else
|
||||
type curl >> /dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
alias download_file="curl --insecure --silent --location"
|
||||
else
|
||||
echo "error, curl or wget not found"
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -rf $WORKSPACE/compile.sh
|
||||
download_file "https://github.com/PocketMine/PocketMine-MP/raw/master/src/build/compile.sh" > $WORKSPACE/compile.sh
|
||||
chmod +x $WORKSPACE/compile.sh
|
||||
SCRIPT="$WORKSPACE/compile.sh"
|
||||
ARCHIVE="$WORKSPACE/archive"
|
||||
COMPILEDIR="$WORKSPACE/compile"
|
||||
rm -rf "$ARCHIVE" "$COMPILEDIR"
|
||||
mkdir -p "$ARCHIVE"
|
||||
mkdir -p "$COMPILEDIR"
|
||||
|
||||
if [ "$COMPILE_LINUX_32BIT" = "true" ];
|
||||
then
|
||||
mkdir -p {$COMPILEDIR,$ARCHIVE}/linux/32bit
|
||||
cd $COMPILEDIR/linux/32bit
|
||||
|
||||
$SCRIPT -t linux32 -o -j 1 -c -f x86
|
||||
|
||||
tar -czf PHP_${PHP_VERSION}_x86_Linux.tar.gz bin/
|
||||
cp -r $COMPILEDIR/linux/32bit/{install.log,PHP_${PHP_VERSION}_x86_Linux.tar.gz,install_data/*} $ARCHIVE/linux/32bit/
|
||||
if [ ! -f $COMPILEDIR/linux/32bit/bin/php5/bin/php ]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$COMPILE_LINUX_64BIT" = "true" ];
|
||||
then
|
||||
mkdir -p {$COMPILEDIR,$ARCHIVE}/linux/64bit
|
||||
cd $COMPILEDIR/linux/64bit
|
||||
|
||||
$SCRIPT -t linux64 -o -j 1 -c -f x86_64
|
||||
|
||||
tar -czf PHP_${PHP_VERSION}_x86-64_Linux.tar.gz bin/
|
||||
cp -r $COMPILEDIR/linux/64bit/{install.log,PHP_${PHP_VERSION}_x86-64_Linux.tar.gz,install_data/*} $ARCHIVE/linux/64bit/
|
||||
if [ ! -f $COMPILEDIR/linux/64bit/bin/php5/bin/php ]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$COMPILE_MAC_32" = "true" ];
|
||||
then
|
||||
mkdir -p {$COMPILEDIR,$ARCHIVE}/mac32
|
||||
cd $COMPILEDIR/mac32
|
||||
|
||||
curl -L http://ftpmirror.gnu.org/libtool/libtool-2.4.2.tar.gz | tar -xz > /dev/null
|
||||
cd libtool-2.4.2
|
||||
./configure --prefix="$COMPILEDIR/mac/libtool" > /dev/null
|
||||
make > /dev/null
|
||||
make install
|
||||
cd ../
|
||||
rm -rf libtool-2.4.2
|
||||
export LIBTOOL="$COMPILEDIR/mac/libtool/bin/libtool"
|
||||
export LIBTOOLIZE="$COMPILEDIR/mac/libtool/bin/libtoolize"
|
||||
$SCRIPT -t mac32 -o -j 1 -c -f
|
||||
|
||||
tar -czf PHP_${PHP_VERSION}_x86_MacOS.tar.gz bin/
|
||||
cp -r $COMPILEDIR/mac32/{install.log,PHP_${PHP_VERSION}_x86_MacOS.tar.gz,install_data/*} $ARCHIVE/mac32/
|
||||
if [ ! -f $COMPILEDIR/mac32/bin/php5/bin/php ]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$COMPILE_MAC_64" = "true" ];
|
||||
then
|
||||
mkdir -p {$COMPILEDIR,$ARCHIVE}/mac64
|
||||
cd $COMPILEDIR/mac64
|
||||
|
||||
curl -L http://ftpmirror.gnu.org/libtool/libtool-2.4.2.tar.gz | tar -xz > /dev/null
|
||||
cd libtool-2.4.2
|
||||
./configure --prefix="$COMPILEDIR/mac/libtool" > /dev/null
|
||||
make > /dev/null
|
||||
make install
|
||||
cd ../
|
||||
rm -rf libtool-2.4.2
|
||||
export LIBTOOL="$COMPILEDIR/mac/libtool/bin/libtool"
|
||||
export LIBTOOLIZE="$COMPILEDIR/mac/libtool/bin/libtoolize"
|
||||
$SCRIPT -t mac64 -o -j 1 -c -f
|
||||
|
||||
tar -czf PHP_${PHP_VERSION}_x86-64_MacOS.tar.gz bin/
|
||||
cp -r $COMPILEDIR/mac64/{install.log,PHP_${PHP_VERSION}_x86-64_MacOS.tar.gz,install_data/*} $ARCHIVE/mac64
|
||||
if [ ! -f $COMPILEDIR/mac64/bin/php5/bin/php ]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$COMPILE_RPI" = "true" ];
|
||||
then
|
||||
mkdir -p {$COMPILEDIR,$ARCHIVE}/rpi
|
||||
cd $COMPILEDIR/rpi
|
||||
|
||||
$SCRIPT -t rpi -o -j 1 -c -f arm
|
||||
|
||||
tar -czf PHP_${PHP_VERSION}_ARM_Raspbian_hard.tar.gz bin/
|
||||
cp -r $COMPILEDIR/rpi/{install.log,PHP_${PHP_VERSION}_ARM_Raspbian_hard.tar.gz,install_data/*} $ARCHIVE/rpi/
|
||||
if [ ! -f $COMPILEDIR/rpi/bin/php5/bin/php ]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$CROSSCOMPILE_ANDROID_ARMV6" = "true" ];
|
||||
then
|
||||
mkdir -p {$COMPILEDIR,$ARCHIVE}/crosscompile/android-armv6
|
||||
cd $COMPILEDIR/crosscompile/android-armv6
|
||||
|
||||
$SCRIPT -t android-armv6 -o -j 1 -c -x -s -f arm
|
||||
|
||||
tar -czf PHP_${PHP_VERSION}_ARMv6_Android.tar.gz bin/
|
||||
cp -r $COMPILEDIR/crosscompile/android-armv6/{install.log,PHP_${PHP_VERSION}_ARMv6_Android.tar.gz,install_data/*} $ARCHIVE/crosscompile/android-armv6/
|
||||
if [ ! -f $COMPILEDIR/crosscompile/android-armv6/bin/php5/bin/php ]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$CROSSCOMPILE_ANDROID_ARMV7" = "true" ];
|
||||
then
|
||||
mkdir -p {$COMPILEDIR,$ARCHIVE}/crosscompile/android-armv7
|
||||
cd $COMPILEDIR/crosscompile/android-armv7
|
||||
|
||||
$SCRIPT -t android-armv7 -o -j 1 -c -x -s -f arm
|
||||
|
||||
tar -czf PHP_${PHP_VERSION}_ARMv7_Android.tar.gz bin/
|
||||
cp -r $COMPILEDIR/crosscompile/android-armv7/{install.log,PHP_${PHP_VERSION}_ARMv7_Android.tar.gz,install_data/*} $ARCHIVE/crosscompile/android-armv7/
|
||||
if [ ! -f $COMPILEDIR/crosscompile/android-armv7/bin/php5/bin/php ]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$CROSSCOMPILE_IOS_ARMV6" = "true" ];
|
||||
then
|
||||
mkdir -p {$COMPILEDIR,$ARCHIVE}/crosscompile/ios-armv6
|
||||
cd $COMPILEDIR/crosscompile/ios-armv6
|
||||
curl -L http://ftpmirror.gnu.org/libtool/libtool-2.4.2.tar.gz | tar -xz > /dev/null
|
||||
cd libtool-2.4.2
|
||||
./configure --prefix="$COMPILEDIR/crosscompile/ios-armv6/libtool" > /dev/null
|
||||
make > /dev/null
|
||||
make install
|
||||
cd ../
|
||||
rm -rf libtool-2.4.2
|
||||
export LIBTOOL="$COMPILEDIR/crosscompile/ios-armv6/libtool/bin/libtool"
|
||||
export LIBTOOLIZE="$COMPILEDIR/crosscompile/ios-armv6/libtool/bin/libtoolize"
|
||||
PATH="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:$PATH" $SCRIPT -t ios-armv6 -o -j 1 -c -x
|
||||
|
||||
cp -r $COMPILEDIR/crosscompile/ios-armv6/{install.log,bin/*,install_data/*} $ARCHIVE/crosscompile/ios-armv6/
|
||||
if [ ! -f $COMPILEDIR/crosscompile/ios-armv6/bin/php5/bin/php ]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$CROSSCOMPILE_IOS_ARMV7" = "true" ];
|
||||
then
|
||||
mkdir -p {$COMPILEDIR,$ARCHIVE}/crosscompile/ios-armv7
|
||||
cd $COMPILEDIR/crosscompile/ios-armv7
|
||||
curl -L http://ftpmirror.gnu.org/libtool/libtool-2.4.2.tar.gz | tar -xz > /dev/null
|
||||
cd libtool-2.4.2
|
||||
./configure --prefix="$COMPILEDIR/crosscompile/ios-armv7/libtool" > /dev/null
|
||||
make > /dev/null
|
||||
make install
|
||||
cd ../
|
||||
rm -rf libtool-2.4.2
|
||||
export LIBTOOL="$COMPILEDIR/crosscompile/ios-armv7/libtool/bin/libtool"
|
||||
export LIBTOOLIZE="$COMPILEDIR/crosscompile/ios-armv7/libtool/bin/libtoolize"
|
||||
PATH="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:$PATH" $SCRIPT -t ios-armv6 -o -j 1 -c -x
|
||||
|
||||
cp -r $COMPILEDIR/crosscompile/ios-armv7/{install.log,bin/*,install_data/*} $ARCHIVE/crosscompile/ios-armv7/
|
||||
if [ ! -f $COMPILEDIR/crosscompile/ios-armv7/bin/php5/bin/php ]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$CROSSCOMPILE_RPI" = "true" ];
|
||||
then
|
||||
mkdir -p {$COMPILEDIR,$ARCHIVE}/crosscompile/rpi
|
||||
cd $COMPILEDIR/crosscompile/rpi
|
||||
|
||||
$SCRIPT -t rpi -o -j 1 -c -x -f arm
|
||||
|
||||
tar -czf PHP_${PHP_VERSION}_ARM_Raspbian_hard.tar.gz bin/
|
||||
cp -r $COMPILEDIR/crosscompile/rpi/{install.log,PHP_${PHP_VERSION}_ARM_Raspbian_hard.tar.gz,install_data/*} $ARCHIVE/crosscompile/rpi/
|
||||
if [ ! -f $COMPILEDIR/crosscompile/rpi/bin/php5/bin/php ]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$CROSSCOMPILE_MAC" = "true" ];
|
||||
then
|
||||
mkdir -p {$COMPILEDIR,$ARCHIVE}/crosscompile/mac
|
||||
cd $COMPILEDIR/crosscompile/mac
|
||||
|
||||
$SCRIPT -t mac -o -j 1 -c -f -x
|
||||
|
||||
cp -r $COMPILEDIR/crosscompile/mac/{install.log,bin/*,install_data/*} $ARCHIVE/crosscompile/mac/
|
||||
if [ ! -f $COMPILEDIR/crosscompile/mac/bin/php5/bin/php ]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
use pocketmine\utils\TextFormat;
|
||||
|
||||
/**
|
||||
@ -32,7 +33,7 @@ abstract class Achievement{
|
||||
public static $list = array(
|
||||
/*"openInventory" => array(
|
||||
"name" => "Taking Inventory",
|
||||
"requires" => array(),
|
||||
"requires" => [],
|
||||
),*/
|
||||
"mineWood" => array(
|
||||
"name" => "Getting Wood",
|
||||
@ -117,7 +118,7 @@ abstract class Achievement{
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function add($achievementId, $achievementName, array $requires = array()){
|
||||
public static function add($achievementId, $achievementName, array $requires = []){
|
||||
if(!isset(Achievement::$list[$achievementId])){
|
||||
Achievement::$list[$achievementId] = array(
|
||||
"name" => $achievementName,
|
78
src/pocketmine/IPlayer.php
Normal file
78
src/pocketmine/IPlayer.php
Normal file
@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
use pocketmine\permission\ServerOperator;
|
||||
|
||||
interface IPlayer extends ServerOperator{
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isOnline();
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName();
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isBanned();
|
||||
|
||||
/**
|
||||
* @param bool $banned
|
||||
*/
|
||||
public function setBanned($banned);
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isWhitelisted();
|
||||
|
||||
/**
|
||||
* @param bool $value
|
||||
*/
|
||||
public function setWhitelisted($value);
|
||||
|
||||
/**
|
||||
* @return Player|null
|
||||
*/
|
||||
public function getPlayer();
|
||||
|
||||
/**
|
||||
* @return int|double
|
||||
*/
|
||||
public function getFirstPlayed();
|
||||
|
||||
/**
|
||||
* @return int|double
|
||||
*/
|
||||
public function getLastPlayed();
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function hasPlayedBefore();
|
||||
|
||||
}
|
134
src/pocketmine/OfflinePlayer.php
Normal file
134
src/pocketmine/OfflinePlayer.php
Normal file
@ -0,0 +1,134 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
|
||||
use pocketmine\metadata\MetadataValue;
|
||||
use pocketmine\nbt\tag\Compound;
|
||||
use pocketmine\plugin\Plugin;
|
||||
|
||||
class OfflinePlayer implements IPlayer{
|
||||
|
||||
private $name;
|
||||
private $server;
|
||||
private $namedtag;
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param string $name
|
||||
*/
|
||||
public function __construct(Server $server, $name){
|
||||
$this->server = $server;
|
||||
$this->name = $name;
|
||||
if(file_exists($this->server->getDataPath() . "players/" . strtolower($this->getName()) . ".dat")){
|
||||
$this->namedtag = $this->server->getOfflinePlayerData($this->name);
|
||||
}else{
|
||||
$this->namedtag = null;
|
||||
}
|
||||
}
|
||||
|
||||
public function isOnline(){
|
||||
return $this->getPlayer() !== null;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getServer(){
|
||||
return $this->server;
|
||||
}
|
||||
|
||||
public function isOp(){
|
||||
return $this->server->isOp(strtolower($this->getName()));
|
||||
}
|
||||
|
||||
public function setOp($value){
|
||||
if($value === $this->isOp()){
|
||||
return;
|
||||
}
|
||||
|
||||
if($value === true){
|
||||
$this->server->addOp(strtolower($this->getName()));
|
||||
}else{
|
||||
$this->server->removeOp(strtolower($this->getName()));
|
||||
}
|
||||
}
|
||||
|
||||
public function isBanned(){
|
||||
return $this->server->getNameBans()->isBanned(strtolower($this->getName()));
|
||||
}
|
||||
|
||||
public function setBanned($value){
|
||||
if($value === true){
|
||||
$this->server->getNameBans()->addBan($this->getName(), null, null, null);
|
||||
}else{
|
||||
$this->server->getNameBans()->remove($this->getName());
|
||||
}
|
||||
}
|
||||
|
||||
public function isWhitelisted(){
|
||||
return $this->server->isWhitelisted(strtolower($this->getName()));
|
||||
}
|
||||
|
||||
public function setWhitelisted($value){
|
||||
if($value === true){
|
||||
$this->server->addWhitelist(strtolower($this->getName()));
|
||||
}else{
|
||||
$this->server->removeWhitelist(strtolower($this->getName()));
|
||||
}
|
||||
}
|
||||
|
||||
public function getPlayer(){
|
||||
return $this->server->getPlayerExact($this->getName());
|
||||
}
|
||||
|
||||
public function getFirstPlayed(){
|
||||
return $this->namedtag instanceof Compound ? $this->namedtag["firstPlayed"] : null;
|
||||
}
|
||||
|
||||
public function getLastPlayed(){
|
||||
return $this->namedtag instanceof Compound ? $this->namedtag["lastPlayed"] : null;
|
||||
}
|
||||
|
||||
public function hasPlayedBefore(){
|
||||
return $this->namedtag instanceof Compound;
|
||||
}
|
||||
|
||||
public function setMetadata($metadataKey, MetadataValue $metadataValue){
|
||||
$this->server->getPlayerMetadata()->setMetadata($this, $metadataKey, $metadataValue);
|
||||
}
|
||||
|
||||
public function getMetadata($metadataKey){
|
||||
return $this->server->getPlayerMetadata()->getMetadata($this, $metadataKey);
|
||||
}
|
||||
|
||||
public function hasMetadata($metadataKey){
|
||||
return $this->server->getPlayerMetadata()->hasMetadata($this, $metadataKey);
|
||||
}
|
||||
|
||||
public function removeMetadata($metadataKey, Plugin $plugin){
|
||||
$this->server->getPlayerMetadata()->removeMetadata($this, $metadataKey, $plugin);
|
||||
}
|
||||
|
||||
|
||||
}
|
2388
src/pocketmine/Player.php
Normal file
2388
src/pocketmine/Player.php
Normal file
File diff suppressed because it is too large
Load Diff
@ -14,24 +14,12 @@
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace {
|
||||
/**
|
||||
* Output text to the console, can contain Minecraft-formatted text.
|
||||
*
|
||||
* @param string $message
|
||||
* @param bool $EOL
|
||||
* @param bool $log
|
||||
* @param int $level
|
||||
*/
|
||||
function console($message, $EOL = true, $log = true, $level = 1){
|
||||
pocketmine\console($message, $EOL, $log, $level);
|
||||
}
|
||||
|
||||
function safe_var_dump(){
|
||||
static $cnt = 0;
|
||||
foreach(func_get_args() as $var){
|
||||
@ -77,28 +65,41 @@ namespace {
|
||||
}
|
||||
|
||||
namespace pocketmine {
|
||||
use LogLevel;
|
||||
use pocketmine\utils\Binary;
|
||||
use pocketmine\utils\MainLogger;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use pocketmine\utils\Utils;
|
||||
use pocketmine\wizard\Installer;
|
||||
use raklib\RakLib;
|
||||
|
||||
const VERSION = "Alpha_1.4dev";
|
||||
const API_VERSION = "1.0.0";
|
||||
const API_VERSION = "1.1.0";
|
||||
const CODENAME = "絶好(Zekkou)ケーキ(Cake)";
|
||||
const MINECRAFT_VERSION = "v0.8.1 alpha";
|
||||
const MINECRAFT_VERSION = "v0.9.1 alpha";
|
||||
const PHP_VERSION = "5.5";
|
||||
|
||||
@define("pocketmine\\PATH", \getcwd() . DIRECTORY_SEPARATOR);
|
||||
if(\Phar::running(true) !== ""){
|
||||
@define("pocketmine\\PATH", \Phar::running(true) . "/");
|
||||
}else{
|
||||
@define("pocketmine\\PATH", \getcwd() . DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
if(!class_exists("SplClassLoader", false)){
|
||||
require_once(\pocketmine\PATH . "src/spl/SplClassLoader.php");
|
||||
}
|
||||
|
||||
|
||||
$autoloader = new \SplClassLoader();
|
||||
$autoloader->add("pocketmine", array(
|
||||
$autoloader->setMode(\SplAutoloader::MODE_DEBUG);
|
||||
$autoloader->add("pocketmine", [
|
||||
\pocketmine\PATH . "src"
|
||||
));
|
||||
]);
|
||||
|
||||
$autoloader->register(true);
|
||||
if(!class_exists("raklib\\RakLib", false)){
|
||||
require(\pocketmine\PATH . "src/raklib/raklib/RakLib.php");
|
||||
}
|
||||
RakLib::bootstrap($autoloader);
|
||||
|
||||
//Startup code. Do not look at it, it can harm you. Most of them are hacks to fix date-related bugs, or basic functions used after this
|
||||
|
||||
@ -134,7 +135,7 @@ namespace pocketmine {
|
||||
}
|
||||
}
|
||||
|
||||
gc_enable();
|
||||
gc_disable();
|
||||
error_reporting(E_ALL | E_STRICT);
|
||||
ini_set("allow_url_fopen", 1);
|
||||
ini_set("display_errors", 1);
|
||||
@ -149,11 +150,9 @@ namespace pocketmine {
|
||||
define("pocketmine\\DATA", isset($opts["data"]) ? realpath($opts["data"]) . DIRECTORY_SEPARATOR : \getcwd() . DIRECTORY_SEPARATOR);
|
||||
define("pocketmine\\PLUGIN_PATH", isset($opts["plugins"]) ? realpath($opts["plugins"]) . DIRECTORY_SEPARATOR : \getcwd() . DIRECTORY_SEPARATOR . "plugins" . DIRECTORY_SEPARATOR);
|
||||
|
||||
if((strpos(strtoupper(php_uname("s")), "WIN") === false or isset($opts["enable-ansi"])) and !isset($opts["disable-ansi"])){
|
||||
define("pocketmine\\ANSI", true);
|
||||
}else{
|
||||
define("pocketmine\\ANSI", false);
|
||||
}
|
||||
define("pocketmine\\ANSI", ((strpos(strtoupper(php_uname("s")), "WIN") === false or isset($opts["enable-ansi"])) and !isset($opts["disable-ansi"])));
|
||||
|
||||
$logger = new MainLogger(\pocketmine\DATA . "server.log", \pocketmine\ANSI);
|
||||
|
||||
function kill($pid){
|
||||
switch(Utils::getOS()){
|
||||
@ -167,61 +166,10 @@ namespace pocketmine {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Output text to the console, can contain Minecraft-formatted text.
|
||||
*
|
||||
* @param $message
|
||||
* @param bool $EOL
|
||||
* @param bool $log
|
||||
* @param int $level
|
||||
*/
|
||||
function console($message, $EOL = true, $log = true, $level = 1){
|
||||
if(!defined("pocketmine\\DEBUG") or \pocketmine\DEBUG >= $level){
|
||||
$message .= $EOL === true ? PHP_EOL : "";
|
||||
if($message{0} !== "["){
|
||||
$message = "[INFO] $message";
|
||||
}
|
||||
$time = (\pocketmine\ANSI === true ? TextFormat::AQUA . date("H:i:s") . TextFormat::RESET : date("H:i:s")) . " ";
|
||||
$replaced = TextFormat::clean(preg_replace('/\x1b\[[0-9;]*m/', "", $time . $message));
|
||||
if($log === true and (!defined("LOG") or LOG === true)){
|
||||
log(date("Y-m-d") . " " . $replaced, "server", false, $level);
|
||||
}
|
||||
if(\pocketmine\ANSI === true){
|
||||
$add = "";
|
||||
if(preg_match("/^\\[([a-zA-Z0-9]*)\\]/", $message, $matches) > 0){
|
||||
switch($matches[1]){
|
||||
case "ERROR":
|
||||
case "SEVERE":
|
||||
$add .= TextFormat::RED;
|
||||
break;
|
||||
case "TRACE":
|
||||
case "INTERNAL":
|
||||
case "DEBUG":
|
||||
$add .= TextFormat::GRAY;
|
||||
break;
|
||||
case "WARNING":
|
||||
$add .= TextFormat::YELLOW;
|
||||
break;
|
||||
case "NOTICE":
|
||||
$add .= TextFormat::AQUA;
|
||||
break;
|
||||
default:
|
||||
$add = "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
$message = TextFormat::toANSI($time . $add . $message . TextFormat::RESET);
|
||||
}else{
|
||||
$message = $replaced;
|
||||
}
|
||||
echo $message;
|
||||
}
|
||||
}
|
||||
|
||||
function getTrace($start = 1){
|
||||
$e = new \Exception();
|
||||
$trace = $e->getTrace();
|
||||
$messages = array();
|
||||
$messages = [];
|
||||
$j = 0;
|
||||
for($i = (int) $start; isset($trace[$i]); ++$i, ++$j){
|
||||
$params = "";
|
||||
@ -257,56 +205,38 @@ namespace pocketmine {
|
||||
E_DEPRECATED => "E_DEPRECATED",
|
||||
E_USER_DEPRECATED => "E_USER_DEPRECATED",
|
||||
);
|
||||
$type = ($errno === E_ERROR or $errno === E_WARNING or $errno === E_USER_ERROR or $errno === E_USER_WARNING) ? "ERROR" : "NOTICE";
|
||||
$type = ($errno === E_ERROR or $errno === E_WARNING or $errno === E_USER_ERROR or $errno === E_USER_WARNING) ? LogLevel::ERROR : LogLevel::NOTICE;
|
||||
$errno = isset($errorConversion[$errno]) ? $errorConversion[$errno] : $errno;
|
||||
console("[$type] A $errno error happened: \"$errstr\" in \"$errfile\" at line $errline", true, true, 0);
|
||||
$logger = MainLogger::getLogger();
|
||||
$logger->log($type, "A $errno error happened: \"$errstr\" in \"$errfile\" at line $errline");
|
||||
foreach(getTrace() as $i => $line){
|
||||
console("[TRACE] $line");
|
||||
$logger->debug($line);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function log($message, $name, $EOL = true, $level = 2, $close = false){
|
||||
global $fpointers;
|
||||
if((!defined("pocketmine\\DEBUG") or \pocketmine\DEBUG >= $level) and (!defined("pocketmine\\LOG") or \pocketmine\LOG === true)){
|
||||
$message .= $EOL === true ? PHP_EOL : "";
|
||||
if(!isset($fpointers)){
|
||||
$fpointers = array();
|
||||
}
|
||||
if(!isset($fpointers[$name]) or $fpointers[$name] === false){
|
||||
$fpointers[$name] = @fopen(\pocketmine\DATA . "/" . $name . ".log", "ab");
|
||||
}
|
||||
@fwrite($fpointers[$name], $message);
|
||||
if($close === true){
|
||||
fclose($fpointers[$name]);
|
||||
unset($fpointers[$name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
set_error_handler("\\pocketmine\\error_handler", E_ALL);
|
||||
|
||||
$errors = 0;
|
||||
|
||||
if(version_compare("5.4.0", PHP_VERSION) > 0){
|
||||
console("[ERROR] Use PHP >= 5.4.0", true, true, 0);
|
||||
$logger->critical("Use PHP >= 5.4.0");
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(php_sapi_name() !== "cli"){
|
||||
console("[ERROR] You must run PocketMine-MP using the CLI.", true, true, 0);
|
||||
$logger->critical("You must run PocketMine-MP using the CLI.");
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(!extension_loaded("sockets")){
|
||||
console("[ERROR] Unable to find the Socket extension.", true, true, 0);
|
||||
$logger->critical("Unable to find the Socket extension.");
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(!extension_loaded("pthreads")){
|
||||
console("[ERROR] Unable to find the pthreads extension.", true, true, 0);
|
||||
$logger->critical("Unable to find the pthreads extension.");
|
||||
++$errors;
|
||||
}else{
|
||||
$pthreads_version = phpversion("pthreads");
|
||||
@ -314,33 +244,54 @@ namespace pocketmine {
|
||||
$pthreads_version = "0.$pthreads_version";
|
||||
}
|
||||
if(version_compare($pthreads_version, "2.0.4") < 0){
|
||||
console("[ERROR] pthreads >= 2.0.4 is required, while you have $pthreads_version.", true, true, 0);
|
||||
$logger->critical("pthreads >= 2.0.4 is required, while you have $pthreads_version.");
|
||||
++$errors;
|
||||
}
|
||||
}
|
||||
|
||||
if(!extension_loaded("uopz")){
|
||||
//$logger->notice("Couldn't find the uopz extension. Some functions may be limited");
|
||||
}
|
||||
|
||||
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("Weakref") and !extension_loaded("weakref")){
|
||||
$logger->critical("Unable to find the Weakref extension.");
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(!extension_loaded("curl")){
|
||||
console("[ERROR] Unable to find the cURL extension.", true, true, 0);
|
||||
$logger->critical("Unable to find the cURL extension.");
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(!extension_loaded("sqlite3")){
|
||||
console("[ERROR] Unable to find the SQLite3 extension.", true, true, 0);
|
||||
$logger->critical("Unable to find the SQLite3 extension.");
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(!extension_loaded("yaml")){
|
||||
console("[ERROR] Unable to find the YAML extension.", true, true, 0);
|
||||
$logger->critical("Unable to find the YAML extension.");
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(!extension_loaded("zlib")){
|
||||
console("[ERROR] Unable to find the Zlib extension.", true, true, 0);
|
||||
$logger->critical("Unable to find the Zlib extension.");
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if($errors > 0){
|
||||
console("[ERROR] Please use the installer provided on the homepage, or recompile PHP again.", true, true, 0);
|
||||
$logger->critical("Please use the installer provided on the homepage, or recompile PHP again.");
|
||||
$logger->shutdown();
|
||||
$logger->join();
|
||||
exit(1); //Exit with error
|
||||
}
|
||||
|
||||
@ -350,20 +301,24 @@ namespace pocketmine {
|
||||
define("pocketmine\\GIT_COMMIT", str_repeat("00", 20));
|
||||
}
|
||||
|
||||
@define("ENDIANNESS", (pack("d", 1) === "\77\360\0\0\0\0\0\0" ? Binary::BIG_ENDIAN : Binary::LITTLE_ENDIAN));
|
||||
@define("INT32_MASK", is_int(0xffffffff) ? 0xffffffff : -1);
|
||||
@ini_set("opcache.mmap_base", bin2hex(Utils::getRandomBytes(8, false))); //Fix OPCache address errors
|
||||
|
||||
if(!file_exists(\pocketmine\DATA . "server.properties") and !isset($opts["no-wizard"])){
|
||||
new Installer();
|
||||
}
|
||||
|
||||
if(substr(__FILE__, 0, 7) !== "phar"){
|
||||
console("[WARNING] Non-packaged PocketMine-MP installation detected, do not use on production.");
|
||||
if(substr(__FILE__, 0, 7) !== "phar://"){
|
||||
$logger->warning("Non-packaged PocketMine-MP installation detected, do not use on production.");
|
||||
}
|
||||
|
||||
$server = new Server($autoloader, \pocketmine\PATH, \pocketmine\DATA, \pocketmine\PLUGIN_PATH);
|
||||
$server = new Server($autoloader, $logger, \pocketmine\PATH, \pocketmine\DATA, \pocketmine\PLUGIN_PATH);
|
||||
$server->start();
|
||||
$logger->shutdown();
|
||||
$logger->join();
|
||||
|
||||
kill(getmypid());
|
||||
exit(0);
|
||||
|
||||
}
|
||||
}
|
2035
src/pocketmine/Server.php
Normal file
2035
src/pocketmine/Server.php
Normal file
File diff suppressed because it is too large
Load Diff
@ -19,23 +19,18 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class PingPacket extends DataPacket{
|
||||
public $time = 0;
|
||||
|
||||
public function pid(){
|
||||
return Info::PING_PACKET;
|
||||
class AcaciaWoodStairs extends Stair{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::ACACIA_WOOD_STAIRS, $meta, "Acacia Wood Stairs");
|
||||
}
|
||||
|
||||
public function decode(){
|
||||
$this->time = $this->getLong();
|
||||
public function getDrops(Item $item){
|
||||
return array(
|
||||
array($this->id, 0, 1),
|
||||
);
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putLong($this->time);
|
||||
}
|
||||
|
||||
}
|
@ -21,6 +21,8 @@
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
|
||||
|
||||
/**
|
||||
* Air block
|
||||
@ -41,4 +43,8 @@ class Air extends Transparent{
|
||||
|
||||
}
|
||||
|
||||
public function getBoundingBox(){
|
||||
return new AxisAlignedBB(0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
}
|
@ -24,7 +24,6 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\network\protocol\ChatPacket;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
|
||||
class Bed extends Transparent{
|
||||
public function __construct($type = 0){
|
||||
@ -35,13 +34,13 @@ class Bed extends Transparent{
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
if($player instanceof Player and Server::getInstance()->api->time->getPhase($this->level) !== "night"){
|
||||
/*if($player instanceof Player and Server::getInstance()->api->time->getPhase($this->getLevel()) !== "night"){
|
||||
$pk = new ChatPacket;
|
||||
$pk->message = "You can only sleep at night";
|
||||
$player->dataPacket($pk);
|
||||
|
||||
return true;
|
||||
}
|
||||
}*/
|
||||
|
||||
$blockNorth = $this->getSide(2); //Gets the blocks around them
|
||||
$blockSouth = $this->getSide(3);
|
||||
@ -90,8 +89,8 @@ class Bed extends Transparent{
|
||||
$downNext = $this->getSide(0);
|
||||
if($next->isReplaceable === true and $downNext->isTransparent === false){
|
||||
$meta = (($d + 3) % 4) & 0x03;
|
||||
$this->level->setBlock($block, Block::get($this->id, $meta), true, false, true);
|
||||
$this->level->setBlock($next, Block::get($this->id, $meta | 0x08), true, false, true);
|
||||
$this->getLevel()->setBlock($block, Block::get($this->id, $meta), true, false, true);
|
||||
$this->getLevel()->setBlock($next, Block::get($this->id, $meta | 0x08), true, false, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -108,26 +107,26 @@ class Bed extends Transparent{
|
||||
|
||||
if(($this->meta & 0x08) === 0x08){ //This is the Top part of bed
|
||||
if($blockNorth->getID() === $this->id and $blockNorth->meta !== 0x08){ //Checks if the block ID and meta are right
|
||||
$this->level->setBlock($blockNorth, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($blockNorth, new Air(), true, false, true);
|
||||
}elseif($blockSouth->getID() === $this->id and $blockSouth->meta !== 0x08){
|
||||
$this->level->setBlock($blockSouth, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($blockSouth, new Air(), true, false, true);
|
||||
}elseif($blockEast->getID() === $this->id and $blockEast->meta !== 0x08){
|
||||
$this->level->setBlock($blockEast, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($blockEast, new Air(), true, false, true);
|
||||
}elseif($blockWest->getID() === $this->id and $blockWest->meta !== 0x08){
|
||||
$this->level->setBlock($blockWest, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($blockWest, new Air(), true, false, true);
|
||||
}
|
||||
}else{ //Bottom Part of Bed
|
||||
if($blockNorth->getID() === $this->id and ($blockNorth->meta & 0x08) === 0x08){
|
||||
$this->level->setBlock($blockNorth, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($blockNorth, new Air(), true, false, true);
|
||||
}elseif($blockSouth->getID() === $this->id and ($blockSouth->meta & 0x08) === 0x08){
|
||||
$this->level->setBlock($blockSouth, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($blockSouth, new Air(), true, false, true);
|
||||
}elseif($blockEast->getID() === $this->id and ($blockEast->meta & 0x08) === 0x08){
|
||||
$this->level->setBlock($blockEast, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($blockEast, new Air(), true, false, true);
|
||||
}elseif($blockWest->getID() === $this->id and ($blockWest->meta & 0x08) === 0x08){
|
||||
$this->level->setBlock($blockWest, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($blockWest, new Air(), true, false, true);
|
||||
}
|
||||
}
|
||||
$this->level->setBlock($this, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($this, new Air(), true, false, true);
|
||||
|
||||
return true;
|
||||
}
|
@ -35,7 +35,7 @@ class Beetroot extends Flowable{
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === self::FARMLAND){
|
||||
$this->level->setBlock($block, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -44,9 +44,9 @@ class Beetroot extends Flowable{
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
if($item->getID() === Item::DYE and $item->getMetadata() === 0x0F){ //Bonemeal
|
||||
if($item->getID() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal
|
||||
$this->meta = 0x07;
|
||||
$this->level->setBlock($this, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($this, $this, true, false, true);
|
||||
$item->count--;
|
||||
|
||||
return true;
|
||||
@ -57,10 +57,9 @@ class Beetroot extends Flowable{
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
|
||||
//TODO
|
||||
//Server::getInstance()->api->entity->drop($this, Item::get(BEETROOT_SEEDS, 0, 1));
|
||||
$this->level->setBlock($this, new Air(), false, false, true);
|
||||
if($this->getSide(0)->isTransparent === true){ //TODO: Replace with common break method
|
||||
$this->getLevel()->dropItem($this, Item::get(Item::BEETROOT_SEEDS, 0, 1));
|
||||
$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
@ -68,7 +67,7 @@ class Beetroot extends Flowable{
|
||||
if(mt_rand(0, 2) == 1){
|
||||
if($this->meta < 0x07){
|
||||
++$this->meta;
|
||||
$this->level->setBlock($this, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($this, $this, true, false, true);
|
||||
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
@ -81,7 +80,7 @@ class Beetroot extends Flowable{
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
$drops = array();
|
||||
$drops = [];
|
||||
if($this->meta >= 0x07){
|
||||
$drops[] = array(Item::BEETROOT, 0, 1);
|
||||
$drops[] = array(Item::BEETROOT_SEEDS, 0, mt_rand(0, 3));
|
@ -27,9 +27,14 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\level\Position;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\metadata\Metadatable;
|
||||
use pocketmine\metadata\MetadataValue;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\plugin\Plugin;
|
||||
|
||||
abstract class Block extends Position{
|
||||
|
||||
abstract class Block extends Position implements Metadatable{
|
||||
const AIR = 0;
|
||||
const STONE = 1;
|
||||
const GRASS = 2;
|
||||
@ -74,7 +79,7 @@ abstract class Block extends Position{
|
||||
const WOOL = 35;
|
||||
const DANDELION = 37;
|
||||
const ROSE = 38;
|
||||
const CYAN_FLOWER = 38;
|
||||
const POPPY = 38;
|
||||
const BROWN_MUSHROOM = 39;
|
||||
const RED_MUSHROOM = 40;
|
||||
const GOLD_BLOCK = 41;
|
||||
@ -168,7 +173,9 @@ abstract class Block extends Position{
|
||||
const NETHER_BRICKS_STAIRS = 114;
|
||||
|
||||
const SANDSTONE_STAIRS = 128;
|
||||
const EMERALD_ORE = 129;
|
||||
|
||||
const EMERALD_BLOCK = 133;
|
||||
const SPRUCE_WOOD_STAIRS = 134;
|
||||
const SPRUCE_WOODEN_STAIRS = 134;
|
||||
const BIRCH_WOOD_STAIRS = 135;
|
||||
@ -193,10 +200,22 @@ abstract class Block extends Position{
|
||||
const WOODEN_SLAB = 158;
|
||||
const WOOD_SLABS = 158;
|
||||
const WOODEN_SLABS = 158;
|
||||
const STAINED_CLAY = 159;
|
||||
const STAINED_HARDENED_CLAY = 159;
|
||||
|
||||
const LEAVES2 = 161;
|
||||
const LEAVE2 = 161;
|
||||
const WOOD2 = 162;
|
||||
const TRUNK2 = 162;
|
||||
const LOG2 = 162;
|
||||
const ACACIA_WOOD_STAIRS = 163;
|
||||
const ACACIA_WOODEN_STAIRS = 163;
|
||||
const DARK_OAK_WOOD_STAIRS = 164;
|
||||
const DARK_OAK_WOODEN_STAIRS = 164;
|
||||
|
||||
const HAY_BALE = 170;
|
||||
const CARPET = 171;
|
||||
|
||||
const HARDENED_CLAY = 172;
|
||||
const COAL_BLOCK = 173;
|
||||
|
||||
const BEETROOT_BLOCK = 244;
|
||||
@ -204,8 +223,277 @@ abstract class Block extends Position{
|
||||
const GLOWING_OBSIDIAN = 246;
|
||||
const NETHER_REACTOR = 247;
|
||||
|
||||
public static $creative = array(
|
||||
//Building
|
||||
[Item::COBBLESTONE, 0],
|
||||
[Item::STONE_BRICKS, 0],
|
||||
[Item::STONE_BRICKS, 1],
|
||||
[Item::STONE_BRICKS, 2],
|
||||
[Item::MOSS_STONE, 0],
|
||||
[Item::WOODEN_PLANKS, 0],
|
||||
[Item::WOODEN_PLANKS, 1],
|
||||
[Item::WOODEN_PLANKS, 2],
|
||||
[Item::WOODEN_PLANKS, 3],
|
||||
[Item::WOODEN_PLANKS, 4],
|
||||
[Item::WOODEN_PLANKS, 5],
|
||||
[Item::BRICKS, 0],
|
||||
|
||||
public static $list = array();
|
||||
[Item::STONE, 0],
|
||||
[Item::STONE, 1],
|
||||
[Item::STONE, 2],
|
||||
[Item::STONE, 3],
|
||||
[Item::STONE, 4],
|
||||
[Item::STONE, 5],
|
||||
[Item::STONE, 6],
|
||||
[Item::DIRT, 0],
|
||||
//TODO: PODZOL
|
||||
[Item::GRASS, 0],
|
||||
//TODO: MYCELIUM
|
||||
[Item::CLAY_BLOCK, 0],
|
||||
[Item::HARDENED_CLAY, 0],
|
||||
[Item::STAINED_CLAY, 0],
|
||||
[Item::STAINED_CLAY, 7],
|
||||
[Item::STAINED_CLAY, 6],
|
||||
[Item::STAINED_CLAY, 5],
|
||||
[Item::STAINED_CLAY, 4],
|
||||
[Item::STAINED_CLAY, 3],
|
||||
[Item::STAINED_CLAY, 2],
|
||||
[Item::STAINED_CLAY, 1],
|
||||
[Item::STAINED_CLAY, 15],
|
||||
[Item::STAINED_CLAY, 14],
|
||||
[Item::STAINED_CLAY, 13],
|
||||
[Item::STAINED_CLAY, 12],
|
||||
[Item::STAINED_CLAY, 11],
|
||||
[Item::STAINED_CLAY, 10],
|
||||
[Item::STAINED_CLAY, 9],
|
||||
[Item::STAINED_CLAY, 8],
|
||||
[Item::SANDSTONE, 0],
|
||||
[Item::SANDSTONE, 1],
|
||||
[Item::SANDSTONE, 2],
|
||||
[Item::SAND, 0],
|
||||
[Item::GRAVEL, 0],
|
||||
[Item::TRUNK, 0],
|
||||
[Item::TRUNK, 1],
|
||||
[Item::TRUNK, 2],
|
||||
[Item::TRUNK, 3],
|
||||
[Item::TRUNK2, 0],
|
||||
[Item::TRUNK2, 1],
|
||||
[Item::NETHER_BRICKS, 0],
|
||||
[Item::NETHERRACK, 0],
|
||||
[Item::BEDROCK, 0],
|
||||
[Item::COBBLESTONE_STAIRS, 0],
|
||||
[Item::OAK_WOODEN_STAIRS, 0],
|
||||
[Item::SPRUCE_WOODEN_STAIRS, 0],
|
||||
[Item::BIRCH_WOODEN_STAIRS, 0],
|
||||
[Item::JUNGLE_WOODEN_STAIRS, 0],
|
||||
[Item::ACACIA_WOODEN_STAIRS, 0],
|
||||
[Item::DARK_OAK_WOODEN_STAIRS, 0],
|
||||
[Item::BRICK_STAIRS, 0],
|
||||
[Item::SANDSTONE_STAIRS, 0],
|
||||
[Item::STONE_BRICK_STAIRS, 0],
|
||||
[Item::NETHER_BRICKS_STAIRS, 0],
|
||||
[Item::QUARTZ_STAIRS, 0],
|
||||
[Item::SLAB, 0],
|
||||
[Item::SLAB, 1],
|
||||
[Item::WOODEN_SLAB, 0],
|
||||
[Item::WOODEN_SLAB, 1],
|
||||
[Item::WOODEN_SLAB, 2],
|
||||
[Item::WOODEN_SLAB, 3],
|
||||
[Item::WOODEN_SLAB, 4],
|
||||
[Item::WOODEN_SLAB, 5],
|
||||
[Item::SLAB, 3],
|
||||
[Item::SLAB, 4],
|
||||
[Item::SLAB, 5],
|
||||
[Item::SLAB, 6],
|
||||
[Item::QUARTZ_BLOCK, 0],
|
||||
[Item::QUARTZ_BLOCK, 1],
|
||||
[Item::QUARTZ_BLOCK, 2],
|
||||
[Item::COAL_ORE, 0],
|
||||
[Item::IRON_ORE, 0],
|
||||
[Item::GOLD_ORE, 0],
|
||||
[Item::DIAMOND_ORE, 0],
|
||||
[Item::LAPIS_ORE, 0],
|
||||
[Item::REDSTONE_ORE, 0],
|
||||
[Item::EMERALD_ORE, 0],
|
||||
[Item::OBSIDIAN, 0],
|
||||
[Item::ICE, 0],
|
||||
[Item::SNOW_BLOCK, 0],
|
||||
//TODO: ENDSTONE
|
||||
|
||||
//Decoration
|
||||
[Item::COBBLESTONE_WALL, 0],
|
||||
[Item::COBBLESTONE_WALL, 1],
|
||||
//TODO: Lilly Pad
|
||||
[Item::GOLD_BLOCK, 0],
|
||||
[Item::IRON_BLOCK, 0],
|
||||
[Item::DIAMOND_BLOCK, 0],
|
||||
[Item::LAPIS_BLOCK, 0],
|
||||
[Item::COAL_BLOCK, 0],
|
||||
[Item::EMERALD_BLOCK, 0],
|
||||
[Item::SNOW_LAYER, 0],
|
||||
[Item::GLASS, 0],
|
||||
[Item::GLOWSTONE_BLOCK, 0],
|
||||
//TODO: Vines
|
||||
[Item::NETHER_REACTOR, 0],
|
||||
[Item::LADDER, 0],
|
||||
[Item::SPONGE, 0],
|
||||
[Item::GLASS_PANE, 0],
|
||||
[Item::WOODEN_DOOR, 0],
|
||||
[Item::TRAPDOOR, 0],
|
||||
[Item::FENCE, 0],
|
||||
[Item::FENCE_GATE, 0],
|
||||
[Item::IRON_BARS, 0],
|
||||
[Item::BED, 0],
|
||||
[Item::BOOKSHELF, 0],
|
||||
[Item::PAINTING, 0],
|
||||
[Item::WORKBENCH, 0],
|
||||
[Item::STONECUTTER, 0],
|
||||
[Item::CHEST, 0],
|
||||
[Item::FURNACE, 0],
|
||||
//TODO: End Portal
|
||||
[Item::DANDELION, 0],
|
||||
[Item::POPPY, 0],
|
||||
//TODO: blue orchid
|
||||
//TODO: Allium
|
||||
//TODO: Azure Bluet
|
||||
//TODO: Red Tulip
|
||||
//TODO: Orange Tulip
|
||||
//TODO: White Tulip
|
||||
//TODO: Pink Tulip
|
||||
//TODO: Oxeye Daisy
|
||||
//TODO: Lilac
|
||||
//TODO: Double Tallgrass
|
||||
//TODO: Large Fern
|
||||
//TODO: Rose Bush
|
||||
//TODO: Peony
|
||||
[Item::BROWN_MUSHROOM, 0],
|
||||
[Item::RED_MUSHROOM, 0],
|
||||
//TODO: Mushroom block (brown, cover)
|
||||
//TODO: Mushroom block (red, cover)
|
||||
//TODO: Mushroom block (brown, stem)
|
||||
//TODO: Mushroom block (red, stem)
|
||||
[Item::CACTUS, 0],
|
||||
[Item::MELON_BLOCK, 0],
|
||||
[Item::PUMPKIN, 0],
|
||||
[Item::LIT_PUMPKIN, 0],
|
||||
[Item::COBWEB, 0],
|
||||
[Item::HAY_BALE, 0],
|
||||
[Item::TALL_GRASS, 1],
|
||||
[Item::TALL_GRASS, 2],
|
||||
[Item::DEAD_BUSH, 0],
|
||||
[Item::SAPLING, 0],
|
||||
[Item::SAPLING, 1],
|
||||
[Item::SAPLING, 2],
|
||||
[Item::SAPLING, 3],
|
||||
[Item::SAPLING, 4],
|
||||
[Item::SAPLING, 5],
|
||||
[Item::LEAVES, 0],
|
||||
[Item::LEAVES, 1],
|
||||
[Item::LEAVES, 2],
|
||||
[Item::LEAVES, 3],
|
||||
[Item::LEAVES, 3],
|
||||
[Item::LEAVES2, 0],
|
||||
[Item::LEAVES2, 1],
|
||||
[Item::CAKE, 0],
|
||||
[Item::SIGN, 0],
|
||||
//TODO: Monster Spawner
|
||||
[Item::WOOL, 0],
|
||||
[Item::WOOL, 7],
|
||||
[Item::WOOL, 6],
|
||||
[Item::WOOL, 5],
|
||||
[Item::WOOL, 4],
|
||||
[Item::WOOL, 3],
|
||||
[Item::WOOL, 2],
|
||||
[Item::WOOL, 1],
|
||||
[Item::WOOL, 15],
|
||||
[Item::WOOL, 14],
|
||||
[Item::WOOL, 13],
|
||||
[Item::WOOL, 12],
|
||||
[Item::WOOL, 11],
|
||||
[Item::WOOL, 10],
|
||||
[Item::WOOL, 9],
|
||||
[Item::WOOL, 8],
|
||||
[Item::CARPET, 0],
|
||||
[Item::CARPET, 7],
|
||||
[Item::CARPET, 6],
|
||||
[Item::CARPET, 5],
|
||||
[Item::CARPET, 4],
|
||||
[Item::CARPET, 3],
|
||||
[Item::CARPET, 2],
|
||||
[Item::CARPET, 1],
|
||||
[Item::CARPET, 15],
|
||||
[Item::CARPET, 14],
|
||||
[Item::CARPET, 13],
|
||||
[Item::CARPET, 12],
|
||||
[Item::CARPET, 11],
|
||||
[Item::CARPET, 10],
|
||||
[Item::CARPET, 9],
|
||||
[Item::CARPET, 8],
|
||||
|
||||
//Tools
|
||||
//TODO [Item::RAILS, 0],
|
||||
//TODO [Item::POWERED_RAILS, 0],
|
||||
[Item::TORCH, 0],
|
||||
[Item::BUCKET, 0],
|
||||
[Item::BUCKET, 8],
|
||||
[Item::BUCKET, 10],
|
||||
[Item::TNT, 0],
|
||||
[Item::IRON_HOE, 0],
|
||||
[Item::IRON_SWORD, 0],
|
||||
[Item::BOW, 0],
|
||||
[Item::SHEARS, 0],
|
||||
[Item::FLINT_AND_STEEL, 0],
|
||||
[Item::CLOCK, 0],
|
||||
[Item::COMPASS, 0],
|
||||
[Item::MINECART, 0],
|
||||
//TODO: Villager
|
||||
[Item::SPAWN_EGG, 10], //Chicken
|
||||
[Item::SPAWN_EGG, 11], //Cow
|
||||
[Item::SPAWN_EGG, 12], //Pig
|
||||
[Item::SPAWN_EGG, 13], //Sheep
|
||||
//TODO: Wolf
|
||||
//TODO: Mooshroom
|
||||
//TODO: Creeper
|
||||
//TODO: Enderman
|
||||
//TODO: Silverfish
|
||||
//TODO: Skeleton
|
||||
//TODO: Slime
|
||||
//TODO: Zombie
|
||||
//TODO: PigZombie
|
||||
//TODO: Replace with Entity constants
|
||||
|
||||
|
||||
//Seeds
|
||||
[Item::SUGARCANE, 0],
|
||||
[Item::WHEAT, 0],
|
||||
[Item::SEEDS, 0],
|
||||
[Item::MELON_SEEDS, 0],
|
||||
[Item::PUMPKIN_SEEDS, 0],
|
||||
[Item::CARROT, 0],
|
||||
[Item::POTATO, 0],
|
||||
[Item::BEETROOT_SEEDS, 0],
|
||||
[Item::EGG, 0],
|
||||
[Item::DYE, 0],
|
||||
[Item::DYE, 7],
|
||||
[Item::DYE, 6],
|
||||
[Item::DYE, 5],
|
||||
[Item::DYE, 4],
|
||||
[Item::DYE, 3],
|
||||
[Item::DYE, 2],
|
||||
[Item::DYE, 1],
|
||||
[Item::DYE, 15],
|
||||
[Item::DYE, 14],
|
||||
[Item::DYE, 13],
|
||||
[Item::DYE, 12],
|
||||
[Item::DYE, 11],
|
||||
[Item::DYE, 10],
|
||||
[Item::DYE, 9],
|
||||
[Item::DYE, 8],
|
||||
|
||||
);
|
||||
|
||||
/** @var Block[] */
|
||||
public static $list = [];
|
||||
protected $id;
|
||||
protected $meta;
|
||||
protected $name;
|
||||
@ -218,13 +506,13 @@ abstract class Block extends Position{
|
||||
public $isTransparent = false;
|
||||
public $isReplaceable = false;
|
||||
public $isPlaceable = true;
|
||||
public $level = false;
|
||||
public $hasPhysics = false;
|
||||
public $isLiquid = false;
|
||||
public $isFullBlock = true;
|
||||
public $x = 0;
|
||||
public $y = 0;
|
||||
public $z = 0;
|
||||
public $frictionFactor = 0.6;
|
||||
|
||||
public static function init(){
|
||||
if(count(self::$list) === 0){
|
||||
@ -259,7 +547,7 @@ abstract class Block extends Position{
|
||||
self::DEAD_BUSH => new DeadBush(),
|
||||
self::WOOL => new Wool(),
|
||||
self::DANDELION => new Dandelion(),
|
||||
self::CYAN_FLOWER => new CyanFlower(),
|
||||
self::POPPY => new CyanFlower(),
|
||||
self::BROWN_MUSHROOM => new BrownMushroom(),
|
||||
self::RED_MUSHROOM => new RedMushroom(),
|
||||
self::GOLD_BLOCK => new Gold(),
|
||||
@ -330,7 +618,9 @@ abstract class Block extends Position{
|
||||
self::NETHER_BRICKS_STAIRS => new NetherBrickStairs(),
|
||||
|
||||
self::SANDSTONE_STAIRS => new SandstoneStairs(),
|
||||
self::EMERALD_ORE => new EmeraldOre(),
|
||||
|
||||
self::EMERALD_BLOCK => new Emerald(),
|
||||
self::SPRUCE_WOOD_STAIRS => new SpruceWoodStairs(),
|
||||
self::BIRCH_WOOD_STAIRS => new BirchWoodStairs(),
|
||||
self::JUNGLE_WOOD_STAIRS => new JungleWoodStairs(),
|
||||
@ -343,15 +633,22 @@ abstract class Block extends Position{
|
||||
self::QUARTZ_STAIRS => new QuartzStairs(),
|
||||
self::DOUBLE_WOOD_SLAB => new DoubleWoodSlab(),
|
||||
self::WOOD_SLAB => new WoodSlab(),
|
||||
self::STAINED_CLAY => new StainedClay(),
|
||||
|
||||
self::LEAVES2 => new Leaves2(),
|
||||
self::WOOD2 => new Wood2(),
|
||||
self::ACACIA_WOOD_STAIRS => new AcaciaWoodStairs(),
|
||||
self::DARK_OAK_WOOD_STAIRS => new DarkOakWoodStairs(),
|
||||
|
||||
self::HAY_BALE => new HayBale(),
|
||||
self::CARPET => new Carpet(),
|
||||
|
||||
self::HARDENED_CLAY => new HardenedClay(),
|
||||
self::COAL_BLOCK => new Coal(),
|
||||
|
||||
self::BEETROOT_BLOCK => new Beetroot(),
|
||||
self::STONECUTTER => new Stonecutter(),
|
||||
self::GLOWING_OBSIDIAN => new GlowingObsidian(),
|
||||
self::NETHER_REACTOR => new NetherReactor(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -366,7 +663,7 @@ abstract class Block extends Position{
|
||||
public static function get($id, $meta = 0, Position $pos = null){
|
||||
if(isset(self::$list[$id])){
|
||||
$block = clone self::$list[$id];
|
||||
$block->setMetadata($meta);
|
||||
$block->setDamage($meta);
|
||||
}else{
|
||||
$block = new Generic($id, $meta);
|
||||
}
|
||||
@ -414,14 +711,14 @@ abstract class Block extends Position{
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
final public function getMetadata(){
|
||||
final public function getDamage(){
|
||||
return $this->meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $meta
|
||||
*/
|
||||
final public function setMetadata($meta){
|
||||
final public function setDamage($meta){
|
||||
$this->meta = $meta & 0x0F;
|
||||
}
|
||||
|
||||
@ -431,10 +728,10 @@ abstract class Block extends Position{
|
||||
* @param Position $v
|
||||
*/
|
||||
final public function position(Position $v){
|
||||
$this->level = $v->level;
|
||||
$this->x = (int) $v->x;
|
||||
$this->y = (int) $v->y;
|
||||
$this->z = (int) $v->z;
|
||||
$this->level = $v->level;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -446,11 +743,11 @@ abstract class Block extends Position{
|
||||
*/
|
||||
public function getDrops(Item $item){
|
||||
if(!isset(self::$list[$this->id])){ //Unknown blocks
|
||||
return array();
|
||||
return [];
|
||||
}else{
|
||||
return array(
|
||||
return [
|
||||
array($this->id, $this->meta, 1),
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -469,16 +766,17 @@ abstract class Block extends Position{
|
||||
* Returns the Block on the side $side, works like Vector3::side()
|
||||
*
|
||||
* @param int $side
|
||||
* @param int $step
|
||||
*
|
||||
* @return Block
|
||||
*/
|
||||
public function getSide($side){
|
||||
$v = parent::getSide($side);
|
||||
if($this->level instanceof Level){
|
||||
return $this->level->getBlock($v);
|
||||
public function getSide($side, $step = 1){
|
||||
$v = parent::getSide($side, $step);
|
||||
if($this->isValid()){
|
||||
return $this->getLevel()->getBlock($v);
|
||||
}
|
||||
|
||||
return $v;
|
||||
return Block::get(Item::AIR, 0, $v);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -506,6 +804,33 @@ abstract class Block extends Position{
|
||||
*/
|
||||
abstract function onBreak(Item $item);
|
||||
|
||||
/**
|
||||
* Checks for collision against an AxisAlignedBB
|
||||
*
|
||||
* @param AxisAlignedBB $bb
|
||||
* @param Block[] $list
|
||||
*/
|
||||
public function collidesWithBB(AxisAlignedBB $bb, &$list = array()){
|
||||
$bb2 = $this->getBoundingBox();
|
||||
if($bb2->intersectsWith($bb)){
|
||||
$list[] = $bb2;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AxisAlignedBB
|
||||
*/
|
||||
public function getBoundingBox(){
|
||||
return new AxisAlignedBB(
|
||||
$this->x,
|
||||
$this->y,
|
||||
$this->z,
|
||||
$this->x + 1,
|
||||
$this->y + 1,
|
||||
$this->z + 1
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Places the Block, using block space and block target, and side. Returns if the block has been placed.
|
||||
*
|
||||
@ -540,4 +865,28 @@ abstract class Block extends Position{
|
||||
* @return void
|
||||
*/
|
||||
abstract function onUpdate($type);
|
||||
|
||||
public function setMetadata($metadataKey, MetadataValue $metadataValue){
|
||||
if($this->getLevel() instanceof Level){
|
||||
$this->getLevel()->getBlockMetadata()->setMetadata($this, $metadataKey, $metadataValue);
|
||||
}
|
||||
}
|
||||
|
||||
public function getMetadata($metadataKey){
|
||||
if($this->getLevel() instanceof Level){
|
||||
$this->getLevel()->getBlockMetadata()->getMetadata($this, $metadataKey);
|
||||
}
|
||||
}
|
||||
|
||||
public function hasMetadata($metadataKey){
|
||||
if($this->getLevel() instanceof Level){
|
||||
$this->getLevel()->getBlockMetadata()->hasMetadata($this, $metadataKey);
|
||||
}
|
||||
}
|
||||
|
||||
public function removeMetadata($metadataKey, Plugin $plugin){
|
||||
if($this->getLevel() instanceof Level){
|
||||
$this->getLevel()->getBlockMetadata()->removeMetadata($this, $metadataKey, $plugin);
|
||||
}
|
||||
}
|
||||
}
|
@ -52,7 +52,7 @@ class Bricks extends Solid{
|
||||
array(Item::BRICKS_BLOCK, 0, 1),
|
||||
);
|
||||
}else{
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
@ -34,9 +34,8 @@ class BrownMushroom extends Flowable{
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
|
||||
//TODO
|
||||
//Server::getInstance()->api->entity->drop($this, Item::get($this->id));
|
||||
$this->level->setBlock($this, new Air(), false, false, true);
|
||||
$this->getLevel()->dropItem($this, Item::get($this->id));
|
||||
$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
@ -48,7 +47,7 @@ class BrownMushroom extends Flowable{
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->isTransparent === false){
|
||||
$this->level->setBlock($block, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
||||
|
||||
return true;
|
||||
}
|
@ -46,49 +46,49 @@ class BurningFurnace extends Solid{
|
||||
3 => 3,
|
||||
);
|
||||
$this->meta = $faces[$player instanceof Player ? $player->getDirection() : 0];
|
||||
$this->level->setBlock($block, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
||||
$nbt = new Compound(false, array(
|
||||
new Enum("Items", array()),
|
||||
new Enum("Items", []),
|
||||
new String("id", Tile::FURNACE),
|
||||
new Int("x", $this->x),
|
||||
new Int("y", $this->y),
|
||||
new Int("z", $this->z)
|
||||
));
|
||||
$nbt->Items->setTagType(NBT::TAG_Compound);
|
||||
new Furnace($this->level, $nbt);
|
||||
new Furnace($this->getLevel()->getChunkAt($this->x >> 4, $this->z >> 4), $nbt);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onBreak(Item $item){
|
||||
$this->level->setBlock($this, new Air(), true, true, true);
|
||||
$this->getLevel()->setBlock($this, new Air(), true, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
if($player instanceof Player){
|
||||
$t = $this->level->getTile($this);
|
||||
$t = $this->getLevel()->getTile($this);
|
||||
$furnace = false;
|
||||
if($t instanceof Furnace){
|
||||
$furnace = $t;
|
||||
}else{
|
||||
$nbt = new Compound(false, array(
|
||||
new Enum("Items", array()),
|
||||
new Enum("Items", []),
|
||||
new String("id", Tile::FURNACE),
|
||||
new Int("x", $this->x),
|
||||
new Int("y", $this->y),
|
||||
new Int("z", $this->z)
|
||||
));
|
||||
$nbt->Items->setTagType(NBT::TAG_Compound);
|
||||
$furnace = new Furnace($this->level, $nbt);
|
||||
$furnace = new Furnace($this->getLevel()->getChunkAt($this->x >> 4, $this->z >> 4), $nbt);
|
||||
}
|
||||
|
||||
if(($player->getGamemode() & 0x01) === 0x01){
|
||||
return true;
|
||||
}
|
||||
|
||||
$furnace->openInventory($player);
|
||||
$player->addWindow($furnace->getInventory());
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -112,16 +112,16 @@ class BurningFurnace extends Solid{
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
$drops = array();
|
||||
$drops = [];
|
||||
if($item->isPickaxe() >= 1){
|
||||
$drops[] = array(Item::FURNACE, 0, 1);
|
||||
}
|
||||
$t = $this->level->getTile($this);
|
||||
$t = $this->getLevel()->getTile($this);
|
||||
if($t instanceof Furnace){
|
||||
for($s = 0; $s < Furnace::SLOTS; ++$s){
|
||||
$slot = $t->getSlot($s);
|
||||
for($s = 0; $s < $t->getInventory()->getSize(); ++$s){
|
||||
$slot = $t->getInventory()->getItem($s);
|
||||
if($slot->getID() > Item::AIR and $slot->getCount() > 0){
|
||||
$drops[] = array($slot->getID(), $slot->getMetadata(), $slot->getCount());
|
||||
$drops[] = array($slot->getID(), $slot->getDamage(), $slot->getCount());
|
||||
}
|
||||
}
|
||||
}
|
@ -38,7 +38,7 @@ class Cactus extends Transparent{
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() !== self::SAND and $down->getID() !== self::CACTUS){ //Replace with common break method
|
||||
$this->level->setBlock($this, new Air(), false);
|
||||
$this->getLevel()->setBlock($this, new Air(), false);
|
||||
Server::getInstance()->api->entity->drop($this, Item::get($this->id));
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
@ -47,17 +47,17 @@ class Cactus extends Transparent{
|
||||
if($this->getSide(0)->getID() !== self::CACTUS){
|
||||
if($this->meta == 0x0F){
|
||||
for($y = 1; $y < 3; ++$y){
|
||||
$b = $this->level->getBlock(new Vector3($this->x, $this->y + $y, $this->z));
|
||||
$b = $this->getLevel()->getBlock(new Vector3($this->x, $this->y + $y, $this->z));
|
||||
if($b->getID() === self::AIR){
|
||||
$this->level->setBlock($b, new Cactus(), true, false, true);
|
||||
$this->getLevel()->setBlock($b, new Cactus(), true, false, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->meta = 0;
|
||||
$this->level->setBlock($this, $this, false);
|
||||
$this->getLevel()->setBlock($this, $this, false);
|
||||
}else{
|
||||
++$this->meta;
|
||||
$this->level->setBlock($this, $this, false);
|
||||
$this->getLevel()->setBlock($this, $this, false);
|
||||
}
|
||||
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
@ -75,7 +75,7 @@ class Cactus extends Transparent{
|
||||
$block2 = $this->getSide(4);
|
||||
$block3 = $this->getSide(5);
|
||||
if($block0->isTransparent === true and $block1->isTransparent === true and $block2->isTransparent === true and $block3->isTransparent === true){
|
||||
$this->level->setBlock($this, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($this, $this, true, false, true);
|
||||
|
||||
return true;
|
||||
}
|
@ -37,7 +37,7 @@ class Cake extends Transparent{
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() !== self::AIR){
|
||||
$this->level->setBlock($block, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -48,7 +48,7 @@ class Cake extends Transparent{
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->getID() === self::AIR){ //Replace with common break method
|
||||
$this->level->setBlock($this, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($this, new Air(), true, false, true);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
@ -58,7 +58,7 @@ class Cake extends Transparent{
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
@ -66,9 +66,9 @@ class Cake extends Transparent{
|
||||
++$this->meta;
|
||||
$player->heal(3, "cake");
|
||||
if($this->meta >= 0x06){
|
||||
$this->level->setBlock($this, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($this, new Air(), true, false, true);
|
||||
}else{
|
||||
$this->level->setBlock($this, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($this, $this, true, false, true);
|
||||
}
|
||||
|
||||
return true;
|
@ -55,7 +55,7 @@ class Carpet extends Flowable{
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() !== self::AIR){
|
||||
$this->level->setBlock($block, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -65,10 +65,9 @@ class Carpet extends Flowable{
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->getID() === self::AIR){ //Replace with common break method
|
||||
//TODO
|
||||
//Server::getInstance()->api->entity->drop($this, Item::get($this->id, $this->meta, 1));
|
||||
$this->level->setBlock($this, new Air(), true, false, true);
|
||||
if($this->getSide(0)->getID() === self::AIR){ //TODO: Replace with common break method
|
||||
$this->getLevel()->dropItem($this, Item::get($this->id, $this->meta, 1));
|
||||
$this->getLevel()->setBlock($this, new Air(), true, false, true);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
@ -35,7 +35,7 @@ class Carrot extends Flowable{
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === self::FARMLAND){
|
||||
$this->level->setBlock($block, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -44,9 +44,9 @@ class Carrot extends Flowable{
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
if($item->getID() === Item::DYE and $item->getMetadata() === 0x0F){ //Bonemeal
|
||||
if($item->getID() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal
|
||||
$this->meta = 0x07;
|
||||
$this->level->setBlock($this, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($this, $this, true, false, true);
|
||||
$item->count--;
|
||||
|
||||
return true;
|
||||
@ -60,7 +60,7 @@ class Carrot extends Flowable{
|
||||
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
|
||||
//TODO
|
||||
//Server::getInstance()->api->entity->drop($this, Item::get(CARROT, 0, 1));
|
||||
$this->level->setBlock($this, new Air(), false, false, true);
|
||||
$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
@ -68,7 +68,7 @@ class Carrot extends Flowable{
|
||||
if(mt_rand(0, 2) == 1){
|
||||
if($this->meta < 0x07){
|
||||
++$this->meta;
|
||||
$this->level->setBlock($this, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($this, $this, true, false, true);
|
||||
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
@ -81,7 +81,7 @@ class Carrot extends Flowable{
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
$drops = array();
|
||||
$drops = [];
|
||||
if($this->meta >= 0x07){
|
||||
$drops[] = array(Item::CARROT, 0, mt_rand(1, 4));
|
||||
}else{
|
@ -59,24 +59,25 @@ class Chest extends Transparent{
|
||||
continue;
|
||||
}
|
||||
$c = $this->getSide($side);
|
||||
if(($c instanceof TileChest) and $c->getMetadata() === $this->meta){
|
||||
if((($tile = $this->level->getTile($c)) instanceof TileChest) and !$tile->isPaired()){
|
||||
if($c instanceof Chest and $c->getDamage() === $this->meta){
|
||||
$tile = $this->getLevel()->getTile($c);
|
||||
if($tile instanceof TileChest and !$tile->isPaired()){
|
||||
$chest = $tile;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->level->setBlock($block, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
||||
$nbt = new Compound(false, array(
|
||||
new Enum("Items", array()),
|
||||
new Enum("Items", []),
|
||||
new String("id", Tile::CHEST),
|
||||
new Int("x", $this->x),
|
||||
new Int("y", $this->y),
|
||||
new Int("z", $this->z)
|
||||
));
|
||||
$nbt->Items->setTagType(NBT::TAG_Compound);
|
||||
$tile = new TileChest($this->level, $nbt);
|
||||
$tile = new TileChest($this->getLevel()->getChunkAt($this->x >> 4, $this->z >> 4), $nbt);
|
||||
|
||||
if($chest instanceof TileChest){
|
||||
$chest->pairWith($tile);
|
||||
@ -87,11 +88,11 @@ class Chest extends Transparent{
|
||||
}
|
||||
|
||||
public function onBreak(Item $item){
|
||||
$t = $this->level->getTile($this);
|
||||
$t = $this->getLevel()->getTile($this);
|
||||
if($t instanceof TileChest){
|
||||
$t->unpair();
|
||||
}
|
||||
$this->level->setBlock($this, new Air(), true, true, true);
|
||||
$this->getLevel()->setBlock($this, new Air(), true, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -103,28 +104,27 @@ class Chest extends Transparent{
|
||||
return true;
|
||||
}
|
||||
|
||||
$t = $this->level->getTile($this);
|
||||
$chest = false;
|
||||
$t = $this->getLevel()->getTile($this);
|
||||
$chest = null;
|
||||
if($t instanceof TileChest){
|
||||
$chest = $t;
|
||||
}else{
|
||||
$nbt = new Compound(false, array(
|
||||
new Enum("Items", array()),
|
||||
new Enum("Items", []),
|
||||
new String("id", Tile::CHEST),
|
||||
new Int("x", $this->x),
|
||||
new Int("y", $this->y),
|
||||
new Int("z", $this->z)
|
||||
));
|
||||
$nbt->Items->setTagType(NBT::TAG_Compound);
|
||||
$chest = new TileChest($this->level, $nbt);
|
||||
$chest = new TileChest($this->getLevel()->getChunkAt($this->x >> 4, $this->z >> 4), $nbt);
|
||||
}
|
||||
|
||||
|
||||
if(($player->gamemode & 0x01) === 0x01){
|
||||
return true;
|
||||
}
|
||||
|
||||
$chest->openInventory($player);
|
||||
$player->addWindow($chest->getInventory());
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -134,12 +134,12 @@ class Chest extends Transparent{
|
||||
$drops = array(
|
||||
array($this->id, 0, 1),
|
||||
);
|
||||
$t = $this->level->getTile($this);
|
||||
if($t instanceof Chest){
|
||||
for($s = 0; $s < Chest::SLOTS; ++$s){
|
||||
$slot = $t->getSlot($s);
|
||||
$t = $this->getLevel()->getTile($this);
|
||||
if($t instanceof TileChest){
|
||||
for($s = 0; $s < $t->getRealInventory()->getSize(); ++$s){
|
||||
$slot = $t->getRealInventory()->getItem($s);
|
||||
if($slot->getID() > Item::AIR and $slot->getCount() > 0){
|
||||
$drops[] = array($slot->getID(), $slot->getMetadata(), $slot->getCount());
|
||||
$drops[] = array($slot->getID(), $slot->getDamage(), $slot->getCount());
|
||||
}
|
||||
}
|
||||
}
|
@ -52,7 +52,7 @@ class Coal extends Solid{
|
||||
array(Item::COAL_BLOCK, 0, 1),
|
||||
);
|
||||
}else{
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
@ -52,7 +52,7 @@ class CoalOre extends Solid{
|
||||
array(Item::COAL, 0, 1),
|
||||
);
|
||||
}else{
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ class Cobblestone extends Solid{
|
||||
array(Item::COBBLESTONE, 0, 1),
|
||||
);
|
||||
}else{
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
@ -32,6 +32,6 @@ class Cobweb extends Flowable{
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
}
|
@ -27,14 +27,14 @@ use pocketmine\Player;
|
||||
|
||||
class CyanFlower extends Flowable{
|
||||
public function __construct(){
|
||||
parent::__construct(self::CYAN_FLOWER, 0, "Cyan Flower");
|
||||
parent::__construct(self::POPPY, 0, "Cyan Flower");
|
||||
$this->hardness = 0;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === 2 or $down->getID() === 3 or $down->getID() === 60){
|
||||
$this->level->setBlock($block, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -44,10 +44,9 @@ class CyanFlower extends Flowable{
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
|
||||
//TODO
|
||||
//Server::getInstance()->api->entity->drop($this, Item::get($this->id));
|
||||
$this->level->setBlock($this, new Air(), false, false, true);
|
||||
if($this->getSide(0)->isTransparent === true){ //TODO: Replace with common break method
|
||||
$this->getLevel()->dropItem($this, Item::get($this->id, 0, 1));
|
||||
$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
@ -34,7 +34,7 @@ class Dandelion extends Flowable{
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === 2 or $down->getID() === 3 or $down->getID() === 60){
|
||||
$this->level->setBlock($block, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -47,7 +47,7 @@ class Dandelion extends Flowable{
|
||||
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
|
||||
//TODO
|
||||
//Server::getInstance()->api->entity->drop($this, Item::get($this->id));
|
||||
$this->level->setBlock($this, new Air(), false, false, true);
|
||||
$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
@ -19,22 +19,18 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class ReadyPacket extends DataPacket{
|
||||
public $status;
|
||||
|
||||
public function pid(){
|
||||
return Info::READY_PACKET;
|
||||
class DarkOakWoodStairs extends Stair{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::DARK_OAK_WOOD_STAIRS, $meta, "Dark Oak Wood Stairs");
|
||||
}
|
||||
|
||||
public function decode(){
|
||||
$this->status = $this->getByte();
|
||||
public function getDrops(Item $item){
|
||||
return array(
|
||||
array($this->id, 0, 1),
|
||||
);
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -33,7 +33,7 @@ class DeadBush extends Flowable{
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
|
||||
$this->level->setBlock($this, new Air(), false, false, true);
|
||||
$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
@ -46,7 +46,7 @@ class Diamond extends Solid{
|
||||
array(Item::DIAMOND_BLOCK, 0, 1),
|
||||
);
|
||||
}else{
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
@ -46,7 +46,7 @@ class DiamondOre extends Solid{
|
||||
array(Item::DIAMOND, 0, 1),
|
||||
);
|
||||
}else{
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
@ -34,7 +34,7 @@ class Dirt extends Solid{
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
if($item->isHoe()){
|
||||
$item->useOn($this);
|
||||
$this->level->setBlock($this, Block::get(Item::FARMLAND, 0), true, false, true);
|
||||
$this->getLevel()->setBlock($this, Block::get(Item::FARMLAND, 0), true, false, true);
|
||||
|
||||
return true;
|
||||
}
|
@ -25,6 +25,7 @@ use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\network\protocol\LevelEventPacket;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
|
||||
|
||||
abstract class Door extends Transparent{
|
||||
@ -36,9 +37,9 @@ abstract class Door extends Transparent{
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->getID() === self::AIR){ //Replace with common break method
|
||||
$this->level->setBlock($this, new Air(), false);
|
||||
$this->getLevel()->setBlock($this, new Air(), false);
|
||||
if($this->getSide(1) instanceof Door){
|
||||
$this->level->setBlock($this->getSide(1), new Air(), false);
|
||||
$this->getLevel()->setBlock($this->getSide(1), new Air(), false);
|
||||
}
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
@ -68,10 +69,10 @@ abstract class Door extends Transparent{
|
||||
if($next->getID() === $this->id or ($next2->isTransparent === false and $next->isTransparent === true)){ //Door hinge
|
||||
$metaUp |= 0x01;
|
||||
}
|
||||
$this->level->setBlock($blockUp, Block::get($this->id, $metaUp), true, false, true); //Top
|
||||
$this->getLevel()->setBlock($blockUp, Block::get($this->id, $metaUp), true, false, true); //Top
|
||||
|
||||
$this->meta = $player->getDirection() & 0x03;
|
||||
$this->level->setBlock($block, $this, true, false, true); //Bottom
|
||||
$this->getLevel()->setBlock($block, $this, true, false, true); //Bottom
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -82,15 +83,15 @@ abstract class Door extends Transparent{
|
||||
if(($this->meta & 0x08) === 0x08){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === $this->id){
|
||||
$this->level->setBlock($down, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($down, new Air(), true, false, true);
|
||||
}
|
||||
}else{
|
||||
$up = $this->getSide(1);
|
||||
if($up->getID() === $this->id){
|
||||
$this->level->setBlock($up, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($up, new Air(), true, false, true);
|
||||
}
|
||||
}
|
||||
$this->level->setBlock($this, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($this, new Air(), true, false, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -99,11 +100,11 @@ abstract class Door extends Transparent{
|
||||
if(($this->meta & 0x08) === 0x08){ //Top
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === $this->id){
|
||||
$meta = $down->getMetadata() ^ 0x04;
|
||||
$this->level->setBlock($down, Block::get($this->id, $meta), true, false, true);
|
||||
$players = $this->level->getUsingChunk($this->x >> 4, $this->z >> 4);
|
||||
$meta = $down->getDamage() ^ 0x04;
|
||||
$this->getLevel()->setBlock($down, Block::get($this->id, $meta), true, false, true);
|
||||
$players = $this->getLevel()->getUsingChunk($this->x >> 4, $this->z >> 4);
|
||||
if($player instanceof Player){
|
||||
unset($players[$player->CID]);
|
||||
unset($players[$player->getID()]);
|
||||
}
|
||||
$pk = new LevelEventPacket;
|
||||
$pk->x = $this->x;
|
||||
@ -111,7 +112,7 @@ abstract class Door extends Transparent{
|
||||
$pk->z = $this->z;
|
||||
$pk->evid = 1003;
|
||||
$pk->data = 0;
|
||||
Player::broadcastPacket($players, $pk);
|
||||
Server::broadcastPacket($players, $pk);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -119,10 +120,10 @@ abstract class Door extends Transparent{
|
||||
return false;
|
||||
}else{
|
||||
$this->meta ^= 0x04;
|
||||
$this->level->setBlock($this, $this, true, false, true);
|
||||
$players = $this->level->getUsingChunk($this->x >> 4, $this->z >> 4);
|
||||
$this->getLevel()->setBlock($this, $this, true, false, true);
|
||||
$players = $this->getLevel()->getUsingChunk($this->x >> 4, $this->z >> 4);
|
||||
if($player instanceof Player){
|
||||
unset($players[$player->CID]);
|
||||
unset($players[$player->getID()]);
|
||||
}
|
||||
$pk = new LevelEventPacket;
|
||||
$pk->x = $this->x;
|
||||
@ -130,7 +131,7 @@ abstract class Door extends Transparent{
|
||||
$pk->z = $this->z;
|
||||
$pk->evid = 1003;
|
||||
$pk->data = 0;
|
||||
Player::broadcastPacket($players, $pk);
|
||||
Server::broadcastPacket($players, $pk);
|
||||
}
|
||||
|
||||
return true;
|
@ -62,7 +62,7 @@ class DoubleSlab extends Solid{
|
||||
array(Item::SLAB, $this->meta & 0x07, 2),
|
||||
);
|
||||
}else{
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,8 @@ class DoubleWoodSlab extends Solid{
|
||||
1 => "Spruce",
|
||||
2 => "Birch",
|
||||
3 => "Jungle",
|
||||
4 => "Acacia",
|
||||
5 => "Dark Oak",
|
||||
);
|
||||
$this->name = "Double " . $names[$this->meta & 0x07] . " Wooden Slab";
|
||||
$this->hardness = 15;
|
@ -23,38 +23,30 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class Stone extends Solid{
|
||||
class Emerald extends Solid{
|
||||
public function __construct(){
|
||||
parent::__construct(self::STONE, 0, "Stone");
|
||||
parent::__construct(self::EMERALD_BLOCK, 0, "Emerald Block");
|
||||
$this->hardness = 30;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
|
||||
switch($item->isPickaxe()){
|
||||
case 5:
|
||||
return 0.4;
|
||||
return 0.95;
|
||||
case 4:
|
||||
return 0.5;
|
||||
case 3:
|
||||
return 0.75;
|
||||
case 2:
|
||||
return 0.25;
|
||||
case 1:
|
||||
return 1.5;
|
||||
return 1.25;
|
||||
default:
|
||||
return 7.5;
|
||||
return 25;
|
||||
}
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
if($item->isPickaxe() >= 1){
|
||||
if($item->isPickaxe() >= 4){
|
||||
return array(
|
||||
array(Item::COBBLESTONE, 0, 1),
|
||||
array(Item::EMERALD_BLOCK, 0, 1),
|
||||
);
|
||||
}else{
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
52
src/pocketmine/block/EmeraldOre.php
Normal file
52
src/pocketmine/block/EmeraldOre.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class EmeraldOre extends Solid{
|
||||
public function __construct(){
|
||||
parent::__construct(self::EMERALD_ORE, 0, "Emerald Ore");
|
||||
$this->hardness = 15;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
switch($item->isPickaxe()){
|
||||
case 5:
|
||||
return 0.6;
|
||||
case 4:
|
||||
return 0.75;
|
||||
default:
|
||||
return 15;
|
||||
}
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
if($item->isPickaxe() >= 4){
|
||||
return array(
|
||||
array(Item::EMERALD, 0, 1),
|
||||
);
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
@ -22,9 +22,7 @@
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
|
||||
class Fallable extends Solid{
|
||||
|
||||
@ -34,8 +32,7 @@ class Fallable extends Solid{
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$ret = $this->level->setBlock($this, $this, true, false, true);
|
||||
Server::getInstance()->api->block->blockUpdate(clone $this, Level::BLOCK_UPDATE_NORMAL);
|
||||
$ret = $this->getLevel()->setBlock($this, $this, true, false, true);
|
||||
|
||||
return $ret;
|
||||
}
|
@ -44,7 +44,7 @@ class FenceGate extends Transparent{
|
||||
3 => 2,
|
||||
);
|
||||
$this->meta = $faces[$player instanceof Player ? $player->getDirection() : 0] & 0x03;
|
||||
$this->level->setBlock($block, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -68,7 +68,7 @@ class FenceGate extends Transparent{
|
||||
}else{
|
||||
$this->isFullBlock = false;
|
||||
}
|
||||
$this->level->setBlock($this, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($this, $this, true, false, true);
|
||||
|
||||
return true;
|
||||
}
|
@ -34,7 +34,7 @@ class Fire extends Flowable{
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
@ -45,12 +45,12 @@ class Fire extends Flowable{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$this->level->setBlock($this, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($this, new Air(), true, false, true);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
if($this->getSide(0)->getID() !== self::NETHERRACK){
|
||||
$this->level->setBlock($this, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($this, new Air(), true, false, true);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
@ -38,7 +38,7 @@ class Generic extends Block{
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
return $this->level->setBlock($this, $this, true, false, true);
|
||||
return $this->getLevel()->setBlock($this, $this, true, false, true);
|
||||
}
|
||||
|
||||
public function isBreakable(Item $item){
|
||||
@ -46,7 +46,7 @@ class Generic extends Block{
|
||||
}
|
||||
|
||||
public function onBreak(Item $item){
|
||||
return $this->level->setBlock($this, new Air(), true, false, true);
|
||||
return $this->getLevel()->setBlock($this, new Air(), true, false, true);
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
@ -60,11 +60,11 @@ class Generic extends Block{
|
||||
"Tile" => $this->id,
|
||||
);
|
||||
$server = Server::getInstance();
|
||||
$this->level->setBlock($this, new Air(), false, false, true);
|
||||
/*$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
||||
//TODO
|
||||
//$e = $server->api->entity->add($this->level, ENTITY_FALLING, FALLING_SAND, $data);
|
||||
//$e = $server->api->entity->add($this->getLevel(), ENTITY_FALLING, FALLING_SAND, $data);
|
||||
//$e->spawnToAll();
|
||||
$server->api->block->blockUpdateAround(clone $this, Level::BLOCK_UPDATE_NORMAL, 1);
|
||||
$server->api->block->blockUpdateAround(clone $this, Level::BLOCK_UPDATE_NORMAL, 1);*/
|
||||
}
|
||||
|
||||
return false;
|
@ -30,6 +30,6 @@ class Glass extends Transparent{
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
}
|
@ -32,7 +32,7 @@ class GlowingRedstoneOre extends Solid{
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_SCHEDULED or $type === Level::BLOCK_UPDATE_RANDOM){
|
||||
$this->level->setBlock($this, Block::get(Item::REDSTONE_ORE, $this->meta), false, false, true);
|
||||
$this->getLevel()->setBlock($this, Block::get(Item::REDSTONE_ORE, $this->meta), false, false, true);
|
||||
|
||||
return Level::BLOCK_UPDATE_WEAK;
|
||||
}
|
||||
@ -58,7 +58,7 @@ class GlowingRedstoneOre extends Solid{
|
||||
array(Item::REDSTONE_DUST, 0, mt_rand(4, 5)),
|
||||
);
|
||||
}else{
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ class Gold extends Solid{
|
||||
array(Item::GOLD_BLOCK, 0, 1),
|
||||
);
|
||||
}else{
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
@ -46,7 +46,7 @@ class GoldOre extends Solid{
|
||||
array(Item::GOLD_ORE, 0, 1),
|
||||
);
|
||||
}else{
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
@ -23,6 +23,8 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\generator\object\TallGrass;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\utils\Random;
|
||||
|
||||
@ -34,20 +36,36 @@ class Grass extends Solid{
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return array(
|
||||
array(Item::DIRT, 0, 1),
|
||||
);
|
||||
return [
|
||||
[Item::DIRT, 0, 1],
|
||||
];
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
//TODO: light levels
|
||||
$x = mt_rand($this->x - 1, $this->x + 1);
|
||||
$y = mt_rand($this->y - 2, $this->y + 2);
|
||||
$z = mt_rand($this->z - 1, $this->z + 1);
|
||||
$block = $this->getLevel()->getBlockIdAt($x, $y, $z);
|
||||
if($block === Block::DIRT){
|
||||
$block = $this->getLevel()->getBlock(new Vector3($x, $y, $z));
|
||||
if($block->getSide(1) instanceof Transparent){
|
||||
$this->getLevel()->setBlock($block, new Grass());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
if($item->getID() === Item::DYE and $item->getMetadata() === 0x0F){
|
||||
if($item->getID() === Item::DYE and $item->getDamage() === 0x0F){
|
||||
$item->count--;
|
||||
TallGrass::growGrass($this->level, $this, new Random(), 8, 2);
|
||||
TallGrass::growGrass($this->getLevel(), $this, new Random(mt_rand()), 8, 2);
|
||||
|
||||
return true;
|
||||
}elseif($item->isHoe()){
|
||||
$item->useOn($this);
|
||||
$this->level->setBlock($this, new Farmland());
|
||||
$this->getLevel()->setBlock($this, new Farmland());
|
||||
|
||||
return true;
|
||||
}
|
49
src/pocketmine/block/HardenedClay.php
Normal file
49
src/pocketmine/block/HardenedClay.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class HardenedClay extends Solid{
|
||||
public function __construct(){
|
||||
parent::__construct(self::HARDENED_CLAY, 0, "Hardened Clay");
|
||||
$this->hardness = 30;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
switch($item->isPickaxe()){
|
||||
case 5:
|
||||
return 0.25;
|
||||
case 4:
|
||||
return 0.35;
|
||||
case 3:
|
||||
return 0.5;
|
||||
case 2:
|
||||
return 0.2;
|
||||
case 1:
|
||||
return 0.95;
|
||||
default:
|
||||
return 6.25;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -41,7 +41,7 @@ class HayBale extends Solid{
|
||||
);
|
||||
|
||||
$this->meta = ($this->meta & 0x03) | $faces[$face];
|
||||
$this->level->setBlock($block, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
||||
|
||||
return true;
|
||||
}
|
@ -30,7 +30,7 @@ class Ice extends Transparent{
|
||||
}
|
||||
|
||||
public function onBreak(Item $item){
|
||||
$this->level->setBlock($this, new Water(), true, false, true);
|
||||
$this->getLevel()->setBlock($this, new Water(), true, false, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -53,6 +53,6 @@ class Ice extends Transparent{
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user