mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-16 06:15:09 +00:00
Compare commits
1570 Commits
api/2.0.0
...
api/3.0.0-
Author | SHA1 | Date | |
---|---|---|---|
6e5759b1d1 | |||
03d3e595d6 | |||
8ca59d12e9 | |||
89e4defa29 | |||
f5534a9ab0 | |||
28bce8d48c | |||
3c02a6a8ed | |||
6b0ac8adb8 | |||
38ec5da260 | |||
240cc3043a | |||
043ae487de | |||
f12701e582 | |||
6e961ae897 | |||
e1d10f595a | |||
178dd1b981 | |||
826ec90856 | |||
0523f26613 | |||
5190d9c1e2 | |||
c8fd0eaf8b | |||
53ef9b653a | |||
030cc4afb0 | |||
9bd7f771d3 | |||
10f6a0eef0 | |||
d0a96f35da | |||
65e908a403 | |||
d7091f4460 | |||
c6670b2e74 | |||
194278d986 | |||
0e2e9aab2e | |||
1b5fed983b | |||
5aba87b250 | |||
f01ce8e994 | |||
d89b8cf12e | |||
6aa9b081e9 | |||
dbed80386a | |||
cefad0444c | |||
ee052f91d4 | |||
ef6250967f | |||
61cfdac6a1 | |||
fd7fb10223 | |||
6897cb4774 | |||
8e7ad532f1 | |||
9e8366725a | |||
b14ecc18c4 | |||
55720d9f0a | |||
0262465a26 | |||
7996a7b08c | |||
4a1fc1bdf7 | |||
85b2b2ae2e | |||
38e11aae5e | |||
f0755d1659 | |||
fd33a65e3b | |||
7baadf9dad | |||
ca23864e4c | |||
8728547a11 | |||
90fb3c5e12 | |||
1fb6d12a6b | |||
1323d89139 | |||
136ab1dba1 | |||
8cae20e818 | |||
ff2b3bfa2a | |||
361b262d3a | |||
1fd7f441b4 | |||
3f56d6ddc8 | |||
1e4cbb0dd9 | |||
a99eee9def | |||
bdee746e46 | |||
642c7733cd | |||
c8199e14ad | |||
0f37bc35ba | |||
8dc3d019f6 | |||
bd64172750 | |||
0e51820dfb | |||
30d2318bb7 | |||
63634d7e7d | |||
d941bf8e74 | |||
8c9d9626ab | |||
6b34c47c96 | |||
77241e14ce | |||
15b08c1417 | |||
4d1daecd91 | |||
53e5db5142 | |||
ad72fe6232 | |||
8b33f711d0 | |||
319735db3a | |||
c283d87494 | |||
be27e03126 | |||
c1c290cd39 | |||
5267c571e9 | |||
0fac3b9a9d | |||
23a38400e2 | |||
297172d111 | |||
825d4f9702 | |||
1d31958ce6 | |||
130a60f2b2 | |||
07268e4b37 | |||
441efc4ae2 | |||
88bd7713c5 | |||
aaa3b6e59a | |||
25adac8859 | |||
8d0b881762 | |||
16cb75ef38 | |||
3b9689674d | |||
7f5d8cc900 | |||
8761256246 | |||
8c363cb571 | |||
10b765e17a | |||
0eb866bf25 | |||
c46caa38e1 | |||
17d949f476 | |||
c569f55933 | |||
01d8d216ca | |||
f1ccee505b | |||
a61adb5991 | |||
cae1a3bb4b | |||
6681bd250a | |||
38293913ee | |||
8493ce8a35 | |||
9b7868238c | |||
953c1ef4ec | |||
021a9a4820 | |||
5b7565664c | |||
ebdfbe6bb9 | |||
85ff236461 | |||
d7422d9283 | |||
fcb3c4820e | |||
c72ef605b9 | |||
e274f1b7f8 | |||
69514c5763 | |||
2c6205e3f3 | |||
12c154badf | |||
2215543e39 | |||
b310959fd1 | |||
c9ee206fe6 | |||
d065e76a41 | |||
6877ac35eb | |||
f0c1ea7dd7 | |||
6aaef1660a | |||
78d49f8e66 | |||
de6ebc5791 | |||
815c697767 | |||
231617b9d0 | |||
90cb3c010f | |||
2398e2450a | |||
bb9299070d | |||
58bf5d6679 | |||
cb7911ee9c | |||
aa9fd1b4f9 | |||
7483f22e8b | |||
89f5567476 | |||
4df261b75a | |||
41780fd195 | |||
0b83c61494 | |||
1d338bfdf9 | |||
2cff5a500c | |||
f077ba4748 | |||
2f614c5dc2 | |||
dcf34b7188 | |||
ca84532640 | |||
4d8d57ca5e | |||
75e32b11b7 | |||
9f44b2ed75 | |||
62aba15f9e | |||
1c02c747ca | |||
22d8626e23 | |||
b071ce9c5a | |||
a6c0f1512c | |||
604d8ecf9a | |||
5d75d3d5b6 | |||
8b13b520e0 | |||
2603f5cc63 | |||
00e4fff259 | |||
a06c934f4d | |||
14ea76ecd7 | |||
c81b76cbf6 | |||
517609dc2e | |||
506118e28f | |||
6e8631347d | |||
5335ed9394 | |||
138d85307b | |||
226175f961 | |||
297cfcf168 | |||
9ea39ea3d7 | |||
16aeb0ac85 | |||
8caabd3267 | |||
ddfe828445 | |||
67ad2d25b9 | |||
b9c4a65307 | |||
23752548fe | |||
190f4dd6ab | |||
120cf56a47 | |||
21f09d5fdb | |||
bde6d7db8d | |||
adc6b03d4c | |||
fd52022065 | |||
ea5bd0348a | |||
c3cf82ab26 | |||
6abef6b22d | |||
9902d29734 | |||
7475aa3a18 | |||
6d6283b7f3 | |||
a3d21de559 | |||
6a717d8050 | |||
ece0692229 | |||
b5d2402c9b | |||
37b050f864 | |||
d07b5ba1e1 | |||
697ea55fb7 | |||
8b3fad8a7b | |||
f2402f2122 | |||
b548c4fdbe | |||
a982344b96 | |||
0b2b9126a2 | |||
f4f2323518 | |||
badd669b3d | |||
c7fd3eb725 | |||
a5f5502380 | |||
6d5620606e | |||
20f34fba53 | |||
61968cca28 | |||
13187e1749 | |||
7c212d3d53 | |||
9e142655ea | |||
1fec16f167 | |||
4ab286a142 | |||
44dd7c2222 | |||
97911aa9cf | |||
7ff143c793 | |||
cd7724d94a | |||
76e213ae73 | |||
8ce833bf74 | |||
ba27fff853 | |||
80f2519d7d | |||
ebda6ec19b | |||
6553c82320 | |||
1b0ed0f1b8 | |||
5433a3f964 | |||
3ee8f2b182 | |||
238b3ca4c1 | |||
2c3d7c49f9 | |||
76acb1da7b | |||
17518195d1 | |||
2443a57234 | |||
90edb8ebe7 | |||
55e32424a0 | |||
d6266d19b6 | |||
95752ef542 | |||
84c8ac03fb | |||
da4c9cf404 | |||
0f2ca99c67 | |||
a7674c52e6 | |||
a52fa93998 | |||
770616d4ab | |||
d1852834de | |||
eb4594348b | |||
5a3ce42f74 | |||
0712979908 | |||
ae715cf2f2 | |||
3a5fc78c53 | |||
445a67954d | |||
50580f4408 | |||
4250e99e3a | |||
8229410e27 | |||
938af60733 | |||
8a35b9da29 | |||
c32b75fa18 | |||
b8ade18888 | |||
592ce3c9e9 | |||
876659cc73 | |||
604d11a8fd | |||
d2ace6bdd2 | |||
672b7610a9 | |||
456ddd3fb3 | |||
b62597fe63 | |||
9e54980ded | |||
121777375e | |||
93e149e91c | |||
1f70a7830e | |||
2f3c77c68a | |||
02f42eba48 | |||
9451dd361e | |||
da83b879c0 | |||
d1fd6aef44 | |||
cd02f1e4be | |||
eeedcf7332 | |||
216fc6fe31 | |||
17053389b0 | |||
8475c63426 | |||
f2ff0198cc | |||
c394aea803 | |||
e1d894057c | |||
5b3bed8b06 | |||
159b2e3d5e | |||
bed68a012d | |||
e0307411da | |||
e88053faf4 | |||
e51106e64c | |||
0e24596aed | |||
276fccf4bb | |||
64f2e7587d | |||
bedfca8698 | |||
4a3f01703e | |||
41c6cb6f97 | |||
384a4b3a09 | |||
e5e76d4c93 | |||
a7ad26426f | |||
2688228a6f | |||
e15eefc58f | |||
f73d3d086e | |||
41f5cba971 | |||
8853452feb | |||
d8f0dd6db8 | |||
09c53552c1 | |||
c8ed2406d7 | |||
a4ec2b7f2c | |||
1f6d325328 | |||
f35ca147bb | |||
9efd350e78 | |||
be4f48a119 | |||
b6fb2bca13 | |||
4f1302adf2 | |||
83f29e5639 | |||
e825ebd8fa | |||
83af4dcd59 | |||
f6c31680f6 | |||
6320a63ca5 | |||
9e02f3c4e3 | |||
2cd05bf5b5 | |||
5b4035253b | |||
77376d3e33 | |||
56e45a031b | |||
21a1e0eb6b | |||
670a9fe44f | |||
6efa4343b1 | |||
dc3f13cd30 | |||
b4c4005009 | |||
eebc52e00b | |||
20aa519f3a | |||
741394dab1 | |||
ea414ea72d | |||
696c67f541 | |||
021dbd65d7 | |||
8510be062c | |||
7b142d4742 | |||
643e10037c | |||
0257432afc | |||
4950157f1d | |||
c4d8c28338 | |||
eda2473e78 | |||
4b65fef957 | |||
fbe2567e58 | |||
9a0b3a6e22 | |||
5fc50aeda5 | |||
ebb71fc6c5 | |||
ae3a8a5493 | |||
9be1b929a5 | |||
6480f7a989 | |||
1576a79644 | |||
02cbf800d0 | |||
5a4fbc6f5a | |||
83fcec3e94 | |||
5d436a06ec | |||
8958b3c51c | |||
c1ff7bbef4 | |||
74ee94b385 | |||
5208ad885c | |||
0c798222a4 | |||
e8bd0c3e09 | |||
51be88c698 | |||
0dc8362536 | |||
9bae4d8ef6 | |||
bb4808c23e | |||
3025f76cd0 | |||
1e539c4e3b | |||
590003d7c1 | |||
72d40860f3 | |||
d3d1e32309 | |||
36d47a33f3 | |||
260179197b | |||
82fd3b540e | |||
75644b5df2 | |||
3ad1b1ba7f | |||
b4c2305c7f | |||
1d0f0a2999 | |||
8ca37b3813 | |||
2ba601b6e9 | |||
06083d6dc4 | |||
2d8395f70e | |||
6b5c0af161 | |||
c84218c55b | |||
6b7a382625 | |||
54b6a5710e | |||
7958fffa07 | |||
98e0a2ecba | |||
44f1dedbf8 | |||
899e318a88 | |||
23eb8600ab | |||
989505c42c | |||
d9da9accbc | |||
711d62b5eb | |||
49506659e0 | |||
7886918140 | |||
8a151dc373 | |||
58a12fdfa3 | |||
50dffeb6a1 | |||
63d2b341b9 | |||
77cd8e7799 | |||
10ff2948ac | |||
0d0df3390a | |||
e4a5cb6021 | |||
71e354cf1d | |||
7d3fca83f0 | |||
3fdbcee10f | |||
4e9af1ac45 | |||
475066c9f5 | |||
d5f6966ce3 | |||
0ad4a59d5a | |||
5f6dc25c9f | |||
3b7fc21839 | |||
ecba80fd63 | |||
fb59b57bdf | |||
2b4e303f52 | |||
2103c981a9 | |||
3188f1c053 | |||
fdf71841e1 | |||
11fae493a5 | |||
3135fe3c69 | |||
561d8e7a39 | |||
3048a3b39b | |||
63c12440dc | |||
b912b9173c | |||
ca3cf3e067 | |||
8a02dbb15a | |||
f0b4a33e2e | |||
306bf7be5f | |||
0b47324fe3 | |||
17be06a56d | |||
caff686827 | |||
210bdc2436 | |||
acaa0d2740 | |||
ffefcd4473 | |||
8957dbf08e | |||
2d626d1d90 | |||
253db40a11 | |||
8a3b31077e | |||
1f4e6535bb | |||
6ae24c5c19 | |||
036663e0b5 | |||
344500785c | |||
a95d173989 | |||
e72d8cf8f5 | |||
c0e0730923 | |||
b6fe231bc1 | |||
3bd94c9da7 | |||
2e5e016b87 | |||
822c048af0 | |||
6e4b8ba677 | |||
a5a8732800 | |||
21887b283f | |||
3e141afe48 | |||
aa6eef26e9 | |||
87c16dab23 | |||
c1542d853f | |||
8274f5b3cc | |||
e8be8550a0 | |||
b3dada4cb9 | |||
ed5f69f170 | |||
7d777510c5 | |||
6ff92f2adf | |||
f32e880542 | |||
6cacb368ce | |||
6fa59230db | |||
1a7f567a70 | |||
42fb1d1fef | |||
cca9cf2c86 | |||
7c00982fff | |||
3150c50cac | |||
57e7c3d91f | |||
3e8825f826 | |||
ab3b50f062 | |||
dbb92096e4 | |||
24bdf330d5 | |||
b28128f835 | |||
fb5587350d | |||
e6a2b0f270 | |||
bb230c5812 | |||
6de8415c79 | |||
2018ad6376 | |||
b5790d19bf | |||
9390866a13 | |||
c3b8be3f60 | |||
b9355387da | |||
7f99d9019a | |||
8bb0c53797 | |||
46a2e6cbf8 | |||
8fc1501e89 | |||
6a191b5069 | |||
08b8debd78 | |||
2a7b736f18 | |||
c2a7c2c6cd | |||
4d874e7e78 | |||
23866359c9 | |||
3a214b7ce6 | |||
6341d3a0dc | |||
72d1948f30 | |||
a7f5ee2f3e | |||
6b773dc04d | |||
6af87b7b30 | |||
5283975f20 | |||
a5c6c8b973 | |||
caa229a25f | |||
4731bf0a16 | |||
30df0c2418 | |||
e485999218 | |||
650afe2d94 | |||
fa58736360 | |||
c33972aa67 | |||
6bcc8cea8e | |||
f2467d3dbc | |||
be7e97e0bb | |||
767f0dcbf6 | |||
c9fdb66c78 | |||
8a28dfa64d | |||
c6a6571c07 | |||
6d7b76f356 | |||
8cca8e1256 | |||
30c5487f94 | |||
728851594b | |||
2726f2a011 | |||
1a5e3b2ad0 | |||
1493cde07f | |||
6cd4d2c5a2 | |||
6504fdabab | |||
394f420059 | |||
b8a30309bb | |||
1a6517ea4e | |||
9c9095060f | |||
97f6a32557 | |||
409fc282d2 | |||
d474f73665 | |||
c2dfef700f | |||
dca7efa03c | |||
b4a149cce8 | |||
2a67507997 | |||
70bd9afd37 | |||
56dfa7d000 | |||
390df00966 | |||
82fd0e8d47 | |||
6259f42d81 | |||
08d4d7fe0e | |||
ae612b913e | |||
adbc298909 | |||
d92a6240d8 | |||
4a7c40edd5 | |||
1dd8fc008b | |||
ec079b68a6 | |||
ecfcf49984 | |||
f7aad8e2fe | |||
a73c6f1861 | |||
a365c831a8 | |||
c0377fc63a | |||
22d148a59d | |||
a1ce535d02 | |||
993af0fa30 | |||
b83c135c3f | |||
8bf1cc9e48 | |||
c70690a600 | |||
4b4f2af9e3 | |||
9047c2c1ef | |||
89ca2ac2d5 | |||
6a2a74a457 | |||
7ba807fd42 | |||
19410754c6 | |||
8cd31c2dc4 | |||
c09a5ab301 | |||
a0ef15b15e | |||
03826d9cbc | |||
080b35bf53 | |||
e9c46da7f0 | |||
0f79b19fdc | |||
69ae37d191 | |||
86742fcf30 | |||
a4b8dd43e6 | |||
e11f1e94e9 | |||
938452bfe9 | |||
a724395148 | |||
bc10edfdd3 | |||
f7d07ca155 | |||
be7b057fa5 | |||
8637e0224f | |||
8919d4a372 | |||
0cf3914f5d | |||
e9a638d84a | |||
e3b3f60c66 | |||
1bae973502 | |||
e0f8a02bb8 | |||
846be84324 | |||
8ef24423d1 | |||
8fc38c36f9 | |||
eb05f2ecde | |||
478e954b3f | |||
313fdb9e87 | |||
1bf18ba8d2 | |||
5011198a4e | |||
e96fa8b682 | |||
bf3868c078 | |||
3167817e34 | |||
433b8369f5 | |||
0612244b5e | |||
487233a101 | |||
4341fb8347 | |||
789df942b6 | |||
9e99252817 | |||
75cc2d6914 | |||
61b857a81c | |||
2024e9ecdf | |||
4765242397 | |||
3687b149b9 | |||
1aae9e03b6 | |||
c43ab12a9a | |||
cd66f58526 | |||
7870a8672e | |||
eac756470a | |||
a302b4988f | |||
2193adf844 | |||
890f72dbf2 | |||
595e1ab52f | |||
4a7abb7033 | |||
d358e13868 | |||
1f630e57f2 | |||
cc1d1b0f45 | |||
78c09267e5 | |||
c445db421f | |||
e18a3ac933 | |||
75863e2a44 | |||
5aea9220c9 | |||
bd7205dd64 | |||
82a63ed18e | |||
cf07af8b55 | |||
b775e8c88a | |||
51091fe87b | |||
7c14ffbcfa | |||
db93827650 | |||
c2186041d6 | |||
481114281e | |||
51b0673b4b | |||
606b9b687d | |||
45618c7cfe | |||
3f03d9e683 | |||
f0d12a0b30 | |||
9cc27b2719 | |||
87e54d7a3a | |||
29e88d8592 | |||
c6e800cf42 | |||
b7b7bcee4f | |||
6ea0eb47ec | |||
b9a87ed147 | |||
742f593758 | |||
1e9ff44890 | |||
55c4e35407 | |||
e83ffd5afe | |||
54453d0b0a | |||
51d510aa4f | |||
4cd97a7c7a | |||
d586ad03ec | |||
61d354a4ea | |||
6f126ad239 | |||
efea39e0a4 | |||
d4bb078566 | |||
6686bd4442 | |||
2b02fcfe2c | |||
138fb88431 | |||
26577d9d5b | |||
2f4943ac90 | |||
eda7965f86 | |||
4666560731 | |||
b01ad01eff | |||
4ba3a3af3d | |||
5baf59ca56 | |||
902957cb53 | |||
3463bea932 | |||
105917a534 | |||
b83082f224 | |||
840a3883b1 | |||
ad4659365a | |||
8d858e3e6d | |||
22ba017965 | |||
8bb0e8d398 | |||
087a994393 | |||
e4e4ef5f2a | |||
3ac51e1095 | |||
2db6ea6b18 | |||
b6ae92e1a7 | |||
31e2c1d26c | |||
846e3b6f1e | |||
0e525ac1c3 | |||
8382970d56 | |||
db3cd1829c | |||
caced595d2 | |||
86f3b257a7 | |||
1ed5de1d3b | |||
63358a8065 | |||
f6ff03fc31 | |||
0ad16c1919 | |||
38b8f14758 | |||
8779259734 | |||
2f306c3a38 | |||
57379b93ce | |||
954271b90f | |||
645d744e05 | |||
4c764072b2 | |||
3446f68c74 | |||
ca6826898b | |||
76ab3d4288 | |||
b6c1139b27 | |||
af06d78725 | |||
8cc1003956 | |||
92281da514 | |||
5c8297f4a1 | |||
23ed3334c2 | |||
674394c4f5 | |||
4e381ab033 | |||
c5527db424 | |||
aecff7c782 | |||
0207b22110 | |||
a77c1ce13c | |||
afd90adb1c | |||
2e480b5ea1 | |||
d4cc7d13cd | |||
f6c0ba9846 | |||
f3c38700f5 | |||
77b1b565a4 | |||
36c95660e6 | |||
905d3f1610 | |||
0f174f7605 | |||
60f5c7ccef | |||
85c1535c75 | |||
568e2760f1 | |||
fe8cb8cd86 | |||
15b47fcb2f | |||
00e6d6a6b1 | |||
8887a92d4b | |||
a9afad10bc | |||
b41fef0276 | |||
fe3b5bac51 | |||
0a4d62b405 | |||
0935855def | |||
c7c7a40899 | |||
162a08b8cb | |||
b9ad0b99a5 | |||
576702ffa9 | |||
dbb8e8ad0a | |||
4a9acf564c | |||
69f64dd802 | |||
11169b0777 | |||
71af694cc1 | |||
c51c8ae700 | |||
713f3facf9 | |||
df577bddc2 | |||
046f17c9e2 | |||
50f7d04044 | |||
4ccd955647 | |||
c383c7b0dd | |||
adbb53929e | |||
8a7259aa73 | |||
76ceddf266 | |||
11f35d28c2 | |||
c4f461f65d | |||
702c129a97 | |||
56306f6636 | |||
18f1376c65 | |||
49eb0eb050 | |||
13fd8b681e | |||
40f2d7fcdc | |||
c537cea87e | |||
eaef2bd169 | |||
966e4bf8a1 | |||
f889bf9cf5 | |||
6d90f91be0 | |||
0a52e210db | |||
971703a618 | |||
de359a2bce | |||
1266f8f1aa | |||
a22306d418 | |||
b542277eca | |||
edf1fbb6e6 | |||
653b6b55a9 | |||
7f09a2a26e | |||
7aeb3129ac | |||
84ec944b6b | |||
6ef132e468 | |||
dc71eb5246 | |||
2a59977440 | |||
bf9b8722c9 | |||
4d897b824b | |||
caf4937222 | |||
2f87dfdcb0 | |||
716efe2549 | |||
ffcada88f3 | |||
946d7e2bb1 | |||
5a9b5db103 | |||
beed94dfb9 | |||
c6229b1e52 | |||
7a2ed232cc | |||
d682fdfdf0 | |||
0e7f364a41 | |||
1be4bd67e4 | |||
559504225a | |||
8ddf781a51 | |||
7cafaf2844 | |||
fcff6961a8 | |||
db4027cdb2 | |||
e22bb213af | |||
179210aa27 | |||
6ece57e23e | |||
be631ad6f7 | |||
2204942338 | |||
00a226921c | |||
e7406ba096 | |||
a356e36340 | |||
547a09c8d4 | |||
3f1790bcb8 | |||
a0ba8f0098 | |||
feb538900b | |||
5ce860c2f5 | |||
6c5ca9b256 | |||
de95046c11 | |||
9e2b26de23 | |||
b867cf4c91 | |||
d3f4b185f3 | |||
86de0bddd9 | |||
207056fb9d | |||
17e4f45e97 | |||
6828ce66b6 | |||
930945db18 | |||
b7b7a93e4e | |||
d2efcee115 | |||
eefa8abaf2 | |||
a34573643f | |||
dab73d8950 | |||
5e6a0e7ba0 | |||
c5eccc8e1c | |||
b55929b382 | |||
8a775e0c45 | |||
d7378fe6f4 | |||
66924729ff | |||
f12a6eed29 | |||
f2159c5948 | |||
4ab8233fe0 | |||
a327a74ece | |||
f3ab45e7d5 | |||
cdf6d200ef | |||
40775f5d86 | |||
319763dd93 | |||
a455e25665 | |||
1c7773c5f1 | |||
7c66af5994 | |||
cb7264e0e5 | |||
f7e1939ae8 | |||
172d7339f9 | |||
894beed59b | |||
c01e0354bd | |||
e312c697fd | |||
80292c6c7a | |||
dda47ee566 | |||
5863d001bd | |||
6b72bbc234 | |||
1c2895eb12 | |||
fd982afce6 | |||
022f33b256 | |||
f1510428d0 | |||
90f1efc667 | |||
f7e959d602 | |||
630f0fab7f | |||
202bac28fc | |||
874afc2fd2 | |||
9c25ec3afd | |||
e47c7ea55f | |||
f75cc93160 | |||
b24d516eda | |||
845b124f89 | |||
16972bf9a5 | |||
87a52a4f35 | |||
7f838a8c36 | |||
b5f473a3df | |||
40a6f4dee9 | |||
69ac80518c | |||
45e5b6b04c | |||
cb059ea713 | |||
afb2e0c51f | |||
cd477163cd | |||
6b747f9272 | |||
868602a559 | |||
bc1c75a15a | |||
1c3d89cfef | |||
c84ec90398 | |||
3e76c3a6dd | |||
52f2596dc5 | |||
2079e2fd88 | |||
217f66e180 | |||
07f32765ba | |||
788bd6fc20 | |||
01440fb659 | |||
dda8c6cc8f | |||
1da870b298 | |||
7a36d80384 | |||
bb79684480 | |||
4245274aec | |||
b9dfc7551a | |||
839a2ce07e | |||
34f833fa79 | |||
c9cf3d5aa4 | |||
5332887a0a | |||
5926bab323 | |||
0750b3ab59 | |||
96801be3d3 | |||
2fb92c1c62 | |||
c040579e09 | |||
9a35b4fbc8 | |||
940b20c191 | |||
c21768df26 | |||
2d927db264 | |||
a5a51fb9c5 | |||
47f7af6739 | |||
b7a3230f73 | |||
6a03f8d434 | |||
06f2a9c674 | |||
0e64d4bbc2 | |||
284c18d401 | |||
6ba4a8fe5c | |||
4638ccbb68 | |||
36cda5de61 | |||
9c350dbe47 | |||
2673e4de7f | |||
be449b6106 | |||
4c61ad9f2d | |||
66fbfdd47b | |||
8a28021b44 | |||
ab1150382a | |||
8114ceaf68 | |||
0d37d0d896 | |||
cc0b4d888e | |||
116cba9fae | |||
51a20470f6 | |||
6e1abe7b15 | |||
cbb003bf29 | |||
fa5e66478c | |||
bcbb5de5bb | |||
548df21645 | |||
b7b73aab23 | |||
a8650a241c | |||
d26713ab59 | |||
3138e02acb | |||
d264a04db4 | |||
3c709b1d3e | |||
c344caaf78 | |||
9e341f74d8 | |||
e7dbda922a | |||
92193fd27b | |||
bb85308b01 | |||
565335f29e | |||
78278a0b93 | |||
955dc38be4 | |||
f58ee2028e | |||
083d1e9ef8 | |||
90abc28c29 | |||
6c5dbd7359 | |||
4f27bce5b3 | |||
6f1b12b021 | |||
a71747347f | |||
004880548c | |||
91a92b4e57 | |||
ed765a2c9b | |||
e1fb4a44e9 | |||
2cb98c48c2 | |||
d41bdfc31c | |||
c925845173 | |||
7fb3c7343f | |||
132e04fdbb | |||
1f2b584400 | |||
d31e92bbe7 | |||
08cd944e5d | |||
dbb579aa73 | |||
bc0598c0f1 | |||
f87b745771 | |||
8d43faf16e | |||
f00e7ccb54 | |||
7b5e5832cb | |||
dd6abff712 | |||
7e1bdd474a | |||
e31333edd4 | |||
c052ee5847 | |||
f8c2eb8c3a | |||
94d78ca554 | |||
c7fdbea0f0 | |||
a19996a7cf | |||
9311b4f248 | |||
295d9bc80b | |||
3a044f0154 | |||
adb7df212c | |||
9e92a350e3 | |||
005c2419e9 | |||
d823ff18d8 | |||
9b47aed0ab | |||
55598ba703 | |||
425686755b | |||
6676029319 | |||
e008a3cd5e | |||
5aed0fb0d5 | |||
d0faf3df91 | |||
564b50ea33 | |||
ea0f291cb5 | |||
56990eb28b | |||
477cb77002 | |||
93896977d0 | |||
554816b8b6 | |||
fc5fa01442 | |||
f204422432 | |||
d6d3184e37 | |||
c569fd86b1 | |||
e33eb0ddb6 | |||
0a8bd72e11 | |||
4ee8d14584 | |||
663cb514e2 | |||
15f098074a | |||
8bf3b6bbea | |||
eb13cec5d0 | |||
0cd1e82c52 | |||
1ee689e759 | |||
d25c8d93ca | |||
4fbc5738e3 | |||
d588222e84 | |||
c3fb2e9f23 | |||
cfb6856634 | |||
11e0387e19 | |||
dc7b5b14d5 | |||
5eab956da6 | |||
ad88ca09bd | |||
f98a964cdc | |||
99995579d7 | |||
4ae18526d1 | |||
282095513a | |||
c21197ef17 | |||
0a8826b21f | |||
dac6c49bce | |||
9f7dc32650 | |||
9195375af4 | |||
c6cf3458de | |||
e2cdd9eddc | |||
f933107af0 | |||
408f63f8fa | |||
68998bac48 | |||
2ff565afe5 | |||
20c7e51077 | |||
89216c3bd4 | |||
834dc343b0 | |||
91907485b4 | |||
ee523eb5cc | |||
f2f51a88e5 | |||
abffe1297d | |||
f8b9a13440 | |||
5c281c6435 | |||
1908ed5812 | |||
2d5567d9dd | |||
b3beb9f71d | |||
14a0ff5caa | |||
119e458ac8 | |||
01a07a0b09 | |||
903534572d | |||
8a3c30ee7e | |||
91fd99d76a | |||
27f2aec160 | |||
8f9c52507a | |||
5a12f40074 | |||
b89a17ffe2 | |||
6dc6e32656 | |||
d430ad50be | |||
06de85fd33 | |||
ffadc34691 | |||
f5e39ea9ad | |||
595fffc432 | |||
c4d0fdb436 | |||
2a4fb93a92 | |||
50bf671c28 | |||
4a2b83ab47 | |||
f332d3647c | |||
0c35c16727 | |||
7c8586684e | |||
6999388dd1 | |||
662652f745 | |||
987d492c1c | |||
80920a1673 | |||
613226c661 | |||
06dd410340 | |||
cf83143bbd | |||
28baae8154 | |||
7701555005 | |||
38937fc4cc | |||
bf6e8db941 | |||
06c399fa05 | |||
82cf38d46c | |||
eb1ec2df05 | |||
17102058ca | |||
f881cea8e0 | |||
8beefabbbc | |||
4cca3b866a | |||
0535acf211 | |||
478a62e17b | |||
9661d845bb | |||
69d6d24a38 | |||
713ee753e4 | |||
740a8ad436 | |||
ccef0455ab | |||
755f4d232f | |||
09a6776674 | |||
661f17b6e0 | |||
77456702e9 | |||
75a38699e2 | |||
9c36e0cd1c | |||
21f5be27b6 | |||
4dd0a13511 | |||
904c52bb0f | |||
3ab9722a9f | |||
08ed2cd353 | |||
06f0534d65 | |||
b22232730e | |||
50b9034e16 | |||
8bf8e2e22f | |||
52748fcf64 | |||
19572b8c51 | |||
496061ba54 | |||
2488d6e957 | |||
8ea03524ff | |||
e4aa3d72fe | |||
26fc21d56c | |||
e4c889ae16 | |||
7de7593b89 | |||
162b993e65 | |||
cb187be1a1 | |||
ab943a0462 | |||
2290c33143 | |||
9869aaa46a | |||
bcf049a660 | |||
0114cb8399 | |||
b72218ac5b | |||
6b9c2b961b | |||
8ba0b49022 | |||
74c9ed04a0 | |||
b28e38ab26 | |||
4577f3ee22 | |||
3b82a5fddf | |||
2d3b8845fd | |||
9004417456 | |||
946d301bc7 | |||
39c3b16e49 | |||
3daa2723bf | |||
085d1a1359 | |||
3bbf2c245a | |||
8f797442b3 | |||
57f3f9b4ed | |||
058468104a | |||
b566c4e609 | |||
0428894cc6 | |||
41d36e4e7a | |||
4bf8f00b0f | |||
6e87a48100 | |||
441961b199 | |||
92b85e0f15 | |||
6fbb9b6083 | |||
67940ad6ab | |||
0a3fd8737a | |||
8902992473 | |||
2e865a3af9 | |||
ed13f7f8e7 | |||
02ddcef24e | |||
3c9db45cf8 | |||
16e7eaaaa4 | |||
4ace4b9542 | |||
86dc8c48b9 | |||
aaf549a469 | |||
ad0553fbf8 | |||
d8908676ac | |||
598e7aac8f | |||
07f18d8f6c | |||
1cb96d24ce | |||
40600be4c1 | |||
096836faaa | |||
b68df2da5c | |||
e2dc1a3bc6 | |||
8a29e77f5e | |||
0bd7ea211d | |||
55791e0819 | |||
69369c8998 | |||
c36fc8c027 | |||
7e15c6638a | |||
88e36eda59 | |||
40d1394e3c | |||
69061ba4ad | |||
e85d6d134e | |||
0e10a149ef | |||
736ec6edac | |||
25b9581254 | |||
b263d81baf | |||
0c3780de40 | |||
850afed2c6 | |||
efc6d429f6 | |||
b082bec150 | |||
2e1f572356 | |||
18ebc64ea0 | |||
4f4bdea104 | |||
c556ec84a2 | |||
a3a07ca847 | |||
227e1c42ea | |||
cb55cefa44 | |||
10c8632417 | |||
942b35ee4c | |||
440d66bd59 | |||
747aae94ec | |||
6d2a57f83a | |||
a63020d6e5 | |||
e2bbb76900 | |||
f180167955 | |||
1eaf7c5431 | |||
3672d60bf4 | |||
7e1557dc94 | |||
3848f6f39c | |||
00158d4805 | |||
3dcfa7b3ce | |||
acd141e5aa | |||
8ee3723588 | |||
29c27993ad | |||
8bdfe0d297 | |||
669af6f7b3 | |||
f4065dd411 | |||
a99d7f93d9 | |||
363b24c663 | |||
9e938baea0 | |||
fb0c8c2c97 | |||
772abc609d | |||
5feff79875 | |||
7190f6a4ca | |||
6a066cdf31 | |||
77b3cd71a3 | |||
5443b10257 | |||
300a3d5ccd | |||
17a418f133 | |||
e2b143a7cf | |||
a1c3ca18ce | |||
8c772fe671 | |||
c4d4277a6c | |||
2987c7a80c | |||
4063bc4ffb | |||
90957cd908 | |||
50d59619a6 | |||
8db4b7116c | |||
4b21e35d6e | |||
76a1165c0e | |||
35fbf78a77 | |||
b86185519a | |||
3433a931c1 | |||
d9eb767420 | |||
71704228a9 | |||
a122ea9e75 | |||
a8694dcbf7 | |||
1ec83420c8 | |||
bb7263beac | |||
d84f990574 | |||
61e8828f94 | |||
aa8a13c4a3 | |||
0380c78926 | |||
2930cf80b4 | |||
5ce6c6227f | |||
5dca11dafb | |||
252d1988dc | |||
bd722bb85f | |||
e1253db37c | |||
175dd0efa6 | |||
146f5a567f | |||
e790573f2e | |||
6ea45c5c4a | |||
544d99f161 | |||
42b78cfba2 | |||
99e8bcf26b | |||
6224f0cdf6 | |||
5e6d452678 | |||
ae6e0773ef | |||
cc9736314e | |||
adabd7ef65 | |||
5d16ecc003 | |||
288bf0fe6c | |||
e92052c2ab | |||
25560a52b0 | |||
d625a20934 | |||
a0cda3b45a | |||
d74486a64a | |||
aafe0c4f69 | |||
4674d34469 | |||
43b3b41039 | |||
d37afde0dc | |||
fecbdc5ff2 | |||
4d121f7d84 | |||
6a8976c534 | |||
74e31fe712 | |||
28c3a882f8 | |||
ebd2830770 | |||
2e540300d8 | |||
fb74d93e00 | |||
6696b7ed52 | |||
35b3259053 | |||
577dbbce1f | |||
ce289cbe25 | |||
756760a2f0 | |||
d6629d6843 | |||
43a36dba40 | |||
5025b4aba1 | |||
dd01407dd4 | |||
d70be232d8 | |||
ecabe945e6 | |||
2b46794ca2 | |||
0be8fa4157 | |||
b1ce19856f | |||
252afde06f | |||
039d6a488a | |||
15f7cfb4f7 | |||
4c49db6036 | |||
60260a294b | |||
18c0567944 | |||
367fa41161 | |||
439f418b0d | |||
fa5624f87e | |||
c79077cbed | |||
995d0847f9 | |||
aa713c4e4a | |||
3b3abab3ad | |||
5f5f71cfbe | |||
363431dac2 | |||
1b543b2c16 | |||
763ef7f937 | |||
e51a2725de | |||
a0111d04ee | |||
958473b333 | |||
744f5a8384 | |||
fe348b0a9d | |||
8d842732e0 | |||
bee342691d | |||
36623d8a5b | |||
7eb9530346 | |||
bd85d53a0b | |||
ac37af3a46 | |||
208884422d | |||
da23568546 | |||
f0f6d85809 | |||
92bd1a755d | |||
3ee43c5a17 | |||
8ced6547f2 | |||
d29e96407e | |||
8214e50bcc | |||
802bc21c53 | |||
25b51b4dfd | |||
794ff643a7 | |||
37ae760417 | |||
ab4d6b1e36 | |||
383df298a6 | |||
7314aaf7f7 | |||
75fa2f1132 | |||
d5881dbe83 | |||
8404ce88bd | |||
7861822a0f | |||
e6485c4734 | |||
bd5bbbea10 | |||
0ac04b52ff | |||
2d37d361a7 | |||
d696049a0a | |||
1d876e30c8 | |||
ea7313779e | |||
5a8008367f | |||
911529a6cc | |||
bee6c546dc | |||
e3c900e071 | |||
e50311f1ea | |||
0bdb8a46f7 | |||
074583d104 | |||
3b7377370c | |||
1ac74fe5bc | |||
c494af618c | |||
557257baed | |||
75cc99a003 | |||
7dc839fbe8 | |||
d3fb8c46f5 | |||
fffa5488fd | |||
e60364d7c9 | |||
cf222324d6 | |||
d3c62988b0 | |||
b34d438ed9 | |||
f50c63a0c2 | |||
d1f59632c2 | |||
03003ffa50 | |||
7a1cdf88e8 | |||
4856dbd1c6 | |||
16d07e1f3d | |||
daed82612c | |||
16d72c7f86 | |||
ce5fa0e836 | |||
dc07fc42b4 | |||
fdf3c0c1c7 | |||
656ec60805 | |||
293af3d55d | |||
0ce25f8b29 | |||
06f8390b30 | |||
55ad6c6b95 | |||
46af92f781 | |||
2765e87677 | |||
5df916099d | |||
137972098f | |||
3d2f9f0e74 | |||
9d16f145dd | |||
ae1501884b | |||
5234327b3f | |||
689a052bda | |||
813bb98850 | |||
d9e6676176 | |||
bfc77a772a | |||
6bcb3aeb26 | |||
0f8a6481c6 | |||
db3e801478 | |||
0f261b7baa | |||
6c1dd81130 | |||
eed8c37eab | |||
6e0cebbe38 | |||
902dd4258b | |||
ce72f634b0 | |||
2dfca14714 | |||
2ffbb452bb | |||
468b3e8d44 | |||
035084a5ac | |||
869721a8ee | |||
787f6594b2 | |||
867ec6b509 | |||
b6e1a21566 | |||
694c9b151f | |||
ed69303b4a | |||
192fba9c88 | |||
018897062c | |||
b198f287db | |||
750462aa75 | |||
b1df4728d3 | |||
5eb2459355 | |||
1120dff492 | |||
bd1b18d9af | |||
01d465b038 | |||
d6fcc59a49 | |||
a45e232829 | |||
9497dff3ee | |||
df88e9272e | |||
ec328a8160 | |||
7cd7a7fbf6 | |||
9a12aa689e | |||
39ffc28f2a | |||
9242f89221 | |||
e35ed7f04a | |||
08f11412a4 | |||
2bb50792c3 | |||
85c50731f8 | |||
ff40c0a070 | |||
8f9574dec5 | |||
86ed0f1397 | |||
affed33066 | |||
9cde63a327 | |||
401de97719 | |||
dd0c5efb56 | |||
bb9ab525b6 | |||
8053066ac0 | |||
88d14e9923 | |||
702ab53e69 | |||
0163555d3e | |||
1c41667b9b | |||
c2299b521f | |||
3692ddab1d | |||
3ddfb97921 | |||
e7e476b65e | |||
f3f853056a | |||
bcc641a25a | |||
ebcc16d283 | |||
4bc2275fc3 | |||
ef7a843fa3 | |||
10698c892e | |||
43842691fe | |||
8637a04e2b | |||
d53810c6bc | |||
f3e35bb94a | |||
707847b46e | |||
e81c738010 | |||
8f3b95164a | |||
19601f998a | |||
2fba1073dd | |||
6b06e407c6 | |||
0b270342b1 | |||
23e4ca64e4 | |||
36207debe0 | |||
de28ddabdb | |||
c328d7359c | |||
5e72850a62 | |||
a9cbe4f63e | |||
beabc5a85c | |||
2a07638af3 | |||
d6fd9259cf | |||
16c09e3610 | |||
b78dd70f72 | |||
92784054cd | |||
98ea674d20 | |||
4b869c8615 | |||
ec79477b3e | |||
58ff381557 | |||
2b6d058760 | |||
535e1a0eb4 | |||
4133f98b23 | |||
d7a78ee00f | |||
e913b16804 | |||
6fc435da0e | |||
84e15b6b1a | |||
e9f2bf0085 | |||
5f26c21b9f | |||
ee4854d07c | |||
9a379734ba | |||
a7366324e5 | |||
39f731aa06 | |||
7c41aa66f1 | |||
98d129f1f4 | |||
99622c5ce7 | |||
ad64a074cb | |||
23f3097390 | |||
abf004de7d | |||
ff4b7612a6 | |||
2d95bdc10f | |||
50c5c1de92 | |||
e2e31d345d | |||
7145e16bce | |||
5485b63e6e | |||
f2f70480ee | |||
900c4adb66 | |||
5f8dc5829c | |||
e962f7fb0a | |||
a3e3a5f631 | |||
b156480550 | |||
7b8548b2b1 | |||
fbe17344fb | |||
e143fb80da | |||
795d6c8ddf | |||
6bd028f8b3 | |||
35c33ba980 | |||
895790f46c | |||
378c3d7994 | |||
9808f874c8 | |||
4198c445b0 | |||
42e8120961 | |||
2a4f85107d | |||
97f6b80969 | |||
a6f8379c40 | |||
bf4b96e144 | |||
4f26e5598c | |||
e00176b677 | |||
f32d588b9b | |||
f14a8e46be | |||
5851e7fe55 | |||
8e9a078ff9 | |||
b16f7e4dd5 | |||
15b9578245 | |||
765bd5ced7 | |||
df4c3ec4a6 | |||
d6e343c2cf |
6
.editorconfig
Normal file
6
.editorconfig
Normal file
@ -0,0 +1,6 @@
|
||||
# http://editorconfig.org/
|
||||
root = yes
|
||||
|
||||
[*]
|
||||
indent_size = 4
|
||||
indent_style = tab
|
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -6,6 +6,7 @@
|
||||
*.properties text eol=lf
|
||||
*.bat text eol=crlf
|
||||
*.cmd text eol=crlf
|
||||
*.ps1 text eol=crlf
|
||||
|
||||
# Custom for Visual Studio
|
||||
*.cs diff=csharp
|
||||
|
37
.github/ISSUE_TEMPLATE.md
vendored
37
.github/ISSUE_TEMPLATE.md
vendored
@ -1,18 +1,47 @@
|
||||
### Issue description
|
||||
<!--- use our forum https://forums.pocketmine.net for questions -->
|
||||
<!---
|
||||
THIS ISSUE TRACKER IS FOR BUG REPORTING, NOT FOR HELP & SUPPORT. If you need help, use the links below.
|
||||
- http://pmmp.readthedocs.io/en/rtfd/ - Documentation
|
||||
- https://forums.pmmp.io - PMMP Forums
|
||||
-->
|
||||
<!--- Any issues requesting updates to new versions of MCPE will be treated as spam. We do not need issues to tell us that there is a new version available. -->
|
||||
<!---
|
||||
Write a short description about the issue
|
||||
|
||||
If you are reporting a regression or unexpected behaviour, please include the below information:
|
||||
Expected result: What were you expecting to happen?
|
||||
Actual result: What actually happened?
|
||||
-->
|
||||
|
||||
### Steps to reproduce the issue
|
||||
<!--- help us find the problem by adding steps to reproduce the issue -->
|
||||
1. ...
|
||||
2. ...
|
||||
|
||||
### OS and versions
|
||||
<!--- use the 'version' command in PocketMine-MP -->
|
||||
<!--- use the 'version' command in PocketMine-MP
|
||||
|
||||
NOTE: LATEST is not a valid version. PocketMine version should include Jenkins build number and/or git commit hash.
|
||||
|
||||
NO support whatsoever will be provided for forks or spoons of PocketMine. Issues relating to non-official distributions will be closed as spam. Please send such issues to whoever is responsible for the fork or spoon you are using.
|
||||
|
||||
Note that 32-bit platforms are no longer supported by PocketMine-MP and issues concerning 32-bit platforms will be closed.
|
||||
-->
|
||||
* PocketMine-MP:
|
||||
* PHP:
|
||||
* OS:
|
||||
* Server OS:
|
||||
* Game version: PE/Win10 (delete as appropriate)
|
||||
|
||||
### Plugins
|
||||
- Test on a clean server without plugins: is the issue reproducible without any plugins loaded?
|
||||
|
||||
If the issue is **not** reproducible without plugins:
|
||||
- Have you asked for help on our forums before creating an issue?
|
||||
- Can you provide sample, *minimal* reproducing code for the issue? If so, paste it in the bottom section
|
||||
- Paste your list of plugins here (use the 'plugins' command in PocketMine-MP)
|
||||
|
||||
### Crashdump, backtrace or other files
|
||||
<!--- please use gist or anything else and add links here -->
|
||||
- Do not paste crashdumps into an issue - please use our Crash Archive at https://crash.pmmp.io for submitting crash reports to not spam the issue tracker. Add links to your reports in the Crash Archive here.
|
||||
- Please use gist or anything else to add other files and add links here
|
||||
|
||||
* ...
|
||||
|
36
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
36
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
## Introduction
|
||||
<!-- Explain existing problems or why this pull request is necessary -->
|
||||
|
||||
### Relevant issues
|
||||
<!-- List relevant issues here -->
|
||||
<!--
|
||||
|
||||
* Fixes #1
|
||||
* Fixes #2
|
||||
|
||||
-->
|
||||
|
||||
## Changes
|
||||
### API changes
|
||||
<!-- Any additions to the API that should be documented in release notes? -->
|
||||
|
||||
### Behavioural changes
|
||||
<!-- Any change in how the server behaves, or its performance? -->
|
||||
|
||||
## Backwards compatibility
|
||||
<!-- Any possible backwards incompatible changes? How are they solved, or how can they be solved? -->
|
||||
|
||||
## Follow-up
|
||||
<!-- Suggest any actions to be done before/after merging this pull request -->
|
||||
<!--
|
||||
|
||||
Requires translations:
|
||||
|
||||
| Name | Value in eng.ini |
|
||||
| :--: | :---: |
|
||||
| `foo.bar` | `Foo bar` |
|
||||
|
||||
-->
|
||||
|
||||
## Tests
|
||||
<!-- Attach scripts or actions to test this pull request, as well as the result -->
|
6
.gitignore
vendored
6
.gitignore
vendored
@ -8,9 +8,11 @@ timings/*
|
||||
*.phar
|
||||
server.properties
|
||||
/pocketmine.yml
|
||||
memoryDump_*/*
|
||||
resource_packs/
|
||||
|
||||
# Common IDEs
|
||||
.idea/*
|
||||
.idea/
|
||||
nbproject/*
|
||||
|
||||
# Windows image file caches
|
||||
@ -26,3 +28,5 @@ Desktop.ini
|
||||
# Sphinx-doc
|
||||
/docs/build/
|
||||
!/docs/requirements.txt
|
||||
|
||||
vendor/*
|
||||
|
22
.gitmodules
vendored
22
.gitmodules
vendored
@ -1,17 +1,19 @@
|
||||
[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
|
||||
url = https://github.com/pmmp/RakLib.git
|
||||
branch = master
|
||||
[submodule "src/spl"]
|
||||
path = src/spl
|
||||
url = https://github.com/PocketMine/PocketMine-SPL.git
|
||||
[submodule "tests/TesterPlugin"]
|
||||
path = tests/TesterPlugin
|
||||
url = https://github.com/PocketMine/TesterPlugin.git
|
||||
url = https://github.com/pmmp/PocketMine-SPL.git
|
||||
[submodule "src/pocketmine/lang/locale"]
|
||||
path = src/pocketmine/lang/locale
|
||||
url = https://github.com/PocketMine/PocketMine-Language.git
|
||||
url = https://github.com/pmmp/PocketMine-Language.git
|
||||
[submodule "tests/preprocessor"]
|
||||
path = tests/preprocessor
|
||||
url = https://github.com/pmmp/preprocessor.git
|
||||
[submodule "tests/plugins/PocketMine-DevTools"]
|
||||
path = tests/plugins/PocketMine-DevTools
|
||||
url = https://github.com/pmmp/PocketMine-DevTools.git
|
||||
[submodule "tests/plugins/PocketMine-TesterPlugin"]
|
||||
path = tests/plugins/PocketMine-TesterPlugin
|
||||
url = https://github.com/pmmp/PocketMine-TesterPlugin.git
|
||||
|
5
.mailmap
5
.mailmap
@ -1,5 +0,0 @@
|
||||
Shoghi Cervantes <shoghicp@gmail.com>
|
||||
Shoghi Cervantes <shoghicp@gmail.com> Shoghi Cervantes <shoghicp@pocketmine.net>
|
||||
Brandon V <brandon15811@gmail.com>
|
||||
Michael Yoo <sekjun9878@gmail.com> Michael Yoo <michael@yoo.id.au>
|
||||
Michael Yoo <sekjun9878@gmail.com> Michael Yoo <sekjun9878@sekjun9878.info>
|
25
.travis.yml
25
.travis.yml
@ -1,21 +1,24 @@
|
||||
language: php
|
||||
|
||||
php:
|
||||
- 7.0
|
||||
|
||||
branches:
|
||||
- master
|
||||
- 7.2
|
||||
|
||||
before_script:
|
||||
- mkdir plugins
|
||||
- wget -O plugins/DevTools.phar https://github.com/PocketMine/DevTools/releases/download/v1.11.0/DevTools_v1.11.0.phar
|
||||
- pecl install channel://pecl.php.net/pthreads-3.1.6
|
||||
- pecl install channel://pecl.php.net/weakref-0.3.2
|
||||
- echo | pecl install channel://pecl.php.net/yaml-2.0.0RC7
|
||||
# - pecl install channel://pecl.php.net/pthreads-3.1.6
|
||||
- echo | pecl install channel://pecl.php.net/yaml-2.0.2
|
||||
- git clone https://github.com/krakjoe/pthreads.git
|
||||
- cd pthreads
|
||||
- git checkout 6c6b15138c923b69cfa46ee05fc2dd45da587287
|
||||
- phpize
|
||||
- ./configure
|
||||
- make
|
||||
- make install
|
||||
- cd ..
|
||||
- echo "extension=pthreads.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
|
||||
- composer install
|
||||
|
||||
script:
|
||||
- php tests/TravisTest.php
|
||||
- ./tests/travis.sh
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
#webhooks: http://n.tkte.ch/h/214/wsNvmG43-ncxUVRrFPwSM-r0
|
||||
|
174
CONTRIBUTING.md
174
CONTRIBUTING.md
@ -2,63 +2,109 @@
|
||||
|
||||
# PocketMine-MP Contribution Guidelines
|
||||
|
||||
You must follow these guidelines if you wish to contribute to the PocketMine-MP code base, or participate in issue tracking.
|
||||
|
||||
## 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 immediate reply.
|
||||
* You may use our [Forum](http://forums.pocketmine.net) to ask questions.
|
||||
* We do not accept questions or support requests in our issue tracker.
|
||||
|
||||
## 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.
|
||||
- Information must be provided in the issue body, not in the title. No tags are allowed in the title, and do not change the title if the issue has been solved.
|
||||
- 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.
|
||||
- To express appreciation, objection, confusion or other supported reactions on pull requests, issues or comments on them, use GitHub [reactions](https://github.com/blog/2119-add-reactions-to-pull-requests-issues-and-comments) rather than posting an individual comment with an emoji only. This helps keeping the issue/pull rqeuest conversation clean and readable.
|
||||
- If you are reporting a bug:
|
||||
- **make sure that you are using the latest supported version** before opening an issue.
|
||||
- **test it on a clean test server, WITHOUT PLUGINS**, to see if the issue still occurs. If not then it may be a plugin issue. Please also indicate the result of such tests.
|
||||
|
||||
- [Search the issue tracker](https://github.com/pmmp/PocketMine-MP/issues?utf8=%E2%9C%93&q=is%3Aissue) to check if anyone has already reported it, to avoid needlessly creating duplicate issues. Make sure you also check closed issues, as an issue you think is valid may already have been resolved.
|
||||
|
||||
- If your issue is related to a plugin, **do not report here, contact the plugin's original author** instead.
|
||||
|
||||
- **Support requests are not bugs.** Issues such as "How do I do this" are not bugs and will be closed. If you need help, please see [here](README.md#discussion) and do not misuse our issue tracker.
|
||||
|
||||
- **No generic titles** such as "Question", "Help", "Crash Report" etc. A good issue report provides a quick summary in the title. If you just got a crash report but you don't understand it, please look for a line starting with `Message`. It summarizes the bug.
|
||||
|
||||
- Information must be provided in the issue body, not in the title. No tags like `[BUG]` are allowed in the title, including `[SOLVED]` for solved issues.
|
||||
|
||||
- Similarly, no generic issue reports. For bugs, it is the issue author's responsibility to provide us an issue that is **trackable, debuggable, reproducible, reported professionally and is an actual bug**.
|
||||
<br><br>Valid issue reports must include instructions how to reproduce the issue or a crashdump/backtrace (unless the cause of the issue is obvious).
|
||||
<br><br>**If you do not provide us with a summary or instructions on how to reproduce the issue, it will be treated as spam and will therefore be closed.**
|
||||
<br><br>In simple words, if the issue cannot be properly confirmed to be valid or lacks required information, the issue will be closed until further information is provided.
|
||||
|
||||
- To express appreciation, objection, confusion or other supported reactions on pull requests, issues or comments on them, use GitHub [reactions](https://github.com/blog/2119-add-reactions-to-pull-requests-issues-and-comments) rather than posting an individual comment with an emoji only. This helps keeping the issue/pull request conversation clean and readable.
|
||||
|
||||
- If your issue is related to the PocketMine-MP website, forums, etc., please [talk to a human directly](README.md#discussion).
|
||||
|
||||
|
||||
|
||||
## 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__
|
||||
* Code using the syntax as in PocketMine-MP. See below for an example.
|
||||
* The code must be clear and written in English, comments included.
|
||||
* Use descriptive commit titles
|
||||
* __No merge commits are allowed, or multiple features per pull request__
|
||||
- To contribute code to the repository, [fork it on GitHub](https://github.com/pmmp/PocketMine-MP/fork), create a branch on your fork, and make your changes on your fork. You can then make a [pull request](https://github.com/pmmp/PocketMine-MP/pull/new) to the project to compare your branch to ours and propose your changes to our repository. We use the Pull Request system to allow members of the team to review changes before they are merged.
|
||||
|
||||
- By proposing a pull request to the project, you agree to your code being distributed within PocketMine-MP under the [LGPL license](LICENSE).
|
||||
|
||||
- At PocketMine, **we enforce a very high standard for contributions**. This is because PocketMine-MP and its related projects are used very widely in production. While this might seem like we are being mean at times, **our priority is what is best for PocketMine-MP itself**. We try to ensure that our project's codebase is as clean as possible and ensure that only top-quality material makes it through to PocketMine-MP itself. **If a contribution does not live up to our standards, changes may be requested or the pull request may be closed.**
|
||||
|
||||
- **Your pull request will be checked and discussed in due time.** Since the team is scattered all around the world, your PR may not receive any attention for some time.
|
||||
|
||||
- **Avoid using GitHub Web Editor**. The web editor lacks most useful GIT features and **should only be used for very minor changes**. It is immediately clear if the web editor has been used, and if so the PR is more likely to be rejected. If you want to make serious contributions, **please learn how to use [GIT version control](https://git-scm.com/)**.
|
||||
|
||||
- **Do not copy-paste code**. There are potential license issues implicit with copy-pasting, and copy-paste usually indicates a lack of understanding of the actual code. Copy-pasted code is obvious a mile off and **any PR like this is likely to be closed**. If you want to use somebody else's code from a Git repository, **use [GIT's cherry-pick feature](https://git-scm.com/docs/git-cherry-pick)** to cherry-pick the commit. **Cherry-picking is the politer way to copy somebody's changes** and retains all the original accreditation, so there is no need for copy-pasted commits with descriptions like `Some code, thanks @exampleperson`.
|
||||
|
||||
- In addition to the above, **make sure you can explain your changes**. If you can't provide a good explanation of changes, your PR may be rejected.
|
||||
|
||||
- **Create a new branch for each pull request.** Do not create a pull request with commits that exist in another pull request.
|
||||
|
||||
- **Code should use the same style as in PocketMine-MP.** See [below](#code-syntax) for an example.
|
||||
|
||||
- **The code must be clear** and written in English, comments included.
|
||||
|
||||
- **Use descriptive commit titles.** You can see an example [here](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
|
||||
|
||||
- **Try to stick to one change per commit.** This ensures that if you create a PR with several changes, we can decide which ones we wish to include and which ones not to include.
|
||||
|
||||
- **It is inadvisable to create pull requests with large commits** unless this has been discussed with the team beforehand. Large pull requests are difficult to review, and such pull requests may end up being closed. The only exception is when all features in the pull request are related to each other, and share the same core changes.
|
||||
|
||||
- **You may be asked to rebase your pull request** if the branch becomes outdated and/or if possibly conflicting changes are made to the target branch. To see how to do this, read [this page](https://github.com/edx/edx-platform/wiki/How-to-Rebase-a-Pull-Request).
|
||||
|
||||
|
||||
**Thanks for contributing to PocketMine-MP!**
|
||||
|
||||
|
||||
|
||||
### 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, and MUST NOT have spaces before.
|
||||
* `else if` MUST be written as `elseif`. _(It is in PSR-2, but using a SHOULD)_
|
||||
* Control structure keywords or opening braces MUST NOT have one space before or after them.
|
||||
* Code MUST use tabs for indenting.
|
||||
* Long arrays MAY be split across multiple lines, where each subsequent line is indented once.
|
||||
* Files MUST use only the `<?php` tag.
|
||||
* Files MUST NOT have an ending `?>` tag.
|
||||
* Code MUST use namespaces.
|
||||
* Strings SHOULD use the double quote `"` except when the single quote is required.
|
||||
|
||||
- Opening braces MUST go on the same line, and MUST NOT have spaces before.
|
||||
- `else if` MUST be written as `elseif`. _(It is in PSR-2, but using a SHOULD)_
|
||||
- Control structure keywords or opening braces MUST NOT have one space before or after them.
|
||||
- Code MUST use tabs for indenting.
|
||||
- Long arrays MAY be split across multiple lines, where each subsequent line is indented once.
|
||||
- Files MUST use only the `<?php` tag.
|
||||
- Files MUST NOT have an ending `?>` tag.
|
||||
- Code MUST use namespaces.
|
||||
- Strings SHOULD use the double quote `"` except when the single quote is required.
|
||||
- All code SHOULD have parameter and type declarations where possible.
|
||||
- Strict types SHOULD be enabled on new files where it is sensible to do so.
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace pocketmine\example;
|
||||
|
||||
class ExampleClass{
|
||||
|
||||
const EXAMPLE_CLASS_CONSTANT = 1;
|
||||
|
||||
public $examplePublicVariable = "defaultValue";
|
||||
private $examplePrivateVariable;
|
||||
|
||||
public function __construct($firstArgument, &$secondArgument = null){
|
||||
if($firstArgument === "exampleValue"){ //Remember to use === instead == when possible
|
||||
/**
|
||||
* Creates an instance of ExampleClass
|
||||
*
|
||||
* @param string $firstArgument the first argument
|
||||
* @param string|null $secondArgument default null
|
||||
*/
|
||||
public function __construct(string $firstArgument, &$secondArgument = null){
|
||||
if($firstArgument === "exampleValue"){ //Remember to use === instead of == when possible
|
||||
//do things
|
||||
}elseif($firstArgument === "otherValue"){
|
||||
$secondArgument = function(){
|
||||
return [
|
||||
$this->examplePrivateVariable = [
|
||||
0 => "value1",
|
||||
1 => "value2",
|
||||
2 => "value3",
|
||||
@ -66,13 +112,18 @@ class ExampleClass{
|
||||
4 => "value5",
|
||||
5 => "value6",
|
||||
];
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public function doStuff(string $stuff) : string{
|
||||
return $stuff;
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
<!-- TODO: RFC and voting on the forums instead -->
|
||||
### RFC and Voting
|
||||
* These are big Pull Requests or contributions that change important behavior.
|
||||
* RFCs will be tagged with the *PR: RFC* label
|
||||
@ -83,58 +134,3 @@ class ExampleClass{
|
||||
* An RFC will be rejected if less than 50% + 1 (simple majority) has voted Yes.
|
||||
* If the RFC is approved, Team Members have the final word on its implementation or rejection.
|
||||
* RFCs with complex voting options will specify the vote percentage or other details.
|
||||
|
||||
|
||||
## 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.
|
||||
- PR: RFC - Request for Comments
|
||||
|
||||
#### 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 beta2
|
||||
```
|
||||
|
82
README.md
82
README.md
@ -1,6 +1,43 @@
|
||||
# 
|
||||
[](https://travis-ci.org/PocketMine/PocketMine-MP)
|
||||
# [](https://pmmp.io)
|
||||
|
||||
__A highly customisable, open source server software for Minecraft: Pocket Edition written in PHP__
|
||||
|
||||
[](https://travis-ci.org/pmmp/PocketMine-MP)
|
||||
|
||||
### Setup, help & support, FAQs
|
||||
Head over to the [documentation site](http://pmmp.readthedocs.org/).
|
||||
If you don't find what you're looking for there, [talk to a human](#discussion). Please do not use our issue tracker for support requests.
|
||||
|
||||
### Discussion
|
||||
- [Forums](https://forums.pmmp.io/)
|
||||
- [#pmmp + #pocketmine channel IRC](http://webchat.freenode.net/?channels=pmmp,pocketmine)
|
||||
|
||||
### Plugins
|
||||
There are a very wide range of already-written plugins available which you can use to customise your server. Check out [Poggit](https://poggit.pmmp.io), or just search GitHub.
|
||||
|
||||
### For developers
|
||||
* [Latest API documentation](https://jenkins.pmmp.io/job/PocketMine-MP-doc/doxygen/) - Doxygen documentation generated from development
|
||||
* [DevTools](https://github.com/pmmp/PocketMine-DevTools/) - A development tools plugin for creating plugins.
|
||||
|
||||
### Can I contribute?
|
||||
Yes you can! Contributions are welcomed provided that they comply with our [Contributing Guidelines](CONTRIBUTING.md). Please ensure you read the relevant sections of the guidelines carefully before making a Pull Request or opening an Issue.
|
||||
|
||||
### Where can I get the latest .phar?
|
||||
Head over to our [official Jenkins server](https://jenkins.pmmp.io/)
|
||||
|
||||
## Third-party Libraries/Protocols Used
|
||||
* __[PHP Sockets](http://php.net/manual/en/book.sockets.php)__
|
||||
* __[PHP mbstring](http://php.net/manual/en/book.mbstring.php)__
|
||||
* __[PHP BCMath](http://php.net/manual/en/book.bc.php)__
|
||||
* __[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.
|
||||
* __[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)__
|
||||
* __[UT3 Query Protocol](http://wiki.unrealadmin.org/UT3_query_protocol)__
|
||||
|
||||
## Licensing information
|
||||
|
||||
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
|
||||
@ -15,43 +52,4 @@
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
__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/)
|
||||
|
||||
### [Documentation](http://pocketmine-mp.readthedocs.org/)
|
||||
|
||||
### [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
|
||||
* [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
|
||||
[#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)__
|
||||
* __[PHP mbstring](http://php.net/manual/en/book.mbstring.php)__
|
||||
* __[PHP SQLite3](http://php.net/manual/en/book.sqlite3.php)__
|
||||
* __[PHP BCMath](http://php.net/manual/en/book.bc.php)__
|
||||
* __[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.
|
||||
* __[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)__
|
||||
* __[UT3 Query Protocol](http://wiki.unrealadmin.org/UT3_query_protocol)__
|
||||
pmmp/PocketMine are not affiliated with Mojang. All brands and trademarks belong to their respective owners. PocketMine-MP is not a Mojang-approved software, nor is it associated with Mojang.
|
||||
|
33
composer.json
Normal file
33
composer.json
Normal file
@ -0,0 +1,33 @@
|
||||
{
|
||||
"name": "pmmp/pocketmine-mp",
|
||||
"description": "A server software for Minecraft: Pocket Edition written in PHP",
|
||||
"type": "project",
|
||||
"homepage": "https://pmmp.io",
|
||||
"license": "LGPL-3.0",
|
||||
"require": {
|
||||
"php": ">=7.2",
|
||||
"ext-bcmath": "*",
|
||||
"ext-curl": "*",
|
||||
"ext-hash": "*",
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-openssl": "*",
|
||||
"ext-pcre": "*",
|
||||
"ext-phar": "*",
|
||||
"ext-pthreads": ">=3.1.7dev",
|
||||
"ext-reflection": "*",
|
||||
"ext-sockets": "*",
|
||||
"ext-spl": "*",
|
||||
"ext-yaml": ">=2.0.0",
|
||||
"ext-zip": "*",
|
||||
"ext-zlib": ">=1.2.11"
|
||||
},
|
||||
"autoload": {
|
||||
"exclude-from-classmap": [
|
||||
"src/spl/stubs"
|
||||
],
|
||||
"psr-0": {
|
||||
"": ["src", "src/spl"]
|
||||
}
|
||||
}
|
||||
}
|
36
composer.lock
generated
Normal file
36
composer.lock
generated
Normal file
@ -0,0 +1,36 @@
|
||||
{
|
||||
"_readme": [
|
||||
"This file locks the dependencies of your project to a known state",
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "d4fecad9dce5314493052c870c8cf059",
|
||||
"packages": [],
|
||||
"packages-dev": [],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": {
|
||||
"ext-pthreads": 20
|
||||
},
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
"php": ">=7.2",
|
||||
"ext-bcmath": "*",
|
||||
"ext-curl": "*",
|
||||
"ext-hash": "*",
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-openssl": "*",
|
||||
"ext-pcre": "*",
|
||||
"ext-phar": "*",
|
||||
"ext-pthreads": ">=3.1.7dev",
|
||||
"ext-reflection": "*",
|
||||
"ext-sockets": "*",
|
||||
"ext-spl": "*",
|
||||
"ext-yaml": ">=2.0.0",
|
||||
"ext-zip": "*",
|
||||
"ext-zlib": ">=1.2.11"
|
||||
},
|
||||
"platform-dev": []
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
use pocketmine\event\TranslationContainer;
|
||||
@ -39,76 +41,82 @@ abstract class Achievement{
|
||||
"mineWood" => [
|
||||
"name" => "Getting Wood",
|
||||
"requires" => [ //"openInventory",
|
||||
],
|
||||
]
|
||||
],
|
||||
"buildWorkBench" => [
|
||||
"name" => "Benchmarking",
|
||||
"requires" => [
|
||||
"mineWood",
|
||||
],
|
||||
"mineWood"
|
||||
]
|
||||
],
|
||||
"buildPickaxe" => [
|
||||
"name" => "Time to Mine!",
|
||||
"requires" => [
|
||||
"buildWorkBench",
|
||||
],
|
||||
"buildWorkBench"
|
||||
]
|
||||
],
|
||||
"buildFurnace" => [
|
||||
"name" => "Hot Topic",
|
||||
"requires" => [
|
||||
"buildPickaxe",
|
||||
],
|
||||
"buildPickaxe"
|
||||
]
|
||||
],
|
||||
"acquireIron" => [
|
||||
"name" => "Acquire hardware",
|
||||
"requires" => [
|
||||
"buildFurnace",
|
||||
],
|
||||
"buildFurnace"
|
||||
]
|
||||
],
|
||||
"buildHoe" => [
|
||||
"name" => "Time to Farm!",
|
||||
"requires" => [
|
||||
"buildWorkBench",
|
||||
],
|
||||
"buildWorkBench"
|
||||
]
|
||||
],
|
||||
"makeBread" => [
|
||||
"name" => "Bake Bread",
|
||||
"requires" => [
|
||||
"buildHoe",
|
||||
],
|
||||
"buildHoe"
|
||||
]
|
||||
],
|
||||
"bakeCake" => [
|
||||
"name" => "The Lie",
|
||||
"requires" => [
|
||||
"buildHoe",
|
||||
],
|
||||
"buildHoe"
|
||||
]
|
||||
],
|
||||
"buildBetterPickaxe" => [
|
||||
"name" => "Getting an Upgrade",
|
||||
"requires" => [
|
||||
"buildPickaxe",
|
||||
],
|
||||
"buildPickaxe"
|
||||
]
|
||||
],
|
||||
"buildSword" => [
|
||||
"name" => "Time to Strike!",
|
||||
"requires" => [
|
||||
"buildWorkBench",
|
||||
],
|
||||
"buildWorkBench"
|
||||
]
|
||||
],
|
||||
"diamonds" => [
|
||||
"name" => "DIAMONDS!",
|
||||
"requires" => [
|
||||
"acquireIron",
|
||||
],
|
||||
],
|
||||
"acquireIron"
|
||||
]
|
||||
]
|
||||
|
||||
];
|
||||
|
||||
|
||||
public static function broadcast(Player $player, $achievementId){
|
||||
/**
|
||||
* @param Player $player
|
||||
* @param string $achievementId
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function broadcast(Player $player, string $achievementId) : bool{
|
||||
if(isset(Achievement::$list[$achievementId])){
|
||||
$translation = new TranslationContainer("chat.type.achievement", [$player->getDisplayName(), TextFormat::GREEN . Achievement::$list[$achievementId]["name"]]);
|
||||
if(Server::getInstance()->getConfigString("announce-player-achievements", true) === true){
|
||||
$translation = new TranslationContainer("chat.type.achievement", [$player->getDisplayName(), TextFormat::GREEN . Achievement::$list[$achievementId]["name"] . TextFormat::RESET]);
|
||||
if(Server::getInstance()->getConfigBoolean("announce-player-achievements", true) === true){
|
||||
Server::getInstance()->broadcastMessage($translation);
|
||||
}else{
|
||||
$player->sendMessage($translation);
|
||||
@ -120,11 +128,18 @@ abstract class Achievement{
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function add($achievementId, $achievementName, array $requires = []){
|
||||
/**
|
||||
* @param string $achievementId
|
||||
* @param string $achievementName
|
||||
* @param array $requires
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function add(string $achievementId, string $achievementName, array $requires = []) : bool{
|
||||
if(!isset(Achievement::$list[$achievementId])){
|
||||
Achievement::$list[$achievementId] = [
|
||||
"name" => $achievementName,
|
||||
"requires" => $requires,
|
||||
"requires" => $requires
|
||||
];
|
||||
|
||||
return true;
|
||||
|
@ -19,17 +19,19 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
abstract class Collectable extends \Threaded implements \Collectable{
|
||||
abstract class Collectable extends \Threaded{
|
||||
|
||||
private $isGarbage = false;
|
||||
private $isGarbage = false;
|
||||
|
||||
public function isGarbage() : bool{
|
||||
return $this->isGarbage;
|
||||
}
|
||||
public function isGarbage() : bool{
|
||||
return $this->isGarbage;
|
||||
}
|
||||
|
||||
public function setGarbage(){
|
||||
$this->isGarbage = true;
|
||||
}
|
||||
public function setGarbage(){
|
||||
$this->isGarbage = true;
|
||||
}
|
||||
}
|
||||
|
@ -19,11 +19,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
use pocketmine\network\protocol\Info;
|
||||
use pocketmine\network\mcpe\protocol\ProtocolInfo;
|
||||
use pocketmine\plugin\PluginBase;
|
||||
use pocketmine\plugin\PluginLoadOrder;
|
||||
use pocketmine\plugin\PluginManager;
|
||||
use pocketmine\utils\Utils;
|
||||
use pocketmine\utils\VersionString;
|
||||
use raklib\RakLib;
|
||||
@ -35,13 +38,18 @@ class CrashDump{
|
||||
private $fp;
|
||||
private $time;
|
||||
private $data = [];
|
||||
private $encodedData = null;
|
||||
/** @var string */
|
||||
private $encodedData = "";
|
||||
/** @var string */
|
||||
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";
|
||||
if(!is_dir($this->server->getDataPath() . "crashdumps")){
|
||||
mkdir($this->server->getDataPath() . "crashdumps");
|
||||
}
|
||||
$this->path = $this->server->getDataPath() . "crashdumps/" . date("D_M_j-H.i.s-T_Y", $this->time) . ".log";
|
||||
$this->fp = @fopen($this->path, "wb");
|
||||
if(!is_resource($this->fp)){
|
||||
throw new \RuntimeException("Could not create Crash Dump");
|
||||
@ -58,7 +66,7 @@ class CrashDump{
|
||||
$this->encodeData();
|
||||
}
|
||||
|
||||
public function getPath(){
|
||||
public function getPath() : string{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
@ -66,7 +74,7 @@ class CrashDump{
|
||||
return $this->encodedData;
|
||||
}
|
||||
|
||||
public function getData(){
|
||||
public function getData() : array{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
@ -83,7 +91,7 @@ class CrashDump{
|
||||
}
|
||||
|
||||
private function pluginsData(){
|
||||
if(class_exists("pocketmine\\plugin\\PluginManager", false)){
|
||||
if($this->server->getPluginManager() instanceof PluginManager){
|
||||
$this->addLine();
|
||||
$this->addLine("Loaded plugins:");
|
||||
$this->data["plugins"] = [];
|
||||
@ -140,7 +148,7 @@ class CrashDump{
|
||||
$error = $lastExceptionError;
|
||||
}else{
|
||||
$error = (array) error_get_last();
|
||||
$error["trace"] = @getTrace(3);
|
||||
$error["trace"] = getTrace(4); //Skipping CrashDump->baseCrash, CrashDump->construct, Server->crashDump
|
||||
$errorConversion = [
|
||||
E_ERROR => "E_ERROR",
|
||||
E_WARNING => "E_WARNING",
|
||||
@ -156,11 +164,11 @@ class CrashDump{
|
||||
E_STRICT => "E_STRICT",
|
||||
E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR",
|
||||
E_DEPRECATED => "E_DEPRECATED",
|
||||
E_USER_DEPRECATED => "E_USER_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"];
|
||||
$error["type"] = $errorConversion[$error["type"]] ?? $error["type"];
|
||||
if(($pos = strpos($error["message"], "\n")) !== false){
|
||||
$error["message"] = substr($error["message"], 0, $pos);
|
||||
}
|
||||
@ -221,9 +229,10 @@ class CrashDump{
|
||||
private function generalData(){
|
||||
$version = new VersionString();
|
||||
$this->data["general"] = [];
|
||||
$this->data["general"]["name"] = $this->server->getName();
|
||||
$this->data["general"]["version"] = $version->get(false);
|
||||
$this->data["general"]["build"] = $version->getBuild();
|
||||
$this->data["general"]["protocol"] = Info::CURRENT_PROTOCOL;
|
||||
$this->data["general"]["protocol"] = ProtocolInfo::CURRENT_PROTOCOL;
|
||||
$this->data["general"]["api"] = \pocketmine\API_VERSION;
|
||||
$this->data["general"]["git"] = \pocketmine\GIT_COMMIT;
|
||||
$this->data["general"]["raklib"] = RakLib::VERSION;
|
||||
@ -232,7 +241,7 @@ class CrashDump{
|
||||
$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->getBuild() . " [Protocol " . Info::CURRENT_PROTOCOL . "; API " . API_VERSION . "]");
|
||||
$this->addLine($this->server->getName() . " version: " . $version->get(false) . " #" . $version->getBuild() . " [Protocol " . ProtocolInfo::CURRENT_PROTOCOL . "; API " . API_VERSION . "]");
|
||||
$this->addLine("Git commit: " . GIT_COMMIT);
|
||||
$this->addLine("uname -a: " . php_uname("a"));
|
||||
$this->addLine("PHP Version: " . phpversion());
|
||||
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
use pocketmine\permission\ServerOperator;
|
||||
@ -28,32 +30,32 @@ interface IPlayer extends ServerOperator{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isOnline();
|
||||
public function isOnline() : bool;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName();
|
||||
public function getName() : string;
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isBanned();
|
||||
public function isBanned() : bool;
|
||||
|
||||
/**
|
||||
* @param bool $banned
|
||||
*/
|
||||
public function setBanned($banned);
|
||||
public function setBanned(bool $banned);
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isWhitelisted();
|
||||
public function isWhitelisted() : bool;
|
||||
|
||||
/**
|
||||
* @param bool $value
|
||||
*/
|
||||
public function setWhitelisted($value);
|
||||
public function setWhitelisted(bool $value);
|
||||
|
||||
/**
|
||||
* @return Player|null
|
||||
@ -61,18 +63,18 @@ interface IPlayer extends ServerOperator{
|
||||
public function getPlayer();
|
||||
|
||||
/**
|
||||
* @return int|double
|
||||
* @return int|null
|
||||
*/
|
||||
public function getFirstPlayed();
|
||||
|
||||
/**
|
||||
* @return int|double
|
||||
* @return int|null
|
||||
*/
|
||||
public function getLastPlayed();
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
* @return bool
|
||||
*/
|
||||
public function hasPlayedBefore();
|
||||
public function hasPlayedBefore() : bool;
|
||||
|
||||
}
|
||||
|
@ -19,42 +19,66 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
use pocketmine\event\server\LowMemoryEvent;
|
||||
use pocketmine\event\Timings;
|
||||
use pocketmine\scheduler\DumpWorkerMemoryTask;
|
||||
use pocketmine\scheduler\GarbageCollectionTask;
|
||||
use pocketmine\utils\MainLogger;
|
||||
use pocketmine\utils\Utils;
|
||||
|
||||
|
||||
class MemoryManager{
|
||||
|
||||
/** @var Server */
|
||||
private $server;
|
||||
|
||||
/** @var int */
|
||||
private $memoryLimit;
|
||||
/** @var int */
|
||||
private $globalMemoryLimit;
|
||||
/** @var int */
|
||||
private $checkRate;
|
||||
/** @var int */
|
||||
private $checkTicker = 0;
|
||||
/** @var bool */
|
||||
private $lowMemory = false;
|
||||
|
||||
/** @var bool */
|
||||
private $continuousTrigger = true;
|
||||
/** @var int */
|
||||
private $continuousTriggerRate;
|
||||
/** @var int */
|
||||
private $continuousTriggerCount = 0;
|
||||
/** @var int */
|
||||
private $continuousTriggerTicker = 0;
|
||||
|
||||
/** @var int */
|
||||
private $garbageCollectionPeriod;
|
||||
/** @var int */
|
||||
private $garbageCollectionTicker = 0;
|
||||
/** @var bool */
|
||||
private $garbageCollectionTrigger;
|
||||
/** @var bool */
|
||||
private $garbageCollectionAsync;
|
||||
|
||||
private $chunkLimit;
|
||||
/** @var int */
|
||||
private $chunkRadiusOverride;
|
||||
/** @var bool */
|
||||
private $chunkCollect;
|
||||
/** @var bool */
|
||||
private $chunkTrigger;
|
||||
|
||||
/** @var bool */
|
||||
private $chunkCache;
|
||||
/** @var bool */
|
||||
private $cacheTrigger;
|
||||
|
||||
/** @var bool */
|
||||
private $dumpWorkers = true;
|
||||
|
||||
public function __construct(Server $server){
|
||||
$this->server = $server;
|
||||
|
||||
@ -91,7 +115,7 @@ class MemoryManager{
|
||||
$hardLimit = ((int) $this->server->getProperty("memory.main-hard-limit", $defaultMemory));
|
||||
|
||||
if($hardLimit <= 0){
|
||||
ini_set("memory_limit", -1);
|
||||
ini_set("memory_limit", '-1');
|
||||
}else{
|
||||
ini_set("memory_limit", $hardLimit . "M");
|
||||
}
|
||||
@ -105,31 +129,53 @@ class MemoryManager{
|
||||
$this->garbageCollectionTrigger = (bool) $this->server->getProperty("memory.garbage-collection.low-memory-trigger", true);
|
||||
$this->garbageCollectionAsync = (bool) $this->server->getProperty("memory.garbage-collection.collect-async-worker", true);
|
||||
|
||||
$this->chunkLimit = (int) $this->server->getProperty("memory.max-chunks.trigger-limit", 96);
|
||||
$this->chunkRadiusOverride = (int) $this->server->getProperty("memory.max-chunks.chunk-radius", 4);
|
||||
$this->chunkCollect = (bool) $this->server->getProperty("memory.max-chunks.trigger-chunk-collect", true);
|
||||
$this->chunkTrigger = (bool) $this->server->getProperty("memory.max-chunks.low-memory-trigger", true);
|
||||
|
||||
$this->chunkCache = (bool) $this->server->getProperty("memory.world-caches.disable-chunk-cache", true);
|
||||
$this->cacheTrigger = (bool) $this->server->getProperty("memory.world-caches.low-memory-trigger", true);
|
||||
|
||||
$this->dumpWorkers = (bool) $this->server->getProperty("memory.memory-dump.dump-async-worker", true);
|
||||
gc_enable();
|
||||
}
|
||||
|
||||
public function isLowMemory(){
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isLowMemory() : bool{
|
||||
return $this->lowMemory;
|
||||
}
|
||||
|
||||
public function canUseChunkCache(){
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function canUseChunkCache() : bool{
|
||||
return !($this->lowMemory and $this->chunkTrigger);
|
||||
}
|
||||
|
||||
public function getViewDistance($distance){
|
||||
return $this->lowMemory ? min($this->chunkLimit, $distance) : $distance;
|
||||
/**
|
||||
* Returns the allowed chunk radius based on the current memory usage.
|
||||
*
|
||||
* @param int $distance
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getViewDistance(int $distance) : int{
|
||||
return $this->lowMemory ? (int) min($this->chunkRadiusOverride, $distance) : $distance;
|
||||
}
|
||||
|
||||
public function trigger($memory, $limit, $global = false, $triggerCount = 0){
|
||||
$this->server->getLogger()->debug("[Memory Manager] ".($global ? "Global " : "") ."Low memory triggered, limit ". round(($limit / 1024) / 1024, 2)."MB, using ". round(($memory / 1024) / 1024, 2)."MB");
|
||||
|
||||
/**
|
||||
* Triggers garbage collection and cache cleanup to try and free memory.
|
||||
*
|
||||
* @param int $memory
|
||||
* @param int $limit
|
||||
* @param bool $global
|
||||
* @param int $triggerCount
|
||||
*/
|
||||
public function trigger(int $memory, int $limit, bool $global = false, int $triggerCount = 0){
|
||||
$this->server->getLogger()->debug(sprintf("[Memory Manager] %sLow memory triggered, limit %gMB, using %gMB",
|
||||
$global ? "Global " : "", round(($limit / 1024) / 1024, 2), round(($memory / 1024) / 1024, 2)));
|
||||
if($this->cacheTrigger){
|
||||
foreach($this->server->getLevels() as $level){
|
||||
$level->clearCache(true);
|
||||
@ -150,9 +196,12 @@ class MemoryManager{
|
||||
$cycles = $this->triggerGarbageCollector();
|
||||
}
|
||||
|
||||
$this->server->getLogger()->debug("[Memory Manager] Freed " . round(($ev->getMemoryFreed() / 1024) / 1024, 2)."MB, $cycles cycles");
|
||||
$this->server->getLogger()->debug(sprintf("[Memory Manager] Freed %gMB, $cycles cycles", round(($ev->getMemoryFreed() / 1024) / 1024, 2)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Called every tick to update the memory manager state.
|
||||
*/
|
||||
public function check(){
|
||||
Timings::$memoryManagerTimer->startTiming();
|
||||
|
||||
@ -190,7 +239,10 @@ class MemoryManager{
|
||||
Timings::$memoryManagerTimer->stopTiming();
|
||||
}
|
||||
|
||||
public function triggerGarbageCollector(){
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function triggerGarbageCollector() : int{
|
||||
Timings::$garbageCollectorTimer->startTiming();
|
||||
|
||||
if($this->garbageCollectionAsync){
|
||||
@ -207,26 +259,110 @@ class MemoryManager{
|
||||
return $cycles;
|
||||
}
|
||||
|
||||
public function dumpServerMemory($outputFolder, $maxNesting, $maxStringSize){
|
||||
/**
|
||||
* Dumps the server memory into the specified output folder.
|
||||
*
|
||||
* @param string $outputFolder
|
||||
* @param int $maxNesting
|
||||
* @param int $maxStringSize
|
||||
*/
|
||||
public function dumpServerMemory(string $outputFolder, int $maxNesting, int $maxStringSize){
|
||||
MainLogger::getLogger()->notice("[Dump] After the memory dump is done, the server might crash");
|
||||
self::dumpMemory($this->server, $this->server->getLoader(), $outputFolder, $maxNesting, $maxStringSize);
|
||||
|
||||
if($this->dumpWorkers){
|
||||
$scheduler = $this->server->getScheduler();
|
||||
for($i = 0, $size = $scheduler->getAsyncTaskPoolSize(); $i < $size; ++$i){
|
||||
$scheduler->scheduleAsyncTaskToWorker(new DumpWorkerMemoryTask($outputFolder, $maxNesting, $maxStringSize), $i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Static memory dumper accessible from any thread.
|
||||
*
|
||||
* @param mixed $startingObject
|
||||
* @param \ClassLoader $loader
|
||||
* @param string $outputFolder
|
||||
* @param int $maxNesting
|
||||
* @param int $maxStringSize
|
||||
*/
|
||||
public static function dumpMemory($startingObject, \ClassLoader $loader, string $outputFolder, int $maxNesting, int $maxStringSize){
|
||||
$hardLimit = ini_get('memory_limit');
|
||||
ini_set('memory_limit', '-1');
|
||||
gc_disable();
|
||||
|
||||
if(!file_exists($outputFolder)){
|
||||
mkdir($outputFolder, 0777, true);
|
||||
}
|
||||
|
||||
$this->server->getLogger()->notice("[Dump] After the memory dump is done, the server might crash");
|
||||
|
||||
$obData = fopen($outputFolder . "/objects.js", "wb+");
|
||||
|
||||
$staticProperties = [];
|
||||
|
||||
$data = [];
|
||||
|
||||
$objects = [];
|
||||
|
||||
$refCounts = [];
|
||||
|
||||
$this->continueDump($this->server, $data, $objects, $refCounts, 0, $maxNesting, $maxStringSize);
|
||||
$instanceCounts = [];
|
||||
|
||||
$staticProperties = [];
|
||||
$staticCount = 0;
|
||||
|
||||
foreach($loader->getClasses() as $className){
|
||||
$reflection = new \ReflectionClass($className);
|
||||
$staticProperties[$className] = [];
|
||||
foreach($reflection->getProperties() as $property){
|
||||
if(!$property->isStatic() or $property->getDeclaringClass()->getName() !== $className){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!$property->isPublic()){
|
||||
$property->setAccessible(true);
|
||||
}
|
||||
|
||||
$staticCount++;
|
||||
self::continueDump($property->getValue(), $staticProperties[$className][$property->getName()], $objects, $refCounts, 0, $maxNesting, $maxStringSize);
|
||||
}
|
||||
|
||||
if(count($staticProperties[$className]) === 0){
|
||||
unset($staticProperties[$className]);
|
||||
}
|
||||
}
|
||||
|
||||
file_put_contents($outputFolder . "/staticProperties.js", json_encode($staticProperties, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
|
||||
MainLogger::getLogger()->info("[Dump] Wrote $staticCount static properties");
|
||||
|
||||
if($GLOBALS !== null){ //This might be null if we're on a different thread
|
||||
$globalVariables = [];
|
||||
$globalCount = 0;
|
||||
|
||||
$ignoredGlobals = [
|
||||
'GLOBALS' => true,
|
||||
'_SERVER' => true,
|
||||
'_REQUEST' => true,
|
||||
'_POST' => true,
|
||||
'_GET' => true,
|
||||
'_FILES' => true,
|
||||
'_ENV' => true,
|
||||
'_COOKIE' => true,
|
||||
'_SESSION' => true
|
||||
];
|
||||
|
||||
foreach($GLOBALS as $varName => $value){
|
||||
if(isset($ignoredGlobals[$varName])){
|
||||
continue;
|
||||
}
|
||||
|
||||
$globalCount++;
|
||||
self::continueDump($value, $globalVariables[$varName], $objects, $refCounts, 0, $maxNesting, $maxStringSize);
|
||||
}
|
||||
|
||||
file_put_contents($outputFolder . "/globalVariables.js", json_encode($globalVariables, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
|
||||
MainLogger::getLogger()->info("[Dump] Wrote $globalCount global variables");
|
||||
}
|
||||
|
||||
self::continueDump($startingObject, $data, $objects, $refCounts, 0, $maxNesting, $maxStringSize);
|
||||
|
||||
do{
|
||||
$continue = false;
|
||||
@ -237,6 +373,11 @@ class MemoryManager{
|
||||
$continue = true;
|
||||
|
||||
$className = get_class($object);
|
||||
if(!isset($instanceCounts[$className])){
|
||||
$instanceCounts[$className] = 1;
|
||||
}else{
|
||||
$instanceCounts[$className]++;
|
||||
}
|
||||
|
||||
$objects[$hash] = true;
|
||||
|
||||
@ -263,41 +404,41 @@ class MemoryManager{
|
||||
if(!$property->isPublic()){
|
||||
$property->setAccessible(true);
|
||||
}
|
||||
$this->continueDump($property->getValue($object), $info["properties"][$property->getName()], $objects, $refCounts, 0, $maxNesting, $maxStringSize);
|
||||
self::continueDump($property->getValue($object), $info["properties"][$property->getName()], $objects, $refCounts, 0, $maxNesting, $maxStringSize);
|
||||
}
|
||||
|
||||
fwrite($obData, "$hash@$className: ". json_encode($info, JSON_UNESCAPED_SLASHES) . "\n");
|
||||
|
||||
if(!isset($objects["staticProperties"][$className])){
|
||||
$staticProperties[$className] = [];
|
||||
foreach($reflection->getProperties() as $property){
|
||||
if(!$property->isStatic() or $property->getDeclaringClass()->getName() !== $className){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!$property->isPublic()){
|
||||
$property->setAccessible(true);
|
||||
}
|
||||
$this->continueDump($property->getValue($object), $staticProperties[$className][$property->getName()], $objects, $refCounts, 0, $maxNesting, $maxStringSize);
|
||||
}
|
||||
}
|
||||
fwrite($obData, "$hash@$className: " . json_encode($info, JSON_UNESCAPED_SLASHES) . "\n");
|
||||
}
|
||||
|
||||
echo "[Dump] Wrote " . count($objects) . " objects\n";
|
||||
|
||||
}while($continue);
|
||||
|
||||
file_put_contents($outputFolder . "/staticProperties.js", json_encode($staticProperties, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
|
||||
MainLogger::getLogger()->info("[Dump] Wrote " . count($objects) . " objects");
|
||||
|
||||
fclose($obData);
|
||||
|
||||
file_put_contents($outputFolder . "/serverEntry.js", json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
|
||||
file_put_contents($outputFolder . "/referenceCounts.js", json_encode($refCounts, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
|
||||
|
||||
echo "[Dump] Finished!\n";
|
||||
arsort($instanceCounts, SORT_NUMERIC);
|
||||
file_put_contents($outputFolder . "/instanceCounts.js", json_encode($instanceCounts, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
|
||||
|
||||
MainLogger::getLogger()->info("[Dump] Finished!");
|
||||
|
||||
ini_set('memory_limit', $hardLimit);
|
||||
gc_enable();
|
||||
|
||||
$this->server->forceShutdown();
|
||||
}
|
||||
|
||||
private function continueDump($from, &$data, &$objects, &$refCounts, $recursion, $maxNesting, $maxStringSize){
|
||||
/**
|
||||
* @param mixed $from
|
||||
* @param mixed &$data
|
||||
* @param object[] &$objects
|
||||
* @param int[] &$refCounts
|
||||
* @param int $recursion
|
||||
* @param int $maxNesting
|
||||
* @param int $maxStringSize
|
||||
*/
|
||||
private static function continueDump($from, &$data, array &$objects, array &$refCounts, int $recursion, int $maxNesting, int $maxStringSize){
|
||||
if($maxNesting <= 0){
|
||||
$data = "(error) NESTING LIMIT REACHED";
|
||||
return;
|
||||
@ -321,10 +462,10 @@ class MemoryManager{
|
||||
}
|
||||
$data = [];
|
||||
foreach($from as $key => $value){
|
||||
$this->continueDump($value, $data[$key], $objects, $refCounts, $recursion + 1, $maxNesting, $maxStringSize);
|
||||
self::continueDump($value, $data[$key], $objects, $refCounts, $recursion + 1, $maxNesting, $maxStringSize);
|
||||
}
|
||||
}elseif(is_string($from)){
|
||||
$data = "(string) len(".strlen($from).") " . substr(Utils::printable($from), 0, $maxStringSize);
|
||||
$data = "(string) len(". strlen($from) .") " . substr(Utils::printable($from), 0, $maxStringSize);
|
||||
}elseif(is_resource($from)){
|
||||
$data = "(resource) " . print_r($from, true);
|
||||
}else{
|
||||
|
@ -19,24 +19,29 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
|
||||
use pocketmine\metadata\Metadatable;
|
||||
use pocketmine\metadata\MetadataValue;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\plugin\Plugin;
|
||||
|
||||
class OfflinePlayer implements IPlayer{
|
||||
class OfflinePlayer implements IPlayer, Metadatable{
|
||||
|
||||
/** @var string */
|
||||
private $name;
|
||||
/** @var Server */
|
||||
private $server;
|
||||
/** @var CompoundTag|null */
|
||||
private $namedtag;
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param string $name
|
||||
*/
|
||||
public function __construct(Server $server, $name){
|
||||
public function __construct(Server $server, string $name){
|
||||
$this->server = $server;
|
||||
$this->name = $name;
|
||||
if(file_exists($this->server->getDataPath() . "players/" . strtolower($this->getName()) . ".dat")){
|
||||
@ -46,11 +51,11 @@ class OfflinePlayer implements IPlayer{
|
||||
}
|
||||
}
|
||||
|
||||
public function isOnline(){
|
||||
public function isOnline() : bool{
|
||||
return $this->getPlayer() !== null;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
@ -58,11 +63,11 @@ class OfflinePlayer implements IPlayer{
|
||||
return $this->server;
|
||||
}
|
||||
|
||||
public function isOp(){
|
||||
public function isOp() : bool{
|
||||
return $this->server->isOp(strtolower($this->getName()));
|
||||
}
|
||||
|
||||
public function setOp($value){
|
||||
public function setOp(bool $value){
|
||||
if($value === $this->isOp()){
|
||||
return;
|
||||
}
|
||||
@ -74,11 +79,11 @@ class OfflinePlayer implements IPlayer{
|
||||
}
|
||||
}
|
||||
|
||||
public function isBanned(){
|
||||
public function isBanned() : bool{
|
||||
return $this->server->getNameBans()->isBanned(strtolower($this->getName()));
|
||||
}
|
||||
|
||||
public function setBanned($value){
|
||||
public function setBanned(bool $value){
|
||||
if($value === true){
|
||||
$this->server->getNameBans()->addBan($this->getName(), null, null, null);
|
||||
}else{
|
||||
@ -86,11 +91,11 @@ class OfflinePlayer implements IPlayer{
|
||||
}
|
||||
}
|
||||
|
||||
public function isWhitelisted(){
|
||||
public function isWhitelisted() : bool{
|
||||
return $this->server->isWhitelisted(strtolower($this->getName()));
|
||||
}
|
||||
|
||||
public function setWhitelisted($value){
|
||||
public function setWhitelisted(bool $value){
|
||||
if($value === true){
|
||||
$this->server->addWhitelist(strtolower($this->getName()));
|
||||
}else{
|
||||
@ -110,24 +115,24 @@ class OfflinePlayer implements IPlayer{
|
||||
return $this->namedtag instanceof CompoundTag ? $this->namedtag["lastPlayed"] : null;
|
||||
}
|
||||
|
||||
public function hasPlayedBefore(){
|
||||
public function hasPlayedBefore() : bool{
|
||||
return $this->namedtag instanceof CompoundTag;
|
||||
}
|
||||
|
||||
public function setMetadata($metadataKey, MetadataValue $metadataValue){
|
||||
$this->server->getPlayerMetadata()->setMetadata($this, $metadataKey, $metadataValue);
|
||||
public function setMetadata(string $metadataKey, MetadataValue $newMetadataValue){
|
||||
$this->server->getPlayerMetadata()->setMetadata($this, $metadataKey, $newMetadataValue);
|
||||
}
|
||||
|
||||
public function getMetadata($metadataKey){
|
||||
public function getMetadata(string $metadataKey){
|
||||
return $this->server->getPlayerMetadata()->getMetadata($this, $metadataKey);
|
||||
}
|
||||
|
||||
public function hasMetadata($metadataKey){
|
||||
public function hasMetadata(string $metadataKey) : bool{
|
||||
return $this->server->getPlayerMetadata()->hasMetadata($this, $metadataKey);
|
||||
}
|
||||
|
||||
public function removeMetadata($metadataKey, Plugin $plugin){
|
||||
$this->server->getPlayerMetadata()->removeMetadata($this, $metadataKey, $plugin);
|
||||
public function removeMetadata(string $metadataKey, Plugin $owningPlugin){
|
||||
$this->server->getPlayerMetadata()->removeMetadata($this, $metadataKey, $owningPlugin);
|
||||
}
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -19,7 +19,12 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace {
|
||||
const INT32_MIN = -0x80000000;
|
||||
const INT32_MAX = 0x7fffffff;
|
||||
|
||||
function safe_var_dump(){
|
||||
static $cnt = 0;
|
||||
foreach(func_get_args() as $var){
|
||||
@ -27,7 +32,7 @@ namespace {
|
||||
case is_array($var):
|
||||
echo str_repeat(" ", $cnt) . "array(" . count($var) . ") {" . PHP_EOL;
|
||||
foreach($var as $key => $value){
|
||||
echo str_repeat(" ", $cnt + 1) . "[" . (is_integer($key) ? $key : '"' . $key . '"') . "]=>" . PHP_EOL;
|
||||
echo str_repeat(" ", $cnt + 1) . "[" . (is_int($key) ? $key : '"' . $key . '"') . "]=>" . PHP_EOL;
|
||||
++$cnt;
|
||||
safe_var_dump($value);
|
||||
--$cnt;
|
||||
@ -65,18 +70,18 @@ namespace {
|
||||
}
|
||||
|
||||
namespace pocketmine {
|
||||
|
||||
use pocketmine\utils\Binary;
|
||||
use pocketmine\utils\MainLogger;
|
||||
use pocketmine\utils\ServerKiller;
|
||||
use pocketmine\utils\Terminal;
|
||||
use pocketmine\utils\Utils;
|
||||
use pocketmine\wizard\Installer;
|
||||
use pocketmine\wizard\SetupWizard;
|
||||
use raklib\RakLib;
|
||||
|
||||
const VERSION = "1.6dev";
|
||||
const API_VERSION = "2.0.0";
|
||||
const CODENAME = "Unleashed";
|
||||
const MINECRAFT_VERSION = "v0.15.0.0 alpha";
|
||||
const MINECRAFT_VERSION_NETWORK = "0.15.0.0";
|
||||
const VERSION = "1.7dev";
|
||||
const API_VERSION = "3.0.0-ALPHA8";
|
||||
const CODENAME = "[REDACTED]";
|
||||
|
||||
/*
|
||||
* Startup code. Do not look at it, it may harm you.
|
||||
@ -85,14 +90,8 @@ namespace pocketmine {
|
||||
* Enjoy it as much as I did writing it. I don't want to do it again.
|
||||
*/
|
||||
|
||||
if(\Phar::running(true) !== ""){
|
||||
@define('pocketmine\PATH', \Phar::running(true) . "/");
|
||||
}else{
|
||||
@define('pocketmine\PATH', \getcwd() . DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
if(version_compare("7.0", PHP_VERSION) > 0){
|
||||
echo "[CRITICAL] You must use PHP >= 7.0" . PHP_EOL;
|
||||
if(version_compare("7.2", PHP_VERSION) > 0){
|
||||
echo "[CRITICAL] You must use PHP >= 7.2" . PHP_EOL;
|
||||
echo "[CRITICAL] Please use the installer provided on the homepage." . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
@ -103,28 +102,80 @@ namespace pocketmine {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
set_error_handler(function($severity, $message, $file, $line){
|
||||
if(error_reporting() & $severity){
|
||||
throw new \ErrorException($message, 0, $severity, $file, $line);
|
||||
}else{ //stfu operator
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
if(!extension_loaded("phar")){
|
||||
echo "[CRITICAL] Unable to find the Phar extension." . PHP_EOL;
|
||||
echo "[CRITICAL] Please use the installer provided on the homepage." . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(\Phar::running(true) !== ""){
|
||||
define('pocketmine\PATH', \Phar::running(true) . "/");
|
||||
}else{
|
||||
define('pocketmine\PATH', dirname(__FILE__, 3) . DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
$requiredSplVer = "0.0.1";
|
||||
if(!is_file(\pocketmine\PATH . "src/spl/version.php")){
|
||||
echo "[CRITICAL] Cannot find PocketMine-SPL or incompatible version." . PHP_EOL;
|
||||
echo "[CRITICAL] Please update your submodules or use provided builds." . PHP_EOL;
|
||||
exit(1);
|
||||
}elseif(version_compare($requiredSplVer, require(\pocketmine\PATH . "src/spl/version.php")) > 0){
|
||||
echo "[CRITICAL] Incompatible PocketMine-SPL submodule version ($requiredSplVer is required)." . PHP_EOL;
|
||||
echo "[CRITICAL] Please update your submodules or use provided builds." . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(is_file(\pocketmine\PATH . "vendor/autoload.php")){
|
||||
require_once(\pocketmine\PATH . "vendor/autoload.php");
|
||||
}else{
|
||||
echo "[CRITICAL] Composer autoloader not found" . PHP_EOL;
|
||||
echo "[CRITICAL] Please initialize composer dependencies before running." . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(!class_exists("ClassLoader", false)){
|
||||
require_once(\pocketmine\PATH . "src/spl/ClassLoader.php");
|
||||
require_once(\pocketmine\PATH . "src/spl/BaseClassLoader.php");
|
||||
require_once(\pocketmine\PATH . "src/pocketmine/CompatibleClassLoader.php");
|
||||
}
|
||||
|
||||
$autoloader = new CompatibleClassLoader();
|
||||
/*
|
||||
* We now use the Composer autoloader, but this autoloader is still used by RakLib and for loading plugins.
|
||||
*/
|
||||
$autoloader = new \BaseClassLoader();
|
||||
$autoloader->addPath(\pocketmine\PATH . "src");
|
||||
$autoloader->addPath(\pocketmine\PATH . "src" . DIRECTORY_SEPARATOR . "spl");
|
||||
$autoloader->register(true);
|
||||
$autoloader->register(false);
|
||||
|
||||
if(!class_exists(RakLib::class)){
|
||||
echo "[CRITICAL] Unable to find the RakLib library." . PHP_EOL;
|
||||
echo "[CRITICAL] Please use provided builds or clone the repository recursively." . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(version_compare(RakLib::VERSION, "0.8.1") < 0){
|
||||
echo "[CRITICAL] RakLib version 0.8.1 is required, while you have version " . RakLib::VERSION . "." . PHP_EOL;
|
||||
echo "[CRITICAL] Please update your submodules or use provided builds." . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
set_time_limit(0); //Who set it to 30 seconds?!?!
|
||||
|
||||
gc_enable();
|
||||
error_reporting(-1);
|
||||
ini_set("allow_url_fopen", 1);
|
||||
ini_set("display_errors", 1);
|
||||
ini_set("display_startup_errors", 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", -1);
|
||||
ini_set("memory_limit", '-1');
|
||||
define('pocketmine\START_TIME', microtime(true));
|
||||
|
||||
$opts = getopt("", ["data:", "plugins:", "no-wizard", "enable-profiler"]);
|
||||
@ -143,42 +194,54 @@ namespace pocketmine {
|
||||
//Logger has a dependency on timezone, so we'll set it to UTC until we can get the actual timezone.
|
||||
date_default_timezone_set("UTC");
|
||||
|
||||
$logger = new MainLogger(\pocketmine\DATA . "server.log", \pocketmine\ANSI);
|
||||
$logger = new MainLogger(\pocketmine\DATA . "server.log");
|
||||
$logger->registerStatic();
|
||||
|
||||
do{
|
||||
$timezone = ini_get("date.timezone");
|
||||
if($timezone !== ""){
|
||||
/*
|
||||
* This is here so that people don't come to us complaining and fill up the issue tracker when they put
|
||||
* an incorrect timezone abbreviation in php.ini apparently.
|
||||
*/
|
||||
if(strpos($timezone, "/") === false){
|
||||
$default_timezone = timezone_name_from_abbr($timezone);
|
||||
if($default_timezone !== false){
|
||||
ini_set("date.timezone", $default_timezone);
|
||||
date_default_timezone_set($default_timezone);
|
||||
break;
|
||||
}else{
|
||||
//Bad php.ini value, try another method to detect timezone
|
||||
$logger->warning("Timezone \"$timezone\" could not be parsed as a valid timezone from php.ini, falling back to auto-detection");
|
||||
}
|
||||
}else{
|
||||
date_default_timezone_set($timezone);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!ini_get("date.timezone")){
|
||||
if(($timezone = detect_system_timezone()) and date_default_timezone_set($timezone)){
|
||||
//Success! Timezone has already been set and validated in the if statement.
|
||||
//This here is just for redundancy just in case some program wants to read timezone data from the ini.
|
||||
ini_set("date.timezone", $timezone);
|
||||
}else{
|
||||
//If system timezone detection fails or timezone is an invalid value.
|
||||
if($response = Utils::getURL("http://ip-api.com/json")
|
||||
and $ip_geolocation_data = json_decode($response, true)
|
||||
and $ip_geolocation_data['status'] != 'fail'
|
||||
and date_default_timezone_set($ip_geolocation_data['timezone'])
|
||||
){
|
||||
//Again, for redundancy.
|
||||
ini_set("date.timezone", $ip_geolocation_data['timezone']);
|
||||
}else{
|
||||
ini_set("date.timezone", "UTC");
|
||||
date_default_timezone_set("UTC");
|
||||
$logger->warning("Timezone could not be automatically determined. An incorrect timezone will result in incorrect timestamps on console logs. It has been set to \"UTC\" by default. You can change it on the php.ini file.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
/*
|
||||
* This is here so that people don't come to us complaining and fill up the issue tracker when they put
|
||||
* an incorrect timezone abbreviation in php.ini apparently.
|
||||
*/
|
||||
$timezone = ini_get("date.timezone");
|
||||
if(strpos($timezone, "/") === false){
|
||||
$default_timezone = timezone_name_from_abbr($timezone);
|
||||
ini_set("date.timezone", $default_timezone);
|
||||
date_default_timezone_set($default_timezone);
|
||||
} else {
|
||||
date_default_timezone_set($timezone);
|
||||
|
||||
if($response = Utils::getURL("http://ip-api.com/json") //If system timezone detection fails or timezone is an invalid value.
|
||||
and $ip_geolocation_data = json_decode($response, true)
|
||||
and $ip_geolocation_data['status'] !== 'fail'
|
||||
and date_default_timezone_set($ip_geolocation_data['timezone'])
|
||||
){
|
||||
//Again, for redundancy.
|
||||
ini_set("date.timezone", $ip_geolocation_data['timezone']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ini_set("date.timezone", "UTC");
|
||||
date_default_timezone_set("UTC");
|
||||
$logger->warning("Timezone could not be automatically determined or was set to an invalid value. An incorrect timezone will result in incorrect timestamps on console logs. It has been set to \"UTC\" by default. You can change it on the php.ini file.");
|
||||
}while(false);
|
||||
|
||||
|
||||
function detect_system_timezone(){
|
||||
switch(Utils::getOS()){
|
||||
@ -217,7 +280,6 @@ namespace pocketmine {
|
||||
}
|
||||
|
||||
return parse_offset($offset);
|
||||
break;
|
||||
case 'linux':
|
||||
// Ubuntu / Debian.
|
||||
if(file_exists('/etc/timezone')){
|
||||
@ -244,7 +306,6 @@ namespace pocketmine {
|
||||
}
|
||||
|
||||
return parse_offset($offset);
|
||||
break;
|
||||
case 'mac':
|
||||
if(is_link('/etc/localtime')){
|
||||
$filename = readlink('/etc/localtime');
|
||||
@ -255,17 +316,15 @@ namespace pocketmine {
|
||||
}
|
||||
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $offset In the format of +09:00, +02:00, -04:00 etc.
|
||||
*
|
||||
* @return string
|
||||
* @return string|bool
|
||||
*/
|
||||
function parse_offset($offset){
|
||||
//Make signed offsets unsigned for date_parse
|
||||
@ -323,7 +382,7 @@ namespace pocketmine {
|
||||
if(function_exists("posix_kill")){
|
||||
posix_kill($pid, SIGKILL);
|
||||
}else{
|
||||
exec("kill -9 " . ((int)$pid) . " > /dev/null 2>&1");
|
||||
exec("kill -9 " . ((int) $pid) . " > /dev/null 2>&1");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -346,7 +405,7 @@ namespace pocketmine {
|
||||
return -1;
|
||||
}
|
||||
|
||||
function getTrace($start = 1, $trace = null){
|
||||
function getTrace($start = 0, $trace = null){
|
||||
if($trace === null){
|
||||
if(function_exists("xdebug_get_function_stack")){
|
||||
$trace = array_reverse(xdebug_get_function_stack());
|
||||
@ -366,118 +425,151 @@ namespace pocketmine {
|
||||
}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) . " " . (is_array($value) ? "Array()" : Utils::printable(@strval($value)))) . ", ";
|
||||
}
|
||||
|
||||
$params = implode(", ", array_map(function($value){
|
||||
return (is_object($value) ? get_class($value) . " object" : gettype($value) . " " . (is_array($value) ? "Array()" : Utils::printable(@strval($value))));
|
||||
}, $args));
|
||||
}
|
||||
$messages[] = "#$j " . (isset($trace[$i]["file"]) ? cleanPath($trace[$i]["file"]) : "") . "(" . (isset($trace[$i]["line"]) ? $trace[$i]["line"] : "") . "): " . (isset($trace[$i]["class"]) ? $trace[$i]["class"] . (($trace[$i]["type"] === "dynamic" or $trace[$i]["type"] === "->") ? "->" : "::") : "") . $trace[$i]["function"] . "(" . Utils::printable(substr($params, 0, -2)) . ")";
|
||||
$messages[] = "#$j " . (isset($trace[$i]["file"]) ? cleanPath($trace[$i]["file"]) : "") . "(" . ($trace[$i]["line"] ?? "") . "): " . (isset($trace[$i]["class"]) ? $trace[$i]["class"] . (($trace[$i]["type"] === "dynamic" or $trace[$i]["type"] === "->") ? "->" : "::") : "") . $trace[$i]["function"] . "(" . Utils::printable($params) . ")";
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
function cleanPath($path){
|
||||
return rtrim(str_replace(["\\", ".php", "phar://", rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PATH), "/"), rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PLUGIN_PATH), "/")], ["/", "", "", "", ""], $path), "/");
|
||||
return str_replace(["\\", ".php", "phar://", str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PATH), str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PLUGIN_PATH)], ["/", "", "", "", ""], $path);
|
||||
}
|
||||
|
||||
$errors = 0;
|
||||
$exitCode = 0;
|
||||
|
||||
if(php_sapi_name() !== "cli"){
|
||||
$logger->critical("You must run PocketMine-MP using the CLI.");
|
||||
++$errors;
|
||||
}
|
||||
do{
|
||||
$errors = 0;
|
||||
|
||||
if(!extension_loaded("sockets")){
|
||||
$logger->critical("Unable to find the Socket extension.");
|
||||
++$errors;
|
||||
}
|
||||
if(PHP_INT_SIZE < 8){
|
||||
$logger->critical("Running PocketMine-MP with 32-bit systems/PHP is no longer supported. Please upgrade to a 64-bit system or use a 64-bit PHP binary.");
|
||||
$exitCode = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
$pthreads_version = phpversion("pthreads");
|
||||
if(substr_count($pthreads_version, ".") < 2){
|
||||
$pthreads_version = "0.$pthreads_version";
|
||||
}
|
||||
if(version_compare($pthreads_version, "3.1.5") < 0){
|
||||
$logger->critical("pthreads >= 3.1.5 is required, while you have $pthreads_version.");
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(!extension_loaded("uopz")){
|
||||
//$logger->notice("Couldn't find the uopz extension. Some functions may be limited");
|
||||
}
|
||||
|
||||
if(extension_loaded("pocketmine")){
|
||||
if(version_compare(phpversion("pocketmine"), "0.0.1") < 0){
|
||||
$logger->critical("You have the native PocketMine extension, but your version is lower than 0.0.1.");
|
||||
++$errors;
|
||||
}elseif(version_compare(phpversion("pocketmine"), "0.0.4") > 0){
|
||||
$logger->critical("You have the native PocketMine extension, but your version is higher than 0.0.4.");
|
||||
if(php_sapi_name() !== "cli"){
|
||||
$logger->critical("You must run PocketMine-MP using the CLI.");
|
||||
++$errors;
|
||||
}
|
||||
}
|
||||
|
||||
if(!extension_loaded("curl")){
|
||||
$logger->critical("Unable to find the cURL extension.");
|
||||
++$errors;
|
||||
}
|
||||
$pthreads_version = phpversion("pthreads");
|
||||
if(substr_count($pthreads_version, ".") < 2){
|
||||
$pthreads_version = "0.$pthreads_version";
|
||||
}
|
||||
if(version_compare($pthreads_version, "3.1.7-dev") < 0){
|
||||
$logger->critical("pthreads >= 3.1.7-dev is required, while you have $pthreads_version.");
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(!extension_loaded("yaml")){
|
||||
$logger->critical("Unable to find the YAML extension.");
|
||||
++$errors;
|
||||
}
|
||||
if(extension_loaded("leveldb")){
|
||||
$leveldb_version = phpversion("leveldb");
|
||||
if(version_compare($leveldb_version, "0.2.0") < 0){
|
||||
$logger->critical("php-leveldb >= 0.2.0 is required, while you have $leveldb_version");
|
||||
++$errors;
|
||||
}
|
||||
}
|
||||
|
||||
if(!extension_loaded("sqlite3")){
|
||||
$logger->critical("Unable to find the SQLite3 extension.");
|
||||
++$errors;
|
||||
}
|
||||
if(extension_loaded("pocketmine")){
|
||||
if(version_compare(phpversion("pocketmine"), "0.0.1") < 0){
|
||||
$logger->critical("You have the native PocketMine extension, but your version is lower than 0.0.1.");
|
||||
++$errors;
|
||||
}elseif(version_compare(phpversion("pocketmine"), "0.0.4") > 0){
|
||||
$logger->critical("You have the native PocketMine extension, but your version is higher than 0.0.4.");
|
||||
++$errors;
|
||||
}
|
||||
}
|
||||
|
||||
if(!extension_loaded("zlib")){
|
||||
$logger->critical("Unable to find the Zlib extension.");
|
||||
++$errors;
|
||||
}
|
||||
if(extension_loaded("xdebug")){
|
||||
$logger->warning(PHP_EOL . PHP_EOL . PHP_EOL . "\tYou are running PocketMine with xdebug enabled. This has a major impact on performance." . PHP_EOL . PHP_EOL);
|
||||
}
|
||||
|
||||
if($errors > 0){
|
||||
$logger->critical("Please use the installer provided on the homepage, or recompile PHP again.");
|
||||
$logger->shutdown();
|
||||
$logger->join();
|
||||
exit(1); //Exit with error
|
||||
}
|
||||
$extensions = [
|
||||
"bcmath" => "BC Math",
|
||||
"curl" => "cURL",
|
||||
"json" => "JSON",
|
||||
"mbstring" => "Multibyte String",
|
||||
"yaml" => "YAML",
|
||||
"sockets" => "Sockets",
|
||||
"zip" => "Zip",
|
||||
"zlib" => "Zlib"
|
||||
];
|
||||
|
||||
if(file_exists(\pocketmine\PATH . ".git/refs/heads/master")){ //Found Git information!
|
||||
define('pocketmine\GIT_COMMIT', strtolower(trim(file_get_contents(\pocketmine\PATH . ".git/refs/heads/master"))));
|
||||
}else{ //Unknown :(
|
||||
define('pocketmine\GIT_COMMIT', str_repeat("00", 20));
|
||||
}
|
||||
foreach($extensions as $ext => $name){
|
||||
if(!extension_loaded($ext)){
|
||||
$logger->critical("Unable to find the $name ($ext) extension.");
|
||||
++$errors;
|
||||
}
|
||||
}
|
||||
|
||||
@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($errors > 0){
|
||||
$logger->critical("Please use the installer provided on the homepage, or recompile PHP again.");
|
||||
$exitCode = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!file_exists(\pocketmine\DATA . "server.properties") and !isset($opts["no-wizard"])){
|
||||
new Installer();
|
||||
}
|
||||
$gitHash = str_repeat("00", 20);
|
||||
|
||||
if(\Phar::running(true) === ""){
|
||||
$logger->warning("Non-packaged PocketMine-MP installation detected, do not use on production.");
|
||||
}
|
||||
if(\Phar::running(true) === ""){
|
||||
if(Utils::execute("git rev-parse HEAD", $out) === 0){
|
||||
$gitHash = trim($out);
|
||||
if(Utils::execute("git diff --quiet") === 1 or Utils::execute("git diff --cached --quiet") === 1){ //Locally-modified
|
||||
$gitHash .= "-dirty";
|
||||
}
|
||||
}
|
||||
}else{
|
||||
$phar = new \Phar(\Phar::running(false));
|
||||
$meta = $phar->getMetadata();
|
||||
if(isset($meta["git"])){
|
||||
$gitHash = $meta["git"];
|
||||
}
|
||||
}
|
||||
|
||||
ThreadManager::init();
|
||||
$server = new Server($autoloader, $logger, \pocketmine\PATH, \pocketmine\DATA, \pocketmine\PLUGIN_PATH);
|
||||
define('pocketmine\GIT_COMMIT', $gitHash);
|
||||
|
||||
$logger->info("Stopping other threads");
|
||||
|
||||
foreach(ThreadManager::getInstance()->getAll() as $id => $thread){
|
||||
$logger->debug("Stopping " . (new \ReflectionClass($thread))->getShortName() . " thread");
|
||||
$thread->quit();
|
||||
}
|
||||
@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(random_bytes(8))); //Fix OPCache address errors
|
||||
|
||||
$killer = new ServerKiller(8);
|
||||
$killer->start();
|
||||
|
||||
if(!file_exists(\pocketmine\DATA . "server.properties") and !isset($opts["no-wizard"])){
|
||||
$installer = new SetupWizard();
|
||||
if(!$installer->run()){
|
||||
$exitCode = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(\Phar::running(true) === ""){
|
||||
$logger->warning("Non-packaged PocketMine-MP installation detected. Consider using a phar in production for better performance.");
|
||||
}
|
||||
|
||||
ThreadManager::init();
|
||||
new Server($autoloader, $logger, \pocketmine\PATH, \pocketmine\DATA, \pocketmine\PLUGIN_PATH);
|
||||
|
||||
$logger->info("Stopping other threads");
|
||||
|
||||
$killer = new ServerKiller(8);
|
||||
$killer->start();
|
||||
usleep(10000); //Fixes ServerKiller not being able to start on single-core machines
|
||||
|
||||
if(ThreadManager::getInstance()->stopAll() > 0){
|
||||
if(\pocketmine\DEBUG > 1){
|
||||
echo "Some threads could not be stopped, performing a force-kill" . PHP_EOL . PHP_EOL;
|
||||
}
|
||||
kill(getmypid());
|
||||
}
|
||||
}while(false);
|
||||
|
||||
$logger->shutdown();
|
||||
$logger->join();
|
||||
|
||||
echo Terminal::$FORMAT_RESET . "\n";
|
||||
|
||||
exit(0);
|
||||
echo Terminal::$FORMAT_RESET . PHP_EOL;
|
||||
|
||||
exit($exitCode);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
/**
|
||||
@ -41,18 +43,25 @@ abstract class Thread extends \Thread{
|
||||
$this->classLoader = $loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the class loader for this thread.
|
||||
*
|
||||
* WARNING: This method MUST be called from any descendent threads' run() method to make autoloading usable.
|
||||
* If you do not do this, you will not be able to use new classes that were not loaded when the thread was started
|
||||
* (unless you are using a custom autoloader).
|
||||
*/
|
||||
public function registerClassLoader(){
|
||||
require(\pocketmine\PATH . "vendor/autoload.php");
|
||||
if(!interface_exists("ClassLoader", false)){
|
||||
require(\pocketmine\PATH . "src/spl/ClassLoader.php");
|
||||
require(\pocketmine\PATH . "src/spl/BaseClassLoader.php");
|
||||
require(\pocketmine\PATH . "src/pocketmine/CompatibleClassLoader.php");
|
||||
}
|
||||
if($this->classLoader !== null){
|
||||
$this->classLoader->register(true);
|
||||
$this->classLoader->register(false);
|
||||
}
|
||||
}
|
||||
|
||||
public function start(int $options = PTHREADS_INHERIT_ALL){
|
||||
public function start(?int $options = \PTHREADS_INHERIT_ALL){
|
||||
ThreadManager::getInstance()->add($this);
|
||||
|
||||
if(!$this->isRunning() and !$this->isJoined() and !$this->isTerminated()){
|
||||
@ -82,7 +91,7 @@ abstract class Thread extends \Thread{
|
||||
ThreadManager::getInstance()->remove($this);
|
||||
}
|
||||
|
||||
public function getThreadName(){
|
||||
public function getThreadName() : string{
|
||||
return (new \ReflectionClass($this))->getShortName();
|
||||
}
|
||||
}
|
||||
|
@ -19,8 +19,12 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
use pocketmine\utils\MainLogger;
|
||||
|
||||
class ThreadManager extends \Volatile{
|
||||
|
||||
/** @var ThreadManager */
|
||||
@ -58,7 +62,7 @@ class ThreadManager extends \Volatile{
|
||||
/**
|
||||
* @return Worker[]|Thread[]
|
||||
*/
|
||||
public function getAll(){
|
||||
public function getAll() : array{
|
||||
$array = [];
|
||||
foreach($this as $key => $thread){
|
||||
$array[$key] = $thread;
|
||||
@ -66,4 +70,23 @@ class ThreadManager extends \Volatile{
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
public function stopAll() : int{
|
||||
$logger = MainLogger::getLogger();
|
||||
|
||||
$erroredThreads = 0;
|
||||
|
||||
foreach($this->getAll() as $thread){
|
||||
$logger->debug("Stopping " . $thread->getThreadName() . " thread");
|
||||
try{
|
||||
$thread->quit();
|
||||
$logger->debug($thread->getThreadName() . " thread stopped successfully.");
|
||||
}catch(\ThreadException $e){
|
||||
++$erroredThreads;
|
||||
$logger->debug("Could not stop " . $thread->getThreadName() . " thread: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return $erroredThreads;
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
/**
|
||||
@ -42,18 +44,25 @@ abstract class Worker extends \Worker{
|
||||
$this->classLoader = $loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the class loader for this thread.
|
||||
*
|
||||
* WARNING: This method MUST be called from any descendent threads' run() method to make autoloading usable.
|
||||
* If you do not do this, you will not be able to use new classes that were not loaded when the thread was started
|
||||
* (unless you are using a custom autoloader).
|
||||
*/
|
||||
public function registerClassLoader(){
|
||||
require(\pocketmine\PATH . "vendor/autoload.php");
|
||||
if(!interface_exists("ClassLoader", false)){
|
||||
require(\pocketmine\PATH . "src/spl/ClassLoader.php");
|
||||
require(\pocketmine\PATH . "src/spl/BaseClassLoader.php");
|
||||
require(\pocketmine\PATH . "src/pocketmine/CompatibleClassLoader.php");
|
||||
}
|
||||
if($this->classLoader !== null){
|
||||
$this->classLoader->register(true);
|
||||
$this->classLoader->register(false);
|
||||
}
|
||||
}
|
||||
|
||||
public function start(int $options = PTHREADS_INHERIT_ALL){
|
||||
public function start(?int $options = \PTHREADS_INHERIT_ALL){
|
||||
ThreadManager::getInstance()->add($this);
|
||||
|
||||
if(!$this->isRunning() and !$this->isJoined() and !$this->isTerminated()){
|
||||
@ -87,7 +96,7 @@ abstract class Worker extends \Worker{
|
||||
ThreadManager::getInstance()->remove($this);
|
||||
}
|
||||
|
||||
public function getThreadName(){
|
||||
public function getThreadName() : string{
|
||||
return (new \ReflectionClass($this))->getShortName();
|
||||
}
|
||||
}
|
||||
|
@ -19,17 +19,17 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
class ActivatorRail extends Solid {
|
||||
class ActivatorRail extends Rail{
|
||||
|
||||
protected $id = self::ACTIVATOR_RAIL;
|
||||
protected $id = self::ACTIVATOR_RAIL;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
public function getName() : string{
|
||||
return "Activator Rail";
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Activator Rail";
|
||||
}
|
||||
//TODO
|
||||
}
|
||||
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -32,35 +34,35 @@ class Air extends Transparent{
|
||||
protected $id = self::AIR;
|
||||
protected $meta = 0;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Air";
|
||||
}
|
||||
|
||||
public function canPassThrough(){
|
||||
public function canPassThrough() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isBreakable(Item $item){
|
||||
public function isBreakable(Item $item) : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function canBeFlowedInto(){
|
||||
public function canBeFlowedInto() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function canBeReplaced(){
|
||||
public function canBeReplaced() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function canBePlaced(){
|
||||
public function canBePlaced() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isSolid(){
|
||||
public function isSolid() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -68,11 +70,11 @@ class Air extends Transparent{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return -1;
|
||||
}
|
||||
|
||||
public function getResistance(){
|
||||
public function getBlastResistance() : float{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -19,64 +19,75 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\inventory\AnvilInventory;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Anvil extends Fallable{
|
||||
|
||||
const TYPE_NORMAL = 0;
|
||||
const TYPE_SLIGHTLY_DAMAGED = 4;
|
||||
const TYPE_VERY_DAMAGED = 8;
|
||||
|
||||
protected $id = self::ANVIL;
|
||||
|
||||
public function isSolid(){
|
||||
public function isSolid() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function getResistance(){
|
||||
public function getBlastResistance() : float{
|
||||
return 6000;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Anvil";
|
||||
public function getName() : string{
|
||||
static $names = [
|
||||
self::TYPE_NORMAL => "Anvil",
|
||||
self::TYPE_SLIGHTLY_DAMAGED => "Slightly Damaged Anvil",
|
||||
self::TYPE_VERY_DAMAGED => "Very Damaged Anvil"
|
||||
];
|
||||
return $names[$this->meta & 0x0c] ?? "Anvil";
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($player instanceof Player){
|
||||
if($player->isCreative()){
|
||||
return true;
|
||||
}
|
||||
|
||||
$player->addWindow(new AnvilInventory($this));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$direction = ($player !== null ? $player->getDirection() : 0) & 0x03;
|
||||
$this->meta = ($this->meta & 0x0c) | $direction;
|
||||
return $this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return [
|
||||
[$this->id, 0, 1], //TODO break level
|
||||
ItemFactory::get($this->getItemId(), $this->getDamage() & 0x0c, 1)
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,31 +19,42 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\tag\ByteTag;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\tag\IntTag;
|
||||
use pocketmine\nbt\tag\StringTag;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\tile\Bed as TileBed;
|
||||
use pocketmine\tile\Tile;
|
||||
use pocketmine\utils\TextFormat;
|
||||
|
||||
class Bed extends Transparent{
|
||||
const BITFLAG_OCCUPIED = 0x04;
|
||||
const BITFLAG_HEAD = 0x08;
|
||||
|
||||
protected $id = self::BED_BLOCK;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
protected $itemId = Item::BED;
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.2;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Bed Block";
|
||||
}
|
||||
|
||||
@ -58,64 +69,135 @@ class Bed extends Transparent{
|
||||
);
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
public function isHeadPart() : bool{
|
||||
return ($this->meta & self::BITFLAG_HEAD) !== 0;
|
||||
}
|
||||
|
||||
$time = $this->getLevel()->getTime() % Level::TIME_FULL;
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isOccupied() : bool{
|
||||
return ($this->meta & self::BITFLAG_OCCUPIED) !== 0;
|
||||
}
|
||||
|
||||
$isNight = ($time >= Level::TIME_NIGHT and $time < Level::TIME_SUNRISE);
|
||||
|
||||
if($player instanceof Player and !$isNight){
|
||||
$player->sendMessage(TextFormat::GRAY . "You can only sleep at night");
|
||||
return true;
|
||||
public function setOccupied(bool $occupied = true){
|
||||
if($occupied){
|
||||
$this->meta |= self::BITFLAG_OCCUPIED;
|
||||
}else{
|
||||
$this->meta &= ~self::BITFLAG_OCCUPIED;
|
||||
}
|
||||
|
||||
$blockNorth = $this->getSide(2); //Gets the blocks around them
|
||||
$blockSouth = $this->getSide(3);
|
||||
$blockEast = $this->getSide(5);
|
||||
$blockWest = $this->getSide(4);
|
||||
if(($this->meta & 0x08) === 0x08){ //This is the Top part of bed
|
||||
$b = $this;
|
||||
}else{ //Bottom Part of Bed
|
||||
if($blockNorth->getId() === $this->id and ($blockNorth->meta & 0x08) === 0x08){
|
||||
$b = $blockNorth;
|
||||
}elseif($blockSouth->getId() === $this->id and ($blockSouth->meta & 0x08) === 0x08){
|
||||
$b = $blockSouth;
|
||||
}elseif($blockEast->getId() === $this->id and ($blockEast->meta & 0x08) === 0x08){
|
||||
$b = $blockEast;
|
||||
}elseif($blockWest->getId() === $this->id and ($blockWest->meta & 0x08) === 0x08){
|
||||
$b = $blockWest;
|
||||
}else{
|
||||
if($player instanceof Player){
|
||||
$player->sendMessage(TextFormat::GRAY . "This bed is incomplete");
|
||||
}
|
||||
$this->getLevel()->setBlock($this, $this, false, false);
|
||||
|
||||
if(($other = $this->getOtherHalf()) !== null and !$other->isOccupied()){
|
||||
$other->setOccupied($occupied);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $meta
|
||||
* @param bool $isHead
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function getOtherHalfSide(int $meta, bool $isHead = false) : int{
|
||||
$rotation = $meta & 0x03;
|
||||
$side = -1;
|
||||
|
||||
switch($rotation){
|
||||
case 0x00: //South
|
||||
$side = Vector3::SIDE_SOUTH;
|
||||
break;
|
||||
case 0x01: //West
|
||||
$side = Vector3::SIDE_WEST;
|
||||
break;
|
||||
case 0x02: //North
|
||||
$side = Vector3::SIDE_NORTH;
|
||||
break;
|
||||
case 0x03: //East
|
||||
$side = Vector3::SIDE_EAST;
|
||||
break;
|
||||
}
|
||||
|
||||
if($isHead){
|
||||
$side = Vector3::getOppositeSide($side);
|
||||
}
|
||||
|
||||
return $side;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Bed|null
|
||||
*/
|
||||
public function getOtherHalf(){
|
||||
$other = $this->getSide(self::getOtherHalfSide($this->meta, $this->isHeadPart()));
|
||||
if($other instanceof Bed and $other->getId() === $this->getId() and $other->isHeadPart() !== $this->isHeadPart() and (($other->getDamage() & 0x03) === ($this->getDamage() & 0x03))){
|
||||
return $other;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($player !== null){
|
||||
$other = $this->getOtherHalf();
|
||||
if($other === null){
|
||||
$player->sendMessage(TextFormat::GRAY . "This bed is incomplete");
|
||||
|
||||
return true;
|
||||
}elseif($player->distanceSquared($this) > 4 and $player->distanceSquared($other) > 4){
|
||||
//MCPE doesn't have messages for bed too far away
|
||||
return true;
|
||||
}
|
||||
|
||||
$time = $this->getLevel()->getTime() % Level::TIME_FULL;
|
||||
|
||||
$isNight = ($time >= Level::TIME_NIGHT and $time < Level::TIME_SUNRISE);
|
||||
|
||||
if(!$isNight){
|
||||
$player->sendMessage(new TranslationContainer(TextFormat::GRAY . "%tile.bed.noSleep"));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if($player instanceof Player and $player->sleepOn($b) === false){
|
||||
$player->sendMessage(TextFormat::GRAY . "This bed is occupied");
|
||||
$b = ($this->isHeadPart() ? $this : $other);
|
||||
|
||||
if($b->isOccupied()){
|
||||
$player->sendMessage(new TranslationContainer(TextFormat::GRAY . "%tile.bed.occupied"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$player->sleepOn($b);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->isTransparent() === false){
|
||||
$faces = [
|
||||
0 => 3,
|
||||
1 => 4,
|
||||
2 => 2,
|
||||
3 => 5,
|
||||
];
|
||||
$d = $player instanceof Player ? $player->getDirection() : 0;
|
||||
$next = $this->getSide($faces[(($d + 3) % 4)]);
|
||||
$downNext = $this->getSide(0);
|
||||
if($next->canBeReplaced() === true and $downNext->isTransparent() === false){
|
||||
$meta = (($d + 3) % 4) & 0x03;
|
||||
$this->getLevel()->setBlock($block, Block::get($this->id, $meta), true, true);
|
||||
$this->getLevel()->setBlock($next, Block::get($this->id, $meta | 0x08), true, true);
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if(!$down->isTransparent()){
|
||||
$meta = (($player instanceof Player ? $player->getDirection() : 0) - 1) & 0x03;
|
||||
$next = $this->getSide(self::getOtherHalfSide($meta));
|
||||
if($next->canBeReplaced() === true and !$next->getSide(Vector3::SIDE_DOWN)->isTransparent()){
|
||||
$this->getLevel()->setBlock($blockReplace, BlockFactory::get($this->id, $meta), true, true);
|
||||
$this->getLevel()->setBlock($next, BlockFactory::get($this->id, $meta | self::BITFLAG_HEAD), true, true);
|
||||
|
||||
$nbt = new CompoundTag("", [
|
||||
new StringTag("id", Tile::BED),
|
||||
new ByteTag("color", $item->getDamage() & 0x0f),
|
||||
new IntTag("x", $blockReplace->x),
|
||||
new IntTag("y", $blockReplace->y),
|
||||
new IntTag("z", $blockReplace->z)
|
||||
]);
|
||||
|
||||
$nbt2 = clone $nbt;
|
||||
$nbt2["x"] = $next->x;
|
||||
$nbt2["z"] = $next->z;
|
||||
|
||||
Tile::createTile(Tile::BED, $this->getLevel(), $nbt);
|
||||
Tile::createTile(Tile::BED, $this->getLevel(), $nbt2);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -124,42 +206,30 @@ class Bed extends Transparent{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onBreak(Item $item){
|
||||
$blockNorth = $this->getSide(2); //Gets the blocks around them
|
||||
$blockSouth = $this->getSide(3);
|
||||
$blockEast = $this->getSide(5);
|
||||
$blockWest = $this->getSide(4);
|
||||
|
||||
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->getLevel()->setBlock($blockNorth, new Air(), true, true);
|
||||
}elseif($blockSouth->getId() === $this->id and $blockSouth->meta !== 0x08){
|
||||
$this->getLevel()->setBlock($blockSouth, new Air(), true, true);
|
||||
}elseif($blockEast->getId() === $this->id and $blockEast->meta !== 0x08){
|
||||
$this->getLevel()->setBlock($blockEast, new Air(), true, true);
|
||||
}elseif($blockWest->getId() === $this->id and $blockWest->meta !== 0x08){
|
||||
$this->getLevel()->setBlock($blockWest, new Air(), true, true);
|
||||
}
|
||||
}else{ //Bottom Part of Bed
|
||||
if($blockNorth->getId() === $this->id and ($blockNorth->meta & 0x08) === 0x08){
|
||||
$this->getLevel()->setBlock($blockNorth, new Air(), true, true);
|
||||
}elseif($blockSouth->getId() === $this->id and ($blockSouth->meta & 0x08) === 0x08){
|
||||
$this->getLevel()->setBlock($blockSouth, new Air(), true, true);
|
||||
}elseif($blockEast->getId() === $this->id and ($blockEast->meta & 0x08) === 0x08){
|
||||
$this->getLevel()->setBlock($blockEast, new Air(), true, true);
|
||||
}elseif($blockWest->getId() === $this->id and ($blockWest->meta & 0x08) === 0x08){
|
||||
$this->getLevel()->setBlock($blockWest, new Air(), true, true);
|
||||
}
|
||||
public function onBreak(Item $item, Player $player = null) : bool{
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true, true);
|
||||
if(($other = $this->getOtherHalf()) !== null){
|
||||
$this->getLevel()->useBreakOn($other, $item, $player, $player !== null); //make sure tiles get removed
|
||||
}
|
||||
$this->getLevel()->setBlock($this, new Air(), true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return [
|
||||
[Item::BED, 0, 1],
|
||||
];
|
||||
public function getDrops(Item $item) : array{
|
||||
if($this->isHeadPart()){
|
||||
$tile = $this->getLevel()->getTile($this);
|
||||
if($tile instanceof TileBed){
|
||||
return [
|
||||
ItemFactory::get($this->getItemId(), $tile->getColor(), 1)
|
||||
];
|
||||
}else{
|
||||
return [
|
||||
ItemFactory::get($this->getItemId(), 14, 1) //Red
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -27,23 +29,23 @@ class Bedrock extends Solid{
|
||||
|
||||
protected $id = self::BEDROCK;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Bedrock";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return -1;
|
||||
}
|
||||
|
||||
public function getResistance(){
|
||||
public function getBlastResistance() : float{
|
||||
return 18000000;
|
||||
}
|
||||
|
||||
public function isBreakable(Item $item){
|
||||
public function isBreakable(Item $item) : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -19,31 +19,35 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
|
||||
class Beetroot extends Crops{
|
||||
|
||||
protected $id = self::BEETROOT_BLOCK;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Beetroot Block";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
$drops = [];
|
||||
public function getDrops(Item $item) : array{
|
||||
if($this->meta >= 0x07){
|
||||
$drops[] = [Item::BEETROOT, 0, 1];
|
||||
$drops[] = [Item::BEETROOT_SEEDS, 0, mt_rand(0, 3)];
|
||||
}else{
|
||||
$drops[] = [Item::BEETROOT_SEEDS, 0, 1];
|
||||
return [
|
||||
ItemFactory::get(Item::BEETROOT, 0, 1),
|
||||
ItemFactory::get(Item::BEETROOT_SEEDS, 0, mt_rand(0, 3))
|
||||
];
|
||||
}
|
||||
|
||||
return $drops;
|
||||
return [
|
||||
ItemFactory::get(Item::BEETROOT_SEEDS, 0, 1)
|
||||
];
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
417
src/pocketmine/block/BlockFactory.php
Normal file
417
src/pocketmine/block/BlockFactory.php
Normal file
@ -0,0 +1,417 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Position;
|
||||
|
||||
/**
|
||||
* Manages block registration and instance creation
|
||||
*/
|
||||
class BlockFactory{
|
||||
/** @var \SplFixedArray<Block> */
|
||||
private static $list = null;
|
||||
/** @var \SplFixedArray<Block> */
|
||||
private static $fullList = null;
|
||||
|
||||
/** @var \SplFixedArray<bool> */
|
||||
public static $solid = null;
|
||||
/** @var \SplFixedArray<bool> */
|
||||
public static $transparent = null;
|
||||
/** @var \SplFixedArray<float> */
|
||||
public static $hardness = null;
|
||||
/** @var \SplFixedArray<int> */
|
||||
public static $light = null;
|
||||
/** @var \SplFixedArray<int> */
|
||||
public static $lightFilter = null;
|
||||
/** @var \SplFixedArray<bool> */
|
||||
public static $diffusesSkyLight = null;
|
||||
/** @var \SplFixedArray<float> */
|
||||
public static $blastResistance = null;
|
||||
|
||||
/**
|
||||
* Initializes the block factory. By default this is called only once on server start, however you may wish to use
|
||||
* this if you need to reset the block factory back to its original defaults for whatever reason.
|
||||
*
|
||||
* @param bool $force
|
||||
*/
|
||||
public static function init(bool $force = false){
|
||||
if(self::$list === null or $force){
|
||||
self::$list = new \SplFixedArray(256);
|
||||
self::$fullList = new \SplFixedArray(4096);
|
||||
|
||||
self::$light = new \SplFixedArray(256);
|
||||
self::$lightFilter = new \SplFixedArray(256);
|
||||
self::$solid = new \SplFixedArray(256);
|
||||
self::$hardness = new \SplFixedArray(256);
|
||||
self::$transparent = new \SplFixedArray(256);
|
||||
self::$diffusesSkyLight = new \SplFixedArray(256);
|
||||
self::$blastResistance = new \SplFixedArray(256);
|
||||
|
||||
self::registerBlock(new Air());
|
||||
self::registerBlock(new Stone());
|
||||
self::registerBlock(new Grass());
|
||||
self::registerBlock(new Dirt());
|
||||
self::registerBlock(new Cobblestone());
|
||||
self::registerBlock(new Planks());
|
||||
self::registerBlock(new Sapling());
|
||||
self::registerBlock(new Bedrock());
|
||||
self::registerBlock(new Water());
|
||||
self::registerBlock(new StillWater());
|
||||
self::registerBlock(new Lava());
|
||||
self::registerBlock(new StillLava());
|
||||
self::registerBlock(new Sand());
|
||||
self::registerBlock(new Gravel());
|
||||
self::registerBlock(new GoldOre());
|
||||
self::registerBlock(new IronOre());
|
||||
self::registerBlock(new CoalOre());
|
||||
self::registerBlock(new Wood());
|
||||
self::registerBlock(new Leaves());
|
||||
self::registerBlock(new Sponge());
|
||||
self::registerBlock(new Glass());
|
||||
self::registerBlock(new LapisOre());
|
||||
self::registerBlock(new Lapis());
|
||||
//TODO: DISPENSER
|
||||
self::registerBlock(new Sandstone());
|
||||
self::registerBlock(new NoteBlock());
|
||||
self::registerBlock(new Bed());
|
||||
self::registerBlock(new PoweredRail());
|
||||
self::registerBlock(new DetectorRail());
|
||||
//TODO: STICKY_PISTON
|
||||
self::registerBlock(new Cobweb());
|
||||
self::registerBlock(new TallGrass());
|
||||
self::registerBlock(new DeadBush());
|
||||
//TODO: PISTON
|
||||
//TODO: PISTONARMCOLLISION
|
||||
self::registerBlock(new Wool());
|
||||
|
||||
self::registerBlock(new Dandelion());
|
||||
self::registerBlock(new Flower());
|
||||
self::registerBlock(new BrownMushroom());
|
||||
self::registerBlock(new RedMushroom());
|
||||
self::registerBlock(new Gold());
|
||||
self::registerBlock(new Iron());
|
||||
self::registerBlock(new DoubleStoneSlab());
|
||||
self::registerBlock(new StoneSlab());
|
||||
self::registerBlock(new Bricks());
|
||||
self::registerBlock(new TNT());
|
||||
self::registerBlock(new Bookshelf());
|
||||
self::registerBlock(new MossyCobblestone());
|
||||
self::registerBlock(new Obsidian());
|
||||
self::registerBlock(new Torch());
|
||||
self::registerBlock(new Fire());
|
||||
self::registerBlock(new MonsterSpawner());
|
||||
self::registerBlock(new WoodenStairs(Block::OAK_STAIRS, 0, "Oak Stairs"));
|
||||
self::registerBlock(new Chest());
|
||||
//TODO: REDSTONE_WIRE
|
||||
self::registerBlock(new DiamondOre());
|
||||
self::registerBlock(new Diamond());
|
||||
self::registerBlock(new CraftingTable());
|
||||
self::registerBlock(new Wheat());
|
||||
self::registerBlock(new Farmland());
|
||||
self::registerBlock(new Furnace());
|
||||
self::registerBlock(new BurningFurnace());
|
||||
self::registerBlock(new SignPost());
|
||||
self::registerBlock(new WoodenDoor(Block::OAK_DOOR_BLOCK, 0, "Oak Door Block", Item::OAK_DOOR));
|
||||
self::registerBlock(new Ladder());
|
||||
self::registerBlock(new Rail());
|
||||
self::registerBlock(new CobblestoneStairs());
|
||||
self::registerBlock(new WallSign());
|
||||
self::registerBlock(new Lever());
|
||||
self::registerBlock(new StonePressurePlate());
|
||||
self::registerBlock(new IronDoor());
|
||||
self::registerBlock(new WoodenPressurePlate());
|
||||
self::registerBlock(new RedstoneOre());
|
||||
self::registerBlock(new GlowingRedstoneOre());
|
||||
self::registerBlock(new RedstoneTorchUnlit());
|
||||
self::registerBlock(new RedstoneTorch());
|
||||
self::registerBlock(new StoneButton());
|
||||
self::registerBlock(new SnowLayer());
|
||||
self::registerBlock(new Ice());
|
||||
self::registerBlock(new Snow());
|
||||
self::registerBlock(new Cactus());
|
||||
self::registerBlock(new Clay());
|
||||
self::registerBlock(new Sugarcane());
|
||||
|
||||
self::registerBlock(new Fence());
|
||||
self::registerBlock(new Pumpkin());
|
||||
self::registerBlock(new Netherrack());
|
||||
self::registerBlock(new SoulSand());
|
||||
self::registerBlock(new Glowstone());
|
||||
//TODO: PORTAL
|
||||
self::registerBlock(new LitPumpkin());
|
||||
self::registerBlock(new Cake());
|
||||
//TODO: REPEATER_BLOCK
|
||||
//TODO: POWERED_REPEATER
|
||||
//TODO: INVISIBLEBEDROCK
|
||||
self::registerBlock(new Trapdoor());
|
||||
//TODO: MONSTER_EGG
|
||||
self::registerBlock(new StoneBricks());
|
||||
self::registerBlock(new BrownMushroomBlock());
|
||||
self::registerBlock(new RedMushroomBlock());
|
||||
self::registerBlock(new IronBars());
|
||||
self::registerBlock(new GlassPane());
|
||||
self::registerBlock(new Melon());
|
||||
self::registerBlock(new PumpkinStem());
|
||||
self::registerBlock(new MelonStem());
|
||||
self::registerBlock(new Vine());
|
||||
self::registerBlock(new FenceGate(Block::OAK_FENCE_GATE, 0, "Oak Fence Gate"));
|
||||
self::registerBlock(new BrickStairs());
|
||||
self::registerBlock(new StoneBrickStairs());
|
||||
self::registerBlock(new Mycelium());
|
||||
self::registerBlock(new WaterLily());
|
||||
self::registerBlock(new NetherBrick(Block::NETHER_BRICK_BLOCK, 0, "Nether Bricks"));
|
||||
self::registerBlock(new NetherBrickFence());
|
||||
self::registerBlock(new NetherBrickStairs());
|
||||
self::registerBlock(new NetherWartPlant());
|
||||
self::registerBlock(new EnchantingTable());
|
||||
self::registerBlock(new BrewingStand());
|
||||
//TODO: CAULDRON_BLOCK
|
||||
//TODO: END_PORTAL
|
||||
self::registerBlock(new EndPortalFrame());
|
||||
self::registerBlock(new EndStone());
|
||||
//TODO: DRAGON_EGG
|
||||
self::registerBlock(new RedstoneLamp());
|
||||
self::registerBlock(new LitRedstoneLamp());
|
||||
//TODO: DROPPER
|
||||
self::registerBlock(new ActivatorRail());
|
||||
self::registerBlock(new CocoaBlock());
|
||||
self::registerBlock(new SandstoneStairs());
|
||||
self::registerBlock(new EmeraldOre());
|
||||
//TODO: ENDER_CHEST
|
||||
self::registerBlock(new TripwireHook());
|
||||
self::registerBlock(new Tripwire());
|
||||
self::registerBlock(new Emerald());
|
||||
self::registerBlock(new WoodenStairs(Block::SPRUCE_STAIRS, 0, "Spruce Stairs"));
|
||||
self::registerBlock(new WoodenStairs(Block::BIRCH_STAIRS, 0, "Birch Stairs"));
|
||||
self::registerBlock(new WoodenStairs(Block::JUNGLE_STAIRS, 0, "Jungle Stairs"));
|
||||
//TODO: COMMAND_BLOCK
|
||||
//TODO: BEACON
|
||||
self::registerBlock(new CobblestoneWall());
|
||||
self::registerBlock(new FlowerPot());
|
||||
self::registerBlock(new Carrot());
|
||||
self::registerBlock(new Potato());
|
||||
self::registerBlock(new WoodenButton());
|
||||
self::registerBlock(new Skull());
|
||||
self::registerBlock(new Anvil());
|
||||
self::registerBlock(new TrappedChest());
|
||||
self::registerBlock(new WeightedPressurePlateLight());
|
||||
self::registerBlock(new WeightedPressurePlateHeavy());
|
||||
//TODO: COMPARATOR_BLOCK
|
||||
//TODO: POWERED_COMPARATOR
|
||||
self::registerBlock(new DaylightSensor());
|
||||
self::registerBlock(new Redstone());
|
||||
self::registerBlock(new NetherQuartzOre());
|
||||
//TODO: HOPPER_BLOCK
|
||||
self::registerBlock(new Quartz());
|
||||
self::registerBlock(new QuartzStairs());
|
||||
self::registerBlock(new DoubleWoodenSlab());
|
||||
self::registerBlock(new WoodenSlab());
|
||||
self::registerBlock(new StainedClay());
|
||||
self::registerBlock(new StainedGlassPane());
|
||||
self::registerBlock(new Leaves2());
|
||||
self::registerBlock(new Wood2());
|
||||
self::registerBlock(new WoodenStairs(Block::ACACIA_STAIRS, 0, "Acacia Stairs"));
|
||||
self::registerBlock(new WoodenStairs(Block::DARK_OAK_STAIRS, 0, "Dark Oak Stairs"));
|
||||
//TODO: SLIME
|
||||
|
||||
self::registerBlock(new IronTrapdoor());
|
||||
self::registerBlock(new Prismarine());
|
||||
self::registerBlock(new SeaLantern());
|
||||
self::registerBlock(new HayBale());
|
||||
self::registerBlock(new Carpet());
|
||||
self::registerBlock(new HardenedClay());
|
||||
self::registerBlock(new Coal());
|
||||
self::registerBlock(new PackedIce());
|
||||
self::registerBlock(new DoublePlant());
|
||||
|
||||
//TODO: DAYLIGHT_DETECTOR_INVERTED
|
||||
//TODO: RED_SANDSTONE
|
||||
//TODO: RED_SANDSTONE_STAIRS
|
||||
//TODO: DOUBLE_STONE_SLAB2
|
||||
//TODO: STONE_SLAB2
|
||||
self::registerBlock(new FenceGate(Block::SPRUCE_FENCE_GATE, 0, "Spruce Fence Gate"));
|
||||
self::registerBlock(new FenceGate(Block::BIRCH_FENCE_GATE, 0, "Birch Fence Gate"));
|
||||
self::registerBlock(new FenceGate(Block::JUNGLE_FENCE_GATE, 0, "Jungle Fence Gate"));
|
||||
self::registerBlock(new FenceGate(Block::DARK_OAK_FENCE_GATE, 0, "Dark Oak Fence Gate"));
|
||||
self::registerBlock(new FenceGate(Block::ACACIA_FENCE_GATE, 0, "Acacia Fence Gate"));
|
||||
//TODO: REPEATING_COMMAND_BLOCK
|
||||
//TODO: CHAIN_COMMAND_BLOCK
|
||||
|
||||
self::registerBlock(new WoodenDoor(Block::SPRUCE_DOOR_BLOCK, 0, "Spruce Door Block", Item::SPRUCE_DOOR));
|
||||
self::registerBlock(new WoodenDoor(Block::BIRCH_DOOR_BLOCK, 0, "Birch Door Block", Item::BIRCH_DOOR));
|
||||
self::registerBlock(new WoodenDoor(Block::JUNGLE_DOOR_BLOCK, 0, "Jungle Door Block", Item::JUNGLE_DOOR));
|
||||
self::registerBlock(new WoodenDoor(Block::ACACIA_DOOR_BLOCK, 0, "Acacia Door Block", Item::ACACIA_DOOR));
|
||||
self::registerBlock(new WoodenDoor(Block::DARK_OAK_DOOR_BLOCK, 0, "Dark Oak Door Block", Item::DARK_OAK_DOOR));
|
||||
self::registerBlock(new GrassPath());
|
||||
self::registerBlock(new ItemFrame());
|
||||
//TODO: CHORUS_FLOWER
|
||||
//TODO: PURPUR_BLOCK
|
||||
|
||||
//TODO: PURPUR_STAIRS
|
||||
|
||||
//TODO: END_BRICKS
|
||||
//TODO: FROSTED_ICE
|
||||
self::registerBlock(new EndRod());
|
||||
//TODO: END_GATEWAY
|
||||
|
||||
self::registerBlock(new Magma());
|
||||
self::registerBlock(new NetherWartBlock());
|
||||
self::registerBlock(new NetherBrick(Block::RED_NETHER_BRICK, 0, "Red Nether Bricks"));
|
||||
self::registerBlock(new BoneBlock());
|
||||
|
||||
//TODO: SHULKER_BOX
|
||||
self::registerBlock(new GlazedTerracotta(Block::PURPLE_GLAZED_TERRACOTTA, 0, "Purple Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::WHITE_GLAZED_TERRACOTTA, 0, "White Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::ORANGE_GLAZED_TERRACOTTA, 0, "Orange Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::MAGENTA_GLAZED_TERRACOTTA, 0, "Magenta Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::LIGHT_BLUE_GLAZED_TERRACOTTA, 0, "Light Blue Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::YELLOW_GLAZED_TERRACOTTA, 0, "Yellow Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::LIME_GLAZED_TERRACOTTA, 0, "Lime Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::PINK_GLAZED_TERRACOTTA, 0, "Pink Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::GRAY_GLAZED_TERRACOTTA, 0, "Grey Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::SILVER_GLAZED_TERRACOTTA, 0, "Light Grey Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::CYAN_GLAZED_TERRACOTTA, 0, "Cyan Glazed Terracotta"));
|
||||
|
||||
self::registerBlock(new GlazedTerracotta(Block::BLUE_GLAZED_TERRACOTTA, 0, "Blue Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::BROWN_GLAZED_TERRACOTTA, 0, "Brown Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::GREEN_GLAZED_TERRACOTTA, 0, "Green Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::RED_GLAZED_TERRACOTTA, 0, "Red Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::BLACK_GLAZED_TERRACOTTA, 0, "Black Glazed Terracotta"));
|
||||
self::registerBlock(new Concrete());
|
||||
//TODO: CONCRETEPOWDER
|
||||
|
||||
//TODO: CHORUS_PLANT
|
||||
self::registerBlock(new StainedGlass());
|
||||
|
||||
self::registerBlock(new Podzol());
|
||||
self::registerBlock(new Beetroot());
|
||||
self::registerBlock(new Stonecutter());
|
||||
self::registerBlock(new GlowingObsidian());
|
||||
self::registerBlock(new NetherReactor());
|
||||
//TODO: INFO_UPDATE
|
||||
//TODO: INFO_UPDATE2
|
||||
//TODO: MOVINGBLOCK
|
||||
//TODO: OBSERVER
|
||||
|
||||
//TODO: RESERVED6
|
||||
|
||||
foreach(self::$list as $id => $block){
|
||||
if($block === null){
|
||||
self::registerBlock(new UnknownBlock($id));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a block type into the index. Plugins may use this method to register new block types or override
|
||||
* existing ones.
|
||||
*
|
||||
* NOTE: If you are registering a new block type, you will need to add it to the creative inventory yourself - it
|
||||
* will not automatically appear there.
|
||||
*
|
||||
* @param Block $block
|
||||
* @param bool $override Whether to override existing registrations
|
||||
*
|
||||
* @throws \RuntimeException if something attempted to override an already-registered block without specifying the
|
||||
* $override parameter.
|
||||
*/
|
||||
public static function registerBlock(Block $block, bool $override = false){
|
||||
$id = $block->getId();
|
||||
|
||||
if(!$override and self::isRegistered($id)){
|
||||
throw new \RuntimeException("Trying to overwrite an already registered block");
|
||||
}
|
||||
|
||||
self::$list[$id] = clone $block;
|
||||
|
||||
for($meta = 0; $meta < 16; ++$meta){
|
||||
$variant = clone $block;
|
||||
$variant->setDamage($meta);
|
||||
self::$fullList[($id << 4) | $meta] = $variant;
|
||||
}
|
||||
|
||||
self::$solid[$id] = $block->isSolid();
|
||||
self::$transparent[$id] = $block->isTransparent();
|
||||
self::$hardness[$id] = $block->getHardness();
|
||||
self::$light[$id] = $block->getLightLevel();
|
||||
self::$lightFilter[$id] = $block->getLightFilter() + 1; //opacity plus 1 standard light filter
|
||||
self::$diffusesSkyLight[$id] = $block->diffusesSkyLight();
|
||||
self::$blastResistance[$id] = $block->getBlastResistance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new Block instance with the specified ID, meta and position.
|
||||
*
|
||||
* @param int $id
|
||||
* @param int $meta
|
||||
* @param Position $pos
|
||||
*
|
||||
* @return Block
|
||||
*/
|
||||
public static function get(int $id, int $meta = 0, Position $pos = null) : Block{
|
||||
if($meta < 0 or $meta > 0xf){
|
||||
throw new \InvalidArgumentException("Block meta value $meta is out of bounds");
|
||||
}
|
||||
|
||||
try{
|
||||
if(self::$fullList !== null){
|
||||
$block = clone self::$fullList[($id << 4) | $meta];
|
||||
}else{
|
||||
$block = new UnknownBlock($id, $meta);
|
||||
}
|
||||
}catch(\RuntimeException $e){
|
||||
throw new \InvalidArgumentException("Block ID $id is out of bounds");
|
||||
}
|
||||
|
||||
if($pos !== null){
|
||||
$block->x = $pos->x;
|
||||
$block->y = $pos->y;
|
||||
$block->z = $pos->z;
|
||||
$block->level = $pos->level;
|
||||
}
|
||||
|
||||
return $block;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @return \SplFixedArray
|
||||
*/
|
||||
public static function getBlockStatesArray() : \SplFixedArray{
|
||||
return self::$fullList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a specified block ID is already registered in the block factory.
|
||||
*
|
||||
* @param int $id
|
||||
* @return bool
|
||||
*/
|
||||
public static function isRegistered(int $id) : bool{
|
||||
$b = self::$list[$id];
|
||||
return $b !== null and !($b instanceof UnknownBlock);
|
||||
}
|
||||
}
|
279
src/pocketmine/block/BlockIds.php
Normal file
279
src/pocketmine/block/BlockIds.php
Normal file
@ -0,0 +1,279 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
interface BlockIds{
|
||||
|
||||
const AIR = 0;
|
||||
const STONE = 1;
|
||||
const GRASS = 2;
|
||||
const DIRT = 3;
|
||||
const COBBLESTONE = 4;
|
||||
const PLANKS = 5, WOODEN_PLANKS = 5;
|
||||
const SAPLING = 6;
|
||||
const BEDROCK = 7;
|
||||
const FLOWING_WATER = 8;
|
||||
const STILL_WATER = 9, WATER = 9;
|
||||
const FLOWING_LAVA = 10;
|
||||
const LAVA = 11, STILL_LAVA = 11;
|
||||
const SAND = 12;
|
||||
const GRAVEL = 13;
|
||||
const GOLD_ORE = 14;
|
||||
const IRON_ORE = 15;
|
||||
const COAL_ORE = 16;
|
||||
const LOG = 17, WOOD = 17;
|
||||
const LEAVES = 18;
|
||||
const SPONGE = 19;
|
||||
const GLASS = 20;
|
||||
const LAPIS_ORE = 21;
|
||||
const LAPIS_BLOCK = 22;
|
||||
const DISPENSER = 23;
|
||||
const SANDSTONE = 24;
|
||||
const NOTEBLOCK = 25, NOTE_BLOCK = 25;
|
||||
const BED_BLOCK = 26;
|
||||
const GOLDEN_RAIL = 27, POWERED_RAIL = 27;
|
||||
const DETECTOR_RAIL = 28;
|
||||
const STICKY_PISTON = 29;
|
||||
const COBWEB = 30, WEB = 30;
|
||||
const TALLGRASS = 31, TALL_GRASS = 31;
|
||||
const DEADBUSH = 32, DEAD_BUSH = 32;
|
||||
const PISTON = 33;
|
||||
const PISTONARMCOLLISION = 34, PISTON_ARM_COLLISION = 34;
|
||||
const WOOL = 35;
|
||||
|
||||
const DANDELION = 37, YELLOW_FLOWER = 37;
|
||||
const POPPY = 38, RED_FLOWER = 38;
|
||||
const BROWN_MUSHROOM = 39;
|
||||
const RED_MUSHROOM = 40;
|
||||
const GOLD_BLOCK = 41;
|
||||
const IRON_BLOCK = 42;
|
||||
const DOUBLE_STONE_SLAB = 43;
|
||||
const STONE_SLAB = 44;
|
||||
const BRICK_BLOCK = 45;
|
||||
const TNT = 46;
|
||||
const BOOKSHELF = 47;
|
||||
const MOSSY_COBBLESTONE = 48, MOSS_STONE = 48;
|
||||
const OBSIDIAN = 49;
|
||||
const TORCH = 50;
|
||||
const FIRE = 51;
|
||||
const MOB_SPAWNER = 52, MONSTER_SPAWNER = 52;
|
||||
const OAK_STAIRS = 53, WOODEN_STAIRS = 53;
|
||||
const CHEST = 54;
|
||||
const REDSTONE_WIRE = 55;
|
||||
const DIAMOND_ORE = 56;
|
||||
const DIAMOND_BLOCK = 57;
|
||||
const CRAFTING_TABLE = 58, WORKBENCH = 58;
|
||||
const WHEAT_BLOCK = 59;
|
||||
const FARMLAND = 60;
|
||||
const FURNACE = 61;
|
||||
const BURNING_FURNACE = 62, LIT_FURNACE = 62;
|
||||
const SIGN_POST = 63, STANDING_SIGN = 63;
|
||||
const OAK_DOOR_BLOCK = 64, WOODEN_DOOR_BLOCK = 64;
|
||||
const LADDER = 65;
|
||||
const RAIL = 66;
|
||||
const COBBLESTONE_STAIRS = 67, STONE_STAIRS = 67;
|
||||
const WALL_SIGN = 68;
|
||||
const LEVER = 69;
|
||||
const STONE_PRESSURE_PLATE = 70;
|
||||
const IRON_DOOR_BLOCK = 71;
|
||||
const WOODEN_PRESSURE_PLATE = 72;
|
||||
const REDSTONE_ORE = 73;
|
||||
const GLOWING_REDSTONE_ORE = 74, LIT_REDSTONE_ORE = 74;
|
||||
const UNLIT_REDSTONE_TORCH = 75;
|
||||
const LIT_REDSTONE_TORCH = 76, REDSTONE_TORCH = 76;
|
||||
const STONE_BUTTON = 77;
|
||||
const SNOW_LAYER = 78;
|
||||
const ICE = 79;
|
||||
const SNOW = 80, SNOW_BLOCK = 80;
|
||||
const CACTUS = 81;
|
||||
const CLAY_BLOCK = 82;
|
||||
const REEDS_BLOCK = 83, SUGARCANE_BLOCK = 83;
|
||||
const JUKEBOX = 84;
|
||||
const FENCE = 85;
|
||||
const PUMPKIN = 86;
|
||||
const NETHERRACK = 87;
|
||||
const SOUL_SAND = 88;
|
||||
const GLOWSTONE = 89;
|
||||
const PORTAL = 90;
|
||||
const JACK_O_LANTERN = 91, LIT_PUMPKIN = 91;
|
||||
const CAKE_BLOCK = 92;
|
||||
const REPEATER_BLOCK = 93, UNPOWERED_REPEATER = 93;
|
||||
const POWERED_REPEATER = 94;
|
||||
const INVISIBLEBEDROCK = 95, INVISIBLE_BEDROCK = 95;
|
||||
const TRAPDOOR = 96, WOODEN_TRAPDOOR = 96;
|
||||
const MONSTER_EGG = 97;
|
||||
const STONEBRICK = 98, STONE_BRICK = 98, STONE_BRICKS = 98;
|
||||
const BROWN_MUSHROOM_BLOCK = 99;
|
||||
const RED_MUSHROOM_BLOCK = 100;
|
||||
const IRON_BARS = 101;
|
||||
const GLASS_PANE = 102;
|
||||
const MELON_BLOCK = 103;
|
||||
const PUMPKIN_STEM = 104;
|
||||
const MELON_STEM = 105;
|
||||
const VINE = 106, VINES = 106;
|
||||
const FENCE_GATE = 107, OAK_FENCE_GATE = 107;
|
||||
const BRICK_STAIRS = 108;
|
||||
const STONE_BRICK_STAIRS = 109;
|
||||
const MYCELIUM = 110;
|
||||
const LILY_PAD = 111, WATERLILY = 111, WATER_LILY = 111;
|
||||
const NETHER_BRICK_BLOCK = 112;
|
||||
const NETHER_BRICK_FENCE = 113;
|
||||
const NETHER_BRICK_STAIRS = 114;
|
||||
const NETHER_WART_PLANT = 115;
|
||||
const ENCHANTING_TABLE = 116, ENCHANTMENT_TABLE = 116;
|
||||
const BREWING_STAND_BLOCK = 117;
|
||||
const CAULDRON_BLOCK = 118;
|
||||
const END_PORTAL = 119;
|
||||
const END_PORTAL_FRAME = 120;
|
||||
const END_STONE = 121;
|
||||
const DRAGON_EGG = 122;
|
||||
const REDSTONE_LAMP = 123;
|
||||
const LIT_REDSTONE_LAMP = 124;
|
||||
const DROPPER = 125;
|
||||
const ACTIVATOR_RAIL = 126;
|
||||
const COCOA = 127, COCOA_BLOCK = 127;
|
||||
const SANDSTONE_STAIRS = 128;
|
||||
const EMERALD_ORE = 129;
|
||||
const ENDER_CHEST = 130;
|
||||
const TRIPWIRE_HOOK = 131;
|
||||
const TRIPWIRE = 132, TRIP_WIRE = 132;
|
||||
const EMERALD_BLOCK = 133;
|
||||
const SPRUCE_STAIRS = 134;
|
||||
const BIRCH_STAIRS = 135;
|
||||
const JUNGLE_STAIRS = 136;
|
||||
const COMMAND_BLOCK = 137;
|
||||
const BEACON = 138;
|
||||
const COBBLESTONE_WALL = 139, STONE_WALL = 139;
|
||||
const FLOWER_POT_BLOCK = 140;
|
||||
const CARROTS = 141, CARROT_BLOCK = 141;
|
||||
const POTATOES = 142, POTATO_BLOCK = 142;
|
||||
const WOODEN_BUTTON = 143;
|
||||
const MOB_HEAD_BLOCK = 144, SKULL_BLOCK = 144;
|
||||
const ANVIL = 145;
|
||||
const TRAPPED_CHEST = 146;
|
||||
const LIGHT_WEIGHTED_PRESSURE_PLATE = 147;
|
||||
const HEAVY_WEIGHTED_PRESSURE_PLATE = 148;
|
||||
const COMPARATOR_BLOCK = 149, UNPOWERED_COMPARATOR = 149;
|
||||
const POWERED_COMPARATOR = 150;
|
||||
const DAYLIGHT_DETECTOR = 151, DAYLIGHT_SENSOR = 151;
|
||||
const REDSTONE_BLOCK = 152;
|
||||
const NETHER_QUARTZ_ORE = 153, QUARTZ_ORE = 153;
|
||||
const HOPPER_BLOCK = 154;
|
||||
const QUARTZ_BLOCK = 155;
|
||||
const QUARTZ_STAIRS = 156;
|
||||
const DOUBLE_WOODEN_SLAB = 157;
|
||||
const WOODEN_SLAB = 158;
|
||||
const STAINED_CLAY = 159, STAINED_HARDENED_CLAY = 159, TERRACOTTA = 159;
|
||||
const STAINED_GLASS_PANE = 160;
|
||||
const LEAVES2 = 161;
|
||||
const LOG2 = 162, WOOD2 = 162;
|
||||
const ACACIA_STAIRS = 163;
|
||||
const DARK_OAK_STAIRS = 164;
|
||||
const SLIME = 165, SLIME_BLOCK = 165;
|
||||
|
||||
const IRON_TRAPDOOR = 167;
|
||||
const PRISMARINE = 168;
|
||||
const SEALANTERN = 169, SEA_LANTERN = 169;
|
||||
const HAY_BALE = 170, HAY_BLOCK = 170;
|
||||
const CARPET = 171;
|
||||
const HARDENED_CLAY = 172;
|
||||
const COAL_BLOCK = 173;
|
||||
const PACKED_ICE = 174;
|
||||
const DOUBLE_PLANT = 175;
|
||||
const STANDING_BANNER = 176;
|
||||
const WALL_BANNER = 177;
|
||||
const DAYLIGHT_DETECTOR_INVERTED = 178, DAYLIGHT_SENSOR_INVERTED = 178;
|
||||
const RED_SANDSTONE = 179;
|
||||
const RED_SANDSTONE_STAIRS = 180;
|
||||
const DOUBLE_STONE_SLAB2 = 181;
|
||||
const STONE_SLAB2 = 182;
|
||||
const SPRUCE_FENCE_GATE = 183;
|
||||
const BIRCH_FENCE_GATE = 184;
|
||||
const JUNGLE_FENCE_GATE = 185;
|
||||
const DARK_OAK_FENCE_GATE = 186;
|
||||
const ACACIA_FENCE_GATE = 187;
|
||||
const REPEATING_COMMAND_BLOCK = 188;
|
||||
const CHAIN_COMMAND_BLOCK = 189;
|
||||
|
||||
const SPRUCE_DOOR_BLOCK = 193;
|
||||
const BIRCH_DOOR_BLOCK = 194;
|
||||
const JUNGLE_DOOR_BLOCK = 195;
|
||||
const ACACIA_DOOR_BLOCK = 196;
|
||||
const DARK_OAK_DOOR_BLOCK = 197;
|
||||
const GRASS_PATH = 198;
|
||||
const FRAME_BLOCK = 199, ITEM_FRAME_BLOCK = 199;
|
||||
const CHORUS_FLOWER = 200;
|
||||
const PURPUR_BLOCK = 201;
|
||||
|
||||
const PURPUR_STAIRS = 203;
|
||||
|
||||
const UNDYED_SHULKER_BOX = 205;
|
||||
const END_BRICKS = 206;
|
||||
const FROSTED_ICE = 207;
|
||||
const END_ROD = 208;
|
||||
const END_GATEWAY = 209;
|
||||
|
||||
const MAGMA = 213;
|
||||
const NETHER_WART_BLOCK = 214;
|
||||
const RED_NETHER_BRICK = 215;
|
||||
const BONE_BLOCK = 216;
|
||||
|
||||
const SHULKER_BOX = 218;
|
||||
const PURPLE_GLAZED_TERRACOTTA = 219;
|
||||
const WHITE_GLAZED_TERRACOTTA = 220;
|
||||
const ORANGE_GLAZED_TERRACOTTA = 221;
|
||||
const MAGENTA_GLAZED_TERRACOTTA = 222;
|
||||
const LIGHT_BLUE_GLAZED_TERRACOTTA = 223;
|
||||
const YELLOW_GLAZED_TERRACOTTA = 224;
|
||||
const LIME_GLAZED_TERRACOTTA = 225;
|
||||
const PINK_GLAZED_TERRACOTTA = 226;
|
||||
const GRAY_GLAZED_TERRACOTTA = 227;
|
||||
const SILVER_GLAZED_TERRACOTTA = 228;
|
||||
const CYAN_GLAZED_TERRACOTTA = 229;
|
||||
|
||||
const BLUE_GLAZED_TERRACOTTA = 231;
|
||||
const BROWN_GLAZED_TERRACOTTA = 232;
|
||||
const GREEN_GLAZED_TERRACOTTA = 233;
|
||||
const RED_GLAZED_TERRACOTTA = 234;
|
||||
const BLACK_GLAZED_TERRACOTTA = 235;
|
||||
const CONCRETE = 236;
|
||||
const CONCRETEPOWDER = 237, CONCRETE_POWDER = 237;
|
||||
|
||||
const CHORUS_PLANT = 240;
|
||||
const STAINED_GLASS = 241;
|
||||
|
||||
const PODZOL = 243;
|
||||
const BEETROOT_BLOCK = 244;
|
||||
const STONECUTTER = 245;
|
||||
const GLOWINGOBSIDIAN = 246, GLOWING_OBSIDIAN = 246;
|
||||
const NETHERREACTOR = 247, NETHER_REACTOR = 247;
|
||||
const INFO_UPDATE = 248;
|
||||
const INFO_UPDATE2 = 249;
|
||||
const MOVINGBLOCK = 250, MOVING_BLOCK = 250;
|
||||
const OBSERVER = 251;
|
||||
const STRUCTURE_BLOCK = 252;
|
||||
|
||||
const RESERVED6 = 255;
|
||||
|
||||
}
|
69
src/pocketmine/block/BoneBlock.php
Normal file
69
src/pocketmine/block/BoneBlock.php
Normal file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\PillarRotationHelper;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class BoneBlock extends Solid{
|
||||
|
||||
protected $id = Block::BONE_BLOCK;
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName() : string{
|
||||
return "Bone Block";
|
||||
}
|
||||
|
||||
public function getHardness() : float{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$this->meta = PillarRotationHelper::getMetaFromFace($this->meta, $face);
|
||||
return $this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
}
|
||||
|
||||
public function getVariantBitmask() : int{
|
||||
return 0x03;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
@ -19,29 +19,42 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
class Bookshelf extends Solid{
|
||||
|
||||
protected $id = self::BOOKSHELF;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Bookshelf";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 1.5;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_AXE;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
return [
|
||||
ItemFactory::get(Item::BOOK, 0, 3)
|
||||
];
|
||||
}
|
||||
|
||||
public function getFuelTime() : int{
|
||||
return 300;
|
||||
}
|
||||
|
||||
}
|
@ -19,28 +19,35 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
class BrewingStand extends Transparent{
|
||||
|
||||
protected $id = self::BREWING_STAND;
|
||||
|
||||
public function __construct(){
|
||||
protected $id = self::BREWING_STAND_BLOCK;
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Brewing Stand";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.5;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//TODO
|
||||
}
|
@ -19,8 +19,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
@ -28,23 +29,23 @@ class BrickStairs extends Stair{
|
||||
|
||||
protected $id = self::BRICK_STAIRS;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function getResistance(){
|
||||
public function getBlastResistance() : float{
|
||||
return 30;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Brick Stairs";
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -26,35 +28,33 @@ use pocketmine\item\Tool;
|
||||
|
||||
class Bricks extends Solid{
|
||||
|
||||
protected $id = self::BRICKS_BLOCK;
|
||||
|
||||
public function __construct(){
|
||||
protected $id = self::BRICK_BLOCK;
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function getResistance(){
|
||||
public function getBlastResistance() : float{
|
||||
return 30;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Bricks";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return [
|
||||
[Item::BRICKS_BLOCK, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,53 +19,19 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\Player;
|
||||
|
||||
class BrownMushroom extends Flowable{
|
||||
class BrownMushroom extends RedMushroom{
|
||||
|
||||
protected $id = self::BROWN_MUSHROOM;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Brown Mushroom";
|
||||
}
|
||||
|
||||
public function getLightLevel(){
|
||||
public function getLightLevel() : int{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent() === true){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
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->getLevel()->setBlock($block, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getBoundingBox(){
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -19,34 +19,23 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\inventory;
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
|
||||
interface Transaction{
|
||||
class BrownMushroomBlock extends RedMushroomBlock{
|
||||
|
||||
/**
|
||||
* @return Inventory
|
||||
*/
|
||||
public function getInventory();
|
||||
protected $id = Block::BROWN_MUSHROOM_BLOCK;
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getSlot();
|
||||
public function getName() : string{
|
||||
return "Brown Mushroom Block";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Item
|
||||
*/
|
||||
public function getSourceItem();
|
||||
|
||||
/**
|
||||
* @return Item
|
||||
*/
|
||||
public function getTargetItem();
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getCreationTime();
|
||||
public function getDrops(Item $item) : array{
|
||||
return [
|
||||
Item::get(Item::BROWN_MUSHROOM, 0, mt_rand(0, 2))
|
||||
];
|
||||
}
|
||||
}
|
@ -19,56 +19,55 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\NBT;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\tag\ListTag;
|
||||
use pocketmine\nbt\tag\IntTag;
|
||||
use pocketmine\nbt\tag\ListTag;
|
||||
use pocketmine\nbt\tag\StringTag;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\tile\Furnace;
|
||||
use pocketmine\tile\Furnace as TileFurnace;
|
||||
use pocketmine\tile\Tile;
|
||||
|
||||
class BurningFurnace extends Solid{
|
||||
|
||||
protected $id = self::BURNING_FURNACE;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Burning Furnace";
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 3.5;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getLightLevel(){
|
||||
public function getLightLevel() : int{
|
||||
return 13;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$faces = [
|
||||
0 => 4,
|
||||
1 => 2,
|
||||
2 => 5,
|
||||
3 => 3,
|
||||
3 => 3
|
||||
];
|
||||
$this->meta = $faces[$player instanceof Player ? $player->getDirection() : 0];
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
$nbt = new CompoundTag("", [
|
||||
new ListTag("Items", []),
|
||||
new StringTag("id", Tile::FURNACE),
|
||||
@ -88,24 +87,15 @@ class BurningFurnace extends Solid{
|
||||
}
|
||||
}
|
||||
|
||||
Tile::createTile("Furnace", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt);
|
||||
Tile::createTile("Furnace", $this->getLevel(), $nbt);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onBreak(Item $item){
|
||||
$this->getLevel()->setBlock($this, new Air(), true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($player instanceof Player){
|
||||
$t = $this->getLevel()->getTile($this);
|
||||
$furnace = false;
|
||||
if($t instanceof Furnace){
|
||||
$furnace = $t;
|
||||
}else{
|
||||
$furnace = $this->getLevel()->getTile($this);
|
||||
if(!($furnace instanceof TileFurnace)){
|
||||
$nbt = new CompoundTag("", [
|
||||
new ListTag("Items", []),
|
||||
new StringTag("id", Tile::FURNACE),
|
||||
@ -114,7 +104,7 @@ class BurningFurnace extends Solid{
|
||||
new IntTag("z", $this->z)
|
||||
]);
|
||||
$nbt->Items->setTagType(NBT::TAG_Compound);
|
||||
$furnace = Tile::createTile("Furnace", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt);
|
||||
$furnace = Tile::createTile("Furnace", $this->getLevel(), $nbt);
|
||||
}
|
||||
|
||||
if(isset($furnace->namedtag->Lock) and $furnace->namedtag->Lock instanceof StringTag){
|
||||
@ -123,22 +113,21 @@ class BurningFurnace extends Solid{
|
||||
}
|
||||
}
|
||||
|
||||
if($player->isCreative()){
|
||||
return true;
|
||||
}
|
||||
|
||||
$player->addWindow($furnace->getInventory());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
$drops = [];
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
$drops[] = [Item::FURNACE, 0, 1];
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return $drops;
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
@ -36,19 +38,19 @@ class Cactus extends Transparent{
|
||||
|
||||
protected $id = self::CACTUS;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.4;
|
||||
}
|
||||
|
||||
public function hasEntityCollision(){
|
||||
public function hasEntityCollision() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Cactus";
|
||||
}
|
||||
|
||||
@ -64,14 +66,18 @@ class Cactus extends Transparent{
|
||||
);
|
||||
}
|
||||
|
||||
public function onEntityCollide(Entity $entity){
|
||||
$ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_CONTACT, 1);
|
||||
$entity->attack($ev->getFinalDamage(), $ev);
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
public function onEntityCollide(Entity $entity){
|
||||
$ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_CONTACT, 1);
|
||||
$entity->attack($ev);
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
$down = $this->getSide(0);
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() !== self::SAND and $down->getId() !== self::CACTUS){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
}else{
|
||||
@ -83,12 +89,12 @@ class Cactus extends Transparent{
|
||||
}
|
||||
}
|
||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
if($this->getSide(0)->getId() !== self::CACTUS){
|
||||
if($this->meta == 0x0F){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() !== self::CACTUS){
|
||||
if($this->meta === 0x0f){
|
||||
for($y = 1; $y < 3; ++$y){
|
||||
$b = $this->getLevel()->getBlock(new Vector3($this->x, $this->y + $y, $this->z));
|
||||
if($b->getId() === self::AIR){
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($b, new Cactus()));
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($b, BlockFactory::get(Block::CACTUS)));
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($b, $ev->getNewState(), true);
|
||||
}
|
||||
@ -106,13 +112,13 @@ class Cactus extends Transparent{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === self::SAND or $down->getId() === self::CACTUS){
|
||||
$block0 = $this->getSide(2);
|
||||
$block1 = $this->getSide(3);
|
||||
$block2 = $this->getSide(4);
|
||||
$block3 = $this->getSide(5);
|
||||
$block0 = $this->getSide(Vector3::SIDE_NORTH);
|
||||
$block1 = $this->getSide(Vector3::SIDE_SOUTH);
|
||||
$block2 = $this->getSide(Vector3::SIDE_WEST);
|
||||
$block3 = $this->getSide(Vector3::SIDE_EAST);
|
||||
if($block0->isTransparent() === true and $block1->isTransparent() === true and $block2->isTransparent() === true and $block3->isTransparent() === true){
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
|
||||
@ -123,9 +129,7 @@ class Cactus extends Transparent{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return [
|
||||
[$this->id, 0, 1],
|
||||
];
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Effect;
|
||||
@ -27,34 +29,31 @@ use pocketmine\item\FoodSource;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Cake extends Transparent implements FoodSource{
|
||||
|
||||
protected $id = self::CAKE_BLOCK;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.5;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Cake Block";
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox(){
|
||||
|
||||
$f = (1 + $this->getDamage() * 2) / 16;
|
||||
$f = $this->getDamage() * 0.125; //1 slice width
|
||||
|
||||
return new AxisAlignedBB(
|
||||
$this->x + $f,
|
||||
$this->x + 0.0625 + $f,
|
||||
$this->y,
|
||||
$this->z + 0.0625,
|
||||
$this->x + 1 - 0.0625,
|
||||
@ -63,10 +62,10 @@ class Cake extends Transparent implements FoodSource{
|
||||
);
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() !== self::AIR){
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -74,10 +73,10 @@ class Cake extends Transparent implements FoodSource{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->getId() === self::AIR){ //Replace with common break method
|
||||
$this->getLevel()->setBlock($this, new Air(), true);
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() === self::AIR){ //Replace with common break method
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
@ -86,15 +85,22 @@ class Cake extends Transparent implements FoodSource{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
if($player instanceof Player and $player->getHealth() < $player->getMaxHealth()){
|
||||
$ev = new EntityEatBlockEvent($player, $this);
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
//TODO: refactor this into generic food handling
|
||||
if($player instanceof Player and $player->getFood() < $player->getMaxFood()){
|
||||
$player->getServer()->getPluginManager()->callEvent($ev = new EntityEatBlockEvent($player, $this));
|
||||
|
||||
if(!$ev->isCancelled()){
|
||||
$player->addFood($ev->getFoodRestore());
|
||||
$player->addSaturation($ev->getSaturationRestore());
|
||||
foreach($ev->getAdditionalEffects() as $effect){
|
||||
$player->addEffect($effect);
|
||||
}
|
||||
|
||||
$this->getLevel()->setBlock($this, $ev->getResidue());
|
||||
return true;
|
||||
}
|
||||
@ -114,8 +120,8 @@ class Cake extends Transparent implements FoodSource{
|
||||
public function getResidue(){
|
||||
$clone = clone $this;
|
||||
$clone->meta++;
|
||||
if($clone->meta >= 0x06){
|
||||
$clone = new Air();
|
||||
if($clone->meta > 0x06){
|
||||
$clone = BlockFactory::get(Block::AIR);
|
||||
}
|
||||
return $clone;
|
||||
}
|
||||
|
@ -19,49 +19,35 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\ColorBlockMetaHelper;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Carpet extends Flowable{
|
||||
|
||||
protected $id = self::CARPET;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.1;
|
||||
}
|
||||
|
||||
public function isSolid(){
|
||||
public function isSolid() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
static $names = [
|
||||
0 => "White Carpet",
|
||||
1 => "Orange Carpet",
|
||||
2 => "Magenta Carpet",
|
||||
3 => "Light Blue Carpet",
|
||||
4 => "Yellow Carpet",
|
||||
5 => "Lime Carpet",
|
||||
6 => "Pink Carpet",
|
||||
7 => "Gray Carpet",
|
||||
8 => "Light Gray Carpet",
|
||||
9 => "Cyan Carpet",
|
||||
10 => "Purple Carpet",
|
||||
11 => "Blue Carpet",
|
||||
12 => "Brown Carpet",
|
||||
13 => "Green Carpet",
|
||||
14 => "Red Carpet",
|
||||
15 => "Black Carpet",
|
||||
];
|
||||
return $names[$this->meta & 0x0f];
|
||||
public function getName() : string{
|
||||
return ColorBlockMetaHelper::getColorFromMeta($this->meta) . " Carpet";
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox(){
|
||||
@ -76,10 +62,10 @@ class Carpet extends Flowable{
|
||||
);
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() !== self::AIR){
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -87,9 +73,9 @@ class Carpet extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->getId() === self::AIR){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() === self::AIR){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
|
@ -19,30 +19,28 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
|
||||
class Carrot extends Crops{
|
||||
|
||||
protected $id = self::CARROT_BLOCK;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Carrot Block";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
$drops = [];
|
||||
if($this->meta >= 0x07){
|
||||
$drops[] = [Item::CARROT, 0, mt_rand(1, 4)];
|
||||
}else{
|
||||
$drops[] = [Item::CARROT, 0, 1];
|
||||
}
|
||||
|
||||
return $drops;
|
||||
public function getDrops(Item $item) : array{
|
||||
return [
|
||||
ItemFactory::get(Item::CARROT, 0, $this->meta >= 0x07 ? mt_rand(1, 4) : 1)
|
||||
];
|
||||
}
|
||||
}
|
@ -19,15 +19,18 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\NBT;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\tag\ListTag;
|
||||
use pocketmine\nbt\tag\IntTag;
|
||||
use pocketmine\nbt\tag\ListTag;
|
||||
use pocketmine\nbt\tag\StringTag;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\tile\Chest as TileChest;
|
||||
@ -37,23 +40,19 @@ class Chest extends Transparent{
|
||||
|
||||
protected $id = self::CHEST;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 2.5;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Chest";
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_AXE;
|
||||
}
|
||||
|
||||
@ -68,12 +67,12 @@ class Chest extends Transparent{
|
||||
);
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$faces = [
|
||||
0 => 4,
|
||||
1 => 2,
|
||||
2 => 5,
|
||||
3 => 3,
|
||||
3 => 3
|
||||
];
|
||||
|
||||
$chest = null;
|
||||
@ -86,7 +85,7 @@ class Chest extends Transparent{
|
||||
continue;
|
||||
}
|
||||
$c = $this->getSide($side);
|
||||
if($c instanceof Chest and $c->getDamage() === $this->meta){
|
||||
if($c->getId() === $this->id and $c->getDamage() === $this->meta){
|
||||
$tile = $this->getLevel()->getTile($c);
|
||||
if($tile instanceof TileChest and !$tile->isPaired()){
|
||||
$chest = $tile;
|
||||
@ -95,7 +94,7 @@ class Chest extends Transparent{
|
||||
}
|
||||
}
|
||||
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
$nbt = new CompoundTag("", [
|
||||
new ListTag("Items", []),
|
||||
new StringTag("id", Tile::CHEST),
|
||||
@ -115,7 +114,7 @@ class Chest extends Transparent{
|
||||
}
|
||||
}
|
||||
|
||||
$tile = Tile::createTile("Chest", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt);
|
||||
$tile = Tile::createTile("Chest", $this->getLevel(), $nbt);
|
||||
|
||||
if($chest instanceof TileChest and $tile instanceof TileChest){
|
||||
$chest->pairWith($tile);
|
||||
@ -125,22 +124,18 @@ class Chest extends Transparent{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onBreak(Item $item){
|
||||
public function onBreak(Item $item, Player $player = null) : bool{
|
||||
$t = $this->getLevel()->getTile($this);
|
||||
if($t instanceof TileChest){
|
||||
$t->unpair();
|
||||
}
|
||||
$this->getLevel()->setBlock($this, new Air(), true, true);
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($player instanceof Player){
|
||||
$top = $this->getSide(1);
|
||||
if($top->isTransparent() !== true){
|
||||
return true;
|
||||
}
|
||||
|
||||
$t = $this->getLevel()->getTile($this);
|
||||
$chest = null;
|
||||
@ -155,27 +150,28 @@ class Chest extends Transparent{
|
||||
new IntTag("z", $this->z)
|
||||
]);
|
||||
$nbt->Items->setTagType(NBT::TAG_Compound);
|
||||
$chest = Tile::createTile("Chest", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt);
|
||||
$chest = Tile::createTile("Chest", $this->getLevel(), $nbt);
|
||||
}
|
||||
|
||||
if(isset($chest->namedtag->Lock) and $chest->namedtag->Lock instanceof StringTag){
|
||||
if($chest->namedtag->Lock->getValue() !== $item->getCustomName()){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if($player->isCreative()){
|
||||
if(
|
||||
!$this->getSide(Vector3::SIDE_UP)->isTransparent() or
|
||||
($chest->isPaired() and !$chest->getPair()->getBlock()->getSide(Vector3::SIDE_UP)->isTransparent()) or
|
||||
(isset($chest->namedtag->Lock) and $chest->namedtag->Lock instanceof StringTag and $chest->namedtag->Lock->getValue() !== $item->getCustomName())
|
||||
){
|
||||
return true;
|
||||
}
|
||||
|
||||
$player->addWindow($chest->getInventory());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return [
|
||||
[$this->id, 0, 1],
|
||||
];
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getFuelTime() : int{
|
||||
return 300;
|
||||
}
|
||||
}
|
@ -19,34 +19,37 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
class Clay extends Solid{
|
||||
|
||||
protected $id = self::CLAY_BLOCK;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.6;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_SHOVEL;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Clay Block";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
return [
|
||||
[Item::CLAY, 0, 4],
|
||||
ItemFactory::get(Item::CLAY_BALL, 0, 4)
|
||||
];
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -28,29 +30,31 @@ class Coal extends Solid{
|
||||
|
||||
protected $id = self::COAL_BLOCK;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Coal Block";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return [
|
||||
[Item::COAL_BLOCK, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getFuelTime() : int{
|
||||
return 16000;
|
||||
}
|
||||
}
|
@ -19,39 +19,42 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
class CoalOre extends Solid{
|
||||
|
||||
protected $id = self::COAL_ORE;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 3;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Coal Ore";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return [
|
||||
[Item::COAL, 0, 1],
|
||||
ItemFactory::get(Item::COAL, 0, 1)
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -28,29 +30,27 @@ class Cobblestone extends Solid{
|
||||
|
||||
protected $id = self::COBBLESTONE;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Cobblestone";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return [
|
||||
[Item::COBBLESTONE, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,8 +19,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
@ -28,19 +29,19 @@ class CobblestoneStairs extends Stair{
|
||||
|
||||
protected $id = self::COBBLESTONE_STAIRS;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Cobblestone Stairs";
|
||||
}
|
||||
|
||||
|
@ -19,36 +19,37 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
|
||||
class StoneWall extends Transparent{
|
||||
class CobblestoneWall extends Transparent{
|
||||
const NONE_MOSSY_WALL = 0;
|
||||
const MOSSY_WALL = 1;
|
||||
|
||||
protected $id = self::STONE_WALL;
|
||||
protected $id = self::COBBLESTONE_WALL;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function isSolid(){
|
||||
public function isSolid() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
if($this->meta === 0x01){
|
||||
return "Mossy Cobblestone Wall";
|
||||
}
|
||||
@ -87,7 +88,7 @@ class StoneWall extends Transparent{
|
||||
}
|
||||
|
||||
public function canConnect(Block $block){
|
||||
return ($block->getId() !== self::COBBLE_WALL and $block->getId() !== self::FENCE_GATE) ? $block->isSolid() and !$block->isTransparent() : true;
|
||||
return ($block->getId() !== self::COBBLESTONE_WALL and $block->getId() !== self::FENCE_GATE) ? $block->isSolid() and !$block->isTransparent() : true;
|
||||
}
|
||||
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
@ -29,23 +31,23 @@ class Cobweb extends Flowable{
|
||||
|
||||
protected $id = self::COBWEB;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function hasEntityCollision(){
|
||||
public function hasEntityCollision() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Cobweb";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 4;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_SWORD;
|
||||
}
|
||||
|
||||
@ -53,8 +55,12 @@ class Cobweb extends Flowable{
|
||||
$entity->resetFallDistance();
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
//TODO: correct drops
|
||||
return [];
|
||||
}
|
||||
|
||||
public function diffusesSkyLight() : bool{
|
||||
return true;
|
||||
}
|
||||
}
|
@ -19,17 +19,21 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
class CocoaBlock extends Solid {
|
||||
class CocoaBlock extends Solid{
|
||||
|
||||
protected $id = self::COCOA_BLOCK;
|
||||
protected $id = self::COCOA_BLOCK;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Cocoa Block";
|
||||
}
|
||||
public function getName() : string{
|
||||
return "Cocoa Block";
|
||||
}
|
||||
|
||||
//TODO
|
||||
}
|
||||
|
58
src/pocketmine/block/Concrete.php
Normal file
58
src/pocketmine/block/Concrete.php
Normal file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\ColorBlockMetaHelper;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
class Concrete extends Solid{
|
||||
|
||||
protected $id = Block::CONCRETE;
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName() : string{
|
||||
return ColorBlockMetaHelper::getColorFromMeta($this->meta) . " Concrete";
|
||||
}
|
||||
|
||||
public function getHardness() : float{
|
||||
return 1.8;
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
@ -19,48 +19,45 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\inventory\BigCraftingGrid;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\Player;
|
||||
|
||||
//TODO: check orientation
|
||||
class Workbench extends Solid{
|
||||
class CraftingTable extends Solid{
|
||||
|
||||
protected $id = self::WORKBENCH;
|
||||
protected $id = self::CRAFTING_TABLE;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 2.5;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Crafting Table";
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_AXE;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($player instanceof Player){
|
||||
$player->setCraftingGrid(new BigCraftingGrid($player));
|
||||
$player->craftingType = 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return [
|
||||
[$this->id, 0, 1],
|
||||
];
|
||||
public function getFuelTime() : int{
|
||||
return 300;
|
||||
}
|
||||
}
|
@ -19,24 +19,22 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\event\block\BlockGrowEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
|
||||
abstract class Crops extends Flowable{
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
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->getLevel()->setBlock($block, $this, true, true);
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
if($blockReplace->getSide(Vector3::SIDE_DOWN)->getId() === Block::FARMLAND){
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -45,7 +43,7 @@ abstract class Crops extends Flowable{
|
||||
}
|
||||
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal
|
||||
$block = clone $this;
|
||||
$block->meta += mt_rand(2, 5);
|
||||
@ -67,14 +65,18 @@ abstract class Crops extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent() === true){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() !== Block::FARMLAND){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
if(mt_rand(0, 2) == 1){
|
||||
if(mt_rand(0, 2) === 1){
|
||||
if($this->meta < 0x07){
|
||||
$block = clone $this;
|
||||
++$block->meta;
|
||||
|
@ -19,29 +19,32 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Dandelion extends Flowable{
|
||||
|
||||
protected $id = self::DANDELION;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Dandelion";
|
||||
}
|
||||
|
||||
|
||||
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->getLevel()->setBlock($block, $this, true, true);
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === Block::GRASS or $down->getId() === Block::DIRT or $down->getId() === Block::FARMLAND){
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -49,9 +52,9 @@ class Dandelion extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent() === true){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent() === true){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
|
@ -1,48 +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\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
class DarkOakWoodStairs extends Stair{
|
||||
|
||||
protected $id = self::DARK_OAK_WOOD_STAIRS;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Dark Oak Wood Stairs";
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
return Tool::TYPE_AXE;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return [
|
||||
[$this->id, 0, 1],
|
||||
];
|
||||
}
|
||||
}
|
@ -19,17 +19,29 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
class DaylightSensor extends Solid {
|
||||
class DaylightSensor extends Transparent{
|
||||
|
||||
protected $id = self::DAYLIGHT_SENSOR;
|
||||
protected $id = self::DAYLIGHT_SENSOR;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Daylight Sensor";
|
||||
}
|
||||
public function getName() : string{
|
||||
return "Daylight Sensor";
|
||||
}
|
||||
|
||||
public function getHardness() : float{
|
||||
return 0.2;
|
||||
}
|
||||
|
||||
public function getFuelTime() : int{
|
||||
return 300;
|
||||
}
|
||||
|
||||
//TODO
|
||||
}
|
||||
|
@ -19,26 +19,29 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
|
||||
class DeadBush extends Flowable{
|
||||
|
||||
protected $id = self::DEAD_BUSH;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Dead Bush";
|
||||
}
|
||||
|
||||
|
||||
public function onUpdate($type){
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent() === true){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent() === true){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
|
@ -19,17 +19,17 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
class DetectorRail extends Solid {
|
||||
class DetectorRail extends Rail{
|
||||
|
||||
protected $id = self::DETECTOR_RAIL;
|
||||
protected $id = self::DETECTOR_RAIL;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
public function getName() : string{
|
||||
return "Detector Rail";
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Detector Rail";
|
||||
}
|
||||
//TODO
|
||||
}
|
||||
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -28,29 +30,27 @@ class Diamond extends Solid{
|
||||
|
||||
protected $id = self::DIAMOND_BLOCK;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Diamond Block";
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_IRON){
|
||||
return [
|
||||
[Item::DIAMOND_BLOCK, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,38 +19,41 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
class DiamondOre extends Solid{
|
||||
|
||||
protected $id = self::DIAMOND_ORE;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 3;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Diamond Ore";
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_IRON){
|
||||
return [
|
||||
[Item::DIAMOND, 0, 1],
|
||||
ItemFactory::get(Item::DIAMOND, 0, 1)
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -29,30 +31,33 @@ class Dirt extends Solid{
|
||||
|
||||
protected $id = self::DIRT;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.5;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_SHOVEL;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
if($this->meta === 1){
|
||||
return "Coarse Dirt";
|
||||
}
|
||||
return "Dirt";
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($item->isHoe()){
|
||||
$item->useOn($this);
|
||||
$this->getLevel()->setBlock($this, Block::get(Item::FARMLAND, 0), true);
|
||||
if($this->meta === 1){
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::DIRT), true);
|
||||
}else{
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::FARMLAND), true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -31,11 +33,7 @@ use pocketmine\Player;
|
||||
|
||||
abstract class Door extends Transparent{
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isSolid(){
|
||||
public function isSolid() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -203,12 +201,12 @@ abstract class Door extends Transparent{
|
||||
return $bb;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->getId() === self::AIR){ //Replace with common break method
|
||||
$this->getLevel()->setBlock($this, new Air(), false);
|
||||
if($this->getSide(1) instanceof Door){
|
||||
$this->getLevel()->setBlock($this->getSide(1), new Air(), false);
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() === self::AIR){ //Replace with common break method
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), false);
|
||||
if($this->getSide(Vector3::SIDE_UP) instanceof Door){
|
||||
$this->getLevel()->setBlock($this->getSide(Vector3::SIDE_UP), BlockFactory::get(Block::AIR), false);
|
||||
}
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
@ -218,64 +216,59 @@ abstract class Door extends Transparent{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
if($face === 1){
|
||||
$blockUp = $this->getSide(1);
|
||||
$blockDown = $this->getSide(0);
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
if($face === Vector3::SIDE_UP){
|
||||
$blockUp = $this->getSide(Vector3::SIDE_UP);
|
||||
$blockDown = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($blockUp->canBeReplaced() === false or $blockDown->isTransparent() === true){
|
||||
return false;
|
||||
}
|
||||
$direction = $player instanceof Player ? $player->getDirection() : 0;
|
||||
$face = [
|
||||
$faces = [
|
||||
0 => 3,
|
||||
1 => 4,
|
||||
2 => 2,
|
||||
3 => 5,
|
||||
3 => 5
|
||||
];
|
||||
$next = $this->getSide($face[(($direction + 2) % 4)]);
|
||||
$next2 = $this->getSide($face[$direction]);
|
||||
$next = $this->getSide($faces[($direction + 2) % 4]);
|
||||
$next2 = $this->getSide($faces[$direction]);
|
||||
$metaUp = 0x08;
|
||||
if($next->getId() === $this->getId() or ($next2->isTransparent() === false and $next->isTransparent() === true)){ //Door hinge
|
||||
$metaUp |= 0x01;
|
||||
}
|
||||
|
||||
$this->setDamage($player->getDirection() & 0x03);
|
||||
$this->getLevel()->setBlock($block, $this, true, true); //Bottom
|
||||
$this->getLevel()->setBlock($blockUp, $b = Block::get($this->getId(), $metaUp), true); //Top
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true); //Bottom
|
||||
$this->getLevel()->setBlock($blockUp, $b = BlockFactory::get($this->getId(), $metaUp), true); //Top
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onBreak(Item $item){
|
||||
public function onBreak(Item $item, Player $player = null) : bool{
|
||||
if(($this->getDamage() & 0x08) === 0x08){
|
||||
$down = $this->getSide(0);
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === $this->getId()){
|
||||
$this->getLevel()->setBlock($down, new Air(), true);
|
||||
$this->getLevel()->setBlock($down, BlockFactory::get(Block::AIR), true);
|
||||
}
|
||||
}else{
|
||||
$up = $this->getSide(1);
|
||||
$up = $this->getSide(Vector3::SIDE_UP);
|
||||
if($up->getId() === $this->getId()){
|
||||
$this->getLevel()->setBlock($up, new Air(), true);
|
||||
$this->getLevel()->setBlock($up, BlockFactory::get(Block::AIR), true);
|
||||
}
|
||||
}
|
||||
$this->getLevel()->setBlock($this, new Air(), true);
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if(($this->getDamage() & 0x08) === 0x08){ //Top
|
||||
$down = $this->getSide(0);
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === $this->getId()){
|
||||
$meta = $down->getDamage() ^ 0x04;
|
||||
$this->getLevel()->setBlock($down, Block::get($this->getId(), $meta), true);
|
||||
$players = $this->getLevel()->getChunkPlayers($this->x >> 4, $this->z >> 4);
|
||||
if($player instanceof Player){
|
||||
unset($players[$player->getLoaderId()]);
|
||||
}
|
||||
|
||||
$this->level->setBlock($down, BlockFactory::get($this->getId(), $meta), true);
|
||||
$this->level->addSound(new DoorSound($this));
|
||||
return true;
|
||||
}
|
||||
@ -283,14 +276,14 @@ abstract class Door extends Transparent{
|
||||
return false;
|
||||
}else{
|
||||
$this->meta ^= 0x04;
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
$players = $this->getLevel()->getChunkPlayers($this->x >> 4, $this->z >> 4);
|
||||
if($player instanceof Player){
|
||||
unset($players[$player->getLoaderId()]);
|
||||
}
|
||||
$this->level->setBlock($this, $this, true);
|
||||
$this->level->addSound(new DoorSound($this));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -19,24 +19,30 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class DoublePlant extends Flowable{
|
||||
const BITFLAG_TOP = 0x08;
|
||||
|
||||
protected $id = self::DOUBLE_PLANT;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function canBeReplaced(){
|
||||
return true;
|
||||
public function canBeReplaced() : bool{
|
||||
return $this->meta === 2 or $this->meta === 3; //grass or fern
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
static $names = [
|
||||
0 => "Sunflower",
|
||||
1 => "Lilac",
|
||||
@ -45,14 +51,44 @@ class DoublePlant extends Flowable{
|
||||
4 => "Rose Bush",
|
||||
5 => "Peony"
|
||||
];
|
||||
return $names[$this->meta & 0x07];
|
||||
return $names[$this->meta & 0x07] ?? "";
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$id = $blockReplace->getSide(Vector3::SIDE_DOWN)->getId();
|
||||
if(($id === Block::GRASS or $id === Block::DIRT) and $blockReplace->getSide(Vector3::SIDE_UP)->canBeReplaced()){
|
||||
$this->getLevel()->setBlock($blockReplace, $this, false, false);
|
||||
$this->getLevel()->setBlock($blockReplace->getSide(Vector3::SIDE_UP), BlockFactory::get($this->id, $this->meta | self::BITFLAG_TOP), false, false);
|
||||
|
||||
public function onUpdate($type){
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this double-plant has a corresponding other half.
|
||||
* @return bool
|
||||
*/
|
||||
public function isValidHalfPlant() : bool{
|
||||
if($this->meta & self::BITFLAG_TOP){
|
||||
$other = $this->getSide(Vector3::SIDE_DOWN);
|
||||
}else{
|
||||
$other = $this->getSide(Vector3::SIDE_UP);
|
||||
}
|
||||
|
||||
return (
|
||||
$other->getId() === $this->getId() and
|
||||
($other->getDamage() & 0x07) === ($this->getDamage() & 0x07) and
|
||||
($other->getDamage() & self::BITFLAG_TOP) !== ($this->getDamage() & self::BITFLAG_TOP)
|
||||
);
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent() === true){ //Replace with common break method
|
||||
$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if(!$this->isValidHalfPlant() or (($this->meta & self::BITFLAG_TOP) === 0 and $down->isTransparent())){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
@ -61,10 +97,33 @@ class DoublePlant extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
//TODO
|
||||
public function onBreak(Item $item, Player $player = null) : bool{
|
||||
if(parent::onBreak($item, $player) and $this->isValidHalfPlant()){
|
||||
$this->getLevel()->useBreakOn($this->getSide(($this->meta & self::BITFLAG_TOP) !== 0 ? Vector3::SIDE_DOWN : Vector3::SIDE_UP), $item, $player, $player !== null);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getVariantBitmask() : int{
|
||||
return 0x07;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($this->meta & self::BITFLAG_TOP){
|
||||
if(!$item->isShears() and ($this->meta === 2 or $this->meta === 3)){ //grass or fern
|
||||
if(mt_rand(0, 24) === 0){
|
||||
return [
|
||||
ItemFactory::get(Item::SEEDS, 0, 1)
|
||||
];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
@ -19,28 +19,31 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
class DoubleSlab extends Solid{
|
||||
class DoubleStoneSlab extends Solid{
|
||||
|
||||
protected $id = self::DOUBLE_SLAB;
|
||||
protected $id = self::DOUBLE_STONE_SLAB;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
static $names = [
|
||||
0 => "Stone",
|
||||
1 => "Sandstone",
|
||||
@ -49,19 +52,19 @@ class DoubleSlab extends Solid{
|
||||
4 => "Brick",
|
||||
5 => "Stone Brick",
|
||||
6 => "Quartz",
|
||||
7 => "Nether Brick",
|
||||
7 => "Nether Brick"
|
||||
];
|
||||
return "DoubleTag " . $names[$this->meta & 0x07] . " Slab";
|
||||
return "Double " . $names[$this->meta & 0x07] . " Slab";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return [
|
||||
[Item::SLAB, $this->meta & 0x07, 2],
|
||||
ItemFactory::get(Item::STONE_SLAB, $this->getDamage() & 0x07, 2)
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
@ -19,44 +19,45 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
class DoubleWoodSlab extends Solid{
|
||||
class DoubleWoodenSlab extends Solid{
|
||||
|
||||
protected $id = self::DOUBLE_WOOD_SLAB;
|
||||
protected $id = self::DOUBLE_WOODEN_SLAB;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_AXE;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
static $names = [
|
||||
0 => "Oak",
|
||||
1 => "Spruce",
|
||||
2 => "Birch",
|
||||
3 => "Jungle",
|
||||
4 => "Acacia",
|
||||
5 => "Dark Oak",
|
||||
6 => "",
|
||||
7 => ""
|
||||
5 => "Dark Oak"
|
||||
];
|
||||
return "DoubleTag " . $names[$this->meta & 0x07] . " Wooden Slab";
|
||||
return "Double " . ($names[$this->meta & 0x07] ?? "") . " Wooden Slab";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
return [
|
||||
[Item::WOOD_SLAB, $this->meta & 0x07, 2],
|
||||
ItemFactory::get(Item::WOODEN_SLAB, $this->getDamage() & 0x07, 2)
|
||||
];
|
||||
}
|
||||
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -28,29 +30,27 @@ class Emerald extends Solid{
|
||||
|
||||
protected $id = self::EMERALD_BLOCK;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Emerald Block";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_IRON){
|
||||
return [
|
||||
[Item::EMERALD_BLOCK, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,38 +19,41 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
class EmeraldOre extends Solid{
|
||||
|
||||
protected $id = self::EMERALD_ORE;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Emerald Ore";
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 3;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_IRON){
|
||||
return [
|
||||
[Item::EMERALD, 0, 1],
|
||||
ItemFactory::get(Item::EMERALD, 0, 1)
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,12 +19,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\inventory\EnchantInventory;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\tag\IntTag;
|
||||
use pocketmine\nbt\tag\StringTag;
|
||||
@ -35,12 +37,12 @@ class EnchantingTable extends Transparent{
|
||||
|
||||
protected $id = self::ENCHANTING_TABLE;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
$nbt = new CompoundTag("", [
|
||||
new StringTag("id", Tile::ENCHANT_TABLE),
|
||||
new IntTag("x", $this->x),
|
||||
@ -58,37 +60,30 @@ class EnchantingTable extends Transparent{
|
||||
}
|
||||
}
|
||||
|
||||
Tile::createTile(Tile::ENCHANT_TABLE, $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt);
|
||||
Tile::createTile(Tile::ENCHANT_TABLE, $this->getLevel(), $nbt);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function getResistance(){
|
||||
public function getBlastResistance() : float{
|
||||
return 6000;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Enchanting Table";
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($player instanceof Player){
|
||||
//TODO lock
|
||||
if($player->isCreative()){
|
||||
return true;
|
||||
}
|
||||
|
||||
$player->addWindow(new EnchantInventory($this));
|
||||
}
|
||||
@ -96,13 +91,11 @@ class EnchantingTable extends Transparent{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return [
|
||||
[$this->id, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -28,27 +30,27 @@ class EndPortalFrame extends Solid{
|
||||
|
||||
protected $id = self::END_PORTAL_FRAME;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getLightLevel(){
|
||||
public function getLightLevel() : int{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "EndTag Portal Frame";
|
||||
public function getName() : string{
|
||||
return "End Portal Frame";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return -1;
|
||||
}
|
||||
|
||||
public function getResistance(){
|
||||
public function getBlastResistance() : float{
|
||||
return 18000000;
|
||||
}
|
||||
|
||||
public function isBreakable(Item $item){
|
||||
public function isBreakable(Item $item) : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
104
src/pocketmine/block/EndRod.php
Normal file
104
src/pocketmine/block/EndRod.php
Normal file
@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class EndRod extends Flowable{
|
||||
|
||||
protected $id = Block::END_ROD;
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName() : string{
|
||||
return "End Rod";
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
if($face === Vector3::SIDE_UP or $face === Vector3::SIDE_DOWN){
|
||||
$this->meta = $face;
|
||||
}else{
|
||||
$this->meta = $face ^ 0x01;
|
||||
}
|
||||
if($blockClicked instanceof EndRod and $blockClicked->getDamage() === $this->meta){
|
||||
$this->meta ^= 0x01;
|
||||
}
|
||||
|
||||
return $this->level->setBlock($blockReplace, $this, true, true);
|
||||
}
|
||||
|
||||
public function isSolid() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getLightLevel() : int{
|
||||
return 14;
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox(){
|
||||
$m = $this->meta & ~0x01;
|
||||
$width = 0.375;
|
||||
|
||||
switch($m){
|
||||
case 0x00: //up/down
|
||||
return new AxisAlignedBB(
|
||||
$this->x + $width,
|
||||
$this->y,
|
||||
$this->z + $width,
|
||||
$this->x + 1 - $width,
|
||||
$this->y + 1,
|
||||
$this->z + 1 - $width
|
||||
);
|
||||
case 0x02: //north/south
|
||||
return new AxisAlignedBB(
|
||||
$this->x,
|
||||
$this->y + $width,
|
||||
$this->z + $width,
|
||||
$this->x + 1,
|
||||
$this->y + 1 - $width,
|
||||
$this->z + 1 - $width
|
||||
);
|
||||
case 0x04: //east/west
|
||||
return new AxisAlignedBB(
|
||||
$this->x + $width,
|
||||
$this->y + $width,
|
||||
$this->z,
|
||||
$this->x + 1 - $width,
|
||||
$this->y + 1 - $width,
|
||||
$this->z + 1
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -19,8 +19,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
@ -28,19 +29,19 @@ class EndStone extends Solid{
|
||||
|
||||
protected $id = self::END_STONE;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "EndTag Stone";
|
||||
public function getName() : string{
|
||||
return "End Stone";
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 3;
|
||||
}
|
||||
}
|
@ -19,49 +19,44 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\tag\ByteTag;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\tag\DoubleTag;
|
||||
use pocketmine\nbt\tag\ListTag;
|
||||
use pocketmine\nbt\tag\FloatTag;
|
||||
use pocketmine\nbt\tag\IntTag;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\nbt\tag\ListTag;
|
||||
|
||||
abstract class Fallable extends Solid{
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$ret = $this->getLevel()->setBlock($this, $this, true, true);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === self::AIR or ($down instanceof Liquid)){
|
||||
$fall = Entity::createEntity("FallingSand", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), new CompoundTag("", [
|
||||
"Pos" => new ListTag("Pos", [
|
||||
$this->level->setBlock($this, BlockFactory::get(Block::AIR), true, true);
|
||||
$fall = Entity::createEntity("FallingSand", $this->getLevel(), new CompoundTag("", [
|
||||
new ListTag("Pos", [
|
||||
new DoubleTag("", $this->x + 0.5),
|
||||
new DoubleTag("", $this->y),
|
||||
new DoubleTag("", $this->z + 0.5)
|
||||
]),
|
||||
"Motion" => new ListTag("Motion", [
|
||||
new ListTag("Motion", [
|
||||
new DoubleTag("", 0),
|
||||
new DoubleTag("", 0),
|
||||
new DoubleTag("", 0)
|
||||
]),
|
||||
"Rotation" => new ListTag("Rotation", [
|
||||
new ListTag("Rotation", [
|
||||
new FloatTag("", 0),
|
||||
new FloatTag("", 0)
|
||||
]),
|
||||
"TileID" => new IntTag("TileID", $this->getId()),
|
||||
"Data" => new ByteTag("Data", $this->getDamage()),
|
||||
new IntTag("TileID", $this->getId()),
|
||||
new ByteTag("Data", $this->getDamage())
|
||||
]));
|
||||
|
||||
$fall->spawnToAll();
|
||||
|
@ -19,46 +19,62 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
|
||||
class Farmland extends Solid{
|
||||
class Farmland extends Transparent{
|
||||
|
||||
protected $id = self::FARMLAND;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Farmland";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.6;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_SHOVEL;
|
||||
}
|
||||
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox(){
|
||||
return new AxisAlignedBB(
|
||||
$this->x,
|
||||
$this->y,
|
||||
$this->z,
|
||||
$this->x + 1,
|
||||
$this->y + 0.9375,
|
||||
$this->y + 1, //TODO: this should be 0.9375, but MCPE currently treats them as a full block (https://bugs.mojang.com/browse/MCPE-12109)
|
||||
$this->z + 1
|
||||
);
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
//TODO: hydration
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
return [
|
||||
[Item::DIRT, 0, 1],
|
||||
ItemFactory::get(Item::DIRT, 0, 1)
|
||||
];
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Tool;
|
||||
@ -35,31 +37,29 @@ class Fence extends Transparent{
|
||||
|
||||
protected $id = self::FENCE;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_AXE;
|
||||
}
|
||||
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
static $names = [
|
||||
self::FENCE_OAK => "Oak Fence",
|
||||
self::FENCE_SPRUCE => "Spruce Fence",
|
||||
self::FENCE_BIRCH => "Birch Fence",
|
||||
self::FENCE_JUNGLE => "Jungle Fence",
|
||||
self::FENCE_ACACIA => "Acacia Fence",
|
||||
self::FENCE_DARKOAK => "Dark Oak Fence",
|
||||
"",
|
||||
""
|
||||
self::FENCE_DARKOAK => "Dark Oak Fence"
|
||||
];
|
||||
return $names[$this->meta & 0x07];
|
||||
return $names[$this->meta & 0x07] ?? "Unknown";
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox(){
|
||||
@ -88,4 +88,8 @@ class Fence extends Transparent{
|
||||
return ($block instanceof Fence or $block instanceof FenceGate) ? true : $block->isSolid() and !$block->isTransparent();
|
||||
}
|
||||
|
||||
public function getFuelTime() : int{
|
||||
return 300;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,35 +19,24 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\level\sound\DoorSound;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class FenceGate extends Transparent{
|
||||
|
||||
protected $id = self::FENCE_GATE;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Oak Fence Gate";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_AXE;
|
||||
}
|
||||
|
||||
@ -59,7 +48,7 @@ class FenceGate extends Transparent{
|
||||
}
|
||||
|
||||
$i = ($this->getDamage() & 0x03);
|
||||
if($i === 2 and $i === 0){
|
||||
if($i === 2 or $i === 0){
|
||||
return new AxisAlignedBB(
|
||||
$this->x,
|
||||
$this->y,
|
||||
@ -80,35 +69,30 @@ class FenceGate extends Transparent{
|
||||
}
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$faces = [
|
||||
0 => 3,
|
||||
1 => 0,
|
||||
2 => 1,
|
||||
3 => 2,
|
||||
];
|
||||
$this->meta = $faces[$player instanceof Player ? $player->getDirection() : 0] & 0x03;
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$this->meta = ($player instanceof Player ? ($player->getDirection() - 1) & 0x03 : 0);
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return [
|
||||
[$this->id, 0, 1],
|
||||
];
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
$faces = [
|
||||
0 => 3,
|
||||
1 => 0,
|
||||
2 => 1,
|
||||
3 => 2,
|
||||
];
|
||||
$this->meta = ($faces[$player instanceof Player ? $player->getDirection() : 0] & 0x03) | ((~$this->meta) & 0x04);
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
$this->meta = (($this->meta ^ 0x04) & ~0x02);
|
||||
|
||||
if($player !== null){
|
||||
$this->meta |= (($player->getDirection() - 1) & 0x02);
|
||||
}
|
||||
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
$this->level->addSound(new DoorSound($this));
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getFuelTime() : int{
|
||||
return 300;
|
||||
}
|
||||
}
|
||||
|
@ -1,32 +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\block;
|
||||
|
||||
|
||||
class FenceGateBirch extends FenceGate{
|
||||
|
||||
protected $id = self::FENCE_GATE_BIRCH;
|
||||
|
||||
public function getName(){
|
||||
return "Birch Fence Gate";
|
||||
}
|
||||
}
|
@ -1,32 +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\block;
|
||||
|
||||
|
||||
class FenceGateDarkOak extends FenceGate{
|
||||
|
||||
protected $id = self::FENCE_GATE_DARK_OAK;
|
||||
|
||||
public function getName(){
|
||||
return "Dark Oak Fence Gate";
|
||||
}
|
||||
}
|
@ -1,32 +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\block;
|
||||
|
||||
|
||||
class FenceGateJungle extends FenceGate{
|
||||
|
||||
protected $id = self::FENCE_GATE_JUNGLE;
|
||||
|
||||
public function getName(){
|
||||
return "Jungle Fence Gate";
|
||||
}
|
||||
}
|
@ -1,32 +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\block;
|
||||
|
||||
|
||||
class FenceGateSpruce extends FenceGate{
|
||||
|
||||
protected $id = self::FENCE_GATE_SPRUCE;
|
||||
|
||||
public function getName(){
|
||||
return "Spruce Fence Gate";
|
||||
}
|
||||
}
|
@ -19,51 +19,55 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Arrow;
|
||||
use pocketmine\entity\Effect;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\event\entity\EntityCombustByBlockEvent;
|
||||
use pocketmine\event\entity\EntityDamageByBlockEvent;
|
||||
use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Server;
|
||||
|
||||
class Fire extends Flowable{
|
||||
|
||||
protected $id = self::FIRE;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function hasEntityCollision(){
|
||||
public function hasEntityCollision() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Fire Block";
|
||||
}
|
||||
|
||||
public function getLightLevel(){
|
||||
public function getLightLevel() : int{
|
||||
return 15;
|
||||
}
|
||||
|
||||
public function isBreakable(Item $item){
|
||||
public function isBreakable(Item $item) : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function canBeReplaced(){
|
||||
public function canBeReplaced() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onEntityCollide(Entity $entity){
|
||||
if(!$entity->hasEffect(Effect::FIRE_RESISTANCE)){
|
||||
$ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_FIRE, 1);
|
||||
$entity->attack($ev->getFinalDamage(), $ev);
|
||||
}
|
||||
$ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_FIRE, 1);
|
||||
$entity->attack($ev);
|
||||
|
||||
$ev = new EntityCombustByBlockEvent($this, $entity, 8);
|
||||
if($entity instanceof Arrow){
|
||||
@ -75,11 +79,11 @@ class Fire extends Flowable{
|
||||
}
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
for($s = 0; $s <= 5; ++$s){
|
||||
$side = $this->getSide($s);
|
||||
@ -87,14 +91,14 @@ class Fire extends Flowable{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$this->getLevel()->setBlock($this, new Air(), true);
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
if($this->getSide(0)->getId() !== self::NETHERRACK){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() !== self::NETHERRACK){
|
||||
if(mt_rand(0, 2) === 0){
|
||||
if($this->meta === 0x0F){
|
||||
$this->level->setBlock($this, new Air());
|
||||
$this->level->setBlock($this, BlockFactory::get(Block::AIR));
|
||||
}else{
|
||||
$this->meta++;
|
||||
$this->level->setBlock($this, $this);
|
||||
@ -103,6 +107,8 @@ class Fire extends Flowable{
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: fire spread
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -19,30 +19,29 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
|
||||
|
||||
|
||||
abstract class Flowable extends Transparent{
|
||||
|
||||
public function canBeFlowedInto(){
|
||||
public function canBeFlowedInto() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getResistance(){
|
||||
public function getBlastResistance() : float{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function isSolid(){
|
||||
public function isSolid() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getBoundingBox(){
|
||||
protected function recalculateBoundingBox(){
|
||||
return null;
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -39,11 +41,11 @@ class Flower extends Flowable{
|
||||
|
||||
protected $id = self::RED_FLOWER;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
static $names = [
|
||||
self::TYPE_POPPY => "Poppy",
|
||||
self::TYPE_BLUE_ORCHID => "Blue Orchid",
|
||||
@ -53,23 +55,15 @@ class Flower extends Flowable{
|
||||
self::TYPE_ORANGE_TULIP => "Orange Tulip",
|
||||
self::TYPE_WHITE_TULIP => "White Tulip",
|
||||
self::TYPE_PINK_TULIP => "Pink Tulip",
|
||||
self::TYPE_OXEYE_DAISY => "Oxeye Daisy",
|
||||
9 => "Unknown",
|
||||
10 => "Unknown",
|
||||
11 => "Unknown",
|
||||
12 => "Unknown",
|
||||
13 => "Unknown",
|
||||
14 => "Unknown",
|
||||
15 => "Unknown"
|
||||
self::TYPE_OXEYE_DAISY => "Oxeye Daisy"
|
||||
];
|
||||
return $names[$this->meta];
|
||||
return $names[$this->meta] ?? "Unknown";
|
||||
}
|
||||
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === Block::GRASS or $down->getId() === Block::DIRT or $down->getId() === Block::FARMLAND){
|
||||
$this->getLevel()->setBlock($block, $this, true);
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -77,7 +71,7 @@ class Flower extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
@ -19,20 +19,122 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\tag\IntTag;
|
||||
use pocketmine\nbt\tag\ShortTag;
|
||||
use pocketmine\nbt\tag\StringTag;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\tile\FlowerPot as TileFlowerPot;
|
||||
use pocketmine\tile\Tile;
|
||||
|
||||
class FlowerPot extends Transparent{
|
||||
class FlowerPot extends Flowable{
|
||||
|
||||
const STATE_EMPTY = 0;
|
||||
const STATE_FULL = 1;
|
||||
|
||||
protected $id = self::FLOWER_POT_BLOCK;
|
||||
protected $itemId = Item::FLOWER_POT;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Flower Pot Block";
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox(){
|
||||
return new AxisAlignedBB(
|
||||
$this->x + 0.3125,
|
||||
$this->y,
|
||||
$this->z + 0.3125,
|
||||
$this->x + 0.6875,
|
||||
$this->y + 0.375,
|
||||
$this->z + 0.6875
|
||||
);
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
$nbt = new CompoundTag("", [
|
||||
new StringTag("id", Tile::FLOWER_POT),
|
||||
new IntTag("x", $blockReplace->x),
|
||||
new IntTag("y", $blockReplace->y),
|
||||
new IntTag("z", $blockReplace->z),
|
||||
new ShortTag("item", 0),
|
||||
new IntTag("mData", 0)
|
||||
]);
|
||||
|
||||
if($item->hasCustomBlockData()){
|
||||
foreach($item->getCustomBlockData() as $key => $v){
|
||||
$nbt->{$key} = $v;
|
||||
}
|
||||
}
|
||||
|
||||
Tile::createTile(Tile::FLOWER_POT, $this->getLevel(), $nbt);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent() === true){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
$pot = $this->getLevel()->getTile($this);
|
||||
if(!($pot instanceof TileFlowerPot)){
|
||||
return false;
|
||||
}
|
||||
if(!$pot->canAddItem($item)){
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->setDamage(self::STATE_FULL); //specific damage value is unnecessary, it just needs to be non-zero to show an item.
|
||||
$this->getLevel()->setBlock($this, $this, true, false);
|
||||
$pot->setItem($item);
|
||||
|
||||
if($player instanceof Player){
|
||||
if($player->isSurvival()){
|
||||
$item->setCount($item->getCount() - 1);
|
||||
$player->getInventory()->setItemInHand($item->getCount() > 0 ? $item : ItemFactory::get(Item::AIR));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
$items = parent::getDrops($item);
|
||||
|
||||
$tile = $this->getLevel()->getTile($this);
|
||||
if($tile instanceof TileFlowerPot){
|
||||
$item = $tile->getItem();
|
||||
if($item->getId() !== Item::AIR){
|
||||
$items[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
|
||||
@ -26,7 +28,11 @@ class Furnace extends BurningFurnace{
|
||||
|
||||
protected $id = self::FURNACE;
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Furnace";
|
||||
}
|
||||
|
||||
public function getLightLevel() : int{
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -27,19 +29,19 @@ class Glass extends Transparent{
|
||||
|
||||
protected $id = self::GLASS;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Glass";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.3;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,8 +19,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
|
||||
@ -28,19 +29,19 @@ class GlassPane extends Thin{
|
||||
|
||||
protected $id = self::GLASS_PANE;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Glass Pane";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.3;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
return [];
|
||||
}
|
||||
}
|
67
src/pocketmine/block/GlazedTerracotta.php
Normal file
67
src/pocketmine/block/GlazedTerracotta.php
Normal file
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class GlazedTerracotta extends Solid{
|
||||
|
||||
public function getHardness() : float{
|
||||
return 1.4;
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
if($player !== null){
|
||||
$faces = [
|
||||
0 => 4,
|
||||
1 => 3,
|
||||
2 => 5,
|
||||
3 => 2
|
||||
];
|
||||
$this->meta = $faces[(~($player->getDirection() - 1)) & 0x03];
|
||||
}
|
||||
|
||||
return $this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
}
|
||||
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
|
||||
@ -26,16 +28,23 @@ class GlowingObsidian extends Solid{
|
||||
|
||||
protected $id = self::GLOWING_OBSIDIAN;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Glowing Obsidian";
|
||||
}
|
||||
|
||||
public function getLightLevel(){
|
||||
public function getLightLevel() : int{
|
||||
return 12;
|
||||
}
|
||||
|
||||
public function getHardness() : float{
|
||||
return 10;
|
||||
}
|
||||
|
||||
public function getBlastResistance() : float{
|
||||
return 50;
|
||||
}
|
||||
}
|
@ -19,26 +19,27 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
|
||||
class GlowingRedstoneOre extends RedstoneOre{
|
||||
|
||||
protected $id = self::GLOWING_REDSTONE_ORE;
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Glowing Redstone Ore";
|
||||
}
|
||||
|
||||
public function getLightLevel(){
|
||||
public function getLightLevel() : int{
|
||||
return 9;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_SCHEDULED or $type === Level::BLOCK_UPDATE_RANDOM){
|
||||
$this->getLevel()->setBlock($this, Block::get(Item::REDSTONE_ORE, $this->meta), false, false);
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::REDSTONE_ORE, $this->meta), false, false);
|
||||
|
||||
return Level::BLOCK_UPDATE_WEAK;
|
||||
}
|
||||
|
@ -19,38 +19,41 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
class Glowstone extends Transparent{
|
||||
|
||||
protected $id = self::GLOWSTONE_BLOCK;
|
||||
|
||||
public function __construct(){
|
||||
protected $id = self::GLOWSTONE;
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Glowstone";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.3;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getLightLevel(){
|
||||
public function getLightLevel() : int{
|
||||
return 15;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
return [
|
||||
[Item::GLOWSTONE_DUST, 0, mt_rand(2, 4)],
|
||||
ItemFactory::get(Item::GLOWSTONE_DUST, 0, mt_rand(2, 4))
|
||||
];
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -28,29 +30,27 @@ class Gold extends Solid{
|
||||
|
||||
protected $id = self::GOLD_BLOCK;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Gold Block";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 3;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_IRON){
|
||||
return [
|
||||
[Item::GOLD_BLOCK, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -28,29 +30,27 @@ class GoldOre extends Solid{
|
||||
|
||||
protected $id = self::GOLD_ORE;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Gold Ore";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 3;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_IRON){
|
||||
return [
|
||||
[Item::GOLD_ORE, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,71 +19,91 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\event\block\BlockSpreadEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\level\generator\object\TallGrass as TallGrassObject;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\utils\Random;
|
||||
|
||||
class Grass extends Solid{
|
||||
|
||||
protected $id = self::GRASS;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Grass";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.6;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_SHOVEL;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
return [
|
||||
[Item::DIRT, 0, 1],
|
||||
ItemFactory::get(Item::DIRT, 0, 1)
|
||||
];
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
$block = $this->getLevel()->getBlock(new Vector3($this->x, $this->y, $this->z));
|
||||
if($block->getSide(1)->getLightLevel() < 4){
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($block, $this, new Dirt()));
|
||||
}elseif($block->getSide(1)->getLightLevel() >= 9){
|
||||
for($l = 0; $l < 4; ++$l){
|
||||
$x = mt_rand($this->x - 1, $this->x + 1);
|
||||
$y = mt_rand($this->y - 2, $this->y + 2);
|
||||
$z = mt_rand($this->z - 1, $this->z + 1);
|
||||
$block = $this->getLevel()->getBlock(new Vector3($x, $y, $z));
|
||||
if($block->getId() === Block::DIRT && $block->getDamage() === 0x0F && $block->getSide(1)->getLightLevel() >= 4 && $block->z <= 2){
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($block, $this, new Grass()));
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($block, $ev->getNewState());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
$lightAbove = $this->level->getFullLightAt($this->x, $this->y + 1, $this->z);
|
||||
if($lightAbove < 4 and BlockFactory::$lightFilter[$this->level->getBlockIdAt($this->x, $this->y + 1, $this->z)] >= 3){ //2 plus 1 standard filter amount
|
||||
//grass dies
|
||||
$this->level->getServer()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($this, $this, BlockFactory::get(Block::DIRT)));
|
||||
if(!$ev->isCancelled()){
|
||||
$this->level->setBlock($this, $ev->getNewState(), false, false);
|
||||
}
|
||||
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}elseif($lightAbove >= 9){
|
||||
//try grass spread
|
||||
$vector = $this->asVector3();
|
||||
for($i = 0; $i < 4; ++$i){
|
||||
$vector->x = mt_rand($this->x - 1, $this->x + 1);
|
||||
$vector->y = mt_rand($this->y - 3, $this->y + 1);
|
||||
$vector->z = mt_rand($this->z - 1, $this->z + 1);
|
||||
if(
|
||||
$this->level->getBlockIdAt($vector->x, $vector->y, $vector->z) !== Block::DIRT or
|
||||
$this->level->getBlockDataAt($vector->x, $vector->y, $vector->z) === 1 or
|
||||
$this->level->getFullLightAt($vector->x, $vector->y + 1, $vector->z) < 4 or
|
||||
BlockFactory::$lightFilter[$this->level->getBlockIdAt($vector->x, $vector->y + 1, $vector->z)] >= 3
|
||||
){
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->level->getServer()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($this->level->getBlock($vector), $this, BlockFactory::get(Block::GRASS)));
|
||||
if(!$ev->isCancelled()){
|
||||
$this->level->setBlock($vector, $ev->getNewState(), false, false);
|
||||
}
|
||||
}
|
||||
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){
|
||||
$item->count--;
|
||||
TallGrassObject::growGrass($this->getLevel(), $this, new Random(mt_rand()), 8, 2);
|
||||
@ -91,12 +111,12 @@ class Grass extends Solid{
|
||||
return true;
|
||||
}elseif($item->isHoe()){
|
||||
$item->useOn($this);
|
||||
$this->getLevel()->setBlock($this, new Farmland());
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::FARMLAND));
|
||||
|
||||
return true;
|
||||
}elseif($item->isShovel() and $this->getSide(1)->getId() === Block::AIR){
|
||||
}elseif($item->isShovel() and $this->getSide(Vector3::SIDE_UP)->getId() === Block::AIR){
|
||||
$item->useOn($this);
|
||||
$this->getLevel()->setBlock($this, new GrassPath());
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::GRASS_PATH));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -19,29 +19,28 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
|
||||
|
||||
class GrassPath extends Transparent{
|
||||
|
||||
protected $id = self::GRASS_PATH;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Grass Path";
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_SHOVEL;
|
||||
}
|
||||
|
||||
@ -51,18 +50,18 @@ class GrassPath extends Transparent{
|
||||
$this->y,
|
||||
$this->z,
|
||||
$this->x + 1,
|
||||
$this->y + 0.9375,
|
||||
$this->y + 1, //TODO: this should be 0.9375, but MCPE currently treats them as a full block (https://bugs.mojang.com/browse/MCPE-12109)
|
||||
$this->z + 1
|
||||
);
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.6;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
return [
|
||||
[Item::DIRT, 0, 1],
|
||||
ItemFactory::get(Item::DIRT, 0, 1)
|
||||
];
|
||||
}
|
||||
}
|
@ -19,41 +19,42 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
class Gravel extends Fallable{
|
||||
|
||||
protected $id = self::GRAVEL;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Gravel";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.6;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_SHOVEL;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if(mt_rand(1, 10) === 1){
|
||||
return [
|
||||
[Item::FLINT, 0, 1],
|
||||
ItemFactory::get(Item::FLINT, 0, 1)
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
[Item::GRAVEL, 0, 1],
|
||||
];
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
}
|
@ -19,8 +19,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
@ -28,19 +29,19 @@ class HardenedClay extends Solid{
|
||||
|
||||
protected $id = self::HARDENED_CLAY;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Hardened Clay";
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 1.25;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user