mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-16 14:25:05 +00:00
Compare commits
654 Commits
before-fix
...
Alpha_1.4d
Author | SHA1 | Date | |
---|---|---|---|
b17ce16262 | |||
fee7f5060b | |||
76cd164aa4 | |||
582f1540a7 | |||
4d7c953572 | |||
06c01f14c6 | |||
c43431c921 | |||
4e1805ae02 | |||
ac34b9eda0 | |||
3495c79c0c | |||
77799d8f3d | |||
dfdf9ddb45 | |||
86d423ae4d | |||
eff454d103 | |||
51120fdd4f | |||
5242e87026 | |||
269a10fadd | |||
232bf5ebe4 | |||
2904aa06ef | |||
e10c70e776 | |||
2cead226db | |||
2784925a5e | |||
d2a14e8303 | |||
071033ad5c | |||
1e3ed8640c | |||
60a576e541 | |||
eee7e659e9 | |||
7ddfd4394d | |||
f0f2eb9a01 | |||
839f6621eb | |||
7fcaa78de4 | |||
915443b508 | |||
e17a7005a1 | |||
c1846e3bcf | |||
81feff6d0d | |||
9b84d8c248 | |||
26ec562fbf | |||
d10274ca7c | |||
7c68e42a86 | |||
171de939cd | |||
58bded4988 | |||
cb4a970631 | |||
95b5979351 | |||
18d13fdc32 | |||
1a442b793c | |||
765d4f30c7 | |||
2eced89e6f | |||
293102d8c4 | |||
25f5d409f1 | |||
4128b22e85 | |||
487ce00542 | |||
a9cd03da2e | |||
f5fee4c909 | |||
016b08ecf2 | |||
3515a037c5 | |||
d6e413e8ca | |||
f991efd5bc | |||
913c116e7b | |||
8fafb85784 | |||
b0aad89e7a | |||
ce018fd7c8 | |||
afe44e6c6f | |||
e9311f5ceb | |||
b2978133f7 | |||
6b331535c6 | |||
3370052fac | |||
7d8a961374 | |||
e97139919a | |||
81faddafb0 | |||
d0936329aa | |||
9124513584 | |||
e860c339e2 | |||
10c67a57a7 | |||
b10e63b951 | |||
409eeda6ee | |||
bf09c48d62 | |||
aac646d343 | |||
ed90d58e32 | |||
e219f4784c | |||
b5a1c23c50 | |||
14817df2c7 | |||
cc87064915 | |||
aded24e6c6 | |||
a95f8b45f1 | |||
7a3703d8b1 | |||
ca59546ace | |||
2330f363bd | |||
042861b51f | |||
98f42a936e | |||
6d77b0883e | |||
f53d513894 | |||
e6e15ceffa | |||
9d75baf212 | |||
7b45df680e | |||
f93d5339bc | |||
677071e7cb | |||
4fa6fb0546 | |||
0ca614a2c3 | |||
bdfa6c0bc5 | |||
ccb7e86cf1 | |||
03a970e91f | |||
b3e9bb8fec | |||
48b99486b0 | |||
6921e6f2aa | |||
987f54ba08 | |||
09ef1f1721 | |||
3eae7a1875 | |||
21587ae3eb | |||
e5337d8949 | |||
c92a1ba7fe | |||
2066e92f84 | |||
cd943f52a1 | |||
c3424beda9 | |||
b6506d1db8 | |||
4cec3e7e37 | |||
2f3a011ed3 | |||
da9dfabae4 | |||
4c83e9bb56 | |||
090d159766 | |||
14d86339fc | |||
ccf34a9db8 | |||
97af1b6008 | |||
16d33b01f4 | |||
fa318ce706 | |||
accea03d52 | |||
adcdf650a3 | |||
e8e825322b | |||
1b36b10520 | |||
0d37e96678 | |||
2448405e3a | |||
2e773a32ff | |||
d8cba4f045 | |||
07c1ed1c36 | |||
d6711125a9 | |||
b8802edd6d | |||
71bf984e9e | |||
9c9d786194 | |||
bd2cb4b851 | |||
6e77901453 | |||
ebe8a902e5 | |||
304524f6d8 | |||
cb879977d2 | |||
096e238242 | |||
f2d5daffc0 | |||
12275125d2 | |||
3d3b6826e4 | |||
3a8adfe2b8 | |||
14116b6730 | |||
241d3d72af | |||
79e864f4f1 | |||
7812a3c4fc | |||
dbe5e9b4e9 | |||
d743888b8d | |||
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 |
11
.gitignore
vendored
11
.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,8 @@ Desktop.ini
|
||||
|
||||
# Mac crap
|
||||
.DS_Store
|
||||
/nbproject/private/
|
||||
|
||||
# Sphinx-doc
|
||||
/docs/build/
|
||||
!/docs/requirements.txt
|
||||
|
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
|
||||
|
@ -2,33 +2,31 @@
|
||||
|
||||
# PocketMine-MP Contribution Guidelines
|
||||
|
||||
Before contributing to PocketMine-MP, please read this. Also, take a look if your contribution fits the PocketMine-MP goals below.
|
||||
You must follow these guidelines if you wish to contribute to the PocketMine-MP code base, or participate in issue tracking.
|
||||
|
||||
|
||||
## 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.
|
||||
* You may use our [Forum](http://forums.pocketmine.net) to ask questions.
|
||||
* We do not accept questions or support requests in our issue trcker.
|
||||
|
||||
## I want to create an issue
|
||||
* First, use the [Issue Search](https://github.com/PocketMine/PocketMine-MP/search?ref=cmdform&type=Issues) to check if anyone has reported it.
|
||||
* Is your issue related to a Plugin? If so, please contact their original author instead of reporting it here.
|
||||
* And no, we won't update a Plugin because you need it.
|
||||
* 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.
|
||||
## Creating an Issue
|
||||
- First, use the [Issue Search](https://github.com/PocketMine/PocketMine-MP/search?ref=cmdform&type=Issues) to check if anyone has reported it.
|
||||
- If your issue is related to a plugin, you must contact their original author instead of reporting it here.
|
||||
- If your issue is related to a PocketMine official plugin, or our Android application, you must create an issue on that specific repository.
|
||||
- **Support requests are not bugs.** Issues such as "How do I do this" are not bugs and are closed as soon as a collaborator spots it. They are referred to our Forum to seek assistance.
|
||||
- **No generic titles** such as "Question", "Help", "Crash Report" etc. If an issue has a generic title they will either be closed on the spot, or a collaborator will edit it to describe the actual symptom.
|
||||
- Similarly, no generic issue reports. It is the issue submitter's responsibility to provide us an issue that is **trackable, debuggable, reproducible, reported professionally and is an actual bug**. If you do not provide us with a summary or instructions on how to reproduce the issue, it is a support request until the actual bug has been found and therefore the issue is closed.
|
||||
|
||||
## I want to contribute code
|
||||
## Contributing 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.
|
||||
* Code using the syntax as in PocketMine-MP. See below for an example.
|
||||
* The code must be clear and written in English, comments included.
|
||||
|
||||
**Thanks for contributing to PocketMine-MP!**
|
||||
|
||||
__Thanks for contributing to PocketMine-MP!__
|
||||
|
||||
|
||||
|
||||
### Code syntax
|
||||
### Code Syntax
|
||||
|
||||
It is mainly [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md) with a few exceptions.
|
||||
* Opening braces MUST go on the same line.
|
||||
@ -40,13 +38,12 @@ 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
|
||||
<?php
|
||||
|
||||
namespace pocketmine\Example;
|
||||
namespace pocketmine\example;
|
||||
|
||||
class ExampleClass{
|
||||
const EXAMPLE_CLASS_CONSTANT = 1;
|
||||
@ -58,17 +55,69 @@ class ExampleClass{
|
||||
//do things
|
||||
}elseif($firstArgument === "otherValue"){
|
||||
$secondArgument = function(){
|
||||
return array(
|
||||
return [
|
||||
0 => "value1",
|
||||
1 => "value2",
|
||||
2 => "value3",
|
||||
3 => "value4",
|
||||
4 => "value5",
|
||||
5 => "value6",
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
## Bug Tracking for Collaborators
|
||||
|
||||
### Labels
|
||||
To provide a concise bug tracking environment, prevent the issue tracker from over flowing and to keep support requests out of the bug tracker, PocketMine-MP uses a label scheme a bit different from the default GitHub Issues labels.
|
||||
|
||||
PocketMine-MP uses GitHub Issues Labels. There are a total of 12 labels.
|
||||
|
||||
Note: For future reference, labels must not be longer than 15 letters.
|
||||
|
||||
#### Categories
|
||||
Category labels are prefixed by `C:`. Multiple category labels may be applied to a single issue(but try to keep this to a minimum and do not overuse category labels).
|
||||
- C: Core - This label is applied when the bug results in a fatal crash, or is related to neither Gameplay nor Plugin API.
|
||||
- C: Gameplay - This label is applied when the bug effects the gameplay.
|
||||
- C: API - This label is applied when the bug effects the Plugin API.
|
||||
|
||||
#### Pull Requests
|
||||
Pull Requests are prefixed by `PR:`. Only one label may be applied for a Pull Request.
|
||||
- PR: Bug Fix - This label is applied when the Pull Request fixes a bug.
|
||||
- PR: Contribution - This label is applied when the Pull Request contributes code to PocketMine-MP such as a new feature or an improvement.
|
||||
|
||||
#### Status
|
||||
Status labels show the status of the issue. Multiple status labels may be applied.
|
||||
- Reproduced - This label is applied when the bug has been reproduced, or multiple people are reporting the same issue and symptoms in which case it is automatically assumed that the bug has been reproduced in different environments.
|
||||
- Debugged - This label is applied when the cause of the bug has been found.
|
||||
- Priority - This label is applied when the bug is easy to fix, or if the scale of the bug is global.
|
||||
- Won't Fix - This label is applied if the bug has been decided not be fixed for some reason. e.g. when the bug benefits gameplay. *This label may only be applied to a closed issue.*
|
||||
|
||||
#### Miscellaneous
|
||||
Miscellaneous labels are labels that show status not related to debugging that bug. The To-Do label and the Mojang label may not be applied to a single issue at the same time.
|
||||
- To-Do - This label is applied when the issue is not a bug, but a feature request or a list of features to be implemented that count towards a milestone.
|
||||
- Mojang - This label is applied when the issue is suspected of being caused by the Minecraft: Pocket Edition client, but has not been confirmed.
|
||||
- Invalid - This label is applied when the issue is reporting a false bug that works as intended, a support request, etc. *This label may only be applied to a closed issue.*
|
||||
|
||||
### Closing Issues
|
||||
To keep the bug tracker clear of non-related issues and to prevent it from overflowing, **issues must be closed as soon as possible** (This may sound unethical, but it is MUCH better than having the BUG TRACKER filled with SUPPORT REQUESTS and "I NEED HELP").
|
||||
|
||||
If an issue does not conform to the "Creating an Issue" guidelines above, the issue should be closed.
|
||||
|
||||
### Milestones
|
||||
PocketMine-MP uses GitHub Milestones to set a goal for a new release. A milestone is set on the following occasions.
|
||||
|
||||
- A new Beta release
|
||||
- A new Stable release
|
||||
|
||||
A milestone must use the following format:
|
||||
```
|
||||
Alpha <version_number> <release_title> <release_version>
|
||||
```
|
||||
For example:
|
||||
```
|
||||
Alpha 1.4 Beta 2
|
||||
```
|
||||
|
22
README.md
22
README.md
@ -15,27 +15,32 @@
|
||||
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/)
|
||||
### [Documentation](http://pocketmine-mp.readthedocs.org/)
|
||||
|
||||
### [FAQ: Frequently Asked Questions](https://github.com/PocketMine/PocketMine-MP/wiki/Frequently-Asked-Questions)
|
||||
### [Plugin Repository](http://plugins.pocketmine.net/)
|
||||
|
||||
<!--## [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 +49,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);
|
||||
}
|
||||
}
|
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
|
@ -1,6 +0,0 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,6 +0,0 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,45 +0,0 @@
|
||||
language_has_been_selected=English has been correctly selected.
|
||||
skip_installer=Do you want to skip the set-up wizard?
|
||||
|
||||
welcome_to_pocketmine=Welcome to PocketMine-MP!\nBefore starting setting up your new server you have to accept the license.\nPocketMine-MP is licensed under the LGPL License,\nthat you can read opening the LICENSE file on this folder.
|
||||
accept_license=Do you accept the License?
|
||||
you_have_to_accept_the_license=You have to accept the LGPL license to continue using PocketMine-MP
|
||||
|
||||
setting_up_server_now=You are going to set up your server now.
|
||||
default_values_info=If you don't want to change the default value, just press Enter.
|
||||
server_properties=You can edit them later on the server.properties file.
|
||||
|
||||
name_your_server=Give a name to your server
|
||||
port_warning=Do not change the default port value if this is your first server.
|
||||
server_port=Server port
|
||||
invalid_port=Invalid server port
|
||||
ram_warning=The RAM is the maximum amount of memory PocketMine-MP will use. A value of 128-256 MB is recommended
|
||||
server_ram=Server RAM in MB
|
||||
gamemode_info=Choose between Creative (1) or Survival (0)
|
||||
default_gamemode=Default Game mode
|
||||
max_players=Max. online players
|
||||
spawn_protection_info=The spawn protection disallows placing/breaking blocks in the spawn zone except for OPs
|
||||
spawn_protection=Enable spawn protection?
|
||||
|
||||
op_info=An OP is the player admin of the server. OPs can run more commands than normal players
|
||||
op_who=OP player name (example, your game name)
|
||||
op_warning=You will be able to add an OP user later using /op <player>
|
||||
whitelist_info=The white-list only allows players in it to join.
|
||||
whitelist_enable=Do you want to enable the white-list?
|
||||
whitelist_warning=You will have to add the players to the white-list
|
||||
|
||||
query_warning1=Query is a protocol used by diferent tools to get information of your server and players logged in.
|
||||
query_warning2=If you disable it, you won't be able to use server lists.
|
||||
query_disable=Do you want to disable Query?
|
||||
rcon_info=RCON is a protocol to remote connect with the server console using a password.
|
||||
rcon_enable=Do you want to enable RCON?
|
||||
rcon_password=RCON password (you can change it later)
|
||||
usage_info=The anonymous usage data allows us to calculate global statistics for PocketMine-MP and its plugins. You can view them on stats.pocketmine.net
|
||||
usage_disable=Do you want to disable the anonymous usage?
|
||||
ip_get=Getting your external IP and internal IP
|
||||
ip_warning=Your external IP is {{EXTERNAL_IP}}. You may have to port-forward to your internal IP {{INTERNAL_IP}}
|
||||
ip_confirm=Be sure to check it, if you have to forward and you skip that, no external players will be able to join. [Press Enter]
|
||||
|
||||
you_have_finished=You have finished the set-up wizard correctly
|
||||
pocketmine_will_start=PocketMine-MP will now start. Type /help to view the list of available commands.
|
||||
pocketmine_plugins=Check the Plugin Repository to add new features, minigames, or advanced protection to your server
|
@ -1,45 +0,0 @@
|
||||
language_has_been_selected=English has been correctly selected.
|
||||
skip_installer=Do you want to skip the set-up wizard?
|
||||
|
||||
welcome_to_pocketmine=Welcome to PocketMine-MP!\nBefore starting setting up your new server you have to accept the license.\nPocketMine-MP is licensed under the LGPL License,\nthat you can read opening the LICENSE file on this folder.
|
||||
accept_license=Do you accept the License?
|
||||
you_have_to_accept_the_license=You have to accept the LGPL license to continue using PocketMine-MP
|
||||
|
||||
setting_up_server_now=You are going to set up your server now.
|
||||
default_values_info=If you don't want to change the default value, just press Enter.
|
||||
server_properties=You can edit them later on the server.properties file.
|
||||
|
||||
name_your_server=Give a name to your server
|
||||
port_warning=Do not change the default port value if this is your first server.
|
||||
server_port=Server port
|
||||
invalid_port=Invalid server port
|
||||
ram_warning=The RAM is the maximum amount of memory PocketMine-MP will use. A value of 128-256 MB is recommended
|
||||
server_ram=Server RAM in MB
|
||||
gamemode_info=Choose between Creative (1) or Survival (0)
|
||||
default_gamemode=Default Game mode
|
||||
max_players=Max. online players
|
||||
spawn_protection_info=The spawn protection disallows placing/breaking blocks in the spawn zone except for OPs
|
||||
spawn_protection=Enable spawn protection?
|
||||
|
||||
op_info=An OP is the player admin of the server. OPs can run more commands than normal players
|
||||
op_who=OP player name (example, your game name)
|
||||
op_warning=You will be able to add an OP user later using /op <player>
|
||||
whitelist_info=The white-list only allows players in it to join.
|
||||
whitelist_enable=Do you want to enable the white-list?
|
||||
whitelist_warning=You will have to add the players to the white-list
|
||||
|
||||
query_warning1=Query is a protocol used by diferent tools to get information of your server and players logged in.
|
||||
query_warning2=If you disable it, you won't be able to use server lists.
|
||||
query_disable=Do you want to disable Query?
|
||||
rcon_info=RCON is a protocol to remote connect with the server console using a password.
|
||||
rcon_enable=Do you want to enable RCON?
|
||||
rcon_password=RCON password (you can change it later)
|
||||
usage_info=The anonymous usage data allows us to calculate global statistics for PocketMine-MP and its plugins. You can view them on stats.pocketmine.net
|
||||
usage_disable=Do you want to disable the anonymous usage?
|
||||
ip_get=Getting your external IP and internal IP
|
||||
ip_warning=Your external IP is {{EXTERNAL_IP}}. You may have to port-forward to your internal IP {{INTERNAL_IP}}
|
||||
ip_confirm=Be sure to check it, if you have to forward and you skip that, no external players will be able to join. [Press Enter]
|
||||
|
||||
you_have_finished=You have finished the set-up wizard correctly
|
||||
pocketmine_will_start=PocketMine-MP will now start. Type /help to view the list of available commands.
|
||||
pocketmine_plugins=Check the Plugin Repository to add new features, minigames, or advanced protection to your server
|
@ -1,47 +0,0 @@
|
||||
language_has_been_selected=English has been correctly selected.
|
||||
skip_installer=Do you want to skip the set-up wizard?
|
||||
|
||||
welcome_to_pocketmine=Welcome to PocketMine-MP!\nBefore starting setting up your new server you have to accept the license.\nPocketMine-MP is licensed under the LGPL License,\nthat you can read opening the LICENSE file on this folder.
|
||||
accept_license=Do you accept the License?
|
||||
you_have_to_accept_the_license=You have to accept the LGPL license to continue using PocketMine-MP
|
||||
|
||||
setting_up_server_now=You are going to set up your server now.
|
||||
default_values_info=If you don't want to change the default value, just press Enter.
|
||||
server_properties=You can edit them later on the server.properties file.
|
||||
|
||||
name_your_server=Give your server a name
|
||||
port_warning=Do not change the default port value if this is your first server.
|
||||
server_port=Server port
|
||||
invalid_port=Invalid server port
|
||||
ram_warning=The RAM is the maximum amount of memory PocketMine-MP can use. A value of 128-256 MB is recommended
|
||||
server_ram=Server RAM in MB
|
||||
gamemode_info=Choose between Survival Mode (0), Creative Mode (1), or Adventure Mode (2)
|
||||
default_gamemode=Default gamemode
|
||||
max_players=Maximum online players at one time
|
||||
spawn_protection_info=The spawn protection prevents the placing/breaking of blocks in the spawn area for all players with the exception of operators
|
||||
spawn_protection=Enable spawn protection?
|
||||
|
||||
op_info=An 'op' is the admin of the server. Ops can run more commands than normal players (like /ban, etc.)
|
||||
op_who=Operator player name (e.g. Steve)
|
||||
op_warning=
|
||||
You will be able to add an operators later using /op <player>
|
||||
|
||||
whitelist_info=When enabled, only players in the whitelist will have access to the server.
|
||||
whitelist_enable=Do you want to enable the whitelist?
|
||||
whitelist_warning=You will have to add the players to the whitelist
|
||||
|
||||
query_warning1=Query is a protocol used by different tools to obtain information about the server and the players logged in.
|
||||
query_warning2=If you disable it, you won't be able to use server lists.
|
||||
query_disable=Do you want to disable Query?
|
||||
rcon_info=RCON is a protocol that allows remote connections with the server console using a password.
|
||||
rcon_enable=Do you want to enable RCON?
|
||||
rcon_password=RCON password (can be changed later)
|
||||
usage_info=The anonymous usage data allows us to calculate global statistics for PocketMine-MP and its plugins. You can view them on stats.pocketmine.net
|
||||
usage_disable=Do you want to disable the anonymous usage?
|
||||
ip_get=Finding your external and internal IP adresses
|
||||
ip_warning=Your current external IP is {{EXTERNAL_IP}}. In some cases, you may have to port-forward to your internal IP ({{INTERNAL_IP}})
|
||||
ip_confirm=Be sure to check it, if you have to forward and you skip that, no external players will be able to join. [Press Enter]
|
||||
|
||||
you_have_finished=You have finished the set-up wizard correctly
|
||||
pocketmine_will_start=PocketMine-MP will now start. Type /help to view the list of available commands.
|
||||
pocketmine_plugins=Check the Plugin Repository to add new features, minigames, or advanced protection to your server
|
@ -1,45 +0,0 @@
|
||||
language_has_been_selected=Español sido seleccionado correctamente.
|
||||
skip_installer=¿Quieres saltarte el asistente de configuración?
|
||||
|
||||
welcome_to_pocketmine=Bienvenido a PocketMine-MP!\nAntes de comenzar a configurar tu nuevo servidor, tienes que aceptar la licencia.\nPocketMine-MP está licenciado con la licencia LGPL,\nque puedes leer abriendo el archivo LICENSE en esta carpeta.
|
||||
accept_license=¿Aceptas la Licencia?
|
||||
you_have_to_accept_the_license=Tienes que aceptar la licencia LGPL antes de continuar usando PocketMine-MP
|
||||
|
||||
setting_up_server_now=La configuración del servidor va a comenzar.
|
||||
default_values_info=Si no quieres cambiar el valor por defecto, pulsa Enter.
|
||||
server_properties=Puedes editar todo despues en el fichero server.properties.
|
||||
|
||||
name_your_server=Nombre del servidor
|
||||
port_warning=No cambies el puerto por defecto si este es tu primer servidor.
|
||||
server_port=Puerto del servidor
|
||||
invalid_port=Puerto inválido
|
||||
ram_warning=La RAM es la máxima memoria que PocketMine-MP usará. Es recomendado usar un valor de 128-256 MB
|
||||
server_ram=RAM del servidor en MB
|
||||
gamemode_info=Elige entre Creativo (1) o Supervivencia (0)
|
||||
default_gamemode=Modo de juego por defecto
|
||||
max_players=Límite de jugadores
|
||||
spawn_protection_info=La protección del inicio bloquea poner/romper bloques en la zona de inicio, excepto los OPs
|
||||
spawn_protection=¿Activar protección de inicio?
|
||||
|
||||
op_info=Un OP es el jugador administrador del servidor. Los OPs pueden usar más comandos que los jugadores normales
|
||||
op_who=Jugador OP (por ejemplo, tu nombre de jugador)
|
||||
op_warning=Podrás añadir mas OPs después usando /op <jugador>
|
||||
whitelist_info=La lista blanca permite entrar únicamente a los jugadores en ella.
|
||||
whitelist_enable=¿Quieres activar la lista blanca?
|
||||
whitelist_warning=Tendrás que añadir los jugadores a la lista blanca
|
||||
|
||||
query_warning1=Query es un protocolo usado por diferentes herramientas para conseguir informacion de tu servidor y los jugadores conectados.
|
||||
query_warning2=Si lo desactivas, no podrás usar listas de servidores.
|
||||
query_disable=¿Quieres desactivar Query?
|
||||
rcon_info=RCON es un protocolo que permite conectarte a la consola del servidor usando una contraseña.
|
||||
rcon_enable=¿Queres activar RCON?
|
||||
rcon_password=Contraseña RCON (puedes cambiarla después)
|
||||
usage_info=Los datos de uso anónimos nos permiten calcular estadísticas globales para PocketMine-MP y sus plugins. Puedes verlas en stats.pocketmine.net
|
||||
usage_disable=¿Quieres desactivar las datos de uso anónimos?
|
||||
ip_get=Obteniendo tu IP externa e IP interna
|
||||
ip_warning=Tu IP externa es {{EXTERNAL_IP}}. Quizás debas redireccionar el puerto a tu IP interna {{INTERNAL_IP}}
|
||||
ip_confirm=Asegúrate de comprobarlo, ya que si debes hacerlo y lo saltas, ningún jugador externo podra entrar. [Pulsa Enter]
|
||||
|
||||
you_have_finished=Has completado el asistente de configuración correctamente
|
||||
pocketmine_will_start=PocketMine-MP se iniciará ahora. Escribe /help para ver la lista de los comandos disponibles.
|
||||
pocketmine_plugins=Ves al Repositorio de Plugins para añadir nuevas funcionalidades, minijuegos o protección avanzada a tu servidor
|
@ -1,45 +0,0 @@
|
||||
language_has_been_selected=Español seleccionado.
|
||||
skip_installer=Deseas omitir el asistente de configuración?
|
||||
|
||||
welcome_to_pocketmine=¡Bienvenido a PocketMine-MP!\nAntes de empezar a configurar tu nuevo servidor necesitas aceptar la licensia.\nLa licensia de PocketMine-MP esta bajo la licensia LGPL,\n que puedes leer abriendo el archivo "License" en esta carpeta.
|
||||
accept_license=Aceptas la licensia?
|
||||
you_have_to_accept_the_license=Debes aceptar la licensia de LPGL para continuar utilizando PocketMine-MP
|
||||
|
||||
setting_up_server_now=Empezemos con la configuración.
|
||||
default_values_info=Si no quieres cambiar los valores predeterminados pulsa Enter.
|
||||
server_properties=Puedes editarlos despues editando el archivo "server.properties".
|
||||
|
||||
name_your_server=Escribe el nombre de tu servidor
|
||||
port_warning=No cambies el puerto predeterminado si este es tu primer servidor.
|
||||
server_port=Puerto del servidor
|
||||
invalid_port=Puerto invalido
|
||||
ram_warning=La RAM es la máxima memoria que PocketMine-MP usará. Se recomienda utilizar un mínimo de 128 MB
|
||||
server_ram=RAM del servidor en MB
|
||||
gamemode_info=Escoge entre Creativo (1) o Survival (0)
|
||||
default_gamemode=Modo de juego predeterminado
|
||||
max_players=Límite de jugadores
|
||||
spawn_protection_info=La protección del inicio impide poner/romper bloques en la zona de aparición, a excepción de los OPs
|
||||
spawn_protection=Activar la protección del spawn?
|
||||
|
||||
op_info=Un OP es el administrador del servidor. Los OPs pueden ejecutar más comandos que los usuarios normales
|
||||
op_who=OP nombre del jugador (Por ejemplo: Tu nombre de Minecraft)
|
||||
op_warning=Podrás añadir más usuarios a la lista de OPs después, utilizando el comando /op <player>
|
||||
whitelist_info=La lista blanca (white-list) permite hacer una lista de invitados, solo los usuarios en la lista podrán entrar a tu servidor.
|
||||
whitelist_enable=¿Deseas activar la lista blanca?
|
||||
whitelist_warning=Tendrás que añadir usuarios a la lista blanca
|
||||
|
||||
query_warning1=Query es un protocolo usado por diferentes herramientas para conseguir informacion de tu servidor y los jugadores conectados.
|
||||
query_warning2=Si lo desactivas, no podrás registrar tu servidor en una lista de servidores.
|
||||
query_disable=¿Quieres desactivar Query?
|
||||
rcon_info=RCON es un protocolo que te permite conectarte a la consola de tu servidor usando una contraseña.
|
||||
rcon_enable=¿Queres activar RCON?
|
||||
rcon_password=Contraseña para RCON (puedes cambiarla después)
|
||||
usage_info=Los datos de uso anónimos nos permiten calcular estadísticas globales para PocketMine-MP y sus plugins. Puedes verlas en stats.pocketmine.net
|
||||
usage_disable=¿Quieres desactivar las datos de uso anónimos?
|
||||
ip_get=Obteniendo tu IP externa e IP interna
|
||||
ip_warning=Tu IP externa es {{EXTERNAL_IP}}. Quizás debas redireccionar el puerto a tu IP interna: {{INTERNAL_IP}}
|
||||
ip_confirm=Asegúrate de que este bien, ya que si debes hacerlo y lo saltas, ningún jugador podrá entrar si esta fuera de tu red WIFI. [Pulsa Enter]
|
||||
|
||||
you_have_finished=Has completado el asistente de configuración correctamente
|
||||
pocketmine_will_start=PocketMine-MP se iniciará ahora. Escribe /help para ver la lista de los comandos disponibles.
|
||||
pocketmine_plugins=Ve al Repositorio de Plugins para añadir nuevas funciones, minijuegos o protección avanzada a tu servidor
|
@ -1,6 +0,0 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,6 +0,0 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,9 +0,0 @@
|
||||
language_has_been_selected=Английский был правильно выбран.
|
||||
skip_installer=Вы хотите пропустить мастер настройки?
|
||||
|
||||
welcome_to_pocketmine=Добро пожаловать в PocketMine-MP!\nПеред началом установки нового сервера, вы должны согласиться с лицензией.\nPocketMine-MP лицензирована под LGPL лицензии, \nчто вы можете прочитать, открыв файл лицензии на эту папку.
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,45 +0,0 @@
|
||||
language_has_been_selected={crwdns106:0}{crwdne106:0}
|
||||
skip_installer={crwdns107:0}{crwdne107:0}
|
||||
|
||||
welcome_to_pocketmine={crwdns108:0}{crwdne108:0}
|
||||
accept_license={crwdns109:0}{crwdne109:0}
|
||||
you_have_to_accept_the_license={crwdns110:0}{crwdne110:0}
|
||||
|
||||
setting_up_server_now={crwdns111:0}{crwdne111:0}
|
||||
default_values_info={crwdns112:0}{crwdne112:0}
|
||||
server_properties={crwdns113:0}{crwdne113:0}
|
||||
|
||||
name_your_server={crwdns114:0}{crwdne114:0}
|
||||
port_warning={crwdns115:0}{crwdne115:0}
|
||||
server_port={crwdns116:0}{crwdne116:0}
|
||||
invalid_port={crwdns117:0}{crwdne117:0}
|
||||
ram_warning={crwdns118:0}{crwdne118:0}
|
||||
server_ram={crwdns119:0}{crwdne119:0}
|
||||
gamemode_info={crwdns120:0}{crwdne120:0}
|
||||
default_gamemode={crwdns121:0}{crwdne121:0}
|
||||
max_players={crwdns122:0}{crwdne122:0}
|
||||
spawn_protection_info={crwdns123:0}{crwdne123:0}
|
||||
spawn_protection={crwdns124:0}{crwdne124:0}
|
||||
|
||||
op_info={crwdns125:0}{crwdne125:0}
|
||||
op_who={crwdns126:0}{crwdne126:0}
|
||||
op_warning={crwdns127:0}{crwdne127:0}
|
||||
whitelist_info={crwdns128:0}{crwdne128:0}
|
||||
whitelist_enable={crwdns129:0}{crwdne129:0}
|
||||
whitelist_warning={crwdns130:0}{crwdne130:0}
|
||||
|
||||
query_warning1={crwdns131:0}{crwdne131:0}
|
||||
query_warning2={crwdns132:0}{crwdne132:0}
|
||||
query_disable={crwdns133:0}{crwdne133:0}
|
||||
rcon_info={crwdns134:0}{crwdne134:0}
|
||||
rcon_enable={crwdns135:0}{crwdne135:0}
|
||||
rcon_password={crwdns136:0}{crwdne136:0}
|
||||
usage_info={crwdns137:0}{crwdne137:0}
|
||||
usage_disable={crwdns138:0}{crwdne138:0}
|
||||
ip_get={crwdns139:0}{crwdne139:0}
|
||||
ip_warning={crwdns140:0}{{EXTERNAL_IP}}{crwdnd140:0}{{INTERNAL_IP}}{crwdne140:0}
|
||||
ip_confirm={crwdns141:0}{crwdne141:0}
|
||||
|
||||
you_have_finished={crwdns142:0}{crwdne142:0}
|
||||
pocketmine_will_start={crwdns143:0}{crwdne143:0}
|
||||
pocketmine_plugins={crwdns144:0}{crwdne144:0}
|
@ -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,
|
247
src/pocketmine/CrashDump.php
Normal file
247
src/pocketmine/CrashDump.php
Normal file
@ -0,0 +1,247 @@
|
||||
<?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
|
||||
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
use pocketmine\network\protocol\Info;
|
||||
use pocketmine\plugin\PluginLoadOrder;
|
||||
use pocketmine\utils\Utils;
|
||||
use pocketmine\utils\VersionString;
|
||||
use raklib\RakLib;
|
||||
|
||||
class CrashDump{
|
||||
|
||||
/** @var Server */
|
||||
private $server;
|
||||
private $fp;
|
||||
private $time;
|
||||
private $data = [];
|
||||
private $encodedData = null;
|
||||
private $path;
|
||||
|
||||
public function __construct(Server $server){
|
||||
$this->time = time();
|
||||
$this->server = $server;
|
||||
$this->path = $this->server->getDataPath() . "CrashDump_" . date("D_M_j-H.i.s-T_Y", $this->time) . ".log";
|
||||
$this->fp = fopen($this->path, "wb");
|
||||
$this->data["time"] = $this->time;
|
||||
$this->addLine("PocketMine-MP Crash Dump " . date("D M j H:i:s T Y", $this->time));
|
||||
$this->addLine();
|
||||
$this->baseCrash();
|
||||
$this->generalData();
|
||||
$this->pluginsData();
|
||||
|
||||
$this->extraData();
|
||||
|
||||
$this->encodeData();
|
||||
}
|
||||
|
||||
public function getPath(){
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
public function getEncodedData(){
|
||||
return $this->encodedData;
|
||||
}
|
||||
|
||||
public function getData(){
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
private function encodeData(){
|
||||
$this->addLine();
|
||||
$this->addLine("----------------------REPORT THE DATA BELOW THIS LINE-----------------------");
|
||||
$this->addLine();
|
||||
$this->addLine("===BEGIN CRASH DUMP===");
|
||||
$this->encodedData = zlib_encode(json_encode($this->data, JSON_UNESCAPED_SLASHES), ZLIB_ENCODING_DEFLATE, 9);
|
||||
foreach(str_split(base64_encode($this->encodedData), 76) as $line){
|
||||
$this->addLine($line);
|
||||
}
|
||||
$this->addLine("===END CRASH DUMP===");
|
||||
}
|
||||
|
||||
private function pluginsData(){
|
||||
if(class_exists("pocketmine\\plugin\\PluginManager", false)){
|
||||
$this->addLine();
|
||||
$this->addLine("Loaded plugins:");
|
||||
$this->data["plugins"] = [];
|
||||
foreach($this->server->getPluginManager()->getPlugins() as $p){
|
||||
$d = $p->getDescription();
|
||||
$this->data["plugins"][$d->getName()] = [
|
||||
"name" => $d->getName(),
|
||||
"version" => $d->getVersion(),
|
||||
"authors" => $d->getAuthors(),
|
||||
"api" => $d->getCompatibleApis(),
|
||||
"enabled" => $p->isEnabled(),
|
||||
"depends" => $d->getDepend(),
|
||||
"softDepends" => $d->getSoftDepend(),
|
||||
"main" => $d->getMain(),
|
||||
"load" => $d->getOrder() === PluginLoadOrder::POSTWORLD ? "POSTWORLD" : "STARTUP",
|
||||
"website" => $d->getWebsite()
|
||||
];
|
||||
$this->addLine($d->getName() . " " . $d->getVersion() . " by " . implode(", ", $d->getAuthors())." for API(s) ". implode(", ", $d->getCompatibleApis()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function extraData(){
|
||||
global $arguments;
|
||||
|
||||
if($this->server->getProperty("auto-report.send-settings", true) !== false){
|
||||
$this->data["parameters"] = (array) $arguments;
|
||||
$this->data["server.properties"] = @file_get_contents($this->server->getDataPath() . "server.properties");
|
||||
$this->data["server.properties"] = preg_replace("#^rcon\\.password=(.*)$#m", "rcon.password=******", $this->data["server.properties"]);
|
||||
$this->data["pocketmine.yml"] = @file_get_contents($this->server->getDataPath() . "pocketmine.yml");
|
||||
}else{
|
||||
$this->data["pocketmine.yml"] = "";
|
||||
$this->data["server.properties"] = "";
|
||||
$this->data["parameters"] = [];
|
||||
}
|
||||
$extensions = [];
|
||||
foreach(get_loaded_extensions() as $ext){
|
||||
$extensions[$ext] = phpversion($ext);
|
||||
}
|
||||
$this->data["extensions"] = $extensions;
|
||||
|
||||
if($this->server->getProperty("auto-report.send-phpinfo", true) !== false){
|
||||
ob_start();
|
||||
phpinfo();
|
||||
$this->data["phpinfo"] = ob_get_contents();
|
||||
ob_end_clean();
|
||||
}
|
||||
}
|
||||
|
||||
private function baseCrash(){
|
||||
global $lastExceptionError, $lastError;
|
||||
|
||||
if(isset($lastExceptionError)){
|
||||
$error = $lastExceptionError;
|
||||
}else{
|
||||
$error = (array) error_get_last();
|
||||
$error["trace"] = getTrace(4);
|
||||
$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",
|
||||
);
|
||||
$error["fullFile"] = $error["file"];
|
||||
$error["file"] = cleanPath($error["file"]);
|
||||
$error["type"] = isset($errorConversion[$error["type"]]) ? $errorConversion[$error["type"]] : $error["type"];
|
||||
if(($pos = strpos($error["message"], "\n")) !== false){
|
||||
$error["message"] = substr($error["message"], 0, $pos);
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($lastError)){
|
||||
$this->data["lastError"] = $lastError;
|
||||
}
|
||||
|
||||
$this->data["error"] = $error;
|
||||
unset($this->data["error"]["fullFile"]);
|
||||
unset($this->data["error"]["trace"]);
|
||||
$this->addLine("Error: ". $error["message"]);
|
||||
$this->addLine("File: ". $error["file"]);
|
||||
$this->addLine("Line: ". $error["line"]);
|
||||
$this->addLine("Type: ". $error["type"]);
|
||||
|
||||
if(strpos($error["file"], "src/pocketmine/") === false and strpos($error["file"], "src/raklib/") === false and file_exists($error["fullFile"])){
|
||||
$this->addLine();
|
||||
$this->addLine("THIS CRASH WAS CAUSED BY A PLUGIN");
|
||||
$this->data["plugin"] = true;
|
||||
|
||||
$reflection = new \ReflectionClass("pocketmine\\plugin\\PluginBase");
|
||||
$file = $reflection->getProperty("file");
|
||||
$file->setAccessible(true);
|
||||
foreach($this->server->getPluginManager()->getPlugins() as $plugin){
|
||||
$filePath = \pocketmine\cleanPath($file->getValue($plugin));
|
||||
if(strpos($error["file"], $filePath) === 0){
|
||||
$this->data["plugin"] = $plugin->getName();
|
||||
$this->addLine("BAD PLUGIN: ".$plugin->getDescription()->getFullName());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
$this->data["plugin"] = false;
|
||||
}
|
||||
|
||||
$this->addLine();
|
||||
$this->addLine("Code:");
|
||||
$this->data["code"] = [];
|
||||
|
||||
if($this->server->getProperty("auto-report.send-code", true) !== false){
|
||||
$file = @file($error["fullFile"], FILE_IGNORE_NEW_LINES);
|
||||
for($l = max(0, $error["line"] - 10); $l < $error["line"] + 10; ++$l){
|
||||
$this->addLine("[" . ($l + 1) . "] " . @$file[$l]);
|
||||
$this->data["code"][$l + 1] = @$file[$l];
|
||||
}
|
||||
}
|
||||
|
||||
$this->addLine();
|
||||
$this->addLine("Backtrace:");
|
||||
foreach(($this->data["trace"] = $error["trace"]) as $line){
|
||||
$this->addLine($line);
|
||||
}
|
||||
$this->addLine();
|
||||
}
|
||||
|
||||
private function generalData(){
|
||||
$version = new VersionString();
|
||||
$this->data["general"] = [];
|
||||
$this->data["general"]["version"] = $version->get(false);
|
||||
$this->data["general"]["build"] = $version->getBuild();
|
||||
$this->data["general"]["protocol"] = Info::CURRENT_PROTOCOL;
|
||||
$this->data["general"]["api"] = \pocketmine\API_VERSION;
|
||||
$this->data["general"]["git"] = \pocketmine\GIT_COMMIT;
|
||||
$this->data["general"]["raklib"] = RakLib::VERSION;
|
||||
$this->data["general"]["uname"] = php_uname("a");
|
||||
$this->data["general"]["php"] = phpversion();
|
||||
$this->data["general"]["zend"] = zend_version();
|
||||
$this->data["general"]["php_os"] = PHP_OS;
|
||||
$this->data["general"]["os"] = Utils::getOS();
|
||||
$this->addLine("PocketMine-MP version: " . $version->get(false). " #" . $version->getNumber() . " [Protocol " . Info::CURRENT_PROTOCOL . "; API " . API_VERSION . "]");
|
||||
$this->addLine("Git commit: " . GIT_COMMIT);
|
||||
$this->addLine("uname -a: " . php_uname("a"));
|
||||
$this->addLine("PHP Version: " . phpversion());
|
||||
$this->addLine("Zend version: " . zend_version());
|
||||
$this->addLine("OS : " . PHP_OS . ", " . Utils::getOS());
|
||||
}
|
||||
|
||||
public function addLine($line = ""){
|
||||
fwrite($this->fp, $line . PHP_EOL);
|
||||
}
|
||||
|
||||
public function add($str){
|
||||
fwrite($this->fp, $str);
|
||||
}
|
||||
|
||||
}
|
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);
|
||||
}
|
||||
|
||||
|
||||
}
|
2399
src/pocketmine/Player.php
Normal file
2399
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,47 @@ 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.2.0";
|
||||
const CODENAME = "絶好(Zekkou)ケーキ(Cake)";
|
||||
const MINECRAFT_VERSION = "v0.8.1 alpha";
|
||||
const MINECRAFT_VERSION = "v0.9.5 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(!extension_loaded("pthreads")){
|
||||
echo "[CRITICAL] Unable to find the pthreads extension." . PHP_EOL;
|
||||
echo "[CRITICAL] Please use the installer provided on the homepage.". PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@ -111,13 +118,13 @@ namespace pocketmine {
|
||||
$time -= $time % 60;
|
||||
//TODO: Parse different time & date formats by region. ¬¬ world
|
||||
//Example: USA
|
||||
exec("time.exe /T", $hour);
|
||||
@exec("time.exe /T", $hour);
|
||||
$i = array_map("intval", explode(":", trim($hour[0])));
|
||||
exec("date.exe /T", $date);
|
||||
@exec("date.exe /T", $date);
|
||||
$j = array_map("intval", explode(substr($date[0], 2, 1), trim($date[0])));
|
||||
$offset = round((mktime($i[0], $i[1], 0, $j[1], $j[0], $j[2]) - $time) / 60) * 60;
|
||||
}else{
|
||||
exec("date +%s", $t);
|
||||
@exec("date +%s", $t);
|
||||
$offset = round((intval(trim($t[0])) - time()) / 60) * 60;
|
||||
}
|
||||
|
||||
@ -135,13 +142,13 @@ namespace pocketmine {
|
||||
}
|
||||
|
||||
gc_enable();
|
||||
error_reporting(E_ALL | E_STRICT);
|
||||
error_reporting(-1);
|
||||
ini_set("allow_url_fopen", 1);
|
||||
ini_set("display_errors", 1);
|
||||
ini_set("display_startup_errors", 1);
|
||||
ini_set("default_charset", "utf-8");
|
||||
|
||||
ini_set("memory_limit", "128M"); //Default
|
||||
ini_set("memory_limit", "256M"); //Default
|
||||
define("pocketmine\\START_TIME", microtime(true));
|
||||
|
||||
$opts = getopt("", array("enable-ansi", "disable-ansi", "data:", "plugins:", "no-wizard"));
|
||||
@ -149,11 +156,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,76 +172,42 @@ 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);
|
||||
function getTrace($start = 1, $trace = null){
|
||||
if($trace === null){
|
||||
if(function_exists("xdebug_get_function_stack")){
|
||||
$trace = array_reverse(xdebug_get_function_stack());
|
||||
}else{
|
||||
$message = $replaced;
|
||||
$e = new \Exception();
|
||||
$trace = $e->getTrace();
|
||||
}
|
||||
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 = "";
|
||||
if(isset($trace[$i]["args"])){
|
||||
foreach($trace[$i]["args"] as $name => $value){
|
||||
if(isset($trace[$i]["args"]) or isset($trace[$i]["params"])){
|
||||
if(isset($trace[$i]["args"])){
|
||||
$args = $trace[$i]["args"];
|
||||
}else{
|
||||
$args = $trace[$i]["params"];
|
||||
}
|
||||
foreach($args as $name => $value){
|
||||
$params .= (is_object($value) ? get_class($value) . " " . (method_exists($value, "__toString") ? $value->__toString() : "object") : gettype($value) . " " . @strval($value)) . ", ";
|
||||
}
|
||||
}
|
||||
$messages[] = "#$j " . (isset($trace[$i]["file"]) ? $trace[$i]["file"] : "") . "(" . (isset($trace[$i]["line"]) ? $trace[$i]["line"] : "") . "): " . (isset($trace[$i]["class"]) ? $trace[$i]["class"] . $trace[$i]["type"] : "") . $trace[$i]["function"] . "(" . substr($params, 0, -2) . ")";
|
||||
$messages[] = "#$j " . (isset($trace[$i]["file"]) ? cleanPath($trace[$i]["file"]) : "") . "(" . (isset($trace[$i]["line"]) ? $trace[$i]["line"] : "") . "): " . (isset($trace[$i]["class"]) ? $trace[$i]["class"] . (($trace[$i]["type"] === "dynamic" or $trace[$i]["type"] === "->") ? "->" : "::") : "") . $trace[$i]["function"] . "(" . substr($params, 0, -2) . ")";
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
function error_handler($errno, $errstr, $errfile, $errline){
|
||||
function cleanPath($path){
|
||||
return rtrim(str_replace(["\\", ".php", "phar://", rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PATH), "/"), rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PLUGIN_PATH), "/")], ["/", "", "", "", ""], $path), "/");
|
||||
}
|
||||
|
||||
function error_handler($errno, $errstr, $errfile, $errline, $trace = null){
|
||||
global $lastError;
|
||||
if(error_reporting() === 0){ //@ error-control
|
||||
return false;
|
||||
}
|
||||
@ -257,90 +228,102 @@ 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);
|
||||
foreach(getTrace() as $i => $line){
|
||||
console("[TRACE] $line");
|
||||
if(($pos = strpos($errstr, "\n")) !== false){
|
||||
$errstr = substr($errstr, 0, $pos);
|
||||
}
|
||||
$logger = MainLogger::getLogger();
|
||||
$oldFile = $errfile;
|
||||
$errfile = cleanPath($errfile);
|
||||
$logger->log($type, "An $errno error happened: \"$errstr\" in \"$errfile\" at line $errline");
|
||||
|
||||
foreach(($trace = getTrace($trace === null ? 3 : 0, $trace)) as $i => $line){
|
||||
$logger->debug($line);
|
||||
}
|
||||
$lastError = [
|
||||
"type" => $type,
|
||||
"message" => $errstr,
|
||||
"fullFile" => $oldFile,
|
||||
"file" => $errfile,
|
||||
"line" => $errline,
|
||||
"trace" => $trace
|
||||
];
|
||||
|
||||
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);
|
||||
$pthreads_version = phpversion("pthreads");
|
||||
if(substr_count($pthreads_version, ".") < 2){
|
||||
$pthreads_version = "0.$pthreads_version";
|
||||
}
|
||||
if(version_compare($pthreads_version, "2.0.4") < 0){
|
||||
$logger->critical("pthreads >= 2.0.4 is required, while you have $pthreads_version.");
|
||||
++$errors;
|
||||
}else{
|
||||
$pthreads_version = phpversion("pthreads");
|
||||
if(substr_count($pthreads_version, ".") < 2){
|
||||
$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);
|
||||
}
|
||||
|
||||
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 +333,36 @@ 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);
|
||||
ThreadManager::init();
|
||||
$server = new Server($autoloader, $logger, \pocketmine\PATH, \pocketmine\DATA, \pocketmine\PLUGIN_PATH);
|
||||
$server->start();
|
||||
|
||||
kill(getmypid());
|
||||
exit(0);
|
||||
foreach(ThreadManager::getInstance()->getAll() as $id => $thread){
|
||||
if($thread->isRunning()){
|
||||
$logger->debug("Stopping ".(new \ReflectionClass($thread))->getShortName()." thread");
|
||||
if($thread instanceof Thread){
|
||||
$thread->kill();
|
||||
$thread->detach();
|
||||
}elseif($thread instanceof Worker){
|
||||
$thread->shutdown();
|
||||
$thread->join();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
$logger->shutdown();
|
||||
$logger->join();
|
||||
|
||||
}
|
2031
src/pocketmine/Server.php
Normal file
2031
src/pocketmine/Server.php
Normal file
File diff suppressed because it is too large
Load Diff
33
src/pocketmine/Thread.php
Normal file
33
src/pocketmine/Thread.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?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;
|
||||
|
||||
/**
|
||||
* This class must be extended by all custom threading classes
|
||||
*/
|
||||
abstract class Thread extends \Thread{
|
||||
|
||||
public final function start($options = PTHREADS_INHERIT_ALL){
|
||||
ThreadManager::getInstance()->add($this);
|
||||
return parent::start($options & ~PTHREADS_INHERIT_CLASSES);
|
||||
}
|
||||
}
|
68
src/pocketmine/ThreadManager.php
Normal file
68
src/pocketmine/ThreadManager.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?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;
|
||||
|
||||
class ThreadManager extends \Threaded{
|
||||
|
||||
/** @var ThreadManager */
|
||||
private static $instance = null;
|
||||
|
||||
public static function init(){
|
||||
self::$instance = new ThreadManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ThreadManager
|
||||
*/
|
||||
public static function getInstance(){
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Worker|Thread $thread
|
||||
*/
|
||||
public function add($thread){
|
||||
if($thread instanceof Thread or $thread instanceof Worker){
|
||||
$this->{spl_object_hash($thread)} = $thread;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Worker|Thread $thread
|
||||
*/
|
||||
public function remove($thread){
|
||||
if($thread instanceof Thread or $thread instanceof Worker){
|
||||
unset($this->{spl_object_hash($thread)});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Worker[]|Thread[]
|
||||
*/
|
||||
public function getAll(){
|
||||
$array = [];
|
||||
foreach($this as $key => $thread){
|
||||
$array[$key] = $thread;
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
}
|
33
src/pocketmine/Worker.php
Normal file
33
src/pocketmine/Worker.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?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;
|
||||
|
||||
/**
|
||||
* This class must be extended by all custom threading classes
|
||||
*/
|
||||
abstract class Worker extends \Worker{
|
||||
|
||||
public final function start($options = PTHREADS_INHERIT_ALL){
|
||||
ThreadManager::getInstance()->add($this);
|
||||
return parent::start($options & ~PTHREADS_INHERIT_CLASSES);
|
||||
}
|
||||
}
|
@ -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,8 +38,8 @@ 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);
|
||||
Server::getInstance()->api->entity->drop($this, Item::get($this->id));
|
||||
$this->getLevel()->setBlock($this, new Air(), false);
|
||||
$this->getLevel()->dropItem($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;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user