Compare commits

..

1199 Commits

Author SHA1 Message Date
27b90c5a9a Stable Alpha_1.3.7 2013-08-30 17:51:33 +02:00
84deac3ef7 Reduced random range 2013-08-30 17:51:12 +02:00
5395f15fe7 Get block drops before breaking [fixes tile drops] 2013-08-30 17:48:46 +02:00
399f9b808b Random pos on item drop 2013-08-30 17:47:54 +02:00
82c655c09a Fixed first slot on Double chests 2013-08-30 17:37:16 +02:00
f6bbedbe91 Updated chests to 0.7.4 RC 2013-08-30 17:09:15 +02:00
77c35dd18e Removed fish from smelting data 2013-08-30 17:09:05 +02:00
ee3ae561b8 Removed fish from Player eating 2013-08-30 16:58:34 +02:00
08ed5dbfac Merge remote-tracking branch 'origin/0.7.4' 2013-08-29 19:47:25 +02:00
a21bb5ab6d Revert "Revert "Roll back""
This reverts commit e1e804ffe3.
2013-08-29 18:52:12 +02:00
fe681cb786 Removed character range check for UTF-8 full support 2013-08-29 18:35:57 +02:00
f609c40bdc Added homepage info on start.cmd 2013-08-29 13:36:09 +02:00
dc5b8ecd30 Fixed low TPS 2013-08-29 09:21:52 +02:00
31bf65ad5c Fixed test + output 2013-08-28 23:42:40 +02:00
d347137148 Removed obsolete Data.php 2013-08-28 23:37:47 +02:00
e1e804ffe3 Revert "Roll back"
This reverts commit 29504c09f263e73492c6ffecea201a81dcf3591d.
2013-08-28 20:55:58 +02:00
71fc3f2ef0 fix 2013-08-28 20:31:45 +02:00
ad1930da88 Custom unit test code. 2013-08-28 18:19:48 +02:00
251859921d $server global 2013-08-28 17:50:39 +02:00
549ad5eff1 Async thread remove on NO_THREADS 2013-08-28 17:41:01 +02:00
b8594ab48f Firce exit(0) 2013-08-28 17:33:29 +02:00
3608ee1194 Moved conditional class 2013-08-28 17:17:34 +02:00
eba33b0e00 Again :'( 2013-08-28 17:13:33 +02:00
06ce84e275 test with debug 2013-08-28 17:07:42 +02:00
feea39a97f test again 2013-08-28 17:02:04 +02:00
5d27a40a6e Remove test suites on compile 2013-08-28 16:54:04 +02:00
d8124d9ddd Removed MobAPI from ServerAPI 2013-08-28 16:49:18 +02:00
392c8d273e phpunit configuration file 2013-08-28 16:48:50 +02:00
29d089db5b Added default class 2013-08-28 16:41:57 +02:00
f5e640c875 Oops, added class name 2013-08-28 16:37:31 +02:00
46e6cd37b7 Merge remote-tracking branch 'origin/master' into 0.7.4 2013-08-28 16:08:51 +02:00
13a5a8df57 Check phpunit classes 2013-08-28 16:07:53 +02:00
f9c405d46a NO_THREADS mode for tests 2013-08-28 16:00:30 +02:00
a07ae731e3 Removed self-kill [will it blend?] 2013-08-28 15:45:15 +02:00
8dcb404bce Correct server object 2013-08-28 15:36:14 +02:00
56fdc87e9b Changed automatic init to manual startup 2013-08-28 15:32:16 +02:00
ff4970578a Moved requires() 2013-08-28 15:27:24 +02:00
4d53d07def Moved tests 2013-08-28 15:24:18 +02:00
9d3379daca Removed MobAPI
Why was that here?
2013-08-28 14:30:27 +02:00
070e9ebbae Removed tests building 2013-08-28 14:20:29 +02:00
8da61e613f Send sign text on update 2013-08-28 11:01:45 +02:00
2fff23019a PHP 5.5.3 2013-08-27 21:22:08 +02:00
093b86fa43 Fixed URL 2013-08-27 19:16:11 +02:00
9d52250afa Fixed flint&steel usage 2013-08-27 19:15:18 +02:00
4cdb751a67 Removed fish items 2013-08-27 18:28:52 +02:00
36ff8331b7 Updated headers 2013-08-27 18:16:57 +02:00
c73c1eb806 Fixed clearQueue() action not being deleted 2013-08-27 17:29:55 +02:00
41084f51a6 Removed double chests 2013-08-27 14:03:48 +02:00
1055ab6a79 Fixed chests 2013-08-27 13:48:08 +02:00
d61f7b889f Fixed level importing 2013-08-27 13:47:26 +02:00
5d6d30ed4e Chest unpairing 2013-08-27 13:06:43 +02:00
176c371330 Added chest pairing 2013-08-27 12:38:00 +02:00
e8c273fc10 Updated Chests [part1] 2013-08-27 02:08:04 +02:00
9e337e21d2 Implemented Level::getSafeSpawn() 2013-08-27 00:22:06 +02:00
4a05f04a00 Sign NBT data on Player, send chests NBT 2013-08-27 00:02:07 +02:00
291ba5c499 Removed third-party NBT link 2013-08-26 23:37:13 +02:00
2de8f95af4 Fixed empty signs on world load 2013-08-26 23:36:28 +02:00
3d5541696b New chat protocol 2013-08-26 23:35:18 +02:00
9ec51b18fe Update Tiles to use NBT 2013-08-26 23:35:04 +02:00
ff99aab6ff New NBT parser/writer 2013-08-26 23:29:56 +02:00
515affa1a7 New API version 2013-08-26 23:29:46 +02:00
3c348f2e22 Added new EntityData Packet 2013-08-26 23:29:32 +02:00
f14c5ec90c Updated version to 0.7.4 2013-08-26 18:36:58 +02:00
dc0577dcfa 0.7.4 compatibility update - new chat message handling [part1] 2013-08-26 18:16:30 +02:00
3779a66bdb Cake is now broken if the bottom block is removed [MCPE-4661] 2013-08-26 15:35:20 +02:00
4156aad71f Preparing 0.7.4 features 2013-08-26 15:32:35 +02:00
a66c1c76f8 Updated links 2013-08-26 13:47:47 +02:00
5f214b0984 Removed chcp from start.cmd 2013-08-26 13:47:39 +02:00
a0bd42712f Dev release version :) 2013-08-26 12:10:45 +02:00
ffc95bf311 Fixed {} 2013-08-26 11:10:25 +02:00
673515bc06 Fixed issues with DevTools 2013-08-26 11:04:21 +02:00
7865b8dbe5 Fixed #748 Player health not being saved [gh#748] 2013-08-26 10:01:12 +02:00
30483d5312 Added Shears check and drops [gh#749,750] 2013-08-25 20:40:36 +02:00
02a8a3e881 Quartz slab recipe added 2013-08-25 20:18:24 +02:00
6dc33791a7 Reload Bugfix 2013-08-22 19:40:20 +09:30
54f058de3e Config Reload 2013-08-22 19:30:27 +09:30
dfd451f620 Simplificated fix 2013-08-22 11:56:57 +02:00
85af510d74 Update ConsoleAPI.php 2013-08-22 19:21:50 +09:30
06554e8669 Added output initialization to allow monitoring of commands. 2013-08-22 19:18:17 +09:30
a91dee0e04 Do not check type on actions 2013-08-22 02:35:13 +02:00
f5492aac91 Stone brick recipe derp 2013-08-22 02:02:25 +02:00
8b5bd8f206 Removed invalid Cookie item 2013-08-21 21:27:19 +02:00
111c716c21 Merge pull request #735 from brandon15811/master
Add support to cross-compile for Mac from Linux
2013-08-21 11:23:46 -07:00
5175e1f297 Add support to cross-compile for Mac from linux 2013-08-21 12:50:31 -05:00
e0390d0f54 Rewrote a bit of Player::teleport() 2013-08-21 14:57:13 +02:00
f7abb6f909 Do not update water 2013-08-21 13:20:14 +02:00
c3517a4a49 compile script armv7a for Android 2013-08-20 23:50:13 +02:00
3cc4ee0281 Alpha_1.3.6 2013-08-20 22:47:00 +02:00
1ca87c7ade Rewrote Location table handling on Pocket Level Format parser [due to MCEdit bug] 2013-08-20 22:46:01 +02:00
6bafcbf2a7 Revert "Lowered process delay"
This reverts commit b905aabd19.
2013-08-20 21:15:06 +02:00
ea2ff5d983 Paintings now have health 1 always 2013-08-20 21:06:44 +02:00
b905aabd19 Lowered process delay 2013-08-20 21:06:31 +02:00
50f6bf7825 Fixed android build script 2013-08-20 19:17:48 +02:00
5ee2ad6a17 Added generic-armv7-a to compile script 2013-08-20 17:45:32 +02:00
26ce2e9e13 Added PocketMinecraftServer::process() limit based on #436 2013-08-20 16:57:23 +02:00
55cfc2895d Fixed Leggins/Pants crafting recipe 2013-08-20 13:13:43 +02:00
3ba213f2f0 Proper same armor check 2013-08-20 12:52:06 +02:00
6c941977f3 Fixed possible armor crash 2013-08-20 12:49:09 +02:00
ea17ff9d9b Alpha_1.3.5 release 2013-08-20 12:25:49 +02:00
1b72ef8827 Better Player:close() cleanup 2013-08-20 11:31:37 +02:00
a34595292d Allow armor replacing (changing armor to another armor) 2013-08-20 11:23:55 +02:00
e42314ade7 Fixed block durability 2013-08-20 04:53:22 +02:00
5683dca9f6 Fixed crash 2013-08-20 02:57:37 +02:00
b5c935559f Alpha_1.3.4 2013-08-20 02:32:47 +02:00
7a37b0e4bf Quartz slabs 2013-08-20 02:24:15 +02:00
19b3ac4a99 Fixed disconnection 2013-08-20 02:15:18 +02:00
bf1b00f0e6 Correct teleporting with the new player list handling 2013-08-20 02:06:14 +02:00
7102787aa9 Added correct handling of RemovePlayer packet for in-game player list 2013-08-20 01:42:45 +02:00
d26d657b95 Fixed /difficulty 2013-08-20 01:16:24 +02:00
3374bbcc9e Chest animations for everyone! Woo! 2013-08-20 00:26:37 +02:00
8d408996f4 Double chest checks, chest opening broadcast 2013-08-19 21:05:09 +02:00
68e78ba40b Implemented basic tool durability 2013-08-19 17:37:08 +02:00
a7b739d17f Fixed hotbar reset bugs in block placement 2013-08-19 17:04:02 +02:00
78c242eac4 Fixed armor hotbar reset bug 2013-08-19 16:51:40 +02:00
7e6758fb60 Alpha_1.3.4dev 2013-08-18 21:32:26 +02:00
39658ef63f Automatic recovery of corrupted maps 2013-08-18 21:31:47 +02:00
4f1ce9adee Revert "Merge pull request #682 from Humerus/patch-1"
This reverts commit 04c641b79b, reversing
changes made to ba9b800eff.

Revert
2013-08-18 13:17:01 +02:00
87a67804c4 Merge pull request #677 from Humerus/master
Enabled autosave via an option in server.properties.
2013-08-18 04:11:53 -07:00
04c641b79b Merge pull request #682 from Humerus/patch-1
I'm bored x2.
2013-08-09 21:22:01 -07:00
9c9939440f I'm bored x2. 2013-08-09 22:57:32 -04:00
ba9b800eff Merge pull request #599 from MinecrafterJPN/master
Fixed player.block.activate
2013-08-09 04:44:10 -07:00
62b589295e Enabled autosave 2013-08-08 23:02:38 -04:00
b6d86c287c Update ServerAPI.php 2013-08-08 22:58:32 -04:00
792a4bd98e Changed IRC Link 2013-08-02 13:01:47 +02:00
28790e0fb3 Changed chcp to normal Unicode 2013-08-01 19:32:17 +02:00
b77e7dd05c Added weird water 2013-08-01 19:31:39 +02:00
4c73629b9e Object check - Fixes #537 2013-07-31 22:38:17 -05:00
330e06b892 Players can no longer be given air (causes client crash) through /give.
Fixes #567.
2013-07-31 22:08:34 -05:00
f3f6828699 Object check on getting distance for PvP attacks
Fixes #586, although I'm not entirely sure what's causing the object to be invalid in the first case, so this is a temporal fix.
2013-07-31 21:45:23 -05:00
c1e1f5195b Fix for players connecting with a blank username field
Fix for players connecting with a blank username field (#636).
2013-07-31 16:45:56 -05:00
a60d41d489 Merge pull request #634 from williamtdr/patch-1
Fix for fly kick when player is standing on Fence
2013-07-31 14:37:04 -07:00
5975bd9d32 Fix for fly kick when player is standing on Fence
Fix for Issue #631 (Player kicked for flying when standing on fence).
2013-07-31 00:44:41 -05:00
e67b583cbe Added Player::realmsData for future checking 2013-07-23 19:02:32 +02:00
4755dee47d Fixed player count bug 2013-07-23 17:33:37 +02:00
fd5d981aa5 Revert "Better Command Permissions Check"
This reverts commit b42222c461.
2013-07-23 16:13:59 +02:00
a93b2cf954 Revert "Minor fix to command.check"
This reverts commit ed9eadd1a0.
2013-07-23 16:13:51 +02:00
16e65560a8 Revert "Update Deprecation.php"
This reverts commit 08000257fb.
2013-07-23 16:13:44 +02:00
32d658122b Fixed player.block.activate 2013-07-22 21:59:29 +09:00
1cf2741f96 Moved chat disconnect broadcast 2013-07-21 23:42:07 +02:00
47c934cee2 Reordered instructions 2013-07-21 23:36:14 +02:00
3606c392f2 Disallow packet receival on Player disconnect 2013-07-21 23:35:03 +02:00
6d4465eb67 Fixed High CPU Usage. setPosition now uses prepared statements. 2013-07-15 21:44:47 +09:00
08000257fb Update Deprecation.php 2013-07-15 12:50:03 +09:30
ed9eadd1a0 Minor fix to command.check 2013-07-15 12:15:23 +09:00
b42222c461 Better Command Permissions Check 2013-07-15 12:08:28 +09:00
635cd677eb minor armor api fix. 2013-07-14 17:50:14 +09:30
56f500d520 Merge branch 'master' of https://github.com/PocketMine/PocketMine-MP 2013-07-13 23:59:39 +02:00
3202678594 Compiler changes 2013-07-13 23:59:23 +02:00
a68676a247 Added setArmor and getArmor 2013-07-13 18:18:10 +09:00
7efed17b74 Possible fix for armor crash 2013-07-04 23:33:56 +02:00
b776d9d5fc Fixed ghost armor 2013-07-04 22:01:28 +02:00
5237867319 Fixed Armor AIR crash 2013-07-04 21:48:35 +02:00
402fc087ca Armor fix 2013-07-04 20:40:35 +02:00
1727e18e31 Updated for Minecraft: PE 0.7.2 2013-07-04 20:24:13 +02:00
03b4e40bf4 Ooops! 2013-07-03 18:12:22 +02:00
8f1c34fdc5 Added whitelist to Query 2013-07-03 18:08:53 +02:00
84bb66357e Cast floats as integers on Level::getBlock() and Level::setBlock() 2013-07-03 10:59:32 +02:00
c00bfe3908 Fixed async thread get 2013-06-25 01:22:02 +02:00
3fb99e118c Added item save check 2013-06-20 22:10:39 +02:00
1d2de1f038 Fixed DEFLATEPacket notification 2013-06-17 10:03:20 +02:00
d177af3297 Fixed #410 2013-06-17 09:29:54 +02:00
8dcdf55264 Frequent memory checks 2013-06-17 09:27:17 +02:00
5a168836c5 Fixed setting the difficulty via command 2013-06-17 03:29:44 +02:00
ce1e95195b Alpha_1.3.3dev 2013-06-17 02:53:29 +02:00
cf5e2f63db Fixed pthreads infinite loop when string length was <= 0 2013-06-17 01:07:58 +02:00
d4c4f8817d Pushed fix for #391 2013-06-17 00:44:18 +02:00
b6a1d42870 Preparing Alpha_1.3.2 fix update 2013-06-16 17:51:31 +02:00
84a5f0fce5 Tweaked block break times #254 2013-06-16 17:33:24 +02:00
c136eb2b2e Fixed #400 2013-06-16 17:31:55 +02:00
d0a021de73 Improved #401 2013-06-16 17:28:12 +02:00
155c918bb8 Fixed Leaf Decay loops causing Lag Spikes, fixed #391 [gh#391] 2013-06-16 17:18:15 +02:00
19d0c70669 Added simple Matrices 2013-06-16 14:34:06 +02:00
02721c09a4 Possible fix for #391 2013-06-15 21:24:06 +02:00
204a4ce831 Updated PHP version 2013-06-14 14:43:43 +02:00
a118e626c2 Changed Languages
Other people that checks issues might not understand Spanish or Korean.
So, the people that use other languages might do it, as an exception,
but we won't add it to the Guidelines. Doing that would encourage it.
2013-06-14 13:49:35 +02:00
01d5612ed8 CONTRIBUTING Better Reading 2013-06-14 19:11:04 +09:30
59aa317546 Update CONTRIBUTING.md with Additional Language Issue stuff.
We need to consider non-English speakers as well.
2013-06-14 19:10:28 +09:30
4c9cbaf1ee Possible fix for #391 2013-06-14 02:56:29 +02:00
18562317c3 Added Packet Count check 2013-06-14 00:21:43 +02:00
f51630c572 Fixes to DEFLATE 2013-06-13 19:53:04 +02:00
847590645d Added CONTRIBUTING.md 2013-06-13 16:46:04 +02:00
fbf22cec39 Fixed #386 Adding items use the correct item max stack size [gh#386] 2013-06-13 10:44:00 +02:00
0dd3d4a457 Alpha_1.3.2dev 2013-06-12 22:48:31 +02:00
f521d16ce3 Alpha_1.3.1 release 2013-06-12 22:18:00 +02:00
72ec318481 Fixed crafting inside a chest 2013-06-12 22:01:42 +02:00
99554caa69 Added some type checks 2013-06-12 20:46:23 +02:00
bfffa35246 Async checks each second 2013-06-12 19:50:37 +02:00
09a388f8de Fixed type again 2013-06-12 19:41:03 +02:00
a7149ad9ef Fixed field type 2013-06-12 19:40:09 +02:00
471de2d1c5 Changed domain 2013-06-12 19:38:34 +02:00
aa7d9b5e05 Added full async operations in a separate Thread 2013-06-12 19:38:11 +02:00
2e23ce8beb Ban API fly fixed 2013-06-12 17:11:37 +02:00
e4871ee0c4 Faster packet broadcast 2013-06-12 17:10:10 +02:00
86469a1031 Fix 2013-06-12 16:43:29 +02:00
533c179622 Added Client Lag detection 2013-06-12 16:25:11 +02:00
4321a03935 Mini fix 2013-06-12 16:11:15 +02:00
68f0a91d56 Fixed Chunk max upload 2013-06-12 16:10:50 +02:00
5e231c846c Chat checks 2013-06-12 14:55:38 +02:00
7d3992bcc2 Improved some events 2013-06-12 14:51:36 +02:00
c83d4d955f Improved Player::blocked 2013-06-12 13:46:44 +02:00
ff7fa066a5 Entities are now updated on block updates 2013-06-12 12:20:56 +02:00
9619ebc2af Fixed lag issues when breaking blocks 2013-06-12 12:13:51 +02:00
0a4beaf051 Fix 2013-06-12 00:07:20 +02:00
2957f35194 Fixed incorrect player count at login 2013-06-12 00:06:09 +02:00
5afd26b1b6 Reduced stats server timeout 2013-06-11 23:08:07 +02:00
152ebcbc17 Fixed Memory Stats collection 2013-06-11 18:55:08 +02:00
73c155090c Fixed UP/Down speed 2013-06-11 18:50:47 +02:00
89cb879f1f Fixed pigs dropping leather 2013-06-11 17:42:47 +02:00
a45858ad94 Fixed #373 2013-06-11 17:01:51 +02:00
c8e157156e Added bandwidth usage measurement to Window Status 2013-06-11 11:00:02 +02:00
6563169527 Removed libedit support temporally 2013-06-11 10:43:50 +02:00
7e67f50da5 Creative players pickup item sound 2013-06-11 00:55:48 +02:00
393b57c535 Few level generation changes 2013-06-10 17:35:11 +02:00
bda5e62788 Fixed syntax 2013-06-10 17:13:34 +02:00
579175b3bc Ore Generation 2013-06-10 17:11:04 +02:00
808f5473d0 Added more Vector math 2013-06-10 17:10:49 +02:00
4284211bd1 Change 2013-06-10 17:10:40 +02:00
33733cd608 New API version 2013-06-10 17:10:18 +02:00
1e14485444 Increased support Y radius 2013-06-10 15:47:53 +02:00
c42fd790ff Fixed error 2013-06-10 15:36:45 +02:00
2ef1f0c9d0 Fixed #364 added despawn timer for arrows [gh#364] 2013-06-10 10:37:33 +02:00
abcb5828ed Fixed #361 2013-06-10 01:29:14 +02:00
ee7c767c16 Limited player upload peak using CLI max-chunks-per-second parameter 2013-06-10 01:20:28 +02:00
affd67debe Added ore generation to Superflat 2013-06-10 01:06:48 +02:00
79555e4029 Fixed Sign update bug 2013-06-09 23:26:03 +02:00
e1c0139ab3 Possible fix for signs bug 2013-06-09 23:02:01 +02:00
ca8be7b047 Lowered max lag acceptance to resend packets 2013-06-09 21:55:43 +02:00
3ab3526404 Improved Player::orderChunks() 2013-06-09 21:35:37 +02:00
523c4390fa Fixed entities not updating 2013-06-09 20:55:37 +02:00
508ee7e1d6 Removed outdated functions 2013-06-09 20:40:18 +02:00
4a5783b57b Large improvement in chunk sending 2013-06-09 20:37:45 +02:00
31490576d2 Added packet loss kicks and packet recovery repetition 2013-06-09 19:07:58 +02:00
b4f95fad11 Fix 2013-06-09 18:53:39 +02:00
8c190ead7f Fixed sand getting block updates 2013-06-09 18:52:56 +02:00
fef0b27f7c Changed speed check 2013-06-09 16:36:44 +02:00
cbe0692696 Players can put out fires 2013-06-09 15:14:30 +02:00
1cc19ae1e8 Fire can be broken 2013-06-09 14:59:55 +02:00
2976db25c3 Basic implementation of Fire 2013-06-09 14:59:02 +02:00
2f6ddb6aa4 Less complete inventory sending 2013-06-09 13:51:45 +02:00
099bedf8ee New speed limit 2013-06-09 13:37:27 +02:00
bd1875f5e4 Added chunk_split() to crash dumps 2013-06-09 13:18:58 +02:00
d82399e686 Fixed #359 crash dump name not compatible with Windows 2013-06-09 13:11:55 +02:00
4f10b1cb7c Fixed #358 2013-06-09 13:02:38 +02:00
ba53a0927f Removed debug message 2013-06-09 06:00:36 +02:00
9b88a4a73f Player packet handling rewrite, fix #350 2013-06-09 05:56:48 +02:00
715b92b681 Typo 2013-06-08 19:27:18 +02:00
1014052a57 Removed /invisible 2013-06-08 19:23:16 +02:00
ac486ec970 Removed generator setting 2013-06-08 18:55:08 +02:00
5a278f8a16 Fixed regeneration acting on all gamemodes 2013-06-08 18:47:30 +02:00
7404279f15 Added spawn-animals and spawn-mobs 2013-06-08 18:34:28 +02:00
5f40ab84f0 Fixed memory tracking error 2013-06-08 18:26:24 +02:00
3061b8eb3c Added a check to memory tracking 2013-06-08 17:48:17 +02:00
e58ef1f62c Added automatic memory usage tracking 2013-06-08 17:45:33 +02:00
4803f14a21 Removed chat repeating lag issues 2013-06-08 17:25:15 +02:00
409cc0931f Fixed some indexes 2013-06-08 17:21:02 +02:00
9874bd199e Marked chat packets as not recoverable 2013-06-08 17:05:39 +02:00
1a822460d8 Fixed DEFLATEPacket return 2013-06-08 16:59:49 +02:00
8d2862a744 Fixed ladders 2013-06-08 16:36:53 +02:00
4f3e49b6a9 Packet loss limit lowered 2013-06-08 14:47:36 +02:00
f1c278915d Possible fix for memory leak 2013-06-08 14:46:34 +02:00
169d122774 Fixed typo 2013-06-08 14:31:19 +02:00
ccc5e1b628 SignPosts drop being without a support block 2013-06-08 14:30:47 +02:00
5786ba7a35 Moved blocks around 2013-06-08 14:30:26 +02:00
cd932d5c07 Snow Layer is broken on update 2013-06-08 14:23:30 +02:00
bfa65e1e7d Time is sent on change 2013-06-08 14:19:10 +02:00
16a8566fca Time now is displayed correctly 2013-06-08 14:17:38 +02:00
28480424c5 Fixed crash 2013-06-08 13:45:42 +02:00
54227b1d86 Possible memory leak fix 2013-06-08 13:43:47 +02:00
04390e758d Fixed #347 2013-06-08 13:25:17 +02:00
3e46fc1fdd Fixed crafting in some cases where item was replaced 2013-06-08 13:11:16 +02:00
97dd718e4f Fixed #348 2013-06-08 12:51:28 +02:00
883b18078f Removed clientID from checks 2013-06-08 02:22:20 +02:00
8bef816061 Added PMF_LEVEL_DEFLATE_LEVEL 2013-06-08 01:59:00 +02:00
13bfaaf7b8 Fixed crash after level unload 2013-06-08 01:50:03 +02:00
164b420af6 Tiles and Entities won't get wiped on level unload 2013-06-08 01:40:39 +02:00
38c50c2fec Fixed API unloading 2013-06-08 01:40:13 +02:00
157237e3ef Proper Level checks on unload 2013-06-08 00:57:21 +02:00
20b83319de Added stop Chunked on Player::close() 2013-06-08 00:43:39 +02:00
1ce23ab8d7 Added DEFLATEPacket protocol support
https://gist.github.com/shoghicp/5729825
2013-06-08 00:41:34 +02:00
4f3700f13a Fixes indexes 2013-06-07 20:35:05 +02:00
129e099f88 Fixed Entity metadata sending, sheeps on fire 2013-06-07 20:32:38 +02:00
9d1369bfe9 Fixed items being consumed on CREATIVE mode 2013-06-07 20:02:25 +02:00
6fa0ef652e Using !== instead of != in recipe checks 2013-06-07 19:36:14 +02:00
71e556a181 Fixed crafting repeated items 2013-06-07 19:30:30 +02:00
51f4faf22e Bonemeal usage count 2013-06-07 19:25:23 +02:00
8e127e60a0 Another fix 2013-06-07 19:18:35 +02:00
3023df2033 Function fix 2013-06-07 19:14:42 +02:00
3463db04a6 Fixed tool metadata [partial] 2013-06-07 19:14:09 +02:00
e9683ff5d2 Fixed eating 2013-06-07 19:04:02 +02:00
64dca86342 Fix overloaded property 2013-06-07 17:36:57 +02:00
6a13705970 Fixed Level PMF 2013-06-07 16:42:31 +02:00
afbde5c7ac Added server.tick event deprecation notice 2013-06-07 16:29:16 +02:00
6f2b2f98d6 Removed debug messages 2013-06-07 16:17:02 +02:00
05ae6cdef3 Better event system 2013-06-07 16:15:19 +02:00
e7c6a0c817 Another typo 2013-06-07 14:02:50 +02:00
81524362c0 Fixed typo 2013-06-07 14:02:22 +02:00
35c0c21c8d Better /kill command, ensures death 2013-06-07 12:54:45 +02:00
c37c6da42d Fixed #339 Creative players have their inventory cleared on death [gh#339] 2013-06-07 12:51:12 +02:00
3fa1bd3a05 Merge branch 'master' of https://github.com/PocketMine/PocketMine-MP 2013-06-07 12:44:15 +02:00
fdb7af5df2 Chests and furnaces drop their items on break 2013-06-07 12:44:10 +02:00
a463e0c09e Revert 67919a6 2013-06-07 09:29:38 +09:30
67919a68e1 Added Lave Bucket as Fuel Check 2013-06-07 09:17:31 +09:30
45ee7ea7ae Correct armor checks 2013-06-07 00:43:15 +02:00
e3e7919652 Fixed wool on sheeps 2013-06-06 23:55:14 +02:00
139d8b38b5 Fixed spawn eggs & buckets on creative ,pde 2013-06-06 23:31:46 +02:00
96c11adc89 Fixed typo 2013-06-06 23:05:38 +02:00
82aa76be17 Added Spawn Eggs 2013-06-06 23:02:44 +02:00
7970b8aeed Buckets 2013-06-06 22:49:43 +02:00
ab3fcfc148 Correct drops for Snow and Cake 2013-06-06 22:44:20 +02:00
28f6a964d4 Added cake eating 2013-06-06 22:24:19 +02:00
306cc9f00c Fixed #333 2013-06-06 21:51:05 +02:00
c1f79fa2f8 Fixed craftin recipes with wildcard 2013-06-06 19:51:24 +02:00
1179369666 Refixed recipe 2013-06-06 19:32:35 +02:00
0bd8d0b0d0 Fixed recipe mixture 2013-06-06 19:31:15 +02:00
67b0b97005 Fix lava buckets on furnaces 2013-06-06 19:09:23 +02:00
5e45567c1d Fixed some slot sending 2013-06-06 19:02:30 +02:00
adce1ad920 Fixed equipment error message 2013-06-06 18:32:49 +02:00
8b1c251a59 Fixes crafting 2013-06-06 18:27:10 +02:00
8b9b05991d Fixed crash 2013-06-06 17:49:38 +02:00
5cb06579cd Another fast network fix 2013-06-06 17:34:42 +02:00
63933ed1fc Fast network fix 2013-06-06 17:31:55 +02:00
4b408675cf Minecraft: Pocket Edition 0.7.0 dev. release
* Crafting enabled, report bugs
* Chat handler
2013-06-06 17:14:09 +02:00
1f4df559e0 Final fix #324 2013-06-05 18:25:16 +02:00
89ef299333 Fixed #324 2013-06-05 16:30:12 +02:00
3d3383bea7 Fix #317 - removed phpseclib 2013-06-05 15:10:40 +02:00
c95c231cfc Possible fix for #323 - Use phtreads release from pecl 2013-06-05 14:40:09 +02:00
d614f3c9da Revert "New Language Output preparation"
This reverts commit 6993528af2.
2013-06-05 14:22:04 +02:00
6993528af2 New Language Output preparation 2013-06-05 21:45:41 +09:30
18b437eec9 Fixed Entity update 2013-06-05 13:15:40 +02:00
67b533a44d Removed debug thing 2013-06-05 12:59:50 +02:00
5def864aca Removed server.tick event 2013-06-05 12:58:58 +02:00
911577e9b8 Fixed syntax error 2013-06-05 12:36:31 +02:00
fbf897d1be Fixed level event duplication on some cases 2013-06-05 12:20:57 +02:00
a5bc95e733 Fixed entities being updated when they shouldn't 2013-06-05 12:11:04 +02:00
2dd188a0bd Old pthreads release 2013-06-04 22:34:39 +02:00
a830555d90 Added a normal Temporal Generator 2013-06-04 22:31:34 +02:00
8bf10c523e Fixed Level Generation block updates 2013-06-04 20:08:14 +02:00
7e13ae2bda Leave improvement 2013-06-04 19:51:16 +02:00
7527c57e1e Fixed #274 #301 Leaves now disappear [gh#274,301] 2013-06-04 19:41:13 +02:00
06a0f169dd Better auto-save, less resource and disk usage 2013-06-04 18:45:30 +02:00
f12620f376 Possible fix for #323 2013-06-04 17:42:32 +02:00
dce9b3140a Plant growth & scheduled updates! 2013-06-04 17:23:03 +02:00
be9676ebe5 Added server_engine to query 2013-06-04 11:25:05 +02:00
bd6e3901a6 More fix 2013-06-04 11:01:59 +02:00
6f8963bdcd Correct line offset in Plugins 2013-06-04 10:58:11 +02:00
033a1673f0 Added bandwidth measure 2013-06-04 10:55:20 +02:00
0c7c36cc03 Fixed unrelated packet loss kicks 2013-06-04 10:06:21 +02:00
e01a3e6811 Increased packet loss allowance 2013-06-04 01:59:35 +02:00
566cee2b0b New way to measure Ping 2013-06-04 01:12:22 +02:00
03e059a190 Added player.spawn and player.respawn 2013-06-04 00:13:12 +02:00
f80326b714 Limited length of messages to 100 2013-06-04 00:10:57 +02:00
1935e2bbf7 Disallow weird characters in chat 2013-06-04 00:08:58 +02:00
e43b4e67c6 Disallow sending empty chat messages 2013-06-03 23:33:52 +02:00
45267ea074 Fixed crash when players try to chat [MCPE 0.7.0] 2013-06-03 23:33:07 +02:00
45efcc5faa Fixed undefined $message 2013-06-03 23:28:24 +02:00
15c9b7214d Fixed crash at unload 2013-06-03 23:26:47 +02:00
be83eaf521 Correct call of destruct chain to release PMF file locks at unload 2013-06-03 23:24:33 +02:00
f2927df2b3 Renamed TileEntity to Tile (TileEntityAPI, TileEntity class, variables) 2013-06-03 19:19:00 +02:00
5bba03eb09 Refactored EntityAPI and TileEntityAPI 2013-06-03 19:11:46 +02:00
588379a430 Added player.teleport.level 2013-06-03 18:51:33 +02:00
dc22e1b81c Kick players on high packet loss 2013-06-03 18:27:17 +02:00
f55fb8d490 Player actions and bows [WiP] 2013-06-03 16:31:33 +02:00
d1f2f82c6d Fixed #313 Entities are updated depending on near block updates [gh#313] 2013-06-03 12:20:07 +02:00
4b6e456c65 Possible solution for #317 [gh#317] 2013-06-03 11:16:12 +02:00
a8b8427065 Updated secure random number generator ith harder entropy distillation 2013-06-02 18:01:34 +02:00
ec22034ad7 Plugin version 2, include extra data 2013-06-02 17:55:59 +02:00
c7a3fc4931 Fixed time checking on Linux 2013-06-02 13:32:36 +02:00
91e414fb87 Added phpseclib for future usage 2013-06-02 13:29:24 +02:00
1b50bd6e0f FInal fix #312 2013-06-02 12:54:21 +02:00
ffd8ac2879 Fix again #312 - Vector3 2013-06-02 12:48:04 +02:00
9ead05a6fa Fixed #312 Position::getSide() now returns a Position object instead of a Vector3 one 2013-06-02 12:46:27 +02:00
4f39818cae Added something to test 2013-06-02 12:22:41 +02:00
15ab47070a Sand now falls through Liquids when placed just on top of them 2013-06-02 11:34:02 +02:00
b72d4ac407 Fixed #311 Check for Liquids, ladders and cobweb for flying 2013-06-02 11:20:16 +02:00
0ca18864f3 Fixes #311 2013-06-02 10:22:28 +09:30
54b73e5f82 Added block cloning fix 2013-06-01 19:58:54 +02:00
24ba7cbbd1 New direct block method, better block placement sending 2013-06-01 00:32:23 +02:00
722eb6d1f9 Added -uclibc for Android 2013-05-31 23:09:15 +02:00
1638e68c53 Another build script fix 2013-05-31 23:03:41 +02:00
75bb2a6399 New method EntityAPI::getRadius() 2013-05-31 18:58:59 +02:00
a890cdc023 Performance improvements - removed Player action queue 2013-05-31 14:43:53 +02:00
66fc483156 Better item pickup 2013-05-31 14:30:07 +02:00
1376cc860d Removed API::action() 2013-05-31 14:29:46 +02:00
732f5f5168 Fixed compile script *again* 2013-05-31 13:46:56 +02:00
66e635daeb New Entity update system, scheduled updates when needed only 2013-05-31 13:44:06 +02:00
3ac4b0af68 Entities spawn with their motion 2013-05-31 12:04:43 +02:00
d7f74a6725 Removed incorrect unloaded chunk detection 2013-05-31 11:53:50 +02:00
0522052c75 New compile script 2013-05-31 00:48:25 +02:00
e6dbd61308 Drops do not get into blocks 2013-05-30 19:54:55 +02:00
848554bc0c Correct falling sand drop position 2013-05-30 19:34:31 +02:00
fc02572065 Drops now have starting speed, correct entity motion at spawn 2013-05-30 18:55:50 +02:00
09efcec605 Better entity position sending using motion update 2013-05-30 16:45:44 +02:00
4507072980 Fixed sand falling replacing other blocks 2013-05-30 16:33:08 +02:00
2c8d527025 Increased view-distance by default, due to Fancy Graphics in 0.7.0 2013-05-30 16:19:58 +02:00
9919a709e9 Vector3 => Position fix 2013-05-30 13:13:36 +02:00
3825edaaab Better item spawning on falling entity break 2013-05-30 12:51:56 +02:00
6e5924a183 Typo fixed 2013-05-30 12:49:35 +02:00
a795b64bab Added new Block properties (Block::isSolid, Block::isFullBlock) 2013-05-30 12:47:24 +02:00
8d00ef381d Fixed Hardcore flags 2013-05-29 23:30:07 +02:00
b564868467 Fixed #305 Made BlockAPI check for flowable blocks instead of transparent blocks [gh#305] 2013-05-29 23:25:43 +02:00
450b5d9560 Updated TileEntity API [fixes #306] 2013-05-29 23:13:01 +02:00
25de7a68d5 API version update 2013-05-29 23:12:23 +02:00
6e2f7af6b4 Added hardcore mode 2013-05-29 22:58:43 +02:00
2f05a03e51 Fixed #304 Calculate Server Time Offset [gh#304] 2013-05-29 18:20:48 +02:00
ddec63c4d4 Fixed cleanup 2013-05-29 15:00:41 +02:00
6242089b28 Removed incomplete generator 2013-05-29 14:09:36 +02:00
1fbf475ace Mini fix 2013-05-29 14:08:30 +02:00
2271d45fd9 Fixed Mac compilation 2013-05-29 14:03:39 +02:00
f6ab39a526 Fixed falling entities falling upwards 2013-05-29 12:18:35 +02:00
71584288dc Fixed Entity floor drag 2013-05-29 12:11:12 +02:00
e67a7a510e Gravel is able to drop Flint 2013-05-29 11:57:58 +02:00
8192b41693 Fixed #303 Checking plants position on normal block update 2013-05-29 11:53:57 +02:00
4a969257d1 #303 Torches are able to be placed on top of Fences [gh#303] 2013-05-29 11:53:55 +02:00
fde93debb4 Fixed @brandon15811 typo 2013-05-29 01:13:57 +03:00
620486a4a0 Merge pull request #302 from brandon15811/patch-1
Add script for android/rpi cross-compiling
2013-05-28 14:39:27 -07:00
0d12039623 Added TileEntity::setText(1,2,3,4) 2013-05-28 23:35:33 +02:00
00427a076e Add script for android/rpi cross-compiling 2013-05-28 16:33:51 -05:00
58fd67d2ed Falling Entities, better Physics [not final] 2013-05-28 22:03:58 +02:00
cb03daf28a Removed duplicate in compile script 2013-05-28 11:05:38 +02:00
3d28f519c7 Revert "Fix for pthreads and cross_compile"
This reverts commit 6b61bc11d0.
2013-05-28 08:23:13 +02:00
6b61bc11d0 Fix for pthreads and cross_compile 2013-05-28 08:06:44 +02:00
c9d0cf3698 Added env. variable to specify the number of threads [gh#300] 2013-05-27 23:20:06 +02:00
5d6669201b Fixed compile script 2013-05-27 21:24:13 +02:00
d8f6e9ff0e Pass compile options via env. variables 2013-05-27 20:36:49 +02:00
929c27e339 Changed the order of some build instructions 2013-05-27 18:16:58 +02:00
a92e4f6acd Disable not needed cURL functions 2013-05-27 16:36:31 +02:00
b7bc0826af Autodetection of native machine and code optimization 2013-05-27 14:23:10 +02:00
044b25ccd2 Faster chunk distance ordering 2013-05-26 19:58:23 +02:00
90effd173b Faster chunk sending algorithm 2013-05-26 19:57:41 +02:00
fc80a85c8c Faster network stack on overflow conditions 2013-05-26 19:57:19 +02:00
06c57a3aae Fixed #293 player.armor data not being correct [gh#293] 2013-05-26 16:16:36 +02:00
6d54495402 Cached Utils::getIP() method 2013-05-26 16:15:30 +02:00
838e7ad010 Hide rcon.password in the crash log 2013-05-26 16:11:21 +02:00
6262fbffcb Send correct entity motion 2013-05-26 14:06:26 +02:00
7622151a21 Pine & Spruce trees fixed 2013-05-26 13:36:33 +02:00
aefcfad296 Added more features to the World Generator 2013-05-26 13:22:22 +02:00
424dba2fdd Filling a chunk triggers the block change saving algorithm 2013-05-26 12:48:20 +02:00
7c3b8807e9 Alpha_1.3.1dev version 2013-05-26 12:16:23 +02:00
f6a395e7b7 Possible fix for #289 [gh#289] 2013-05-26 12:04:26 +02:00
d92056fe77 Fixed typo in deop 2013-05-26 17:36:45 +09:30
161a271127 Merge pull request #290 from sfan5/patch-1
Allow DeOPing disconnected players
2013-05-26 01:03:07 -07:00
8ec11b35ad Set up base for upcoming Mob MobAI and MobAPI 2013-05-26 17:27:16 +09:30
df4a29d7d6 Allow DeOPing disconnected players 2013-05-26 09:55:03 +03:00
00de63986b Alpha_1.3 stable release 2013-05-26 01:18:44 +02:00
60c0345c81 Fixed cobweb 2013-05-26 00:49:20 +02:00
b39677cc96 Added LevelAPI::unloadLevel(Level $level) 2013-05-26 00:37:18 +02:00
72f8f00c5d Autorecovery of bad chunks 2013-05-25 23:46:02 +02:00
ce391160f4 Added hostile mobs drops 2013-05-25 23:21:21 +02:00
7111bc5e64 Improved updated messages 2013-05-25 22:56:09 +02:00
7a5df07ee5 Fixed #220 Players now drop items on death [gh#220] 2013-05-25 22:36:13 +02:00
7ade4762b9 Fixed #288 [gh#288] 2013-05-25 21:19:24 +02:00
a153f2ebdc Minifix 2013-05-25 19:29:24 +02:00
a538543e4c Fixed #287 Items dropped will be deleted if picked up in creative mode [gh#287] 2013-05-25 19:27:29 +02:00
5e1dddaba0 Added correct clay blocks 2013-05-25 19:20:37 +02:00
f224c26084 Furnaces and Burning items 2013-05-25 19:06:31 +02:00
221da1685e Fixed #281 client crashes due to packet recovery 2013-05-25 14:07:08 +02:00
e34b407538 Fixed #283 server crash when placing brown mushrooms [gh#283] 2013-05-24 23:56:35 +02:00
b8834890b6 Temporal fix for player crashing 2013-05-22 16:31:59 +02:00
03062c4e54 Fixed #204 Packet recovery algorithm can recover unsent chunks [gh#204] 2013-05-22 12:17:31 +02:00
929aebc1bf added ticks to error logs 2013-05-21 23:02:56 +02:00
363501d988 Fixed #275 2013-05-21 23:01:56 +02:00
9857f40175 Removed notice message 2013-05-21 20:44:02 +02:00
29b96fa855 Merge pull request #273 from greyson/master
Nearer-original tree generation
2013-05-21 11:29:51 -07:00
49716cfb18 Fixed packet-related stuff 2013-05-21 20:29:10 +02:00
acc373525f Removed MT Random generator namespace 2013-05-21 20:14:03 +02:00
c29d3a3e56 Better (more original) looking trees 2013-05-21 14:03:42 -04:00
b7083032f3 Updated settings, less memory usage 2013-05-21 19:50:59 +02:00
c9cecaf218 Fixes 2013-05-21 19:29:57 +02:00
9dbdab8060 Added } 2013-05-21 19:19:50 +02:00
8c5d0f070d Changed flying checks 2013-05-21 19:17:13 +02:00
73c5e7d7bc Added more food sources 2013-05-21 18:52:56 +02:00
4766424cb3 Fixed moving to fast message during Player blocking 2013-05-21 18:40:00 +02:00
8e8002c479 Fixed crash 2013-05-21 15:52:37 +02:00
409f0670bd Added sendUsage() port 2013-05-21 11:06:38 +02:00
ee12b41c39 Allow-flight disables speed checks 2013-05-21 08:24:17 +02:00
cd30f51979 Added startup errors display 2013-05-20 23:39:15 +02:00
6dc1e99f5a Merge pull request #269 from greyson/master
added libedit/readline support
2013-05-20 13:32:54 -07:00
cca453cc06 Feature complete: 'libedit' 2013-05-20 16:26:06 -04:00
ff8de264c0 Added "readline" support using libedit. 2013-05-20 16:17:11 -04:00
c6121e88bf Optionally disabled libedit based on results of compile 2013-05-20 16:17:11 -04:00
27050b9ec4 Internal ticker autocalculation 2013-05-20 17:21:04 +02:00
43071dd0ac RCON bad reading fixed 2013-05-20 17:20:35 +02:00
281d3b037f Fixed #255 Player and item bounding boxes 2013-05-20 16:53:57 +02:00
13b00988f0 Added GLOWSTONE constant 2013-05-20 16:44:28 +02:00
228075851c Correct Ice drop 2013-05-20 16:38:41 +02:00
47b54cfd28 Fixed #270 Blocks that need to be broken with a pickaxe now give correct drops & items 2013-05-20 16:33:09 +02:00
8336b4c91b Added libedit download/compile 2013-05-20 03:53:58 -04:00
713f16771f Added some socket options to cURL 2013-05-20 09:43:32 +02:00
aa14539274 Added execute bit to scripts 2013-05-20 08:26:04 +02:00
98c790d731 Fixed #265 2013-05-20 00:28:58 +02:00
00a41e7e11 Correct Slab checking error 2013-05-20 00:24:13 +02:00
ae13512627 Added index 2013-05-19 23:03:59 +02:00
95f2f347ff Updated Level::setMiniChunk() and Level::setRawBlock 2013-05-19 23:03:09 +02:00
48b5afac46 Packet broadcast to players 2013-05-19 22:49:40 +02:00
b9e3acd017 Do not grow trees on incorrect blocks 2013-05-19 21:00:38 +02:00
2fc542d93d Added trees to the flat preset 2013-05-19 20:54:43 +02:00
a7a45dfe96 Updated flat preset, do not allow empty Level names 2013-05-19 20:53:12 +02:00
bb9067acd7 Fixed #262 2013-05-19 19:32:40 +02:00
68855bdd4f Buffered block changes and sending big changes with Chunk Packets 2013-05-19 19:27:55 +02:00
10ed95a469 Don't fire change events if block has not changed 2013-05-19 17:53:40 +02:00
04f0500822 MTU used correctly 2013-05-19 17:11:21 +02:00
e3de52ba8b Fixed bigRaw packets reliability 2013-05-19 16:47:57 +02:00
2c4a428698 Packets bigger than the MTU are automagically split in different packets 2013-05-19 13:51:02 +02:00
b481c26839 Fixed teleporting to worlds with spaces 2013-05-19 13:32:27 +02:00
e163223134 Implemented safe_var_dump() 2013-05-19 03:39:33 +02:00
295363a381 New Player::directBigRawPacket() method 2013-05-19 02:50:04 +02:00
db97c0c5f7 Updated hook 2013-05-18 21:04:58 +02:00
d28780fa05 Updated Travis repo 2013-05-18 21:03:00 +02:00
a7709f827f Updated repository URL 2013-05-18 21:00:16 +02:00
22cc3d4d83 Clear Plugin file error during a crash 2013-05-18 19:47:50 +02:00
f485124190 Fixed #257 2013-05-18 19:12:50 +02:00
b48f486620 Fixed no params aliases 2013-05-18 19:04:31 +02:00
e3bf38e0b2 Plugin API: Allow Plugins without Main class 2013-05-18 18:24:48 +02:00
7297f8d2c0 Level Generation API updated 2013-05-18 15:22:07 +02:00
c408ee07b1 Player spawning on unknown worlds will be redirected properly to the main world 2013-05-18 15:21:54 +02:00
6adc41f301 Fixed #256 Signs not attaching to walls 2013-05-18 13:26:31 +02:00
af85c7ce45 Added Perlin noise generator 2013-05-18 13:16:35 +02:00
22d9cefe96 Fixed build 2013-05-18 11:24:31 +02:00
5faeff9e16 Fixed PMF metadata set 2013-05-18 11:19:08 +02:00
e81d68c8d0 Added trees to teh SuperflatGenerator 2013-05-18 11:02:00 +02:00
3c4d4f5cff Updated pthreads version 2013-05-18 02:53:35 +02:00
5ea6052a8a New Level Generator API & Support for MC Superflat Presets 2013-05-18 02:05:56 +02:00
edb93d6312 Fixed #254 2013-05-17 18:45:02 +02:00
3bb7114e7c Fixed PMFLevel::getBlock() not converting to int 2013-05-17 15:08:56 +02:00
d71a088460 Added MC_REMOVE_PLAYER 2013-05-17 14:33:14 +02:00
6db36c238f Allow OPping disconnected players 2013-05-17 14:02:01 +02:00
09fabfc87e Fixed getting spawn seed 2013-05-17 13:56:18 +02:00
2377cf7199 Index fix 2013-05-17 13:19:44 +02:00
b82e9b2895 Fixed already loaded worlds 2013-05-17 13:14:52 +02:00
651398e500 Fixed #249 2013-05-17 12:33:42 +02:00
2b89b51621 Fixed #251 implode() error 2013-05-17 12:30:39 +02:00
f3fe0a6d27 Merge pull request #250 from zhuowei/master
Fixed a few missing methods due to the Multiworld conversion fixed #248
2013-05-16 22:20:38 -07:00
4678b57c75 Fixed a few missing methods due to multiworld conversion 2013-05-16 19:03:18 -07:00
7bbda6dd67 Detect non loaded chunks 2013-05-16 20:24:05 +02:00
4564765470 Added "player.teleport" 2013-05-16 19:39:15 +02:00
2305322ed0 tp help 2013-05-16 19:13:36 +02:00
848a69b28a /tp [player] w:[world] & simple /spawn 2013-05-16 19:13:03 +02:00
6a0cc4e122 Fixed teleport pitch 2013-05-16 18:13:08 +02:00
beb84ca013 Teleport fixes 2013-05-16 18:11:26 +02:00
9dd1568c40 New Player::getSpawn() 2013-05-16 18:05:05 +02:00
66322d7719 Selector aliases & @world & /spawnpoint 2013-05-16 18:02:24 +02:00
ad4959f8c0 Fixed selectors 2013-05-16 17:44:43 +02:00
fceb076b9b Better speed measure 2013-05-16 17:31:26 +02:00
1dbbf08f1b Use other things instead of array_shift 2013-05-16 17:30:34 +02:00
5277555d33 Relative teleporting 2013-05-16 17:21:39 +02:00
7d49847ae7 Correct teleport message 2013-05-16 17:14:02 +02:00
3cc4546f93 Fixed Level::nextSave 2013-05-16 17:07:28 +02:00
9a3f887f44 Attacking entities fixed 2013-05-16 16:41:54 +02:00
1f8987183b Removed libevent 2013-05-16 16:12:15 +02:00
072e1328f1 Updated pthreads version 2013-05-15 23:37:54 +02:00
d071497747 Fixed redstone scheduled update 2013-05-15 23:30:47 +02:00
e0e724bcc3 Saving entities/tiles 2013-05-15 23:30:46 +02:00
fb69cf3392 Chunk unloading fixed 2013-05-15 23:30:45 +02:00
f1e4bb0f62 Scheduled saving 2013-05-15 23:30:44 +02:00
244fde8143 Chunk unloading 2013-05-15 23:30:43 +02:00
3f532d419c Saplings 2013-05-15 23:30:43 +02:00
6f59e2eaad Time API working with changes 2013-05-15 23:30:42 +02:00
5ee2cda4a6 Level-independient time change 2013-05-15 23:30:41 +02:00
e63677a23d Level saving 2013-05-15 23:30:40 +02:00
78baa237e3 Remove teleporting players from the other world 2013-05-15 23:30:39 +02:00
3fca7ab6a5 Don't fire events in different worlds 2013-05-15 23:30:38 +02:00
9e55de134f Added /seed 2013-05-15 23:30:37 +02:00
bcbc65ed5e Added /spawn [world] [player] 2013-05-15 23:30:36 +02:00
838e08b33b Fixed metadata packing 2013-05-15 23:30:36 +02:00
991436993f Fixed things 2013-05-15 23:30:35 +02:00
cef4347a02 Fixed error with world teleporting 2013-05-15 23:30:34 +02:00
de5be4168d Fixed RCON non-blocking sockets 2013-05-15 23:30:33 +02:00
33bd66c1da Added world teleporting 2013-05-15 23:30:33 +02:00
7de0835ad9 Chat Selectors [@player] 2013-05-15 23:30:32 +02:00
d0d5c1bb79 CMD Selectors [@all, @player, @random] 2013-05-15 23:30:31 +02:00
c6c82f7e55 Player scheduled actions get cleaned 2013-05-15 23:30:30 +02:00
5dade755eb Fixed Player memory leak 2013-05-15 23:30:29 +02:00
24c0e2742a Fixes 2013-05-15 23:30:29 +02:00
c27cca6741 More fixes :D 2013-05-15 23:30:28 +02:00
7236f4aad6 Few fixes 2013-05-15 23:30:25 +02:00
2254e87ce4 PMF & Multiworld [part 3] 2013-05-15 23:30:24 +02:00
5938747083 PMF & Multiworld [part 2] 2013-05-15 23:30:22 +02:00
9b212ae034 New stats 2013-05-15 23:30:21 +02:00
db8f50f408 PMF & Multiworld [part 1] 2013-05-15 23:30:20 +02:00
bbbc54f606 New API version 2013-05-15 23:30:19 +02:00
703803eb6b New pthreads version 2013-05-12 12:32:02 +02:00
60b559d64b Added webhook 2013-05-12 13:19:57 +03:00
6610f82ceb Updated PHP version 2013-05-12 11:48:23 +02:00
73867f1f80 Updated ZLIB version 2013-05-10 21:49:45 +09:30
cfb2d939a4 Added little bits of comments to the BanAPI for better understanding by newbies. 2013-05-10 18:38:32 +09:30
5b6724a452 Mac machines are detected 2013-04-29 00:46:36 +03:00
4ec2bed44d More fix 2013-04-27 01:02:30 +02:00
2a4d2a92ab Fix :DD (remove temp. feature) 2013-04-27 00:49:59 +02:00
47e9a7b6a1 Fix :D 2013-04-27 00:43:42 +02:00
d7a54123e2 New Event ConsoleLoop 2013-04-27 00:39:59 +02:00
3cae25cebd Fix ^^ 2013-04-27 00:27:37 +02:00
e0727d2e57 Fix 2013-04-27 00:21:22 +02:00
77ecdb8727 Event test in ConsoleAPI 2013-04-27 00:15:01 +02:00
21150cd239 Added Event and libevent to README.md 2013-04-26 23:55:03 +02:00
cea84879e7 OCD 2013-04-26 23:35:07 +02:00
e43c45768d Added Event support 2013-04-26 23:25:26 +02:00
d48a1a6ce3 Fixed typo 2013-04-26 23:15:06 +02:00
83cce9cdf3 *changes* 2013-04-26 23:01:13 +02:00
d56328b16a Added PHP event and libevent2 for testing 2013-04-26 21:22:56 +02:00
8aa047b3f0 Removed obsolete methods from the Utils class 2013-04-26 19:56:08 +02:00
c4ff8921f1 StackableArrays class 2013-04-25 20:29:45 +02:00
6a4010a9af Fixed plugins not generating their config file 2013-04-25 18:52:14 +02:00
8149c9e7ca Better plugin list in the Error dump 2013-04-25 18:31:03 +02:00
a3a2155026 Removed startup binary I/O test 2013-04-25 18:30:44 +02:00
173784752e Added GIT_COMMIT to the Error dump 2013-04-25 17:54:32 +02:00
33a614c615 Removed libevent dependency 2013-04-25 17:29:32 +02:00
515fcf0890 Updated build script path 2013-04-24 22:27:45 +02:00
72208d9159 Added shmop to build script 2013-04-24 20:32:25 +02:00
31ffe8017f Updated build script for libevent 2013-04-24 19:37:02 +02:00
9624b9c35e Added libevent dependency 2013-04-24 00:41:37 +02:00
9b07994913 Chat & Console fixes 2013-04-23 19:21:08 +02:00
fea6e9c432 Fixed Container::check() blacklist 2013-04-23 18:21:37 +02:00
13aa73d26e Added correct Painting placing checks & bigger Paintings 2013-04-23 15:32:09 +02:00
dffbfa0754 PlayerAPI teleport commands now return a correct name 2013-04-23 12:42:43 +02:00
2e4724c596 Added Query protocol description 2013-04-23 12:18:08 +02:00
3378c44542 Added output redirection to kill() 2013-04-23 11:59:34 +02:00
093bf3ddee Query now checks for the last token when changed (30-sec change) 2013-04-23 11:44:58 +02:00
85e3c08aa9 Added the "rcon.port", "rcon.threads", "rcon.clients-per-thread" ghost properties 2013-04-23 11:39:39 +02:00
8345fd02c4 Set default gamemode to SURVIVAL 2013-04-23 10:49:25 +02:00
1c03fb0de9 Removed the rcon.port property, being the same as the server 2013-04-23 10:33:15 +02:00
2ae0cf65c5 Added protocol info to README.md 2013-04-23 02:00:22 +02:00
cb42e5832b Added documentation for RCON and Query 2013-04-23 01:21:34 +02:00
ee73ccc0e2 Remoced "hostip" from Query 2013-04-23 01:17:39 +02:00
cc2addfe92 Implemented Query protocol 2013-04-23 00:58:26 +02:00
be7e5cd67a Unknown packets are always discarded even if they have been processed 2013-04-22 23:46:34 +02:00
e428b4cfc4 Limited RCON threads to one and added a auth timeout 2013-04-22 23:33:46 +02:00
f466e1f791 Added Player::getSlot() for consistency 2013-04-22 21:01:53 +02:00
bb9a6146fd Raised the speed limit 2013-04-22 19:20:25 +02:00
34ca8baa29 Fixed "player.interact" event only being fired with weird conditions 2013-04-22 18:46:35 +02:00
d552042094 Fixed #166 2013-04-22 17:25:45 +02:00
6457055be3 Added TimeAPI command responses 2013-04-22 16:51:04 +02:00
02bbfb60b6 Increased RCON max clients per thread to 25 (total 100 clients) 2013-04-22 16:46:48 +02:00
b759863bb1 Changed /list to be the same as vanilla 2013-04-22 16:39:33 +02:00
e81793174b Multiple RCON clients per thread, allow external connections 2013-04-22 16:28:24 +02:00
d08807abaf Added 4 RCON threads 2013-04-22 14:29:30 +02:00
1cb3e25bf9 Added RCON protocol 2013-04-22 14:22:52 +02:00
70056b8d1f Save config filles automatically after adding new defaults 2013-04-22 00:05:56 +02:00
2f1e37ce6c Updated Spyc library 2013-04-21 22:29:44 +02:00
80488784f9 Updated cURL release 2013-04-21 22:23:52 +02:00
55b8401967 Updated pthreads version 2013-04-21 22:22:43 +02:00
269e63ab50 Rewrite /defaultgamemode command to allow multiple values 2013-04-20 21:00:52 +02:00
d0d8d281d2 Revert "Added coordinates command. Displays your coordinates"
This reverts commit 4434fe2a5b.
2013-04-20 20:56:58 +02:00
4434fe2a5b Added coordinates command. Displays your coordinates 2013-04-20 14:45:35 +09:30
82c72f8beb Added defaultgamemode command 2013-04-20 12:26:26 +09:30
083110ffd0 Fixed #194 Implemented armor damage reduction 2013-04-19 14:31:41 +02:00
0bea234788 Fixed #206 2013-04-19 13:53:58 +02:00
e444f2a9e0 Fixed #208 2013-04-19 13:40:02 +02:00
38950969dd Added Player::setSpawn(Vector3 $pos) method 2013-04-18 22:34:12 +02:00
9a4c3f8c9f Revert "Updated PHP version on .travis.yml"
This reverts commit e4e649ec49.
2013-04-18 20:37:07 +02:00
c3a0600ffd Added __get() magic methods to Player and set some properties private 2013-04-18 20:22:20 +02:00
78167a3cd4 Fixed players not getting their inventory reset on gamemode change 2013-04-18 19:33:51 +02:00
724e9d9bb2 Fixed changing gamemodes 2013-04-18 17:25:07 +02:00
8b41246f2d Added "player.gamemode.change" 2013-04-18 17:18:42 +02:00
e4e649ec49 Updated PHP version on .travis.yml 2013-04-18 17:10:14 +02:00
639ca67a10 Blocked again opening of chests in Creative mode 2013-04-18 17:05:26 +02:00
96baeaaad2 Fixed VIEW gamemode crash 2013-04-18 16:54:48 +02:00
bcb76b51f4 Fixed setting more gamemodes 2013-04-18 16:43:00 +02:00
3577667039 New VIEW gamemode 2013-04-18 16:40:30 +02:00
5848d283da Correct MC_LOGIN_STATUS usage 2013-04-18 16:16:54 +02:00
8f724ffc46 Resend slot on change 2013-04-17 23:29:44 +02:00
26c2f61da0 Added fix so players aren't targeted by name completion by default 2013-04-17 23:02:53 +02:00
fd8166c836 Obligatory Creative mode item enforcement 2013-04-17 22:57:44 +02:00
bc80c01348 Return output of commands on ConsoleAPI::run() method 2013-04-17 20:24:10 +02:00
e0a59486eb Force inventory sending on death 2013-04-17 20:15:51 +02:00
393f54fe28 /give compatible with "item-enforcement" = off 2013-04-17 19:48:13 +02:00
1885cdf3a2 Changed item enforcement option name 2013-04-17 19:41:46 +02:00
e65731e3ec Item enforcement optional for packet sending 2013-04-17 19:38:29 +02:00
f7f05d4175 Paintings are removed at usage 2013-04-17 19:32:06 +02:00
cd8211a9d3 Fixed client-side item duplication 2013-04-17 19:31:15 +02:00
09301f0e5f Added a way to send Player's inventory directly 2013-04-17 19:25:53 +02:00
5e4ef9732b Oops! 2013-04-17 17:23:12 +02:00
44cb66837e Fixed torch sides 2013-04-17 17:22:57 +02:00
f195168132 Fixed Player not getting in survival mode removed due to BlockAPI checking Server default gamemode 2013-04-17 17:13:36 +02:00
32e0085c1e Allow placing torches on top of side blocks 2013-04-17 17:10:05 +02:00
b34e55eec5 Torches drop when no supporting block is present 2013-04-17 17:09:48 +02:00
758070e478 Optimized block updates 2013-04-17 16:41:36 +02:00
2790f60491 Added Redstone Ore block update 2013-04-17 16:36:37 +02:00
d8bf5ce711 Added Cakes 2013-04-16 20:00:41 +02:00
bbbdaa30d1 Better online player list 2013-04-16 19:48:33 +02:00
2438c9535b Only shown available commands in help 2013-04-16 19:46:14 +02:00
3d48eec887 Allow looking the help of an alias 2013-04-16 19:41:37 +02:00
f1cb29cc8b Increased Socket buffer size 2013-04-16 19:11:03 +02:00
710ed5c704 Improved block updates and Scheduled block updates [part1] 2013-04-16 17:15:39 +02:00
3c40c8734f Changed PHP directory [migration included] 2013-04-15 16:02:43 +02:00
80aaf9923c Fixed packets being discarded due to a bad ordering 2013-04-14 23:19:55 +02:00
cad9908f94 Added new network reliability identifiers 2013-04-14 18:47:50 +02:00
9ad73b00c8 Removed online broadcast 2013-04-14 18:47:34 +02:00
fb805f2b0f Re-fixed #200 2013-04-14 17:08:05 +02:00
e0791b9bae Log out message 2013-04-14 17:00:13 +02:00
10d34a7ce6 Fixed 0x60 packets being received 2013-04-14 16:58:54 +02:00
69b78a9dd6 Send Usage data again 2013-04-14 16:30:26 +02:00
8442c0529e Added player.connect (pre-join) 2013-04-14 16:19:27 +02:00
77da9d3a7c Chat messages are shown on the server log 2013-04-14 16:19:16 +02:00
5e9e2b2a7d Commands are executed as console by default 2013-04-14 16:10:41 +02:00
88a4116398 Fixed #200 Running in a folder with spaces 2013-04-14 13:10:04 +02:00
633f7233b4 New network reliability layer 2013-04-14 13:04:57 +02:00
a92518ef9e Fixed console messages without [TAG] 2013-04-14 13:01:50 +02:00
0c051fb02e Removed MP chat tag 2013-04-13 20:03:07 +02:00
e71b6946f3 Fixed /help paging 2013-04-13 20:01:27 +02:00
d157299c7a Updated console texts and help 2013-04-13 19:47:20 +02:00
82d49b0343 PluginAPI API error to warning 2013-04-13 18:55:29 +02:00
790b9c19b6 Fixed hack check crash 2013-04-13 16:22:05 +02:00
439d0ead4f Default equipment fix 2013-04-13 14:37:01 +02:00
3ae18c85b1 Round coords at spawn 2013-04-13 14:34:04 +02:00
74c4fab58d Space 2013-04-13 14:32:58 +02:00
199fbb644b Fixed spawning despawned entities 2013-04-13 14:21:58 +02:00
4867533ab7 Removed TNT explosion on break 2013-04-13 13:47:37 +02:00
452df5b2f8 Added Buckets 2013-04-13 13:42:55 +02:00
c334bbce12 Item change protection 2013-04-13 13:37:14 +02:00
8d7fafe167 Removed /crash 2013-04-13 13:23:05 +02:00
996bf6b366 Updated PHP & pthreads version 2013-04-13 13:02:41 +02:00
1cf61fc829 Fixed #196 syntax error 2013-04-13 11:55:45 +02:00
75a2bf122f Added "disallow-crafting" to enable item protection 2013-04-12 23:11:07 +02:00
159d1c5024 Added missing parameters 2013-04-12 23:09:28 +02:00
e2b68a01d1 UDP Sokcet port blocking exit 2013-04-12 20:35:39 +02:00
bab3b8274a Explosions 2013-04-12 20:35:16 +02:00
a6615560bc fix. 2013-04-12 14:21:09 +02:00
62735c8e41 Changed messages 2013-04-12 14:20:52 +02:00
5c2a2ecd6d Added a security radius for flying 2013-04-12 14:09:36 +02:00
432eb36b83 Fixed support check height difference 2013-04-12 14:06:12 +02:00
7388a32869 Fixed flying check support range 2013-04-12 14:04:57 +02:00
83a63ef805 Added login packet protection 2013-04-12 13:59:21 +02:00
c45cd5e12a Fixed a crash 2013-04-12 13:58:25 +02:00
c138cb2797 Fixed player death name 2013-04-12 13:55:26 +02:00
feaecbcd60 First usage report 5 minutes after the server restart. 2013-04-11 23:16:29 +02:00
3e4efbb26a Fixed players not being able to move after being damaged 2013-04-11 22:40:18 +02:00
b9498275a4 Fixed /invisible not working 2013-04-11 22:35:47 +02:00
f7af97c651 Direct fix for speed hack 2013-04-09 21:07:35 +02:00
076691ec52 Added fixes for hacks like Health protection and speed hack 2013-04-09 21:02:46 +02:00
2763401be3 /give now checks correctly 2013-04-09 20:44:57 +02:00
a3b7f12803 /banip add <player> works banning the Player's IP 2013-04-09 19:52:10 +02:00
eac72bb8ae Added "player.flying" event, ops can always fly 2013-04-09 19:11:45 +02:00
7b8a27f7b0 Removed time-per-second property 2013-04-09 19:04:01 +02:00
6ba7486097 Gamemode check for flying 2013-04-09 18:58:32 +02:00
4dd66b450c Flying damage & kicks less random 2013-04-09 18:57:41 +02:00
2b741a2913 Fixed crashes, added flying check 2013-04-09 18:44:13 +02:00
2043534003 Removed constant property file write 2013-04-09 17:39:36 +02:00
7e37a60a67 Changed property names for consistency (migration included) 2013-04-09 17:35:37 +02:00
f093286fb2 Disallow joining invisible servers 2013-04-09 17:26:30 +02:00
7c9eec7869 Added a parameter to remove directly the async thread 2013-04-09 17:23:29 +02:00
79ca735fb0 Fixed a weird, random, pthreads-caused crash 2013-04-09 17:21:49 +02:00
533b175b66 Syntax error 2013-04-09 17:09:21 +02:00
2c81518c5d OP players are automatically whitelisted 2013-04-09 17:08:44 +02:00
dccfbfd572 Added "view-distance" setting to change chunk sending radius 2013-04-09 17:07:17 +02:00
e88c337229 Added the "spawn-protection" property to define the protection radius 2013-04-09 17:02:03 +02:00
5f55cdf26a Added pvp server property 2013-04-09 16:58:52 +02:00
3e3521086b Fixed crash due to new API changes 2013-04-08 23:07:01 +02:00
01e31fc82e Updated test to reflect changes 2013-04-08 22:59:34 +02:00
b66e784a12 Removed GMP dependency, using bundled BCMath 2013-04-08 20:23:44 +02:00
20694f2c77 Changes to Threads 2013-04-07 14:35:39 +02:00
539c8046d8 Removed deprecated chat() method in server 2013-04-07 13:47:11 +02:00
1d32e82265 Usage sending in background 2013-04-07 12:28:34 +02:00
12f9c12fe4 Changed default file permissions 2013-04-07 12:15:34 +02:00
0060c3f10d Duplicated chunk loading speed 2013-04-05 16:33:47 +02:00
6456d2383b Added a spawn protection 2013-04-05 15:51:19 +02:00
793aaf87c0 /op and /deop needs the player connected 2013-04-05 15:37:18 +02:00
f7de979de1 Added commands to whitelist 2013-04-05 15:14:32 +02:00
82a789687c Added /me 2013-04-05 15:13:17 +02:00
026353399b Added /tell 2013-04-05 15:09:25 +02:00
febfbb19c4 Updated /gamemode command to follow Minecraft structure 2013-04-05 14:09:02 +02:00
45bbc86830 Username completion & better gamemode change 2013-04-05 14:04:51 +02:00
3d8c9db430 Fixed #183 Players taking damage landing on water (temp. fix) 2013-04-05 12:43:18 +02:00
8405c74b42 Fixed #186 players not teleporting due to speed check 2013-04-05 12:41:05 +02:00
93cfa035d4 Fixed #187 Opening Chests with solid blocks on top 2013-04-05 12:37:08 +02:00
463e82a1e7 Changed final public methods 2013-04-04 12:04:03 +02:00
cd946a7273 Added fix to Utils::getOS() method 2013-04-03 19:21:12 +02:00
074c1b5295 Added a fix so higher PMF version files doesn't get loaded 2013-04-03 13:20:18 +02:00
ad6b48a599 Updated README.md 2013-04-03 12:43:54 +02:00
e77db15c21 Error suppression 2013-04-03 12:30:51 +02:00
683fd03f45 Set process title PHP 5.5 function fallback 2013-04-03 12:28:57 +02:00
dbc357c266 Removed killing php to end the process 2013-04-03 12:21:12 +02:00
e0747a9c44 PHP 5.5 2013-04-03 11:38:50 +02:00
cdc164729c Added server.unknownpacket to receive unknown packets 2013-04-02 20:45:30 +02:00
4e8e132fcf Added damage for Axe, Pickaxe, and Shovel 2013-04-02 16:37:08 +02:00
77fa1608c1 Fixed #179 2013-04-02 16:33:15 +02:00
e3a858a089 Merge pull request #179 from williamtdr/master
Updated Player.php for sword damage amounts
2013-04-02 07:27:55 -07:00
eeb9b925a5 Removed unnecessary left bracket causing syntax error
Sorry 'bout that.
2013-04-01 18:01:15 -05:00
082c4429cd Updated PECL pthreads release 2013-04-02 00:14:19 +02:00
314da7b30e Update Player.php
Swords now do proper damage amount
2013-04-01 12:03:38 -05:00
1129df6194 View connection lag in-game 2013-04-01 16:25:25 +02:00
1ef0a41944 Added Ping / Pong system 2013-04-01 16:03:43 +02:00
1cb30601b5 20 mini chunks / second 2013-04-01 14:54:08 +02:00
534898167e Improve loading on Y chunks 2013-04-01 14:49:13 +02:00
f53877c070 Fixed a few things
REALLY BUGGY!!! DO NOT USE THIS!
2013-03-31 15:03:13 +02:00
ecc2faffea Fixed #128 player death 2013-03-31 14:44:39 +02:00
66169d63c4 Force chunk resend on teleport 2013-03-31 13:50:13 +02:00
b83ef4e70b Automatically remove ANSI codes from chat 2013-03-31 13:36:19 +02:00
e2d4b49266 Remove single beds 2013-03-31 13:27:31 +02:00
1b92b1177c Fixed #176 bed breaking not removing origin block 2013-03-31 13:25:58 +02:00
251b88f8ba Limited Player tick time queue further 2013-03-31 13:20:05 +02:00
f8c6921ac4 Few protocol edits 2013-03-31 00:12:19 +01:00
2b03e71c97 Do not measure Y dimension for moving speed 2013-03-30 21:38:29 +01:00
263824fa01 Fixed division by zero 2013-03-30 21:35:59 +01:00
abf52079fc Chunk loading based on X,Y,Z (+1 dimension) 2013-03-30 21:35:50 +01:00
7312c57123 Improved internal Client IDs 2013-03-30 21:09:12 +01:00
f7a12b09f7 Better Player queue completion limited by time 2013-03-30 20:56:01 +01:00
949ab34b42 Added player.block.(break/place).invalid handling events 2013-03-30 20:26:15 +01:00
121fd51dc6 Fixed placing blocks on activable blocks 2013-03-30 19:51:21 +01:00
44fcf4a6ed Noob-proof memory-limit server property 2013-03-30 19:36:49 +01:00
a6cc0f8261 Same for Peak Memory usage 2013-03-30 19:34:08 +01:00
bd196c0fcb Typo 2013-03-30 19:33:18 +01:00
caa32edf6f Get REAL memory usage, not allocated 2013-03-30 19:33:05 +01:00
87ebe7fac4 Generic importing to PMF Level format 2013-03-30 14:08:22 +01:00
8c9f07f737 PMF Level format fixes 2013-03-30 14:08:11 +01:00
cbe160e655 Fixed #169 and fixed #168 2013-03-30 13:11:06 +01:00
efa8692bfa Added wget dependency 2013-03-30 02:25:12 +01:00
3f2cb86859 Normalized Item Names 2013-03-29 20:11:53 +01:00
6d39f54591 Removed $server constructor arguments because of ServerAPI::request() 2013-03-29 19:49:33 +01:00
af52b0a5b5 Fixed ACK/NACK range writing 2013-03-29 11:18:47 +01:00
257b330a53 Fixed ACK/NACK range reading 2013-03-29 11:07:45 +01:00
8a9e6426ca Optional teleport yaw & pitch 2013-03-29 10:56:28 +01:00
3f820d18d2 Removed teleport jerking 2013-03-29 10:54:58 +01:00
677e1f8ce0 Added Player automatic blocking during spawn or gamemode change 2013-03-28 17:59:45 +01:00
822adcae2d Packet Cleaning 2013-03-28 16:56:50 +01:00
4ea4431986 Less Server->Client NACK usage 2013-03-28 14:37:35 +01:00
e392a35598 Fixed client-side ACK & NACK 2013-03-28 14:08:45 +01:00
912e35f202 Fixed server-side NACK & ACK 2013-03-28 13:59:56 +01:00
f1a28f23ae New ACK/NACK structure & Packet multiple ressend issue 2013-03-28 13:56:11 +01:00
c68b4ebda6 Few packet loss system fixes 2013-03-28 13:10:51 +01:00
98976ac56c Fixed NACK handling - Works even with 90% packet loss 2013-03-28 13:00:18 +01:00
42d5296533 Fixed invalid ACK/NACK handling 2013-03-28 11:20:40 +01:00
6260d66bde Updated pthreads version in compiler 2013-03-28 10:59:33 +01:00
2861fe0703 New Plugin format includes multiple API versions 2013-03-27 18:02:10 +01:00
012ecbe40a Fixed #165 2013-03-27 15:53:48 +01:00
c5326131a2 Fixed a server crash related to #162 2013-03-25 20:26:20 +01:00
174160c65c Fixed incorrect gamemode change close message 2013-03-25 19:57:57 +01:00
a5998ff9a2 Start of API 6
Don't try making plugins with this until the stable release
2013-03-25 18:55:25 +01:00
ec5f255a71 Fixed bad PMFLevel::getXZ() logic 2013-03-25 18:54:25 +01:00
e7fcbe206f Create PMF Levels 2013-03-25 18:46:08 +01:00
89b38c25ce Raised ticks directive to 40 2013-03-25 16:46:01 +01:00
88a1f83545 Added protection for fast movements 2013-03-24 11:02:37 +01:00
14ab386b0f Fixed typo 2013-03-23 23:00:23 +01:00
7dbf421e99 Fixed things in PMF Level 2013-03-23 22:46:54 +01:00
0d3624e6a7 :DDDD 2013-03-23 18:27:21 +01:00
14ff3e0a9b Internal API's are now shown as Debug level 2013-03-23 18:26:18 +01:00
ae731c9093 Added the caseusername preference on offline player data 2013-03-23 18:21:40 +01:00
d613fa2138 Fixed Chest Slots not getting sent and shown 2013-03-23 17:44:32 +01:00
5e52bbdd16 Fixed Syntax Error 2013-03-23 17:33:06 +01:00
0b6ff03d5a Revert "API version changed to 6"
This reverts commit 1ff8945015.
2013-03-23 17:32:51 +01:00
1ff8945015 API version changed to 6 2013-03-23 17:18:02 +01:00
a603732bb4 PMF Level reader 2013-03-23 16:59:44 +01:00
23a7847350 Added Plugin List on sendUsage() 2013-03-23 13:14:14 +01:00
f07cd21dd1 Updated PMF 2013-03-23 13:04:02 +01:00
8bbd899689 Fixed #156 2013-03-22 14:44:22 +01:00
2a8c72dfc2 Updated the compile script 2013-03-22 13:51:53 +01:00
59763a35c7 Reverting 75a42ce26c 2013-03-21 17:03:22 +01:00
2e0d49a2ba Moved the RAKNET_MAGIC constant 2013-03-21 17:03:13 +01:00
6e4141f140 Changed the Utils::isOnline() method 2013-03-21 16:27:02 +01:00
75a42ce26c Added reload feature UNTESTED 2013-03-21 22:41:25 +10:30
38d361bb07 Added Wooden Tools Item Settings 2013-03-21 16:50:09 +10:30
13ae305bdd Change to dev version 2013-03-20 19:06:10 +01:00
ec55ebc14e Sign Post orientation 2013-03-20 19:03:09 +01:00
698515f31b Fixed #152 #149 2013-03-20 18:39:24 +01:00
58c258d422 Cancellation of entity.move and player.move (impeding player movement) 2013-03-20 18:35:32 +01:00
eb90c777f3 Better Teleportation 2013-03-20 18:32:47 +01:00
7a0ff2a1c0 Updated some level things 2013-03-20 18:23:08 +01:00
57df6e61aa Raised buffer time 2013-03-20 18:14:04 +01:00
5e44ecf63b Paginated help command 2013-03-20 18:12:06 +01:00
4a9374a58c Updated compile script 2013-03-20 17:51:23 +01:00
f936e29d34 TPS check 2013-03-20 16:42:20 +01:00
6dba82c695 Disable reloading the config from server 2013-03-20 16:38:38 +01:00
df77f725fd Syntax error fix 2013-03-20 15:45:03 +01:00
2c952a5a4f Removed equipment change notification 2013-03-20 15:20:21 +01:00
9ee7180681 Lower API version of a plugin is notified with a debug level of 2 2013-03-20 15:19:24 +01:00
65110d5358 Removed /harm 2013-03-20 15:17:58 +01:00
da849a7251 /say is now prefixed by [Server] 2013-03-20 15:17:22 +01:00
28d431e497 Removed reference in BlockAPI::drop() of Server gamemode 2013-03-20 15:16:37 +01:00
9bd4b02908 Cancel past movements 2013-03-20 14:56:18 +01:00
4ff9753ede Checking for GIT now stops the update on the latest version 2013-03-20 14:51:06 +01:00
518902caf4 fixed creative players taking damage 2013-03-19 23:44:23 +01:00
2c3ab413f5 Fixed Creative players spawning drops 2013-03-19 23:44:10 +01:00
3ba56c3e81 Independient Player gamemode, saved between sessions, set it via /gamemode 2013-03-19 19:54:13 +01:00
49d2723806 Fixed Entity updates getting duplicated and negated 2013-03-19 19:07:07 +01:00
70b86061f6 Drowing is only checked once per check 2013-03-19 19:05:46 +01:00
6a29dd5a8d Ghost players don't leave a quit message 2013-03-19 18:59:44 +01:00
58631ba1d0 Send the entire Buffer at disconnect 2013-03-19 18:58:10 +01:00
fe2b9a6ac5 Fixed memory Leak 2013-03-19 18:55:35 +01:00
4d2835a37a Swapped X and Z 2013-03-19 18:39:29 +01:00
e1c5d965a0 Disable placing a chest when a chest already exists on the side 2013-03-19 18:21:43 +01:00
a3268d2405 Update README.md 2013-03-19 18:07:32 +01:00
5eaa432ddb Updated API Domain 2013-03-19 17:06:01 +01:00
acc0311386 Lowercase enforcement (fixes #144) 2013-03-19 16:06:23 +01:00
8842d8d772 Fixed EID typo on TileEntity API 2013-03-18 17:08:34 +01:00
6fb8e754d6 Fixed #142 Server crash while using whitelist 2013-03-18 15:06:39 +01:00
6763e93a8d Obtain GIT information 2013-03-17 17:35:33 +01:00
40b43a911e Optimization 2013-03-17 17:26:15 +01:00
012c86ef00 Player Entity preload 2013-03-17 16:56:36 +01:00
5fedf27255 Player gamemode fix 2013-03-17 16:51:08 +01:00
3967c8eec1 Sandstone ^^ 2013-03-17 16:42:46 +01:00
23ca20855a New Generated worlds are higher (so no more complains about "moving walls") 2013-03-17 16:39:42 +01:00
01628b88b7 Added Furnace inventory 2013-03-17 11:47:52 +01:00
b5cd877b3e Updated Tile Slot handling 2013-03-17 11:47:43 +01:00
c536a35beb Player data now uses YAML 2013-03-16 23:26:46 +01:00
bb968451ba Players are able to omit arguments on /tp, /tppos, /kill 2013-03-16 20:36:08 +01:00
a5e52e7b9a Players now respawn on the server's spawn point 2013-03-16 20:19:06 +01:00
47af98a875 Fixed spawning on top of chunks & added Player::teleport() method 2013-03-16 19:36:30 +01:00
ed003cd207 Updated the API version 2013-03-16 19:36:08 +01:00
3bf9d5b911 Dev Alpha_1.3dev 2013-03-16 13:23:53 +01:00
db4bdcd2bd PocketMine-MP Alpha_1.2.1 2013-03-16 13:12:08 +01:00
ce8724c5ed PMF Plugin Loading 2013-03-16 12:52:14 +01:00
d46a61d0c4 Removed Server getting via Plugin Loading 2013-03-16 12:29:29 +01:00
1bfef261ab PMF Plugin Reading 2013-03-16 12:27:23 +01:00
6dfe348767 Added Command Permissions Whitelist 2013-03-16 09:54:42 +01:00
3f10e11ddf Array format fixes 2013-03-16 00:21:50 +01:00
5b79722fa9 Better NACK handling (#133, #16, fixes #75) 2013-03-16 00:16:47 +01:00
fc06e1bcaf Packet Sending Buffering 2013-03-16 00:09:00 +01:00
ffaaca6f2d PMF class 2013-03-15 21:54:19 +01:00
0660409987 Updated Spyc 2013-03-14 21:55:50 +01:00
bbc925b188 Updated Message level of World generation 2013-03-14 21:55:31 +01:00
6f7268902d Added the libtool dependency to the compile script 2013-03-14 19:42:23 +01:00
6851f9c7b1 Added a dynamic title function 2013-03-14 16:36:34 +01:00
9ec9d22bbc BlockAPI::setBlock now uses a Vector3 2013-03-10 13:34:11 +01:00
40842ec794 Fixed Vector3::add() 2013-03-10 13:33:52 +01:00
ab1c28fc57 Changed the api.op.check event check 2013-03-09 22:38:53 +01:00
a9f7d47c25 Added all the future tags 2013-03-09 13:58:22 +01:00
5241f0527b Fix typo for De-Op (I know a very little change) 2013-03-09 22:52:56 +10:30
5c7f397bde Changed default debug level 2013-03-09 12:52:57 +01:00
84ac13d591 Added checks 2013-03-09 12:40:53 +01:00
8bf4b5cafa Added callable type hinting 2013-03-09 10:08:42 +01:00
7acbf13a8a Updated README.md image 2013-03-09 09:33:39 +01:00
fa4813d335 Raised save interval to 25 minutes 2013-03-09 09:31:41 +01:00
3432a69a41 Cancel correctly Handling Events using return true 2013-03-09 09:27:29 +01:00
bc5516867c Fixed Quartz Blocks not getting placed correctly 2013-03-08 23:05:57 +01:00
5c17f77bcc Name update 2013-03-07 19:56:07 +01:00
5fab555c48 Real Minecraft username check 2013-03-07 18:46:04 +01:00
ba3dfd91db Removed unnecesary replace 2013-03-07 18:11:35 +01:00
8f21eb41ee Added message separation 2013-03-07 18:06:51 +01:00
d90e41c0d5 Fixed Server description not being displayed 2013-03-07 18:05:33 +01:00
aecfbbbdc1 Removed flying damage 2013-03-07 17:56:33 +01:00
1c63448c6c Drop in the correct position 2013-03-07 17:44:28 +01:00
8253d63d9b Case-insensitive playernames, removed Client ID kick 2013-03-07 17:43:44 +01:00
a7d8e22e7e Player inventory is changed using chests (Fixes #127) 2013-03-07 17:36:19 +01:00
ad11851c61 Remove items from Player inventory on drop 2013-03-07 17:15:12 +01:00
b259ed2532 Fixed #124 2013-03-06 20:29:49 +01:00
9510cbd716 New block touch event 2013-03-06 20:17:38 +01:00
8a345e6582 Target player gets notified of op 2013-03-06 19:28:24 +01:00
66fe5d2a3e Added Kicking on Ban 2013-03-06 19:21:50 +01:00
7f88ab95e2 Added the /sudo command 2013-03-06 19:19:12 +01:00
3355f71ab3 Added a tile.update event to the container slot change 2013-03-06 19:00:48 +01:00
e8c2662258 Get Item Lists from BlockAPI::fromString() method 2013-03-06 16:43:25 +01:00
6c4900cd32 Dev version 2013-03-06 14:40:58 +01:00
265549906b Version 2013-03-06 14:38:24 +01:00
b1003500c6 Revert "Possible Solution to Issue #119"
This reverts commit 365b7bec7d.
2013-03-06 14:37:45 +01:00
804636b99f Revert "Updated Possible Fix to #119"
This reverts commit 139dfdf59f.
2013-03-06 14:37:40 +01:00
139dfdf59f Updated Possible Fix to #119 2013-03-06 20:25:48 +10:30
a85c865099 OpCheck Typo fixes #121 2013-03-06 19:06:24 +10:30
365b7bec7d Possible Solution to Issue #119 2013-03-06 18:29:59 +10:30
b0722a8ab1 Changed to next release Alpha_1.3dev 2013-03-05 20:44:34 +01:00
69de47da92 PocketMine-MP Alpha_1.2 release 2013-03-05 20:36:24 +01:00
f4ce715efc Furnace Simplification 2013-03-05 20:23:39 +01:00
55cb79fdf6 Send Slot Data to other players opened chests 2013-03-05 20:17:22 +01:00
4db8c0e68d Functional Chests 2013-03-05 20:09:53 +01:00
68d71b367d Force drops on Creative mode 2013-03-05 18:00:54 +01:00
7e8e273be7 Mob Drops 2013-03-05 17:54:34 +01:00
7cf9c03735 Better Entity attacking system 2013-03-05 17:37:09 +01:00
52aa57d400 Less BlockAPI::cancelAction lag, send only to the starter Player 2013-03-05 17:19:18 +01:00
845e48db66 Instant Break protection 2013-03-05 17:16:26 +01:00
0ab5fc8fcd Entity::getDirection() method 2013-03-05 17:03:34 +01:00
3b2a7e68f3 Fixed DevTools plugin related issues 2013-03-05 13:26:10 +01:00
8c32b3d896 Removed the last backtrace funcion due to an infinite loop 2013-03-05 12:51:39 +01:00
a3e141672a Added option to change the DATA_PATH via CLI argument data-path=<directory> 2013-03-05 12:43:35 +01:00
c60e15a682 Correct Line Breaks 2013-03-04 21:36:07 +01:00
76fcad92b3 Pretty print options for Config JSON 2013-03-04 17:29:15 +01:00
a964c0e3ec Added Stack Count 2013-03-04 17:01:28 +01:00
474c1d2093 Added Vector3 preload 2013-03-04 17:01:15 +01:00
354893ba11 BlockAPI::getBlockFace() method optimization to use the Vector3 method 2013-03-04 16:50:41 +01:00
287fa7e551 Updated the BlockAPI::drop method 2013-03-04 16:50:11 +01:00
326864f889 Fixed FILE_PATH on tests 2013-03-02 15:35:07 +01:00
3e1dfa07c0 Once again on PHP 5.4.12, fixed krakjoe/pthreads#62 2013-03-01 18:48:44 +01:00
5aa34b2803 Downgrade to PHP 5.4.11 as a temp. fix to krakjoe/pthreads#62 2013-03-01 15:38:20 +01:00
ccd1231d42 Remove Chest TileEntities on break 2013-02-27 19:32:59 +01:00
69a1c97a36 Updated PHP to 5.4.12 2013-02-26 19:54:50 +01:00
28bfdbb3c5 Fixed the String test (fixes #117) 2013-02-26 19:21:13 +01:00
0852c42de7 Removing sudo on travis 2013-02-26 12:18:05 +01:00
44dc1b13e3 Fixed breaking a bed from the bottom part 2013-02-25 20:54:16 +01:00
8d522077c4 Removed big & nasty unhandled message for inventory sending 2013-02-25 20:51:32 +01:00
53b79a1f7b Fixed Bed Breaking & added return info 2013-02-25 20:49:34 +01:00
66d43228cd Added comments to bed block fix 2013-02-19 18:10:55 +10:30
536bfa1f46 Correct Bed Breaking UNSTABLE NEEDS TESTING 2013-02-19 17:43:20 +10:30
6bed89f4b5 Update PocketMine-MP.php 2013-02-16 23:12:38 +01:00
20e6d19d85 Added GMP base 2013-02-15 20:11:40 +01:00
b3db08a370 Removed Math_BigInteger dependency 2013-02-15 20:04:21 +01:00
39df588dd9 Removed header 2013-02-14 21:24:26 +01:00
874571d572 Changes made to be compatible with the DevTools plugin 2013-02-14 20:37:16 +01:00
717c668787 Removed includes, moving to only one main folder 2013-02-13 20:35:56 +01:00
09e81b8e17 New tests branch 2013-02-12 16:55:01 +01:00
45192c4448 Updated gamemode constant names 2013-02-12 16:42:58 +01:00
6c4670421c Moved tests 2013-02-12 16:34:52 +01:00
eff4631f35 Fixes #103 2013-02-11 21:04:35 +01:00
20066ddb89 Added GeneralConstants file 2013-02-11 20:29:37 +01:00
ed1f5f225e Fixed glowstone block placing 2013-02-11 20:25:18 +01:00
881e363d1b Readme 2013-02-11 19:44:53 +01:00
db8e00ca4c Update README.md 2013-02-10 16:59:23 +01:00
ce925cd382 Updated ConsoleAPI::alias(), BlockAPI::fromString() 2013-02-10 11:04:14 +01:00
fbc1873e06 Merge branch 'master' of https://github.com/shoghicp/PocketMine-MP 2013-02-10 19:42:59 +10:30
1a2fbd7389 Added Iron Tool IDs 2013-02-10 19:41:58 +10:30
5970927e8a Fixed teleport commands for disconnected players 2013-02-09 21:03:54 +01:00
7c33c4f75a Set a name for unnamed worlds 2013-02-09 20:39:52 +01:00
6dcf9e5da1 Preparation for future changes 2013-02-09 18:07:25 +01:00
4e4aab247a Fixed #93 Path with spaces bug 2013-02-09 13:06:40 +01:00
6ef89cbf8c Added Build status 2013-02-09 12:28:52 +01:00
88b7cb7228 Merge branch 'master' of https://github.com/shoghicp/PocketMine-MP 2013-02-09 21:37:13 +10:30
731827cf7d Added Ingot Item IDs 2013-02-09 21:35:50 +10:30
9281d68bea Exit after an error with exit(1) 2013-02-09 11:32:53 +01:00
1cc15ddd42 Updated README.md 2013-02-09 11:27:17 +01:00
d0057b6595 Merge branch 'master' of https://github.com/shoghicp/PocketMine-MP 2013-02-09 20:44:00 +10:30
c7866fc352 Removed Old and Added New mailing list to README 2013-02-09 20:43:02 +10:30
862938cfc7 Fixed /whitelist reload crash 2013-02-09 10:41:36 +01:00
afbc3da6ed Now following PHPUnit file name pattern 2013-02-09 01:06:36 +01:00
aaaa68ff66 Fixed YAML syntax error 2013-02-09 01:01:20 +01:00
c46eee611f Added some Travis-CI tests 2013-02-09 00:57:41 +01:00
90c8ac1461 Better Console Alias 2013-02-08 17:46:05 +01:00
967a929723 Send Inventory Support 2013-02-08 14:17:52 +01:00
506b9f4a4f Updated packet names 2013-02-08 13:58:00 +01:00
539993751f Moved chat message to console 2013-02-08 13:52:37 +01:00
32df30448b Typo 2013-02-07 17:10:02 +01:00
e7d56a837f Added __toString() to Player, Block and Item classes & added protocol order enforcement after login 2013-02-07 17:04:04 +01:00
4d05d7da0d Fixed #96 server crash 2013-02-07 16:56:10 +01:00
498c050da7 Added OPs and permission checks 2013-02-07 09:37:15 +01:00
c2e55941d8 Added player commands, better console API and implemented future player chat 2013-02-07 09:24:44 +01:00
72388fa3cb Corrected Feather and Added Brick 2013-02-07 16:24:06 +10:30
318590e664 Merge branch 'master' of https://github.com/shoghicp/PocketMine-MP 2013-02-07 16:12:24 +10:30
466ae6290d Merge pull request #95 from snake302/patch-2
Update compile_php.sh
2013-02-06 13:14:06 -08:00
816ef08ad2 Update compile_php.sh
Update version
- pthread
- curl 7.29.0
2013-02-07 00:26:44 +04:00
e288a8a880 Multiple Paintings 2013-02-06 17:04:19 +01:00
d2dcf4f43a Switched gamemode handler to Player object 2013-02-06 16:18:15 +01:00
4aa0f8f8d1 Slab placement fix 2013-02-06 16:06:23 +01:00
5bca4242c2 Bedrock breakeable 2013-02-06 15:59:51 +01:00
93fa008acb Correct Painting placement 2013-02-06 15:57:48 +01:00
639cfc8ab8 GMP version 2013-02-06 11:22:55 +01:00
854599005a Fixed assembly instructions blocking compilation on iOS 2013-02-06 11:18:23 +01:00
72bc35a219 changes 2013-02-06 10:44:04 +01:00
d76408b809 Added Feather Item Code 2013-02-06 20:05:14 +10:30
320dc1af88 Working on Item IDs Added COAL APPLE DIAMOND STICK BOWL 2013-02-06 19:57:32 +10:30
1c05455514 Weird Painting spawn (WiP) 2013-02-05 23:25:40 +01:00
0be3379720 Updated view-distance 2013-02-05 21:43:01 +01:00
e433f0f6dc Flying damage 2013-02-05 21:33:30 +01:00
f53e08bb84 Glass pane suffocation 2013-02-05 21:18:27 +01:00
09dd47722b Meaningful crash reports 2013-02-05 19:15:51 +01:00
74f139ea85 Fixed server crash 2013-02-05 17:58:46 +01:00
b0c520f72a Send only field of view + Chunk resend support 2013-02-05 17:53:22 +01:00
e5ed7e04cf Send MiniChunks 2013-02-05 17:36:38 +01:00
7f92c6fab3 Automatic channel selection & use PocketMine.org API 2013-02-05 16:44:13 +01:00
50815c7ca8 Fixed #92 crash 2013-02-05 07:25:15 +01:00
67925b7df2 Snow Layer is now replaceable and flowable 2013-02-04 23:29:01 +01:00
23dc1033d5 Better chunk distance calculation 2013-02-04 23:11:45 +01:00
34f0e5170b Better door Hinges 2013-02-04 23:03:41 +01:00
e07302b021 Improvement in chunk sending to reduce server lag 2013-02-04 22:48:06 +01:00
ac6c3c7e69 Allow binding to an specific IP 2013-02-04 22:37:56 +01:00
6839001dc3 New Chunks are sent based on the current player position 2013-02-04 22:17:23 +01:00
1b37caf732 Added fast Item check 2013-02-04 20:48:02 +01:00
a07e002565 Added tile update event 2013-02-04 20:31:02 +01:00
25549bbf51 Updated GMP version 2013-02-04 20:27:45 +01:00
6b77a69302 Updated API methods to use less events 2013-02-04 20:27:36 +01:00
565cb9781c Bed placement 2013-02-04 19:57:23 +01:00
719dff6e3c Added API Version check 2013-02-04 19:39:00 +01:00
4f0517a5a7 Added Sign placement 2013-02-04 19:35:11 +01:00
3e87d1927d Cactus Placement 2013-02-04 19:08:31 +01:00
7e7f1892fd Instant growth using bonemeal 2013-02-04 19:00:21 +01:00
fee04cd0d9 Tilling Dirt & Grass, tall gras growth 2013-02-04 18:54:48 +01:00
a718294a08 Seed placement 2013-02-04 18:41:23 +01:00
65280d85d1 Spawning blocks/items using its name 2013-02-04 17:44:41 +01:00
cdb05f0695 Updated Entity class to reflect changes in BlockAPI 2013-02-04 17:26:55 +01:00
37f5626e9a Added more future possible placements for 2013-02-04 17:21:11 +01:00
bb27c0623c Made liquid blocks replaceable 2013-02-04 17:16:01 +01:00
3519cb230c Correct Sugarcane placement 2013-02-04 17:15:01 +01:00
213cda27aa Added conversion between Items <==> Blocks 2013-02-04 16:26:47 +01:00
d5aa898ffe Finished Adding Item IDs 2013-02-04 16:13:11 +01:00
f1c593d809 Fix for crashes via item (MCPE-1198) 2013-02-04 15:02:21 +01:00
3578b90a39 Ladder placement 2013-02-03 22:53:22 +01:00
afe33202dc Added Chest & Furnace placement 2013-02-03 22:50:59 +01:00
a5651c0f43 Door Placement, Breaking and Activation 2013-02-03 22:39:30 +01:00
9cdd616852 Corrected Fence Gate activation 2013-02-03 21:21:16 +01:00
084acfab00 Fence Gate Placement 2013-02-03 21:17:55 +01:00
59ae4f6faa Trapdoor placement & activation 2013-02-03 21:13:16 +01:00
e15392f7bc Added Quartz Stairs to placement 2013-02-03 21:03:20 +01:00
a3260814b8 Upside-down stairs placement 2013-02-03 21:01:21 +01:00
8df59078ad Stair Block placement 2013-02-03 20:59:34 +01:00
b45676d2b5 Fixed Torch block target 2013-02-03 20:47:58 +01:00
399050fc4e Added Torches placement 2013-02-03 20:45:12 +01:00
3ecbe7dbf7 Added Mushroom placement 2013-02-03 20:24:22 +01:00
a9c7a6642e Added flowers placement 2013-02-03 20:23:07 +01:00
d1610ce7a1 Check for player in range for slab placement 2013-02-03 20:21:03 +01:00
fb9a0f2119 Slab placement 2013-02-03 20:15:55 +01:00
d9c87161ba Place/Breaking/Activation logic separated from BlockAPI 2013-02-03 18:55:59 +01:00
6156baab85 Added Liquid check to Fall Damage 2013-02-03 11:03:54 +01:00
bf63065d4e Added Fall damage message 2013-02-03 10:55:54 +01:00
38a1f82456 Added Fall Damage 2013-02-03 10:51:12 +01:00
861a017fa0 Fixed redstone IDs 2013-02-02 21:14:49 +01:00
c95f671271 Added block classes to BlockAPI 2013-02-02 21:12:56 +01:00
49faebde2c Added all the blocks 2013-02-02 21:06:26 +01:00
bb68f8f305 Added PHP version check 2013-02-02 20:27:07 +01:00
8513a34358 Added construct method 2013-02-02 19:52:06 +01:00
8a9762cd31 Second sugarcane fix 2013-02-02 19:03:45 +01:00
38f40eb540 Fix for growing trees 2013-02-02 18:55:53 +01:00
69d2557e32 Fix for sugarcane placing 2013-02-02 18:50:54 +01:00
8d6d5306c1 Added Liquids properties 2013-02-02 17:50:17 +01:00
328cc968bd Added more block properties 2013-02-02 17:38:15 +01:00
e6c2ddbb47 Fixed usage stats 2013-02-02 16:21:00 +01:00
ad98fbf380 Added block info to /give command 2013-02-02 16:19:31 +01:00
34db027ffd Corrected block metadata 2013-02-02 15:53:22 +01:00
bbd113692e Disallow placing torches on ceilings 2013-02-02 15:43:20 +01:00
888e84dd69 Block Names 2013-02-02 15:42:06 +01:00
5a054a8ab4 Added new methods of Block properties (WiP) 2013-02-02 13:36:18 +01:00
4c06b384c7 Added Block Properties 2013-02-02 12:50:53 +01:00
4e740e1862 Next dev version 2013-02-01 18:30:22 +01:00
c9e459cb0f Stable release Alpha_1.1.1 2013-02-01 18:28:25 +01:00
d24d826ffd Adventure Mode 2013-02-01 18:15:14 +01:00
eaa3006d51 Implemented nametags 2013-02-01 15:02:36 +01:00
198a0e69de Updated target version 2013-02-01 00:18:35 +01:00
c7e1a36bd5 Updated version to next development release 2013-01-31 18:28:29 +01:00
f0aecabef7 Updated Version 2013-01-31 18:20:31 +01:00
60c57a6330 Correct and new slab placement (upside-down) 2013-01-31 18:20:01 +01:00
ba4fe61cdb Better event handling 2013-01-31 17:23:50 +01:00
a485536716 Fixed protocol errors 2013-01-30 23:38:07 +01:00
9ef2dc6fe1 Small changes, Ellie 2013-01-30 20:49:34 +01:00
d0a08d16e7 Added new packets 2013-01-30 20:21:18 +01:00
0e889b0139 Armor is shown on multiplayer 2013-01-30 19:57:11 +01:00
fe8b4b7aa7 Added Armor 2013-01-30 18:46:06 +01:00
1e8b012a6e Added structure version 2013-01-30 18:09:19 +01:00
5096cdcde8 Added item pickup delay 2013-01-30 18:02:13 +01:00
08b67428a0 Placing signs text 2013-01-30 17:07:43 +01:00
b697f1441e Protocol changes 4 2013-01-30 16:29:00 +01:00
62578d5fc7 Protocol changes 3 2013-01-30 16:25:26 +01:00
c787142346 Protocol changes 2 2013-01-30 16:13:33 +01:00
db38b824b7 Protocol changes 1 2013-01-30 16:00:22 +01:00
a75f8c2737 Updating version & protocol enforcement 2013-01-30 15:35:33 +01:00
9a8850cb9c Added Stonecutter 2013-01-30 12:47:47 +01:00
8d232cf623 Save paintings 2013-01-29 22:44:19 +01:00
a7079fc49b Correctly handle paintings 2013-01-29 22:38:48 +01:00
71b12191b2 Eating 2013-01-29 20:53:43 +01:00
2011d1d339 Void damage 2013-01-29 20:01:33 +01:00
1976e1c6f6 Item movement fix 2013-01-29 19:29:16 +01:00
5a2156c2bf New compile options for speed improvement 2013-01-29 19:05:47 +01:00
a86213dad8 Include Yaw and Pitch in entity tracking 2013-01-29 17:16:20 +01:00
6095432a4f Updated versions 2013-01-29 10:01:46 +01:00
46f7279a26 Fixes #83 #82 2013-01-29 08:40:36 +01:00
da2b800ea8 Changes in item spawning 2013-01-28 23:07:17 +01:00
862947ab6b Entity Motion packet (WiP) 2013-01-28 22:48:18 +01:00
f8179f0f7c Removed var_dump()! 2013-01-28 20:30:31 +01:00
db9625b52f Entity Gravity 2013-01-28 20:26:57 +01:00
fe3be181e8 Sign placing improvement 2013-01-28 19:06:39 +01:00
8a5708f47a Placing Signs 2013-01-28 19:01:41 +01:00
df46e241d3 Added marble block 2013-01-28 18:37:26 +01:00
104817162d Added upside-down stairs 2013-01-28 18:19:16 +01:00
50ae0953ac Allow for command-line arguments to starter scripts 2013-01-28 18:10:43 +01:00
d9e9b9fd22 Updated target version 2013-01-28 16:22:11 +01:00
eeb623cf21 Added new 0.6.0 blocks 2013-01-28 16:21:50 +01:00
1474d8c785 Better Tile selection & player death check and fix 2013-01-27 23:21:08 +01:00
26fb652c5a Added entity dead check for damage 2013-01-27 23:08:30 +01:00
c06ffe3003 TileEntity spawning improvement 2013-01-27 22:58:54 +01:00
2cb7a21b76 Entity and TileEntity saving 2013-01-27 21:33:57 +01:00
5c11f48270 Tile Entities & Signs 2013-01-27 19:36:12 +01:00
3c4888521d Fix for feet suffocation 2013-01-27 19:14:51 +01:00
d54161f5ca Fixed Signs sufocation 2013-01-27 18:46:09 +01:00
67341c6420 Added regeneration fix, item despawn and damage check 2013-01-27 18:23:51 +01:00
2eb93c1676 Entity metadata 2013-01-27 13:32:55 +01:00
d69291e2fa Added logged in checks 2013-01-27 11:34:24 +01:00
0c5826c8ab Water now generates source blocks 2013-01-27 11:29:43 +01:00
880121a83f Fixed a special water & lava case 2013-01-27 00:29:25 +01:00
0082bc9d10 Lava & water flow now creates stone, cobblestona and obsidian 2013-01-27 00:10:34 +01:00
895e001216 Fixed PHP-Powered memory leaks 2013-01-26 22:00:34 +01:00
1f8939da6e Fixed entities memory leak 2013-01-26 21:45:31 +01:00
c77a3c2f87 Added new IP site 2013-01-26 20:57:13 +01:00
f476cf6943 Send optional usage data 2013-01-26 20:50:34 +01:00
8e3efa0b7e Removed unknown Packet 0xa9 2013-01-26 19:01:05 +01:00
81423e6c3d Fixed health not being correctly displayed after reconnect 2013-01-26 18:55:09 +01:00
e1cf3cc25e Entity death status 2013-01-26 18:51:50 +01:00
fe7138b21e Entity moving optimization 2013-01-26 18:44:13 +01:00
234aee9dfa Entity harm sound 2013-01-26 18:24:10 +01:00
88725100a0 Version - Arggghhhhh!!!! 2013-01-26 17:36:34 +01:00
15772bfad4 Version 2013-01-26 17:34:02 +01:00
afbb5fab04 Fixed old & deprecated plugins not being able to create a config file 2013-01-26 17:32:56 +01:00
00c3201580 Fixed suffocating in fences 2013-01-26 17:24:05 +01:00
36fdb10b9e Fixed random suffocation 2013-01-26 17:19:52 +01:00
828b794555 Fixed suffocating in doors 2013-01-26 17:09:00 +01:00
e1ce88c0ef Fixed creative mode damage 2013-01-26 17:06:30 +01:00
4b744d7af3 Fixed server crash releated to inventory spawning 2013-01-26 16:58:10 +01:00
59a95aadd2 Fixed server crash 2013-01-26 16:23:33 +01:00
20035d18cd Updated version 2013-01-26 14:50:20 +01:00
0425b630ca Updated homepage 2013-01-26 14:38:41 +01:00
d3c6c41ad0 Removed irrelevant things 2013-01-26 14:36:39 +01:00
0ae467c33f Bonemeal tall grass and flowers grow 2013-01-26 14:27:56 +01:00
f917111f31 Implemented drowing damage 2013-01-26 13:44:38 +01:00
ac0fab8f0b Made Zlib required 2013-01-26 13:21:58 +01:00
d1d720e9ef Updated compiler to use less instructions & disk usage 2013-01-26 13:15:53 +01:00
2a63699dcc Updated Entity::touchingBlock() 2013-01-26 12:59:22 +01:00
6a0b3c0e9a Kill messages 2013-01-26 12:56:29 +01:00
09385daf60 Better damage handling + cactus damage 2013-01-26 12:53:37 +01:00
061faaa410 Entity closing fix 2013-01-26 12:31:09 +01:00
26da585889 health regeneration cancelled when dead 2013-01-26 12:12:59 +01:00
a0cb4d2698 Fixed item restoration duplication 2013-01-26 11:57:19 +01:00
5101391c29 Lava, fire and suffocation damage 2013-01-26 11:31:38 +01:00
f06f1d81c1 Fixed cURL version 2013-01-25 14:24:00 +01:00
75eb324967 Added inline compiler optimization for big servers 2013-01-24 17:11:30 +01:00
e5bed548b9 Added Kick API 2013-01-24 19:13:48 +10:30
fde7b5ab5d New compiler using variables to handle versions 2013-01-23 22:16:24 +01:00
237ad4eee4 Fixed random entity memory leak + loops 2013-01-23 20:50:01 +01:00
6660a0a771 Changed version to development 2013-01-23 20:20:12 +01:00
243 changed files with 20008 additions and 10326 deletions

156
.gitignore vendored
View File

@ -2,128 +2,11 @@ players/*
worlds/*
plugins/*
logs/*
bin/*
*.log
*.pmf
*.txt
server.properties
white-list.txt
banned-ips.txt
banned.txt
#################
## Eclipse
#################
*.pydevproject
.project
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
#################
## Visual Studio
#################
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.vspscc
.builds
*.dotCover
## TODO: If you have NuGet Package Restore enabled, uncomment this
#packages/
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
# Visual Studio profiler
*.psess
*.vsp
# ReSharper is a .NET coding add-in
_ReSharper*
# Installshield output folder
[Ee]xpress
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish
# Others
[Bb]in
[Oo]bj
sql
TestResults
*.Cache
ClientBin
stylecop.*
~$*
*.dbmdl
Generated_Code #added for RIA/Silverlight projects
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
############
@ -136,38 +19,5 @@ Thumbs.db
# Folder config file
Desktop.ini
#############
## Python
#############
*.py[co]
# Packages
*.egg
*.egg-info
dist
build
eggs
parts
bin
var
sdist
develop-eggs
.installed.cfg
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
#Translations
*.mo
#Mr Developer
.mr.developer.cfg
# Mac crap
.DS_Store

14
.travis.yml Normal file
View File

@ -0,0 +1,14 @@
language: php
php:
- 5.4
before_script:
- pecl install channel://pecl.php.net/pthreads-0.0.44
script:
- php src/tests/ServerSuiteTest.php
notifications:
email: false
webhooks: http://n.tkte.ch/h/214/wsNvmG43-ncxUVRrFPwSM-r0

27
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,27 @@
![](http://www.pocketmine.net/favicon.png)
# PocketMine-MP Contribution Gidelines
Before contributing to PocketMine-MP, please read this.
## I've a question
* For questions, please refer to the _#mcpedevs_ IRC
channel on Freenode. There is a [WebIRC](http://webchat.freenode.net?channels=mcpedevs&uio=d4) if you want.
* You can ask directly to _[@PocketMine](https://twitter.com/PocketMine)_ in Twitter.
## I want to create an issue
* First, use the [Issue Search](https://github.com/PocketMine/PocketMine-MP/search?ref=cmdform&type=Issues) to check if anyone has reported it.
* Is your issue related to a Plugin? If so, please contact their original author instead of reporting it here.
* And no, we won't update a Plugin because you need it.
* When reporting, give as much info as you can, and if the Issue is a crash, give the Crash Dump.
* Issues should be written in English.
## I want to contribute code
* Use the [Pull Request](https://github.com/PocketMine/PocketMine-MP/pull/new) system, your request will be checked and discussed.
* If you want to be part of PocketMine-MP, we will ask you to.
* Code using the syntax as in PocketMine-MP.
* The code must be clear and written in English, comments included.
__Thanks for contributing to PocketMine-MP!__

View File

@ -1,35 +1,33 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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/
*
*
*/
require_once(dirname(__FILE__)."/src/common/dependencies.php");
require_once("API/ServerAPI.php");
/***REM_START***/
require_once(dirname(__FILE__)."/src/config.php");
require_once(FILE_PATH."/src/functions.php");
require_once(FILE_PATH."/src/dependencies.php");
/***REM_END***/
$server = new ServerAPI();
$server->run();//$server->start();
//$server->join();
$server->start();
kill(getmypid()); //Fix for segfault
kill(getmypid()); //Fix for ConsoleAPI being blocked
exit(0);

View File

@ -1,6 +1,6 @@
![](http://shoghicp.github.com/PocketMine-MP/favicon.png)
![](http://www.pocketmine.net/favicon.png)
# PocketMine-MP
# PocketMine-MP [![Build Status](https://travis-ci.org/PocketMine/PocketMine-MP.png?branch=master)](https://travis-ci.org/PocketMine/PocketMine-MP)
```
This program is free software: you can redistribute it and/or modify
@ -17,31 +17,34 @@ 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 Server for Minecraft Pocket Edition done in PHP__. It has a Plugin API that enables a developer to extend it and add new features, or change default ones.
__PocketMine-MP is a sofware for creating Minecraft Pocket Edition servers__. It has a Plugin API that enables a developer to extend it and add new features, or change default ones.
The entire server is done in PHP, and has been tested, profiled and optimized to run smoothly.
### [Homepage](http://shoghicp.github.com/PocketMine-MP/)
### [Homepage](http://www.pocketmine.net/)
### [Go to Wiki for more information](https://github.com/shoghicp/PocketMine-MP/wiki)
### [Forums](http://forums.pocketmine.net/)
### [FAQ: Frequently Asked Questions](https://github.com/shoghicp/PocketMine-MP/wiki/Frequently-Asked-Questions)
### [Wiki](https://github.com/PocketMine/PocketMine-MP/wiki/)
### [@PocketMine](https://twitter.com/PocketMine)
### [Mailing List](https://groups.google.com/forum/#!forum/pocketmine-development) pocketmine-development@googlegroups.com
### [FAQ: Frequently Asked Questions](https://github.com/PocketMine/PocketMine-MP/wiki/Frequently-Asked-Questions)
## Third-party Libraries Used
* __[PHP cURL](http://php.net/manual/en/book.curl.php)__
### [Twitter @PocketMine](https://twitter.com/PocketMine)
## IRC #pocketmine (or #mcpedevs) @ irc.freenode.net
* [WebIRC](http://webchat.freenode.net?channels=pocketmine,mcpedevs&uio=d4)
## Third-party Libraries/Protocols Used
* __[PHP Sockets](http://php.net/manual/en/book.sockets.php)__
* __[PHP SQLite3](http://php.net/manual/en/book.sqlite3.php)__
* __[PHP BCMath](http://php.net/manual/en/book.bc.php)__
* __[PHP pthreads](https://github.com/krakjoe/pthreads)__ by _[krakjoe](https://github.com/krakjoe)_: Threading for PHP - Share Nothing, Do Everything.
* __[PHP NBT](https://github.com/TheFrozenFire/PHP-NBT-Decoder-Encoder/blob/master/nbt.class.php)__ by _[TheFrozenFire](https://github.com/TheFrozenFire)_: Class for reading in NBT-format files (modified to handle Little-Endian files).
* __[Math_BigInteger](http://phpseclib.sourceforge.net/math/intro.html)__ by _[phpseclib](http://phpseclib.sourceforge.net/)_: Pure-PHP arbitrary precission integer arithmetic library
* __[Spyc](https://github.com/mustangostang/spyc/blob/master/Spyc.php)__ by _[Vlad Andersen](https://github.com/mustangostang)_: A simple YAML loader/dumper class for PHP.
* __[ANSICON](https://github.com/adoxa/ansicon)__ by _[Jason Hood](https://github.com/adoxa)_: Process ANSI escape sequences for Windows console programs.
## IRC #mcpedevs @ irc.freenode.net
* [WebIRC](http://webchat.freenode.net?channels=mcpedevs&uio=d4)
* __[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)__

View File

@ -1,156 +0,0 @@
#!/bin/bash
echo "[PocketMine] PHP installer and compiler for Linux - by @shoghicp v0.3"
DIR=`pwd`
date > $DIR/install.log 2>&1
uname -a >> $DIR/install.log 2>&1
echo "[INFO] Checking dependecies"
type make >> $DIR/install.log 2>&1 || { echo >&2 "[ERROR] Please install \"make\""; exit 1; }
type autoconf >> $DIR/install.log 2>&1 || { echo >&2 "[ERROR] Please install \"autoconf\""; exit 1; }
type automake >> $DIR/install.log 2>&1 || { echo >&2 "[ERROR] Please install \"automake\""; exit 1; }
type gcc >> $DIR/install.log 2>&1 || { echo >&2 "[ERROR] Please install \"gcc\""; exit 1; }
type m4 >> $DIR/install.log 2>&1 || { echo >&2 "[ERROR] Please install \"m4\""; exit 1; }
rm -r -f install_data/ >> $DIR/install.log 2>&1
rm -r -f php5/ >> $DIR/install.log 2>&1
mkdir -m 0777 install_data >> $DIR/install.log 2>&1
mkdir -m 0777 php5 >> $DIR/install.log 2>&1
cd install_data
#PHP 5
echo -n "[PHP5] downloading..."
wget http://php.net/get/php-5.4.11.tar.gz/from/this/mirror -O php-5.4.11.tar.gz >> $DIR/install.log 2>&1
echo -n " extracting..."
tar -zxvf php-5.4.11.tar.gz >> $DIR/install.log 2>&1
rm -f php-5.4.11.tar.gz >> $DIR/install.log 2>&1
mv php-5.4.11 php
echo " done!"
#zlib
echo -n "[zlib] downloading..."
wget http://zlib.net/zlib-1.2.7.tar.gz -O zlib-1.2.7.tar.gz >> $DIR/install.log 2>&1
echo -n " extracting..."
tar -zxvf zlib-1.2.7.tar.gz >> $DIR/install.log 2>&1
rm -f zlib-1.2.7.tar.gz >> $DIR/install.log 2>&1
mv zlib-1.2.7 zlib
echo -n " checking..."
cd zlib
./configure --prefix=$DIR/install_data/php/ext/zlib \
--static >> $DIR/install.log 2>&1
echo -n " compiling..."
make >> $DIR/install.log 2>&1
echo -n " installing..."
make install >> $DIR/install.log 2>&1
echo -n " cleaning..."
cd ..
rm -r -f ./zlib
echo " done!"
#OpenSSL
#echo -n "[OpenSSL] downloading..."
#wget ftp://ftp.openssl.org/source/openssl-1.0.1c.tar.gz -O openssl-1.0.1c.tar.gz >> $DIR/install.log 2>&1
#echo -n " extracting..."
#tar -zxvf openssl-1.0.1c.tar.gz >> $DIR/install.log 2>&1
#rm -f openssl-1.0.1c.tar.gz >> $DIR/install.log 2>&1
#mv openssl-1.0.1c openssl
#echo -n " checking..."
#cd openssl
#./config --prefix=$DIR/install_data/php/ext/openssl >> $DIR/install.log 2>&1
#echo -n " compiling..."
#make >> $DIR/install.log 2>&1
#echo -n " installing..."
#make install >> $DIR/install.log 2>&1
#echo -n " cleaning..."
#cd ..
#rm -r -f ./openssl
#echo " done!"
#GMP
echo -n "[GMP] downloading..."
wget ftp://ftp.gmplib.org/pub/gmp-5.1.0/gmp-5.1.0.tar.bz2 -O gmp-5.1.0.tar.bz2 >> $DIR/install.log 2>&1
echo -n " extracting..."
tar -jxvf gmp-5.1.0.tar.bz2 >> $DIR/install.log 2>&1
rm -f gmp-5.1.0.tar.bz2 >> $DIR/install.log 2>&1
mv gmp-5.1.0 gmp
echo -n " checking..."
cd gmp
./configure --prefix=$DIR/install_data/php/ext/gmp \
--disable-shared >> $DIR/install.log 2>&1
echo -n " compiling..."
make >> $DIR/install.log 2>&1
echo -n " installing..."
make install >> $DIR/install.log 2>&1
echo -n " cleaning..."
cd ..
rm -r -f ./gmp
echo " done!"
echo -n "[cURL] downloading..."
wget https://github.com/bagder/curl/archive/master.tar.gz --no-check-certificate -O curl-master.tar.gz >> $DIR/install.log 2>&1
echo -n " extracting..."
tar -zxvf curl-master.tar.gz >> $DIR/install.log 2>&1
rm -f curl-master.tar.gz >> $DIR/install.log 2>&1
mv curl-master curl
echo -n " checking..."
cd curl
./buildconf >> $DIR/install.log 2>&1
./configure --prefix=$DIR/install_data/php/ext/curl \
--disable-shared >> $DIR/install.log 2>&1
echo -n " compiling..."
make >> $DIR/install.log 2>&1
echo -n " installing..."
make install >> $DIR/install.log 2>&1
echo -n " cleaning..."
cd ..
rm -r -f ./curl
echo " done!"
#pthreads
echo -n "[PHP pthreads] downloading..."
wget https://github.com/krakjoe/pthreads/archive/master.tar.gz --no-check-certificate -O pthreads-master.tar.gz >> $DIR/install.log 2>&1
echo -n " extracting..."
tar -zxvf pthreads-master.tar.gz >> $DIR/install.log 2>&1
rm -f pthreads-master.tar.gz >> $DIR/install.log 2>&1
mv pthreads-master $DIR/install_data/php/ext/pthreads
echo " done!"
#--with-openssl=$DIR/install_data/php/ext/openssl
echo -n "[PHP5] checking..."
cd php
./buildconf --force >> $DIR/install.log 2>&1
./configure --prefix=$DIR/php5 \
--exec-prefix=$DIR/php5 \
--enable-embedded-mysqli \
--enable-bcmath \
--with-gmp=$DIR/install_data/php/ext/gmp \
--with-curl=$DIR/install_data/php/ext/curl \
--with-zlib=$DIR/install_data/php/ext/zlib \
--disable-libxml \
--disable-xml \
--disable-dom \
--disable-simplexml \
--disable-xmlreader \
--disable-xmlwriter \
--without-pear \
--disable-cgi \
--disable-session \
--enable-ctype \
--without-iconv \
--without-pdo-sqlite \
--enable-sockets \
--enable-shared=no \
--enable-static=yes \
--enable-pcntl \
--enable-pthreads \
--enable-maintainer-zts \
--enable-cli >> $DIR/install.log 2>&1
echo -n " compiling..."
make >> $DIR/install.log 2>&1
echo -n " installing..."
make install >> $DIR/install.log 2>&1
echo " done!"
cd $DIR
echo -n "[INFO] Cleaning up..."
rm -r -f install_data/ >> $DIR/install.log 2>&1
date >> $DIR/install.log 2>&1
echo " done!"
echo "[PocketMine] You should start the server now using \"./start.sh\""
echo "[PocketMine] If it doesn't works, please send the \"install.log\" file to the Bug Tracker"

View File

@ -1,65 +1,164 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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/
*
*
*/
class BanAPI{
private $server;
private $whitelist;
private $banned;
private $ops;
private $bannedIPs;
function __construct(PocketMinecraftServer $server){
$this->server = $server;
private $cmdWL = array();//Command WhiteList
function __construct(){
$this->server = ServerAPI::request();
}
public function init(){
console("[INFO] Loading authentication lists...");
$this->whitelist = new Config(FILE_PATH."white-list.txt", CONFIG_LIST);
$this->bannedIPs = new Config(FILE_PATH."banned-ips.txt", CONFIG_LIST);
$this->banned = new Config(FILE_PATH."banned.txt", CONFIG_LIST);
$this->server->api->console->register("banip", "Manages IP Banning", array($this, "commandHandler"));
$this->server->api->console->register("ban", "Manages Bannning", array($this, "commandHandler"));
$this->server->api->console->register("kick", "Kicks a player", array($this, "commandHandler"));
$this->server->api->console->register("whitelist", "Manages White-listing", array($this, "commandHandler"));
$this->whitelist = new Config(DATA_PATH."white-list.txt", CONFIG_LIST);//Open whitelist list file
$this->bannedIPs = new Config(DATA_PATH."banned-ips.txt", CONFIG_LIST);//Open Banned IPs list file
$this->banned = new Config(DATA_PATH."banned.txt", CONFIG_LIST);//Open Banned Usernames list file
$this->ops = new Config(DATA_PATH."ops.txt", CONFIG_LIST);//Open list of OPs
$this->server->api->console->register("banip", "<add|remove|list|reload> [IP|player]", array($this, "commandHandler"));
$this->server->api->console->register("ban", "<add|remove|list|reload> [username]", array($this, "commandHandler"));
$this->server->api->console->register("kick", "<player> [reason ...]", array($this, "commandHandler"));
$this->server->api->console->register("whitelist", "<on|off|list|add|remove|reload> [username]", array($this, "commandHandler"));
$this->server->api->console->register("op", "<player>", array($this, "commandHandler"));
$this->server->api->console->register("deop", "<player>", array($this, "commandHandler"));
$this->server->api->console->register("sudo", "<player>", array($this, "commandHandler"));
$this->server->api->console->alias("ban-ip", "banip add");
$this->server->api->console->alias("banlist", "ban list");
$this->server->api->console->alias("pardon", "ban remove");
$this->server->api->console->alias("pardon-ip", "banip remove");
$this->server->addHandler("console.command", array($this, "permissionsCheck"), 1);//Event handler when commands are issued. Used to check permissions of commands that go through the server.
$this->server->addHandler("player.block.break", array($this, "permissionsCheck"), 1);//Event handler for blocks
$this->server->addHandler("player.block.place", array($this, "permissionsCheck"), 1);//Event handler for blocks
$this->server->addHandler("player.flying", array($this, "permissionsCheck"), 1);//Flying Event
}
public function commandHandler($cmd, $params){
public function cmdWhitelist($cmd){//Whitelists a CMD so everyone can issue it - Even non OPs.
$this->cmdWhitelist[strtolower(trim($cmd))] = true;
}
public function isOp($username){//Is a player op?
$username = strtolower($username);
if($this->server->api->dhandle("op.check", $username) === true){
return true;
}elseif($this->ops->exists($username)){
return true;
}
return false;
}
public function permissionsCheck($data, $event){
switch($event){
case "player.flying"://OPs can fly around the server.
if($this->isOp($data->iusername)){
return true;
}
break;
case "player.block.break":
case "player.block.place"://Spawn protection detection. Allows OPs to place/break blocks in the spawn area.
if(!$this->isOp($data["player"]->iusername)){
$t = new Vector2($data["target"]->x, $data["target"]->z);
$s = new Vector2($this->server->spawn->x, $this->server->spawn->z);
if($t->distance($s) <= $this->server->api->getProperty("spawn-protection") and $this->server->api->dhandle($event.".spawn", $data) !== true){
return false;
}
}
return;
break;
case "console.command"://Checks if a command is allowed with the current user permissions.
if(isset($this->cmdWhitelist[$data["cmd"]])){
return;
}
if($data["issuer"] instanceof Player){
if($this->server->api->handle("console.check", $data) === true or $this->isOp($data["issuer"]->iusername)){
return;
}
}elseif($data["issuer"] === "console" or $data["issuer"] === "rcon"){
return;
}
return false;
break;
}
}
public function commandHandler($cmd, $params, $issuer, $alias){
$output = "";
switch($cmd){
case "sudo":
$target = strtolower(array_shift($params));
$player = $this->server->api->player->get($target);
if(!($player instanceof Player)){
$output .= "Player not connected.\n";
break;
}
$this->server->api->console->run(implode(" ", $params), $player);
$output .= "Command ran as ".$player->username.".\n";
break;
case "op":
$user = strtolower($params[0]);
$player = $this->server->api->player->get($user);
if(!($player instanceof Player)){
$this->ops->set($user);
$this->ops->save($user);
$output .= $user." is now op\n";
break;
}
$this->ops->set($player->iusername);
$this->ops->save();
$output .= $player->iusername." is now op\n";
$this->server->api->chat->sendTo(false, "You are now op.", $player->iusername);
break;
case "deop":
$user = strtolower($params[0]);
$player = $this->server->api->player->get($user);
if(!($player instanceof Player)){
$this->ops->set($user, false);
$this->ops->save($user);
$output .= $user." is no longer op\n";
break;
}
$this->ops->remove($player->iusername);
$this->ops->save();
$output .= $player->iusername." is not longer op\n";
$this->server->api->chat->sendTo(false, "You are no longer op.", $player->iusername);
break;
case "kick":
if(!isset($params[0])){
console("[INFO] Usage: /kick <playername> [reason]");
$output .= "Usage: /kick <player> [reason ...]\n";
}else{
$name = array_shift($params);
$name = strtolower(array_shift($params));
$player = $this->server->api->player->get($name);
if($player === false){
console("[ERROR] Player \"".$name."\" does not exist");
$output .= "Player \"".$name."\" does not exist\n";
}else{
$reason = implode(" ", $params);
$reason = $reason == "" ? "No reason":$reason;
$player->close("You have been kicked: ".$reason);
console("[INFO] Player \"".$player->username."\" has been kicked: $reason");
if($issuer instanceof Player){
$this->server->api->chat->broadcast($player->username." has been kicked by ".$issuer->username.": $reason\n");
}else{
$this->server->api->chat->broadcast($player->username." has been kicked: $reason\n");
}
}
}
break;
@ -67,37 +166,37 @@ class BanAPI{
$p = strtolower(array_shift($params));
switch($p){
case "remove":
$user = trim(implode(" ", $params));
$user = strtolower($params[0]);
$this->whitelist->remove($user);
$this->whitelist->save();
console("[INFO] Player \"$user\" removed from white-list");
$output .= "Player \"$user\" removed from white-list\n";
break;
case "add":
$user = trim(implode(" ", $params));
$user = strtolower($params[0]);
$this->whitelist->set($user);
$this->whitelist->save();
console("[INFO] Player \"$user\" added to white-list");
$output .= "Player \"$user\" added to white-list\n";
break;
case "reload":
$this->whitelist = $this->load(FILE_PATH."white-list.txt", CONFIG_LIST);
$this->whitelist = new Config(DATA_PATH."white-list.txt", CONFIG_LIST);
break;
case "list":
console("[INFO] White-list: ".implode(", ", $this->whitelist->getAll(true)));
$output .= "White-list: ".implode(", ", $this->whitelist->getAll(true))."\n";
break;
case "on":
case "true":
case "1":
console("[INFO] White-list turned on");
$output .= "White-list turned on\n";
$this->server->api->setProperty("white-list", true);
break;
case "off":
case "false":
case "0":
console("[INFO] White-list turned off");
$output .= "White-list turned off\n";
$this->server->api->setProperty("white-list", false);
break;
default:
console("[INFO] Usage: /whitelist <on | off | add | remove | reload | list> [username]");
$output .= "Usage: /whitelist <on|off|list|add|remove|reload> [username]\n";
break;
}
break;
@ -106,26 +205,31 @@ class BanAPI{
switch($p){
case "pardon":
case "remove":
$ip = trim(implode($params));
$ip = strtolower($params[0]);
$this->bannedIPs->remove($ip);
$this->bannedIPs->save();
console("[INFO] IP \"$ip\" removed from ban list");
$output .= "IP \"$ip\" removed from ban list\n";
break;
case "add":
case "ban":
$ip = trim(implode($params));
$ip = strtolower($params[0]);
$player = $this->server->api->player->get($ip);
if($player instanceof Player){
$ip = $player->ip;
$player->close("banned");
}
$this->bannedIPs->set($ip);
$this->bannedIPs->save();
console("[INFO] IP \"$ip\" added to ban list");
$output .= "IP \"$ip\" added to ban list\n";
break;
case "reload":
$this->bannedIPs = new Config(FILE_PATH."banned-ips.txt", CONFIG_LIST);
$this->bannedIPs = new Config(DATA_PATH."banned-ips.txt", CONFIG_LIST);
break;
case "list":
console("[INFO] IP ban list: ".implode(", ", $this->bannedIPs->getAll(true)));
$output .= "IP ban list: ".implode(", ", $this->bannedIPs->getAll(true))."\n";
break;
default:
console("[INFO] Usage: /banip <add | remove | list | reload> [IP]");
$output .= "Usage: /banip <add|remove|list|reload> [IP|player]\n";
break;
}
break;
@ -134,57 +238,67 @@ class BanAPI{
switch($p){
case "pardon":
case "remove":
$user = trim(implode($params));
$user = strtolower($params[0]);
$this->banned->remove($user);
$this->banned->save();
console("[INFO] Player \"$user\" removed from ban list");
$output .= "Player \"$user\" removed from ban list\n";
break;
case "add":
case "ban":
$user = trim(implode($params));
$user = strtolower($params[0]);
$this->banned->set($user);
$this->banned->save();
$player = $this->server->api->player->get($user);
if($player !== false){
$player->close("You have been banned");
}
$this->server->api->chat->broadcast("$user has been banned");
console("[INFO] Player \"$user\" added to ban list");
if($issuer instanceof Player){
$this->server->api->chat->broadcast($user." has been banned by ".$issuer->username."\n");
}else{
$this->server->api->chat->broadcast($user." has been banned\n");
}
$this->kick($user, "Banned");
$output .= "Player \"$user\" added to ban list\n";
break;
case "reload":
$this->banned = new Config(FILE_PATH."banned.txt", CONFIG_LIST);
$this->banned = new Config(DATA_PATH."banned.txt", CONFIG_LIST);
break;
case "list":
console("[INFO] Ban list: ".implode(", ", $this->banned->getAll(true)));
$output .= "Ban list: ".implode(", ", $this->banned->getAll(true))."\n";
break;
default:
console("[INFO] Usage: /ban <add | remove | list | reload> [player]");
$output .= "Usage: /ban <add|remove|list|reload> [username]\n";
break;
}
break;
}
return $output;
}
public function ban($username){
$this->commandHandler("ban", array("add", $username));
$this->commandHandler("ban", array("add", $username), "console", "");
}
public function pardon($username){
$this->commandHandler("ban", array("pardon", $username));
$this->commandHandler("ban", array("pardon", $username), "console", "");
}
public function banIP($ip){
$this->commandHandler("banip", array("add", $ip));
$this->commandHandler("banip", array("add", $ip), "console", "");
}
public function pardonIP($ip){
$this->commandHandler("banip", array("pardon", $ip));
$this->commandHandler("banip", array("pardon", $ip), "console", "");
}
public function kick($username, $reason = "No Reason"){
$this->commandHandler("kick", array($username, $reason), "console", "");
}
public function reload(){
$this->commandHandler("ban", array("reload"));
$this->commandHandler("banip", array("reload"));
$this->commandHandler("whitelist", array("reload"));
$this->commandHandler("ban", array("reload"), "console", "");
$this->commandHandler("banip", array("reload"), "console", "");
$this->commandHandler("whitelist", array("reload"), "console", "");
}
public function isIPBanned($ip){
@ -197,6 +311,7 @@ class BanAPI{
}
public function isBanned($username){
$username = strtolower($username);
if($this->server->api->dhandle("api.ban.check", $username) === false){
return true;
}elseif($this->banned->exists($username)){
@ -206,11 +321,14 @@ class BanAPI{
}
public function inWhitelist($username){
if($this->server->api->dhandle("api.ban.whitelist.check", $ip) === false){
$username = strtolower($username);
if($this->isOp($username)){
return true;
}elseif($this->server->api->dhandle("api.ban.whitelist.check", $username) === false){
return true;
}elseif($this->whitelist->exists($username)){
return true;
}
return false;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,51 +1,123 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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/
*
*
*/
class ChatAPI{
private $server;
function __construct(PocketMinecraftServer $server){
$this->server = $server;
function __construct(){
$this->server = ServerAPI::request();
}
public function init(){
$this->server->api->console->register("tell", "<player> <private message ...>", array($this, "commandHandler"));
$this->server->api->console->register("me", "<action ...>", array($this, "commandHandler"));
$this->server->api->console->register("say", "<message ...>", array($this, "commandHandler"));
$this->server->api->ban->cmdWhitelist("tell");
$this->server->api->ban->cmdWhitelist("me");
}
public function commandHandler($cmd, $params, $issuer, $alias){
$output = "";
switch($cmd){
case "say":
$s = implode(" ", $params);
if(trim($s) == ""){
$output .= "Usage: /say <message>\n";
break;
}
$sender = ($issuer instanceof Player) ? "Server":ucfirst($issuer);
$this->server->api->chat->broadcast("[$sender] ".$s);
break;
case "me":
if(!($issuer instanceof Player)){
if($issuer === "rcon"){
$sender = "Rcon";
}else{
$sender = ucfirst($issuer);
}
}else{
$sender = $issuer->username;
}
$this->broadcast("* $sender ".implode(" ", $params));
break;
case "tell":
if(!isset($params[0]) or !isset($params[1])){
$output .= "Usage: /$cmd <player> <message>\n";
break;
}
if(!($issuer instanceof Player)){
$sender = ucfirst($issuer);
}else{
$sender = $issuer->username;
}
$n = array_shift($params);
$target = $this->server->api->player->get($n);
if($target instanceof Player){
$target = $target->username;
}else{
$target = strtolower($n);
if($t === "server" or $t === "console" or $t === "rcon"){
$target = "Console";
}
}
$mes = implode(" ", $params);
$output .= "[me -> ".$target."] ".$mes."\n";
if($target !== "Console" and $target !== "Rcon"){
$this->sendTo(false, "[".$sender." -> me] ".$mes, $target);
}
console("[INFO] [".$sender." -> ".$target."] ".$mes);
break;
}
return $output;
}
public function broadcast($message){
$this->send(false, $message);
}
public function sendTo($owner, $text, $player){
$this->send($owner, $text, array($player));
}
public function send($owner, $text, $whitelist = false, $blacklist = false){
$message = "";
$message = array(
"player" => $owner,
"message" => $text,
);
if($owner !== false){
$message = "<".$owner."> ";
if($owner instanceof Player){
if($whitelist === false){
console("[INFO] <".$owner->username."> ".$text);
}
}else{
if($whitelist === false){
console("[INFO] <".$owner."> ".$text);
}
}
}else{
if($whitelist === false){
console("[INFO] $text");
}
$message["player"] = "";
}
$message .= $text;
console("[CHAT] ".$message);
$this->server->handle("server.chat", new Container($message, $whitelist, $blacklist));
}
}

View File

@ -1,148 +1,154 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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/
*
*
*/
class ConsoleAPI{
private $loop, $server, $event, $help, $cmds;
function __construct(PocketMinecraftServer $server){
private $loop, $server, $event, $help, $cmds, $alias;
function __construct(){
$this->help = array();
$this->cmds = array();
$this->server = $server;
$this->alias = array();
$this->server = ServerAPI::request();
$this->last = microtime(true);
}
public function init(){
$this->event = $this->server->event("server.tick", array($this, "handle"));
$this->loop = new ConsoleLoop;
$this->loop->start();
$this->server->schedule(2, array($this, "handle"), array(), true);
if(!defined("NO_THREADS")){
$this->loop = new ConsoleLoop();
}
$this->register("help", "[page|command name]", array($this, "defaultCommands"));
$this->register("status", "", array($this, "defaultCommands"));
$this->register("difficulty", "<0|1|2|3>", array($this, "defaultCommands"));
$this->register("stop", "", array($this, "defaultCommands"));
$this->register("defaultgamemode", "<mode>", array($this, "defaultCommands"));
$this->server->api->ban->cmdWhitelist("help");
}
function __destruct(){
$this->server->deleteEvent($this->event);
$this->loop->stop = true;
$this->loop->notify();
$this->loop->join();
if(!defined("NO_THREADS")){
$this->loop->stop();
$this->loop->notify();
//$this->loop->join();
}
}
public function defaultCommands($cmd, $params){
switch($cmd){
case "crash": //Crashes the server to generate an report
$this->callNotDefinedMethodCrash();
$this->server->api->server; //Access a private property
callNotExistingFunction();
break;
case "invisible":
$p = strtolower(array_shift($params));
switch($p){
case "on":
case "true":
case "1":
console("[INFO] Server is invisible");
$this->server->api->setProperty("invisible", true);
public function defaultCommands($cmd, $params, $issuer, $alias){
$output = "";
switch($cmd){
case "defaultgamemode":
$gms = array(
"0" => SURVIVAL,
"survival" => SURVIVAL,
"s" => SURVIVAL,
"1" => CREATIVE,
"creative" => CREATIVE,
"c" => CREATIVE,
"2" => ADVENTURE,
"adventure" => ADVENTURE,
"a" => ADVENTURE,
"3" => VIEW,
"view" => VIEW,
"viewer" => VIEW,
"spectator" => VIEW,
"v" => VIEW,
);
if(!isset($gms[strtolower($params[0])])){
$output .= "Usage: /$cmd <mode>\n";
break;
case "off":
case "false":
case "0":
console("[INFO] Server is visible");
$this->server->api->setProperty("invisible", false);
}
$this->server->api->setProperty("gamemode", $gms[strtolower($params[0])]);
$output .= "Default Gamemode is now ".strtoupper($this->server->getGamemode()).".\n";
break;
case "status":
if(!($issuer instanceof Player) and $issuer === "console"){
$this->server->debugInfo(true);
}
$info = $this->server->debugInfo();
$output .= "TPS: ".$info["tps"].", Memory usage: ".$info["memory_usage"]." (Peak ".$info["memory_peak_usage"].")\n";
break;
case "update-done":
$this->server->api->setProperty("last-update", time());
break;
case "stop":
$this->loop->stop = true;
$output .= "Stopping the server\n";
$this->server->close();
break;
case "difficulty":
$s = trim(array_shift($params));
if($s === "" or (((int) $s) > 3 and ((int) $s) < 0)){
$output .= "Usage: /difficulty <0|1|2|3>\n";
break;
default:
console("[INFO] Usage: /invisible <on | off>");
}
$this->server->api->setProperty("difficulty", (int) $s);
$output .= "Difficulty changed to ".$this->server->difficulty."\n";
break;
case "?":
if($issuer !== "console" and $issuer !== "rcon"){
break;
}
break;
case "status":
case "lag":
$info = $this->server->debugInfo();
console("[INFO] TPS: ".$info["tps"].", Memory usage: ".$info["memory_usage"]." (Peak ".$info["memory_peak_usage"].")");
break;
case "update-done":
$this->server->api->setProperty("last-update", time());
break;
case "stop":
$this->loop->stop = true;
console("[INFO] Stopping the server...");
$this->server->close();
break;
case "gamemode":
$s = trim(array_shift($params));
if($s == "" or (((int) $s) !== 0 and ((int) $s) !== 1)){
console("[INFO] Usage: /gamemode <0 | 1>");
}
case "help":
if(isset($params[0]) and !is_numeric($params[0])){
$c = trim(strtolower($params[0]));
if(isset($this->help[$c]) or isset($this->alias[$c])){
$c = isset($this->help[$c]) ? $c : $this->alias[$c];
if($this->server->api->dhandle("console.command.".$c, array("cmd" => $c, "parameters" => array(), "issuer" => $issuer, "alias" => false)) === false or $this->server->api->dhandle("console.command", array("cmd" => $c, "parameters" => array(), "issuer" => $issuer, "alias" => false)) === false){
break;
}
$output .= "Usage: /$c ".$this->help[$c]."\n";
break;
}
}
$cmds = array();
foreach($this->help as $c => $h){
if($this->server->api->dhandle("console.command.".$c, array("cmd" => $c, "parameters" => array(), "issuer" => $issuer, "alias" => false)) === false or $this->server->api->dhandle("console.command", array("cmd" => $c, "parameters" => array(), "issuer" => $issuer, "alias" => false)) === false){
continue;
}
$cmds[$c] = $h;
}
$max = ceil(count($cmds) / 5);
$page = (int) (isset($params[0]) ? min($max, max(1, intval($params[0]))):1);
$output .= "- Showing help page $page of $max (/help <page>) -\n";
$current = 1;
foreach($cmds as $c => $h){
$curpage = (int) ceil($current / 5);
if($curpage === $page){
$output .= "/$c ".$h."\n";
}elseif($curpage > $page){
break;
}
++$current;
}
break;
}
$this->server->api->setProperty("gamemode", (int) $s);
console("[INFO] Gamemode changed to ".$this->server->gamemode);
break;
case "difficulty":
$s = trim(array_shift($params));
if($s == "" or (((int) $s) !== 0 and ((int) $s) !== 1)){
console("[INFO] Usage: /difficulty <0 | 1>");
default:
$output .= "Command doesn't exist! Use /help\n";
break;
}
$this->server->api->setProperty("difficulty", (int) $s);
console("[INFO] Difficulty changed to ".$this->server->difficulty);
loadConfig(true);
break;
case "say":
$s = implode(" ", $params);
if(trim($s) == ""){
console("[INFO] Usage: /say <message>");
break;
}
$this->server->api->chat->broadcast($s);
break;
case "save-all":
$this->server->save();
break;
case "help":
case "?":
console("[INFO] /help: Show available commands");
console("[INFO] /status: Show server TPS and memory usage");
console("[INFO] /gamemode: Changes default gamemode");
console("[INFO] /difficulty: Changes difficulty");
console("[INFO] /invisible: Manages server visibility");
console("[INFO] /say: Broadcasts mesages");
console("[INFO] /save-all: Saves pending changes");
console("[INFO] /stop: Stops the server");
//console("[INFO] /restart: Restarts the server");
foreach($this->help as $c => $h){
console("[INFO] /$c: ".$h);
}
break;
default:
console("[ERROR] Command doesn't exist! Use /help");
break;
}
}
return $output;
}
public function alias($alias, $cmd){
if(!isset($this->cmds[$cmd])){
return false;
}
$this->cmds[strtolower(trim($alias))] = &$this->cmds[$cmd];
$this->alias[strtolower(trim($alias))] = trim($cmd);
return true;
}
@ -153,26 +159,112 @@ class ConsoleAPI{
$cmd = strtolower(trim($cmd));
$this->cmds[$cmd] = $callback;
$this->help[$cmd] = $help;
ksort($this->help, SORT_NATURAL | SORT_FLAG_CASE);
}
public function run($line = ""){
public function run($line = "", $issuer = "console", $alias = false){
if($line != ""){
$params = explode(" ", $line);
$cmd = strtolower(array_shift($params));
console("[INFO] Issued server command: /$cmd ".implode(" ", $params));
if(isset($this->cmds[$cmd]) and is_callable($this->cmds[$cmd])){
call_user_func($this->cmds[$cmd], $cmd, $params);
}elseif($this->server->api->dhandle("api.console.command", array("cmd" => $cmd, "params" => $params)) !== false){
$this->defaultCommands($cmd, $params);
$output = "";
$end = strpos($line, " ");
if($end === false){
$end = strlen($line);
}
$cmd = strtolower(substr($line, 0, $end));
$params = (string) substr($line, $end + 1);
if(isset($this->alias[$cmd])){
return $this->run($this->alias[$cmd] . ($params !== "" ? " " .$params:""), $issuer, $cmd);
}
if($issuer instanceof Player){
console("[DEBUG] \x1b[33m".$issuer->username."\x1b[0m issued server command: ".ltrim("$alias ")."/$cmd ".$params, true, true, 2);
}else{
console("[DEBUG] \x1b[33m*".$issuer."\x1b[0m issued server command: ".ltrim("$alias ")."/$cmd ".$params, true, true, 2);
}
if(preg_match_all('#@([@a-z]{1,})#', $params, $matches, PREG_OFFSET_CAPTURE) > 0){
$offsetshift = 0;
foreach($matches[1] as $selector){
if($selector[0]{0} === "@"){ //Escape!
$params = substr_replace($params, $selector[0], $selector[1] + $offsetshift - 1, strlen($selector[0]) + 1);
--$offsetshift;
continue;
}
switch(strtolower($selector[0])){
case "u":
case "player":
case "username":
$p = ($issuer instanceof Player) ? $issuer->username:$issuer;
$params = substr_replace($params, $p, $selector[1] + $offsetshift - 1, strlen($selector[0]) + 1);
$offsetshift -= strlen($selector[0]) - strlen($p) + 1;
break;
case "w":
case "world":
$p = ($issuer instanceof Player) ? $issuer->level->getName():$this->server->api->level->getDefault()->getName();
$params = substr_replace($params, $p, $selector[1] + $offsetshift - 1, strlen($selector[0]) + 1);
$offsetshift -= strlen($selector[0]) - strlen($p) + 1;
break;
case "a":
case "all":
$output = "";
foreach($this->server->api->player->getAll() as $p){
$output .= $this->run($cmd . " ". substr_replace($params, $p->username, $selector[1] + $offsetshift - 1, strlen($selector[0]) + 1), $issuer, $alias);
}
return $output;
case "r":
case "random":
$l = array();
foreach($this->server->api->player->getAll() as $p){
if($p !== $issuer){
$l[] = $p;
}
}
if(count($l) === 0){
return;
}
$p = $l[mt_rand(0, count($l) - 1)]->username;
$params = substr_replace($params, $p, $selector[1] + $offsetshift - 1, strlen($selector[0]) + 1);
$offsetshift -= strlen($selector[0]) - strlen($p) + 1;
break;
}
}
}
$params = explode(" ", $params);
if(count($params) === 1 and $params[0] === ""){
$params = array();
}
if(($d1 = $this->server->api->dhandle("console.command.".$cmd, array("cmd" => $cmd, "parameters" => $params, "issuer" => $issuer, "alias" => $alias))) === false
or ($d2 = $this->server->api->dhandle("console.command", array("cmd" => $cmd, "parameters" => $params, "issuer" => $issuer, "alias" => $alias))) === false){
$output = "You don't have permissions to use this command.\n";
}elseif($d1 !== true and $d2 !== true){
if(isset($this->cmds[$cmd]) and is_callable($this->cmds[$cmd])){
$output = @call_user_func($this->cmds[$cmd], $cmd, $params, $issuer, $alias);
}elseif($this->server->api->dhandle("console.command.unknown", array("cmd" => $cmd, "params" => $params, "issuer" => $issuer, "alias" => $alias)) !== false){
$output = $this->defaultCommands($cmd, $params, $issuer, $alias);
}
}
if($output != "" and ($issuer instanceof Player)){
$issuer->sendChat(trim($output));
}
return $output;
}
}
public function handle($time){
if(defined("NO_THREADS")){
return;
}
if($this->loop->line !== false){
$line = trim($this->loop->line);
$this->loop->line = false;
$this->run($line);
$output = $this->run($line, "console");
if($output != ""){
$mes = explode("\n", trim($output));
foreach($mes as $m){
console("[CMD] ".$m);
}
}
}else{
$this->loop->notify();
}
@ -181,19 +273,47 @@ class ConsoleAPI{
}
class ConsoleLoop extends Thread{
public $line, $stop;
public $line;
public $stop;
public $base;
public $ev;
public $fp;
public function __construct(){
$this->line = false;
$this->stop = false;
$this->start();
}
public function stop(){
$this->stop = true;
}
private function readLine(){
if($this->fp){
$line = trim(fgets($this->fp));
}else{
$line = trim(readline(""));
if($line != ""){
readline_add_history( $line );
}
}
return $line;
}
public function run(){
$fp = fopen("php://stdin", "r");
while($this->stop === false and ($line = fgets($fp)) !== false){
$this->line = $line;
if(!extension_loaded("readline")){
$this->fp = fopen( "php://stdin", "r" );
}
while($this->stop === false){
$this->line = $this->readLine();
$this->wait();
$this->line = false;
}
if(!$this->haveReadline){
@fclose($fp);
}
exit(0);
}
}
}

View File

@ -1,102 +1,172 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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/
*
*
*/
class EntityAPI{
private $server;
function __construct(PocketMinecraftServer $server){
$this->server = $server;
private $entities;
private $eCnt = 1;
function __construct(){
$this->entities = array();
$this->server = ServerAPI::request();
}
public function get($eid){
if(isset($this->server->entities[$eid])){
return $this->server->entities[$eid];
if(isset($this->entities[$eid])){
return $this->entities[$eid];
}
return false;
}
public function init(){
$this->server->schedule(25, array($this, "updateEntities"), array(), true);
}
public function updateEntities(){
$l = $this->server->query("SELECT EID FROM entities WHERE hasUpdate = 1;");
if($l !== false and $l !== true){
while(($e = $l->fetchArray(SQLITE3_ASSOC)) !== false){
$e = $this->get($e["EID"]);
if($e instanceof Entity){
$e->update();
$this->server->query("UPDATE entities SET hasUpdate = 0 WHERE EID = ".$e->eid.";");
}
}
}
}
public function updateRadius(Position $center, $radius = 15, $class = false){
$this->server->query("UPDATE entities SET hasUpdate = 1 WHERE level = '".$center->level->getName()."' ".($class !== false ? "AND class = $class ":"")."AND abs(x - {$center->x}) <= $radius AND abs(y - {$center->y}) <= $radius AND abs(z - {$center->z}) <= $radius;");
}
public function getAll(){
return $this->server->entities;
public function getRadius(Position $center, $radius = 15, $class = false){
$entities = array();
$l = $this->server->query("SELECT EID FROM entities WHERE level = '".$center->level->getName()."' ".($class !== false ? "AND class = $class ":"")."AND abs(x - {$center->x}) <= $radius AND abs(y - {$center->y}) <= $radius AND abs(z - {$center->z}) <= $radius;");
if($l !== false and $l !== true){
while(($e = $l->fetchArray(SQLITE3_ASSOC)) !== false){
$e = $this->get($e["EID"]);
if($e instanceof Entity){
$entities[$e->eid] = $e;
}
}
}
return $entities;
}
public function getAll($level = null){
if($level instanceof Level){
$entities = array();
$l = $this->server->query("SELECT EID FROM entities WHERE level = '".$level->getName()."';");
if($l !== false and $l !== true){
while(($e = $l->fetchArray(SQLITE3_ASSOC)) !== false){
$e = $this->get($e["EID"]);
if($e instanceof Entity){
$entities[$e->eid] = $e;
}
}
}
return $entities;
}
return $this->entities;
}
public function heal($eid, $heal = 1, $cause){
$this->harm($eid, -$heal, $cause);
}
public function harm($eid, $attack = 1, $cause){
public function harm($eid, $attack = 1, $cause, $force = false){
$e = $this->get($eid);
if($e === false or $e->dead === true){
return false;
}
$e->setHealth($e->getHealth() - $attack, $cause);
$e->setHealth($e->getHealth() - $attack, $cause, $force);
}
public function add($class, $type = 0, $data = array()){
$eid = $this->server->eidCnt++;
$this->server->entities[$eid] = new Entity($this->server, $eid, $class, $type, $data);
$this->server->handle("entity.add", $this->server->entities[$eid]);
return $this->server->entities[$eid];
public function add(Level $level, $class, $type = 0, $data = array()){
$eid = $this->eCnt++;
$this->entities[$eid] = new Entity($level, $eid, $class, $type, $data);
$this->server->handle("entity.add", $this->entities[$eid]);
return $this->entities[$eid];
}
public function spawnTo($eid, $player){
$e = $this->get($eid);
if($e === false){
return false;
public function spawnToAll(Entity $e){
foreach($this->server->api->player->getAll($e->level) as $player){
if($player->eid !== false and $player->eid !== $e->eid and $e->class !== ENTITY_PLAYER){
$e->spawn($player);
}
}
}
public function drop(Position $pos, Item $item){
if($item->getID() === AIR or $item->count <= 0){
return;
}
$data = array(
"x" => $pos->x + mt_rand(-10, 10) / 50,
"y" => $pos->y + 0.19,
"z" => $pos->z + mt_rand(-10, 10) / 50,
//"speedX" => mt_rand(-3, 3) / 8,
"speedY" => mt_rand(5, 8) / 2,
//"speedZ" => mt_rand(-3, 3) / 8,
"item" => $item,
);
if($this->server->api->handle("item.drop", $data) !== false){
for($count = $item->count; $count > 0; ){
$item->count = min($item->getMaxStackSize(), $count);
$count -= $item->count;
$e = $this->add($pos->level, ENTITY_ITEM, $item->getID(), $data);
$this->spawnToAll($e);
$this->server->api->handle("entity.motion", $e);
}
}
$e->spawn($player);
}
public function spawnToAll($eid){
$e = $this->get($eid);
if($e === false){
return false;
}
foreach($this->server->api->player->getAll() as $player){
if($player->eid !== false){
public function spawnAll(Player $player){
foreach($this->getAll($player->level) as $e){
if($e->class !== ENTITY_PLAYER){
$e->spawn($player);
}
}
}
public function spawnAll($player){
foreach($this->getAll() as $e){
$e->spawn($player);
}
}
public function remove($eid){
if(isset($this->server->entities[$eid])){
$entity = $this->server->entities[$eid];
unset($this->server->entities[$eid]);
$this->server->query("DELETE FROM entities WHERE EID = ".$entity->eid.";");
if(isset($this->entities[$eid])){
$entity = $this->entities[$eid];
$this->entities[$eid] = null;
unset($this->entities[$eid]);
$entity->closed = true;
$this->server->query("DELETE FROM entities WHERE EID = ".$eid.";");
if($entity->class === ENTITY_PLAYER){
$this->server->api->player->broadcastPacket($this->server->api->player->getAll(), MC_REMOVE_PLAYER, array(
"clientID" => 0,
"eid" => $entity->eid,
));
}else{
$this->server->api->player->broadcastPacket($this->server->api->player->getAll($entity->level), MC_REMOVE_ENTITY, array(
"eid" => $entity->eid,
));
}
$this->server->api->dhandle("entity.remove", $entity);
$entity = null;
unset($entity);
}
}

View File

@ -1,134 +1,240 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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/
*
*
*/
class LevelAPI{
private $server, $map;
function __construct(PocketMinecraftServer $server){
$this->server = $server;
$this->map = $this->server->map;
$this->heightMap = array_fill(0, 256, array());
private $server, $levels, $default;
public function __construct(){
$this->server = ServerAPI::request();
$this->levels = array();
}
public function get($name){
if(isset($this->levels[$name])){
return $this->levels[$name];
}
return false;
}
public function getDefault(){
return $this->levels[$this->default];
}
public function init(){
$this->server->event("player.block.break", array($this, "handle"));
$this->server->event("player.block.place", array($this, "handle"));
$this->server->event("player.block.update", array($this, "handle"));
$this->server->api->console->register("seed", "[world]", array($this, "commandHandler"));
$this->server->api->console->register("save-all", "", array($this, "commandHandler"));
$this->server->api->console->register("save-on", "", array($this, "commandHandler"));
$this->server->api->console->register("save-off", "", array($this, "commandHandler"));
$this->default = $this->server->api->getProperty("level-name");
if($this->loadLevel($this->default) === false){
$this->generateLevel($this->default, $this->server->seed);
$this->loadLevel($this->default);
}
$this->server->spawn = $this->getDefault()->getSafeSpawn();
}
public function commandHandler($cmd, $params, $issuer, $alias){
$output = "";
switch($cmd){
case "save-all":
$save = $this->server->saveEnabled;
$this->server->saveEnabled = true;
$this->saveAll();
$this->server->saveEnabled = $save;
break;
case "save-on":
$this->server->saveEnabled = true;
break;
case "save-off":
$this->server->saveEnabled = false;
break;
case "seed":
if(!isset($params[0]) and ($issuer instanceof Player)){
$output .= "Seed: ".$issuer->level->getSeed()."\n";
}elseif(isset($params[0])){
if(($lv = $this->server->api->level->get(trim(implode(" ", $params)))) !== false){
$output .= "Seed: ".$lv->getSeed()."\n";
}
}else{
$output .= "Seed: ".$this->server->api->level->getDefault()->getSeed()."\n";
}
}
return $output;
}
public function generateLevel($name, $seed = false, $generator = false){
if($this->levelExists($name)){
return false;
}
$options = array();
if($this->server->api->getProperty("generator-settings") !== false and trim($this->server->api->getProperty("generator-settings")) != ""){
$options["preset"] = $this->server->api->getProperty("generator-settings");
}
if($generator !== false and class_exists($generator)){
$generator = new $generator($options);
}else{
if(strtoupper($this->server->api->getProperty("level-type")) == "FLAT"){
$generator = new SuperflatGenerator($options);
}else{
$generator = new TemporalGenerator($options);
}
}
$gen = new WorldGenerator($generator, $name, $seed === false ? Utils::readInt(Utils::getRandomBytes(4, false)):(int) $seed);
$gen->generate();
$gen->close();
return true;
}
public function levelExists($name){
if($name === ""){
return false;
}
$path = DATA_PATH."worlds/".$name."/";
if($this->get($name) === false and !file_exists($path."level.pmf")){
$level = new LevelImport($path);
if($level->import() === false){
return false;
}
}
return true;
}
public function unloadLevel(Level $level, $force = false){
$name = $level->getName();
if($name === $this->default and $force !== true){
return false;
}
console("[INFO] Unloading level \"".$name."\"");
$level->nextSave = PHP_INT_MAX;
$level->save();
foreach($this->server->api->player->getAll($level) as $player){
$player->teleport($this->server->spawn);
}
foreach($this->server->api->entity->getAll($level) as $entity){
if($entity->class !== ENTITY_PLAYER){
$entity->close();
}
}
foreach($this->server->api->tile->getAll($level) as $tile){
$tile->close();
}
$level->close();
unset($this->levels[$name]);
return true;
}
public function loadLevel($name){
if($this->get($name) !== false){
return true;
}elseif($this->levelExists($name) === false){
console("[NOTICE] Level \"".$name."\" not found");
return false;
}
$path = DATA_PATH."worlds/".$name."/";
console("[INFO] Preparing level \"".$name."\"");
$level = new PMFLevel($path."level.pmf");
$entities = new Config($path."entities.yml", CONFIG_YAML);
if(file_exists($path."tileEntities.yml")){
@rename($path."tileEntities.yml", $path."tiles.yml");
}
$tiles = new Config($path."tiles.yml", CONFIG_YAML);
$blockUpdates = new Config($path."bupdates.yml", CONFIG_YAML);
$this->levels[$name] = new Level($level, $entities, $tiles, $blockUpdates, $name);
foreach($entities->getAll() as $entity){
if(!isset($entity["id"])){
break;
}
if($entity["id"] === 64){ //Item Drop
$e = $this->server->api->entity->add($this->levels[$name], ENTITY_ITEM, $entity["Item"]["id"], array(
"meta" => $entity["Item"]["Damage"],
"stack" => $entity["Item"]["Count"],
"x" => $entity["Pos"][0],
"y" => $entity["Pos"][1],
"z" => $entity["Pos"][2],
"yaw" => $entity["Rotation"][0],
"pitch" => $entity["Rotation"][1],
));
}elseif($entity["id"] === FALLING_SAND){
$e = $this->server->api->entity->add($this->levels[$name], ENTITY_FALLING, $entity["id"], $entity);
$e->setPosition(new Vector3($entity["Pos"][0], $entity["Pos"][1], $entity["Pos"][2]), $entity["Rotation"][0], $entity["Rotation"][1]);
$e->setHealth($entity["Health"]);
}elseif($entity["id"] === OBJECT_PAINTING or $entity["id"] === OBJECT_ARROW){ //Painting
$e = $this->server->api->entity->add($this->levels[$name], ENTITY_OBJECT, $entity["id"], $entity);
$e->setPosition(new Vector3($entity["Pos"][0], $entity["Pos"][1], $entity["Pos"][2]), $entity["Rotation"][0], $entity["Rotation"][1]);
$e->setHealth(1);
}else{
$e = $this->server->api->entity->add($this->levels[$name], ENTITY_MOB, $entity["id"], $entity);
$e->setPosition(new Vector3($entity["Pos"][0], $entity["Pos"][1], $entity["Pos"][2]), $entity["Rotation"][0], $entity["Rotation"][1]);
$e->setHealth($entity["Health"]);
}
}
foreach($tiles->getAll() as $tile){
if(!isset($tile["id"])){
break;
}
$t = $this->server->api->tile->add($this->levels[$name], $tile["id"], $tile["x"], $tile["y"], $tile["z"], $tile);
}
$timeu = microtime(true);
foreach($blockUpdates->getAll() as $bupdate){
$this->server->api->block->scheduleBlockUpdate(new Position((int) $bupdate["x"],(int) $bupdate["y"],(int) $bupdate["z"], $this->levels[$name]), (float) $bupdate["delay"], (int) $bupdate["type"]);
}
return true;
}
public function handle($data, $event){
switch($event){
case "player.block.place":
case "player.block.update":
console("[DEBUG] EID ".$data["eid"]." placed ".$data["block"].":".$data["meta"]." at X ".$data["x"]." Y ".$data["y"]." Z ".$data["z"], true, true, 2);
$this->setBlock($data["x"], $data["y"], $data["z"], $data["block"], $data["meta"]);
break;
case "player.block.break":
$block = $this->getBlock($data["x"], $data["y"], $data["z"]);
console("[DEBUG] EID ".$data["eid"]." broke ".$block[0].":".$block[1]." at X ".$data["x"]." Y ".$data["y"]." Z ".$data["z"], true, true, 2);
if($block[0] === 0){
break;
}
$this->setBlock($data["x"], $data["y"], $data["z"], 0, 0);
break;
}
}
public function saveAll(){
foreach($this->levels as $level){
$level->save();
}
}
public function __destruct(){
$this->saveAll();
foreach($this->levels as $level){
$this->unloadLevel($level, true);
}
}
public function getSpawn(){
return $this->server->spawn;
}
public function getChunk($X, $Z){
return $this->map->map[$X][$Z];
}
public function getBlockFace($block, $face){
$data = array("x" => $block[2][0], "y" => $block[2][1], "z" => $block[2][2]);
BlockFace::setPosition($data, $face);
return $this->getBlock($data["x"], $data["y"], $data["z"]);
}
public function getBlock($x, $y, $z){
$b = $this->map->getBlock($x, $y, $z);
$b[2] = array($x, $y, $z);
return $b;
}
public function getFloor($x, $z){
if(!isset($this->heightMap[$z][$x])){
$this->heightMap[$z][$x] = $this->map->getFloor($x, $z);
}
return $this->heightMap[$z][$x];
}
public function setBlock($x, $y, $z, $block, $meta = 0, $update = true){
if($x < 0 or $y < 0 or $z < 0){
return false;
}
$this->map->setBlock($x, $y, $z, $block, $meta);
$this->heightMap[$z][$x] = $this->map->getFloor($x, $z);
if($this->server->api->dhandle("block.change", array(
"x" => $x,
"y" => $y,
"z" => $z,
"block" => $block,
"meta" => $meta,
)) !== false){
if($update === true){
$this->server->api->block->updateBlock($x, $y, $z, BLOCK_UPDATE_NORMAL);
$this->server->api->block->updateBlocksAround($x, $y, $z, BLOCK_UPDATE_NORMAL);
public function loadMap(){
if($this->mapName !== false and trim($this->mapName) !== ""){
if(!file_exists($this->mapDir."level.pmf")){
$level = new LevelImport($this->mapDir);
$level->import();
}
$this->level = new PMFLevel($this->mapDir."level.pmf");
console("[INFO] Preparing level \"".$this->level->getData("name")."\"");
$this->time = (int) $this->level->getData("time");
$this->seed = (int) $this->level->getData("seed");
$this->spawn = $this->level->getSpawn();
}
return true;
}
public function getOrderedChunk($X, $Z, $columnsPerPacket = 2){
$columnsPerPacket = max(1, (int) $columnsPerPacket);
$c = $this->getChunk($X, $Z);
$ordered = array();
$i = 0;
$cnt = 0;
$ordered[$i] = "";
for($z = 0; $z < 16; ++$z){
for($x = 0; $x < 16; ++$x){
if($cnt >= $columnsPerPacket){
++$i;
$ordered[$i] = str_repeat("\x00", $i * $columnsPerPacket);
$cnt = 0;
}
$ordered[$i] .= "\xff";
$block = $this->map->getChunkColumn($X, $Z, $x, $z, 0);
$meta = $this->map->getChunkColumn($X, $Z, $x, $z, 1);
for($k = 0; $k < 8; ++$k){
$ordered[$i] .= substr($block, $k << 4, 16);
$ordered[$i] .= substr($meta, $k << 3, 8);
}
++$cnt;
}
}
return $ordered;
}
}

View File

@ -1,179 +1,341 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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/
*
*
*/
class PlayerAPI{
private $server;
function __construct(PocketMinecraftServer $server){
$this->server = $server;
function __construct(){
$this->server = ServerAPI::request();
}
public function init(){
$this->server->addHandler("server.regeneration", array($this, "handle"));
$this->server->schedule(20 * 15, array($this, "handle"), 1, true, "server.regeneration");
$this->server->addHandler("player.death", array($this, "handle"), 1);
$this->server->api->console->register("list", "Shows connected player list", array($this, "commandHandler"));
$this->server->api->console->register("kill", "Kills a player", array($this, "commandHandler"));
$this->server->api->console->register("tppos", "Teleports a player to a position", array($this, "commandHandler"));
$this->server->api->console->register("tp", "Teleports a player to another player", array($this, "commandHandler"));
$this->server->api->console->register("list", "", array($this, "commandHandler"));
$this->server->api->console->register("kill", "<player>", array($this, "commandHandler"));
$this->server->api->console->register("gamemode", "<mode> [player]", array($this, "commandHandler"));
$this->server->api->console->register("tp", "[target player] <destination player|w:world> OR /tp [target player] <x> <y> <z>", array($this, "commandHandler"));
$this->server->api->console->register("spawnpoint", "[player] [x] [y] [z]", array($this, "commandHandler"));
$this->server->api->console->register("spawn", "", array($this, "commandHandler"));
$this->server->api->console->register("ping", "", array($this, "commandHandler"));
$this->server->api->console->alias("lag", "ping");
$this->server->api->console->alias("suicide", "kill");
$this->server->api->console->alias("tppos", "tp");
$this->server->api->ban->cmdWhitelist("list");
$this->server->api->ban->cmdWhitelist("ping");
$this->server->api->ban->cmdWhitelist("spawn");
$this->server->preparedSQL->selectPlayersToHeal = $this->server->database->prepare("SELECT EID FROM entities WHERE class = ".ENTITY_PLAYER." AND health < 20;");
}
public function handle($data, $event){
switch($event){
case "server.regeneration":
$result = $this->server->query("SELECT EID FROM players WHERE EID = (SELECT EID FROM entities WHERE health < 20);");
if($result !== true and $result !== false){
while(false !== ($player = $result->fetchArray())){
if(($player = $this->server->api->player->getByEID($player["EID"])) !== false){
$player->entity->setHealth(min(20, $player->entity->getHealth() + $data), "regeneration");
if($this->server->difficulty === 0){
$result = $this->server->preparedSQL->selectPlayersToHeal->execute();
if($result !== false){
while(($player = $result->fetchArray()) !== false){
if(($player = $this->server->api->entity->get($player["EID"])) !== false){
if($player->getHealth() <= 0){
continue;
}
$player->setHealth(min(20, $player->getHealth() + $data), "regeneration");
}
}
return true;
}
}
break;
case "player.death":
$message = $data["name"];
if(is_numeric($data["cause"]) and isset($this->entities[$data["cause"]])){
$e = $this->api->entity->get($data["cause"]);
switch($e->class){
case ENTITY_PLAYER:
$message .= " was killed by ".$e->name;
break;
default:
$message .= " was killed";
break;
if(is_numeric($data["cause"])){
$e = $this->server->api->entity->get($data["cause"]);
if($e instanceof Entity){
switch($e->class){
case ENTITY_PLAYER:
$message = " was killed by ".$e->name;
break;
default:
$message = " was killed";
break;
}
}
}else{
switch($data["cause"]){
case "cactus":
$message = " was pricked to death";
break;
case "lava":
$message = " tried to swim in lava";
break;
case "fire":
$message = " went up in flames";
break;
case "burning":
$message = " burned to death";
break;
case "suffocation":
$message = " suffocated in a wall";
break;
case "water":
$message = " drowned";
break;
case "void":
$message = " fell out of the world";
break;
case "fall":
$message = " hit the ground too hard";
break;
default:
$message .= " was killed";
$message = " died";
break;
}
}
$this->server->chat(false, $message);
$this->server->api->chat->broadcast($data["player"]->username . $message);
return true;
break;
}
}
public function commandHandler($cmd, $params){
public function commandHandler($cmd, $params, $issuer, $alias){
$output = "";
switch($cmd){
case "tp":
$name = array_shift($params);
$target = array_shift($params);
if($name == null or $target == null){
console("[INFO] Usage: /tp <player> <target>");
case "spawnpoint":
if(!($issuer instanceof Player)){
$output .= "Please run this command in-game.\n";
break;
}
if($this->teleport($name, $target)){
console("[INFO] \"$name\" teleported to \"$target\"");
if(count($params) === 1 or count($params) === 4){
$target = $this->server->api->player->get(array_shift($params));
}else{
console("[ERROR] Couldn't teleport");
$target = $issuer;
}
if(!($target instanceof Player)){
$output .= "That player cannot be found.\n";
break;
}
if(count($params) === 3){
$spawn = new Position(floatval(array_shift($params)), floatval(array_shift($params)), floatval(array_shift($params)), $issuer->level);
}else{
$spawn = new Position($issuer->entity->x, $issuer->entity->y, $issuer->entity->z, $issuer->entity->level);
}
$target->setSpawn($spawn);
$output .= "Spawnpoint set correctly!\n";
break;
case "spawn":
if(!($issuer instanceof Player)){
$output .= "Please run this command in-game.\n";
break;
}
$spawn = $issuer->getSpawn();
$issuer->teleport($spawn);
break;
case "ping":
if(!($issuer instanceof Player)){
$output .= "Please run this command in-game.\n";
break;
}
$output .= "ping ".round($issuer->getLag(), 2)."ms, packet loss ".round($issuer->getPacketLoss() * 100, 2)."%, ".round($issuer->getBandwidth() / 1024, 2)." KB/s\n";
break;
case "gamemode":
$player = false;
$gms = array(
"0" => SURVIVAL,
"survival" => SURVIVAL,
"s" => SURVIVAL,
"1" => CREATIVE,
"creative" => CREATIVE,
"c" => CREATIVE,
"2" => ADVENTURE,
"adventure" => ADVENTURE,
"a" => ADVENTURE,
"3" => VIEW,
"view" => VIEW,
"viewer" => VIEW,
"spectator" => VIEW,
"v" => VIEW,
);
if($issuer instanceof Player){
$player = $issuer;
}
if(isset($params[1])){
$player = $this->server->api->player->get($params[1]);
}
if(!($player instanceof Player) or !isset($gms[strtolower($params[0])])){
$output .= "Usage: /$cmd <mode> [player]\n";
break;
}
if($player->setGamemode($gms[strtolower($params[0])])){
$output .= "Gamemode of ".$player->username." changed to ".$player->getGamemode()."\n";
}
break;
case "tppos":
$z = array_pop($params);
$y = array_pop($params);
$x = array_pop($params);
$name = implode(" ", $params);
if($name == null or $x === null or $y === null or $z === null){
console("[INFO] Usage: /tp <player> <x> <y> <z>");
break;
}
if($this->tppos($name, $x, $y, $z)){
console("[INFO] \"$name\" teleported to ($x, $y, $z)");
case "tp":
if(count($params) <= 2 or substr($params[0], 0, 2) === "w:" or substr($params[1], 0, 2) === "w:"){
if((!isset($params[1]) or substr($params[0], 0, 2) === "w:") and isset($params[0]) and ($issuer instanceof Player)){
$name = $issuer->username;
$target = implode(" ", $params);
}elseif(isset($params[1]) and isset($params[0])){
$name = array_shift($params);
$target = implode(" ", $params);
}else{
$output .= "Usage: /$cmd [target player] <destination player>\n";
break;
}
if($this->teleport($name, $target) !== false){
$output .= "\"$name\" teleported to \"$target\"\n";
}else{
$output .= "Couldn't teleport.\n";
}
}else{
console("[ERROR] Couldn't teleport");
if(!isset($params[3]) and isset($params[2]) and isset($params[1]) and isset($params[0]) and ($issuer instanceof Player)){
$name = $issuer->username;
$x = $params[0];
$y = $params[1];
$z = $params[2];
}elseif(isset($params[3]) and isset($params[2]) and isset($params[1]) and isset($params[0])){
$name = $params[0];
$x = $params[1];
$y = $params[2];
$z = $params[3];
}else{
$output .= "Usage: /$cmd [player] <x> <y> <z>\n";
break;
}
if($this->tppos($name, $x, $y, $z)){
$output .= "\"$name\" teleported to ($x, $y, $z)\n";
}else{
$output .= "Couldn't teleport.\n";
}
}
break;
case "kill":
$player = $this->get(implode(" ", $params));
if($player !== false){
$this->server->api->entity->harm($player->eid, 20, "console");
case "suicide":
if(!isset($params[0]) and ($issuer instanceof Player)){
$player = $issuer;
}else{
console("[INFO] Usage: /kill <player>");
$player = $this->get($params[0]);
}
if($player instanceof Player){
$player->entity->harm(1000, "console", true);
$player->sendChat("Ouch. That looks like it hurt.\n");
}else{
$output .= "Usage: /$cmd [player]\n";
}
break;
case "list":
console("[INFO] Player list:");
foreach($this->server->clients as $c){
console("[INFO] ".$c->username." (".$c->ip.":".$c->port."), ClientID ".$c->clientID.", (".round($c->entity->x, 2).", ".round($c->entity->y, 2).", ".round($c->entity->z, 2).")");
$output .= "There are ".count($this->server->clients)."/".$this->server->maxClients." players online:\n";
if(count($this->server->clients) == 0){
break;
}
foreach($this->server->clients as $c){
$output .= $c->username.", ";
}
$output = substr($output, 0, -2)."\n";
break;
}
return $output;
}
public function teleport($name, $target){
$target = $this->get($target);
if($target !== false){
return $this->tppos($name, $target->entity->x, $target->entity->y, $target->entity->z);
public function teleport(&$name, &$target){
if(substr($target, 0, 2) === "w:"){
$lv = $this->server->api->level->get(substr($target, 2));
if($lv instanceof Level){
$origin = $this->get($name);
if($origin instanceof Player){
$name = $origin->username;
return $origin->teleport($lv->getSafeSpawn());
}
}else{
return false;
}
}
$player = $this->get($target);
if(($player instanceof Player) and ($player->entity instanceof Entity)){
$target = $player->username;
$origin = $this->get($name);
if($origin instanceof Player){
$name = $origin->username;
return $origin->teleport($player->entity);
}
}
return false;
}
public function tppos($name, $x, $y, $z){
public function tppos(&$name, &$x, &$y, &$z){
$player = $this->get($name);
if($player !== false){
$player->dataPacket(MC_MOVE_PLAYER, array(
"eid" => 0,
"x" => $x,
"y" => $y,
"z" => $z,
"yaw" => 0,
"pitch" => 0,
));
if(($player instanceof Player) and ($player->entity instanceof Entity)){
$name = $player->username;
$x = $x{0} === "~" ? $player->entity->x + floatval(substr($x, 1)):floatval($x);
$y = $y{0} === "~" ? $player->entity->y + floatval(substr($y, 1)):floatval($y);
$z = $z{0} === "~" ? $player->entity->z + floatval(substr($z, 1)):floatval($z);
$player->teleport(new Vector3($x, $y, $z));
return true;
}
return false;
}
public function get($name){
$CID = $this->server->query("SELECT ip,port FROM players WHERE name = '".str_replace("'", "", $name)."';", true);
$CID = $this->server->clientID($CID["ip"], $CID["port"]);
public function get($name, $alike = true){
$name = trim(strtolower($name));
if($name === ""){
return false;
}
$CID = $this->server->query("SELECT ip,port FROM players WHERE name ".($alike === true ? "LIKE '%".$name."%'":"= '".$name."'").";", true);
$CID = PocketMinecraftServer::clientID($CID["ip"], $CID["port"]);
if(isset($this->server->clients[$CID])){
return $this->server->clients[$CID];
}
return false;
}
public function getAll(){
public function getAll($level = null){
if($level instanceof Level){
$clients = array();
$l = $this->server->query("SELECT EID FROM entities WHERE level = '".$level->getName()."' AND class = '".ENTITY_PLAYER."';");
if($l !== false and $l !== true){
while(($e = $l->fetchArray(SQLITE3_ASSOC)) !== false){
$e = $this->getByEID($e["EID"]);
if($e instanceof Player){
$clients[$e->CID] = $e;
}
}
}
return $clients;
}
return $this->server->clients;
}
public function broadcastPacket(array $players, $id, $data = array()){
$data = new CustomPacketHandler($id, "", $data, true);
$packet = array("raw" => chr($id).$data->raw);
foreach($players as $p){
$p->dataPacket(false, $packet);
}
}
public function getByEID($eid){
$eid = (int) $eid;
$CID = $this->server->query("SELECT ip,port FROM players WHERE EID = '".$eid."';", true);
$CID = $this->server->clientID($CID["ip"], $CID["port"]);
if(isset($this->server->clients[$CID])){
return $this->server->clients[$CID];
}
return false;
}
public function getByClientID($clientID){
$clientID = (int) $clientID;
$CID = $this->server->query("SELECT ip,port FROM players WHERE clientID = '".$clientID."';", true);
$CID = $this->server->clientID($CID["ip"], $CID["port"]);
$CID = PocketMinecraftServer::clientID($CID["ip"], $CID["port"]);
if(isset($this->server->clients[$CID])){
return $this->server->clients[$CID];
}
@ -193,9 +355,54 @@ class PlayerAPI{
public function add($CID){
if(isset($this->server->clients[$CID])){
$player = $this->server->clients[$CID];
console("[INFO] Player \"\x1b[33m".$player->username."\x1b[0m\" connected from \x1b[36m".$player->ip.":".$player->port."\x1b[0m");
$player->data = $this->getOffline($player->username);
$this->server->query("INSERT OR REPLACE INTO players (clientID, ip, port, name) VALUES (".$player->clientID.", '".$player->ip."', ".$player->port.", '".$player->username."');");
$player->gamemode = $player->data->get("gamemode");
if(($player->level = $this->server->api->level->get($player->data->get("position")["level"])) === false){
$player->level = $this->server->api->level->getDefault();
$player->data->set("position", array(
"level" => $player->level->getName(),
"x" => $player->level->getSpawn()->x,
"y" => $player->level->getSpawn()->y,
"z" => $player->level->getSpawn()->z,
));
}
$this->server->query("INSERT OR REPLACE INTO players (CID, ip, port, name) VALUES (".$player->CID.", '".$player->ip."', ".$player->port.", '".strtolower($player->username)."');");
}
}
public function spawnAllPlayers(Player $player){
foreach($this->getAll() as $p){
if($p !== $player and ($p->entity instanceof Entity)){
$p->entity->spawn($player);
if($p->level !== $player->level){
$player->dataPacket(MC_MOVE_ENTITY_POSROT, array(
"eid" => $p->entity->eid,
"x" => -256,
"y" => 128,
"z" => -256,
"yaw" => 0,
"pitch" => 0,
));
}
}
}
}
public function spawnToAllPlayers(Player $player){
foreach($this->getAll() as $p){
if($p !== $player and ($p->entity instanceof Entity)){
$player->entity->spawn($p);
if($p->level !== $player->level){
$p->dataPacket(MC_MOVE_ENTITY_POSROT, array(
"eid" => $player->entity->eid,
"x" => -256,
"y" => 128,
"z" => -256,
"yaw" => 0,
"pitch" => 0,
));
}
}
}
}
@ -204,37 +411,61 @@ class PlayerAPI{
$player = $this->server->clients[$CID];
unset($this->server->clients[$CID]);
$player->close();
$this->saveOffline($player->username, $player->data);
if($player->username != "" and ($player->data instanceof Config)){
$this->saveOffline($player->data);
}
$this->server->query("DELETE FROM players WHERE name = '".$player->username."';");
if($player->entity instanceof Entity){
unset($player->entity->player);
unset($player->entity);
}
$this->server->api->entity->remove($player->eid);
$player = null;
unset($player);
}
}
public function getOffline($name){
if(!file_exists(FILE_PATH."players/".$name.".dat")){
console("[NOTICE] Player data not found for \"".$name."\", creating new profile");
$data = array(
"spawn" => array(
"x" => $this->server->spawn["x"],
"y" => $this->server->spawn["y"],
"z" => $this->server->spawn["z"],
),
"inventory" => array_fill(0, 36, array(0, 0, 0)),
"health" => 20,
"lastIP" => "",
"lastID" => 0,
);
$this->saveOffline($name, $data);
$iname = strtolower($name);
$default = array(
"caseusername" => $name,
"position" => array(
"level" => $this->server->spawn->level->getName(),
"x" => $this->server->spawn->x,
"y" => $this->server->spawn->y,
"z" => $this->server->spawn->z,
),
"spawn" => array(
"level" => $this->server->spawn->level->getName(),
"x" => $this->server->spawn->x,
"y" => $this->server->spawn->y,
"z" => $this->server->spawn->z,
),
"inventory" => array_fill(0, PLAYER_SURVIVAL_SLOTS, array(AIR, 0, 0)),
"armor" => array_fill(0, 4, array(AIR, 0)),
"gamemode" => $this->server->gamemode,
"health" => 20,
"lastIP" => "",
"lastID" => 0,
);
if(!file_exists(DATA_PATH."players/".$iname.".yml")){
console("[NOTICE] Player data not found for \"".$iname."\", creating new profile");
$data = new Config(DATA_PATH."players/".$iname.".yml", CONFIG_YAML, $default);
$data->save();
}else{
$data = unserialize(file_get_contents(FILE_PATH."players/".$name.".dat"));
$data = new Config(DATA_PATH."players/".$iname.".yml", CONFIG_YAML, $default);
}
$this->server->handle("api.player.offline.get", $data);
if(($data->get("gamemode") & 0x01) === 1){
$data->set("health", 20);
}
$this->server->handle("player.offline.get", $data);
return $data;
}
public function saveOffline($name, $data){
$this->server->handle("api.player.offline.save", $data);
file_put_contents(FILE_PATH."players/".str_replace("/", "", $name).".dat", serialize($data));
public function saveOffline(Config $data){
$this->server->handle("player.offline.save", $data);
$data->save();
}
}

View File

@ -1,35 +1,29 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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/
*
*
*/
class PluginAPI extends stdClass{
private $server;
private $plugins = array();
public function __construct(PocketMinecraftServer $server){
$this->server = $server;
public function __construct(){
$this->server = ServerAPI::request();
}
public function getList(){
@ -41,6 +35,7 @@ class PluginAPI extends stdClass{
}
public function getInfo($className){
$className = strtolower($className);
if(!isset($this->plugins[$className])){
return false;
}
@ -49,54 +44,71 @@ class PluginAPI extends stdClass{
}
public function load($file){
$content = file_get_contents($file);
$info = strstr($content, "*/", true);
$content = substr(strstr($content, "*/"),2);
if(preg_match_all('#([a-zA-Z0-9\-_]*)=([^\r\n]*)#u', $info, $matches) == 0){ //false or 0 matches
console("[ERROR] [PluginAPI] Failed parsing of ".basename($file));
return false;
}
$info = array();
foreach($matches[1] as $k => $i){
$v = $matches[2][$k];
switch(strtolower($v)){
case "on":
case "true":
case "yes":
$v = true;
break;
case "off":
case "false":
case "no":
$v = false;
break;
if(strtolower(substr($file, -3)) === "pmf"){
$pmf = new PMFPlugin($file);
$info = $pmf->getPluginInfo();
}else{
$content = file_get_contents($file);
$info = strstr($content, "*/", true);
$content = str_repeat(PHP_EOL, substr_count($info, "\n")).substr(strstr($content, "*/"),2);
if(preg_match_all('#([a-zA-Z0-9\-_]*)=([^\r\n]*)#u', $info, $matches) == 0){ //false or 0 matches
console("[ERROR] Failed parsing of ".basename($file));
return false;
}
$info[$i] = $v;
$info = array();
foreach($matches[1] as $k => $i){
$v = $matches[2][$k];
switch(strtolower($v)){
case "on":
case "true":
case "yes":
$v = true;
break;
case "off":
case "false":
case "no":
$v = false;
break;
}
$info[$i] = $v;
}
$info["code"] = $content;
$info["class"] = trim(strtolower($info["class"]));
}
if(!isset($info["name"]) or !isset($info["version"]) or !isset($info["class"]) or !isset($info["author"])){
console("[ERROR] [PluginAPI] Failed parsing of ".basename($file));
console("[ERROR] Failed parsing of ".basename($file));
return false;
}
console("[INFO] [PluginAPI] Loading plugin \"\x1b[32m".$info["name"]."\x1b[0m\" \x1b[35m".$info["version"]."\x1b[0m by \x1b[36m".$info["author"]."\x1b[0m");
if(class_exists($info["class"])){
console("[ERROR] [PluginAPI] Failed loading plugin: class exists");
console("[INFO] Loading plugin \"\x1b[32m".$info["name"]."\x1b[0m\" \x1b[35m".$info["version"]." \x1b[0mby \x1b[36m".$info["author"]."\x1b[0m");
if($info["class"] !== "none" and class_exists($info["class"])){
console("[ERROR] Failed loading plugin: class already exists");
return false;
}
if(eval($content) === false or !class_exists($info["class"])){
console("[ERROR] [PluginAPI] Failed loading plugin: evaluation error");
if(eval($info["code"]) === false or ($info["class"] !== "none" and !class_exists($info["class"]))){
console("[ERROR] Failed loading plugin: evaluation error");
return false;
}
$className = trim($info["class"]);
if(isset($info["api"]) and $info["api"] !== true){
console("[NOTICE] [PluginAPI] Plugin \"\x1b[36m".$info["name"]."\x1b[0m\" got raw access to Server methods");
$className = $info["class"];
$apiversion = array_map("intval", explode(",", (string) $info["apiversion"]));
if(!in_array((string) CURRENT_API_VERSION, $apiversion)){
console("[WARNING] Plugin \"".$info["name"]."\" may not be compatible with the API (".$info["apiversion"]." != ".CURRENT_API_VERSION.")! It can crash or corrupt the server!");
}
$object = new $className($this->server->api, ((isset($info["api"]) and $info["api"] !== true) ? $this->server:false));
if(!($object instanceof Plugin)){
console("[ERROR] [PluginAPI] Plugin \"\x1b[36m".$info["name"]."\x1b[0m\" doesn't use the Plugin Interface");
if(method_exists($object, "__destruct")){
$object->__destruct();
if($info["class"] !== "none"){
$object = new $className($this->server->api, false);
if(!($object instanceof Plugin)){
console("[ERROR] Plugin \"\x1b[36m".$info["name"]."\x1b[0m\" doesn't use the Plugin Interface");
if(method_exists($object, "__destruct")){
$object->__destruct();
}
$object = null;
unset($object);
}else{
$this->plugins[$className] = array($object, $info);
}
$object = null;
unset($object);
}else{
$this->plugins[$className] = array($object, $info);
$this->plugins[md5($info["name"])] = array(new DummyPlugin($this->server->api, false), $info);
}
}
@ -114,8 +126,9 @@ class PluginAPI extends stdClass{
if($p === false){
return false;
}
$path = FILE_PATH."plugins/".$p[1]["name"]."/";
$path = DATA_PATH."plugins/".$p[1]["name"]."/";
$this->plugins[$p[1]["class"]][1]["path"] = $path;
@mkdir($path);
return $path;
}
@ -124,8 +137,7 @@ class PluginAPI extends stdClass{
if($p === false){
return false;
}
$path = FILE_PATH."plugins/".$p[1]["name"]."/";
$this->plugins[$p[1]["class"]][1]["path"] = $path;
$path = $this->configPath($plugin);
$cnf = new Config($path."config.yml", CONFIG_YAML, $default);
$cnf->save();
return $path;
@ -158,18 +170,19 @@ class PluginAPI extends stdClass{
}
public function loadAll(){
console("[INFO] Loading Plugins...");
$dir = dir(FILE_PATH."plugins/");
$dir = dir(DATA_PATH."plugins/");
while(false !== ($file = $dir->read())){
if($file{0} !== "."){
if(strtolower(substr($file, -3)) === "php"){
$this->load(FILE_PATH."plugins/" . $file);
$ext = strtolower(substr($file, -3));
if($ext === "php" or $ext === "pmf"){
$this->load(DATA_PATH."plugins/" . $file);
}
}
}
}
public function initAll(){
console("[INFO] Starting plugins...");
foreach($this->plugins as $p){
$p[0]->init(); //ARGHHH!!! Plugin loading randomly fails!!
}
@ -181,4 +194,15 @@ interface Plugin{
public function __construct(ServerAPI $api, $server = false);
public function init();
public function __destruct();
}
class DummyPlugin implements Plugin{
public function __construct(ServerAPI $api, $server = false){
}
public function init(){
}
public function __destruct(){
}
}

View File

@ -1,35 +1,42 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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/
*
*
*/
class ServerAPI{
var $restart = false;
public $restart = false;
private static $serverRequest = false;
private $asyncCalls = array();
private $server;
private $config;
private $apiList = array();
private $asyncCnt = 0;
private $rcon;
private $query;
public static function request(){
return self::$serverRequest;
}
public function start(){
return $this->run();
}
public function run(){
$this->load();
@ -37,181 +44,112 @@ class ServerAPI{
}
public function load(){
@mkdir(FILE_PATH."logs/", 0777, true);
@mkdir(FILE_PATH."players/", 0777);
@mkdir(FILE_PATH."worlds/", 0777);
@mkdir(FILE_PATH."plugins/", 0777);
console("[INFO] Starting ServerAPI server handler...");
file_put_contents(FILE_PATH."logs/packets.log", "");
if(!file_exists(FILE_PATH."logs/test.bin.log") or md5_file(FILE_PATH."logs/test.bin.log") !== TEST_MD5){
console("[NOTICE] Executing tests...");
console("[INFO] OS: ".PHP_OS.", ".Utils::getOS());
console("[INFO] uname -a: ".php_uname("a"));
console("[INFO] PHP Version: ".phpversion());
console("[INFO] Endianness: ".ENDIANNESS);
$test = b"";
$test .= Utils::writeLong("5567381823242127440");
$test .= Utils::writeLong("2338608908624488819");
$test .= Utils::writeLong("2333181766244987936");
$test .= Utils::writeLong("2334669371112169504");
$test .= Utils::writeShort(Utils::readShort("\xff\xff\xff\xff"));
$test .= Utils::writeShort(Utils::readShort("\xef\xff\xff\xff"));
$test .= Utils::writeInt(Utils::readInt("\xff\xff\xff\xff"));
$test .= Utils::writeInt(1);
$test .= Utils::writeInt(-1);
$test .= Utils::writeFloat(Utils::readfloat("\xff\xff\xff\xff"));
$test .= Utils::writeFloat(-1.584563155838E+29);
$test .= Utils::writeFloat(1);
$test .= Utils::writeLDouble(Utils::readLDouble("\xff\xff\xff\xff\xff\xff\xff\xff"));
$test .= Utils::writeLong("-1152921504606846977");
$test .= Utils::writeLong("-1152921504606846976");
$test .= Utils::writeTriad(16777215);
$test .= Utils::writeTriad(16777216);
$str = new Java_String("TESTING\x00\n\r\t\xff");
$test .= Utils::writeLong($str->hashCode());
$test .= Utils::writeDataArray(array("a", "b", "c", "\xff\xff\xff\xff"));
$test .= Utils::hexToStr("012334567890");
file_put_contents(FILE_PATH."logs/test.bin.log", $test);
$md5 = md5($test);
console("[INFO] MD5 of test: ".$md5);
if($md5 !== TEST_MD5){
console("[ERROR] Test error, please send your console.log + test.bin.log to the Github repo");
die();
}
}
@mkdir(DATA_PATH."players/", 0755);
@mkdir(DATA_PATH."worlds/", 0755);
@mkdir(DATA_PATH."plugins/", 0755);
console("[INFO] \x1b[33;1mPocketMine-MP ".MAJOR_VERSION." API #".CURRENT_API_VERSION.", LGPL License", true, true, 0);
console("[DEBUG] Loading server.properties...", true, true, 2);
$this->config = new Config(FILE_PATH . "server.properties", CONFIG_PROPERTIES, array(
"server-name" => "Minecraft Server",
console("[INFO] Loading properties...");
$this->config = new Config(DATA_PATH . "server.properties", CONFIG_PROPERTIES, array(
"server-name" => "Minecraft: PE Server",
"description" => "Server made using PocketMine-MP",
"motd" => "Welcome @username to this server!",
"invisible" => false,
"port" => 19132,
"memory-limit" => "256M",
"last-update" => false,
"update-channel" => "stable",
"white-list" => false,
"debug" => 2,
"max-players" => 20,
"motd" => "Welcome @player to this server!",
"server-ip" => "",
"server-port" => 19132,
"server-type" => "normal",
"time-per-second" => 20,
"gamemode" => 1,
"memory-limit" => "128M",
"last-update" => false,
"white-list" => false,
"spawn-protection" => 16,
"view-distance" => 10,
"max-players" => 20,
"allow-flight" => false,
"spawn-animals" => true,
"spawn-mobs" => true,
"gamemode" => SURVIVAL,
"hardcore" => false,
"pvp" => true,
"difficulty" => 1,
"generator" => "",
"generator-settings" => "",
"level-name" => false,
"server-id" => false,
"upnp-forwarding" => false,
"level-name" => "world",
"level-seed" => "",
"level-type" => "DEFAULT",
"enable-query" => true,
"enable-rcon" => false,
"rcon.password" => substr(base64_encode(Utils::getRandomBytes(20, false)), 3, 10),
"send-usage" => true,
"auto-save" => true,
));
$this->parseProperties();
define("DEBUG", $this->getProperty("debug"));
$this->server = new PocketMinecraftServer($this->getProperty("server-name"), $this->getProperty("gamemode"), false, $this->getProperty("port"), $this->getProperty("server-id"));
$this->setProperty("server-id", $this->server->serverID);
define("DEBUG", $this->getProperty("debug", 1));
if($this->getProperty("port") !== false){
$this->setProperty("server-port", $this->getProperty("port"));
$this->config->remove("port");
$this->config->remove("invisible");
}
$this->server = new PocketMinecraftServer($this->getProperty("server-name"), $this->getProperty("gamemode"), ($seed = $this->getProperty("level-seed")) != "" ? (int) $seed:false, $this->getProperty("server-port"), ($ip = $this->getProperty("server-ip")) != "" ? $ip:"0.0.0.0");
$this->server->api = $this;
self::$serverRequest = $this->server;
if($this->getProperty("upnp-forwarding") === true){
console("[INFO] [UPnP] Trying to port forward...");
UPnP_PortForward($this->getProperty("port"));
}
if(($ip = Utils::getIP()) !== false){
console("[INFO] External IP: ".$ip);
UPnP_PortForward($this->getProperty("server-port"));
}
if($this->getProperty("last-update") === false or ($this->getProperty("last-update") + 3600) < time()){
console("[INFO] Checking for new server version");
console("[INFO] Last check: \x1b[36m".date("Y-m-d H:i:s", $this->getProperty("last-update"))."\x1b[0m");
$channel = "stable";
if($this->getProperty("update-channel") == "dev" or $this->getProperty("update-channel") == "development"){
$channel = "dev";
}
$this->setProperty("update-channel", $channel);
if($channel === "dev"){
$info = json_decode(Utils::curl_get("https://api.github.com/repos/shoghicp/PocketMine-MP"), true);
if($info === false or !isset($info["updated_at"])){
console("[ERROR] GitHub API Error");
$info = json_decode(Utils::curl_get("http://www.pocketmine.net/latest"), true);
if($this->server->version->isDev()){
if($info === false or !isset($info["development"])){
console("[ERROR] PocketMine API error");
}else{
$last = new DateTime($info["updated_at"]);
$last = $last->getTimestamp();
if($last >= $this->getProperty("last-update") and $this->getProperty("last-update") !== false){
$last = $info["development"]["date"];
if($last >= $this->getProperty("last-update") and $this->getProperty("last-update") !== false and GIT_COMMIT != $info["development"]["commit"]){
console("[NOTICE] \x1b[33mA new DEVELOPMENT version of PocketMine-MP has been released");
console("[NOTICE] \x1b[36mIf you want to update, get the latest version at https://github.com/shoghicp/PocketMine-MP/archive/master.zip");
console("[NOTICE] This message will dissapear when you issue the command \"/update-done\"");
sleep(3);
console("[NOTICE] \x1b[33mVersion \"".$info["development"]["version"]."\" [".substr($info["development"]["commit"], 0, 10)."]");
console("[NOTICE] \x1b[36mGet it at PocketMine.net or ".$info["development"]["download"]);
console("[NOTICE] This message will dissapear after issuing the command \"/update-done\"");
}else{
$this->setProperty("last-update", time());
console("[INFO] \x1b[36mThis is the latest DEVELOPMENT version");
}
}
}else{
$info = json_decode(Utils::curl_get("https://api.github.com/repos/shoghicp/PocketMine-MP/tags"), true);
if($info === false or !isset($info[0])){
console("[ERROR] GitHub API Error");
if($info === false or !isset($info["stable"])){
console("[ERROR] PocketMine API error");
}else{
$newest = new VersionString(MAJOR_VERSION);
$newest = array(-1, $newest->getNumber());
foreach($info as $i => $tag){
$update = new VersionString($tag["name"]);
$update = $update->getNumber();
if($update > $newest[1]){
$newest = array($i, $update);
}
}
if($newest[0] !== -1){
$target = $info[$newest[0]];
$newestN = $newest->getNumber();
$update = new VersionString($info["stable"]["version"]);
$updateN = $update->getNumber();
if($updateN > $newestN){
console("[NOTICE] \x1b[33mA new STABLE version of PocketMine-MP has been released");
console("[NOTICE] \x1b[36mVersion \"".(new VersionString($newest[1]))."\" #".$newest[1]." [".substr($target["commit"]["sha"], 0, 10)."]");
console("[NOTICE] Download it at ".$target["zipball_url"]);
console("[NOTICE] \x1b[36mVersion \"".$info["stable"]["version"]."\" #".$updateN);
console("[NOTICE] Get it at PocketMine.net or ".$info["stable"]["download"]);
console("[NOTICE] This message will dissapear as soon as you update");
sleep(5);
}else{
$this->setProperty("last-update", time());
console("[INFO] \x1b[36mThis is the latest STABLE version");
}
}
}
}
}
}
if(file_exists(FILE_PATH."worlds/level.dat")){
console("[NOTICE] Detected unimported map data. Importing...");
$this->importMap(FILE_PATH."worlds/", true);
}
$this->server->mapName = $this->getProperty("level-name");
$this->server->mapDir = FILE_PATH."worlds/".$this->server->mapName."/";
if($this->server->mapName === false or trim($this->server->mapName) === "" or (!file_exists($this->server->mapDir."chunks.dat") and !file_exists($this->server->mapDir."chunks.dat.gz"))){
if($this->server->mapName === false or trim($this->server->mapName) === ""){
$this->server->mapName = "world";
}
$this->server->mapDir = FILE_PATH."worlds/".$this->server->mapName."/";
$generator = "SuperflatGenerator";
if($this->getProperty("generator") !== false and class_exists($this->getProperty("generator"))){
$generator = $this->getProperty("generator");
}
$this->gen = new WorldGenerator($generator, $this->server->seed);
if($this->getProperty("generator-settings") !== false and trim($this->getProperty("generator-settings")) != ""){
$this->gen->set("preset", $this->getProperty("generator-settings"));
}
$this->gen->init();
$this->gen->generate();
$this->gen->save($this->server->mapDir, $this->server->mapName);
$this->setProperty("level-name", $this->server->mapName);
$this->setProperty("gamemode", 1);
}
$this->loadProperties();
$this->server->loadMap();
//Autoload all default APIs
console("[INFO] Loading default APIs");
$dir = dir(FILE_PATH."src/API/");
while(false !== ($file = $dir->read())){
if($file{0} !== "."){ //Hidden and upwards folders
$API = basename($file, ".php");
if(strtolower($API) !== "serverapi" and strtolower($API) !== "pluginapi"){
$name = strtolower(substr($API, 0, -3));
$this->loadAPI($name, $API);
}
}
}
$this->loadAPI("console", "ConsoleAPI");
$this->loadAPI("level", "LevelAPI");
$this->loadAPI("block", "BlockAPI");
$this->loadAPI("chat", "ChatAPI");
$this->loadAPI("ban", "BanAPI");
$this->loadAPI("entity", "EntityAPI");
$this->loadAPI("tile", "TileAPI");
$this->loadAPI("player", "PlayerAPI");
$this->loadAPI("time", "TimeAPI");
foreach($this->apiList as $ob){
if(is_callable(array($ob, "init"))){
$ob->init(); //Fails sometimes!!!
@ -219,39 +157,77 @@ class ServerAPI{
}
$this->loadAPI("plugin", "PluginAPI"); //fix :(
$this->plugin->init();
}
public function async(callable $callable, $params = array(), $remove = false){
$cnt = $this->asyncCnt++;
$this->asyncCalls[$cnt] = new Async($callable, $params);
return $remove === true ? $this->getAsync($cnt):$cnt;
}
public function getAsync($id){
if(!isset($this->asyncCalls[$id])){
return false;
}
$ob = $this->asyncCalls[$id];
unset($this->asyncCalls[$id]);
return $ob;
}
public function autoSave(){
console("[DEBUG] Saving....", true, true, 2);
$this->server->api->level->saveAll();
}
public function sendUsage(){
console("[DEBUG] Sending usage data...", true, true, 2);
$plist = "";
foreach($this->plugin->getList() as $p){
$plist .= str_replace(array(";", ":"), "", $p["name"]).":".str_replace(array(";", ":"), "", $p["version"]).";";
}
$this->server->loadEntities();
$this->asyncOperation(ASYNC_CURL_POST, array(
"url" => "http://stats.pocketmine.net/usage.php",
"data" => array(
"serverid" => $this->server->serverID,
"port" => $this->server->port,
"os" => Utils::getOS(),
"memory_total" => $this->getProperty("memory-limit"),
"memory_usage" => memory_get_usage(true),
"php_version" => PHP_VERSION,
"version" => MAJOR_VERSION,
"mc_version" => CURRENT_MINECRAFT_VERSION,
"protocol" => CURRENT_PROTOCOL,
"online" => count($this->server->clients),
"max" => $this->server->maxClients,
"plugins" => $plist,
),
), NULL);
}
public function __destruct(){
foreach($this->apiList as $ob){
if(is_callable($ob, "__destruct")){
foreach($this->apiList as $i => $ob){
if(method_exists($ob, "__destruct")){
$ob->__destruct();
unset($this->apiList[$ob]);
unset($this->apiList[$i]);
}
}
}
private function loadProperties(){
if(($memory = $this->getProperty("memory-limit")) !== false){
if(($memory = str_replace("B", "", strtoupper($this->getProperty("memory-limit")))) !== false){
$value = array("M" => 1, "G" => 1024);
$real = ((int) substr($memory, 0, -1)) * $value[substr($memory, -1)];
if($real < 128){
console("[ERROR] PocketMine doesn't work right with less than 128MB of RAM", true, true, 0);
console("[WARNING] PocketMine-MP may not work right with less than 128MB of RAM", true, true, 0);
}
@ini_set("memory_limit", $memory);
}else{
$this->setProperty("memory-limit", "256M");
$this->setProperty("memory-limit", "128M");
}
if(!$this->config->exists("invisible")){
$this->config->set("invisible", false);
}
if(is_object($this->server)){
if($this->server instanceof PocketMinecraftServer){
$this->server->setType($this->getProperty("server-type"));
$this->server->timePerSecond = $this->getProperty("time-per-second");
$this->server->invisible = $this->getProperty("invisible");
$this->server->maxClients = $this->getProperty("max-players");
$this->server->description = $this->getProperty("description");
$this->server->motd = $this->getProperty("motd");
@ -278,10 +254,9 @@ class ServerAPI{
break;
case "gamemode":
case "max-players":
case "port":
case "server-port":
case "debug":
case "difficulty":
case "time-per-second":
$v = (int) $v;
break;
case "server-id":
@ -292,22 +267,47 @@ class ServerAPI{
}
$this->config->set($n, $v);
}
if($this->getProperty("hardcore") == 1 and $this->getProperty("difficulty") < 3){
$this->setProperty("difficulty", 3);
}
}
public function init(){
if($this->getProperty("send-usage") !== false){
$this->server->schedule(6000, array($this, "sendUsage"), array(), true); //Send the info after 5 minutes have passed
$this->sendUsage();
}
if($this->getProperty("auto-save") === true){
$this->server->schedule(18000, array($this, "autoSave"), array(), true);
}
if(!defined("NO_THREADS") and $this->getProperty("enable-rcon") === true){
$this->rcon = new RCON($this->getProperty("rcon.password", ""), $this->getProperty("rcon.port", $this->getProperty("server-port")), ($ip = $this->getProperty("server-ip")) != "" ? $ip:"0.0.0.0", $this->getProperty("rcon.threads", 1), $this->getProperty("rcon.clients-per-thread", 50));
}
if($this->getProperty("enable-query") === true){
$this->query = new Query();
}
CraftingRecipes::init();
$this->server->init();
unregister_tick_function(array($this->server, "tick"));
$this->console->__destruct();
if($this->rcon instanceof RCON){
$this->rcon->stop();
}
$this->__destruct();
unset($this->server);
if($this->getProperty("upnp-forwarding") === true ){
console("[INFO] [UPnP] Removing port forward...");
UPnP_RemovePortForward($this->getProperty("port"));
UPnP_RemovePortForward($this->getProperty("server-port"));
}
return $this->restart;
}
/*-------------------------------------------------------------*/
public function asyncOperation($t, $d, $c = null){
return $this->server->asyncOperation($t, $d, $c);
}
public function addHandler($e, $c, $p = 5){
return $this->server->addHandler($e, $c, $p);
}
@ -320,10 +320,6 @@ class ServerAPI{
return $this->server->handle($e, $d);
}
public function action($t, $c, $r = true){
return $this->server->action($t, $c, $r);
}
public function schedule($t, $c, $d, $r = false, $e = "server.schedule"){
return $this->server->schedule($t, $c, $d, $r, $e);
}
@ -339,53 +335,12 @@ class ServerAPI{
public function deleteEvent($id){
return $this->server->deleteEvent($id);
}
public function importMap($dir, $remove = false){
if(file_exists($dir."level.dat")){
$nbt = new NBT();
$level = parseNBTData($nbt->loadFile($dir."level.dat"));
console("[DEBUG] Importing map \"".$level["LevelName"]."\" gamemode ".$level["GameType"]." with seed ".$level["RandomSeed"], true, true, 2);
unset($level["Player"]);
$lvName = $level["LevelName"]."/";
@mkdir(FILE_PATH."worlds/".$lvName, 0777);
file_put_contents(FILE_PATH."worlds/".$lvName."level.dat", serialize($level));
$entities = parseNBTData($nbt->loadFile($dir."entities.dat"));
file_put_contents(FILE_PATH."worlds/".$lvName."entities.dat", serialize($entities["Entities"]));
if(!isset($entities["TileEntities"])){
$entities["TileEntities"] = array();
}
file_put_contents(FILE_PATH."worlds/".$lvName."tileEntities.dat", serialize($entities["TileEntities"]));
console("[DEBUG] Imported ".count($entities["Entities"])." Entities and ".count($entities["TileEntities"])." TileEntities", true, true, 2);
if($remove === true){
rename($dir."chunks.dat", FILE_PATH."worlds/".$lvName."chunks.dat");
unlink($dir."level.dat");
@unlink($dir."level.dat_old");
@unlink($dir."player.dat");
unlink($dir."entities.dat");
}else{
copy($dir."chunks.dat", FILE_PATH."worlds/".$lvName."chunks.dat");
}
if($this->getProperty("level-name") === false){
console("[INFO] Setting default level to \"".$level["LevelName"]."\"");
$this->setProperty("level-name", $level["LevelName"]);
$this->setProperty("gamemode", $level["GameType"]);
$this->server->seed = $level["RandomSeed"];
$this->server->spawn = array("x" => $level["SpawnX"], "y" => $level["SpawnY"], "z" => $level["SpawnZ"]);
$this->writeProperties();
}
console("[INFO] Map \"".$level["LevelName"]."\" importing done!");
unset($level, $entities, $nbt);
return true;
}
return false;
}
public function getProperties(){
return $this->config->getAll();
}
public function getProperty($name){
public function getProperty($name, $default = false){
if(($v = arg($name)) !== false){ //Allow for command-line arguments
switch(strtolower(trim($v))){
case "on":
@ -409,7 +364,7 @@ class ServerAPI{
break;
case "gamemode":
case "max-players":
case "port":
case "server-port":
case "debug":
case "difficulty":
case "time-per-second":
@ -423,7 +378,7 @@ class ServerAPI{
}
return $v;
}
return $this->config->get($name);
return ($this->config->exists($name) ? $this->config->get($name):$default);
}
public function setProperty($name, $value){
@ -437,18 +392,26 @@ class ServerAPI{
}
public function loadAPI($name, $class, $dir = false){
if($dir === false){
$dir = FILE_PATH."src/API/";
}
$file = $dir.$class.".php";
if(!file_exists($file)){
console("[ERROR] API ".$name." [".$class."] in ".$dir." doesn't exist", true, true, 0);
if(isset($this->$name)){
return false;
}elseif(!class_exists($class)){
$internal = false;
if($dir === false){
$internal = true;
$dir = FILE_PATH."src/API/";
}
$file = $dir.$class.".php";
if(!file_exists($file)){
console("[ERROR] API ".$name." [".$class."] in ".$dir." doesn't exist", true, true, 0);
return false;
}
require_once($file);
}else{
$internal = true;
}
require_once($file);
$this->$name = new $class($this->server);
$this->$name = new $class();
$this->apiList[] = $this->$name;
console("[INFO] API \x1b[36m".$name."\x1b[0m [\x1b[30;1m".$class."\x1b[0m] loaded");
console("[".($internal === true ? "INTERNAL":"DEBUG")."] API \x1b[36m".$name."\x1b[0m [\x1b[30;1m".$class."\x1b[0m] loaded", true, true, ($internal === true ? 3:2));
}
}
}

116
src/API/TileAPI.php Normal file
View File

@ -0,0 +1,116 @@
<?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/
*
*
*/
class TileAPI{
private $server;
private $tiles;
private $tCnt = 1;
function __construct(){
$this->tiles = array();
$this->server = ServerAPI::request();
}
public function get(Position $pos){
$tile = $this->server->query("SELECT * FROM tiles WHERE level = '".$pos->level->getName()."' AND x = {$pos->x} AND y = {$pos->y} AND z = {$pos->z};", true);
if($tile !== false and $tile !== true and ($tile = $this->getByID($tile["ID"])) !== false){
return $tile;
}
return false;
}
public function getByID($id){
if($id instanceof Tile){
return $id;
}elseif(isset($this->tiles[$id])){
return $this->tiles[$id];
}
return false;
}
public function init(){
}
public function getAll($level = null){
if($level instanceof Level){
$tiles = array();
$l = $this->server->query("SELECT ID FROM tiles WHERE level = '".$level->getName()."';");
if($l !== false and $l !== true){
while(($t = $l->fetchArray(SQLITE3_ASSOC)) !== false){
$t = $this->getByID($t["ID"]);
if($t instanceof Tile){
$tiles[$t->id] = $t;
}
}
}
return $tiles;
}
return $this->tiles;
}
public function add(Level $level, $class, $x, $y, $z, $data = array()){
$id = $this->tCnt++;
$this->tiles[$id] = new Tile($level, $id, $class, $x, $y, $z, $data);
$this->spawnToAll($this->tiles[$id]);
return $this->tiles[$id];
}
public function addSign(Level $level, $x, $y, $z, $lines = array("", "", "", "")){
return $this->add($level, TILE_SIGN, $x, $y, $z, $data = array(
"id" => "Sign",
"x" => $x,
"y" => $y,
"z" => $z,
"Text1" => $lines[0],
"Text2" => $lines[1],
"Text3" => $lines[2],
"Text4" => $lines[3],
));
}
public function spawnToAll(Tile $t){
foreach($this->server->api->player->getAll($t->level) as $player){
if($player->eid !== false){
$t->spawn($player);
}
}
}
public function spawnAll(Player $player){
foreach($this->getAll($player->level) as $t){
$t->spawn($player);
}
}
public function remove($id){
if(isset($this->tiles[$id])){
$t = $this->tiles[$id];
$this->tiles[$id] = null;
unset($this->tiles[$id]);
$t->closed = true;
$t->close();
$this->server->query("DELETE FROM tiles WHERE ID = ".$id.";");
$this->server->api->dhandle("tile.remove", $t);
$t = null;
unset($t);
}
}
}

View File

@ -1,28 +1,22 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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/
*
*
*/
class TimeAPI{
@ -33,76 +27,82 @@ class TimeAPI{
"sunrise" => 17800,
);
private $server;
function __construct(PocketMinecraftServer $server){
$this->server = $server;
function __construct(){
$this->server = ServerAPI::request();
}
public function init(){
$this->server->api->console->register("time", "Manages server time", array($this, "commandHandler"));
$this->server->api->console->register("time", "<check|set|add> [time]", array($this, "commandHandler"));
}
public function commandHandler($cmd, $params){
public function commandHandler($cmd, $params, $issuer, $alias){
$output = "";
switch($cmd){
case "time":
$level = false;
if($issuer instanceof Player){
$level = $issuer->level;
}
$p = strtolower(array_shift($params));
switch($p){
case "check":
console("[INFO] Time: ".$this->getDate().", ".$this->getPhase()." (".$this->get(true).")");
$output .= "Time: ".$this->getDate($level).", ".$this->getPhase($level)." (".$this->get(true, $level).")\n";
break;
case "add":
$this->add(array_shift($params));
$output .= "Set the time to ".$this->add(array_shift($params), $level)."\n";
break;
case "set":
$this->set(array_shift($params));
$output .= "Set the time to ".$this->set(array_shift($params), $level)."\n";
break;
case "sunrise":
$this->sunrise();
break;
case "day":
$this->day();
break;
case "sunset":
$this->sunset();
break;
case "night":
$this->night();
$output .= "Set the time to ".$this->set($p, $level)."\n";
break;
default:
console("[INFO] Usage: /time <check | set | add | sunrise | day | sunset | night> [time]");
$output .= "Usage: /time <check|set|add> [time]\n";
break;
}
break;
}
return $output;
}
public function night(){
$this->set("night");
return $this->set("night");
}
public function day(){
$this->set("day");
return $this->set("day");
}
public function sunrise(){
$this->set("sunrise");
return $this->set("sunrise");
}
public function sunset(){
$this->set("sunset");
return $this->set("sunset");
}
public function get($raw = false){
return $raw === true ? $this->server->time:abs($this->server->time) % 19200;
public function get($raw = false, $level = false){
if(!($level instanceof Level)){
$level = $this->server->api->level->getDefault();
}
return $raw === true ? $level->getTime():abs($level->getTime()) % 19200;
}
public function add($time){
$this->server->time += (int) $time;
public function add($time, $level = false){
if(!($level instanceof Level)){
$level = $this->server->api->level->getDefault();
}
$level->setTime($level->getTime() + (int) $time);
}
public function getDate($time = false){
$time = $time === false ? $this->get():$time;
$time = !is_integer($time) ? $this->get(false, $time):$time;
return str_pad(strval((floor($time /800) + 6) % 24), 2, "0", STR_PAD_LEFT).":".str_pad(strval(floor(($time % 800) / 13.33)), 2, "0", STR_PAD_LEFT);
}
public function getPhase($time = false){
$time = $time === false ? $this->get():$time;
$time = !is_integer($time) ? $this->get(false, $time):$time;
if($time < $this->phase["sunset"]){
$time = "day";
}elseif($time < $this->phase["night"]){
@ -115,13 +115,17 @@ class TimeAPI{
return $time;
}
public function set($time){
if(is_string($time) and isset($this->phases[$time])){
$this->server->time = $this->phases[$time];
}else{
$this->server->time = (int) $time;
public function set($time, $level = false){
if(!($level instanceof Level)){
$level = $this->server->api->level->getDefault();
}
if(is_string($time) and isset($this->phases[$time])){
$level->setTime($this->phases[$time]);
}else{
$level->setTime((int) $time);
}
return $level->getTime();
}
}
}

35
src/Deprecation.php Normal file
View File

@ -0,0 +1,35 @@
<?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/
*
*
*/
class Deprecation{
public static $events = array(
"server.tick" => "ServerAPI::schedule()",
"server.time" => "time.change",
"world.block.change" => "block.change",
"block.drop" => "item.drop",
"api.op.check" => "op.check",
"api.player.offline.get" => "player.offline.get",
"api.player.offline.save" => "player.offline.save",
);
}

1989
src/Player.php Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,676 @@
<?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/
*
*
*/
class PocketMinecraftServer{
public $tCnt;
public $serverID, $interface, $database, $version, $invisible, $api, $tickMeasure, $preparedSQL, $seed, $gamemode, $name, $maxClients, $clients, $eidCnt, $custom, $description, $motd, $port, $saveEnabled;
private $serverip, $evCnt, $handCnt, $events, $eventsID, $handlers, $serverType, $lastTick, $ticks, $memoryStats, $async = array(), $asyncID = 0;
private function load(){
$this->version = new VersionString();
if(defined("DEBUG") and DEBUG >= 0){
@cli_set_process_title("PocketMine-MP ".MAJOR_VERSION);
}
if($this->version->isDev()){
console("[INFO] \x1b[31;1mThis is a Development version");
}
console("[INFO] Starting server for Minecraft: PE \x1b[36;1m".CURRENT_MINECRAFT_VERSION."\x1b[0m #".CURRENT_PROTOCOL." at ".$this->serverip.":".$this->port);
define("BOOTUP_RANDOM", Utils::getRandomBytes(16));
$this->serverID = $this->serverID === false ? Utils::readLong(Utils::getRandomBytes(8, false)):$this->serverID;
$this->seed = $this->seed === false ? Utils::readInt(Utils::getRandomBytes(4, false)):$this->seed;
$this->startDatabase();
$this->api = false;
$this->tCnt = 1;
$this->events = array();
$this->eventsID = array();
$this->handlers = array();
$this->invisible = false;
$this->levelData = false;
$this->difficulty = 1;
$this->tiles = array();
$this->entities = array();
$this->custom = array();
$this->evCnt = 1;
$this->handCnt = 1;
$this->eidCnt = 1;
$this->maxClients = 20;
$this->schedule = array();
$this->scheduleCnt = 1;
$this->description = "";
$this->whitelist = false;
$this->memoryStats = array();
$this->clients = array();
$this->spawn = false;
$this->saveEnabled = true;
$this->tickMeasure = array_fill(0, 40, 0);
$this->setType("normal");
$this->interface = new MinecraftInterface($this, "255.255.255.255", $this->port, true, false, $this->serverip);
$this->reloadConfig();
$this->stop = false;
$this->ticks = 0;
if(!defined("NO_THREADS")){
$this->asyncThread = new AsyncMultipleQueue();
}
}
function __construct($name, $gamemode = SURVIVAL, $seed = false, $port = 19132, $serverip = "0.0.0.0"){
$this->port = (int) $port;
$this->doTick = true;
$this->gamemode = (int) $gamemode;
$this->name = $name;
$this->motd = "Welcome to ".$name;
$this->serverID = false;
$this->seed = $seed;
$this->serverip = $serverip;
$this->load();
}
public function getTPS(){
$v = array_values($this->tickMeasure);
$tps = 40 / ($v[39] - $v[0]);
return round($tps, 4);
}
public function titleTick(){
$time = microtime(true);
if(defined("DEBUG") and DEBUG >= 0 and ENABLE_ANSI === true){
echo "\x1b]0;PocketMine-MP ".MAJOR_VERSION." | Online ". count($this->clients)."/".$this->maxClients." | RAM ".round((memory_get_usage() / 1024) / 1024, 2)."MB | U ".round(($this->interface->bandwidth[1] / max(1, $time - $this->interface->bandwidth[2])) / 1024, 2)." D ".round(($this->interface->bandwidth[0] / max(1, $time - $this->interface->bandwidth[2])) / 1024, 2)." kB/s | TPS ".$this->getTPS()."\x07";
}
$this->interface->bandwidth = array(0, 0, $time);
}
public function loadEvents(){
if(ENABLE_ANSI === true){
$this->schedule(30, array($this, "titleTick"), array(), true);
}
$this->schedule(20 * 15, array($this, "checkTicks"), array(), true);
$this->schedule(20 * 60, array($this, "checkMemory"), array(), true);
$this->schedule(20, array($this, "asyncOperationChecker"), array(), true);
}
public function checkTicks(){
if($this->getTPS() < 12){
console("[WARNING] Can't keep up! Is the server overloaded?");
}
}
public function checkMemory(){
$info = $this->debugInfo();
$data = $info["memory_usage"].",".$info["players"].",".$info["entities"];
$i = count($this->memoryStats) - 1;
if($i < 0 or $this->memoryStats[$i] !== $data){
$this->memoryStats[] = $data;
}
}
public function startDatabase(){
$this->preparedSQL = new stdClass();
$this->preparedSQL->entity = new stdClass();
$this->database = new SQLite3(":memory:");
$this->query("PRAGMA journal_mode = OFF;");
$this->query("PRAGMA encoding = \"UTF-8\";");
$this->query("PRAGMA secure_delete = OFF;");
$this->query("CREATE TABLE players (CID INTEGER PRIMARY KEY, EID NUMERIC, ip TEXT, port NUMERIC, name TEXT UNIQUE COLLATE NOCASE);");
$this->query("CREATE TABLE entities (EID INTEGER PRIMARY KEY, level TEXT, type NUMERIC, class NUMERIC, hasUpdate NUMERIC, name TEXT, x NUMERIC, y NUMERIC, z NUMERIC, yaw NUMERIC, pitch NUMERIC, health NUMERIC);");
$this->query("CREATE TABLE tiles (ID INTEGER PRIMARY KEY, level TEXT, class TEXT, x NUMERIC, y NUMERIC, z NUMERIC, spawnable NUMERIC);");
$this->query("CREATE TABLE actions (ID INTEGER PRIMARY KEY, interval NUMERIC, last NUMERIC, code TEXT, repeat NUMERIC);");
$this->query("CREATE TABLE handlers (ID INTEGER PRIMARY KEY, name TEXT, priority NUMERIC);");
$this->query("CREATE TABLE blockUpdates (level TEXT, x INTEGER, y INTEGER, z INTEGER, type INTEGER, delay NUMERIC);");
$this->query("CREATE TABLE recipes (id INTEGER PRIMARY KEY, type NUMERIC, recipe TEXT);");
$this->query("PRAGMA synchronous = OFF;");
$this->preparedSQL->selectHandlers = $this->database->prepare("SELECT DISTINCT ID FROM handlers WHERE name = :name ORDER BY priority DESC;");
$this->preparedSQL->selectActions = $this->database->prepare("SELECT ID,code,repeat FROM actions WHERE last <= (:time - interval);");
$this->preparedSQL->updateAction = $this->database->prepare("UPDATE actions SET last = :time WHERE ID = :id;");
$this->preparedSQL->entity->setPosition = $this->database->prepare("UPDATE entities SET x = :x, y = :y, z = :z, pitch = :pitch, yaw = :yaw WHERE EID = :eid ;");
$this->preparedSQL->entity->setLevel = $this->database->prepare("UPDATE entities SET level = :level WHERE EID = :eid ;");
}
public function query($sql, $fetch = false){
$result = $this->database->query($sql) or console("[ERROR] [SQL Error] ".$this->database->lastErrorMsg().". Query: ".$sql, true, true, 0);
if($fetch === true and ($result instanceof SQLite3Result)){
$result = $result->fetchArray(SQLITE3_ASSOC);
}
return $result;
}
public function reloadConfig(){
}
public function debugInfo($console = false){
$info = array();
$info["tps"] = $this->getTPS();
$info["memory_usage"] = round((memory_get_usage() / 1024) / 1024, 2)."MB";
$info["memory_peak_usage"] = round((memory_get_peak_usage() / 1024) / 1024, 2)."MB";
$info["entities"] = $this->query("SELECT count(EID) as count FROM entities;", true);
$info["entities"] = $info["entities"]["count"];
$info["players"] = $this->query("SELECT count(CID) as count FROM players;", true);
$info["players"] = $info["players"]["count"];
$info["events"] = count($this->eventsID);
$info["handlers"] = $this->query("SELECT count(ID) as count FROM handlers;", true);
$info["handlers"] = $info["handlers"]["count"];
$info["actions"] = $this->query("SELECT count(ID) as count FROM actions;", true);
$info["actions"] = $info["actions"]["count"];
$info["garbage"] = gc_collect_cycles();
$this->handle("server.debug", $info);
if($console === true){
console("[DEBUG] TPS: ".$info["tps"].", Memory usage: ".$info["memory_usage"]." (Peak ".$info["memory_peak_usage"]."), Entities: ".$info["entities"].", Events: ".$info["events"].", Handlers: ".$info["handlers"].", Actions: ".$info["actions"].", Garbage: ".$info["garbage"], true, true, 2);
}
return $info;
}
public function close($reason = "server stop"){
if($this->stop !== true){
if(is_int($reason)){
$reason = "signal stop";
}
if(($this->api instanceof ServerAPI) === true){
if(($this->api->chat instanceof ChatAPI) === true){
$this->api->chat->broadcast("Stopping server...");
}
}
$this->stop = true;
$this->trigger("server.close", $reason);
$this->interface->close();
if(!defined("NO_THREADS")){
@$this->asyncThread->stop = true;
}
}
}
public function setType($type = "normal"){
switch(trim(strtolower($type))){
case "normal":
case "demo":
$this->serverType = "MCCPP;Demo;";
break;
case "minecon":
$this->serverType = "MCCPP;MINECON;";
break;
}
}
public function asyncOperation($type, array $data, callable $callable = null){
if(defined("NO_THREADS")){
return false;
}
$d = "";
$type = (int) $type;
switch($type){
case ASYNC_CURL_GET:
$d .= Utils::writeShort(strlen($data["url"])).$data["url"].(isset($data["timeout"]) ? Utils::writeShort($data["timeout"]) : Utils::writeShort(10));
break;
case ASYNC_CURL_POST:
$d .= Utils::writeShort(strlen($data["url"])).$data["url"].(isset($data["timeout"]) ? Utils::writeShort($data["timeout"]) : Utils::writeShort(10));
$d .= Utils::writeShort(count($data["data"]));
foreach($data["data"] as $key => $value){
$d .= Utils::writeShort(strlen($key)).$key . Utils::writeInt(strlen($value)).$value;
}
break;
default:
return false;
}
$ID = $this->asyncID++;
$this->async[$ID] = $callable;
$this->asyncThread->input .= Utils::writeInt($ID).Utils::writeShort($type).$d;
return $ID;
}
public function asyncOperationChecker(){
if(defined("NO_THREADS")){
return false;
}
if(isset($this->asyncThread->output{5})){
$offset = 0;
$ID = Utils::readInt(substr($this->asyncThread->output, $offset, 4));
$offset += 4;
$type = Utils::readShort(substr($this->asyncThread->output, $offset, 2));
$offset += 2;
$data = array();
switch($type){
case ASYNC_CURL_GET:
case ASYNC_CURL_POST:
$len = Utils::readInt(substr($this->asyncThread->output, $offset, 4));
$offset += 4;
$data["result"] = substr($this->asyncThread->output, $offset, $len);
$offset += $len;
break;
}
$this->asyncThread->output = substr($this->asyncThread->output, $offset);
if(isset($this->async[$ID]) and $this->async[$ID] !== null and is_callable($this->async[$ID])){
if(is_array($this->async[$ID])){
$method = $this->async[$ID][1];
$result = $this->async[$ID][0]->$method($data, $type, $ID);
}else{
$result = $this->async[$ID]($data, $type, $ID);
}
}
unset($this->async[$ID]);
}
}
public function addHandler($event,callable $callable, $priority = 5){
if(!is_callable($callable)){
return false;
}elseif(isset(Deprecation::$events[$event])){
$sub = "";
if(Deprecation::$events[$event] !== false){
$sub = " Substitute \"".Deprecation::$events[$event]."\" found.";
}
console("[ERROR] Event \"$event\" has been deprecated.$sub [Adding handle to ".(is_array($callable) ? get_class($callable[0])."::".$callable[1]:$callable)."]");
}
$priority = (int) $priority;
$hnid = $this->handCnt++;
$this->handlers[$hnid] = $callable;
$this->query("INSERT INTO handlers (ID, name, priority) VALUES (".$hnid.", '".str_replace("'", "\\'", $event)."', ".$priority.");");
console("[INTERNAL] New handler ".(is_array($callable) ? get_class($callable[0])."::".$callable[1]:$callable)." to special event ".$event." (ID ".$hnid.")", true, true, 3);
return $hnid;
}
public function dhandle($e, $d){
return $this->handle($e, $d);
}
public function handle($event, &$data){
$this->preparedSQL->selectHandlers->reset();
$this->preparedSQL->selectHandlers->clear();
$this->preparedSQL->selectHandlers->bindValue(":name", $event, SQLITE3_TEXT);
$handlers = $this->preparedSQL->selectHandlers->execute();
$result = null;
if($handlers instanceof SQLite3Result){
$call = array();
while(($hn = $handlers->fetchArray(SQLITE3_ASSOC)) !== false){
$call[(int) $hn["ID"]] = true;
}
$handlers->finalize();
foreach($call as $hnid => $boolean){
if($result !== false and $result !== true){
$called[$hnid] = true;
$handler = $this->handlers[$hnid];
if(is_array($handler)){
$method = $handler[1];
$result = $handler[0]->$method($data, $event);
}else{
$result = $handler($data, $event);
}
}else{
break;
}
}
}elseif(isset(Deprecation::$events[$event])){
$sub = "";
if(Deprecation::$events[$event] !== false){
$sub = " Substitute \"".Deprecation::$events[$event]."\" found.";
}
console("[ERROR] Event \"$event\" has been deprecated.$sub [Handler]");
}
if($result !== false){
$this->trigger($event, $data);
}
return $result;
}
public function eventHandler($data, $event){
switch($event){
}
}
public function getGamemode(){
switch($this->gamemode){
case SURVIVAL:
return "survival";
case CREATIVE:
return "creative";
case ADVENTURE:
return "adventure";
case VIEW:
return "view";
}
}
public function init(){
register_tick_function(array($this, "tick"));
console("[INFO] Starting internal ticker calculation");
$t = 0;
while(true){
switch($t){
case 0:
declare(ticks=100);
break;
case 1:
declare(ticks=60);
break;
case 2:
declare(ticks=40);
break;
case 3:
declare(ticks=30);
break;
case 4:
declare(ticks=20);
break;
case 5:
declare(ticks=15);
break;
default:
declare(ticks=10);
break;
}
if($t > 5){
break;
}
$this->ticks = 0;
while($this->ticks < 20){
usleep(1);
}
if($this->getTPS() < 19.5){
++$t;
}else{
break;
}
}
$this->loadEvents();
register_shutdown_function(array($this, "dumpError"));
register_shutdown_function(array($this, "close"));
if(function_exists("pcntl_signal")){
pcntl_signal(SIGTERM, array($this, "close"));
pcntl_signal(SIGINT, array($this, "close"));
pcntl_signal(SIGHUP, array($this, "close"));
}
console("[INFO] Default game type: ".strtoupper($this->getGamemode()));
$this->trigger("server.start", microtime(true));
console('[INFO] Done ('.round(microtime(true) - START_TIME, 3).'s)! For help, type "help" or "?"');
$this->process();
}
public function dumpError(){
if($this->stop === true){
return;
}
console("[ERROR] An Unrecovereable has ocurred and the server has Crashed. Creating an Error Dump");
$dump = "```\r\n# PocketMine-MP Error Dump ".date("D M j H:i:s T Y")."\r\n";
$er = error_get_last();
$dump .= "Error: ".var_export($er, true)."\r\n\r\n";
$dump .= "Code: \r\n";
$file = @file($er["file"], FILE_IGNORE_NEW_LINES);
for($l = max(0, $er["line"] - 10); $l < $er["line"] + 10; ++$l){
$dump .= "[".($l + 1)."] ".@$file[$l]."\r\n";
}
$dump .= "\r\n\r\n";
$version = new VersionString();
$dump .= "PM Version: ".$version." #".$version->getNumber()." [Protocol ".CURRENT_PROTOCOL."]\r\n";
$dump .= "Commit: ".GIT_COMMIT."\r\n";
$dump .= "uname -a: ".php_uname("a")."\r\n";
$dump .= "PHP Version: " .phpversion()."\r\n";
$dump .= "Zend version: ".zend_version()."\r\n";
$dump .= "OS : " .PHP_OS.", ".Utils::getOS()."\r\n";
$dump .= "Debug Info: ".var_export($this->debugInfo(false), true)."\r\n\r\n\r\n";
global $arguments;
$dump .= "Parameters: ".var_export($arguments, true)."\r\n\r\n\r\n";
$p = $this->api->getProperties();
if($p["rcon.password"] != ""){
$p["rcon.password"] = "******";
}
$dump .= "server.properties: ".var_export($p, true)."\r\n\r\n\r\n";
if($this->api->plugin instanceof PluginAPI){
$plist = $this->api->plugin->getList();
$dump .= "Loaded plugins:\r\n";
foreach($plist as $p){
$dump .= $p["name"]." ".$p["version"]." by ".$p["author"]."\r\n";
}
$dump .= "\r\n\r\n";
}
$dump .= "Loaded Modules: ".var_export(get_loaded_extensions(), true)."\r\n";
$dump .= "Memory Usage Tracking: \r\n".chunk_split(base64_encode(gzdeflate(implode(";", $this->memoryStats), 9)))."\r\n";
ob_start();
phpinfo();
$dump .= "\r\nphpinfo(): \r\n".chunk_split(base64_encode(gzdeflate(ob_get_contents(), 9)))."\r\n";
ob_end_clean();
$dump .= "\r\n```";
$name = "Error_Dump_".date("D_M_j-H.i.s-T_Y");
logg($dump, $name, true, 0, true);
console("[ERROR] Please submit the \"{$name}.log\" file to the Bug Reporting page. Give as much info as you can.", true, true, 0);
}
public function tick(){
$time = microtime(true);
if($this->lastTick <= ($time - 0.05)){
$this->tickMeasure[] = $this->lastTick = $time;
unset($this->tickMeasure[key($this->tickMeasure)]);
++$this->ticks;
$this->tickerFunction($time);
}
}
public static function clientID($ip, $port){
//faster than string indexes in PHP
return crc32($ip . $port) ^ crc32($port . $ip . BOOTUP_RANDOM);
}
public function packetHandler($packet){
$data =& $packet["data"];
$CID = PocketMinecraftServer::clientID($packet["ip"], $packet["port"]);
if(isset($this->clients[$CID])){
$this->clients[$CID]->handlePacket($packet["pid"], $data);
}else{
if($this->handle("server.noauthpacket", $packet) === false){
return;
}
switch($packet["pid"]){
case 0x01:
case 0x02:
if($this->invisible === true){
$this->send(0x1c, array(
$data[0],
$this->serverID,
RAKNET_MAGIC,
$this->serverType,
), false, $packet["ip"], $packet["port"]);
break;
}
if(!isset($this->custom["times_".$CID])){
$this->custom["times_".$CID] = 0;
}
$ln = 15;
if($this->description == "" or substr($this->description, -1) != " "){
$this->description .= " ";
}
$txt = substr($this->description, $this->custom["times_".$CID], $ln);
$txt .= substr($this->description, 0, $ln - strlen($txt));
$this->send(0x1c, array(
$data[0],
$this->serverID,
RAKNET_MAGIC,
$this->serverType. $this->name . " [".count($this->clients)."/".$this->maxClients."] ".$txt,
), false, $packet["ip"], $packet["port"]);
$this->custom["times_".$CID] = ($this->custom["times_".$CID] + 1) % strlen($this->description);
break;
case 0x05:
$version = $data[1];
$size = strlen($data[2]);
if($version !== CURRENT_STRUCTURE){
console("[DEBUG] Incorrect structure #$version from ".$packet["ip"].":".$packet["port"], true, true, 2);
$this->send(0x1a, array(
CURRENT_STRUCTURE,
RAKNET_MAGIC,
$this->serverID,
), false, $packet["ip"], $packet["port"]);
}else{
$this->send(0x06, array(
RAKNET_MAGIC,
$this->serverID,
0,
strlen($packet["raw"]),
), false, $packet["ip"], $packet["port"]);
}
break;
case 0x07:
if($this->invisible === true){
break;
}
$port = $data[2];
$MTU = $data[3];
$clientID = $data[4];
if(count($this->clients) < $this->maxClients){
$this->clients[$CID] = new Player($clientID, $packet["ip"], $packet["port"], $MTU); //New Session!
$this->send(0x08, array(
RAKNET_MAGIC,
$this->serverID,
$this->port,
$data[3],
0,
), false, $packet["ip"], $packet["port"]);
}
break;
}
}
}
public function send($pid, $data = array(), $raw = false, $dest = false, $port = false){
return $this->interface->writePacket($pid, $data, $raw, $dest, $port);
}
public function process(){
$lastLoop = 0;
while($this->stop === false){
$packet = $this->interface->readPacket();
if($packet !== false){
$this->packetHandler($packet);
$lastLoop = 0;
}else{
++$lastLoop;
if($lastLoop < 16){
usleep(1);
}elseif($lastLoop >= 128){
usleep(100);
}elseif($lastLoop >= 256){
usleep(512);
}
}
}
}
public function trigger($event, $data = ""){
if(isset($this->events[$event])){
foreach($this->events[$event] as $evid => $ev){
if(!is_callable($ev)){
$this->deleteEvent($evid);
continue;
}
if(is_array($ev)){
$method = $ev[1];
$ev[0]->$method($data, $event);
}else{
$ev($data, $event);
}
}
}elseif(isset(Deprecation::$events[$event])){
$sub = "";
if(Deprecation::$events[$event] !== false){
$sub = " Substitute \"".Deprecation::$events[$event]."\" found.";
}
console("[ERROR] Event \"$event\" has been deprecated.$sub [Trigger]");
}
}
public function schedule($ticks, callable $callback, $data = array(), $repeat = false, $eventName = "server.schedule"){
if(!is_callable($callback)){
return false;
}
$chcnt = $this->scheduleCnt++;
$this->schedule[$chcnt] = array($callback, $data, $eventName);
$this->query("INSERT INTO actions (ID, interval, last, repeat) VALUES(".$chcnt.", ".($ticks / 20).", ".microtime(true).", ".(((bool) $repeat) === true ? 1:0).");");
return $chcnt;
}
public function tickerFunction($time){
//actions that repeat every x time will go here
$this->preparedSQL->selectActions->reset();
$this->preparedSQL->selectActions->bindValue(":time", $time, SQLITE3_FLOAT);
$actions = $this->preparedSQL->selectActions->execute();
if($actions instanceof SQLite3Result){
while(($action = $actions->fetchArray(SQLITE3_ASSOC)) !== false){
$cid = $action["ID"];
$this->preparedSQL->updateAction->reset();
$this->preparedSQL->updateAction->bindValue(":time", $time, SQLITE3_FLOAT);
$this->preparedSQL->updateAction->bindValue(":id", $cid, SQLITE3_INTEGER);
$this->preparedSQL->updateAction->execute();
$schedule = $this->schedule[$cid];
if(!is_callable($schedule[0])){
$return = false;
}else{
$return = call_user_func($schedule[0], $schedule[1], $schedule[2]);
}
if($action["repeat"] == 0 or $return === false){
$this->query("DELETE FROM actions WHERE ID = ".$action["ID"].";");
$this->schedule[$cid] = null;
unset($this->schedule[$cid]);
}
}
$actions->finalize();
}
}
public function event($event,callable $func){
if(!is_callable($func)){
return false;
}elseif(isset(Deprecation::$events[$event])){
$sub = "";
if(Deprecation::$events[$event] !== false){
$sub = " Substitute \"".Deprecation::$events[$event]."\" found.";
}
console("[ERROR] Event \"$event\" has been deprecated.$sub [Attach to ".(is_array($func) ? get_class($func[0])."::".$func[1]:$func)."]");
}
$evid = $this->evCnt++;
if(!isset($this->events[$event])){
$this->events[$event] = array();
}
$this->events[$event][$evid] = $func;
$this->eventsID[$evid] = $event;
console("[INTERNAL] Attached ".(is_array($func) ? get_class($func[0])."::".$func[1]:$func)." to event ".$event." (ID ".$evid.")", true, true, 3);
return $evid;
}
public function deleteEvent($id){
$id = (int) $id;
if(isset($this->eventsID[$id])){
$ev = $this->eventsID[$id];
$this->eventsID[$id] = null;
unset($this->eventsID[$id]);
$this->events[$ev][$id] = null;
unset($this->events[$ev][$id]);
if(count($this->events[$ev]) === 0){
unset($this->events[$ev]);
}
}
}
}

278
src/build/compile.sh Executable file
View File

@ -0,0 +1,278 @@
#!/bin/bash
COMPILER_VERSION="0.13"
PHP_VERSION="5.5.3"
ZEND_VM="GOTO"
LIBEDIT_VERSION="0.3"
ZLIB_VERSION="1.2.8"
PTHREADS_VERSION="0.0.44"
CURL_VERSION="curl-7_32_0"
echo "[PocketMine] PHP installer and compiler for Linux & Mac"
DIR="$(pwd)"
date > "$DIR/install.log" 2>&1
uname -a >> "$DIR/install.log" 2>&1
echo "[INFO] Checking dependecies"
type make >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"make\""; read -p "Press [Enter] to continue..."; exit 1; }
type autoconf >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"autoconf\""; read -p "Press [Enter] to continue..."; exit 1; }
type automake >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"automake\""; read -p "Press [Enter] to continue..."; exit 1; }
type libtool >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"libtool\""; read -p "Press [Enter] to continue..."; exit 1; }
type m4 >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"m4\""; read -p "Press [Enter] to continue..."; exit 1; }
type wget >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"wget\""; read -p "Press [Enter] to continue..."; exit 1; }
export CC="gcc"
COMPILE_FOR_ANDROID=no
RANLIB=ranlib
if [ "$1" == "rpi" ]; then
[ -z "$march" ] && march=armv6zk;
[ -z "$mtune" ] && mtune=arm1176jzf-s;
[ -z "$CFLAGS" ] && CFLAGS="-mfloat-abi=hard -mfpu=vfp";
echo "[INFO] Compiling for Raspberry Pi ARMv6zk hard float"
elif [ "$1" == "mac" ]; then
[ -z "$march" ] && march=prescott;
[ -z "$mtune" ] && mtune=generic;
[ -z "$CFLAGS" ] && CFLAGS="-fomit-frame-pointer";
echo "[INFO] Compiling for Intel MacOS"
elif [ "$1" == "crosscompile" ]; then
if [ "$2" == "android" ] || [ "$2" == "android-armv6" ]; then
COMPILE_FOR_ANDROID=yes
[ -z "$march" ] && march=armv6;
[ -z "$mtune" ] && mtune=generic;
TOOLCHAIN_PREFIX="arm-none-linux-gnueabi"
export CC="$TOOLCHAIN_PREFIX-gcc"
CONFIGURE_FLAGS="--host=$TOOLCHAIN_PREFIX"
[ -z "$CFLAGS" ] && CFLAGS="-uclibc";
echo "[INFO] Cross-compiling for Android ARMv6"
elif [ "$2" == "android-armv7" ]; then
COMPILE_FOR_ANDROID=yes
[ -z "$march" ] && march=armv7a;
[ -z "$mtune" ] && mtune=generic-armv7-a;
TOOLCHAIN_PREFIX="arm-none-linux-gnueabi"
export CC="$TOOLCHAIN_PREFIX-gcc"
CONFIGURE_FLAGS="--host=$TOOLCHAIN_PREFIX"
[ -z "$CFLAGS" ] && CFLAGS="-uclibc";
echo "[INFO] Cross-compiling for Android ARMv7"
elif [ "$2" == "rpi" ]; then
TOOLCHAIN_PREFIX="arm-linux-gnueabihf"
[ -z "$march" ] && march=armv6zk;
[ -z "$mtune" ] && mtune=arm1176jzf-s;
[ -z "$CFLAGS" ] && CFLAGS="-mfloat-abi=hard -mfpu=vfp";
export CC="$TOOLCHAIN_PREFIX-gcc"
CONFIGURE_FLAGS="--host=$TOOLCHAIN_PREFIX"
[ -z "$CFLAGS" ] && CFLAGS="-uclibc";
echo "[INFO] Cross-compiling for Raspberry Pi ARMv6zk hard float"
elif [ "$2" == "mac" ]; then
[ -z "$march" ] && march=prescott;
[ -z "$mtune" ] && mtune=generic;
[ -z "$CFLAGS" ] && CFLAGS="-fomit-frame-pointer";
TOOLCHAIN_PREFIX="i686-apple-darwin10"
export CC="$TOOLCHAIN_PREFIX-gcc"
CONFIGURE_FLAGS="--host=$TOOLCHAIN_PREFIX"
#zlib doesn't use the correct ranlib
RANLIB=$TOOLCHAIN_PREFIX-ranlib
echo "[INFO] Cross-compiling for Intel MacOS"
else
echo "Please supply a proper platform [android android-armv6 android-armv7 rpi mac] to cross-compile"
exit 1
fi
else
echo "[INFO] Compiling for current machine"
fi
type $CC >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"$CC\""; read -p "Press [Enter] to continue..."; exit 1; }
[ -z "$THREADS" ] && THREADS=1;
[ -z "$march" ] && march=native;
[ -z "$mtune" ] && mtune=native;
[ -z "$CFLAGS" ] && CFLAGS="";
[ -z "$CONFIGURE_FLAGS" ] && CONFIGURE_FLAGS="";
$CC -O3 -march=$march -mtune=$mtune -fno-gcse $CFLAGS -Q --help=target >> "$DIR/install.log" 2>&1
if [ $? -ne 0 ]; then
$CC -O3 -fno-gcse $CFLAGS -Q --help=target >> "$DIR/install.log" 2>&1
if [ $? -ne 0 ]; then
export CFLAGS="-O3 -fno-gcse "
else
export CFLAGS="-O3 -fno-gcse $CFLAGS"
fi
else
export CFLAGS="-O3 -march=$march -mtune=$mtune -fno-gcse $CFLAGS"
fi
rm -r -f install_data/ >> "$DIR/install.log" 2>&1
rm -r -f php5/ >> "$DIR/install.log" 2>&1
rm -r -f bin/ >> "$DIR/install.log" 2>&1
mkdir -m 0777 install_data >> "$DIR/install.log" 2>&1
mkdir -m 0777 php5 >> "$DIR/install.log" 2>&1
mkdir -m 0777 bin >> "$DIR/install.log" 2>&1
cd install_data
set -e
#PHP 5
echo -n "[PHP] downloading $PHP_VERSION..."
wget http://php.net/get/php-$PHP_VERSION.tar.gz/from/this/mirror -q -O - | tar -zx >> "$DIR/install.log" 2>&1
mv php-$PHP_VERSION php
echo " done!"
if [ 1 ] || [ "$1" == "crosscompile" ] || [ "$1" == "rpi" ]; then
HAVE_LIBEDIT="--without-libedit"
else
#libedit
echo -n "[libedit] downloading $LIBEDIT_VERSION..."
wget http://download.sourceforge.net/project/libedit/libedit/libedit-$LIBEDIT_VERSION/libedit-$LIBEDIT_VERSION.tar.gz -q -O - | tar -zx >> "$DIR/install.log" 2>&1
echo -n " checking..."
cd libedit
./configure --prefix="$DIR/install_data/php/ext/libedit" --enable-static >> "$DIR/install.log" 2>&1
echo -n " compiling..."
if make -j $THREADS >> "$DIR/install.log" 2>&1; then
echo -n " installing..."
make install >> "$DIR/install.log" 2>&1
HAVE_LIBEDIT="--with-libedit=\"$DIR/install_data/php/ext/libedit\""
else
echo -n " disabling..."
HAVE_LIBEDIT="--without-libedit"
fi
echo -n " cleaning..."
cd ..
rm -r -f ./libedit
echo " done!"
fi
#zlib
echo -n "[zlib] downloading $ZLIB_VERSION..."
wget http://zlib.net/zlib-$ZLIB_VERSION.tar.gz -q -O - | tar -zx >> "$DIR/install.log" 2>&1
mv zlib-$ZLIB_VERSION zlib
echo -n " checking..."
cd zlib
RANLIB=$RANLIB ./configure --prefix="$DIR/install_data/php/ext/zlib" \
--static >> "$DIR/install.log" 2>&1
echo -n " compiling..."
make -j $THREADS >> "$DIR/install.log" 2>&1
echo -n " installing..."
make install >> "$DIR/install.log" 2>&1
echo -n " cleaning..."
cd ..
rm -r -f ./zlib
echo " done!"
if [ "$(uname -s)" == "Darwin" ] && [ "$1" != "crosscompile" ] && [ "$2" != "curl" ]; then
HAVE_CURL="shared,/usr/local"
else
#curl
echo -n "[cURL] downloading $CURL_VERSION..."
wget https://github.com/bagder/curl/archive/$CURL_VERSION.tar.gz --no-check-certificate -q -O - | tar -zx >> "$DIR/install.log" 2>&1
mv curl-$CURL_VERSION curl
echo -n " checking..."
cd curl
./buildconf >> "$DIR/install.log" 2>&1
./configure --enable-ipv6 \
--enable-optimize \
--enable-http \
--enable-ftp \
--disable-dict \
--enable-file \
--disable-gopher \
--disable-imap \
--disable-pop3 \
--disable-rtsp \
--disable-smtp \
--disable-telnet \
--disable-tftp \
--prefix="$DIR/install_data/php/ext/curl" \
--disable-shared \
$CONFIGURE_FLAGS >> "$DIR/install.log" 2>&1
echo -n " compiling..."
make -j $THREADS >> "$DIR/install.log" 2>&1
echo -n " installing..."
make install >> "$DIR/install.log" 2>&1
echo -n " cleaning..."
cd ..
rm -r -f ./curl
echo " done!"
HAVE_CURL="$DIR/install_data/php/ext/curl"
fi
#pthreads
echo -n "[PHP pthreads] downloading $PTHREADS_VERSION..."
wget http://pecl.php.net/get/pthreads-$PTHREADS_VERSION.tgz --no-check-certificate -q -O - | tar -zx >> "$DIR/install.log" 2>&1
mv pthreads-$PTHREADS_VERSION "$DIR/install_data/php/ext/pthreads"
echo " done!"
echo -n "[PHP]"
set +e
if which free >/dev/null; then
MAX_MEMORY=$(free -m | awk '/^Mem:/{print $2}')
else
MAX_MEMORY=$(top -l 1 | grep PhysMem: | awk '{print $10}' | tr -d 'a-zA-Z')
fi
if [ $MAX_MEMORY -gt 512 ] && [ "$1" != "crosscompile" ]; then
echo -n " enabling optimizations..."
OPTIMIZATION="--enable-inline-optimization "
else
OPTIMIZATION="--disable-inline-optimization "
fi
set -e
echo -n " checking..."
cd php
rm -rf ./aclocal.m4 >> "$DIR/install.log" 2>&1
rm -rf ./autom4te.cache/ >> "$DIR/install.log" 2>&1
rm -f ./configure >> "$DIR/install.log" 2>&1
./buildconf --force >> "$DIR/install.log" 2>&1
if [ "$1" == "crosscompile" ]; then
sed -i 's/pthreads_working=no/pthreads_working=yes/' ./configure
export LIBS="-lpthread -ldl"
fi
./configure $OPTIMIZATION--prefix="$DIR/php5" \
--exec-prefix="$DIR/php5" \
--with-curl="$HAVE_CURL" \
--with-zlib="$DIR/install_data/php/ext/zlib" \
$HAVE_LIBEDIT \
--disable-libxml \
--disable-xml \
--disable-dom \
--disable-simplexml \
--disable-xmlreader \
--disable-xmlwriter \
--disable-cgi \
--disable-session \
--disable-zip \
--disable-debug \
--disable-phar \
--enable-ctype \
--enable-sockets \
--enable-shared=no \
--enable-static=yes \
--enable-shmop \
--enable-pcntl \
--enable-pthreads \
--enable-maintainer-zts \
--enable-zend-signals \
--enable-embedded-mysqli \
--enable-bcmath \
--enable-cli \
--without-pear \
--without-iconv \
--disable-pdo \
--without-pdo-sqlite \
--with-zend-vm=$ZEND_VM \
$CONFIGURE_FLAGS >> "$DIR/install.log" 2>&1
echo -n " compiling..."
if [ $COMPILE_FOR_ANDROID == "yes" ]; then
sed -i 's/-export-dynamic/-all-static/g' Makefile
fi
make -j $THREADS >> "$DIR/install.log" 2>&1
echo -n " installing..."
make install >> "$DIR/install.log" 2>&1
echo " done!"
cd "$DIR"
echo -n "[INFO] Cleaning up..."
rm -r -f install_data/ >> "$DIR/install.log" 2>&1
mv php5/bin/php bin/php
rm -r -f php5/ >> "$DIR/install.log" 2>&1
date >> "$DIR/install.log" 2>&1
echo " done!"
echo "[PocketMine] You should start the server now using \"./start.sh\""
echo "[PocketMine] If it doesn't works, please send the \"install.log\" file to the Bug Tracker"

View File

@ -1,71 +0,0 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
*/
class Async extends Thread {
/**
* Provide a passthrough to call_user_func_array
**/
public function __construct($method, $params = array()){
$this->method = $method;
$this->params = $params;
$this->result = null;
$this->joined = false;
}
/**
* The smallest thread in the world
**/
public function run(){
if(($this->result=call_user_func_array($this->method, $this->params))){
return true;
}else{
return false;
}
}
/**
* Static method to create your threads from functions ...
**/
public static function call($method, $params = array()){
$thread = new Async($method, $params);
if($thread->start()){
return $thread;
} /** else throw Nastyness **/
}
/**
* Do whatever, result stored in $this->result, don't try to join twice
**/
public function __toString(){
if(!$this->joined) {
$this->joined = true;
$this->join();
}
return $this->result;
}
}

View File

@ -1,31 +0,0 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
*/
/*
class BlockIterator implements Iterator{
}*/

View File

@ -1,243 +0,0 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
*/
class BlockFace{
const BOTTOM = 0;
const TOP = 1;
const DOWN = 0;
const UP = 1;
const SOUTH = 3;
const EAST = 5;
const NORTH = 2;
const WEST = 4;
public static function setPosition(&$data, $face){
switch((int) $face){
case 0:
--$data["y"];
break;
case 1:
++$data["y"];
break;
case 2:
--$data["z"];
break;
case 3:
++$data["z"];
break;
case 4:
--$data["x"];
break;
case 5:
++$data["x"];
break;
default:
return false;
}
return true;
}
}
class Material{
static $flowable = array(
0 => true,
6 => true,
30 => true,
31 => true,
32 => true,
37 => true,
38 => true,
39 => true,
40 => true,
50 => true,
51 => true,
55 => true,
59 => true,
78 => true,
105 => true,
);
static $unbreakable = array(
0 => true,
7 => true,
8 => true,
9 => true,
10 => true,
11 => true,
);
static $transparent = array(
0 => true,
6 => true,
8 => true,
9 => true,
10 => true,
11 => true,
18 => true,
20 => true,
26 => true,
30 => true,
31 => true,
32 => true,
37 => true,
38 => true,
39 => true,
40 => true,
44 => true,
46 => true,
50 => true,
51 => true,
53 => true,
59 => true,
65 => true,
67 => true,
78 => true,
79 => true,
83 => true,
89 => true,
96 => true,
102 => true,
105 => true,
107 => true,
108 => true,
);
static $replaceable = array(
0 => true,
8 => true,
9 => true,
10 => true,
11 => true,
31 => true,
51 => true,
78 => true,
);
static $activable = array(
2 => true,
3 => true,
6 => true,
26 => true,
31 => true,
//46 => true,
51 => true,
54 => true,
58 => true,
59 => true,
61 => true,
62 => true,
64 => true,
71 => true,
78 => true,
96 => true,
105 => true,
107 => true,
247 => true,
);
static $placeable = array(
1 => true,
2 => true,
3 => true,
4 => true,
5 => true,
6 => true,
//7 => true,
8 => true,
9 => true,
10 => true,
11 => true,
12 => true,
13 => true,
14 => true,
15 => true,
16 => true,
17 => true,
18 => true,
19 => true,
20 => true,
21 => true,
22 => true,
24 => true,
355 => 26,
30 => true,
35 => true,
37 => true,
38 => true,
39 => true,
40 => true,
41 => true,
42 => true,
43 => true,
44 => true,
45 => true,
46 => true,
47 => true,
48 => true,
49 => true,
50 => true,
53 => true,
54 => true,
56 => true,
59 => true,
57 => true,
58 => true,
295 => 59,
61 => true,
324 => 64,
65 => true,
67 => true,
330 => 71,
73 => true,
79 => true,
80 => true,
81 => true,
82 => true,
83 => true,
85 => true,
86 => true,
87 => true,
88 => true,
89 => true,
91 => true,
96 => true,
98 => true,
102 => true,
103 => true,
362 => 105,
107 => true,
108 => true,
246 => true,
247 => true,
);
static $blocks = array(
0 => "Air",
1 => "Stone",
2 => "Grass",
3 => "Dirt",
4 => "Cobblestone",
5 => "Wooden Planks",
6 => "Sapling",
7 => "Bedrock",
);
}

View File

@ -1,35 +0,0 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
*/
class Deprecation{
public static $events = array(
"world.block.change" => "block.change",
);
}

View File

@ -1,565 +0,0 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
*/
class Player{
private $server;
private $queue = array();
private $buffer = array();
private $evid = array();
var $timeout;
var $connected = true;
var $clientID;
var $ip;
var $port;
var $counter = array(0, 0, 0);
var $username;
var $eid = false;
var $data = array();
var $entity = false;
var $auth = false;
var $CID;
var $MTU;
var $spawned = false;
var $inventory;
var $equipment = array(1, 0);
var $loggedIn = false;
function __construct(PocketMinecraftServer $server, $clientID, $ip, $port, $MTU){
$this->MTU = $MTU;
$this->server = $server;
$this->clientID = $clientID;
$this->CID = $this->server->clientID($ip, $port);
$this->ip = $ip;
$this->port = $port;
$this->timeout = microtime(true) + 25;
$this->inventory = array_fill(0, 36, array(0, 0, 0));
$this->evid[] = $this->server->event("server.tick", array($this, "onTick"));
$this->evid[] = $this->server->event("server.close", array($this, "close"));
console("[DEBUG] New Session started with ".$ip.":".$port.". MTU ".$this->MTU.", Client ID ".$this->clientID, true, true, 2);
}
public function onTick($time, $event){
if($event !== "server.tick"){ //WTF??
return;
}
if($time > $this->timeout){
$this->close("timeout");
}else{
if(!empty($this->queue)){
$cnt = 0;
while($cnt < 4){
$p = array_shift($this->queue);
if($p === null){
break;
}
switch($p[0]){
case 0:
$this->dataPacket($p[1], $p[2], false, $p[3]);
break;
case 1:
eval($p[1]);
break;
}
++$cnt;
}
}
}
}
public function save(){
if(is_object($this->entity)){
$this->data["spawn"] = array(
"x" => $this->entity->x,
"y" => $this->entity->y,
"z" => $this->entity->z,
);
}
}
public function close($reason = "", $msg = true){
if($this->connected === true){
foreach($this->evid as $ev){
$this->server->deleteEvent($ev);
}
$this->server->api->dhandle("player.quit", $this);
$reason = $reason == "" ? "server stop":$reason;
$this->save();
$this->eventHandler(new Container("You have been kicked. Reason: ".$reason), "server.chat");
$this->dataPacket(MC_LOGIN_STATUS, array(
"status" => 1,
));
$this->dataPacket(MC_DISCONNECT);
$this->connected = false;
if($msg === true){
$this->server->api->chat->broadcast($this->username." left the game");
}
console("[INFO] Session with \x1b[36m".$this->ip.":".$this->port."\x1b[0m Client ID ".$this->clientID." closed due to ".$reason);
$this->server->api->player->remove($this->CID);
}
}
public function addItem($type, $damage, $count){
while($count > 0){
$add = 0;
foreach($this->inventory as $s => $data){
if($data[0] === 0){
$add = min(64, $count);
$this->inventory[$s] = array($type, $damage, $add);
break;
}elseif($data[0] === $type and $data[1] === $damage){
$add = min(64 - $data[2], $count);
if($add <= 0){
continue;
}
$this->inventory[$s] = array($type, $damage, $data[2] + $add);
break;
}
}
if($add === 0){
return false;
}
$count -= $add;
}
return true;
}
public function removeItem($type, $damage, $count){
while($count > 0){
$remove = 0;
foreach($this->inventory as $s => $data){
if($data[0] === $type and $data[1] === $damage){
$remove = min($count, $data[2]);
if($remove < $data[2]){
$this->inventory[$s][2] -= $remove;
}else{
$this->inventory[$s] = array(0, 0, 0);
}
break;
}
}
if($remove === 0){
return false;
}
$count -= $remove;
}
return true;
}
public function hasItem($type, $damage = false){
foreach($this->inventory as $s => $data){
if($data[0] === $type and ($data[1] === $damage or $damage === false) and $data[2] > 0){
return true;
}
}
return false;
}
public function eventHandler($data, $event){
switch($event){
case "player.block.place":
if($data["eid"] === $this->eid and $this->server->gamemode === 0){
$this->removeItem($data["original"][0], $data["original"][1], 1);
}
break;
case "player.pickup":
if($data["eid"] === $this->eid){
$data["eid"] = 0;
if($this->server->gamemode === 0){
$this->addItem($data["entity"]->type, $data["entity"]->meta, $data["entity"]->stack);
}
}
$this->dataPacket(MC_TAKE_ITEM_ENTITY, $data);
break;
case "player.equipment.change":
if($data["eid"] === $this->eid){
break;
}
$this->dataPacket(MC_PLAYER_EQUIPMENT, $data);
break;
case "block.change":
$this->dataPacket(MC_UPDATE_BLOCK, $data);
break;
case "entity.move":
if($data->eid === $this->eid){
break;
}
$this->dataPacket(MC_MOVE_ENTITY_POSROT, array(
"eid" => $data->eid,
"x" => $data->x,
"y" => $data->y,
"z" => $data->z,
"yaw" => $data->yaw,
"pitch" => $data->pitch,
));
break;
case "entity.remove":
if($data->eid === $this->eid){
break;
}
$this->dataPacket(MC_REMOVE_ENTITY, array(
"eid" => $data->eid,
));
break;
case "server.time":
$this->dataPacket(MC_SET_TIME, array(
"time" => $data,
));
break;
case "entity.animate":
if($data["eid"] === $this->eid){
break;
}
$this->dataPacket(MC_ANIMATE, array(
"eid" => $data["eid"],
"action" => $data["action"],
));
break;
case "server.chat":
if(($data instanceof Container) === true){
if(!$data->check($this->username)){
return;
}else{
$message = $data->get();
}
}else{
$message = (string) $data;
}
$this->dataPacket(MC_CHAT, array(
"message" => str_replace("@username", $this->username, $message),
));
break;
}
}
public function handle($pid, $data){
if($this->connected === true){
$this->timeout = microtime(true) + 25;
switch($pid){
case 0xa0: //NACK
if(isset($this->buffer[$data[2]])){
array_unshift($this->queue, array(0, $this->buffer[$data[2]][0], $this->buffer[$data[2]][1], $data[2]));
}
if(isset($data[3])){
if(isset($this->buffer[$data[3]])){
array_unshift($this->queue, array(0, $this->buffer[$data[3]][0], $this->buffer[$data[3]][1], $data[3]));
}
}
break;
case 0xc0: //ACK
$diff = $data[2] - $this->counter[2];
if($diff > 8){ //Packet recovery
array_unshift($this->queue, array(0, $this->buffer[$data[2]][0], $this->buffer[$data[2]][1], $data[2]));
}
$this->counter[2] = $data[2];
unset($this->buffer[$data[2]]);
if(isset($data[3])){
$diff = $data[3] - $this->counter[2];
if($diff > 8){ //Packet recovery
array_unshift($this->queue, array(0, $this->buffer[$data[3]][0], $this->buffer[$data[3]][1], $data[3]));
}
$this->counter[2] = $data[3];
unset($this->buffer[$data[3]]);
}
break;
case 0x07:
$this->send(0x08, array(
MAGIC,
$this->server->serverID,
$this->port,
$data[3],
0,
));
break;
case 0x80:
case 0x81:
case 0x82:
case 0x83:
case 0x84:
case 0x85:
case 0x86:
case 0x87:
case 0x88:
case 0x89:
case 0x8a:
case 0x8b:
case 0x8c:
case 0x8d:
case 0x8e:
case 0x8f:
if(isset($data[0])){
$diff = $data[0] - $this->counter[1];
if($diff > 1){ //Packet recovery
for($i = $this->counter[1]; $i < $data[0]; ++$i){
$this->send(0xa0, array(1, true, $i));
}
$this->counter[1] = $data[0];
}elseif($diff === 1){
$this->counter[1] = $data[0];
}
$this->send(0xc0, array(1, true, $data[0]));
}
switch($data["id"]){
case MC_KEEP_ALIVE:
break;
case 0x03:
break;
case MC_DISCONNECT:
$this->close("client disconnect");
break;
case MC_CLIENT_CONNECT:
$this->dataPacket(MC_SERVER_HANDSHAKE, array(
"port" => $this->port,
"session" => $data["session"],
"session2" => Utils::readLong("\x00\x00\x00\x00\x04\x44\x0b\xa9"),
));
break;
case MC_CLIENT_HANDSHAKE:
break;
case MC_LOGIN:
if($this->loggedIn === true){
break;
}
$this->loggedIn = true;
$this->username = str_replace(array("\x00", "/", " ", "\r", "\n"), array("", "-", "_", "", ""), $data["username"]);
if($this->username == ""){
$this->close("bad username", false);
break;
}
$o = $this->server->api->player->getOffline($this->username);
if($this->server->whitelist === true and !$this->server->api->ban->inWhitelist($this->username)){
$this->close("\"\x1b[33m".$this->username."\x1b[0m\" not being on white-list", false);
break;
}elseif($this->server->api->ban->isBanned($this->username) or $this->server->api->ban->isIPBanned($this->ip)){
$this->close("\"\x1b[33m".$this->username."\x1b[0m\" is banned!", false);
}
$u = $this->server->api->player->get($this->username);
$c = $this->server->api->player->getByClientID($this->clientID);
if($u !== false){
$u->close("logged in from another location");
}
if($c !== false){
$c->close("logged in from another location");
}
if($this->server->api->dhandle("player.join", $this) === false){
$this->close();
return;
}
$this->server->api->player->add($this->CID);
$this->auth = true;
if(!isset($this->data["inventory"]) or $this->server->gamemode === 1){
$this->data["inventory"] = $this->inventory;
}
$this->inventory = &$this->data["inventory"];
$this->data["lastIP"] = $this->ip;
$this->data["lastID"] = $this->clientID;
$this->server->api->player->saveOffline($this->username, $this->data);
$this->dataPacket(MC_LOGIN_STATUS, array(
"status" => 0,
));
$this->dataPacket(MC_START_GAME, array(
"seed" => $this->server->seed,
"x" => $this->data["spawn"]["x"],
"y" => $this->data["spawn"]["y"],
"z" => $this->data["spawn"]["z"],
"unknown1" => 0,
"gamemode" => $this->server->gamemode,
"eid" => 0,
));
break;
case MC_READY:
switch($data["status"]){
case 1:
if($this->spawned !== false){
break;
}
$this->spawned = true;
$this->entity = $this->server->api->entity->add(ENTITY_PLAYER, 0, array("player" => $this));
$this->eid = $this->entity->eid;
$this->server->query("UPDATE players SET EID = ".$this->eid." WHERE clientID = ".$this->clientID.";");
$this->entity->x = $this->data["spawn"]["x"];
$this->entity->y = $this->data["spawn"]["y"];
$this->entity->z = $this->data["spawn"]["z"];
$this->entity->setName($this->username);
$this->entity->data["clientID"] = $this->clientID;
$this->server->api->entity->spawnAll($this);
$this->server->api->entity->spawnToAll($this->eid);
$this->evid[] = $this->server->event("server.time", array($this, "eventHandler"));
$this->evid[] = $this->server->event("server.chat", array($this, "eventHandler"));
$this->evid[] = $this->server->event("entity.remove", array($this, "eventHandler"));
$this->evid[] = $this->server->event("entity.move", array($this, "eventHandler"));
$this->evid[] = $this->server->event("entity.animate", array($this, "eventHandler"));
$this->evid[] = $this->server->event("player.equipment.change", array($this, "eventHandler"));
$this->evid[] = $this->server->event("player.pickup", array($this, "eventHandler"));
$this->evid[] = $this->server->event("block.change", array($this, "eventHandler"));
$this->evid[] = $this->server->event("player.block.place", array($this, "eventHandler"));
console("[DEBUG] Player \"".$this->username."\" EID ".$this->eid." spawned at X ".$this->entity->x." Y ".$this->entity->y." Z ".$this->entity->z, true, true, 2);
$this->eventHandler(new Container($this->server->motd), "server.chat");
if($this->MTU <= 548){
$this->eventHandler("Your connection is bad, you may experience lag and slow map loading.", "server.chat");
}
foreach($this->inventory as $s => $data){
if($data[0] <= 0 or $data[2] <= 0){
$this->inventory[$s] = array(0, 0, 0);
continue;
}
$e = $this->server->api->entity->add(ENTITY_ITEM, $data[0], array(
"x" => $this->entity->x + 0.5,
"y" => $this->entity->y + 0.19,
"z" => $this->entity->z + 0.5,
"meta" => $data[1],
"stack" => $data[2],
));
$this->server->api->entity->spawnTo($e->eid, $this);
}
break;
case 2://Chunk loaded?
break;
}
break;
case MC_MOVE_PLAYER:
if(is_object($this->entity)){
$this->entity->setPosition($data["x"], $data["y"], $data["z"], $data["yaw"], $data["pitch"]);
$this->server->api->dhandle("player.move", $this->entity);
}
break;
case MC_PLAYER_EQUIPMENT:
$data["eid"] = $this->eid;
if($this->server->handle("player.equipment.change", $data) !== false){
$this->equipment[0] = $data["block"];
$this->equipment[1] = $data["meta"];
console("[DEBUG] EID ".$this->eid." has now ".$data["block"].":".$data["meta"]." in their hands!", true, true, 2);
}
break;
case MC_REQUEST_CHUNK:
$this->actionQueue('
$max = max(1, floor(($this->MTU - 16 - 255) / 192));
$chunk = $this->server->api->level->getOrderedChunk('.$data["x"].', '.$data["z"].', $max);
foreach($chunk as $d){
$this->dataPacket(MC_CHUNK_DATA, array(
"x" => '.$data["x"].',
"z" => '.$data["z"].',
"data" => $d,
), true);
}
');
console("[INTERNAL] Chunk X ".$data["x"]." Z ".$data["z"]." requested", true, true, 3);
break;
case MC_USE_ITEM:
$data["eid"] = $this->eid;
if(Utils::distance($this->entity->position, $data) > 10){
break;
}elseif($this->server->gamemode === 0 and !$this->hasItem($data["block"], $data["meta"])){
console("[DEBUG] Player \"".$this->username."\" tried to place not got block (or crafted block)", true, true, 2);
//break;
}
$this->server->handle("player.block.action", $data);
break;
case MC_REMOVE_BLOCK:
$data["eid"] = $this->eid;
if(Utils::distance($this->entity->position, $data) > 8){
break;
}
$this->server->handle("player.block.break", $data);
break;
case MC_INTERACT:
if(isset($this->server->entities[$data["target"]]) and Utils::distance($this->entity->position, $this->server->entities[$data["target"]]->position) <= 8){
if($this->handle("player.interact", $data) !== false){
console("[DEBUG] EID ".$this->eid." attacked EID ".$data["target"], true, true, 2);
if($this->server->gamemode !== 1 and $this->server->difficulty > 0){
$this->server->api->entity->harm($data["target"], $this->server->difficulty, $this->eid);
}
}
}
break;
case MC_ANIMATE:
$this->server->api->dhandle("entity.animate", array("eid" => $this->eid, "action" => $data["action"]));
break;
case MC_RESPAWN:
$this->entity->invincible = true;
$this->entity->setHealth(20, "respawn");
$this->entity->setPosition($data["x"], $data["y"], $data["z"], 0, 0);
$this->entity->invincible = false;
break;
case MC_SET_HEALTH:
if($this->server->gamemode === 1){
break;
}
//$this->entity->setHealth($data["health"], "client");
break;
case MC_DROP_ITEM:
if($this->server->handle("player.drop", $data) !== false){
$this->server->api->block->drop($this->entity->x, $this->entity->y, $this->entity->z, $data["block"], $data["meta"], $data["stack"]);
}
break;
default:
console("[DEBUG] Unhandled 0x".dechex($data["id"])." Data Packet for Client ID ".$this->clientID.": ".print_r($data, true), true, true, 2);
break;
}
break;
}
}
}
public function send($pid, $data = array(), $raw = false){
if($this->connected === true){
$this->server->send($pid, $data, $raw, $this->ip, $this->port);
}
}
public function actionQueue($code){
$this->queue[] = array(1, $code);
}
public function dataPacket($id, $data = array(), $queue = false, $count = false){
if($queue === true){
$this->queue[] = array(0, $id, $data, $count);
}else{
if($count === false){
$count = $this->counter[0];
++$this->counter[0];
if(count($this->buffer) >= 512){
array_shift($this->buffer);
}
$this->buffer[$count] = array($id, $data);
}
$data["id"] = $id;
$this->send(0x80, array(
$count,
0x00,
$data,
));
}
}
}

View File

@ -1,643 +0,0 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
*/
class PocketMinecraftServer{
var $version, $invisible, $api, $tickMeasure, $preparedSQL, $seed, $gamemode, $name, $maxClients, $clients, $eidCnt, $custom, $description, $motd, $timePerSecond, $spawn, $entities, $mapDir, $mapName, $map, $levelData, $tileEntities;
private $database, $interface, $evCnt, $handCnt, $events, $handlers, $serverType, $lastTick, $ticker;
private function load(){
$this->version = new VersionString();
console("[INFO] \x1b[33;1mPocketMine-MP ".MAJOR_VERSION." #".$this->version->getNumber()." by @shoghicp, LGPL License", true, true, 0);
console("[INFO] Target Minecraft PE: \x1b[36;1m".CURRENT_MINECRAFT_VERSION."\x1b[0m, protocol #".CURRENT_PROTOCOL, true, true, 0);
if($this->version->isDev()){
console("[INFO] \x1b[31;1mThis is a Development version");
}
console("[INFO] Starting Minecraft PE Server at *:".$this->port);
if($this->port < 19132 or $this->port > 19135){
console("[WARNING] You've selected a not-standard port. Normal port range is from 19132 to 19135 included");
}
$this->serverID = $this->serverID === false ? Utils::readLong(Utils::getRandomBytes(8)):$this->serverID;
$this->seed = $this->seed === false ? Utils::readInt(Utils::getRandomBytes(4)):$this->seed;
console("[INFO] Loading database...");
$this->startDatabase();
$this->doTick = false;
$this->api = false;
$this->mapDir = false;
$this->mapName = false;
$this->events = array();
$this->handlers = array();
$this->map = false;
$this->invisible = false;
$this->levelData = false;
$this->difficulty = 1;
$this->tileEntities = array();
$this->entities = array();
$this->custom = array();
$this->evCnt = 0;
$this->handCnt = 0;
$this->eidCnt = 1;
$this->maxClients = 20;
$this->schedule = array();
$this->scheduleCnt = 0;
$this->description = "";
$this->whitelist = false;
$this->clients = array();
$this->spawn = array("x" => 128.5,"y" => 100,"z" => 128.5);
$this->time = 0;
$this->timePerSecond = 10;
$this->tickMeasure = array_fill(0, 40, 0);
$this->setType("normal");
$this->interface = new MinecraftInterface("255.255.255.255", $this->port, true, false);
$this->reloadConfig();
console("[INFO] Server Name: \x1b[36m".$this->name."\x1b[0m");
console("[DEBUG] Server ID: ".$this->serverID, true, true, 2);
$this->stop = false;
}
function __construct($name, $gamemode = 1, $seed = false, $port = 19132, $serverID = false){
$this->port = (int) $port; //19132 - 19135
$this->gamemode = (int) $gamemode;
$this->name = $name;
$this->motd = "Welcome to ".$name;
$this->serverID = $serverID;
$this->seed = $seed;
$this->load();
}
public function getTPS(){
$v = array_values($this->tickMeasure);
$tps = 40 / ($v[39] - $v[0]);
return round($tps, 4);
}
public function loadEvents(){
$this->action(500000, '$this->time += (int) ($this->timePerSecond / 2);$this->api->dhandle("server.time", $this->time);');
$this->action(5000000, 'if($this->difficulty < 2){$this->api->dhandle("server.regeneration", 1);}');
$this->action(1000000 * 60, '$this->reloadConfig();');
$this->action(1000000 * 60 * 10, '$this->custom = array();');
if($this->api !== false){
$this->action(1000000 * 80, '$cnt = count($this->clients); if($cnt > 1){$this->api->chat->broadcast("Online (".$cnt."): ".implode(", ",$this->api->player->online()));}');
}
$this->action(1000000 * 120, '$this->debugInfo(true);');
}
public function startDatabase(){
$this->preparedSQL = new stdClass();
$this->database = new SQLite3(":memory:");
//$this->query("PRAGMA journal_mode = OFF;");
//$this->query("PRAGMA encoding = \"UTF-8\";");
//$this->query("PRAGMA secure_delete = OFF;");
$this->query("CREATE TABLE players (clientID INTEGER PRIMARY KEY, EID NUMERIC, ip TEXT, port NUMERIC, name TEXT UNIQUE);");
$this->query("CREATE TABLE entities (EID INTEGER PRIMARY KEY, type NUMERIC, class NUMERIC, name TEXT, x NUMERIC, y NUMERIC, z NUMERIC, yaw NUMERIC, pitch NUMERIC, health NUMERIC);");
$this->query("CREATE TABLE metadata (EID INTEGER PRIMARY KEY, name TEXT, value TEXT);");
$this->query("CREATE TABLE actions (ID INTEGER PRIMARY KEY, interval NUMERIC, last NUMERIC, code TEXT, repeat NUMERIC);");
$this->query("CREATE TABLE events (ID INTEGER PRIMARY KEY, name TEXT);");
$this->query("CREATE TABLE handlers (ID INTEGER PRIMARY KEY, name TEXT, priority NUMERIC);");
//$this->query("PRAGMA synchronous = OFF;");
$this->preparedSQL->selectHandlers = $this->database->prepare("SELECT DISTINCT ID FROM handlers WHERE name = :name ORDER BY priority DESC;");
$this->preparedSQL->selectEvents = $this->database->prepare("SELECT DISTINCT ID FROM events WHERE name = :name;");
$this->preparedSQL->selectActions = $this->database->prepare("SELECT ID,code,repeat FROM actions WHERE last <= (:time - interval);");
$this->preparedSQL->updateActions = $this->database->prepare("UPDATE actions SET last = :time WHERE last <= (:time - interval);");
}
public function query($sql, $fetch = false){
console("[INTERNAL] [SQL] ".$sql, true, true, 3);
$result = $this->database->query($sql) or console("[ERROR] [SQL Error] ".$this->database->lastErrorMsg().". Query: ".$sql, true, true, 0);
if($fetch === true and ($result !== false and $result !== true)){
$result = $result->fetchArray(SQLITE3_ASSOC);
}
return $result;
}
public function reloadConfig(){
}
public function debugInfo($console = false){
$info = array();
$info["tps"] = $this->getTPS();
$info["memory_usage"] = round((memory_get_usage(true) / 1024) / 1024, 2)."MB";
$info["memory_peak_usage"] = round((memory_get_peak_usage(true) / 1024) / 1024, 2)."MB";
$info["entities"] = $this->query("SELECT count(EID) as count FROM entities;", true);
$info["entities"] = $info["entities"]["count"];
$info["events"] = $this->query("SELECT count(ID) as count FROM events;", true);
$info["events"] = $info["events"]["count"];
$info["handlers"] = $this->query("SELECT count(ID) as count FROM handlers;", true);
$info["handlers"] = $info["handlers"]["count"];
$info["actions"] = $this->query("SELECT count(ID) as count FROM actions;", true);
$info["actions"] = $info["actions"]["count"];
$info["garbage"] = gc_collect_cycles();
$this->handle("server.debug", $info);
if($console === true){
console("[DEBUG] TPS: ".$info["tps"].", Memory usage: ".$info["memory_usage"]." (Peak ".$info["memory_peak_usage"]."), Entities: ".$info["entities"].", Events: ".$info["events"].", Handlers: ".$info["handlers"].", Actions: ".$info["actions"].", Garbage: ".$info["garbage"], true, true, 2);
}
return $info;
}
public function close($reason = "stop"){
if($this->stop !== true){
if(is_int($reason)){
$reason = "signal stop";
}
if(($this->api instanceof ServerAPI) === true){
if(($this->api->chat instanceof ChatAPI) === true){
$this->api->chat->send(false, "Stopping server...");
}
}
//$this->ticker->stop = true;
$this->save(true);
$this->stop = true;
$this->trigger("server.close", $reason);
$this->interface->close();
}
}
public function chat($owner, $text, $target = false){
$this->api->chat->send($owner, $text, $target);
}
public function setType($type = "normal"){
switch($type){
case "normal":
$this->serverType = "MCCPP;Demo;";
break;
case "minecon":
$this->serverType = "MCCPP;MINECON;";
break;
}
}
public function addHandler($event, $callable, $priority = 5){
if(!is_callable($callable)){
return false;
}elseif(isset(Deprecation::$events[$event])){
$sub = "";
if(Deprecation::$events[$event] !== false){
$sub = " Substitute \"".Deprecation::$events[$event]."\" found.";
}
console("[ERROR] Event \"$event\" has been deprecated.$sub [Adding handle to ".(is_array($callable) ? get_class($callable[0])."::".$callable[1]:$callable)."]");
}
$priority = (int) $priority;
$hnid = $this->handCnt++;
$this->handlers[$hnid] = $callable;
$this->query("INSERT INTO handlers (ID, name, priority) VALUES (".$hnid.", '".str_replace("'", "\\'", $event)."', ".$priority.");");
console("[INTERNAL] New handler ".(is_array($callable) ? get_class($callable[0])."::".$callable[1]:$callable)." to special event ".$event." (ID ".$hnid.")", true, true, 3);
return $hnid;
}
public function handle($event, &$data){
$this->preparedSQL->selectHandlers->reset();
$this->preparedSQL->selectHandlers->clear();
$this->preparedSQL->selectHandlers->bindValue(":name", $event, SQLITE3_TEXT);
$handlers = $this->preparedSQL->selectHandlers->execute();
$result = true;
if($handlers !== false and $handlers !== true){
console("[INTERNAL] Handling ".$event, true, true, 3);
$call = array();
while(($hn = $handlers->fetchArray(SQLITE3_ASSOC)) !== false){
$call[(int) $hn["ID"]] = true;
}
$handlers->finalize();
foreach($call as $hnid => $boolean){
if($result !== false){
$called[$hnid] = true;
$handler = $this->handlers[$hnid];
if(is_array($handler)){
$method = $handler[1];
$result = $handler[0]->$method($data, $event);
}else{
$result = $handler($data, $event);
}
}else{
break;
}
}
}elseif(isset(Deprecation::$events[$event])){
$sub = "";
if(Deprecation::$events[$event] !== false){
$sub = " Substitute \"".Deprecation::$events[$event]."\" found.";
}
console("[ERROR] Event \"$event\" has been deprecated.$sub [Handler]");
}
if($result !== false){
$this->trigger($event, $data);
}
return $result;
}
public function eventHandler($data, $event){
switch($event){
}
}
public function loadMap(){
if($this->mapName !== false and trim($this->mapName) !== ""){
$this->levelData = unserialize(file_get_contents($this->mapDir."level.dat"));
if($this->levelData === false){
console("[ERROR] Invalid world data for \"".$this->mapDir."\. Please import the world correctly");
$this->close("invalid world data");
}
console("[INFO] Map: ".$this->levelData["LevelName"]);
$this->time = (int) $this->levelData["Time"];
$this->seed = (int) $this->levelData["RandomSeed"];
if(isset($this->levelData["SpawnX"])){
$this->spawn = array("x" => $this->levelData["SpawnX"], "y" => $this->levelData["SpawnY"], "z" => $this->levelData["SpawnZ"]);
}else{
$this->levelData["SpawnX"] = $this->spawn["x"];
$this->levelData["SpawnY"] = $this->spawn["y"];
$this->levelData["SpawnZ"] = $this->spawn["z"];
}
$this->levelData["Time"] = $this->time;
console("[INFO] Spawn: X \x1b[36m".$this->levelData["SpawnX"]."\x1b[0m Y \x1b[36m".$this->levelData["SpawnY"]."\x1b[0m Z \x1b[36m".$this->levelData["SpawnZ"]."\x1b[0m");
console("[INFO] Time: \x1b[36m".$this->time."\x1b[0m");
console("[INFO] Seed: \x1b[36m".$this->seed."\x1b[0m");
console("[INFO] Gamemode: \x1b[36m".($this->gamemode === 0 ? "survival":"creative")."\x1b[0m");
$d = array(0 => "peaceful", 1 => "easy", 2 => "normal", 3 => "hard");
console("[INFO] Difficulty: \x1b[36m".$d[$this->difficulty]."\x1b[0m");
console("[INFO] Loading map...");
$this->map = new ChunkParser();
if(!$this->map->loadFile($this->mapDir."chunks.dat")){
console("[ERROR] Couldn't load the map \"\x1b[32m".$this->levelData["LevelName"]."\x1b[0m\"!", true, true, 0);
$this->map = false;
}else{
$this->map->loadMap();
}
}else{
console("[INFO] Time: \x1b[36m".$this->time."\x1b[0m");
console("[INFO] Seed: \x1b[36m".$this->seed."\x1b[0m");
console("[INFO] Gamemode: \x1b[36m".($this->gamemode === 0 ? "survival":"creative")."\x1b[0m");
}
}
public function loadEntities(){
if($this->map !== false){
console("[INFO] Loading entities...");
$entities = unserialize(file_get_contents($this->mapDir."entities.dat"));
if($entities === false or !is_array($entities)){
console("[ERROR] Invalid world data for \"".$this->mapDir."\. Please import the world correctly");
$this->close("invalid world data");
}
foreach($entities as $entity){
if(!isset($entity["id"])){
break;
}
if(isset($this->api) and $this->api !== false){
if($entity["id"] === 64){ //Item Drop
$e = $this->api->entity->add(ENTITY_ITEM, $entity["Item"]["id"], array(
"meta" => $entity["Item"]["Damage"],
"stack" => $entity["Item"]["Count"],
"x" => $entity["Pos"][0],
"y" => $entity["Pos"][1],
"z" => $entity["Pos"][2],
"yaw" => $entity["Rotation"][0],
"pitch" => $entity["Rotation"][1],
));
}else{
$e = $this->api->entity->add(ENTITY_MOB, $entity["id"]);
$e->setPosition($entity["Pos"][0], $entity["Pos"][1], $entity["Pos"][2], $entity["Rotation"][0], $entity["Rotation"][1]);
$e->setHealth($entity["Health"]);
}
}
}
console("[DEBUG] Loaded ".count($this->entities)." Entities", true, true, 2);
$this->action(1000000 * 60 * 15, '$this->api->chat->broadcast("Forcing save...");$this->save();');
}
}
public function save($final = false){
if($this->mapName !== false){
$this->levelData["Time"] = $this->time;
file_put_contents($this->mapDir."level.dat", serialize($this->levelData));
$this->map->saveMap($final);
console("[INFO] Saving entities...");
foreach($this->entities as $entity){
}
$this->trigger("server.save", $final);
}
}
public function init(){
if($this->mapName !== false and $this->map === false){
$this->loadMap();
$this->loadEntities();
}
console("[INFO] Loading events...");
$this->loadEvents();
//$this->ticker = new TickLoop($this);
//$this->ticker->start();
declare(ticks=15);
register_tick_function(array($this, "tick"));
register_shutdown_function(array($this, "dumpError"));
register_shutdown_function(array($this, "close"));
if(function_exists("pcntl_signal")){
pcntl_signal(SIGTERM, array($this, "close"));
pcntl_signal(SIGINT, array($this, "close"));
pcntl_signal(SIGHUP, array($this, "close"));
}
$this->trigger("server.start", microtime(true));
console("[INFO] Server started!");
$this->process();
}
public function dumpError(){
console("[ERROR] An Unrecovereable has ocurred and the server has Crashed. Creating an Error Dump");
$dump = "# PocketMine-MP Error Dump ".date("D M j H:i:s T Y")."\r\n";
$dump .= "Error: ".var_export(error_get_last(), true)."\r\n\r\n";
$version = new VersionString();
$dump .= "PM Version: ".$version." #".$version->getNumber()." [Protocol ".CURRENT_PROTOCOL."]\r\n";
$dump .= "uname -a: ".php_uname("a")."\r\n";
$dump .= "PHP Version: " .phpversion()."\r\n";
$dump .= "Zend version: ".zend_version()."\r\n";
$dump .= "OS : " .PHP_OS.", ".Utils::getOS()."\r\n";
$dump .= "Debug Info: ".var_export($this->debugInfo(false), true)."\r\n\r\n\r\n";
global $arguments;
$dump .= "Parameters: ".var_export($arguments, true)."\r\n\r\n\r\n";
$dump .= "server.properties: ".var_export($this->api->getProperties(), true)."\r\n\r\n\r\n";
global $lasttrace;
$dump .= "Last Backtrace: ".$lasttrace."\r\n\r\n\r\n";
$dump .= "Loaded Modules: ".var_export(get_loaded_extensions(), true)."\r\n\r\n";
$name = "error_dump_".time();
logg($dump, $name, true, 0, true);
console("[ERROR] Please submit the \"logs/{$name}.log\" file to the Bug Reporting page. Give as much info as you can.", true, true, 0);
}
public function tick(){
/*if($this->ticker->tick === true and $this->ticker->isWaiting() === true){
$this->ticker->tick = false;
$time = microtime(true);
array_shift($this->tickMeasure);
$this->tickMeasure[] = $this->lastTick = $time;
$this->tickerFunction($time);
$this->trigger("server.tick", $time);
$this->ticker->notify();
}*/
$time = microtime(true);
if($this->lastTick <= ($time - 0.05)){
array_shift($this->tickMeasure);
$this->tickMeasure[] = $this->lastTick = $time;
$this->tickerFunction($time);
$this->trigger("server.tick", $time);
}
}
public function clientID($ip, $port){
return md5($ip . $port, true);
}
public function packetHandler($packet){
$data =& $packet["data"];
$CID = $this->clientID($packet["ip"], $packet["port"]);
if(isset($this->clients[$CID])){
$this->clients[$CID]->handle($packet["pid"], $data);
}else{
if($this->handle("server.noauthpacket", $packet) === false){
return;
}
switch($packet["pid"]){
case 0x02:
if($this->invisible === true){
$this->send(0x1c, array(
$data[0],
$this->serverID,
MAGIC,
$this->serverType,
), false, $packet["ip"], $packet["port"]);
break;
}
if($this->api->ban->isIPBanned($packet["ip"])){
$this->send(0x1c, array(
$data[0],
$this->serverID,
MAGIC,
$this->serverType. $this->name . " [You're banned]",
), false, $packet["ip"], $packet["port"]);
break;
}
if(!isset($this->custom["times_".$CID])){
$this->custom["times_".$CID] = 0;
}
$ln = 15;
$this->description .= " ";
$txt = substr($this->description, $this->custom["times_".$CID], $ln);
$txt .= substr($this->description, 0, $ln - strlen($txt));
$this->send(0x1c, array(
$data[0],
$this->serverID,
MAGIC,
$this->serverType. $this->name . " [".($this->gamemode === 1 ? "C":"S").($this->whitelist !== false ? "W":"")." ".count($this->clients)."/".$this->maxClients."] ".$txt,
), false, $packet["ip"], $packet["port"]);
$this->custom["times_".$CID] = ($this->custom["times_".$CID] + 1) % strlen($this->description);
break;
case 0x05:
if($this->api->ban->isIPBanned($packet["ip"]) or count($this->clients) >= $this->maxClients){
$this->send(0x80, array(
0,
0x00,
array(
"id" => MC_LOGIN_STATUS,
"status" => 1,
),
), false, $packet["ip"], $packet["port"]);
$this->send(0x80, array(
1,
0x00,
array(
"id" => MC_DISCONNECT,
),
), false, $packet["ip"], $packet["port"]);
break;
}
$version = $data[1];
$size = strlen($data[2]);
if($version !== CURRENT_PROTOCOL){
$this->send(0x1a, array(
CURRENT_PROTOCOL,
MAGIC,
$this->serverID,
), false, $packet["ip"], $packet["port"]);
}else{
$this->send(0x06, array(
MAGIC,
$this->serverID,
0,
strlen($packet["raw"]),
), false, $packet["ip"], $packet["port"]);
}
break;
case 0x07:
if($this->api->ban->isIPBanned($packet["ip"]) or count($this->clients) >= $this->maxClients){
$this->send(0x80, array(
0,
0x00,
array(
"id" => MC_LOGIN_STATUS,
"status" => 1,
),
), false, $packet["ip"], $packet["port"]);
$this->send(0x80, array(
1,
0x00,
array(
"id" => MC_DISCONNECT,
),
), false, $packet["ip"], $packet["port"]);
break;
}
$port = $data[2];
$MTU = $data[3];
$clientID = $data[4];
$this->clients[$CID] = new Player($this, $clientID, $packet["ip"], $packet["port"], $MTU); //New Session!
$this->clients[$CID]->handle(0x07, $data);
break;
}
}
}
public function send($pid, $data = array(), $raw = false, $dest = false, $port = false){
$this->interface->writePacket($pid, $data, $raw, $dest, $port);
}
public function process(){
while($this->stop === false){
$packet = $this->interface->readPacket();
if($packet !== false){
$this->packetHandler($packet);
}else{
usleep(1);
}
}
}
public function trigger($event, $data = ""){
$this->preparedSQL->selectEvents->reset();
$this->preparedSQL->selectEvents->clear();
$this->preparedSQL->selectEvents->bindValue(":name", $event, SQLITE3_TEXT);
$events = $this->preparedSQL->selectEvents->execute();
if($events === false or $events === true){
return;
}
$call = array();
while(($evn = $events->fetchArray(SQLITE3_ASSOC)) !== false){
$call[(int) $evn["ID"]] = true;
}
$events->finalize();
if(count($call) > 0){
foreach($call as $evid => $boolean){
$ev = $this->events[$evid];
if(!is_callable($ev)){
$this->deleteEvent($evid);
continue;
}
if(is_array($ev)){
$method = $ev[1];
$ev[0]->$method($data, $event);
}else{
$ev($data, $event);
}
}
}elseif(isset(Deprecation::$events[$event])){
$sub = "";
if(Deprecation::$events[$event] !== false){
$sub = " Substitute \"".Deprecation::$events[$event]."\" found.";
}
console("[ERROR] Event \"$event\" has been deprecated.$sub [Trigger]");
}
return true;
}
public function schedule($ticks, $callback, $data = array(), $repeat = false, $eventName = "server.schedule"){
if(!is_callable($callback)){
return false;
}
$add = "";
$chcnt = $this->scheduleCnt++;
if($repeat === false){
$add = ' unset($this->schedule['.$chcnt.']);';
}
$this->schedule[$chcnt] = array($callback, $data, $eventName);
$this->action(50000 * $ticks, '$schedule = $this->schedule['.$chcnt.'];'.$add.'if(!is_callable($schedule[0])){unset($this->schedule['.$chcnt.']);return false;} call_user_func($schedule[0], $schedule[1], $schedule[2]);', (bool) $repeat);
return $chcnt;
}
public function action($microseconds, $code, $repeat = true){
$this->query("INSERT INTO actions (interval, last, code, repeat) VALUES(".($microseconds / 1000000).", ".microtime(true).", '".base64_encode($code)."', ".($repeat === true ? 1:0).");");
console("[INTERNAL] Attached to action ".$microseconds, true, true, 3);
}
public function tickerFunction($time){
//actions that repeat every x time will go here
$this->preparedSQL->selectActions->reset();
$this->preparedSQL->selectActions->clear();
$this->preparedSQL->selectActions->bindValue(":time", $time, SQLITE3_FLOAT);
$actions = $this->preparedSQL->selectActions->execute();
if($actions === false or $actions === true){
return;
}
while(($action = $actions->fetchArray(SQLITE3_ASSOC)) !== false){
$return = eval(base64_decode($action["code"]));
if($action["repeat"] === 0 or $return === false){
$this->query("DELETE FROM actions WHERE ID = ".$action["ID"].";");
}
}
$actions->finalize();
$this->preparedSQL->updateActions->reset();
$this->preparedSQL->updateActions->clear();
$this->preparedSQL->updateActions->bindValue(":time", $time, SQLITE3_FLOAT);
$this->preparedSQL->updateActions->execute();
}
public function event($event, $func){
if(!is_callable($func)){
return false;
}elseif(isset(Deprecation::$events[$event])){
$sub = "";
if(Deprecation::$events[$event] !== false){
$sub = " Substitute \"".Deprecation::$events[$event]."\" found.";
}
console("[ERROR] Event \"$event\" has been deprecated.$sub [Attach to ".(is_array($func) ? get_class($func[0])."::".$func[1]:$func)."]");
}
$evid = $this->evCnt++;
$this->events[$evid] = $func;
$this->query("INSERT INTO events (ID, name) VALUES (".$evid.", '".str_replace("'", "\\'", $event)."');");
console("[INTERNAL] Attached ".(is_array($func) ? get_class($func[0])."::".$func[1]:$func)." to event ".$event." (ID ".$evid.")", true, true, 3);
return $evid;
}
public function deleteEvent($id){
$id = (int) $id;
unset($this->events[$id]);
$this->query("DELETE FROM events WHERE ID = ".$id.";");
}
}

View File

@ -1,38 +0,0 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
*/
class Sapling{
const OAK = 0;
const SPRUCE = 1;
const BIRCH = 2;
const BURN_TIME = 5;
public static function growTree(LevelAPI $level, $block, $type){
$type = $type & 0x03;
TreeObject::growTree($level, $block, $type);
}
}

View File

@ -1,49 +0,0 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
*/
class Item{
public $id;
protected $maxStackSize = 64;
private $durability = 0;
private $name = "Unknown";
public function __construct($id){
$this->id = (int) $id;
}
public function setMaxStackSize($size = 64){
$this->maxStackSize = (int) $size;
}
public function getDestroySpeed(Item $item, Entity $entity){
return 1;
}
public function getMaxStackSize(){
return $this->maxStackSize;
}
}

View File

@ -1,39 +0,0 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
*/
define("WINDOW_CHEST", 0);
define("WINDOW_WORKBENCH", 1);
define("WINDOW_FURNACE", 2);
class Window{
private $server;
public function __construct(PocketMinecraftServer $server){
}
}
?>

View File

@ -1,136 +0,0 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
*/
class MinecraftInterface{
var $pstruct;
var $name;
var $client;
var $dataName;
private $socket;
private $data;
function __construct($server, $port = 25565, $listen = false, $client = true){
$this->socket = new UDPSocket($server, $port, (bool) $listen);
require("protocol/RakNet.php");
require("protocol/packetName.php");
require("protocol/current.php");
require("protocol/dataName.php");
$this->pstruct = $pstruct;
$this->name = $packetName;
$this->dataName = $dataName;
$this->client = (bool) $client;
$this->start = microtime(true);
}
public function close(){
return $this->socket->close(false);
}
protected function getStruct($pid){
if(isset($this->pstruct[$pid])){
return $this->pstruct[$pid];
}
return false;
}
protected function writeDump($pid, $raw, $data, $origin = "client", $ip = "", $port = 0){
if(LOG === true and DEBUG >= 3){
$p = "[".(microtime(true) - $this->start)."] [".((($origin === "client" and $this->client === true) or ($origin === "server" and $this->client === false)) ? "CLIENT->SERVER":"SERVER->CLIENT")." ".$ip.":".$port."]: ".(isset($data["id"]) ? "MC Packet ".$this->dataName[$pid]:$this->name[$pid])." (0x".Utils::strTohex(chr($pid)).") [length ".strlen($raw)."]".PHP_EOL;
$p .= Utils::hexdump($raw);
if(is_array($data)){
foreach($data as $i => $d){
$p .= $i ." => ".(!is_array($d) ? $this->pstruct[$pid][$i]."(".(($this->pstruct[$pid][$i] === "magic" or substr($this->pstruct[$pid][$i], 0, 7) === "special" or is_int($this->pstruct[$pid][$i])) ? Utils::strToHex($d):Utils::printable($d)).")":$this->pstruct[$pid][$i]."(\"".serialize(array_map("Utils::printable", $d))."\")").PHP_EOL;
}
}
$p .= PHP_EOL;
logg($p, "packets", false);
}
}
public function readPacket(){
$p = $this->popPacket();
if($p !== false){
return $p;
}
if($this->socket->connected === false){
return false;
}
$data = $this->socket->read();
if($data[3] === false){
return false;
}
$pid = ord($data[0]);
$struct = $this->getStruct($pid);
if($struct === false){
console("[ERROR] Unknown Packet ID 0x".Utils::strToHex(chr($pid)), true, true, 0);
$p = "[".(microtime(true) - $this->start)."] [".((($origin === "client" and $this->client === true) or ($origin === "server" and $this->client === false)) ? "CLIENT->SERVER":"SERVER->CLIENT")." ".$ip.":".$port."]: Error, bad packet id 0x".Utils::strTohex(chr($pid))." [length ".strlen($raw)."]".PHP_EOL;
$p .= Utils::hexdump($data[0]);
$p .= PHP_EOL;
logg($p, "packets", true, 2);
return false;
}
$packet = new Packet($pid, $struct, $data[0]);
@$packet->parse();
$this->data[] = array($pid, $packet->data, $data[0], $data[1], $data[2]);
return $this->popPacket();
}
public function popPacket(){
if(count($this->data) > 0){
$p = array_shift($this->data);
if(isset($p[1]["packets"]) and is_array($p[1]["packets"])){
foreach($p[1]["packets"] as $d){
$this->data[] = array($p[0], $d[1], $d[2], $p[3], $p[4]);
}
}
$c = (isset($p[1]["id"]) ? true:false);
$p[2] = $c ? chr($p[1]["id"]).$p[2]:$p[2];
$this->writeDump(($c ? $p[1]["id"]:$p[0]), $p[2], $p[1], "server", $p[3], $p[4]);
return array("pid" => $p[0], "data" => $p[1], "raw" => $p[2], "ip" => $p[3], "port" => $p[4]);
}
return false;
}
public function writePacket($pid, $data = array(), $raw = false, $dest = false, $port = false){
$struct = $this->getStruct($pid);
if($raw === false){
$packet = new Packet($pid, $struct);
$packet->data = $data;
@$packet->create();
$write = $this->socket->write($packet->raw, $dest, $port);
$this->writeDump($pid, $packet->raw, $data, "client", $dest, $port);
}else{
$write = $this->socket->write($data, $dest, $port);
$this->writeDump($pid, $data, false, "client", $dest, $port);
}
return true;
}
}
?>

View File

@ -1,238 +0,0 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
*/
class Packet{
private $struct, $sock;
protected $pid, $packet;
public $data, $raw;
function __construct($pid, $struct, $data = ""){
$this->pid = $pid;
$this->offset = 1;
$this->raw = $data;
$this->data = array();
if($data === ""){
$this->addRaw(chr($pid));
}
$this->struct = $struct;
$this->sock = $sock;
}
public function create($raw = false){
foreach($this->struct as $field => $type){
if(!isset($this->data[$field])){
$this->data[$field] = "";
}
if($raw === true){
$this->addRaw($this->data[$field]);
continue;
}
if(is_int($type)){
$this->addRaw($this->data[$field]);
continue;
}
switch($type){
case "special1":
switch($this->pid){
case 0xc0:
case 0xa0:
if($this->data[1] === false){
$this->addRaw($this->data[$field]);
}
break;
case 0x05:
$this->addRaw($this->data[$field]);
break;
}
break;
case "customData":
switch($this->data[1]){
case 0x40:
$reply = new CustomPacketHandler($this->data[$field]["id"], "", $this->data[$field], true);
$this->addRaw(Utils::writeShort((strlen($reply->raw) + 1) << 3));
$this->addRaw(Utils::writeTriad(strrev($this->data[$field]["count"])));
$this->addRaw(chr($this->data[$field]["id"]));
$this->addRaw($reply->raw);
break;
case 0x00:
$reply = new CustomPacketHandler($this->data[$field]["id"], "", $this->data[$field], true);
$this->addRaw(Utils::writeShort((strlen($reply->raw) + 1) << 3));
$this->addRaw(chr($this->data[$field]["id"]));
$this->addRaw($reply->raw);
break;
}
break;
case "magic":
$this->addRaw(MAGIC);
break;
case "float":
$this->addRaw(Utils::writeFloat($this->data[$field]));
break;
case "triad":
$this->addRaw(Utils::writeTriad($this->data[$field]));
break;
case "itriad":
$this->addRaw(strrev(Utils::writeTriad($this->data[$field])));
break;
case "int":
$this->addRaw(Utils::writeInt($this->data[$field]));
break;
case "double":
$this->addRaw(Utils::writeDouble($this->data[$field]));
break;
case "long":
$this->addRaw(Utils::writeLong($this->data[$field]));
break;
case "bool":
case "boolean":
$this->addRaw(Utils::writeBool($this->data[$field]));
break;
case "ubyte":
case "byte":
$this->addRaw(Utils::writeByte($this->data[$field]));
break;
case "short":
$this->addRaw(Utils::writeShort($this->data[$field]));
break;
case "byteArray":
$this->addRaw($this->data[$field]);
break;
case "string":
$this->addRaw(Utils::writeShort(strlen($this->data[$field])));
$this->addRaw($this->data[$field]);
break;
case "slotData":
$this->addRaw(Utils::writeShort($this->data[$field][0]));
if($this->data[$field][0]!=-1){
$this->addRaw(Utils::writeByte($this->data[$field][1]));
$this->addRaw(Utils::writeShort($this->data[$field][2]));
}
break;
default:
$this->addRaw(Utils::writeByte($this->data[$field]));
break;
}
}
}
private function get($len = true){
if($len === true){
$data = substr($this->raw, $this->offset);
$this->offset = strlen($this->raw);
return $data;
}
$data = substr($this->raw, $this->offset, $len);
$this->offset += $len;
return $data;
}
protected function addRaw($str){
$this->raw .= $str;
return $str;
}
public function parse(){
$continue = true;
foreach($this->struct as $field => $type){
if(is_int($type)){
$this->data[] = $this->get($type);
continue;
}
switch($type){
case "special1":
switch($this->pid){
case 0xc0:
case 0xa0:
if($this->data[1] === false){
$this->data[] = $this->get(3);
}
break;
case 0x05:
$this->data[] = $this->get(true);
break;
}
break;
case "customData":
$d = new SerializedPacketHandler($this->data[1], $this->get(true));
if(isset($d->data["packets"])){
$this->data["packets"] = $d->data["packets"];
}else{
$this->data[] = $d->data;
}
break;
case "magic":
$this->data[] = $this->get(16);
break;
case "triad":
$this->data[] = Utils::readTriad($this->get(3));
break;
case "itriad":
$this->data[] = Utils::readTriad(strrev($this->get(3)));
break;
case "int":
$this->data[] = Utils::readInt($this->get(4));
break;
case "string":
$this->data[] = $this->get(Utils::readShort($this->get(2)));
break;
case "long":
$this->data[] = Utils::readLong($this->get(8));
break;
case "byte":
$this->data[] = Utils::readByte($this->get(1));
break;
case "ubyte":
$this->data[] = ord($this->get(1));
break;
case "float":
$this->data[] = Utils::readFloat($this->get(4));
break;
case "double":
$this->data[] = Utils::readDouble($this->get(8));
break;
case "ushort":
$this->data[] = Utils::readShort($this->get(2), false);
break;
case "short":
$this->data[] = Utils::readShort($this->get(2));
break;
case "bool":
case "boolean":
$this->data[] = Utils::readBool($this->get(1));
break;
}
if($continue === false){
break;
}
}
}
}

View File

@ -1,87 +0,0 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
*/
class SerializedPacketHandler{
var $offset, $raw, $c, $data, $name = "";
private function get($len = true, $check = true){
if($len === true){
$data = substr($this->raw, $this->offset);
if($check === true){
$this->offset = strlen($this->raw);
}
return $data;
}
$data = substr($this->raw, $this->offset, $len);
if($check === true){
$this->offset += $len;
}
return $data;
}
public function __construct($pid, $raw = "", $data = array(), $create = false){
$this->raw = $raw;
$this->data = $data;
$this->offset = 0;
$this->c = (bool) $create;
switch($pid){
case 0x60:
case 0x40:
case 0x00:
if($this->c === false){
$this->data["packets"] = array();
$i = 0;
while($this->offset < strlen($this->raw)){
if($i > 0){
$pid = ord($this->get(1));
}
$len = ceil(Utils::readShort($this->get(2), false) / 8); //Utils::readShort($this->get(2), false) >> 3;
if($pid !== 0x00){
$c = Utils::readTriad(strrev($this->get(3)));
}
if($pid === 0x60 and $i === 0){
$this->data["unknown1"] = $this->get(4);
}
$id = ord($this->get(1));
$raw = $this->get($len - 1);
$pk = new CustomPacketHandler($id, $raw);
$pk->data["length"] = $len;
$pk->data["id"] = $id;
if($pid !== 0x00){
$pk->data["counter"] = $c;
}
$pk->data["packetName"] = $pk->name;
$this->data["packets"][] = array($pid, $pk->data, $raw);
++$i;
}
}
break;
}
}
}

View File

@ -1,92 +0,0 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
*/
class UDPSocket{
private $encrypt;
var $buffer, $connected, $errors, $sock, $server;
function __construct($server, $port, $listen = false){
$this->errors = array_fill(88,(125 - 88) + 1, true);
$this->server = $server;
$this->port = $port;
$this->sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_set_option($this->sock, SOL_SOCKET, SO_BROADCAST, 1); //Allow sending broadcast messages
if($listen !== true){
$this->connected = true;
$this->buffer = array();
$this->unblock();
}else{
if(socket_bind($this->sock, "0.0.0.0", $port) === true){
$this->unblock();
}else{
console("[ERROR] Couldn't bind to 0.0.0.0:".$port, true, true, 0);
die();
}
}
}
public function listenSocket(){
$sock = @socket_accept($this->sock);
if($sock !== false){
$sock = new Socket(false, false, false, $sock);
$sock->unblock();
return $sock;
}
return false;
}
public function close($error = 125){
$this->connected = false;
if($error !== false){
console("[ERROR] [Socket] Socket closed, Error $error: ".socket_strerror($error));
}
return @socket_close($this->sock);
}
public function block(){
socket_set_block($this->sock);
}
public function unblock(){
socket_set_nonblock($this->sock);
}
public function read(){
$source = false;
$port = 1;
$len = @socket_recvfrom($this->sock, $buf, 65536, 0, $source, $port);
return array($buf, $source, $port, $len);
}
public function write($data, $dest = false, $port = false){
return @socket_sendto($this->sock, $data, strlen($data), 0, ($dest === false ? $this->server:$dest), ($port === false ? $this->port:$port));
}
}
?>

File diff suppressed because it is too large Load Diff

View File

@ -1,102 +0,0 @@
<?php
/**
* Class for reading in NBT-format files.
*
* @author Justin Martin <frozenfire@thefrozenfire.com>
* @version 1.0
* MODIFIED BY @shoghicp
*
* Dependencies:
* PHP 4.3+ (5.3+ recommended)
*/
class NBT {
public $root = array();
const TAG_END = 0;
const TAG_BYTE = 1;
const TAG_SHORT = 2;
const TAG_INT = 3;
const TAG_LONG = 4;
const TAG_FLOAT = 5;
const TAG_DOUBLE = 6;
const TAG_BYTE_ARRAY = 7;
const TAG_STRING = 8;
const TAG_LIST = 9;
const TAG_COMPOUND = 10;
public function loadFile($filename) {
if(is_file($filename)) {
$fp = fopen($filename, "rb");
}else{
trigger_error("First parameter must be a filename", E_USER_WARNING);
return false;
}
switch(basename($filename, ".dat")){
case "level":
$version = Utils::readLInt(fread($fp, 4));
$lenght = Utils::readLInt(fread($fp, 4));
break;
case "entities":
fread($fp, 12);
break;
}
$this->traverseTag($fp, $this->root);
return end($this->root);
}
public function traverseTag($fp, &$tree) {
if(feof($fp)) {
return false;
}
$tagType = $this->readType($fp, self::TAG_BYTE); // Read type byte.
if($tagType == self::TAG_END) {
return false;
} else {
$tagName = $this->readType($fp, self::TAG_STRING);
$tagData = $this->readType($fp, $tagType);
$tree[] = array("type"=>$tagType, "name"=>$tagName, "value"=>$tagData);
return true;
}
}
public function readType($fp, $tagType) {
switch($tagType) {
case self::TAG_BYTE: // Signed byte (8 bit)
return Utils::readByte(fread($fp, 1));
case self::TAG_SHORT: // Signed short (16 bit, big endian)
return Utils::readLShort(fread($fp, 2));
case self::TAG_INT: // Signed integer (32 bit, big endian)
return Utils::readLInt(fread($fp, 4));
case self::TAG_LONG: // Signed long (64 bit, big endian)
return Utils::readLLong(fread($fp, 8));
case self::TAG_FLOAT: // Floating point value (32 bit, big endian, IEEE 754-2008)
return Utils::readLFloat(fread($fp, 4));
case self::TAG_DOUBLE: // Double value (64 bit, big endian, IEEE 754-2008)
return Utils::readLDouble(fread($fp, 8));
case self::TAG_BYTE_ARRAY: // Byte array
$arrayLength = $this->readType($fp, self::TAG_INT);
$array = array();
for($i = 0; $i < $arrayLength; $i++) $array[] = $this->readType($fp, self::TAG_BYTE);
return $array;
case self::TAG_STRING: // String
if(!$stringLength = $this->readType($fp, self::TAG_SHORT)) return "";
$string = fread($fp, $stringLength); // Read in number of bytes specified by string length, and decode from utf8.
return $string;
case self::TAG_LIST: // List
$tagID = $this->readType($fp, self::TAG_BYTE);
$listLength = $this->readType($fp, self::TAG_INT);
$list = array("type"=>$tagID, "value"=>array());
for($i = 0; $i < $listLength; $i++) {
if(feof($fp)) break;
$list["value"][] = $this->readType($fp, $tagID);
}
return $list;
case self::TAG_COMPOUND: // Compound
$tree = array();
while($this->traverseTag($fp, $tree));
return $tree;
}
}
}
?>

View File

@ -1,49 +0,0 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
*/
class TickLoop extends Thread{
public $tick, $stop, $lastTic;
private $server;
public function __construct(PocketMinecraftServer $server){
$this->tick = false;
$this->lastTick = 0;
$this->server = $server;
}
public function run(){
while($this->stop !== true){
usleep(1);
$time = microtime(true);
if($this->lastTick <= ($time - 0.05)){
$this->lastTick = $time;
$this->tick = true;
$this->wait();
$this->tick = false;
}
}
exit(0);
}
}

View File

@ -1,284 +0,0 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
*/
define("ENTITY_PLAYER", 0);
define("ENTITY_MOB", 1);
define("ENTITY_OBJECT", 2);
define("ENTITY_ITEM", 3);
define("ENTITY_PAINTING", 4);
class Entity extends stdClass{
var $invincible = false, $eid, $type, $name, $x, $y, $z, $speedX, $speedY, $speedZ, $speed, $last = array(0, 0, 0, 0), $yaw, $pitch, $dead, $data, $class, $attach, $metadata, $closed, $player, $onTick;
private $server;
function __construct($server, $eid, $class, $type = 0, $data = array()){
$this->server = $server;
$this->eid = (int) $eid;
$this->type = (int) $type;
$this->class = (int) $class;
$this->player = false;
$this->attach = false;
$this->data = $data;
$this->status = 0;
$this->health = 20;
$this->dead = false;
$this->closed = false;
$this->name = "";
$this->server->query("INSERT OR REPLACE INTO entities (EID, type, class, health) VALUES (".$this->eid.", ".$this->type.", ".$this->class.", ".$this->health.");");
$this->server->schedule(4, array($this, "update"), array(), true);
$this->metadata = array();
$this->x = isset($this->data["x"]) ? $this->data["x"]:0;
$this->y = isset($this->data["y"]) ? $this->data["y"]:0;
$this->z = isset($this->data["z"]) ? $this->data["z"]:0;
$this->speedX = isset($this->data["speedX"]) ? $this->data["speedX"]:0;
$this->speedY = isset($this->data["speedY"]) ? $this->data["speedY"]:0;
$this->speedZ = isset($this->data["speedZ"]) ? $this->data["speedZ"]:0;
$this->speed = 0;
$this->yaw = isset($this->data["yaw"]) ? $this->data["yaw"]:0;
$this->pitch = isset($this->data["pitch"]) ? $this->data["pitch"]:0;
$this->position = array("x" => &$this->x, "y" => &$this->y, "z" => &$this->z, "yaw" => &$this->yaw, "pitch" => &$this->pitch);
switch($this->class){
case ENTITY_PLAYER:
$this->player = $this->data["player"];
$this->health = &$this->player->data["health"];
break;
case ENTITY_ITEM:
$this->meta = (int) $this->data["meta"];
$this->stack = (int) $this->data["stack"];
break;
case ENTITY_MOB:
//$this->setName((isset($mobs[$this->type]) ? $mobs[$this->type]:$this->type));
break;
case ENTITY_OBJECT:
//$this->setName((isset($objects[$this->type]) ? $objects[$this->type]:$this->type));
break;
}
}
public function update(){
$this->calculateVelocity();
$this->server->api->dhandle("entity.move", $this);
if($this->class === ENTITY_ITEM and $this->closed === false and $this->server->gamemode === 0){
$player = $this->server->query("SELECT EID FROM entities WHERE class == ".ENTITY_PLAYER." AND abs(x - {$this->x}) <= 1.5 AND abs(y - {$this->y}) <= 1.5 AND abs(z - {$this->z}) <= 1.5 LIMIT 1;", true);
if($player !== true and $player !== false){
if($this->server->api->dhandle("player.pickup", array(
"eid" => $player["EID"],
"entity" => $this,
"block" => $this->type,
"meta" => $this->meta,
"target" => $this->eid
)) !== false){
$this->close();
}
}
}
}
public function getDirection(){
$rotation = ($this->yaw - 90) % 360;
if ($rotation < 0) {
$rotation += 360.0;
}
if(0 <= $rotation && $rotation < 45) {
return 2;
}elseif(45 <= $rotation && $rotation < 135) {
return 3;
}elseif(135 <= $rotation && $rotation < 225) {
return 0;
}elseif(225 <= $rotation && $rotation < 315) {
return 1;
}elseif(315 <= $rotation && $rotation < 360) {
return 2;
}else{
return null;
}
}
public function spawn($player){
if(!is_object($player)){
$player = $this->server->api->player->get($player);
}
if($player->eid === $this->eid){
return false;
}
switch($this->class){
case ENTITY_PLAYER:
$player->dataPacket(MC_ADD_PLAYER, array(
"clientID" => $this->player->clientID,
"username" => $this->player->username,
"eid" => $this->eid,
"x" => $this->x,
"y" => $this->y,
"z" => $this->z,
));
$player->dataPacket(MC_PLAYER_EQUIPMENT, array(
"eid" => $this->eid,
"block" => $this->player->equipment[0],
"meta" => $this->player->equipment[1],
));
break;
case ENTITY_ITEM:
$player->dataPacket(MC_ADD_ITEM_ENTITY, array(
"eid" => $this->eid,
"x" => $this->x,
"y" => $this->y,
"z" => $this->z,
"block" => $this->type,
"meta" => $this->meta,
"stack" => $this->stack,
));
break;
case ENTITY_MOB:
$player->dataPacket(MC_ADD_MOB, array(
"type" => $this->type,
"eid" => $this->eid,
"x" => $this->x,
"y" => $this->y,
"z" => $this->z,
));
break;
case ENTITY_OBJECT:
//$this->setName((isset($objects[$this->type]) ? $objects[$this->type]:$this->type));
break;
}
}
public function close(){
if($this->closed === false){
$this->server->api->entity->remove($this->eid);
$this->closed = true;
}
}
public function __destruct(){
$this->close();
}
public function getEID(){
return $this->eid;
}
public function getName(){
return $this->name;
}
public function setName($name){
$this->name = $name;
$this->server->query("UPDATE entities SET name = '".str_replace("'", "", $this->name)."' WHERE EID = ".$this->eid.";");
}
public function look($pos2){
$pos = $this->getPosition();
$angle = Utils::angle3D($pos2, $pos);
$this->yaw = $angle["yaw"];
$this->pitch = $angle["pitch"];
$this->server->query("UPDATE entities SET pitch = ".$this->pitch.", yaw = ".$this->yaw." WHERE EID = ".$this->eid.";");
}
public function setCoords($x, $y, $z){
$this->x = $x;
$this->y = $y;
$this->z = $z;
$this->server->query("UPDATE entities SET x = ".$this->x.", y = ".$this->y.", z = ".$this->z." WHERE EID = ".$this->eid.";");
}
public function move($x, $y, $z, $yaw = 0, $pitch = 0){
$this->x += $x;
$this->y += $y;
$this->z += $z;
$this->yaw += $yaw;
$this->yaw %= 360;
$this->pitch += $pitch;
$this->pitch %= 90;
$this->server->query("UPDATE entities SET x = ".$this->x.", y = ".$this->y.", z = ".$this->z.", pitch = ".$this->pitch.", yaw = ".$this->yaw." WHERE EID = ".$this->eid.";");
}
public function setPosition($x, $y, $z, $yaw, $pitch){
$this->x = $x;
$this->y = $y;
$this->z = $z;
$this->yaw = $yaw;
$this->pitch = $pitch;
$this->server->query("UPDATE entities SET x = ".$this->x.", y = ".$this->y.", z = ".$this->z.", pitch = ".$this->pitch.", yaw = ".$this->yaw." WHERE EID = ".$this->eid.";");
}
public function inBlock($x, $y, $z){
$block = new Vector3($x + 0.5, $y, $z + 0.5);
$me = new Vector3($this->x, $this->y, $this->z);
if(($y == ((int) $this->y) or $y == (((int) $this->y) + 1)) and $block->maxPlainDistance($me) < 0.8){
return true;
}
return false;
}
public function calculateVelocity(){
$diffTime = microtime(true) - $this->last[3];
$this->last[3] = microtime(true);
$origin = new Vector3($this->last[0], $this->last[1], $this->last[2]);
$final = new Vector3($this->x, $this->y, $this->z);
$speedX = abs($this->x - $this->last[0]) / $diffTime;
$this->last[0] = $this->x;
$speedY = ($this->y - $this->last[1]) / $diffTime;
$this->last[1] = $this->y;
$speedZ = abs($this->z - $this->last[2]) / $diffTime;
$this->last[2] = $this->z;
$this->speedX = $speedX;
$this->speedY = $speedY;
$this->speedZ = $speedZ;
$this->speed = $origin->distance($final) / $diffTime;
}
public function getPosition($round = false){
return !isset($this->position) ? false:($round === true ? array_map("floor", $this->position):$this->position);
}
public function setHealth($health, $cause = ""){
$this->health = (int) $health;
$this->server->query("UPDATE entities SET health = ".$this->health." WHERE EID = ".$this->eid.";");
$this->server->api->dhandle("entity.health.change", array("eid" => $this->eid, "health" => $health, "cause" => $cause));
if($this->player !== false){
$this->player->dataPacket(MC_SET_HEALTH, array(
"health" => $this->health,
));
}
if($this->health <= 0 and $this->dead === false){
$this->dead = true;
if($this->player !== false){
$this->server->api->dhandle("player.death", array("name" => $this->name, "cause" => $cause));
}
}elseif($this->health > 0){
$this->dead = false;
}
}
public function getHealth(){
return $this->health;
}
}
?>

View File

@ -1,36 +0,0 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
*/
class TileEntity extends stdClass{
private $server;
function __construct(PocketMinecraftServer $server){
}
}
?>

View File

@ -1,357 +0,0 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
*/
class WorldGenerator{
private $gen, $seed, $genName, $raw;
public function __construct($genName, $seed){
$this->seed = (int) $seed;
$this->raw = b"";
$this->genName = $genName;
$this->gen = new $genName($this->seed);
}
public function getSpawn(){
return $this->gen->getSpawn();
}
public function set($name, $value){
$this->gen->set($name, $value);
}
public function init(){
$this->raw = "\x15\x01\x00\x00\x15\x16\x00\x00\x15\x2b\x00\x00\x15\x40\x00\x00". //Location Header
"\x15\x55\x00\x00\x15\x6a\x00\x00\x15\x7f\x00\x00\x15\x94\x00\x00".
"\x15\xa9\x00\x00\x15\xbe\x00\x00\x15\xd3\x00\x00\x15\xe8\x00\x00".
"\x15\xfd\x00\x00\x15\x12\x01\x00\x15\x27\x01\x00\x15\x3c\x01\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x15\x51\x01\x00\x15\x66\x01\x00\x15\x7b\x01\x00\x15\x90\x01\x00".
"\x15\xa5\x01\x00\x15\xba\x01\x00\x15\xcf\x01\x00\x15\xe4\x01\x00".
"\x15\xf9\x01\x00\x15\x0e\x02\x00\x15\x23\x02\x00\x15\x38\x02\x00".
"\x15\x4d\x02\x00\x15\x62\x02\x00\x15\x77\x02\x00\x15\x8c\x02\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x15\xa1\x02\x00\x15\xb6\x02\x00\x15\xcb\x02\x00\x15\xe0\x02\x00".
"\x15\xf5\x02\x00\x15\x0a\x03\x00\x15\x1f\x03\x00\x15\x34\x03\x00".
"\x15\x49\x03\x00\x15\x5e\x03\x00\x15\x73\x03\x00\x15\x88\x03\x00".
"\x15\x9d\x03\x00\x15\xb2\x03\x00\x15\xc7\x03\x00\x15\xdc\x03\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x15\xf1\x03\x00\x15\x06\x04\x00\x15\x1b\x04\x00\x15\x30\x04\x00".
"\x15\x45\x04\x00\x15\x5a\x04\x00\x15\x6f\x04\x00\x15\x84\x04\x00".
"\x15\x99\x04\x00\x15\xae\x04\x00\x15\xc3\x04\x00\x15\xd8\x04\x00".
"\x15\xed\x04\x00\x15\x02\x05\x00\x15\x17\x05\x00\x15\x2c\x05\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x15\x41\x05\x00\x15\x56\x05\x00\x15\x6b\x05\x00\x15\x80\x05\x00".
"\x15\x95\x05\x00\x15\xaa\x05\x00\x15\xbf\x05\x00\x15\xd4\x05\x00".
"\x15\xe9\x05\x00\x15\xfe\x05\x00\x15\x13\x06\x00\x15\x28\x06\x00".
"\x15\x3d\x06\x00\x15\x52\x06\x00\x15\x67\x06\x00\x15\x7c\x06\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x15\x91\x06\x00\x15\xa6\x06\x00\x15\xbb\x06\x00\x15\xd0\x06\x00".
"\x15\xe5\x06\x00\x15\xfa\x06\x00\x15\x0f\x07\x00\x15\x24\x07\x00".
"\x15\x39\x07\x00\x15\x4e\x07\x00\x15\x63\x07\x00\x15\x78\x07\x00".
"\x15\x8d\x07\x00\x15\xa2\x07\x00\x15\xb7\x07\x00\x15\xcc\x07\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x15\xe1\x07\x00\x15\xf6\x07\x00\x15\x0b\x08\x00\x15\x20\x08\x00".
"\x15\x35\x08\x00\x15\x4a\x08\x00\x15\x5f\x08\x00\x15\x74\x08\x00".
"\x15\x89\x08\x00\x15\x9e\x08\x00\x15\xb3\x08\x00\x15\xc8\x08\x00".
"\x15\xdd\x08\x00\x15\xf2\x08\x00\x15\x07\x09\x00\x15\x1c\x09\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x15\x31\x09\x00\x15\x46\x09\x00\x15\x5b\x09\x00\x15\x70\x09\x00".
"\x15\x85\x09\x00\x15\x9a\x09\x00\x15\xaf\x09\x00\x15\xc4\x09\x00".
"\x15\xd9\x09\x00\x15\xee\x09\x00\x15\x03\x0a\x00\x15\x18\x0a\x00".
"\x15\x2d\x0a\x00\x15\x42\x0a\x00\x15\x57\x0a\x00\x15\x6c\x0a\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x15\x81\x0a\x00\x15\x96\x0a\x00\x15\xab\x0a\x00\x15\xc0\x0a\x00".
"\x15\xd5\x0a\x00\x15\xea\x0a\x00\x15\xff\x0a\x00\x15\x14\x0b\x00".
"\x15\x29\x0b\x00\x15\x3e\x0b\x00\x15\x53\x0b\x00\x15\x68\x0b\x00".
"\x15\x7d\x0b\x00\x15\x92\x0b\x00\x15\xa7\x0b\x00\x15\xbc\x0b\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x15\xd1\x0b\x00\x15\xe6\x0b\x00\x15\xfb\x0b\x00\x15\x10\x0c\x00".
"\x15\x25\x0c\x00\x15\x3a\x0c\x00\x15\x4f\x0c\x00\x15\x64\x0c\x00".
"\x15\x79\x0c\x00\x15\x8e\x0c\x00\x15\xa3\x0c\x00\x15\xb8\x0c\x00".
"\x15\xcd\x0c\x00\x15\xe2\x0c\x00\x15\xf7\x0c\x00\x15\x0c\x0d\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x15\x21\x0d\x00\x15\x36\x0d\x00\x15\x4b\x0d\x00\x15\x60\x0d\x00".
"\x15\x75\x0d\x00\x15\x8a\x0d\x00\x15\x9f\x0d\x00\x15\xb4\x0d\x00".
"\x15\xc9\x0d\x00\x15\xde\x0d\x00\x15\xf3\x0d\x00\x15\x08\x0e\x00".
"\x15\x1d\x0e\x00\x15\x32\x0e\x00\x15\x47\x0e\x00\x15\x5c\x0e\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x15\x71\x0e\x00\x15\x86\x0e\x00\x15\x9b\x0e\x00\x15\xb0\x0e\x00".
"\x15\xc5\x0e\x00\x15\xda\x0e\x00\x15\xef\x0e\x00\x15\x04\x0f\x00".
"\x15\x19\x0f\x00\x15\x2e\x0f\x00\x15\x43\x0f\x00\x15\x58\x0f\x00".
"\x15\x6d\x0f\x00\x15\x82\x0f\x00\x15\x97\x0f\x00\x15\xac\x0f\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x15\xc1\x0f\x00\x15\xd6\x0f\x00\x15\xeb\x0f\x00\x15\x00\x10\x00".
"\x15\x15\x10\x00\x15\x2a\x10\x00\x15\x3f\x10\x00\x15\x54\x10\x00".
"\x15\x69\x10\x00\x15\x7e\x10\x00\x15\x93\x10\x00\x15\xa8\x10\x00".
"\x15\xbd\x10\x00\x15\xd2\x10\x00\x15\xe7\x10\x00\x15\xfc\x10\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x15\x11\x11\x00\x15\x26\x11\x00\x15\x3b\x11\x00\x15\x50\x11\x00".
"\x15\x65\x11\x00\x15\x7a\x11\x00\x15\x8f\x11\x00\x15\xa4\x11\x00".
"\x15\xb9\x11\x00\x15\xce\x11\x00\x15\xe3\x11\x00\x15\xf8\x11\x00".
"\x15\x0d\x12\x00\x15\x22\x12\x00\x15\x37\x12\x00\x15\x4c\x12\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x15\x61\x12\x00\x15\x76\x12\x00\x15\x8b\x12\x00\x15\xa0\x12\x00".
"\x15\xb5\x12\x00\x15\xca\x12\x00\x15\xdf\x12\x00\x15\xf4\x12\x00".
"\x15\x09\x13\x00\x15\x1e\x13\x00\x15\x33\x13\x00\x15\x48\x13\x00".
"\x15\x5d\x13\x00\x15\x72\x13\x00\x15\x87\x13\x00\x15\x9c\x13\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x15\xb1\x13\x00\x15\xc6\x13\x00\x15\xdb\x13\x00\x15\xf0\x13\x00".
"\x15\x05\x14\x00\x15\x1a\x14\x00\x15\x2f\x14\x00\x15\x44\x14\x00".
"\x15\x59\x14\x00\x15\x6e\x14\x00\x15\x83\x14\x00\x15\x98\x14\x00".
"\x15\xad\x14\x00\x15\xc2\x14\x00\x15\xd7\x14\x00\x15\xec\x14\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
$this->gen->init();
}
public function generate(){
for($Z = 0; $Z < 16; ++$Z){
for($X = 0; $X < 16; ++$X){
$chunk = str_pad($this->getChunk($X, $Z), 86012, "\x00", STR_PAD_RIGHT);
$this->raw .= Utils::writeLInt(strlen($chunk)) . $chunk;
}
console("[DEBUG] Generating level ".ceil(($Z + 1)/0.16)."%", true, true, 2);
}
return true;
}
private function getChunk($X, $Z){
$chunk = b"";
$columns = array();
$X *= 16;
$Z *= 16;
for($x = 0; $x < 16; ++$x){
for($z = 0; $z < 16; ++$z){
$columns[$x * 16 + $z] = $this->gen->getColumn($X + $x, $Z + $z);
}
}
for($i = 0; $i < 4; ++$i){
for($x = 0; $x < 16; ++$x){
for($z = 0; $z < 16; ++$z){
$chunk .= $columns[$x * 16 + $z][$i];
}
}
}
unset($columns);
return $chunk;
}
public function save($dir, $name){
@mkdir($dir, 0777, true);
file_put_contents($dir."chunks.dat", $this->raw);
$s = $this->getSpawn();
$array = array();
file_put_contents($dir."entities.dat", serialize($array));
file_put_contents($dir."tileEntities.dat", serialize($array));
$level = array(
"LevelName" => $name,
"Time" => 0,
"Gamemode" => 1,
"RandomSeed" => $this->seed,
"Generator" => $this->genName,
"SpawnX" => $s[0],
"SpawnY" => $s[1],
"SpawnZ" => $s[2],
);
file_put_contents($dir."level.dat", serialize($level));
}
}

View File

@ -1,66 +0,0 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
*/
class NormalGenerator{
private $config, $spawn, $structure;
public function __construct($seed){
$this->config = array(
"seed" => (int) $seed,
);
}
public function set($name, $value){
$this->config[$name] = $value;
}
public function init(){
$this->spawn = array(128, 128, 128);
}
public function getSpawn(){
return $this->spawn;
}
public function getColumn($x, $z){
$x = (int) $x;
$z = (int) $z;
$column = $this->structure;
if(floor(sqrt(pow($x - $this->spawn[0], 2) + pow($z - $this->spawn[2], 2))) <= $this->config["spawn-radius"]){
$column[0]{strlen($column[0])-1} = chr($this->config["spawn-surface"]);
}
if(($x % 8) === 0 and ($z % 8) === 0 and $this->config["torches"] == "1"){
$column[0] .= chr(50);
}
$column[0] .= str_repeat(chr(0), 128 - strlen($column[0]));
$column[1] .= str_repeat(chr(0), 64 - strlen($column[1]));
$column[2] .= str_repeat(chr(0), 64 - strlen($column[2]));
$column[3] .= str_repeat(chr(0), 64 - strlen($column[3]));
return $column;
}
}

View File

@ -1,107 +0,0 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
*/
class SuperflatGenerator{
private $config, $spawn, $structure;
public function __construct($seed){
$this->config = array(
"preset" => "7;20x1;3x3;2",
"spawn-surface" => 24,
"spawn-radius" => 10,
"torches" => 0,
"seed" => (int) $seed,
);
$this->parsePreset();
}
public function set($name, $value){
$this->config[$name] = $value;
if($name === "preset"){
$this->parsePreset();
}
}
private function parsePreset(){
$this->structure = array(
0 => "",
1 => "",
2 => str_repeat("\x00", 64),
3 => str_repeat("\x00", 64),
);
$preset = explode(";", trim($this->config["preset"]));
foreach($preset as $i => $data){
$num = 1;
if(preg_match('#([a-zA-Z\-_]*)\((.*)\)#', $data, $matches) > 0){ //Property
$this->config[$matches[1]] = $matches[2];
continue;
}elseif(preg_match('#([0-9]*)x([0-9:]*)#', $data, $matches) > 0){
$num = (int) $matches[1];
$d = explode(":", $matches[2]);
}else{
$d = explode(":", $data);
}
$block = (int) array_shift($d);
$meta = (int) @array_shift($d);
for($j = 0; $j < $num; ++$j){
$this->structure[0] .= chr($block & 0xFF);
$this->structure[1] .= substr(dechex($meta & 0x0F), -1);
}
}
$this->structure[1] = pack("h*", str_pad($this->structure[1], (strlen($this->structure[1])&0xFE) + 2, "0", STR_PAD_RIGHT)); //invert nibbles
$this->structure[0] = substr($this->structure[0], 0, 128);
$this->structure[1] = substr($this->structure[1], 0, 64);
$this->structure[2] = substr($this->structure[2], 0, 64);
$this->structure[3] = substr($this->structure[3], 0, 64);
}
public function init(){
$this->spawn = array(128, strlen($this->structure[0]), 128);
}
public function getSpawn(){
return $this->spawn;
}
public function getColumn($x, $z){
$x = (int) $x;
$z = (int) $z;
$column = $this->structure;
if(floor(sqrt(pow($x - $this->spawn[0], 2) + pow($z - $this->spawn[2], 2))) <= $this->config["spawn-radius"]){
$column[0]{strlen($column[0])-1} = chr($this->config["spawn-surface"]);
}
if(($x % 8) === 0 and ($z % 8) === 0 and $this->config["torches"] == "1"){
$column[0] .= chr(50);
}
$column[0] .= str_repeat(chr(0), 128 - strlen($column[0]));
$column[1] .= str_repeat(chr(0), 64 - strlen($column[1]));
$column[2] .= str_repeat(chr(0), 64 - strlen($column[2]));
$column[3] .= str_repeat(chr(0), 64 - strlen($column[3]));
return $column;
}
}

View File

@ -1,97 +0,0 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
*/
require_once("classes/world/generator/object/tree/TreeObject.php");
class PineTreeObject extends TreeObject{
var $type = 1;
private $totalHeight = 8;
private $leavesSizeY = -1;
private $leavesAbsoluteMaxRadius = -1;
public function canPlaceObject(LevelAPI $level, $x, $y, $z){
$this->findRandomLeavesSize();
$checkRadius = 0;
for($yy = 0; $yy < $this->totalHeight; ++$yy) {
if($yy === $this->leavesSizeY) {
$checkRadius = $this->leavesAbsoluteMaxRadius;
}
for($xx = -$checkRadius; $xx < ($checkRadius + 1); ++$xx){
for($zz = -$checkRadius; $zz < ($checkRadius + 1); ++$zz){
$block = $level->getBlock($x + $xx, $y + $yy, $z + $zz);
if(!isset($this->overridable[$block[0]])){
return false;
}
}
}
}
return true;
}
private function findRandomLeavesSize(){
$this->totalHeight += mt_rand(-1, 2);
$this->leavesSizeY = 1 + mt_rand(0,2);
$this->leavesAbsoluteMaxRadius = 2 + mt_rand(0, 2);
}
public function placeObject(LevelAPI $level, $x, $y, $z){
if($this->leavesSizeY === -1 or $this->leavesAbsoluteMaxRadius === -1) {
$this->findRandomLeavesSize();
}
$level->setBlock($x, $y - 1, $z, 3, 0);
$leavesRadius = mt_rand(0,2);
$leavesMaxRadius = 1;
$leavesBottomY = $this->totalHeight - $this->leavesSizeY;
$firstMaxedRadius = false;
for($leavesY = 0; $leavesY < ($leavesBottomY + 1); ++$leavesY) {
$yy = $this->totalHeight - $leavesY;
for ($xx = -$leavesRadius; $xx < ($leavesRadius + 1); ++$xx) {
for ($zz = -$leavesRadius; $zz < ($leavesRadius + 1); ++$zz) {
if (abs($xx) != $leavesRadius or abs($zz) != $leavesRadius or $leavesRadius <= 0) {
$level->setBlock($x + $xx, $y + $yy, $z + $zz, 18, $this->type);
}
}
}
if ($leavesRadius >= $leavesMaxRadius) {
$leavesRadius = $firstMaxedRadius ? 1 : 0;
$firstMaxedRadius = true;
if (++$leavesMaxRadius > $this->leavesAbsoluteMaxRadius) {
$leavesMaxRadius = $this->leavesAbsoluteMaxRadius;
}
}else{
++$leavesRadius;
}
}
$trunkHeightReducer = mt_rand(0,3);
for($yy = 0; $yy < ($this->totalHeight - $trunkHeightReducer); ++$yy){
$level->setBlock($x, $y + $yy, $z, 17, $this->type);
}
}
}

View File

@ -1,79 +0,0 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
*/
require_once("classes/world/generator/object/tree/TreeObject.php");
class SmallTreeObject extends TreeObject{
var $type = 0;
private $totalHeight = 6;
private $leavesHeight = 3;
protected $radiusIncrease = 0;
private $addLeavesVines = false;
private $addLogVines = false;
private $addCocoaPlants = false;
public function canPlaceObject(LevelAPI $level, $x, $y, $z){
$radiusToCheck = $this->radiusIncrease;
for ($yy = 0; $yy < $this->totalHeight + 2; ++$yy) {
if ($yy == 1 or $yy === $this->totalHeight - 1) {
++$radiusToCheck;
}
for($xx = -$radiusToCheck; $xx < ($radiusToCheck + 1); ++$xx){
for($zz = -$radiusToCheck; $zz < ($radiusToCheck + 1); ++$zz){
$block = $level->getBlock($x + $xx, $y + $yy, $z + $zz);
if(!isset($this->overridable[$block[0]])){
return false;
}
}
}
}
return true;
}
public function placeObject(LevelAPI $level, $x, $y, $z){
$level->setBlock($x, $y - 1, $z, 3, 0);
$this->totalHeight += mt_rand(-1, 3);
$this->leavesHeight += mt_rand(0, 1);
for($yy = ($this->totalHeight - $this->leavesHeight); $yy < ($this->totalHeight + 1); ++$yy){
$yRadius = ($yy - $this->totalHeight);
$xzRadius = (int) (($this->radiusIncrease + 1) - $yRadius / 2);
for($xx = -$xzRadius; $xx < ($xzRadius + 1); ++$xx){
for($zz = -$xzRadius; $zz < ($xzRadius + 1); ++$zz){
if((abs($xx) != $xzRadius or abs($zz) != $xzRadius) and $yRadius != 0){
$level->setBlock($x + $xx, $y + $yy, $z + $zz, 18, $this->type);
}
}
}
}
for($yy = 0; $yy < ($this->totalHeight - 1); ++$yy){
$level->setBlock($x, $y + $yy, $z, 17, $this->type);
}
}
}

View File

@ -1,88 +0,0 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
*/
require_once("classes/world/generator/object/tree/TreeObject.php");
class SpruceTreeObject extends TreeObject{
var $type = 1;
private $totalHeight = 8;
private $leavesBottomY = -1;
private $leavesMaxRadius = -1;
public function canPlaceObject(LevelAPI $level, $x, $y, $z){
$this->findRandomLeavesSize();
$checkRadius = 0;
for($yy = 0; $yy < $this->totalHeight + 2; ++$yy) {
if($yy === $this->leavesBottomY) {
$checkRadius = $this->leavesMaxRadius;
}
for($xx = -$checkRadius; $xx < ($checkRadius + 1); ++$xx){
for($zz = -$checkRadius; $zz < ($checkRadius + 1); ++$zz){
$block = $level->getBlock($x + $xx, $y + $yy, $z + $zz);
if(!isset($this->overridable[$block[0]])){
return false;
}
}
}
}
return true;
}
private function findRandomLeavesSize(){
$this->totalHeight += mt_rand(-1, 2);
$this->leavesBottomY = (int) ($this->totalHeight - mt_rand(1,2) - 3);
$this->leavesMaxRadius = 1 + mt_rand(0, 1);
}
public function placeObject(LevelAPI $level, $x, $y, $z){
if($this->leavesBottomY === -1 or $this->leavesMaxRadius === -1) {
$this->findRandomLeavesSize();
}
$level->setBlock($x, $y - 1, $z, 3, 0);
$leavesRadius = 0;
for($yy = $this->totalHeight; $yy >= $this->leavesBottomY; --$yy){
for ($xx = -$leavesRadius; $xx < ($leavesRadius + 1); ++$xx) {
for ($zz = -$leavesRadius; $zz < ($leavesRadius + 1); ++$zz) {
if (abs($xx) != $leavesRadius or abs($zz) != $leavesRadius or $leavesRadius <= 0) {
$level->setBlock($x + $xx, $y + $yy, $z + $zz, 18, $this->type);
}
}
}
if ($leavesRadius > 0 and $yy === ($y + $this->leavesBottomY + 1)) {
--$leavesRadius;
}elseif($leavesRadius < $this->leavesMaxRadius){
++$leavesRadius;
}
}
for($yy = 0; $yy < ($this->totalHeight - 1); ++$yy){
$level->setBlock($x, $y + $yy, $z, 17, $this->type);
}
}
}

View File

@ -1,62 +0,0 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
*/
class TreeObject{
var $overridable = array(
0 => true,
6 => true,
17 => true,
18 => true,
);
public static function growTree(LevelAPI $level, $block, $type){
switch($type){
case Sapling::SPRUCE:
if(mt_rand(0,1) == 1){
$tree = new SpruceTreeObject();
}else{
$tree = new PineTreeObject();
}
break;
case Sapling::BIRCH:
$tree = new SmallTreeObject();
$tree->type = Sapling::BIRCH;
break;
default:
case Sapling::OAK:
if(mt_rand(0,9) === 0){
$tree = new BigTreeObject();
}else{
$tree = new SmallTreeObject();
}
break;
}
if($tree->canPlaceObject($level, $block[2][0], $block[2][1], $block[2][2])){
$tree->placeObject($level, $block[2][0], $block[2][1], $block[2][2]);
}
}
}

View File

@ -1,43 +0,0 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
*/
set_time_limit(0);
date_default_timezone_set(@date_default_timezone_get());
gc_enable();
error_reporting(E_ALL ^ E_NOTICE);
ini_set("allow_url_fopen", 1);
ini_set("display_errors", 1);
ini_set('default_charset', 'utf-8');
define("FILE_PATH", dirname(__FILE__)."/../../");
set_include_path(get_include_path() . PATH_SEPARATOR . FILE_PATH . PATH_SEPARATOR . FILE_PATH . "/src/" . PATH_SEPARATOR . FILE_PATH . "/src/classes/");
ini_set("memory_limit", "256M");
define("LOG", true);
define("MAGIC", "\x00\xff\xff\x00\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\x12\x34\x56\x78");
define("TEST_MD5", "d0ca3786e53b615bb4fb9f5094d5c9a7");
define("MAJOR_VERSION", "Alpha_1.0.7");
define("CURRENT_PROTOCOL", 5);
define("CURRENT_MINECRAFT_VERSION", "v0.5.0 alpha");

View File

@ -1,92 +0,0 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
*/
require_once(dirname(__FILE__)."/config.php");
require_once("common/functions.php");
if(strpos(strtoupper(php_uname("s")), "WIN") === false or arg("enable-ansi", false) === true){
define("ENABLE_ANSI", true);
}else{
define("ENABLE_ANSI", false);
}
set_error_handler("fatal_handler", E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR | E_RECOVERABLE_ERROR | E_DEPRECATED);
$errors = 0;
if(version_compare("5.3.3", PHP_VERSION) > 0){
console("[ERROR] Use PHP >= 5.3.3", true, true, 0);
++$errors;
}elseif(version_compare("5.5.0", PHP_VERSION) <= 0){
console("[NOTICE] PocketMine-MP hasn't been tested with PHP >= 5.5", true, true, 0);
++$errors;
}
if(version_compare("5.4.0", PHP_VERSION) > 0){
console("[NOTICE] Use PHP >= 5.4.0 to increase performance", true, true, 0);
define("HEX2BIN", false);
}else{
define("HEX2BIN", true);
}
if(php_sapi_name() !== "cli"){
console("[ERROR] Use PHP-CLI to execute the library or create your own", true, true, 0);
++$errors;
}
if(!extension_loaded("sockets") and @dl((PHP_SHLIB_SUFFIX === "dll" ? "php_":"") . "sockets." . PHP_SHLIB_SUFFIX) === false){
console("[ERROR] Unable to find Socket extension", true, true, 0);
++$errors;
}
if(!extension_loaded("pthreads") and @dl((PHP_SHLIB_SUFFIX === "dll" ? "php_":"") . "pthreads." . PHP_SHLIB_SUFFIX) === false){
console("[ERROR] Unable to find pthreads extension. Use the Installer available in the Homepage", true, true, 0);
++$errors;
}
if(!extension_loaded("curl") and @dl((PHP_SHLIB_SUFFIX === "dll" ? "php_":"") . "curl." . PHP_SHLIB_SUFFIX) === false){
console("[ERROR] Unable to find cURL extension", true, true, 0);
++$errors;
}
if(!extension_loaded("sqlite3") and @dl((PHP_SHLIB_SUFFIX === "dll" ? "php_":"") . "sqlite3." . PHP_SHLIB_SUFFIX) === false){
console("[ERROR] Unable to find SQLite3 extension", true, true, 0);
++$errors;
}
if(!extension_loaded("zlib") and @dl((PHP_SHLIB_SUFFIX === "dll" ? "php_":"") . "zlib." . PHP_SHLIB_SUFFIX) === false){
console("[ERROR] Unable to find Zlib extension. Compressed worlds won't be loaded", true, true, 0);
define("ZLIB_EXTENSION", false);
}else{
define("ZLIB_EXTENSION", true);
}
if($errors > 0){
die();
}
require_all(FILE_PATH . "src/classes/");
?>

71
src/config.php Normal file
View File

@ -0,0 +1,71 @@
<?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/
*
*
*/
set_time_limit(0);
date_default_timezone_set("GMT");
if(strpos(" ".strtoupper(php_uname("s")), " WIN") !== false){
$time = time();
$time -= $time % 60;
exec("time.exe /T", $hour);
$i = array_map("intval", explode(":", trim($hour[0])));
exec("date.exe /T", $date);
$j = array_map("intval", explode("/", trim($date[0])));
$offset = round((mktime($i[0], $i[1], 0, $j[1], $j[0], $j[2]) - $time) / 60) * 60;
}else{
exec("date +%s", $t);
$offset = round((intval(trim($t[0])) - time()) / 60) * 60;
}
$daylight = (int) date("I");
if($daylight === 0){
$offset -= 3600;
}
date_default_timezone_set(timezone_name_from_abbr("", $offset, $daylight));
gc_enable();
error_reporting(E_ALL ^ E_NOTICE);
ini_set("allow_url_fopen", 1);
ini_set("display_errors", 1);
ini_set("display_startup_errors", 1);
ini_set("default_charset", "utf-8");
if(defined("POCKETMINE_COMPILE") and POCKETMINE_COMPILE === true){
define("FILE_PATH", realpath(dirname(__FILE__))."/");
}else{
define("FILE_PATH", realpath(dirname(__FILE__)."/../")."/");
}
set_include_path(get_include_path() . PATH_SEPARATOR . FILE_PATH);
ini_set("memory_limit", "128M"); //Default
define("LOG", true);
define("START_TIME", microtime(true));
define("MAJOR_VERSION", "Alpha_1.3.7");
define("CURRENT_MINECRAFT_VERSION", "0.7.4 alpha");
define("CURRENT_API_VERSION", 10);
define("CURRENT_PHP_VERSION", "5.5");
$gitsha1 = false;
if(file_exists(FILE_PATH.".git/refs/heads/master")){ //Found Git information!
define(GIT_COMMIT, strtolower(trim(file_get_contents(FILE_PATH.".git/refs/heads/master"))));
}else{ //Unknown :(
define(GIT_COMMIT, str_repeat("00", 20));
}

158
src/constants/BlockIDs.php Normal file
View File

@ -0,0 +1,158 @@
<?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/
*
*
*/
define("AIR", 0);
define("STONE", 1);
define("GRASS", 2);
define("DIRT", 3);
define("COBBLESTONE", 4);
define("COBBLE", 4);
define("PLANK", 5);
define("PLANKS", 5);
define("WOODEN_PLANK", 5);
define("WOODEN_PLANKS", 5);
define("SAPLING", 6);
define("SAPLINGS", 6);
define("BEDROCK", 7);
define("WATER", 8);
define("STILL_WATER", 9);
define("LAVA", 10);
define("STILL_LAVA", 11);
define("SAND", 12);
define("GRAVEL", 13);
define("GOLD_ORE", 14);
define("IRON_ORE", 15);
define("COAL_ORE", 16);
define("WOOD", 17);
define("TRUNK", 17);
define("LEAVES", 18);
define("LEAVE", 18);
define("GLASS", 20);
define("LAPIS_ORE", 21);
define("LAPIS_BLOCK", 22);
define("SANDSTONE", 24);
define("BED_BLOCK", 26);
define("COBWEB", 30);
define("TALL_GRASS", 31);
define("BUSH", 32);
define("DEAD_BUSH", 32);
define("WOOL", 35);
define("DANDELION", 37);
define("ROSE", 38);
define("CYAN_FLOWER", 38);
define("BROWN_MUSHROOM", 39);
define("RED_MUSHROOM", 40);
define("GOLD_BLOCK", 41);
define("IRON_BLOCK", 42);
define("DOUBLE_SLAB", 43);
define("DOUBLE_SLABS", 43);
define("SLAB", 44);
define("SLABS", 44);
define("BRICKS", 45);
define("BRICKS_BLOCK", 45);
define("TNT", 46);
define("BOOKSHELF", 47);
define("MOSS_STONE", 48);
define("MOSSY_STONE", 48);
define("OBSIDIAN", 49);
define("TORCH", 50);
define("FIRE", 51);
define("WOOD_STAIRS", 53);
define("WOODEN_STAIRS", 53);
define("CHEST", 54);
define("DIAMOND_ORE", 56);
define("DIAMOND_BLOCK", 57);
define("CRAFTING_TABLE", 58);
define("WORKBENCH", 58);
define("WHEAT_BLOCK", 59);
define("FARMLAND", 60);
define("FURNACE", 61);
define("BURNING_FURNACE", 62);
define("LIT_FURNACE", 62);
define("SIGN_POST", 63);
define("DOOR_BLOCK", 64);
define("WOODEN_DOOR_BLOCK", 64);
define("WOOD_DOOR_BLOCK", 64);
define("LADDER", 65);
define("COBBLE_STAIRS", 67);
define("COBBLESTONE_STAIRS", 67);
define("WALL_SIGN", 68);
define("IRON_DOOR_BLOCK", 71);
define("REDSTONE_ORE", 73);
define("GLOWING_REDSTONE_ORE", 74);
define("LIT_REDSTONE_ORE", 74);
define("SNOW", 78);
define("SNOW_LAYER", 78);
define("ICE", 79);
define("SNOW_BLOCK", 80);
define("CACTUS", 81);
define("CLAY_BLOCK", 82);
define("REEDS", 83);
define("SUGARCANE_BLOCK", 83);
define("FENCE", 85);
define("NETHERRACK", 87);
define("SOUL_SAND", 88);
define("GLOWSTONE", 89);
define("GLOWSTONE_BLOCK", 89);
define("CAKE_BLOCK", 92);
define("TRAPDOOR", 96);
define("STONE_BRICKS", 98);
define("STONE_BRICK", 98);
define("GLASS_PANE", 102);
define("GLASS_PANEL", 102);
define("MELON_BLOCK", 103);
define("MELON_STEM", 105);
define("FENCE_GATE", 107);
define("BRICK_STAIRS", 108);
define("STONE_BRICK_STAIRS", 109);
define("NETHER_BRICKS", 112);
define("NETHER_BRICK_BLOCK", 112);
define("NETHER_BRICKS_STAIRS", 114);
define("SANDSTONE_STAIRS", 128);
define("QUARTZ_BLOCK", 155);
define("QUARTZ_STAIRS", 156);
define("STONECUTTER", 245);
define("GLOWING_OBSIDIAN", 246);
define("NETHER_REACTOR", 247);

View File

@ -0,0 +1,79 @@
<?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/
*
*
*/
define("PMF_LEVEL_DEFLATE_LEVEL", 6);
//Gamemodes
define("SURVIVAL", 0);
define("CREATIVE", 1);
define("ADVENTURE", 2);
define("VIEW", 3);
define("VIEWER", 3);
//Players
define("MAX_CHUNK_RATE", 20 / arg("max-chunks-per-second", 3.5)); //Default rate ~172 kB/s
define("PLAYER_MAX_QUEUE", 1024);
define("PLAYER_SURVIVAL_SLOTS", 36);
define("PLAYER_CREATIVE_SLOTS", 112);
//Block Updates
define("BLOCK_UPDATE_NORMAL", 1);
define("BLOCK_UPDATE_RANDOM", 2);
define("BLOCK_UPDATE_SCHEDULED", 3);
define("BLOCK_UPDATE_WEAK", 4);
define("BLOCK_UPDATE_TOUCH", 5);
//Entities
define("ENTITY_PLAYER", 1);
define("ENTITY_MOB", 2);
define("MOB_CHICKEN", 10);
define("MOB_COW", 11);
define("MOB_PIG", 12);
define("MOB_SHEEP", 13);
define("MOB_ZOMBIE", 32);
define("MOB_CREEPER", 33);
define("MOB_SKELETON", 34);
define("MOB_SPIDER", 35);
define("MOB_PIGMAN", 36);
define("ENTITY_OBJECT", 3);
define("OBJECT_ARROW", 80);
define("OBJECT_PAINTING", 83);
define("ENTITY_ITEM", 4);
define("ENTITY_FALLING", 5);
define("FALLING_SAND", 66);
//TileEntities
define("TILE_SIGN", "Sign");
define("TILE_CHEST", "Chest");
define("CHEST_SLOTS", 27);
define("TILE_FURNACE", "Furnace");
define("FURNACE_SLOTS", 3);

150
src/constants/ItemIDs.php Normal file
View File

@ -0,0 +1,150 @@
<?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/
*
*
*/
define("IRON_SHOVEL", 256);//Implemented
define("IRON_PICKAXE", 257);//Implemented
define("IRON_AXE", 258);//Implemented
define("FLINT_STEEL", 259);
define("FLINT_AND_STEEL", 259);
define("APPLE", 260);//Implemented
define("BOW", 261);
define("ARROW", 262);
define("COAL", 263);//Implemented
define("DIAMOND", 264);//Implemented
define("IRON_INGOT", 265);//Implemented
define("GOLD_INGOT", 266);//Implemented
define("IRON_SWORD", 267);
define("WOODEN_SWORD", 268);//Implemented
define("WOODEN_SHOVEL", 269);//Implemented
define("WOODEN_PICKAXE", 270);//Implemented
define("WOODEN_AXE", 271);//Implemented
define("STONE_SWORD", 272);
define("STONE_SHOVEL", 273);
define("STONE_PICKAXE", 274);
define("STONE_AXE", 275);
define("DIAMOND_SWORD", 276);
define("DIAMOND_SHOVEL", 277);
define("DIAMOND_PICKAXE", 278);
define("DIAMOND_AXE", 279);
define("STICK", 280);//Implemented
define("STICKS", 280);
define("BOWL", 281);//Implemented
define("MUSHROOM_STEW", 282);
define("GOLD_SWORD", 283);
define("GOLD_SHOVEL", 284);
define("GOLD_PICKAXE", 285);
define("GOLD_AXE", 286);
define("GOLDEN_SWORD", 283);
define("GOLDEN_SHOVEL", 284);
define("GOLDEN_PICKAXE", 285);
define("GOLDEN_AXE", 286);
define("STRING", 287);
define("FEATHER", 288);//Implemented
define("GUNPOWDER", 289);
define("WOODEN_HOE", 290);
define("STONE_HOE", 291);
define("IRON_HOE", 292);//Implemented
define("DIAMOND_HOE", 293);
define("GOLD_HOE", 294);
define("GOLDEN_HOE", 294);
define("SEEDS", 295);
define("WHEAT_SEEDS", 295);
define("WHEAT", 296);
define("BREAD", 297);
define("LEATHER_CAP", 298);
define("LEATHER_TUNIC", 299);
define("LEATHER_PANTS", 300);
define("LEATHER_BOOTS", 301);
define("CHAIN_HELMET", 302);
define("CHAIN_CHESTPLATE", 303);
define("CHAIN_LEGGINGS", 304);
define("CHAIN_BOOTS", 305);
define("IRON_HELMET", 306);
define("IRON_CHESTPLATE", 307);
define("IRON_LEGGINGS", 308);
define("IRON_BOOTS", 309);
define("DIAMOND_HELMET", 310);
define("DIAMOND_CHESTPLATE", 311);
define("DIAMOND_LEGGINGS", 312);
define("DIAMOND_BOOTS", 313);
define("GOLD_HELMET", 314);
define("GOLD_CHESTPLATE", 315);
define("GOLD_LEGGINGS", 316);
define("GOLD_BOOTS", 317);
define("FLINT", 318);
define("RAW_PORKCHOP", 319);
define("COOKED_PORKCHOP", 320);
define("PAINTING", 321);
define("GOLDEN_APPLE", 322);
define("SIGN", 323);
define("WOODEN_DOOR", 324);
define("BUCKET", 325);
define("IRON_DOOR", 330);
define("SNOWBALL", 332);
define("LEATHER", 334);
define("BRICK", 336);
define("CLAY", 337);
define("SUGARCANE", 338);
define("SUGAR_CANE", 338);
define("SUGAR_CANES", 338);
define("PAPER", 339);
define("SLIMEBALL", 341);
define("EGG", 344);
define("COMPASS", 345);
define("GLOWSTONE_DUST", 348);
//define("RAW_FISH", 349);
//define("COOKED_FISH", 350);
define("DYE", 351);
define("BONE", 352);
define("SUGAR", 353);
define("CAKE", 354);
define("BED", 355);
//define("COOKIE", 357);
define("SHEARS", 359);
define("MELON", 360);
define("MELON_SLICE", 360);
define("MELON_SEEDS", 362);
define("RAW_BEEF", 363);
define("STEAK", 364);
define("COOKED_BEEF", 364);
define("RAW_CHICKEN", 365);
define("COOKED_CHICKEN", 366);
define("SPAWN_EGG", 383);
define("NETHER_BRICK", 405);
define("QUARTZ", 406);
define("NETHER_QUARTZ", 406);
define("CAMERA", 456);

84
src/dependencies.php Normal file
View File

@ -0,0 +1,84 @@
<?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/
*
*
*/
/***REM_START***/
require_once(dirname(__FILE__)."/config.php");
require_once(FILE_PATH."/src/functions.php");
/***REM_END***/
define(DATA_PATH, realpath(arg("data-path", FILE_PATH))."/");
if(arg("enable-ansi", strpos(strtoupper(php_uname("s")), "WIN") === false ? true:false) === true){
define("ENABLE_ANSI", true);
}else{
define("ENABLE_ANSI", false);
}
set_error_handler("error_handler", E_ALL);
$errors = 0;
if(version_compare("5.4.0", PHP_VERSION) > 0){
console("[ERROR] Use PHP >= 5.4.0", true, true, 0);
++$errors;
}
if(php_sapi_name() !== "cli"){
console("[ERROR] You must run PocketMine-MP using the CLI.", true, true, 0);
++$errors;
}
if(!extension_loaded("sockets") and @dl((PHP_SHLIB_SUFFIX === "dll" ? "php_":"") . "sockets." . PHP_SHLIB_SUFFIX) === false){
console("[ERROR] Unable to find the Socket extension.", true, true, 0);
++$errors;
}
if(!extension_loaded("pthreads") and @dl((PHP_SHLIB_SUFFIX === "dll" ? "php_":"") . "pthreads." . PHP_SHLIB_SUFFIX) === false){
console("[ERROR] Unable to find the pthreads extension.", true, true, 0);
++$errors;
}
if(!extension_loaded("curl") and @dl((PHP_SHLIB_SUFFIX === "dll" ? "php_":"") . "curl." . PHP_SHLIB_SUFFIX) === false){
console("[ERROR] Unable to find the cURL extension.", true, true, 0);
++$errors;
}
if(!extension_loaded("sqlite3") and @dl((PHP_SHLIB_SUFFIX === "dll" ? "php_":"") . "sqlite3." . PHP_SHLIB_SUFFIX) === false){
console("[ERROR] Unable to find the SQLite3 extension.", true, true, 0);
++$errors;
}
if(!extension_loaded("zlib") and @dl((PHP_SHLIB_SUFFIX === "dll" ? "php_":"") . "zlib." . PHP_SHLIB_SUFFIX) === false){
console("[ERROR] Unable to find the Zlib extension.", true, true, 0);
++$errors;
}
if($errors > 0){
console("[ERROR] Please use the installer provided on the homepage.", true, true, 0);
exit(1); //Exit with error
}
/***REM_START***/
require_once(FILE_PATH."/src/math/Vector3.php");
require_once(FILE_PATH."/src/world/Position.php");
require_once(FILE_PATH."/src/pmf/PMF.php");
require_all(FILE_PATH . "src/");
/***REM_END***/

View File

@ -1,61 +1,102 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
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.
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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/
*
*
*/
if(!function_exists("cli_set_process_title")){
function cli_set_process_title($title){
if(ENABLE_ANSI === true){
echo "\x1b]0;".$title."\x07";
return true;
}else{
return false;
}
}
}
function dummy(){
}
function safe_var_dump($var, $cnt = 0){
switch(true){
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;
safe_var_dump($value, $cnt + 1);
}
echo str_repeat(" ", $cnt)."}".PHP_EOL;
break;
case is_integer($var):
echo str_repeat(" ", $cnt)."int(".$var.")".PHP_EOL;
break;
case is_float($var):
echo str_repeat(" ", $cnt)."float(".$var.")".PHP_EOL;
break;
case is_bool($var):
echo str_repeat(" ", $cnt)."bool(".($var === true ? "true":"false").")".PHP_EOL;
break;
case is_string($var):
echo str_repeat(" ", $cnt)."string(".strlen($var).") \"$var\"".PHP_EOL;
break;
case is_resource($var):
echo str_repeat(" ", $cnt)."resource() of type (".get_resource_type($var).")".PHP_EOL;
break;
case is_object($var):
echo str_repeat(" ", $cnt)."object(".get_class($var).")".PHP_EOL;
break;
case is_null($var):
echo str_repeat(" ", $cnt)."NULL".PHP_EOL;
break;
}
}
function kill($pid){
switch(Utils::getOS()){
case "win":
ob_start();
passthru("%WINDIR%\\System32\\taskkill.exe /F /PID ".((int) $pid));
ob_end_clean();
exec("taskkill.exe /F /PID ".((int) $pid)." > NUL");
break;
case "mac":
case "linux":
default:
ob_start();
passthru("kill -9 ".((int) $pid));
ob_end_clean();
exec("kill -9 ".((int) $pid)." > /dev/null 2>&1");
}
}
function require_all($path, &$count = 0){
$dir = dir($path."/");
$dirs = array();
while(false !== ($file = $dir->read())){
if($file !== "." and $file !== ".."){
if(!is_dir($path.$file) and strtolower(substr($file, -3)) === "php"){
require_once($path.$file);
++$count;
}elseif(is_dir($path.$file)){
require_all($path.$file."/", $count);
$dirs[] = $path.$file."/";
}
}
}
foreach($dirs as $dir){
require_all($dir, $count);
}
}
@ -81,32 +122,6 @@ function hard_unset(&$var){
}
}
function parseNBTData($data){
$x = array();
if(isset($data["value"])){
return parseNBTData($data["value"]);
}
foreach($data as $d){
if(!isset($d["value"]) and is_array($d) and count($d) == 1){
return parseNBTData(array_pop($d));
}elseif(!isset($d["value"]) and is_array($d)){
$x[] = parseNBTData($d);
}elseif(is_array($d["value"]) and isset($d["name"])){
$x[$d["name"]] = parseNBTData($d["value"]);
}elseif(is_array($d["value"]) and $d["type"] == 10){
return parseNBTData($d["value"]);
}elseif($d["name"] != ""){
$x[$d["name"]] = $d["value"];
}
}
if(count($x) == 0){
$x = $data;
}
return $x;
}
function arg($name, $default = false){
global $arguments, $argv;
if(!isset($arguments)){
@ -173,8 +188,9 @@ function console($message, $EOL = true, $log = true, $level = 1){
logg($replaced, "console", false, $level);
}
if(ENABLE_ANSI === true){
$add = "";
if(preg_match("/\[([a-zA-Z0-9]*)\]/", $message, $matches) > 0){
$add = "\x1b";
$add .= "\x1b";
switch($matches[1]){
case "ERROR":
$add .= "[31;1m";
@ -193,8 +209,8 @@ function console($message, $EOL = true, $log = true, $level = 1){
$add = "";
break;
}
$message = $time . $add . $message . "\x1b[0m";
}
$message = $time . $add . $message . "\x1b[0m";
}else{
$message = $replaced;
}
@ -202,15 +218,12 @@ function console($message, $EOL = true, $log = true, $level = 1){
}
}
function fatal_handler($errno, $errstr, $errfile, $errline){
global $lasttrace;
function error_handler($errno, $errstr, $errfile, $errline){
if(error_reporting() === 0){ //@ error-control
return false;
}
console("[ERROR] A level ".$errno." error happened: \"$errstr\" in \"$errfile\" at line $errline", true, true, 0);
ob_start();
debug_print_backtrace();
$lasttrace = ob_get_contents();
ob_end_clean();
console("[ERROR] [Backtrace] $lasttrace", true, true, 0);
return false;
return true;
}
function logg($message, $name, $EOL = true, $level = 2, $close = false){
@ -221,7 +234,7 @@ function logg($message, $name, $EOL = true, $level = 2, $close = false){
$fpointers = array();
}
if(!isset($fpointers[$name]) or $fpointers[$name] === false){
$fpointers[$name] = @fopen(FILE_PATH."logs/".$name.".log", "ab");
$fpointers[$name] = @fopen(DATA_PATH."/".$name.".log", "ab");
}
@fwrite($fpointers[$name], $message);
if($close === true){

34
src/inventory/Window.php Normal file
View File

@ -0,0 +1,34 @@
<?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/
*
*
*/
define("WINDOW_CHEST", 0);
define("WINDOW_WORKBENCH", 1);
define("WINDOW_FURNACE", 2);
define("WINDOW_STONECUTTER", 3);
class Window{
private $server;
public function __construct(){
$this->server = ServerAPI::request();
}
}
?>

223
src/material/Block.php Normal file
View File

@ -0,0 +1,223 @@
<?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/
*
*
*/
abstract class Block extends Position{
public static $class = array(
AIR => "AirBlock",
STONE => "StoneBlock",
GRASS => "GrassBlock",
DIRT => "DirtBlock",
COBBLESTONE => "CobblestoneBlock",
PLANKS => "PlanksBlock",
SAPLING => "SaplingBlock",
BEDROCK => "BedrockBlock",
WATER => "WaterBlock",
STILL_WATER => "StillWaterBlock",
LAVA => "LavaBlock",
STILL_LAVA => "StillLavaBlock",
SAND => "SandBlock",
GRAVEL => "GravelBlock",
GOLD_ORE => "GoldOreBlock",
IRON_ORE => "IronOreBlock",
COAL_ORE => "CoalOreBlock",
WOOD => "WoodBlock",
LEAVES => "LeavesBlock",
GLASS => "GlassBlock",
LAPIS_ORE => "LapisOreBlock",
LAPIS_BLOCK => "LapisBlock",
SANDSTONE => "SandstoneBlock",
BED_BLOCK => "BedBlock",
COBWEB => "CobwebBlock",
TALL_GRASS => "TallGrassBlock",
DEAD_BUSH => "DeadBushBlock",
WOOL => "WoolBlock",
DANDELION => "DandelionBlock",
CYAN_FLOWER => "CyanFlowerBlock",
BROWN_MUSHROOM => "BrownMushroomBlock",
RED_MUSHROOM => "RedMushRoomBlock",
GOLD_BLOCK => "GoldBlock",
IRON_BLOCK => "IronBlock",
DOUBLE_SLAB => "DoubleSlabBlock",
SLAB => "SlabBlock",
BRICKS_BLOCK => "BricksBlock",
TNT => "TNTBlock",
BOOKSHELF => "BookshelfBlock",
MOSS_STONE => "MossStoneBlock",
OBSIDIAN => "ObsidianBlock",
TORCH => "TorchBlock",
FIRE => "FireBlock",
WOOD_STAIRS => "WoodStairsBlock",
CHEST => "ChestBlock",
DIAMOND_ORE => "DiamondOreBlock",
DIAMOND_BLOCK => "DiamondBlock",
WORKBENCH => "WorkbenchBlock",
WHEAT_BLOCK => "WheatBlock",
FARMLAND => "FarmlandBlock",
FURNACE => "FurnaceBlock",
BURNING_FURNACE => "BurningFurnaceBlock",
SIGN_POST => "SignPostBlock",
WOOD_DOOR_BLOCK => "WoodDoorBlock",
LADDER => "LadderBlock",
COBBLESTONE_STAIRS => "CobblestoneStairsBlock",
WALL_SIGN => "WallSignBlock",
IRON_DOOR_BLOCK => "IronDoorBlock",
REDSTONE_ORE => "RedstoneOreBlock",
GLOWING_REDSTONE_ORE => "GlowingRedstoneOreBlock",
SNOW_LAYER => "SnowLayerBlock",
ICE => "IceBlock",
SNOW_BLOCK => "SnowBlock",
CACTUS => "CactusBlock",
CLAY_BLOCK => "ClayBlock",
SUGARCANE_BLOCK => "SugarcaneBlock",
FENCE => "FenceBlock",
NETHERRACK => "NetherrackBlock",
SOUL_SAND => "SoulSandBlock",
GLOWSTONE_BLOCK => "GlowstoneBlock",
CAKE_BLOCK => "CakeBlock",
TRAPDOOR => "TrapdoorBlock",
STONE_BRICKS => "StoneBricksBlock",
GLASS_PANE => "GlassPaneBlock",
MELON_BLOCK => "MelonBlock",
MELON_STEM => "MelonStemBlock",
FENCE_GATE => "FenceGateBlock",
BRICK_STAIRS => "BrickStairsBlock",
STONE_BRICK_STAIRS => "StoneBrickStairsBlock",
NETHER_BRICKS => "NetherBricksBlock",
NETHER_BRICKS_STAIRS => "NetherBricksStairsBlock",
SANDSTONE_STAIRS => "SandstoneStairsBlock",
QUARTZ_BLOCK => "QuartzBlock",
QUARTZ_STAIRS => "QuartzStairsBlock",
STONECUTTER => "StonecutterBlock",
GLOWING_OBSIDIAN => "GlowingObsidianBlock",
NETHER_REACTOR => "NetherReactorBlock",
);
protected $id;
protected $meta;
protected $name;
protected $breakTime;
public $isActivable = false;
public $breakable = true;
public $isFlowable = false;
public $isSolid = true;
public $isTransparent = false;
public $isReplaceable = false;
public $isPlaceable = true;
public $level = false;
public $hasPhysics = false;
public $isLiquid = false;
public $isFullBlock = true;
public $x = 0;
public $y = 0;
public $z = 0;
public function __construct($id, $meta = 0, $name = "Unknown"){
$this->id = (int) $id;
$this->meta = (int) $meta;
$this->name = $name;
$this->breakTime = 0.20;
}
final public function getName(){
return $this->name;
}
final public function getID(){
return $this->id;
}
final public function getMetadata(){
return $this->meta & 0x0F;
}
final public function position(Position $v){
$this->level = $v->level;
$this->x = (int) $v->x;
$this->y = (int) $v->y;
$this->z = (int) $v->z;
}
public function getDrops(Item $item, Player $player){
if(!isset(Block::$class[$this->id])){ //Unknown blocks
return array();
}else{
return array(
array($this->id, $this->meta, 1),
);
}
}
public function getBreakTime(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0x01){
return 0.15;
}
return $this->breakTime;
}
public function getSide($side){
$v = parent::getSide($side);
if($this->level instanceof Level){
return $this->level->getBlock($v);
}
return $v;
}
final public function __toString(){
return "Block ". $this->name ." (".$this->id.":".$this->meta.")";
}
abstract function isBreakable(Item $item, Player $player);
abstract function onBreak(Item $item, Player $player);
abstract function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz);
abstract function onActivate(Item $item, Player $player);
abstract function onUpdate($type);
}
/***REM_START***/
require_once("block/GenericBlock.php");
require_once("block/SolidBlock.php");
require_once("block/TransparentBlock.php");
require_once("block/FallableBlock.php");
require_once("block/LiquidBlock.php");
require_once("block/StairBlock.php");
require_once("block/DoorBlock.php");
/***REM_END***/

275
src/material/Item.php Normal file
View File

@ -0,0 +1,275 @@
<?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/
*
*
*/
class Item{
public static $class = array(
SUGARCANE => "SugarcaneItem",
WHEAT_SEEDS => "WheatSeedsItem",
MELON_SEEDS => "MelonSeedsItem",
SIGN => "SignItem",
WOODEN_DOOR => "WoodenDoorItem",
BUCKET => "BucketItem",
IRON_DOOR => "IronDoorItem",
CAKE => "CakeItem",
BED => "BedItem",
PAINTING => "PaintingItem",
COAL => "CoalItem",
APPLE => "AppleItem",
SPAWN_EGG => "SpawnEggItem",
DIAMOND => "DiamondItem",
STICK => "StickItem",
BOWL => "BowlItem",
FEATHER => "FeatherItem",
BRICK => "BrickItem",
IRON_INGOT => "IronIngotItem",
GOLD_INGOT => "GoldIngotItem",
IRON_SHOVEL => "IronShovelItem",
IRON_PICKAXE => "IronPickaxeItem",
IRON_AXE => "IronAxeItem",
IRON_HOE => "IronHoeItem",
WOODEN_SWORD => "WoodenSwordItem",
WOODEN_SHOVEL => "WoodenShovelItem",
WOODEN_PICKAXE => "WoodenPickaxeItem",
WOODEN_AXE => "WoodenAxeItem",
FLINT_STEEL => "FlintSteelItem",
);
protected $block;
protected $id;
protected $meta;
public $count;
protected $maxStackSize = 64;
protected $durability = 0;
protected $name;
public $isActivable = false;
public function __construct($id, $meta = 0, $count = 1, $name = "Unknown"){
$this->id = (int) $id;
$this->meta = (int) $meta;
$this->count = (int) $count;
$this->name = $name;
if(!isset($this->block) and $this->id <= 0xff and isset(Block::$class[$this->id])){
$this->block = BlockAPI::get($this->id, $this->meta);
$this->name = $this->block->getName();
}
if($this->isTool() !== false){
$this->maxStackSize = 1;
}
}
final public function getName(){
return $this->name;
}
final public function isPlaceable(){
return (($this->block instanceof Block) and $this->block->isPlaceable === true);
}
final public function getBlock(){
if($this->block instanceof Block){
return $this->block;
}else{
return BlockAPI::get(AIR);
}
}
final public function getID(){
return $this->id;
}
final public function getMetadata(){
return $this->meta;
}
final public function getMaxStackSize(){
return $this->maxStackSize;
}
final public function getFuelTime(){
if(!isset(FuelData::$duration[$this->id])){
return false;
}
if($this->id !== BUCKET or $this->meta === 10){
return FuelData::$duration[$this->id];
}
return false;
}
final public function getSmeltItem(){
if(!isset(SmeltingData::$product[$this->id])){
return false;
}
if(isset(SmeltingData::$product[$this->id][0]) and !is_array(SmeltingData::$product[$this->id][0])){
return BlockAPI::getItem(SmeltingData::$product[$this->id][0], SmeltingData::$product[$this->id][1]);
}
if(!isset(SmeltingData::$product[$this->id][$this->meta])){
return false;
}
return BlockAPI::getItem(SmeltingData::$product[$this->id][$this->meta][0], SmeltingData::$product[$this->id][$this->meta][1]);
}
public function useOn($object, $force = false){
if($this->isTool() or $force === true){
if(($object instanceof Entity) and !$this->isSword()){
$this->meta += 2;
}else{
$this->meta++;
}
return true;
}
return false;
}
final public function isTool(){
return ($this->id === FLINT_STEEL or $this->id === SHEARS or $this->isPickaxe() !== false or $this->isAxe() !== false or $this->isShovel() !== false or $this->isSword() !== false);
}
final public function getMaxDurability(){
if(!$this->isTool() and $this->isHoe() === false and $this->id !== BOW){
return false;
}
$levels = array(
2 => 33,
1 => 60,
3 => 132,
4 => 251,
5 => 1562,
FLINT_STEEL => 65,
SHEARS => 239,
BOW => 385,
);
if(($type = $this->isPickaxe()) === false){
if(($type = $this->isAxe()) === false){
if(($type = $this->isSword()) === false){
if(($type = $this->isShovel()) === false){
if(($type = $this->isHoe()) === false){
$type = $this->id;
}
}
}
}
}
return $levels[$type];
}
final public function isPickaxe(){ //Returns false or level of the pickaxe
switch($this->id){
case IRON_PICKAXE:
return 4;
case WOODEN_PICKAXE:
return 1;
case STONE_PICKAXE:
return 3;
case DIAMOND_PICKAXE:
return 5;
case GOLD_PICKAXE:
return 2;
default:
return false;
}
}
final public function isAxe(){
switch($this->id){
case IRON_AXE:
return 4;
case WOODEN_AXE:
return 1;
case STONE_AXE:
return 3;
case DIAMOND_AXE:
return 5;
case GOLD_AXE:
return 2;
default:
return false;
}
}
final public function isSword(){
switch($this->id){
case IRON_SWORD:
return 4;
case WOODEN_SWORD:
return 1;
case STONE_SWORD:
return 3;
case DIAMOND_SWORD:
return 5;
case GOLD_SWORD:
return 2;
default:
return false;
}
}
final public function isShovel(){
switch($this->id){
case IRON_SHOVEL:
return 4;
case WOODEN_SHOVEL:
return 1;
case STONE_SHOVEL:
return 3;
case DIAMOND_SHOVEL:
return 5;
case GOLD_SHOVEL:
return 2;
default:
return false;
}
}
public function isHoe(){
switch($this->id){
case IRON_HOE:
case WOODEN_HOE:
case STONE_HOE:
case DIAMOND_HOE:
case GOLD_HOE:
return true;
default:
return false;
}
}
public function isShears(){
return ($this->id === SHEARS);
}
final public function __toString(){
return "Item ". $this->name ." (".$this->id.":".$this->meta.")";
}
public function getDestroySpeed(Block $block, Player $player){
return 1;
}
public function onActivate(Level $level, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
return false;
}
}

View File

@ -0,0 +1,88 @@
<?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/
*
*
*/
class DoorBlock extends TransparentBlock{
public function __construct($id, $meta = 0, $name = "Unknown"){
parent::__construct($id, $meta, $name);
$this->isSolid = false;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
if($face === 1){
$blockUp = $this->getSide(1);
$blockDown = $this->getSide(0);
if($blockUp->isReplaceable === false or $blockDown->isTransparent === true){
return false;
}
$direction = $player->entity->getDirection();
$face = array(
0 => 3,
1 => 4,
2 => 2,
3 => 5,
);
$next = $this->getSide($face[(($direction + 2) % 4)]);
$next2 = $this->getSide($face[$direction]);
$metaUp = 0x08;
if($next->getID() === $this->id or ($next2->isTransparent === false and $next->isTransparent === true)){ //Door hinge
$metaUp |= 0x01;
}
$this->level->setBlock($blockUp, BlockAPI::get($this->id, $metaUp)); //Top
$this->meta = $direction & 0x03;
$this->level->setBlock($block, $this); //Bottom
return true;
}
return false;
}
public function onBreak(Item $item, Player $player){
if(($this->meta & 0x08) === 0x08){
$down = $this->getSide(0);
if($down->getID() === $this->id){
$this->level->setBlock($down, new AirBlock());
}
}else{
$up = $this->getSide(1);
if($up->getID() === $this->id){
$this->level->setBlock($up, new AirBlock());
}
}
$this->level->setBlock($this, new AirBlock());
return true;
}
public function onActivate(Item $item, Player $player){
if(($this->meta & 0x08) === 0x08){ //Top
$down = $this->getSide(0);
if($down->getID() === $this->id){
$meta = $down->getMetadata() ^ 0x04;
$this->level->setBlock($down, BlockAPI::get($this->id, $meta));
return true;
}
return false;
}else{
$this->meta ^= 0x04;
$this->level->setBlock($this, $this);
}
return true;
}
}

View File

@ -0,0 +1,33 @@
<?php
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
class FallableBlock extends SolidBlock{
public function __construct($id, $meta = 0, $name = "Unknown"){
parent::__construct($id, $meta, $name);
$this->hasPhysics = true;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
$ret = $this->level->setBlock($this, $this, true, false, true);
ServerAPI::request()->api->block->blockUpdate(clone $this, BLOCK_UPDATE_NORMAL);
return $ret;
}
}

View File

@ -0,0 +1,29 @@
<?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/
*
*
*/
class FlowableBlock extends TransparentBlock{
public function __construct($id, $meta = 0, $name = "Unknown"){
parent::__construct($id, $meta, $name);
$this->isFlowable = true;
$this->isFullBlock = false;
$this->isSolid = false;
}
}

View File

@ -0,0 +1,63 @@
<?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/
*
*
*/
class GenericBlock extends Block{
public function __construct($id, $meta = 0, $name = "Unknown"){
parent::__construct($id, $meta, $name);
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
return $this->level->setBlock($this, $this, true, false, true);
}
public function isBreakable(Item $item, Player $player){
return ($this->breakable);
}
public function onBreak(Item $item, Player $player){
return $this->level->setBlock($this, new AirBlock(), true, false, true);
}
public function onUpdate($type){
if($this->hasPhysics === true and $type === BLOCK_UPDATE_NORMAL){
$down = $this->getSide(0);
if($down->getID() === AIR or ($down instanceof LiquidBlock)){
$data = array(
"x" => $this->x + 0.5,
"y" => $this->y + 0.5,
"z" => $this->z + 0.5,
"Tile" => $this->id,
);
$server = ServerAPI::request();
$this->level->setBlock($this, new AirBlock(), false, false, true);
$e = $server->api->entity->add($this->level, ENTITY_FALLING, FALLING_SAND, $data);
$server->api->entity->spawnToAll($e);
$server->api->block->blockUpdateAround(clone $this, BLOCK_UPDATE_NORMAL, 1);
}
return false;
}
return false;
}
public function onActivate(Item $item, Player $player){
return $this->isActivable;
}
}

View File

@ -0,0 +1,31 @@
<?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/
*
*
*/
class LiquidBlock extends TransparentBlock{
public function __construct($id, $meta = 0, $name = "Unknown"){
parent::__construct($id, $meta, $name);
$this->isLiquid = true;
$this->breakable = false;
$this->isReplaceable = true;
$this->isSolid = false;
$this->isFullBlock = true;
}
}

View File

@ -0,0 +1,28 @@
<?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/
*
*
*/
class SolidBlock extends GenericBlock{
public function __construct($id, $meta = 0, $name = "Unknown"){
parent::__construct($id, $meta, $name);
$this->isSolid = true;
$this->isFullBlock = true;
}
}

View File

@ -0,0 +1,56 @@
<?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/
*
*
*/
class StairBlock extends TransparentBlock{
public function __construct($id, $meta = 0, $name = "Unknown"){
parent::__construct($id, $meta, $name);
if(($this->meta & 0x04) === 0x04){
$this->isFullBlock = true;
}else{
$this->isFullBlock = false;
}
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
$faces = array(
0 => 0,
1 => 2,
2 => 1,
3 => 3,
);
$this->meta = $faces[$player->entity->getDirection()] & 0x03;
if(($fy > 0.5 and $face !== 1) or $face === 0){
$this->meta |= 0x04; //Upside-down stairs
}
$this->level->setBlock($block, $this);
return true;
}
public function getDrops(Item $item, Player $player){
if($item->isPickaxe() >= 1){
return array(
array($this->id, 0, 1),
);
}else{
return array();
}
}
}

View File

@ -0,0 +1,33 @@
<?php
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
class TransparentBlock extends GenericBlock{
public function __construct($id, $meta = 0, $name = "Unknown"){
parent::__construct($id, $meta, $name);
$this->isActivable = false;
$this->breakable = true;
$this->isFlowable = false;
$this->isTransparent = true;
$this->isReplaceable = false;
$this->isPlaceable = true;
$this->isSolid = true;
}
}

View File

@ -0,0 +1,49 @@
<?php
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
class LadderBlock extends TransparentBlock{
public function __construct($meta = 0){
parent::__construct(LADDER, $meta, "Ladder");
$this->isSolid = false;
$this->isFullBlock = false;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
if($target->isTransparent === false){
$faces = array(
2 => 2,
3 => 3,
4 => 4,
5 => 5,
);
if(isset($faces[$face])){
$this->meta = $faces[$face];
$this->level->setBlock($block, $this);
return true;
}
}
return false;
}
public function getDrops(Item $item, Player $player){
return array(
array($this->id, 0, 1),
);
}
}

View File

@ -0,0 +1,71 @@
<?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/
*
*
*/
class SignPostBlock extends TransparentBlock{
public function __construct($meta = 0){
parent::__construct(SIGN_POST, $meta, "Sign Post");
$this->isSolid = false;
$this->isFullBlock = false;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
if($face !== 0){
$faces = array(
2 => 2,
3 => 3,
4 => 4,
5 => 5,
);
if(!isset($faces[$face])){
$this->meta = floor((($player->entity->yaw + 180) * 16 / 360) + 0.5) & 0x0F;
$this->level->setBlock($block, BlockAPI::get(SIGN_POST, $this->meta));
return true;
}else{
$this->meta = $faces[$face];
$this->level->setBlock($block, BlockAPI::get(WALL_SIGN, $this->meta));
return true;
}
}
return false;
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->getID() === AIR){ //Replace wit common break method
ServerAPI::request()->api->entity->drop($this, BlockAPI::getItem(SIGN, 0, 1));
$this->level->setBlock($this, new AirBlock(), false);
return BLOCK_UPDATE_NORMAL;
}
}
return false;
}
public function onBreak(Item $item, Player $player){
$this->level->setBlock($this, new AirBlock(), true, true);
return true;
}
public function getDrops(Item $item, Player $player){
return array(
array(SIGN, 0, 1),
);
}
}

View File

@ -0,0 +1,73 @@
<?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/
*
*
*/
class TorchBlock extends FlowableBlock{
public function __construct($meta = 0){
parent::__construct(TORCH, $meta, "Torch");
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
$side = $this->getMetadata();
$faces = array(
1 => 4,
2 => 5,
3 => 2,
4 => 3,
5 => 0,
6 => 0,
0 => 0,
);
if($this->getSide($faces[$side])->isTransparent === true and !($side === 0 and $this->getSide(0)->getID() === FENCE)){ //Replace wit common break method
ServerAPI::request()->api->entity->drop($this, BlockAPI::getItem($this->id, 0, 1));
$this->level->setBlock($this, new AirBlock(), false);
return BLOCK_UPDATE_NORMAL;
}
}
return false;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
if($target->isTransparent === false and $face !== 0){
$faces = array(
1 => 5,
2 => 4,
3 => 3,
4 => 2,
5 => 1,
);
$this->meta = $faces[$face];
$this->level->setBlock($block, $this);
return true;
}elseif($this->getSide(0)->isTransparent === false or $this->getSide(0)->getID() === FENCE){
$this->meta = 0;
$this->level->setBlock($block, $this);
return true;
}
return false;
}
public function getDrops(Item $item, Player $player){
return array(
array($this->id, 0, 1),
);
}
}

View 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/
*
*
*/
class TrapdoorBlock extends TransparentBlock{
public function __construct($meta = 0){
parent::__construct(TRAPDOOR, $meta, "Trapdoor");
$this->isActivable = true;
if(($this->meta & 0x04) === 0x04){
$this->isFullBlock = false;
}else{
$this->isFullBlock = true;
}
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
if(($target->isTransparent === false or $target->getID() === SLAB) and $face !== 0 and $face !== 1){
$faces = array(
2 => 0,
3 => 1,
4 => 2,
5 => 3,
);
$this->meta = $faces[$face] & 0x03;
if($fy > 0.5){
$this->meta |= 0x08;
}
$this->level->setBlock($block, $this);
return true;
}
}
public function getDrops(Item $item, Player $player){
return array(
array($this->id, 0, 1),
);
}
public function onActivate(Item $item, Player $player){
$this->meta ^= 0x04;
$this->level->setBlock($this, $this);
return true;
}
}

View File

@ -0,0 +1,34 @@
<?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/
*
*
*/
/***REM_START***/
require_once("SignPost.php");
/***REM_END***/
class WallSignBlock extends SignPostBlock{
public function __construct($meta = 0){
TransparentBlock::__construct(WALL_SIGN, $meta, "Wall Sign");
}
public function onUpdate($type){
return false;
}
}

View File

@ -0,0 +1,27 @@
<?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/
*
*
*/
class LavaBlock extends LiquidBlock{
public function __construct($meta = 0){
parent::__construct(LAVA, $meta, "Lava");
}
}

View File

@ -0,0 +1,27 @@
<?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/
*
*
*/
class StillLavaBlock extends LiquidBlock{
public function __construct($meta = 0){
parent::__construct(STILL_LAVA, $meta, "Still Lava");
}
}

View File

@ -0,0 +1,32 @@
<?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/
*
*
*/
/***REM_START***/
require_once("Water.php");
/***REM_END***/
class StillWaterBlock extends WaterBlock{
public function __construct($meta = 0){
LiquidBlock::__construct(STILL_WATER, $meta, "Still Water");
}
}

View File

@ -0,0 +1,112 @@
<?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/
*
*
*/
class WaterBlock extends LiquidBlock{
public function __construct($meta = 0){
parent::__construct(WATER, $meta, "Water");
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
$ret = $this->level->setBlock($this, $this, true, false, true);
ServerAPI::request()->api->block->scheduleBlockUpdate(clone $this, 10, BLOCK_UPDATE_NORMAL);
return $ret;
}
public function onUpdate($type){
return false;
$newId = $this->id;
$level = $this->meta & 0x07;
if($type !== BLOCK_UPDATE_NORMAL){
return false;
}
$falling = $this->meta >> 3;
$down = $this->getSide(0);
if($falling === 0){
$countSources = 0;
$maxLevel = $level;
$hasPath = false;
for($side = 2; $side <= 5; ++$side){
$b = $this->getSide($side);
if($b->isFlowable === true and $level < 0x07){
$d = $b->getSide(0);
$this->level->setBlock($b, new WaterBlock($level + 1), false, false, true);
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($b, 0, 0, $this->level), 10, BLOCK_UPDATE_NORMAL);
}elseif($b instanceof WaterBlock){
$oLevel = $b->getMetadata();
$oFalling = $oLevel >> 3;
$oLevel &= 0x07;
if($oFalling === 0){
if($oLevel === 0){
++$countSources;
$maxLevel = 1;
$hasPath = true;
}elseif($oLevel < 0x07 and ($oLevel + 1) <= $maxLevel){
$maxLevel = $oLevel + 1;
$hasPath = true;
}elseif(($level + 1) < $oLevel){
$this->level->setBlock($b, new WaterBlock($level + 1), false, false, true);
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($b, 0, 0, $this->level), 10, BLOCK_UPDATE_NORMAL);
}elseif($level === $oLevel){
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($b, 0, 0, $this->level), 10, BLOCK_UPDATE_NORMAL);
}
}
}
}
if($countSources >= 2){
$level = 0; //Source block
}elseif($maxLevel < $level){
$level = $maxLevel;
}elseif($maxLevel === $level and $level > 0 and $hasPath === false){
if($level < 0x07){
++$level;
}else{
$newId = AIR;
$level = 0;
}
}
}
if($down->isFlowable){
$this->level->setBlock($down, new WaterBlock(0b1001), false, false, true);
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($down, 0, 0, $this->level), 5, BLOCK_UPDATE_NORMAL);
return false;
}elseif($down instanceof LiquidBlock){
if($down instanceof WaterBlock and ($down->getMetadata() >> 3) === 0){
$this->level->setBlock($down, new WaterBlock(0b1000 & min($down->getMetadata(), 1)), false, false, true);
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($down, 0, 0, $this->level), 5, BLOCK_UPDATE_NORMAL);
}
}else{
$falling = 0;
}
$newMeta = ($falling << 0x03) | $level;
if($newMeta !== $this->meta or $newId !== $this->id){
$this->id = $newId;
$this->meta = $newMeta;
$this->level->setBlock($this, $this, false, false, true);
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($this, 0, 0, $this->level), 10, BLOCK_UPDATE_NORMAL);
return false;
}
return false;
}
}

View File

@ -0,0 +1,37 @@
<?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/
*
*
*/
class AirBlock extends TransparentBlock{
public function __construct(){
parent::__construct(AIR, 0, "Air");
$this->isActivable = false;
$this->breakable = false;
$this->isFlowable = true;
$this->isTransparent = true;
$this->isReplaceable = true;
$this->isPlaceable = false;
$this->hasPhysics = false;
$this->isSolid = false;
$this->isFullBlock = true;
}
}

View File

@ -0,0 +1,95 @@
<?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/
*
*
*/
class BedBlock extends TransparentBlock{
public function __construct($type = 0){
parent::__construct(BED_BLOCK, $type, "Bed Block");
$this->isActivable = true;
$this->isFullBlock = false;
}
public function onActivate(Item $item, Player $player){
$player->dataPacket(MC_CLIENT_MESSAGE, array(
"message" => "This bed has been corrupted by your hands!"
));
return true;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
$down = $this->getSide(0);
if($down->isTransparent === false){
$faces = array(
0 => 3,
1 => 4,
2 => 2,
3 => 5,
);
$d = $player->entity->getDirection();
$next = $this->getSide($faces[(($d + 3) % 4)]);
$downNext = $this->getSide(0);
if($next->isReplaceable === true and $downNext->isTransparent === false){
$meta = (($d + 3) % 4) & 0x03;
$this->level->setBlock($block, BlockAPI::get($this->id, $meta));
$this->level->setBlock($next, BlockAPI::get($this->id, $meta | 0x08));
return true;
}
}
return false;
}
public function onBreak(Item $item, Player $player){
$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->level->setBlock($blockNorth, new AirBlock());
}elseif($blockSouth->getID() === $this->id and $blockSouth->meta !== 0x08){
$this->level->setBlock($blockSouth, new AirBlock());
}elseif($blockEast->getID() === $this->id and $blockEast->meta !== 0x08){
$this->level->setBlock($blockEast, new AirBlock());
}elseif($blockWest->getID() === $this->id and $blockWest->meta !== 0x08){
$this->level->setBlock($blockWest, new AirBlock());
}
}else{ //Bottom Part of Bed
if($blockNorth->getID() === $this->id and ($blockNorth->meta & 0x08) === 0x08){
$this->level->setBlock($blockNorth, new AirBlock());
}elseif($blockSouth->getID() === $this->id and ($blockSouth->meta & 0x08) === 0x08){
$this->level->setBlock($blockSouth, new AirBlock());
}elseif($blockEast->getID() === $this->id and ($blockEast->meta & 0x08) === 0x08){
$this->level->setBlock($blockEast, new AirBlock());
}elseif($blockWest->getID() === $this->id and ($blockWest->meta & 0x08) === 0x08){
$this->level->setBlock($blockWest, new AirBlock());
}
}
$this->level->setBlock($this, new AirBlock());
return true;
}
public function getDrops(Item $item, Player $player){
return array(
array(BED, 0, 1),
);
}
}

View File

@ -0,0 +1,53 @@
<?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/
*
*
*/
class FireBlock extends FlowableBlock{
public function __construct($meta = 0){
parent::__construct(FIRE, $meta, "Fire");
$this->isReplaceable = true;
$this->breakable = false;
$this->isFullBlock = true;
}
public function getDrops(Item $item, Player $player){
return array();
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
for($s = 0; $s <= 5; ++$s){
$side = $this->getSide($s);
if($side->getID() !== AIR and !($side instanceof LiquidBlock)){
return false;
}
}
$this->level->setBlock($this, new AirBlock(), false);
return BLOCK_UPDATE_NORMAL;
}elseif($type === BLOCK_UPDATE_RANDOM){
if($this->getSide(0)->getID() !== NETHERRACK){
$this->level->setBlock($this, new AirBlock(), false);
return BLOCK_UPDATE_NORMAL;
}
}
return false;
}
}

View File

@ -0,0 +1,28 @@
<?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/
*
*
*/
class NetherReactorBlock extends SolidBlock{
public function __construct($meta = 0){
parent::__construct(NETHER_REACTOR, $meta, "Nether Reactor");
$this->isActivable = true;
}
}

View File

@ -0,0 +1,26 @@
<?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/
*
*
*/
class TNTBlock extends SolidBlock{
public function __construct(){
parent::__construct(TNT, 0, "TNT");
}
}

View 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/
*
*
*/
class CakeBlock extends TransparentBlock{
public function __construct($meta = 0){
parent::__construct(CAKE_BLOCK, 0, "Cake Block");
$this->isFullBlock = false;
$this->isActivable = true;
$this->meta = $meta & 0x07;
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->getID() === AIR){ //Replace wit common break method
$this->level->setBlock($this, new AirBlock(), false);
return BLOCK_UPDATE_NORMAL;
}
}
return false;
}
public function getDrops(Item $item, Player $player){
return array();
}
public function onActivate(Item $item, Player $player){
if($player->entity->getHealth() < 20){
++$this->meta;
$player->entity->heal(3, "cake");
if($this->meta >= 0x06){
$this->level->setBlock($this, new AirBlock());
}else{
$this->level->setBlock($this, $this);
}
return true;
}
return false;
}
}

View File

@ -0,0 +1,31 @@
<?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/
*
*
*/
class CobwebBlock extends FlowableBlock{
public function __construct(){
parent::__construct(COBWEB, 0, "Cobweb");
$this->isSolid = true;
$this->isFullBlock = false;
}
public function getDrops(Item $item, Player $player){
return array();
}
}

View File

@ -0,0 +1,28 @@
<?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/
*
*
*/
class FenceBlock extends TransparentBlock{
public function __construct(){
parent::__construct(FENCE, 0, "Fence");
$this->isFullBlock = false;
}
}

View File

@ -0,0 +1,59 @@
<?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/
*
*
*/
class FenceGateBlock extends TransparentBlock{
public function __construct($meta = 0){
parent::__construct(FENCE_GATE, $meta, "Fence Gate");
$this->isActivable = true;
if(($this->meta & 0x04) === 0x04){
$this->isFullBlock = true;
}else{
$this->isFullBlock = false;
}
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
$faces = array(
0 => 3,
1 => 0,
2 => 1,
3 => 2,
);
$this->meta = $faces[$player->entity->getDirection()] & 0x03;
$this->level->setBlock($block, $this);
return true;
}
public function getDrops(Item $item, Player $player){
return array(
array($this->id, 0, 1),
);
}
public function onActivate(Item $item, Player $player){
$faces = array(
0 => 3,
1 => 0,
2 => 1,
3 => 2,
);
$this->meta = ($faces[$player->entity->getDirection()] & 0x03) | ((~$this->meta) & 0x04);
$this->level->setBlock($this, $this);
return true;
}
}

View File

@ -0,0 +1,27 @@
<?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/
*
*
*/
class GlassPaneBlock extends TransparentBlock{
public function __construct(){
parent::__construct(GLASS_PANE, 0, "Glass Pane");
}
}

View File

@ -0,0 +1,70 @@
<?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/
*
*
*/
class IronDoorBlock extends DoorBlock{
public function __construct($meta = 0){
parent::__construct(IRON_DOOR_BLOCK, $meta, "Iron Door Block");
//$this->isActivable = true;
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->getID() === AIR){ //Replace wit common break method
$this->level->setBlock($this, new AirBlock(), false);
if($this->getSide(1) instanceof DoorBlock){
$this->level->setBlock($this->getSide(1), new AirBlock(), false);
}
return BLOCK_UPDATE_NORMAL;
}
}
return false;
}
public function getBreakTime(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0x01){
return 0.20;
}
switch($item->isPickaxe()){
case 5:
return 0.95;
case 4:
return 1.25;
case 3:
return 1.9;
case 2:
return 0.65;
case 1:
return 3.75;
default:
return 25;
}
}
public function getDrops(Item $item, Player $player){
if($item->isPickaxe() >= 1){
return array(
array(IRON_DOOR, 0, 1),
);
}else{
return array();
}
}
}

View File

@ -0,0 +1,108 @@
<?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/
*
*
*/
class SlabBlock extends TransparentBlock{
public function __construct($meta = 0){
parent::__construct(SLAB, $meta, "Slab");
$names = array(
0 => "Stone",
1 => "Sandstone",
2 => "Wooden",
3 => "Cobblestone",
4 => "Brick",
5 => "Stone Brick",
//6 => "Nether Brick",
6 => "Quartz",
);
$this->name = (($this->meta & 0x08) === 0x08 ? "Upper ":"") . $names[$this->meta & 0x07] . " Slab";
if(($this->meta & 0x08) === 0x08){
$this->isFullBlock = true;
}else{
$this->isFullBlock = false;
}
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
$this->meta &= 0x07;
if($face === 0){
if($target->getID() === SLAB and ($target->getMetadata() & 0x08) === 0x08 and ($target->getMetadata() & 0x07) === ($this->meta & 0x07)){
$this->level->setBlock($target, BlockAPI::get(DOUBLE_SLAB, $this->meta));
return true;
}else{
$this->meta |= 0x08;
}
}elseif($face === 1){
if($target->getID() === SLAB and ($target->getMetadata() & 0x08) === 0 and ($target->getMetadata() & 0x07) === ($this->meta & 0x07)){
$this->level->setBlock($target, BlockAPI::get(DOUBLE_SLAB, $this->meta));
return true;
}
}elseif(!$player->entity->inBlock($block)){
if($block->getID() === SLAB){
if(($block->getMetadata() & 0x07) === ($this->meta & 0x07)){
$this->level->setBlock($block, BlockAPI::get(DOUBLE_SLAB, $this->meta));
return true;
}
return false;
}else{
if($fy > 0.5){
$this->meta |= 0x08;
}
}
}else{
return false;
}
if($block->getID() === SLAB and ($target->getMetadata() & 0x07) !== ($this->meta & 0x07)){
return false;
}
$this->level->setBlock($block, $this);
return true;
}
public function getBreakTime(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0x01){
return 0.20;
}
switch($item->isPickaxe()){
case 5:
return 0.4;
case 4:
return 0.5;
case 3:
return 0.75;
case 2:
return 0.25;
case 1:
return 1.5;
default:
return 10;
}
}
public function getDrops(Item $item, Player $player){
if($item->isPickaxe() >= 1){
return array(
array($this->id, $this->meta & 0x07, 1),
);
}else{
return array();
}
}
}

View File

@ -0,0 +1,47 @@
<?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/
*
*
*/
class SnowLayerBlock extends FlowableBlock{
public function __construct($meta = 0){
parent::__construct(SNOW_LAYER, $meta, "Snow Layer");
$this->isReplaceable = true;
$this->isSolid = false;
$this->isFullBlock = false;
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->getID() === AIR){ //Replace wit common break method
$this->level->setBlock($this, new AirBlock(), false);
return BLOCK_UPDATE_NORMAL;
}
}
return false;
}
public function getDrops(Item $item, Player $player){
if($item->isShovel() !== false){
return array(
array(SNOWBALL, 0, 1),
);
}
}
}

View File

@ -0,0 +1,33 @@
<?php
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
class WoodDoorBlock extends DoorBlock{
public function __construct($meta = 0){
parent::__construct(WOOD_DOOR_BLOCK, $meta, "Wood Door Block");
$this->isActivable = true;
}
public function getDrops(Item $item, Player $player){
return array(
array(WOODEN_DOOR, 0, 1),
);
}
}

View File

@ -0,0 +1,27 @@
<?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/
*
*
*/
class BrickStairsBlock extends StairBlock{
public function __construct($meta = 0){
parent::__construct(BRICK_STAIRS, $meta, "Brick Stairs");
}
}

View File

@ -0,0 +1,27 @@
<?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/
*
*
*/
class CobblestoneStairsBlock extends StairBlock{
public function __construct($meta = 0){
parent::__construct(COBBLESTONE_STAIRS, $meta, "Cobblestone Stairs");
}
}

View File

@ -0,0 +1,27 @@
<?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/
*
*
*/
class NetherBricksStairsBlock extends StairBlock{
public function __construct($meta = 0){
parent::__construct(NETHER_BRICKS_STAIRS, $meta, "Nether Bricks Stairs");
}
}

View File

@ -0,0 +1,27 @@
<?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/
*
*
*/
class QuartzStairsBlock extends StairBlock{
public function __construct($meta = 0){
parent::__construct(QUARTZ_STAIRS, $meta, "Quartz Stairs");
}
}

View File

@ -0,0 +1,27 @@
<?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/
*
*
*/
class SandstoneStairsBlock extends StairBlock{
public function __construct($meta = 0){
parent::__construct(SANDSTONE_STAIRS, $meta, "Sandstone Stairs");
}
}

View File

@ -0,0 +1,27 @@
<?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/
*
*
*/
class StoneBrickStairsBlock extends StairBlock{
public function __construct($meta = 0){
parent::__construct(STONE_BRICK_STAIRS, $meta, "Stone Brick Stairs");
}
}

View File

@ -0,0 +1,27 @@
<?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/
*
*
*/
class WoodStairsBlock extends StairBlock{
public function __construct($meta = 0){
parent::__construct(WOOD_STAIRS, $meta, "Wood Stairs");
}
}

View File

@ -0,0 +1,57 @@
<?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/
*
*
*/
class CoalOreBlock extends SolidBlock{
public function __construct(){
parent::__construct(COAL_ORE, 0, "Coal Ore");
}
public function getBreakTime(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0x01){
return 0.20;
}
switch($item->isPickaxe()){
case 5:
return 0.6;
case 4:
return 0.75;
case 3:
return 1.15;
case 2:
return 0.4;
case 1:
return 2.25;
default:
return 15;
}
}
public function getDrops(Item $item, Player $player){
if($item->isPickaxe() >= 1){
return array(
array(COAL, 0, 1),
);
}else{
return array();
}
}
}

View File

@ -0,0 +1,50 @@
<?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/
*
*
*/
class DiamondOreBlock extends SolidBlock{
public function __construct(){
parent::__construct(DIAMOND_ORE, 0, "Diamond Ore");
}
public function getBreakTime(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0x01){
return 0.20;
}
switch($item->isPickaxe()){
case 5:
return 0.6;
case 4:
return 0.75;
default:
return 15;
}
}
public function getDrops(Item $item, Player $player){
if($item->isPickaxe() >= 4){
return array(
array(DIAMOND, 0, 1),
);
}else{
return array();
}
}
}

View File

@ -0,0 +1,62 @@
<?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/
*
*
*/
class GlowingRedstoneOreBlock extends SolidBlock{
public function __construct(){
parent::__construct(GLOWING_REDSTONE_ORE, 0, "Glowing Redstone Ore");
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_SCHEDULED or $type === BLOCK_UPDATE_RANDOM){
$this->level->setBlock($this, BlockAPI::get(REDSTONE_ORE, $this->meta), false);
return BLOCK_UPDATE_WEAK;
}else{
$this->level->scheduleBlockUpdate(new Position($this, 0, 0, $this->level), Utils::getRandomUpdateTicks(), BLOCK_UPDATE_RANDOM);
}
return false;
}
public function getBreakTime(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0x01){
return 0.20;
}
switch($item->isPickaxe()){
case 5:
return 0.6;
case 4:
return 0.75;
default:
return 15;
}
}
public function getDrops(Item $item, Player $player){
if($item->isPickaxe() >= 4){
return array(
//array(331, 4, mt_rand(4, 5)),
);
}else{
return array();
}
}
}

View File

@ -0,0 +1,50 @@
<?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/
*
*
*/
class GoldOreBlock extends SolidBlock{
public function __construct(){
parent::__construct(GOLD_ORE, 0, "Gold Ore");
}
public function getBreakTime(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0x01){
return 0.20;
}
switch($item->isPickaxe()){
case 5:
return 0.6;
case 4:
return 0.75;
default:
return 15;
}
}
public function getDrops(Item $item, Player $player){
if($item->isPickaxe() >= 4){
return array(
array(GOLD_ORE, 0, 1),
);
}else{
return array();
}
}
}

View File

@ -0,0 +1,52 @@
<?php
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
class IronOreBlock extends SolidBlock{
public function __construct(){
parent::__construct(IRON_ORE, 0, "Iron Ore");
}
public function getBreakTime(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0x01){
return 0.20;
}
switch($item->isPickaxe()){
case 5:
return 0.6;
case 4:
return 0.75;
case 3:
return 1.15;
default:
return 15;
}
}
public function getDrops(Item $item, Player $player){
if($item->isPickaxe() >= 3){
return array(
array(IRON_ORE, 0, 1),
);
}else{
return array();
}
}
}

Some files were not shown because too many files have changed in this diff Show More