Compare commits

..

1152 Commits

Author SHA1 Message Date
6a7b03e1bf Updated PHP and cURL 2014-01-13 04:35:36 +01:00
8c648fc6f7 PocketMine-MP Alpha_1.3.11 「甘いビートルート」 Added CODENAME 2014-01-13 04:16:38 +01:00
6c5356fc80 Merge branch 'master' of github.com:PocketMine/PocketMine-MP 2014-01-13 03:35:56 +01:00
70445bdeba Added timeout to Utils::getOnline(), fixes #1071 [gh#1071] 2014-01-13 03:34:40 +01:00
65767312a3 Merge pull request #1064 from wrewolf/patch-2
Update Lava.php
2014-01-12 18:28:54 -08:00
2551bd64ca Merge pull request #1063 from wrewolf/patch-1
Update Water.php
2014-01-12 18:28:43 -08:00
1f360c8bfb Update Lava.php 2014-01-12 12:05:17 +03:00
65a7560185 Update Lava.php
Fix Remove for Left Lavas
2014-01-10 09:45:21 +03:00
860f723518 Update Water.php
Fix Remove for Left Waters
2014-01-10 09:43:31 +03:00
969f0f05b0 Fix #1037 2014-01-04 11:59:07 +09:00
1ce7366cc3 Merge pull request #1025 from InusualZ/patch-1
Level::getAll()
2014-01-03 18:52:44 -08:00
3ed2155c5b Merge pull request #1030 from wallace/patch-1
Update compile.sh
2013-12-27 20:44:43 -08:00
1cc12616e8 Update compile.sh
Properly escape nested double quotes.
2013-12-25 21:46:04 -05:00
e3d3f91c54 Level::getAll() 2013-12-23 20:15:53 -05:00
039edead18 Merge remote-tracking branch 'origin/master' 2013-12-19 18:42:58 +10:30
a141ea5018 Config Object PHPDoc 2013-12-19 18:42:45 +10:30
b63e49acf8 Fixed slot AIR offset 2013-12-18 18:01:06 +01:00
5dc52ad97d Add PHPDoc Documentation to block types. 2013-12-18 20:05:04 +10:30
5eed43ddd0 Added Level::startTime() and Level::stopTime() 2013-12-18 09:45:00 +01:00
9137a36b55 MCPE 0.8.1 version change 2013-12-18 09:44:42 +01:00
5623fa3601 Even more grammar! 2013-12-17 15:45:56 -06:00
78d72201ce (ノಠ益ಠ)ノ彡┻━┻ 2013-12-17 22:30:45 +01:00
d4057a2113 Fixed #997 carrots converting to potatoes [gh#997] 2013-12-17 10:34:24 +01:00
1eab1e382a Merge pull request #1007 from InusualZ/fix
Fixed Event "entity.explosion"
2013-12-16 18:40:04 -08:00
351ac0d7af Fixed Event "entity.explosion"
The event don't listen to the handler
2013-12-16 19:42:35 -05:00
b457e63d20 Reverted Item despawn timer 2013-12-16 17:12:25 +01:00
7bc9500484 Increased error level 2013-12-16 13:06:33 +01:00
6d4472a339 Added Source SHA1 sum 2013-12-16 13:06:31 +01:00
050d3424f0 Fix #999. 2013-12-14 16:14:41 +10:30
01e9ca7852 Fix #971. Add lowercase checking of Config. 2013-12-14 16:06:28 +10:30
e2298d861c Fix #996 2013-12-14 15:27:38 +10:30
a8f2225c4c PHP 5.5.7 2013-12-13 13:10:19 +01:00
1a7e916928 Fixed player heads not being rotated 2013-12-13 01:17:55 +01:00
2b0fdd5062 Time syncronized again 2013-12-13 00:52:55 +01:00
af8b380d10 Added Cobweb to Creative Inventory 2013-12-13 00:34:37 +01:00
90e598bb2c Added minecart item (not placeable) 2013-12-13 00:33:07 +01:00
4d0eb5e529 Fixed #988 2013-12-09 21:55:49 +01:00
02dc06c58b Fixed plugin path 2013-12-09 21:50:58 +01:00
c23fc0057a PHP plugins are now included using include() 2013-12-08 17:17:47 +01:00
1693f5655e Updeted to protocol 14 MCPE v0.8.0 build 8 2013-12-08 13:25:21 +01:00
565fe70c7e v0.8.0 alpha version 2013-12-07 13:50:14 +01:00
7cf662fb81 Only show private messages in console when the sender or the target is the console 2013-12-07 12:44:23 +01:00
894325aef6 ¬¬ 2013-12-06 01:50:48 +01:00
423ead6b64 Added item pickup animation 2013-12-06 01:49:47 +01:00
a0a7042d43 Look! New PluginAPI! 2013-12-06 01:24:41 +01:00
14e1dda327 Removed KiwiIRC chat, use official freenode webirc 2013-12-04 18:19:39 +01:00
3cffa66490 added Entity::setHealth() force 2013-12-03 22:25:25 +01:00
2b28e26392 Fixed map chunks bug 2013-12-03 20:39:28 +01:00
8543c06db4 Merge pull request #975 from wiezz/master
Allow chat plugins to work with eachother
2013-12-03 10:04:43 -08:00
adcf95f486 Fix
Send the normal message when $data["message"] is removed by a plugin.
2013-12-03 18:33:37 +01:00
736c233e76 Allow chat plugins to work with eachother 2013-12-03 18:26:38 +01:00
fd2eb7b230 OOPS! 2013-12-03 02:10:43 +01:00
bad8365e28 Fixed zero-length packets spamming the console 2013-12-03 02:07:33 +01:00
e9e59c33cc Fixed 969 2013-12-02 17:45:01 +01:00
8532f53f8e Schedule player kick so it can read the reason 2013-12-02 01:00:11 +01:00
230a3c00fc Removed LevelAPI::isLoaded()
Not needed, everything can be obtained with current methods
2013-12-01 22:01:04 +01:00
d515da8963 Fixed Level::setMiniChunk() parameter bug 2013-12-01 21:37:33 +01:00
f5d69e6905 Fixed Level::getMiniChunk() parameter bug 2013-12-01 21:32:35 +01:00
bcf6571cc2 Delete PermissionsAPI. 2013-12-01 23:52:31 +10:30
7d0ff5e073 Formatting OCD
Please refer to CONTRIBUTING.md
2013-12-01 14:16:38 +01:00
5e2de356bf Modified update system to check the Github API 2013-12-01 14:14:37 +01:00
2d67af6fbd Sugarcane now grows when using bonemeal 2013-12-01 14:14:36 +01:00
bd8110edab MCPE v0.8.0 alpha build 5 2013-12-01 14:14:35 +01:00
25cd58bd99 Merge remote-tracking branch 'origin/master' 2013-11-30 13:10:27 +10:30
a6cd8ece1b Added isLoaded function to LevelAPI. Fixes #959. 2013-11-30 13:10:02 +10:30
0bac7418db Updated StackableArray 2013-11-29 00:18:38 +01:00
a4e38689db Added REDSTONE constant 2013-11-27 23:19:48 +01:00
f3f61e7a4a Cobblestone Walls height handling 2013-11-27 17:41:39 +01:00
bc48e70d6c Remove fire effects on Creative mode 2013-11-27 17:24:33 +01:00
b21ee37c07 MCPE v0.8.0 alpha build 4 2013-11-27 17:22:41 +01:00
2f7e5688e2 Fixed #418 Placing blocks on top of Snow replaces it now 2013-11-27 15:28:10 +01:00
0d6ae6067c Fixed #956 BEETROOT_BLOCK typo 2013-11-27 12:10:26 +01:00
3337e5980e Added ZIP to compile script 2013-11-27 00:18:13 +01:00
493b7532df Removed debug code 2013-11-26 17:28:48 +01:00
bd0d708274 Fixed Packet of Death 2013-11-26 17:23:45 +01:00
5ad72b4f49 Return a bowl when eating stew or soup 2013-11-26 15:29:34 +01:00
7b9edffa47 Mushroom Stew and Beetroot Soup are no longer stackable 2013-11-26 15:23:39 +01:00
6e9b70c9cb Better Tall Grass generation with bonemeal 2013-11-26 13:32:19 +01:00
0f01570d01 "Better" Tall Grass drops 2013-11-26 13:20:19 +01:00
cf5bc916c0 Reordered Creative inventory 2013-11-26 13:15:56 +01:00
35119befd9 Tall Grass now drops Melon and Pumpkin seeds with a probability of 1/15 2013-11-26 12:46:30 +01:00
02150da862 Tall Grass can now drop Carrots, potatoes, beetroot seeds 2013-11-26 12:45:27 +01:00
2044269d86 Added Shears, bedrock and Dyes to creative inventory 2013-11-26 12:42:09 +01:00
2d3ba111e0 Rewrote Generic Explosion drop 2013-11-26 12:28:05 +01:00
98097b0703 Check for $newPermissions is_array 2013-11-26 21:38:48 +10:30
c4ba06b58c Add Restriction Interface 2013-11-26 21:32:08 +10:30
3e12a41a91 permissions.request function use instead of additional argument for player variable. 2013-11-26 21:20:44 +10:30
daaa9394c4 PermissionsAPI Basic Structure Complete. Now uses restrictions. Player dedicated emitEvent functions. Use more anonymous functions. 2013-11-26 21:17:44 +10:30
71a1986980 Add EventRestriction 2013-11-26 20:00:15 +10:30
3352c36ba4 Merge branch 'master' of https://github.com/PocketMine/PocketMine-MP 2013-11-26 15:15:30 +10:30
d2fa06cb64 More comments. 2013-11-26 15:15:24 +10:30
0e9458fafc Merge pull request #950 from InusualZ/test
Fixed #332. Temporary Silk Touch fix. Replace this system with class-based silk touch variable.
2013-11-25 20:32:58 -08:00
75e4174a2b Repaired 2013-11-25 19:31:40 -05:00
509e67bfb7 No More Silk Touch On Explosion 2013-11-25 19:28:59 -05:00
0d25118eef Fixed gh#332
Crafting with buckets (milk) returns the bucket
2013-11-25 18:53:36 -05:00
c798a33363 Fixed gh#332
Crafting with buckets (milk) returns the bucket
2013-11-25 18:53:02 -05:00
5fc192b730 Fixed gh#332
Crafting with buckets (milk) returns the bucket
2013-11-25 18:27:34 -05:00
286b30cf4e Giant typo 2013-11-25 18:36:03 +01:00
a0fac71385 Added coding standards by request of @sekjun9878. Fixed #949 [gh#949] 2013-11-25 18:34:06 +01:00
273a74d566 Added Beetroot Soup food value 2013-11-25 18:01:19 +01:00
aefcab9a49 Really minor changes. 2013-11-25 22:37:30 +10:30
f5989d461c Fix possible variable bug with /tell. 2013-11-25 22:06:25 +10:30
68076fedc8 Some PHPDoc comment updates. 2013-11-25 22:05:07 +10:30
2339525478 Merge remote-tracking branch 'origin/master' 2013-11-25 20:34:57 +10:30
62f5f0d325 Add PHPDoc information to sub-APIs. 2013-11-25 20:34:48 +10:30
0ac81968b7 OCD 2013-11-25 11:02:33 +01:00
b8763a7a3f Add PHPDoc information for API parsing. 2013-11-25 20:28:19 +10:30
249e83db91 Merge branch 'master' of https://github.com/PocketMine/PocketMine-MP 2013-11-25 20:11:57 +10:30
e6f855abbd Add Default permission, and remove construct restriction in Permission interface. Note that all changes on permission API are untested therefore not enabled by default. 2013-11-25 20:11:38 +10:30
75e1a6e97e Added bowl crafting 2013-11-25 09:52:28 +01:00
fb9f7891c7 Added Beetroot soup, beetroot seeds, crafting 2013-11-25 09:42:41 +01:00
03e71ee3ff Added comment in Player.php 2013-11-25 09:35:54 +01:00
9cf91ca3fa Added beetroot IDs
TODO: Beetroot Soup ID
2013-11-25 09:34:57 +01:00
fc7c14ae16 BeetRoot soup doesn't need a class 2013-11-25 09:34:36 +01:00
5ac0907aeb Added $permissions property to Player so pthreads doesn't crash 2013-11-25 09:31:02 +01:00
2f3817322b Formatting OCD 2013-11-25 09:28:41 +01:00
624219f680 Merge remote-tracking branch 'origin/master' 2013-11-25 18:57:33 +10:30
646390812a Beetroot Soup Item template. @shoghicp Add in the Item ID to ItemID.php constants file. 2013-11-25 18:57:13 +10:30
7190d444e3 Revert "Remove Achievement API. Alters game play mechanics."
This reverts commit 2621aab2ef.
2013-11-25 09:26:12 +01:00
bfe0d04663 More notes in Contributions.md 2013-11-25 09:25:48 +01:00
44d63c74dd Update some comments on the recipes. 2013-11-25 18:50:01 +10:30
d7d5e66de6 Use interfaces and closures and abstracts and anonymous functions and all the fancy OOP PHP stuff. 2013-11-25 18:33:12 +10:30
eb7d8a3240 Minor Adjustments 2013-11-25 18:05:21 +10:30
698feccd54 Minor Adjustments. 2013-11-25 18:04:47 +10:30
d3e8cba132 Basic PermissionsAPI template for others to improve. 2013-11-25 18:02:31 +10:30
2621aab2ef Remove Achievement API. Alters game play mechanics. 2013-11-25 17:39:19 +10:30
6ab29f993d OCD 2013-11-24 23:29:17 +01:00
d11cf83a47 Added note about pull requests 2013-11-24 23:26:12 +01:00
336a40ae90 Merge pull request #947 from 99leonchang/master
Multiple orders for /gamemode
2013-11-24 14:20:04 -08:00
a8055eb59a Warn about not using the bin/ PHP binary 2013-11-24 20:09:04 +01:00
2b920033ff Drop boots on death 2013-11-24 19:23:56 +01:00
8665035381 Added Cocoa Beans crafting 2013-11-24 19:01:24 +01:00
e0021b8927 Fixed first hotbar item in Creative 2013-11-24 18:43:14 +01:00
44a9639150 Fixed POTATOE constant 2013-11-24 18:41:57 +01:00
e700179bb0 Multiple changes
* Fixed hoe durability
* Fixed some blocks hitbox
* Added Creative pseudo-inventory
* Added Carrots and Carrot Crops
* Added Potatoes, Baked potatoes and Potato Crops
2013-11-24 18:38:37 +01:00
f8d8052ec3 Correct placement for cakes and snow layers 2013-11-24 15:52:35 +01:00
0dc783f285 Added carpets, crafting recipes, placement 2013-11-24 15:50:02 +01:00
7cd5c5cde1 Fixed paintings resetting the hotbar 2013-11-24 15:18:58 +01:00
3968f3b298 Jungle Tree generation placeholder 2013-11-24 15:12:31 +01:00
9105e59f2a Jungle Sapling 2013-11-24 15:12:14 +01:00
5ac92ee0db Formatting 2013-11-24 20:48:03 +08:00
b5a53c04ac Merge pull request #5 from PocketMine/master
Fixed Wheat recipes
2013-11-24 04:40:15 -08:00
a93798719f Fixed Wheat recipes 2013-11-24 13:38:53 +01:00
1eda0d72a8 Different orders for /gamemode 2013-11-24 20:38:40 +08:00
1331c8aeb2 Merge pull request #4 from PocketMine/master
Update
2013-11-24 04:36:13 -08:00
b9e2576208 f 2013-11-24 20:34:58 +08:00
c25607588b Added sideway Hay Bales 2013-11-24 13:32:21 +01:00
ff8363e2ae Added Wooden Slabs, Double Wooden Slabs, new Wooden Slab crafting 2013-11-24 13:22:09 +01:00
64f7a78329 Added achievement.grant and achievement.broadcast handlers for more customization 2013-11-24 12:18:50 +01:00
f377eacc0f Merge pull request #3 from PocketMine/master
Update
2013-11-24 03:11:57 -08:00
8e452831e1 Fixed undefined $orderingChannel 2013-11-24 12:04:40 +01:00
2483614459 Merge pull request #944 from lloydw/master
Fix argument parsing
2013-11-24 02:52:17 -08:00
53fd9cb466 Merge pull request #945 from 99leonchang/master
AchievmentAPI logic change
2013-11-24 02:51:11 -08:00
1c5b473b36 Added player.craft handler 2013-11-24 11:45:18 +01:00
918fb62ce9 Logic changes 2013-11-24 12:42:31 +08:00
1350e1bc4e Merge pull request #2 from PocketMine/master
Update
2013-11-23 20:33:33 -08:00
5d53c259cf Fix argument parsing 2013-11-24 16:27:09 +13:00
5a71043ab0 Fix 2013-11-24 01:52:23 +01:00
6ff6a5fc91 More achievements 2013-11-24 01:10:05 +01:00
6de602a174 Fixed Coal Block ID 2013-11-24 00:52:21 +01:00
3ff4b9eae0 Achievements API 2013-11-24 00:51:04 +01:00
ae8c934b5f Allow accessing Config data keys directly 2013-11-23 19:14:45 +01:00
5803a4e649 Added Coal Blocks, crafting, fuel information 2013-11-23 18:18:02 +01:00
78f7964d57 Fixed bread crafting & added Hay Bales 2013-11-23 18:09:04 +01:00
78f9e40730 Added Compass and Clock 2013-11-23 17:54:19 +01:00
a0ca572d1f Added Cobblestone Walls, Mossy Stone Walls, crafting recipes, correct drops 2013-11-23 17:40:22 +01:00
af66e5a444 iron bars crafting 2013-11-23 17:23:03 +01:00
1ad00a453b Added Iron bars, Pumpkins, lit pumpkins and pumpkin grow, pumpkin growth, pumpkin seeds, pumpkin pie... 2013-11-23 16:36:30 +01:00
5fa6c5962e Added more Wood stairs, and planks 2013-11-23 15:51:09 +01:00
de98dd920b Sponges added 2013-11-23 15:34:32 +01:00
1a0bccf288 Sideway logs placement & correct drop 2013-11-23 15:21:48 +01:00
e4221b8552 Redstone Ore drops Redstone dust 2013-11-23 13:56:47 +01:00
ba7c9503d8 0.8.0 partial compatibility
* Not compatible with Creative mode
2013-11-23 13:52:13 +01:00
3d53b9eb3a Armor drop - tested 2013-11-23 11:06:01 +01:00
f32f379e97 Lava flow code reformatting 2013-11-23 11:04:36 +01:00
809ca802b3 PocketMine-MP Alpha_1.3.10 Stable Release 2013-11-23 11:00:22 +01:00
719df75886 Water flow code reformatting 2013-11-23 10:59:52 +01:00
14a40ac11e Remove keycodes from console input 2013-11-23 10:46:24 +01:00
c973abc36f Added --disable-ansi to disable console colors #887 2013-11-23 10:22:24 +01:00
54d37a432e Check that ServerAPI::request() works, fixes #916 [gh#916] 2013-11-23 10:17:38 +01:00
c7168a6c64 Fixed #926 [gh#926] 2013-11-23 10:11:25 +01:00
079d24055d Updated compile script
* PHP 5.5.6
* pthreads 0.0.45 (stable!)
* cURL 7.33.0
2013-11-22 23:42:48 +01:00
b1748b5393 Removed language include 2013-11-22 15:28:28 +01:00
dafb12c3d3 Merge pull request #1 from PocketMine/master
Merge pull request #930 from beN39sGroup/master
2013-11-22 05:58:19 -08:00
b66f34b308 Merge pull request #930 from beN39sGroup/master 2013-11-22 23:59:50 +10:30
1cb711d32d Temporaily fix multilanguage bug. Waiting on pull request author to remove multi language. 2013-11-22 22:56:02 +10:30
94a9b7b431 Merge pull request #925 from beN39sGroup/master
Liquid Performance
2013-11-22 03:12:16 -08:00
7acdb0dd3f Fix Performance Problem
Welcome, TPS!
2013-11-17 09:39:40 +09:00
fe70fa467d Slower Unflow & Basic for Multi Language
Slower Unflow!
I wanna Multi Language!
2013-11-15 19:14:02 +09:00
d4a5e4e5c4 Merge pull request #920 from beN39sGroup/master
Liquid Flowing. This requires further testing before stable release.
2013-11-12 21:48:02 -08:00
db289f9871 Mixable Lava & Water
I Wanna Make Cobblestone Generator!
2013-11-10 22:11:45 +09:00
b822b314cb Simple Flowable Lava & English Comment
Still A Flowing
2013-11-10 17:59:36 +09:00
77ca6da14c Simple Flowable Water!
Meet the 'Flowing' Water.
2013-11-10 17:19:50 +09:00
9373c93737 Prefix for Kick Flying when Player on Fence 2013-11-10 13:52:41 +09:00
cb47bf82c9 Reset player's armors after death UNTESTED. Fixes #896. 2013-11-09 20:44:09 +10:30
3498c876df Reset player's armors after death 2013-11-09 20:43:06 +10:30
df01e92ab6 Merge pull request #886 from JWhy/patch-1
Extract plugins/ path lookup to pluginsPath() function in PluginAPI
2013-11-09 01:34:54 -08:00
1f1f955eef Add plugin name info to Evaluation Error. 2013-11-09 20:00:24 +10:30
0e471ab38c Fixed leftover reference in pluginsPath() function 2013-10-22 14:53:12 +02:00
9f211bd7fb Extract plugins/ path lookup to pluginsPath() function in PluginAPI 2013-10-22 14:05:11 +02:00
af486917a1 Fixed #884 2013-10-22 21:26:30 +10:30
c197a58a3a Merge pull request #881 from JWhy/patch-1
Use DIRECTORY_SEPERATOR constant for safer cross-platform file access
2013-10-21 04:22:23 -07:00
ca0d682d87 Use DIRECTORY_SEPERATOR constant for safer cross-platform file access 2013-10-21 12:27:48 +02:00
70ec644658 Merge pull request #880 from JWhy/patch-1
Support other local date format for timezone detection to avoid startup errors
2013-10-20 21:55:48 -07:00
a860f16f4a Support other local date format for timezone detection to avoid startup errors
fixes PocketMine/PocketMine-MP#718
2013-10-21 06:12:27 +02:00
9ac72026b9 Fix #831 2013-10-19 11:47:53 +10:30
0ad0071107 Fix crash bug when @all is used in console. 2013-10-19 11:28:43 +10:30
386b2cb0ef Fix 805 2013-10-19 11:20:33 +10:30
58fce0e939 Fix /me @all critical server crash bug. Fix #840. Disabled usage of @all for non-ops. 2013-10-19 11:12:54 +10:30
780f60554d Fix #871 2013-10-19 10:58:49 +10:30
4aa0ae86fb Update config.php 2013-10-18 18:04:45 +10:30
f005b82a70 Fixed typo. Not Longer -> No Longer 2013-10-09 13:09:35 +10:30
c35c004827 Added the ability to shoot arrows
Credit to ljyloo (http://forums.pocketmine.net/index.php?threads/shooting-arrows-in-pm-server.508/#post-4338).
2013-10-08 16:52:37 -05:00
e179de1613 Better :3 2013-10-02 16:57:37 +02:00
3354df0360 More KiwiIRC Buttons 2013-10-03 00:25:38 +09:30
d8cfc06d3a KiwiIRC! 2013-10-03 00:24:48 +09:30
3b0e553e17 Merge pull request #812 from Humerus/patch-2
Made it so deop doesn't op the player.
2013-09-15 13:18:26 -07:00
c53ea830ea Made it so deop doesn't op the player. 2013-09-15 12:00:00 -04:00
0c1afe15fd Added .idea to .gitignore 2013-09-11 11:13:09 +02:00
6a24700f6e Fix compiler again 2013-09-10 22:52:24 +02:00
000dfc8601 Fix 64 bit builds 2013-09-10 22:49:33 +02:00
a011ad8fb6 Reverted DIAMOND_HOE to IRON_HOE 2013-09-10 20:11:31 +02:00
d41c30945b Level optimizations 2013-09-09 10:44:50 +02:00
b3c51c6d2e Faster level generator 2013-09-09 03:32:24 +02:00
4ccaccc126 Fixed Player::setSpawn() 2013-09-08 15:37:28 +02:00
8aef462a68 Fixed #784 Slabs replacing other slabs 2013-09-08 10:45:36 +02:00
c4a5a9c849 Better explosion damage calculation 2013-09-08 01:35:48 +02:00
275e27f7a9 Low level PMF level interface 2013-09-08 01:21:40 +02:00
1abe7626bf Using Vectors for explosions 2013-09-08 00:27:35 +02:00
7c9255e21e Incremented speedMeasure() size 2013-09-07 21:27:05 +02:00
0c6eaa0609 Fixed entity motion condition 2013-09-07 21:19:47 +02:00
1bc3b66afd Player check is done with equal name, not alike 2013-09-07 14:24:17 +02:00
df174d1b8e Tuned power again xD 2013-09-07 13:35:32 +02:00
f56dd60708 Correct item drop related to explosion power 2013-09-07 12:37:04 +02:00
2271d0b6fc Lowered TNT explosion force from 4 to 3 2013-09-07 12:28:18 +02:00
6d2eea8887 Level::getSafeSpawn() on player normal spawn 2013-09-07 12:05:04 +02:00
fb2bcdb722 Level::getSafeSpawn() look for solid block 2013-09-07 12:04:49 +02:00
c8dd85de75 Better fuse calculation 2013-09-07 11:55:14 +02:00
a00375b1a9 Perfect explosions 2013-09-07 11:40:22 +02:00
e7e05d37b3 Moved -mx32 flag 2013-09-07 10:30:08 +02:00
6ac54925ff Added -mx32 flag 2013-09-07 10:26:22 +02:00
555da94612 Moved patch location :P 2013-09-07 10:21:42 +02:00
774debb299 Fixed #781 2013-09-07 10:18:06 +02:00
9b63a0b0bf Fixed colors on MacOS 2013-09-07 10:13:14 +02:00
397b47d719 Added secondary explosions 2013-09-07 02:51:15 +02:00
5952e34995 PrimedTNT Entity implemented 2013-09-07 02:46:18 +02:00
0ddc48ca80 Vanilla-alike Explosions 2013-09-07 01:28:15 +02:00
24211764ce Tuned TNT force 2013-09-06 22:17:13 +02:00
4a2e3d3611 Fixed Flint & Steel order 2013-09-06 19:33:16 +02:00
e5841e623e Fixed comparison order with flint & steel metadata 2013-09-06 17:50:01 +02:00
215141d552 Added Diamond Hoe, Flint & Steel and Diamond Sword to the Creative inventory 2013-09-06 17:40:07 +02:00
94f8cfb59b Added Single Explosions [ignite TNT using fling & steel] 2013-09-06 13:46:52 +02:00
41b1a0f991 Fixed bottom bed offset 2013-09-05 22:58:49 +02:00
08d93fa021 Fixed #774 [gh#774] 2013-09-05 19:58:31 +02:00
ce65801d14 Keep window open 2013-09-05 17:17:54 +02:00
bb9923d210 Fixed position offset when sleeping on beds 2013-09-05 15:19:27 +02:00
ccac35d5a2 Fixed player catching fire after death 2013-09-05 00:39:06 +02:00
c11ee468a2 Added Door sounds 2013-09-05 00:37:07 +02:00
e48126a0c9 Fixed possible cases on infinite loop on addItem and removeItem 2013-09-04 21:29:21 +02:00
b56ee69f0d Alpha_1.3.10dev 2013-09-04 21:27:13 +02:00
4a46d8fd9c Fixed possible infinite loop in hasSpace 2013-09-04 21:26:22 +02:00
f29181a8ee Removed check on start.cmd 2013-09-04 20:49:25 +02:00
8515e7ff33 Fixed speed limiter 2013-09-04 20:49:14 +02:00
9db1b741a7 Another Typo ¬¬ 2013-09-04 20:34:48 +02:00
401c201a97 Fix start.cmd ¬¬ 2013-09-04 20:27:49 +02:00
fc3fb651b2 Fix fix fix 2013-09-04 20:25:36 +02:00
b4bfceeb6d Added README credits :) 2013-09-04 20:03:59 +02:00
a965103a03 Windows installer fix 2013-09-04 19:59:12 +02:00
f569587764 Alpha_1.3.9 2013-09-04 19:53:42 +02:00
1a9641e93a Dynamic title fix 2013-09-04 19:52:37 +02:00
b297ba16ed New starting scripts for mintty 2013-09-04 19:49:32 +02:00
809076b7d7 Added new text formatting system for future updates [like vanilla PC] 2013-09-04 19:49:19 +02:00
56d829eec6 Fixed #767 Players move laggy [gh#767] 2013-09-04 19:33:11 +02:00
7f15b27ff0 Fixed server crash when two players sleep together 2013-09-04 17:13:03 +02:00
28afadce0a Max chunk rate: 172kB/s => 256kB/s 2013-09-04 13:37:52 +02:00
ae92c968b4 PocketMine-MP Alpha_1.3.8 stable 2013-09-04 13:34:08 +02:00
2a2f2d8043 Changed newest MCPE version to 0.7.5 2013-09-04 13:33:50 +02:00
c9a7067e3f Added date on server logs 2013-09-04 13:32:36 +02:00
160aa3a199 Improved scripts 2013-09-04 13:29:27 +02:00
2b24dab57b Modified startup messages 2013-09-04 13:29:05 +02:00
49b7f60662 Doors fall when the block below is removed 2013-09-04 13:00:04 +02:00
19112f0d06 Updated blocks direct break 2013-09-04 12:59:08 +02:00
cf8e3e41ba Fixed Ice converting to water on creative 2013-09-04 12:56:35 +02:00
aff9349d20 Fixed SignPost Tile remove on block update break 2013-09-04 12:48:35 +02:00
71dd3fe3af Send broken bed block directly [no cache] 2013-09-04 12:41:04 +02:00
bee3e7d67a Fixed players sleeping on the same bed 2013-09-04 12:36:50 +02:00
dd5b1869e2 /spawn teleports to the server spawn instead of the player spawn 2013-09-04 10:49:19 +02:00
724d336853 Fixed blocks being placed on beds during day 2013-09-04 10:30:48 +02:00
3fe3aa2a62 Added force position on teleport [Fixes #356 gh#356] 2013-09-04 01:04:51 +02:00
bb9420753d Round of teleports on spawn 2013-09-03 22:55:47 +02:00
f14999c57f Check phase on sleep 2013-09-03 22:53:53 +02:00
40a20d1467 Send correct spawn position (client-side check) 2013-09-03 22:52:17 +02:00
4d2dc63182 Schedule a teleport on chunk load 2013-09-03 22:51:02 +02:00
1677ce4b1d Adds beds 2013-09-03 22:50:47 +02:00
f7508adb29 Fixed TimeAPI bugs 2013-09-03 22:40:48 +02:00
d86c9982b3 Fixed some item stack size 2013-09-03 20:33:15 +02:00
241a66f5d8 Stonecutter recipes fix 2013-09-02 01:13:21 +02:00
dc940ffcb6 Fix for cross compiling php 2013-09-01 13:51:40 -05:00
58d8fc339e Fix for invalid CPU usage limit 2013-08-31 21:26:55 +02:00
4d4786dc0d Fixed packet index when opening a furnace 2013-08-31 19:27:22 +02:00
8c6bf01815 Alpha_1.3.8dev 2013-08-31 19:26:50 +02:00
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
267 changed files with 18928 additions and 9517 deletions

157
.gitignore vendored
View File

@ -2,130 +2,12 @@ players/*
worlds/*
plugins/*
logs/*
bin/*
.idea/*
*.log
*.pmf
*.txt
server.properties
white-list.txt
banned-ips.txt
banned.txt
ops.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
############
@ -138,38 +20,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

View File

@ -4,16 +4,11 @@ php:
- 5.4
before_script:
- pecl install channel://pecl.php.net/pthreads-0.0.42
- git clone --depth=100 --quiet --branch=tests git://github.com/shoghicp/PocketMine-MP.git $(pwd)/tests/
- pecl install channel://pecl.php.net/pthreads-0.0.44
script:
- phpunit tests/
- php src/tests/ServerSuiteTest.php
notifications:
email: false
irc:
channels:
- "irc.freenode.org#mcpedevs"
template:
- "PocketMine-MP #%{build_number} %{commit}: %{message} (%{build_url})"
webhooks: http://n.tkte.ch/h/214/wsNvmG43-ncxUVRrFPwSM-r0

73
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,73 @@
![](http://www.pocketmine.net/favicon.png)
# PocketMine-MP Contribution Guidelines
Before contributing to PocketMine-MP, please read this.
## I've a question
* For questions, please refer to the _#pocketmine_ or _#mcpedevs_ IRC channel on Freenode. There is a [WebIRC](http://webchat.freenode.net?channels=pockdetmine,mcpedevs&uio=d4) if you want.
* You can ask directly to _[@PocketMine](https://twitter.com/PocketMine)_ in Twitter, but don't expect an inmediate reply.
## 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.
* __Create a single branch for that pull request__
* If you want to be part of PocketMine-MP, we will ask you to.
* Code using the syntax as in PocketMine-MP. See below for an example.
* The code must be clear and written in English, comments included.
__Thanks for contributing to PocketMine-MP!__
#### Code syntax
It is mainly [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md) with a few exceptions.
* Opening braces MUST go on the same line.
* `else if` MUST be written as `elseif`. _(It is in PSR-2, but using a SHOULD)_
* Control structure keywords or opening braces MUST NOT have one space after them.
* Code MUST use tabs for indenting.
* Long arrays MAY be split across multiple lines, where each subsequent line is indented once.
* Files MUST use only the `<?php` tag.
* Files MUST NOT have an ending `?>` tag.
* Code MUST NOT use namespaces. _(This restriction will be lifted on the Alpha_1.4 code)_
* Strings SHOULD use the double quote `"` except when the single quote is required.
* Arrays SHOULD be declared using `array()`, not the `[]` shortcut.
* Argument lists MAY NOT be split across multiple lines, except long arrays.
```php
<?php
class ExampleClass{
const EXAMPLE_CLASS_CONSTANT = 1;
public $examplePublicVariable = "defaultValue";
private $examplePrivateVariable;
public function __construct($firstArgument, &$secondArgument = null){
if($firstArgument === "exampleValue"){ //Remember to use === instead == when possible
//do things
}elseif($firstArgument === "otherValue"){
$secondArgument = function(){
return array(
0 => "value1",
1 => "value2",
2 => "value3",
3 => "value4",
4 => "value5",
5 => "value6",
);
}
}
}
}
```

View File

@ -1,39 +1,34 @@
<?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/
*
*
*/
/***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();
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 [![Build Status](https://travis-ci.org/shoghicp/PocketMine-MP.png?branch=master)](https://travis-ci.org/shoghicp/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,29 +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__. 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://www.pocketmine.net/)
### [FAQ: Frequently Asked Questions](https://github.com/shoghicp/PocketMine-MP/wiki/Frequently-Asked-Questions)
### [Forums](http://forums.pocketmine.net/)
### [Wiki](https://github.com/PocketMine/PocketMine-MP/wiki/)
### [FAQ: Frequently Asked Questions](https://github.com/PocketMine/PocketMine-MP/wiki/Frequently-Asked-Questions)
### [Help Page](http://www.pocketmine.net/help.php)
### [Twitter @PocketMine](https://twitter.com/PocketMine)
## IRC #mcpedevs @ irc.freenode.net
* [WebIRC](http://webchat.freenode.net?channels=mcpedevs&uio=d4)
## IRC Chat #pocketmine (or #mcpedevs) @ irc.freenode.net
[#pocketmine + #mcpedevs channel WebIRC](http://webchat.freenode.net/?channels=pocketmine,mcpedevs)
## Third-party Libraries Used
## 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)__
* __[cURL](http://curl.haxx.se/)__: cURL is a command line tool for transferring data with URL syntax
* __[GMP](http://gmplib.org/)__: Arithmetic without limitations
* __[Zlib](http://www.zlib.net/)__: A Massively Spiffy Yet Delicately Unobtrusive Compression Library
* __[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).
* __[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.
* __[mintty](https://code.google.com/p/mintty/)__ : xterm Terminal Emulator
* __[cURL](http://curl.haxx.se/)__: cURL is a command line tool for transferring data with URL syntax
* __[Zlib](http://www.zlib.net/)__: A Massively Spiffy Yet Delicately Unobtrusive Compression Library
* __[Source RCON Protocol](https://developer.valvesoftware.com/wiki/Source_RCON_Protocol)__
* __[UT3 Query Protocol](http://wiki.unrealadmin.org/UT3_query_protocol)__

View File

@ -1,176 +0,0 @@
#!/bin/bash
COMPILER_VERSION="0.10"
PHP_VERSION="5.4.13"
ZEND_VM="GOTO"
ZLIB_VERSION="1.2.8"
GMP_VERSION="5.1.1"
PTHREADS_VERSION="0d5df071231478ff3b1982eb2b0d96cc24e39d9a"
CURL_VERSION="curl-7_29_0"
#READLINE_VERSION="6.2"
echo "[PocketMine] PHP installer and compiler for Linux & Mac - by @shoghicp v$COMPILER_VERSION"
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 libtool >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"libtool\""; 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
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!"
#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
./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!"
#Readline
#echo -n "[Readline] downloading $READLINE_VERSION..."
#wget ftp://ftp.cwru.edu/pub/bash/readline-$READLINE_VERSION.tar.gz -q -O - | tar -xz >> "$DIR/install.log" 2>&1
#mv readline-$READLINE_VERSION readline
#echo -n " checking..."
#cd readline
#./configure --prefix="$DIR/install_data/php/ext/readline" \
#--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 ./readine
#echo " done!"
#--with-readline=$DIR/install_data/php/ext/readline
#GMP
echo -n "[GMP] downloading $GMP_VERSION..."
wget ftp://ftp.gmplib.org/pub/gmp-$GMP_VERSION/gmp-$GMP_VERSION.tar.bz2 -q -O - | tar -xj >> "$DIR/install.log" 2>&1
mv gmp-$GMP_VERSION gmp
echo -n " checking..."
cd gmp
./configure --prefix="$DIR/install_data/php/ext/gmp" \
--disable-assembly \
--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 $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 --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 $PTHREADS_VERSION..."
wget https://github.com/krakjoe/pthreads/archive/$PTHREADS_VERSION.tar.gz --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 2048 ]
then
echo -n " enabling optimizations..."
OPTIMIZATION="--enable-inline-optimization "
else
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
./configure $OPTIMIZATION--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-zend-signals \
--with-zend-vm=$ZEND_VM \
--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"

164
src/API/AchievementAPI.php Normal file
View File

@ -0,0 +1,164 @@
<?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 AchievementAPI{
public static $achievements = array(
/*"openInventory" => array(
"name" => "Taking Inventory",
"requires" => array(),
),*/
"mineWood" => array(
"name" => "Getting Wood",
"requires" => array(
//"openInventory",
),
),
"buildWorkBench" => array(
"name" => "Benchmarking",
"requires" => array(
"mineWood",
),
),
"buildPickaxe" => array(
"name" => "Time to Mine!",
"requires" => array(
"buildWorkBench",
),
),
"buildFurnace" => array(
"name" => "Hot Topic",
"requires" => array(
"buildPickaxe",
),
),
"acquireIron" => array(
"name" => "Acquire hardware",
"requires" => array(
"buildFurnace",
),
),
"buildHoe" => array(
"name" => "Time to Farm!",
"requires" => array(
"buildWorkBench",
),
),
"makeBread" => array(
"name" => "Bake Bread",
"requires" => array(
"buildHoe",
),
),
"bakeCake" => array(
"name" => "The Lie",
"requires" => array(
"buildHoe",
),
),
"buildBetterPickaxe" => array(
"name" => "Getting an Upgrade",
"requires" => array(
"buildPickaxe",
),
),
"buildSword" => array(
"name" => "Time to Strike!",
"requires" => array(
"buildWorkBench",
),
),
"diamonds" => array(
"name" => "DIAMONDS!",
"requires" => array(
"acquireIron",
),
),
);
function __construct(){
}
public static function broadcastAchievement(Player $player, $achievementId){
if(isset(self::$achievements[$achievementId])){
$result = ServerAPI::request()->api->dhandle("achievement.broadcast", array("player" => $player, "achievementId" => $achievementId));
if($result !== false and $result !== true){
if(ServerAPI::request()->api->getProperty("announce-player-achievements") == true){
ServerAPI::request()->api->chat->broadcast($player->username." has just earned the achievement ".self::$achievements[$achievementId]["name"]);
}else{
$player->sendChat("You have just earned the achievement ".self::$achievements[$achievementId]["name"]);
}
}
return true;
}
return false;
}
public static function addAchievement($achievementId, $achievementName, array $requires = array()){
if(!isset(self::$achievements[$achievementId])){
self::$achievements[$achievementId] = array(
"name" => $achievementName,
"requires" => $requires,
);
return true;
}
return false;
}
public static function hasAchievement(Player $player, $achievementId){
if(!isset(self::$achievements[$achievementId]) or !isset($player->achievements)){
$player->achievements = array();
return false;
}
if(!isset($player->achievements[$achievementId]) or $player->achievements[$achievementId] == false){
return false;
}
return true;
}
public static function grantAchievement(Player $player, $achievementId){
if(isset(self::$achievements[$achievementId]) and !self::hasAchievement($player, $achievementId)){
foreach(self::$achievements[$achievementId]["requires"] as $requerimentId){
if(!self::hasAchievement($player, $requerimentId)){
return false;
}
}
if(ServerAPI::request()->api->dhandle("achievement.grant", array("player" => $player, "achievementId" => $achievementId)) !== false){
$player->achievements[$achievementId] = true;
self::broadcastAchievement($player, $achievementId);
return true;
}else{
return false;
}
}
return false;
}
public static function removeAchievement(Player $player, $achievementId){
if(self::hasAchievement($player, $achievementId)){
$player->achievements[$achievementId] = false;
}
}
public function init(){
}
}

View File

@ -1,67 +1,78 @@
<?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;
/*
* I would use PHPDoc Template here but PHPStorm does not recognise it. - @sekjun9878
*/
/** @var Config */
private $whitelist;
/** @var Config */
private $banned;
/** @var Config */
private $ops;
/** @var Config */
private $bannedIPs;
private $cmdWL = array();
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(DATA_PATH."white-list.txt", CONFIG_LIST);
$this->bannedIPs = new Config(DATA_PATH."banned-ips.txt", CONFIG_LIST);
$this->banned = new Config(DATA_PATH."banned.txt", CONFIG_LIST);
$this->ops = new Config(DATA_PATH."ops.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->server->api->console->register("op", "Ops a player", array($this, "commandHandler"));
$this->server->api->console->register("deop", "De-ops a player", array($this, "commandHandler"));
$this->server->api->console->register("sudo", "Run a command as a player", 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);
$this->cmdWhitelist("help");
$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 cmdWhitelist($cmd){
/**
* @param string $cmd Command to Whitelist
*/
public function cmdWhitelist($cmd){//Whitelists a CMD so everyone can issue it - Even non OPs.
$this->cmdWhitelist[strtolower(trim($cmd))] = true;
}
public function isOp($username){
/**
* @param string $username
*
* @return boolean
*/
public function isOp($username){//Is a player op?
$username = strtolower($username);
if($this->server->api->dhandle("op.check", $username) === true){
return true;
}elseif($this->ops->exists($username)){
@ -69,24 +80,57 @@ class BanAPI{
}
return false;
}
public function permissionsCheck($data, $event){
if(isset($this->cmdWhitelist[$data["cmd"]])){
return true;
/**
* @param mixed $data
* @param string $event
*
* @return boolean
*/
public function permissionsCheck($data, $event){
switch($event){
case "player.flying"://OPs can fly around the server.
if($this->isOp($data->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;
}
if($data["issuer"] instanceof Player){
if($this->server->api->handle("console.check", $data) === true or $this->isOp($data["issuer"]->username)){
return true;
}
}elseif($data["issuer"] === "console"){
return true;
}
return false;
}
public function commandHandler($cmd, $params, $issuer, $alias){
/**
* @param string $cmd
* @param array $params
* @param string $issuer
* @param string $alias
*
* @return string
*/
public function commandHandler($cmd, $params, $issuer, $alias){
$output = "";
switch($cmd){
case "sudo":
@ -101,27 +145,35 @@ class BanAPI{
break;
case "op":
$user = strtolower($params[0]);
if($user == ""){
$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($user);
$this->ops->set($player->iusername);
$this->ops->save();
$output .= $user." is now op\n";
$this->server->api->chat->sendTo(false, "You are now op.", $user);
$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]);
if($user == ""){
$player = $this->server->api->player->get($user);
if(!($player instanceof Player)){
$this->ops->remove($user);
$this->ops->save();
$output .= $user." is no longer op\n";
break;
}
$this->ops->remove($user);
$this->ops->remove($player->iusername);
$this->ops->save();
$output .= $user." is not longer op\n";
$this->server->api->chat->sendTo(false, "You are not longer op.", $user);
$output .= $player->iusername." is no longer op\n";
$this->server->api->chat->sendTo(false, "You are no longer op.", $player->iusername);
break;
case "kick":
if(!isset($params[0])){
$output .= "Usage: /kick <playername> [reason]\n";
$output .= "Usage: /kick <player> [reason ...]\n";
}else{
$name = strtolower(array_shift($params));
$player = $this->server->api->player->get($name);
@ -130,7 +182,9 @@ class BanAPI{
}else{
$reason = implode(" ", $params);
$reason = $reason == "" ? "No reason":$reason;
$player->close("You have been kicked: ".$reason);
$this->server->schedule(60, array($player, "close"), "You have been kicked: ".$reason); //Forces a kick
$player->blocked = true;
if($issuer instanceof Player){
$this->server->api->chat->broadcast($player->username." has been kicked by ".$issuer->username.": $reason\n");
}else{
@ -173,7 +227,7 @@ class BanAPI{
$this->server->api->setProperty("white-list", false);
break;
default:
$output .= "Usage: /whitelist <on | off | add | remove | reload | list> [username]\n";
$output .= "Usage: /whitelist <on|off|list|add|remove|reload> [username]\n";
break;
}
break;
@ -190,6 +244,11 @@ class BanAPI{
case "add":
case "ban":
$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();
$output .= "IP \"$ip\" added to ban list\n";
@ -201,7 +260,7 @@ class BanAPI{
$output .= "IP ban list: ".implode(", ", $this->bannedIPs->getAll(true))."\n";
break;
default:
$output .= "Usage: /banip <add | remove | list | reload> [IP]\n";
$output .= "Usage: /banip <add|remove|list|reload> [IP|player]\n";
break;
}
break;
@ -239,64 +298,103 @@ class BanAPI{
$output .= "Ban list: ".implode(", ", $this->banned->getAll(true))."\n";
break;
default:
$output .= "Usage: /ban <add | remove | list | reload> [player]\n";
$output .= "Usage: /ban <add|remove|list|reload> [username]\n";
break;
}
break;
}
return $output;
}
public function ban($username){
$this->commandHandler("ban", array("add", $username));
/**
* @param string $username
*/
public function ban($username){
$this->commandHandler("ban", array("add", $username), "console", "");
}
/**
* @param string $username
*/
public function pardon($username){
$this->commandHandler("ban", array("pardon", $username));
$this->commandHandler("ban", array("pardon", $username), "console", "");
}
/**
* @param string $ip
*/
public function banIP($ip){
$this->commandHandler("banip", array("add", $ip));
$this->commandHandler("banip", array("add", $ip), "console", "");
}
/**
* @param string $ip
*/
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));
/**
* @param string $username
* @param string $reason
*/
public function kick($username, $reason = "No Reason"){
$this->commandHandler("kick", array($username, $reason), "console", "");
}
public function reload(){
$this->commandHandler("ban", array("reload"));
$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){
/**
* @param string $ip
*
* @return boolean
*/
public function isIPBanned($ip){
if($this->server->api->dhandle("api.ban.ip.check", $ip) === false){
return true;
}elseif($this->bannedIPs->exists($ip)){
}elseif($this->bannedIPs->exists($ip, true)){
return true;
}
return false;
else
{
return false;
}
}
public function isBanned($username){
/**
* @param string $username
*
* @return boolean
*/
public function isBanned($username){
$username = strtolower($username);
if($this->server->api->dhandle("api.ban.check", $username) === false){
return true;
}elseif($this->banned->exists($username)){
}elseif($this->banned->exists($username, true)){
return true;
}
return false;
else
{
return false;
}
}
public function inWhitelist($username){
/**
* @param string $username
*
* @return boolean
*/
public function inWhitelist($username){
$username = strtolower($username);
if($this->server->api->dhandle("api.ban.whitelist.check", $ip) === false){
if($this->isOp($username)){
return true;
}elseif($this->whitelist->exists($username)){
}elseif($this->server->api->dhandle("api.ban.whitelist.check", $username) === false){
return true;
}elseif($this->whitelist->exists($username, true)){
return true;
}
return false;

View File

@ -1,42 +1,223 @@
<?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/
*
*
*/
define("BLOCK_UPDATE_NORMAL", 0);
define("BLOCK_UPDATE_RANDOM", 1);
define("BLOCK_UPDATE_SCHEDULED", 2);
define("BLOCK_UPDATE_WEAK", 3);
class BlockAPI{
private $server;
private $scheduledUpdates = array();
private $randomUpdates = array();
public static $creative = array(
//Building
array(STONE, 0),
array(COBBLESTONE, 0),
array(STONE_BRICKS, 0),
array(STONE_BRICKS, 1),
array(STONE_BRICKS, 2),
array(MOSS_STONE, 0),
array(WOODEN_PLANKS, 0),
array(WOODEN_PLANKS, 1),
array(WOODEN_PLANKS, 2),
array(WOODEN_PLANKS, 3),
array(BRICKS, 0),
array(DIRT, 0),
array(GRASS, 0),
array(CLAY_BLOCK, 0),
array(SANDSTONE, 0),
array(SANDSTONE, 1),
array(SANDSTONE, 2),
array(SAND, 0),
array(GRAVEL, 0),
array(TRUNK, 0),
array(TRUNK, 1),
array(TRUNK, 2),
array(TRUNK, 3),
array(NETHER_BRICKS, 0),
array(NETHERRACK, 0),
array(BEDROCK, 0),
array(COBBLESTONE_STAIRS, 0),
array(OAK_WOODEN_STAIRS, 0),
array(SPRUCE_WOODEN_STAIRS, 0),
array(BIRCH_WOODEN_STAIRS, 0),
array(JUNGLE_WOODEN_STAIRS, 0),
array(BRICK_STAIRS, 0),
array(SANDSTONE_STAIRS, 0),
array(STONE_BRICK_STAIRS, 0),
array(NETHER_BRICKS_STAIRS, 0),
array(QUARTZ_STAIRS, 0),
array(SLAB, 0),
array(SLAB, 1),
array(WOODEN_SLAB, 0),
array(WOODEN_SLAB, 1),
array(WOODEN_SLAB, 2),
array(WOODEN_SLAB, 3),
array(SLAB, 3),
array(SLAB, 4),
array(SLAB, 5),
array(SLAB, 6),
array(QUARTZ_BLOCK, 0),
array(QUARTZ_BLOCK, 1),
array(QUARTZ_BLOCK, 2),
array(COAL_ORE, 0),
array(IRON_ORE, 0),
array(GOLD_ORE, 0),
array(DIAMOND_ORE, 0),
array(LAPIS_ORE, 0),
array(REDSTONE_ORE, 0),
array(OBSIDIAN, 0),
array(ICE, 0),
array(SNOW_BLOCK, 0),
//Decoration
array(COBBLESTONE_WALL, 0),
array(COBBLESTONE_WALL, 1),
array(GOLD_BLOCK, 0),
array(IRON_BLOCK, 0),
array(DIAMOND_BLOCK, 0),
array(LAPIS_BLOCK, 0),
array(COAL_BLOCK, 0),
array(SNOW_LAYER, 0),
array(GLASS, 0),
array(GLOWSTONE_BLOCK, 0),
array(NETHER_REACTOR, 0),
array(WOOL, 0),
array(WOOL, 7),
array(WOOL, 6),
array(WOOL, 5),
array(WOOL, 4),
array(WOOL, 3),
array(WOOL, 2),
array(WOOL, 1),
array(WOOL, 15),
array(WOOL, 14),
array(WOOL, 13),
array(WOOL, 12),
array(WOOL, 11),
array(WOOL, 10),
array(WOOL, 9),
array(WOOL, 8),
array(LADDER, 0),
array(SPONGE, 0),
array(GLASS_PANE, 0),
array(WOODEN_DOOR, 0),
array(TRAPDOOR, 0),
array(FENCE, 0),
array(FENCE_GATE, 0),
array(IRON_BARS, 0),
array(BED, 0),
array(BOOKSHELF, 0),
array(PAINTING, 0),
array(WORKBENCH, 0),
array(STONECUTTER, 0),
array(CHEST, 0),
array(FURNACE, 0),
array(DANDELION, 0),
array(CYAN_FLOWER, 0),
array(BROWN_MUSHROOM, 0),
array(RED_MUSHROOM, 0),
array(CACTUS, 0),
array(MELON_BLOCK, 0),
array(PUMPKIN, 0),
array(LIT_PUMPKIN, 0),
array(COBWEB, 0),
array(HAY_BALE, 0),
array(TALL_GRASS, 1),
array(TALL_GRASS, 2),
array(DEAD_BUSH, 0),
array(SAPLING, 0),
array(SAPLING, 1),
array(SAPLING, 2),
array(SAPLING, 3),
array(LEAVES, 0),
array(LEAVES, 1),
array(LEAVES, 2),
array(LEAVES, 3),
array(CAKE, 0),
array(SIGN, 0),
array(CARPET, 0),
array(CARPET, 7),
array(CARPET, 6),
array(CARPET, 5),
array(CARPET, 4),
array(CARPET, 3),
array(CARPET, 2),
array(CARPET, 1),
array(CARPET, 15),
array(CARPET, 14),
array(CARPET, 13),
array(CARPET, 12),
array(CARPET, 11),
array(CARPET, 10),
array(CARPET, 9),
array(CARPET, 8),
//Tools
//array(RAILS, 0),
//array(POWERED_RAILS, 0),
array(TORCH, 0),
array(BUCKET, 0),
array(BUCKET, 8),
array(BUCKET, 10),
array(TNT, 0),
array(IRON_HOE, 0),
array(IRON_SWORD, 0),
array(BOW, 0),
array(SHEARS, 0),
array(FLINT_AND_STEEL, 0),
array(CLOCK, 0),
array(COMPASS, 0),
array(MINECART, 0),
array(SPAWN_EGG, MOB_CHICKEN),
array(SPAWN_EGG, MOB_COW),
array(SPAWN_EGG, MOB_PIG),
array(SPAWN_EGG, MOB_SHEEP),
//Seeds
array(SUGARCANE, 0),
array(WHEAT, 0),
array(SEEDS, 0),
array(MELON_SEEDS, 0),
array(PUMPKIN_SEEDS, 0),
array(CARROT, 0),
array(POTATO, 0),
array(BEETROOT_SEEDS, 0),
array(EGG, 0),
array(DYE, 0),
array(DYE, 7),
array(DYE, 6),
array(DYE, 5),
array(DYE, 4),
array(DYE, 3),
array(DYE, 2),
array(DYE, 1),
array(DYE, 15),
array(DYE, 14),
array(DYE, 13),
array(DYE, 12),
array(DYE, 11),
array(DYE, 10),
array(DYE, 9),
array(DYE, 8),
);
public static function fromString($str, $multiple = false){
if($multiple === true){
@ -66,14 +247,13 @@ class BlockAPI{
}
public static function get($id, $meta = 0, $v = false){
$id = (int) $id;
if(isset(Block::$class[$id])){
$classname = Block::$class[$id];
$b = new $classname($meta);
}else{
$b = new GenericBlock($id, $meta);
$b = new GenericBlock((int) $id, $meta);
}
if($v instanceof Vector3){
if($v instanceof Position){
$b->position($v);
}
return $b;
@ -90,35 +270,13 @@ class BlockAPI{
return $i;
}
public function setBlock(Vector3 $block, $id, $meta, $update = true, $tiles = false){
if(($block instanceof Vector3) or (($block instanceof Block) and $block->inWorld === true)){
$this->server->api->level->setBlock($block->x, $block->y, $block->z, (int) $id, (int) $meta, $update, $tiles);
return true;
}
return false;
}
public function getBlock($x, $y = 0, $z = 0){
if($x instanceof Vector3){
$y = $x->y;
$z = $x->z;
$x = $x->x;
}
$b = $this->server->api->level->getBlock($x, $y, $z);
return BlockAPI::get($b[0], $b[1], new Vector3($b[2][0], $b[2][1], $b[2][2]));
}
public function getBlockFace(Block $block, $face){
return $this->getBlock($block->getSide($face));
}
function __construct(PocketMinecraftServer $server){
$this->server = $server;
function __construct(){
$this->server = ServerAPI::request();
}
public function init(){
$this->server->addHandler("block.update", array($this, "updateBlockRemote"), 1);
$this->server->api->console->register("give", "Give items to a player", array($this, "commandHandler"));
$this->server->schedule(1, array($this, "blockUpdateTick"), array(), true);
$this->server->api->console->register("give", "<player> <item[:damage]> [amount]", array($this, "commandHandler"));
}
public function commandHandler($cmd, $params, $issuer, $alias){
@ -126,10 +284,10 @@ class BlockAPI{
switch($cmd){
case "give":
if(!isset($params[0]) or !isset($params[1])){
$output .= "Usage: /give <username> <item> [amount] [damage]\n";
$output .= "Usage: /give <player> <item[:damage]> [amount]\n";
break;
}
$username = $params[0];
$player = $this->server->api->player->get($params[0]);
$item = BlockAPI::fromString($params[1]);
if(!isset($params[2])){
@ -138,11 +296,19 @@ class BlockAPI{
$item->count = (int) $params[2];
}
if(($player = $this->server->api->player->get($username)) !== false){
$this->drop(new Vector3($player->entity->x - 0.5, $player->entity->y, $player->entity->z - 0.5), $item, true);
$output .= "Giving ".$item->count." of ".$item->getName()." (".$item->getID().":".$item->getMetadata().") to ".$username."\n";
if($player instanceof Player){
if(($player->gamemode & 0x01) === 0x01){
$output .= "Player is in creative mode.\n";
break;
}
if($item->getID() == 0) {
$output .= "You cannot give an air block to a player.\n";
break;
}
$player->addItem($item->getID(), $item->getMetadata(), $item->count);
$output .= "Giving ".$item->count." of ".$item->getName()." (".$item->getID().":".$item->getMetadata().") to ".$player->username."\n";
}else{
$output .= "Unknown player\n";
$output .= "Unknown player.\n";
}
break;
@ -150,7 +316,7 @@ class BlockAPI{
return $output;
}
private function cancelAction(Block $block, Player $player){
private function cancelAction(Block $block, Player $player, $send = true){
$player->dataPacket(MC_UPDATE_BLOCK, array(
"x" => $block->x,
"y" => $block->y,
@ -158,74 +324,57 @@ class BlockAPI{
"block" => $block->getID(),
"meta" => $block->getMetadata()
));
if($send === true){
$player->sendInventorySlot($player->slot);
}
return false;
}
public function playerBlockBreak(Player $player, Vector3 $vector){
$target = $this->getBlock($vector);
$item = $player->equipment;
$target = $player->level->getBlock($vector);
$item = $player->getSlot($player->slot);
if($this->server->api->dhandle("player.block.touch", array("type" => "break", "player" => $player, "target" => $target, "item" => $item)) === false){
return $this->cancelAction($target, $player);
return $this->cancelAction($target, $player, false);
}
if(!$target->isBreakable($item, $player) or $player->gamemode === ADVENTURE or ($player->lastBreak + $target->getBreakTime($item, $player)) >= microtime(true)){
return $this->cancelAction($target, $player);
if((!$target->isBreakable($item, $player) and $this->server->api->dhandle("player.block.break.invalid", array("player" => $player, "target" => $target, "item" => $item)) !== true) or ($player->gamemode & 0x02) === 0x02 or (($player->lastBreak - $player->getLag() / 1000) + $target->getBreakTime($item, $player) - 0.1) >= microtime(true)){
return $this->cancelAction($target, $player, false);
}
$player->lastBreak = microtime(true);
if($this->server->api->dhandle("player.block.break", array("player" => $player, "target" => $target, "item" => $item)) !== false){
$player->lastBreak = microtime(true);
$drops = $target->getDrops($item, $player);
$target->onBreak($this, $item, $player);
if($target->onBreak($item, $player) === false){
return $this->cancelAction($target, $player, false);
}
if(($player->gamemode & 0x01) === 0 and $item->useOn($target) and $item->getMetadata() >= $item->getMaxDurability()){
$player->setSlot($player->slot, new Item(AIR, 0, 0), false);
}
}else{
return $this->cancelAction($target, $player);
return $this->cancelAction($target, $player, false);
}
if($player->gamemode !== CREATIVE and count($drops) > 0){
if(($player->gamemode & 0x01) === 0x00 and count($drops) > 0){
foreach($drops as $drop){
$this->drop($target, BlockAPI::getItem($drop[0] & 0xFFFF, $drop[1] & 0xFFFF, $drop[2] & 0xFF));
$this->server->api->entity->drop(new Position($target->x + 0.5, $target->y, $target->z + 0.5, $target->level), BlockAPI::getItem($drop[0] & 0xFFFF, $drop[1] & 0xFFFF, $drop[2]));
}
}
return false;
}
public function drop(Vector3 $pos, Item $item){
if($item->getID() === AIR or $item->count <= 0){
return;
}
$data = array(
"x" => $pos->x + mt_rand(2, 8) / 10,
"y" => $pos->y + 0.19,
"z" => $pos->z + mt_rand(2, 8) / 10,
"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;
$server = ServerAPI::request();
$e = $server->api->entity->add(ENTITY_ITEM, $item->getID(), $data);
//$e->speedX = mt_rand(-10, 10) / 100;
//$e->speedY = mt_rand(0, 5) / 100;
//$e->speedZ = mt_rand(-10, 10) / 100;
$server->api->entity->spawnToAll($e->eid);
}
}
}
public function playerBlockAction(Player $player, Vector3 $vector, $face, $fx, $fy, $fz){
if($face < 0 or $face > 5){
return false;
}
$target = $this->getBlock($vector);
$block = $this->getBlockFace($target, $face);
$item = $player->equipment;
$target = $player->level->getBlock($vector);
$block = $target->getSide($face);
$item = $player->getSlot($player->slot);
if($target->getID() === AIR){ //If no block exists
if($target->getID() === AIR and $this->server->api->dhandle("player.block.place.invalid", array("player" => $player, "block" => $block, "target" => $target, "item" => $item)) !== true){ //If no block exists or not allowed in CREATIVE
$this->cancelAction($target, $player);
return $this->cancelAction($block, $player);
}
@ -233,67 +382,74 @@ class BlockAPI{
if($this->server->api->dhandle("player.block.touch", array("type" => "place", "player" => $player, "block" => $block, "target" => $target, "item" => $item)) === false){
return $this->cancelAction($block, $player);
}
$this->blockUpdate($target, BLOCK_UPDATE_TOUCH);
if($target->isActivable === true){
if($this->server->api->dhandle("player.block.activate", array("player" => $player, "block" => $block, "target" => $target, "item" => $item)) !== false and $target->onActivate($this, $item, $player) === true){
if($this->server->api->dhandle("player.block.activate", array("player" => $player, "block" => $block, "target" => $target, "item" => $item)) !== false and $target->onActivate($item, $player) === true){
return false;
}
}
if($player->gamemode === ADVENTURE){ //Adventure mode!!
return $this->cancelAction($block, $player);
if(($player->gamemode & 0x02) === 0x02){ //Adventure mode!!
return $this->cancelAction($block, $player, false);
}
if($block->y > 127 or $block->y < 0){
return false;
}
if($item->isActivable === true and $item->onActivate($this, $player, $block, $target, $face, $fx, $fy, $fz)){
return $this->cancelAction($block, $player);
if($item->isActivable === true and $item->onActivate($player->level, $player, $block, $target, $face, $fx, $fy, $fz) === true){
if($item->count <= 0){
$player->setSlot($player->slot, BlockAPI::getItem(AIR, 0, 0), false);
}
return false;
}
if($item->isPlaceable()){
$hand = $item->getBlock();
$hand->position($block);
}elseif($block->getID() === FIRE){
$player->level->setBlock($block, new AirBlock(), true, false, true);
return false;
}else{
return $this->cancelAction($block, $player);
return $this->cancelAction($block, $player, false);
}
if(!($block->isReplaceable === true or ($hand->getID() === SLAB and $block->getID() === SLAB))){
return $this->cancelAction($block, $player);
return $this->cancelAction($block, $player, false);
}
if($hand->isTransparent === false and $player->entity->inBlock($block->x, $block->y, $block->z)){
return $this->cancelAction($block, $player); //Entity in block
if($target->isReplaceable === true){
$block = $target;
$hand->position($block);
$face = -1;
}
if($hand->isSolid === true and $player->entity->inBlock($block)){
return $this->cancelAction($block, $player, false); //Entity in block
}
if($this->server->api->dhandle("player.block.place", array("player" => $player, "block" => $block, "target" => $target, "item" => $item)) === false){
return $this->cancelAction($block, $player);
}elseif($hand->place($this, $item, $player, $block, $target, $face, $fx, $fy, $fz) === false){
return $this->cancelAction($block, $player);
}elseif($hand->place($item, $player, $block, $target, $face, $fx, $fy, $fz) === false){
return $this->cancelAction($block, $player, false);
}
if($hand->getID() === SIGN_POST or $hand->getID() === WALL_POST){
$t = $this->server->api->tileentity->addSign($block->x, $block->y, $block->z);
if($hand->getID() === SIGN_POST or $hand->getID() === WALL_SIGN){
$t = $this->server->api->tile->addSign($player->level, $block->x, $block->y, $block->z);
$t->data["creator"] = $player->username;
}
if($this->server->gamemode === SURVIVAL or $this->server->gamemode === ADVENTURE){
$player->removeItem($item->getID(), $item->getMetadata(), 1);
if(($player->gamemode & 0x01) === 0x00){
--$item->count;
if($item->count <= 0){
$player->setSlot($player->slot, BlockAPI::getItem(AIR, 0, 0), false);
}
}
return false;
}
public function blockScheduler($data){
$this->updateBlock($data["x"], $data["y"], $data["z"], BLOCK_UPDATE_SCHEDULED);
}
public function updateBlockRemote($data, $event){
if($event !== "block.update"){
return;
}
$this->updateBlock($data["x"], $data["y"], $data["z"], isset($data["type"]) ? $data["type"]:BLOCK_UPDATE_RANDOM);
return true;
}
/*
public function flowLavaOn($source, $face){
$down = 0;
@ -640,25 +796,6 @@ class BlockAPI{
}
}
break;
case 74:
if($type === BLOCK_UPDATE_SCHEDULED or $type === BLOCK_UPDATE_RANDOM){
$changed = true;
$this->server->api->level->setBlock($x, $y, $z, 73, $block[1], false);
$type = BLOCK_UPDATE_WEAK;
}
break;
case 73:
if($type === BLOCK_UPDATE_NORMAL){
$changed = true;
$this->server->api->level->setBlock($x, $y, $z, 74, $block[1], false);
$this->server->schedule(mt_rand(40, 100), array($this, "blockScheduler"), array(
"x" => $x,
"y" => $y,
"z" => $z,
));
$type = BLOCK_UPDATE_WEAK;
}
break;
}
if($type === BLOCK_TYPE_SCHEDULED){
@ -667,14 +804,107 @@ class BlockAPI{
if($changed === true){
$this->updateBlocksAround($x, $y, $z, $type);
}
}*/
public function blockUpdateAround(Position $pos, $type = BLOCK_UPDATE_NORMAL, $delay = false){
if($delay !== false){
$this->scheduleBlockUpdate($pos->getSide(0), $delay, $type);
$this->scheduleBlockUpdate($pos->getSide(1), $delay, $type);
$this->scheduleBlockUpdate($pos->getSide(2), $delay, $type);
$this->scheduleBlockUpdate($pos->getSide(3), $delay, $type);
$this->scheduleBlockUpdate($pos->getSide(4), $delay, $type);
$this->scheduleBlockUpdate($pos->getSide(5), $delay, $type);
}else{
$this->blockUpdate($pos->getSide(0), $type);
$this->blockUpdate($pos->getSide(1), $type);
$this->blockUpdate($pos->getSide(2), $type);
$this->blockUpdate($pos->getSide(3), $type);
$this->blockUpdate($pos->getSide(4), $type);
$this->blockUpdate($pos->getSide(5), $type);
}
}
public function blockUpdate(Position $pos, $type = BLOCK_UPDATE_NORMAL){
if(!($pos instanceof Block)){
$block = $pos->level->getBlock($pos);
}else{
$pos = new Position($pos->x, $pos->y, $pos->z, $pos->level);
$block = $pos->level->getBlock($pos);
}
if($block === false){
return false;
}
$level = $block->onUpdate($type);
if($level === BLOCK_UPDATE_NORMAL){
$this->blockUpdateAround($block, $level);
$this->server->api->entity->updateRadius($pos, 1);
}elseif($level === BLOCK_UPDATE_RANDOM){
$this->nextRandomUpdate($pos);
}
return $level;
}
public function scheduleBlockUpdate(Position $pos, $delay, $type = BLOCK_UPDATE_SCHEDULED){
$type = (int) $type;
if($delay < 0){
return false;
}
$index = $pos->x.".".$pos->y.".".$pos->z.".".$pos->level->getName().".".$type;
$delay = microtime(true) + $delay * 0.05;
if(!isset($this->scheduledUpdates[$index])){
$this->scheduledUpdates[$index] = $pos;
$this->server->query("INSERT INTO blockUpdates (x, y, z, level, type, delay) VALUES (".$pos->x.", ".$pos->y.", ".$pos->z.", '".$pos->level->getName()."', ".$type.", ".$delay.");");
return true;
}
return false;
}
public function nextRandomUpdate(Position $pos){
if(!isset($this->scheduledUpdates[$pos->x.".".$pos->y.".".$pos->z.".".$pos->level->getName().".".BLOCK_UPDATE_RANDOM])){
$X = (($pos->x >> 4) << 4);
$Y = (($pos->y >> 4) << 4);
$Z = (($pos->z >> 4) << 4);
$time = microtime(true);
$i = 0;
$offset = 0;
while(true){
$t = $offset + Utils::getRandomUpdateTicks() * 0.05;
$update = $this->server->query("SELECT COUNT(*) FROM blockUpdates WHERE level = '".$pos->level->getName()."' AND type = ".BLOCK_UPDATE_RANDOM." AND delay >= ".($time + $t - 1)." AND delay <= ".($time + $t + 1).";");
if($update instanceof SQLite3Result){
$update = $update->fetchArray(SQLITE3_NUM);
if($update[0] < 3){
break;
}
}else{
break;
}
$offset += mt_rand(25, 75);
}
$this->scheduleBlockUpdate($pos, $t / 0.05, BLOCK_UPDATE_RANDOM);
}
}
public function blockUpdateTick(){
$time = microtime(true);
if(count($this->scheduledUpdates) > 0){
$update = $this->server->query("SELECT x,y,z,level,type FROM blockUpdates WHERE delay <= ".$time.";");
if($update instanceof SQLite3Result){
$upp = array();
while(($up = $update->fetchArray(SQLITE3_ASSOC)) !== false){
$index = $up["x"].".".$up["y"].".".$up["z"].".".$up["level"].".".$up["type"];
if(isset($this->scheduledUpdates[$index])){
$upp[] = array((int) $up["type"], $this->scheduledUpdates[$index]);
unset($this->scheduledUpdates[$index]);
}
}
$this->server->query("DELETE FROM blockUpdates WHERE delay <= ".$time.";");
foreach($upp as $b){
$this->blockUpdate($b[1], $b[0]);
}
}
}
}
public function updateBlocksAround($x, $y, $z, $type){
$this->updateBlock($x + 1, $y, $z, $type);
$this->updateBlock($x, $y + 1, $z, $type);
$this->updateBlock($x, $y, $z + 1, $type);
$this->updateBlock($x - 1, $y, $z, $type);
$this->updateBlock($x, $y - 1, $z, $type);
$this->updateBlock($x, $y, $z - 1, $type);
}
}
}

View File

@ -1,59 +1,147 @@
<?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 broadcast($message){
/**
* @param string $cmd
* @param array $params
* @param string $issuer
* @param string $alias
*
* @return string
*/
public function commandHandler($cmd, $params, $issuer, $alias){
$output = "";
switch($cmd){
case "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($target === "server" or $target === "console" or $target === "rcon"){
$target = "Console";
}
}
$mes = implode(" ", $params);
$output .= "[me -> ".$target."] ".$mes."\n";
if($target !== "Console" and $target !== "Rcon"){
$this->sendTo(false, "[".$sender." -> me] ".$mes, $target);
}
if($target === "Console" or $sender === "Console"){
console("[INFO] [".$sender." -> ".$target."] ".$mes);
}
break;
}
return $output;
}
/**
* @param string $message
*/
public function broadcast($message){
$this->send(false, $message);
console("[CHAT] ".$message);
}
public function sendTo($owner, $text, $player){
/**
* @param string $owner
* @param string $text
* @param mixed $player Can be either Player object or string username. Boolean false for broadcast.
*/
public function sendTo($owner, $text, $player){
$this->send($owner, $text, array($player));
}
public function send($owner, $text, $whitelist = false, $blacklist = false){
$message = "";
/**
* @param mixed $owner Can be either Player object or string username. Boolean false for broadcast.
* @param string $text
* @param $whitelist
* @param $blacklist
*/
public function send($owner, $text, $whitelist = false, $blacklist = false){
$message = array(
"player" => $owner,
"message" => $text,
);
if($owner !== false){
if($owner instanceof Player){
$message = "<".$owner->username."> ";
if($whitelist === false){
console("[INFO] <".$owner->username."> ".$text);
}
}else{
$message = "<".$owner."> ";
if($whitelist === false){
console("[INFO] <".$owner."> ".$text);
}
}
}else{
if($whitelist === false){
console("[INFO] $text");
}
$message["player"] = "";
}
$message .= $text;
$this->server->handle("server.chat", new Container($message, $whitelist, $blacklist));
}
}

View File

@ -1,91 +1,84 @@
<?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, $alias;
function __construct(PocketMinecraftServer $server){
function __construct(){
$this->help = array();
$this->cmds = array();
$this->alias = array();
$this->server = $server;
$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->register("help", "Show available commands", array($this, "defaultCommands"));
$this->register("status", "Show server TPS and memory usage", array($this, "defaultCommands"));
$this->alias("lag", "status");
$this->register("difficulty", "Changes server difficulty", array($this, "defaultCommands"));
$this->register("invisible", "Changes server visibility", array($this, "defaultCommands"));
$this->register("say", "Broadcast a message", array($this, "defaultCommands"));
$this->register("save-all", "Save pending changes to disk", array($this, "defaultCommands"));
$this->register("stop", "Stops the server gracefully", array($this, "defaultCommands"));
$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, $issuer, $alias){
$output = "";
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":
$output .= "Server is invisible\n";
$this->server->api->setProperty("invisible", true);
break;
case "off":
case "false":
case "0":
$output .= "Server is visible\n";
$this->server->api->setProperty("invisible", false);
break;
default:
$output .= "Usage: /invisible <on | off>\n";
break;
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;
}
$this->server->api->setProperty("gamemode", $gms[strtolower($params[0])]);
$output .= "Default Gamemode is now ".strtoupper($this->server->getGamemode()).".\n";
break;
case "status":
case "lag":
if(!($issuer instanceof Player) and $issuer === "console"){
$this->server->debugInfo(true);
}
@ -102,42 +95,48 @@ class ConsoleAPI{
break;
case "difficulty":
$s = trim(array_shift($params));
if($s == "" or (((int) $s) !== 0 and ((int) $s) !== 1)){
$output .= "Usage: /difficulty <0 | 1>\n";
if($s === "" or (((int) $s) > 3 and ((int) $s) < 0)){
$output .= "Usage: /difficulty <0|1|2|3>\n";
break;
}
$this->server->api->setProperty("difficulty", (int) $s);
$output .= "Difficulty changed to ".$this->server->difficulty."\n";
loadConfig(true);
break;
case "say":
$s = implode(" ", $params);
if(trim($s) == ""){
$output .= "Usage: /say <message>\n";
break;
}
$this->server->api->chat->broadcast("[Server] ".$s);
break;
case "save-all":
$this->server->save();
break;
case "?":
if($issuer !== "console"){
if($issuer !== "console" and $issuer !== "rcon"){
break;
}
case "help":
$max = ceil(count($this->help) / 5);
$page = isset($params[0]) ? min($max - 1, max(0, intval($params[0]) - 1)):0;
$output .= "- Showing help page ". ($page + 1) ." of $max (/help <page>) -\n";
$current = 0;
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){
$curpage = (int) ($current / 5);
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 .= "\x1b[31;1m-\x1b[0m Showing help page $page of $max (/help <page>) \x1b[31;1m-\x1b[0m\n";
$current = 1;
foreach($cmds as $c => $h){
$curpage = (int) ceil($current / 5);
if($curpage === $page){
$output .= "/$c: ".$h."\n";
$output .= "/$c ".$h."\n";
}elseif($curpage > $page){
break;
}
}
++$current;
}
break;
@ -163,46 +162,126 @@ class ConsoleAPI{
ksort($this->help, SORT_NATURAL | SORT_FLAG_CASE);
}
public function run($line = "", $issuer = false, $alias = false){
public function run($line = "", $issuer = "console", $alias = false){
if($line != ""){
$params = explode(" ", $line);
$cmd = strtolower(array_shift($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])){
$this->run($this->alias[$cmd] . " " .implode(" ", $params), $issuer, $cmd);
return;
return $this->run($this->alias[$cmd] . ($params !== "" ? " " .$params:""), $issuer, $cmd);
}
if($issuer instanceof Player){
console("[INFO] \"".$issuer->username."\" issued server command: $alias /$cmd ".implode(" ", $params));
console("[DEBUG] ".FORMAT_AQUA.$issuer->username.FORMAT_RESET." issued server command: ".ltrim("$alias ")."/$cmd ".$params, true, true, 2);
}else{
console("[INFO] Issued server command: $alias /$cmd ".implode(" ", $params));
console("[DEBUG] ".FORMAT_YELLOW."*".$issuer.FORMAT_RESET." issued server command: ".ltrim("$alias ")."/$cmd ".$params, true, true, 2);
}
if($this->server->api->dhandle("console.command.".$cmd, array("cmd" => $cmd, "parameters" => $params, "issuer" => $issuer, "alias" => $alias)) === false
or $this->server->api->dhandle("console.command", array("cmd" => $cmd, "parameters" => $params, "issuer" => $issuer, "alias" => $alias)) === false){
$output = "You don't have permissions\n";
}else{
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":
if($issuer instanceof Player)
{
if($this->server->api->ban->isOp($issuer->username))
{
$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);
}
}
else
{
$issuer->sendChat("You don't have permissions to use this command.\n");
}
}
else
{
$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));
}elseif($output != "" and $issuer === "console"){
$mes = explode("\n", trim($output));
foreach($mes as $m){
console("[CMD] ".$m);
}
}
return $output;
}
}
public function handle($time){
if(defined("NO_THREADS")){
return;
}
if($this->loop->line !== false){
$line = trim($this->loop->line);
$line = preg_replace("#\\x1b\\x5b([^\\x1b]*\\x7e|[\\x40-\\x50])#", "", trim($this->loop->line));
$this->loop->line = false;
$this->run($line, "console");
$output = $this->run($line, "console");
if($output != ""){
$mes = explode("\n", trim($output));
foreach($mes as $m){
console("[CMD] ".$m);
}
}
}else{
$this->loop->notify();
}
@ -211,19 +290,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,49 +1,92 @@
<?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){
@ -58,46 +101,70 @@ class EntityAPI{
$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 and $player->eid !== $eid){
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];
$this->server->entities[$eid] = null;
unset($this->server->entities[$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 = ".$entity->eid.";");
$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,145 +1,245 @@
<?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->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){
}
}
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, $tiles = false){
if($x < 0 or $y < 0 or $z < 0){
return false;
}
if($this->server->api->dhandle("block.change", array(
"x" => $x,
"y" => $y,
"z" => $z,
"block" => $block,
"meta" => $meta,
)) !== false){
$this->map->setBlock($x, $y, $z, $block, $meta);
$this->heightMap[$z][$x] = $this->map->getFloor($x, $z);
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);
}
if($tiles === true){
if(($t = $this->server->api->tileentity->get($x, $y, $z)) !== false){
$t[0]->close();
}
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 getOrderedChunks($X, $Z, $columnsPerPacket = 2){
$columnsPerPacket = max(1, (int) $columnsPerPacket);
$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;
}
public function getMiniChunk($X, $Z, $Y, $MTU){
$ordered = array();
$i = 0;
$ordered[$i] = "";
$cnt = 0;
for($z = 0; $z < 16; ++$z){
for($x = 0; $x < 16; ++$x){
if((strlen($ordered[$i]) + 16 + 8 + 1) > $MTU){
++$i;
$ordered[$i] = str_repeat("\x00", $cnt);
}
$ordered[$i] .= chr(1 << $Y);
$block = $this->map->getChunkColumn($X, $Z, $x, $z, 0);
$meta = $this->map->getChunkColumn($X, $Z, $x, $z, 1);
$ordered[$i] .= substr($block, $Y << 4, 16);
$ordered[$i] .= substr($meta, $Y << 3, 8);
++$cnt;
}
}
return $ordered;
public function getAll()
{
return $this->levels;
}
}
}

View File

@ -1,318 +1,484 @@
<?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;
}
private $server;
function __construct(){
$this->server = ServerAPI::request();
}
public function init(){
$this->server->addHandler("server.regeneration", array($this, "handle"));
$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("gamemode", "Changes the player gamemode", 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->alias("suicide", "kill");
}
public function init(){
$this->server->schedule(20 * 15, array($this, "handle"), 1, true, "server.regeneration");
$this->server->addHandler("player.death", array($this, "handle"), 1);
$this->server->api->console->register("list", "", array($this, "commandHandler"));
$this->server->api->console->register("kill", "<player>", array($this, "commandHandler"));
$this->server->api->console->register("gamemode", "<mode> [player]", array($this, "commandHandler"));
$this->server->api->console->register("tp", "[target player] <destination player|w:world> OR /tp [target player] <x> <y> <z>", array($this, "commandHandler"));
$this->server->api->console->register("spawnpoint", "[player] [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 entities WHERE class = ".ENTITY_PLAYER." AND health < 20;");
if($result !== true and $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;
}
}else{
switch($data["cause"]){
case "cactus":
$message .= " was pricked to death";
break;
case "lava":
$message .= " tried to swim in lava";
break;
case "fire":
$message .= " went up in flames";
break;
case "burning":
$message .= " burned to death";
break;
case "suffocation":
$message .= " suffocated in a wall";
break;
case "water":
$message .= " drowned";
break;
case "void":
$message .= " fell out of the world";
break;
case "fall":
$message .= " hit the ground too hard";
break;
case "flying":
$message .= " tried to fly up to the sky";
break;
default:
$message .= " died";
break;
}
}
$this->server->chat(false, $message);
return true;
break;
}
}
public function handle($data, $event){
switch($event){
case "server.regeneration":
if($this->server->difficulty === 0){
$result = $this->server->preparedSQL->selectPlayersToHeal->execute();
if($result !== false){
while(($player = $result->fetchArray()) !== false){
if(($player = $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":
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;
case "explosion":
$message = " blew up";
break;
default:
$message = " died";
break;
}
}
$this->server->api->chat->broadcast($data["player"]->username . $message);
return true;
break;
}
}
public function commandHandler($cmd, $params, $issuer, $alias){
$output = "";
switch($cmd){
case "gamemode":
$gm = -1;
$player = false;
if(!isset($params[1]) and isset($params[0]) and ($issuer instanceof Player)){
$player = $issuer;
$gm = (int) $params[1];
}elseif(isset($params[1]) and isset($params[0])){
$player = $this->server->api->player->get($params[0]);
$gm = (int) $params[1];
}
if(!($player instanceof Player) or $gm < 0 or $gm > 2){
$output .= "Usage: /gamemode [player] <0 | 1 | 2>\n";
break;
}
if($player->setGamemode($gm)){
$output .= "Gamemode of ".$player->username." changed to ".$player->getGamemode()."\n";
}
break;
case "tp":
if(!isset($params[1]) and isset($params[0]) and ($issuer instanceof Player)){
$name = $issuer->username;
$target = $params[1];
}elseif(isset($params[1]) and isset($params[0])){
$name = $params[0];
$target = $params[1];
}else{
$output .= "Usage: /tp [player] <target>\n";
break;
}
if($this->teleport($name, $target)){
$output .= "\"$name\" teleported to \"$target\"\n";
}else{
$output .= "Couldn't teleport\n";
}
break;
case "tppos":
if(!isset($params[3]) and isset($params[2]) and isset($params[1]) and isset($params[0]) and ($issuer instanceof Player)){
$name = $issuer->username;
$x = (float) $params[0];
$y = (float) $params[1];
$z = (float) $params[2];
}elseif(isset($params[3]) and isset($params[2]) and isset($params[1]) and isset($params[0])){
$name = $params[0];
$x = (float) $params[1];
$y = (float) $params[2];
$z = (float) $params[3];
}else{
$output .= "Usage: /tp [player] <x> <y> <z>\n";
break;
}
if($this->tppos($name, $x, $y, $z)){
$output .= "\"$name\" teleported to ($x, $y, $z)\n";
}else{
$output .= "Couldn't teleport\n";
}
break;
case "kill":
case "suicide":
if(!isset($params[0]) and ($issuer instanceof Player)){
$player = $issuer;
}else{
$player = $this->get($params[0]);
}
if($player instanceof Player){
$this->server->api->entity->harm($player->eid, 20, "console", true);
}else{
$output .= "Usage: /kill [player]\n";
}
break;
case "list":
$output .= "Player list:\n";
foreach($this->server->clients as $c){
$output .= $c->username." (".$c->ip.":".$c->port."), ClientID ".$c->clientID.", (".round($c->entity->x, 2).", ".round($c->entity->y, 2).", ".round($c->entity->z, 2).")\n";
}
break;
}
return $output;
}
public function commandHandler($cmd, $params, $issuer, $alias){
$output = "";
switch($cmd){
case "spawnpoint":
if(!($issuer instanceof Player)){
$output .= "Please run this command in-game.\n";
break;
}
public function teleport($name, $target){
$target = $this->get($target);
if(($target instanceof Player) and ($target->entity instanceof Entity)){
return $this->tppos($name, $target->entity->x, $target->entity->y, $target->entity->z);
}
return false;
}
if(count($params) === 1 or count($params) === 4){
$target = $this->server->api->player->get(array_shift($params));
}else{
$target = $issuer;
}
public function tppos($name, $x, $y, $z){
$player = $this->get($name);
if(($player instanceof Player) and ($player->entity instanceof Entity)){
$player->teleport(new Vector3($x, $y, $z));
return true;
}
return false;
}
if(!($target instanceof Player)){
$output .= "That player cannot be found.\n";
break;
}
public function get($name){
$CID = $this->server->query("SELECT ip,port FROM players WHERE name = '".$name."';", true);
$CID = $this->server->clientID($CID["ip"], $CID["port"]);
if(isset($this->server->clients[$CID])){
return $this->server->clients[$CID];
}
return false;
}
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);
}
public function getAll(){
return $this->server->clients;
}
$target->setSpawn($spawn);
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;
}
$output .= "Spawnpoint set correctly!\n";
break;
case "spawn":
if(!($issuer instanceof Player)){
$output .= "Please run this command in-game.\n";
break;
}
$issuer->teleport($this->server->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;
$setgm = 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])){
if($this->server->api->player->get($params[1]) instanceof Player){
$player = $this->server->api->player->get($params[1]);
$setgm = $params[0];
}elseif($this->server->api->player->get($params[0]) instanceof Player){
$player = $this->server->api->player->get($params[0]);
$setgm = $params[1];
}else{
$output .= "Usage: /$cmd <mode> [player] or /$cmd [player] <mode>\n";
break;
}
}
if(!($player instanceof Player) or !isset($gms[strtolower($setgm)])){
$output .= "Usage: /$cmd <mode> [player] or /$cmd [player] <mode>\n";
break;
}
if($player->setGamemode($gms[strtolower($setgm)])){
$output .= "Gamemode of ".$player->username." changed to ".$player->getGamemode()."\n";
}
break;
case "tp":
if(count($params) <= 2 or substr($params[0], 0, 2) === "w:" or substr($params[1], 0, 2) === "w:"){
if((!isset($params[1]) or substr($params[0], 0, 2) === "w:") and isset($params[0]) and ($issuer instanceof Player)){
$name = $issuer->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{
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":
case "suicide":
if(!isset($params[0]) and ($issuer instanceof Player)){
$player = $issuer;
}else{
$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":
$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 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"]);
if(isset($this->server->clients[$CID])){
return $this->server->clients[$CID];
}
return false;
}
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 online(){
$o = array();
foreach($this->server->clients as $p){
if($p->auth === true){
$o[] = $p->username;
}
}
return $o;
}
public function tppos(&$name, &$x, &$y, &$z){
$player = $this->get($name);
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 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);
$player->gamemode = $player->data->get("gamemode");
$this->server->query("INSERT OR REPLACE INTO players (clientID, ip, port, name) VALUES (".$player->clientID.", '".$player->ip."', ".$player->port.", '".$player->username."');");
}
}
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 remove($CID){
if(isset($this->server->clients[$CID])){
$player = $this->server->clients[$CID];
$this->server->clients[$CID] = null;
unset($this->server->clients[$CID]);
$player->close();
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){
$player->entity->player = null;
$player->entity = null;
}
$this->server->api->entity->remove($player->eid);
$player = null;
unset($player);
}
}
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 getOffline($name){
$iname = strtolower($name);
$default = array(
"position" => array(
"x" => $this->server->spawn["x"],
"y" => $this->server->spawn["y"],
"z" => $this->server->spawn["z"],
),
"inventory" => array_fill(0, 36, array(AIR, 0, 0)),
"armor" => array_fill(0, 4, array(AIR, 0, 0)),
"gamemode" => $this->server->gamemode,
"health" => 20,
"lastIP" => "",
"lastID" => 0,
);
$data = new Config(DATA_PATH."players/".$iname.".yml", CONFIG_YAML, $default);
if(!file_exists(DATA_PATH."players/".$iname.".yml")){
console("[NOTICE] Player data not found for \"".$iname."\", creating new profile");
$data->save();
}
if($this->server->gamemode === CREATIVE){
$data->set("health", 20);
}
$this->server->handle("player.offline.get", $data);
return $data;
}
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 saveOffline(Config $data){
$this->server->handle("player.offline.save", $data);
$data->save();
}
public function getByEID($eid){
$eid = (int) $eid;
$CID = $this->server->query("SELECT ip,port FROM players WHERE EID = '".$eid."';", true);
$CID = PocketMinecraftServer::clientID($CID["ip"], $CID["port"]);
if(isset($this->server->clients[$CID])){
return $this->server->clients[$CID];
}
return false;
}
public function online(){
$o = array();
foreach($this->server->clients as $p){
if($p->auth === true){
$o[] = $p->username;
}
}
return $o;
}
public function add($CID){
if(isset($this->server->clients[$CID])){
$player = $this->server->clients[$CID];
$player->data = $this->getOffline($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) and ($player->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,
));
}
}
}
}
public function remove($CID){
if(isset($this->server->clients[$CID])){
$player = $this->server->clients[$CID];
unset($this->server->clients[$CID]);
$player->close();
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){
$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,
"achievements" => array(),
);
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 = new Config(DATA_PATH."players/".$iname.".yml", CONFIG_YAML, $default);
}
if(($data->get("gamemode") & 0x01) === 1){
$data->set("health", 20);
}
$this->server->handle("player.offline.get", $data);
return $data;
}
public function saveOffline(Config $data){
$this->server->handle("player.offline.save", $data);
$data->save();
}
}

View File

@ -1,35 +1,31 @@
<?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;
private $randomNonce;
public function __construct(){
$this->server = ServerAPI::request();
$this->randomNonce = Utils::getRandomBytes(16, false);
}
public function getList(){
@ -39,26 +35,25 @@ class PluginAPI extends stdClass{
}
return $list;
}
public function getInfo($className){
$className = strtolower($className);
if(!isset($this->plugins[$className])){
return false;
}
$plugin = $this->plugins[$className];
return array($plugin[1], get_class_methods($plugin[0]));
public function getAll(){
return $this->plugins;
}
public function load($file){
if(is_link($file) or is_dir($file) or !file_exists($file)){
console("[ERROR] ".basename($file)." is not a file");
return false;
}
if(strtolower(substr($file, -3)) === "pmf"){
$pmf = new PMFPlugin($file);
$info = $pmf->getPluginInfo();
}else{
$content = file_get_contents($file);
$info = strstr($content, "*/", true);
$content = substr(strstr($content, "*/"),2);
$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] [PluginAPI] Failed parsing of ".basename($file));
console("[ERROR] Failed parsing of ".basename($file));
return false;
}
$info = array();
@ -82,54 +77,80 @@ class PluginAPI extends stdClass{
$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"]." #".intval($info["apiversion"])."\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 \"".FORMAT_GREEN.$info["name"].FORMAT_RESET."\" ".FORMAT_AQUA.$info["version"].FORMAT_RESET." by ".FORMAT_AQUA.$info["author"].FORMAT_RESET);
if($info["class"] !== "none" and class_exists($info["class"])){
console("[ERROR] Failed loading plugin: class already exists");
return false;
}
if(eval($info["code"]) === false or !class_exists($info["class"])){
console("[ERROR] [PluginAPI] Failed loading plugin: evaluation error");
if(((!isset($pmf) and (include $file) === false) or (isset($pmf) and eval($info["code"]) === false)) and $info["class"] !== "none" and !class_exists($info["class"])){
console("[ERROR] Failed loading {$info['name']}: evaluation error");
return false;
}
$className = $info["class"];
if(isset($info["apiversion"]) and intval($info["apiversion"]) > CURRENT_API_VERSION){
console("[ERROR] [PluginAPI] Plugin \"".$info["name"]."\" uses a newer API! It can crash or corrupt the server!");
}elseif(!isset($info["apiversion"]) or intval($info["apiversion"]) < CURRENT_API_VERSION){
console("[DEBUG] [PluginAPI] Plugin \"".$info["name"]."\" uses an old API", true, true, 2);
$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, 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();
$identifier = $this->getIdentifier($info["name"], $info["author"]);
if($info["class"] !== "none"){
$object = new $className($this->server->api, false);
if(!($object instanceof Plugin)){
console("[ERROR] Plugin \"".$info["name"]."\" doesn't use the Plugin Interface");
if(method_exists($object, "__destruct")){
$object->__destruct();
}
$object = null;
unset($object);
}else{
$this->plugins[$identifier] = array($object, $info);
}
$object = null;
unset($object);
}else{
$this->plugins[$className] = array($object, $info);
$this->plugins[$identifier] = array(new DummyPlugin($this->server->api, false), $info);
}
return true;
}
public function get(Plugin $plugin){
foreach($this->plugins as &$p){
if($p[0] === $plugin){
return $p;
public function getIdentifier($name, $author){
return sha1(trim(strtolower($name)), true) ^ sha1(trim(strtolower($author)), true) ^ sha1($this->randomNonce, true);
}
public function get($identifier){
if($identifier instanceof Plugin){
foreach($this->plugins as $p){
if($p[0] === $identifier){
return $p;
}
}
return false;
}
if(isset($this->plugins[$identifier])){
return $this->plugins[$identifier];
}
return false;
}
public function pluginsPath(){
$path = join(DIRECTORY_SEPARATOR, array(DATA_PATH."plugins", ""));
@mkdir($path);
return $path;
}
public function configPath(Plugin $plugin){
$p = $this->get($plugin);
$identifier = $this->getIdentifier($p[1]["name"], $p[1]["author"]);
if($p === false){
return false;
}
$path = DATA_PATH."plugins/".$p[1]["name"]."/";
$this->plugins[$p[1]["class"]][1]["path"] = $path;
$path = $this->pluginsPath() . $p[1]["name"] . DIRECTORY_SEPARATOR;
$this->plugins[$identifier][1]["path"] = $path;
@mkdir($path);
return $path;
}
@ -138,9 +159,7 @@ class PluginAPI extends stdClass{
if($p === false){
return false;
}
$path = DATA_PATH."plugins/".$p[1]["name"]."/";
@mkdir($path);
$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;
@ -172,20 +191,20 @@ class PluginAPI extends stdClass{
$this->loadAll();
}
public function loadAll(){
console("[INFO] Loading Plugins...");
$dir = dir(DATA_PATH."plugins/");
private function loadAll(){
$dir = dir($this->pluginsPath());
while(false !== ($file = $dir->read())){
if($file{0} !== "."){
$ext = strtolower(substr($file, -3));
if($ext === "php" or $ext === "pmf"){
$this->load(DATA_PATH."plugins/" . $file);
$this->load($dir->path . $file);
}
}
}
}
public function initAll(){
console("[INFO] Starting plugins...");
foreach($this->plugins as $p){
$p[0]->init(); //ARGHHH!!! Plugin loading randomly fails!!
}
@ -197,4 +216,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,202 +1,200 @@
<?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;
//TODO: Instead of hard-coding functions, use PHPDoc-compatible methods to load APIs.
/**
* @var ConsoleAPI
*/
public $console;
/**
* @var LevelAPI
*/
public $level;
/**
* @var BlockAPI
*/
public $block;
/**
* @var ChatAPI
*/
public $chat;
/**
* @var BanAPI
*/
public $ban;
/**
* @var EntityAPI
*/
public $entity;
/**
* @var TimeAPI
*/
public $time;
/**
* @var PlayerAPI
*/
public $player;
/**
* @var TileAPI
*/
public $tile;
/**
* @return PocketMinecraftServer
*/
public static function request(){
return self::$serverRequest;
}
public function start(){
return $this->run();
}
public function run(){
$this->load();
return $this->init();
}
public function load(){
@mkdir(DATA_PATH."logs/", 0777, true);
@mkdir(DATA_PATH."players/", 0777);
@mkdir(DATA_PATH."worlds/", 0777);
@mkdir(DATA_PATH."plugins/", 0777);
console("[INFO] Starting ServerAPI server handler...");
file_put_contents(DATA_PATH."logs/packets.log", "");
if(!file_exists(DATA_PATH."logs/test.bin.log") or md5_file(DATA_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");
$str = new Java_String("TESTING\x00\n\r\t\xff");
$test .= Utils::writeInt($str->hashCode());
$test .= Utils::writeDataArray(array("a", "b", "c", "\xff\xff\xff\xff"));
$test .= Utils::hexToStr("012334567890");
file_put_contents(DATA_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();
}
}
console("[DEBUG] Loading server.properties...", true, true, 2);
@mkdir(DATA_PATH."players/", 0755);
@mkdir(DATA_PATH."worlds/", 0755);
@mkdir(DATA_PATH."plugins/", 0755);
$version = new VersionString();
console("[INFO] Starting Minecraft PE server version ".FORMAT_AQUA.CURRENT_MINECRAFT_VERSION);
console("[INFO] Loading properties...");
$this->config = new Config(DATA_PATH . "server.properties", CONFIG_PROPERTIES, array(
"server-name" => "Minecraft Server",
"server-name" => "Minecraft: PE Server",
"description" => "Server made using PocketMine-MP",
"motd" => "Welcome @username to this server!",
"invisible" => false,
"server-ip" => "0.0.0.0",
"port" => 19132,
"memory-limit" => "256M",
"motd" => "Welcome @player to this server!",
"server-ip" => "",
"server-port" => 19132,
"server-type" => "normal",
"memory-limit" => "128M",
"last-update" => false,
"white-list" => false,
"debug" => 1,
"announce-player-achievements" => true,
"spawn-protection" => 16,
"view-distance" => 10,
"max-players" => 20,
"server-type" => "normal",
"time-per-second" => 20,
"gamemode" => 1,
"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->getProperty("server-ip"));
self::$serverRequest = $this->server;
$this->setProperty("server-id", $this->server->serverID);
$this->server->api = $this;
$gitsha1 = false;
if(file_exists(FILE_PATH.".git/refs/heads/master")){ //Found Git information!
$gitsha1 = trim(file_get_contents(FILE_PATH.".git/refs/heads/master"));
console("[GIT] Commit \x1b[33m".$gitsha1);
}
$this->parseProperties();
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;
console("[INFO] This server is running PocketMine-MP version ".($version->isDev() ? FORMAT_YELLOW:"").MAJOR_VERSION.FORMAT_RESET." \"".CODENAME."\" (MCPE: ".CURRENT_MINECRAFT_VERSION.") (API ".CURRENT_API_VERSION.")", true, true, 0);
console("[INFO] PocketMine-MP is distibuted under the LGPL License", true, true, 0);
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");
$info = json_decode(Utils::curl_get("http://www.pocketmine.net/latest"), true);
console("[INFO] Last check: ".FORMAT_AQUA.date("Y-m-d H:i:s", $this->getProperty("last-update"))."\x1b[0m");
if($this->server->version->isDev()){
if($info === false or !isset($info["development"])){
console("[ERROR] PocketMine API error");
$info = json_decode(Utils::curl_get("https://api.github.com/repos/PocketMine/PocketMine-MP/commits"), true);
if($info === false or !isset($info[0])){
console("[ERROR] Github API error");
}else{
$last = $info["development"]["date"];
if($last >= $this->getProperty("last-update") and $this->getProperty("last-update") !== false and $gitsha1 != $info["development"]["commit"]){
console("[NOTICE] \x1b[33mA new DEVELOPMENT version of PocketMine-MP has been released");
console("[NOTICE] \x1b[33mVersion \"".$info["development"]["version"]."\" [".substr($info["development"]["commit"], 0, 10)."]");
console("[NOTICE] \x1b[36mIf you want to update, get the latest version at ".$info["development"]["download"]);
$last = new DateTime($info[0]["commit"]["committer"]["date"]);
$last = $last->getTimestamp();
if($last >= $this->getProperty("last-update") and $this->getProperty("last-update") !== false and GIT_COMMIT != $info[0]["sha"]){
console("[NOTICE] ".FORMAT_YELLOW."A new DEVELOPMENT version of PocketMine-MP has been released!");
console("[NOTICE] ".FORMAT_YELLOW."Commit \"".$info[0]["commit"]["message"]."\" [".substr($info[0]["sha"], 0, 10)."] by ".$info[0]["commit"]["committer"]["name"]);
console("[NOTICE] ".FORMAT_YELLOW."Get it at PocketMine.net or at https://github.com/PocketMine/PocketMine-MP/archive/".$info[0]["sha"].".zip");
console("[NOTICE] This message will dissapear after issuing the command \"/update-done\"");
sleep(3);
}else{
$this->setProperty("last-update", time());
console("[INFO] \x1b[36mThis is the latest DEVELOPMENT version");
console("[INFO] ".FORMAT_AQUA."This is the latest DEVELOPMENT version");
}
}
}else{
if($info === false or !isset($info["stable"])){
console("[ERROR] PocketMine API error");
$info = json_decode(Utils::curl_get("https://api.github.com/repos/PocketMine/PocketMine-MP/tags"), true);
if($info === false or !isset($info[0])){
console("[ERROR] Github API error");
}else{
$newest = new VersionString(MAJOR_VERSION);
$newestN = $newest->getNumber();
$update = new VersionString($info["stable"]["version"]);
$update = new VersionString($info[0]["name"]);
$updateN = $update->getNumber();
if($updateN > $newestN){
console("[NOTICE] \x1b[33mA new STABLE version of PocketMine-MP has been released");
console("[NOTICE] \x1b[36mVersion \"".$info["stable"]["version"]."\" #".$updateN);
console("[NOTICE] Download it at ".$info["stable"]["download"]);
console("[NOTICE] ".FORMAT_GREEN."A new STABLE version of PocketMine-MP has been released!");
console("[NOTICE] ".FORMAT_GREEN."Version \"".$info[0]["name"]."\" #".$updateN);
console("[NOTICE] Get it at PocketMine.net or at ".$info[0]["zipball_url"]);
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");
console("[INFO] ".FORMAT_AQUA."This is the latest STABLE version");
}
}
}
}
}
}
if(file_exists(DATA_PATH."worlds/level.dat")){
console("[NOTICE] Detected unimported map data. Importing...");
$this->importMap(DATA_PATH."worlds/", true);
}
$this->server->mapName = $this->getProperty("level-name");
$this->server->mapDir = DATA_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 = DATA_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();
console("[INFO] Loading default APIs");
$this->loadAPI("console", "ConsoleAPI");
$this->loadAPI("level", "LevelAPI");
@ -204,7 +202,7 @@ class ServerAPI{
$this->loadAPI("chat", "ChatAPI");
$this->loadAPI("ban", "BanAPI");
$this->loadAPI("entity", "EntityAPI");
$this->loadAPI("tileentity", "TileEntityAPI");
$this->loadAPI("tile", "TileAPI");
$this->loadAPI("player", "PlayerAPI");
$this->loadAPI("time", "TimeAPI");
@ -215,51 +213,77 @@ class ServerAPI{
}
$this->loadAPI("plugin", "PluginAPI"); //fix :(
$this->plugin->init();
$this->server->loadEntities();
}
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("[INTERNAL] Sending usage data...", true, true, 3);
Utils::curl_post("http://stats.pocketmine.net/usage.php", array(
"serverid" => $this->server->serverID,
"os" => Utils::getOS(),
"version" => MAJOR_VERSION,
"protocol" => CURRENT_PROTOCOL,
"online" => count($this->server->clients),
"max" => $this->server->maxClients,
));
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->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");
}
if(!$this->config->exists("invisible")){
$this->config->set("invisible", false);
$this->setProperty("memory-limit", "128M");
}
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");
@ -286,10 +310,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":
@ -300,26 +323,51 @@ 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(!(self::$serverRequest instanceof PocketMinecraftServer)){
self::$serverRequest = $this->server;
}
if($this->getProperty("send-usage") !== false){
$this->server->schedule(36000, array($this, "sendUsage"), array(), true); //Send usage data every 30 minutes
$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);
}
@ -332,10 +380,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);
}
@ -351,56 +395,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"));
if($level["LevelName"] == ""){
$level["LevelName"] = "world".time();
}
console("[DEBUG] Importing map \"".$level["LevelName"]."\" gamemode ".$level["GameType"]." with seed ".$level["RandomSeed"], true, true, 2);
unset($level["Player"]);
$lvName = $level["LevelName"]."/";
@mkdir(DATA_PATH."worlds/".$lvName, 0777);
file_put_contents(DATA_PATH."worlds/".$lvName."level.dat", serialize($level));
$entities = parseNBTData($nbt->loadFile($dir."entities.dat"));
file_put_contents(DATA_PATH."worlds/".$lvName."entities.dat", serialize($entities["Entities"]));
if(!isset($entities["TileEntities"])){
$entities["TileEntities"] = array();
}
file_put_contents(DATA_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", DATA_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", DATA_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":
@ -424,7 +424,7 @@ class ServerAPI{
break;
case "gamemode":
case "max-players":
case "port":
case "server-port":
case "debug":
case "difficulty":
case "time-per-second":
@ -438,7 +438,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){
@ -455,7 +455,9 @@ class ServerAPI{
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";
@ -464,10 +466,12 @@ class ServerAPI{
return false;
}
require_once($file);
}else{
$internal = true;
}
$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,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 TileEntityAPI{
private $server;
function __construct(PocketMinecraftServer $server){
$this->server = $server;
}
public function get($x, $y = false, $z = false){
if(($x instanceof Vector3) or ($x instanceof Block)){
$z = (int) $x->z;
$y = (int) $x->y;
$x = (int) $x->x;
}else{
$x = (int) $x;
$y = (int) $y;
$z = (int) $z;
}
$tiles = $this->server->query("SELECT * FROM tileentities WHERE x = $x AND y = $y AND z = $z;");
$ret = array();
if($tiles !== false and $tiles !== true){
while(($t = $tiles->fetchArray(SQLITE3_ASSOC)) !== false){
if(($tile = $this->getByID($t["ID"])) !== false){
if($tile->normal === true){
$ret[] = $tile;
}
}
}
}
if(count($ret) === 0){
return false;
}
return $ret;
}
public function getByID($id){
if($id instanceof TileEntity){
return $id;
}elseif(isset($this->server->tileEntities[$id])){
return $this->server->tileEntities[$id];
}
return false;
}
public function init(){
}
public function getAll(){
return $this->server->tileEntities;
}
public function add($class, $x, $y, $z, $data = array()){
$id = $this->tCnt++;
$this->server->tileEntities[$id] = new TileEntity($this->server, $id, $class, $x, $y, $z, $data);
$this->spawnToAll($id);
return $this->server->tileEntities[$id];
}
public function addSign($x, $y, $z, $lines = array("", "", "", "")){
return $this->add(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 spawnTo($id, $player, $queue = false){
$t = $this->getByID($id);
if($t === false){
return false;
}
$t->spawn($player, $queue);
}
public function spawnToAll($id){
$t = $this->getByID($id);
if($t === false){
return false;
}
foreach($this->server->api->player->getAll() as $player){
if($player->eid !== false){
$t->spawn($player);
}
}
}
public function spawnAll($player){
foreach($this->getAll() as $t){
$t->spawn($player);
}
}
public function remove($id){
if(isset($this->server->tileEntities[$id])){
$t = $this->server->tileEntities[$id];
$this->server->tileEntities[$id] = null;
unset($this->server->tileEntities[$id]);
$t->closed = true;
$t->close();
$this->server->query("DELETE FROM tileentities WHERE ID = ".$id.";");
$t = null;
unset($t);
}
}
}

View File

@ -1,75 +1,67 @@
<?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{
var $phases = array(
public static $phases = array(
"day" => 0,
"sunset" => 9500,
"night" => 10900,
"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, $issuer, $alias){
$output = "";
switch($cmd){
case "time":
$level = false;
if($issuer instanceof Player){
$level = $issuer->level;
}
$p = strtolower(array_shift($params));
switch($p){
case "check":
$output .= "Time: ".$this->getDate().", ".$this->getPhase()." (".$this->get(true).")\n";
$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:
$output .= "Usage: /time <check | set | add | sunrise | day | sunset | night> [time]\n";
$output .= "Usage: /time <check|set|add> [time]\n";
break;
}
break;
@ -78,38 +70,44 @@ class TimeAPI{
}
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;
if($time < $this->phase["sunset"]){
$time = !is_integer($time) ? $this->get(false, $time):$time;
if($time < TimeAPI::$phases["sunset"]){
$time = "day";
}elseif($time < $this->phase["night"]){
}elseif($time < TimeAPI::$phases["night"]){
$time = "sunset";
}elseif($time < $this->phase["sunrise"]){
}elseif($time < TimeAPI::$phases["sunrise"]){
$time = "night";
}else{
$time = "sunrise";
@ -117,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(TimeAPI::$phases[$time])){
$level->setTime(TimeAPI::$phases[$time]);
}else{
$level->setTime((int) $time);
}
return $level->getTime();
}
}
}

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,262 +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,
63 => true,
64 => true,
65 => true,
67 => true,
68 => true,
71 => true,
78 => true,
79 => true,
83 => true,
85 => true,
89 => true,
96 => true,
102 => true,
105 => true,
107 => true,
108 => true,
109 => true,
114 => true,
128 => true,
156 => 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,
245 => 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,
109 => true,
112 => true,
114 => true,
128 => true,
155 => true,
156 => true,
245 => true,
246 => true,
247 => true,
323 => true, //Special case of signs
338 => 83,
);
static $blocks = array(
0 => "Air",
1 => "Stone",
2 => "Grass",
3 => "Dirt",
4 => "Cobblestone",
5 => "Wooden Planks",
6 => "Sapling",
7 => "Bedrock",
);
}

View File

@ -1,33 +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 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",

File diff suppressed because it is too large Load Diff

View File

@ -1,63 +1,53 @@
<?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 PocketMinecraftServer{
public $tCnt;
public $version, $invisible, $api, $tickMeasure, $preparedSQL, $seed, $gamemode, $name, $maxClients, $clients, $eidCnt, $custom, $description, $motd, $timePerSecond, $spawn, $entities, $mapDir, $mapName, $map, $levelData, $tileEntities;
private $serverip, $database, $interface, $evCnt, $handCnt, $events, $eventsID, $handlers, $serverType, $lastTick, $ticker;
public $serverID, $interface, $database, $version, $invisible, $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;
/**
* @var ServerAPI
*/
public $api;
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->serverip.":".$this->port);
if($this->port < 19132 or $this->port > 19135){ //Mojang =(
console("[WARNING] You've selected a not-standard port. Normal port range is from 19132 to 19135 included");
}
/*if(defined("DEBUG") and DEBUG >= 0){
@cli_set_process_title("PocketMine-MP ".MAJOR_VERSION);
}*/
console("[INFO] Starting Minecraft PE server on ".($this->serverip === "0.0.0.0" ? "*":$this->serverip).":".$this->port);
define("BOOTUP_RANDOM", Utils::getRandomBytes(16));
$this->serverID = $this->serverID === false ? Utils::readLong(Utils::getRandomBytes(8, false)):$this->serverID;
$this->seed = $this->seed === false ? Utils::readInt(Utils::getRandomBytes(4, false)):$this->seed;
console("[INFO] Loading database...");
$this->startDatabase();
$this->doTick = false;
$this->api = false;
$this->tCnt = 1;
$this->mapDir = false;
$this->mapName = false;
$this->events = array();
$this->eventsID = array();
$this->handlers = array();
$this->map = false;
$this->invisible = false;
$this->levelData = false;
$this->difficulty = 1;
$this->tileEntities = array();
$this->tiles = array();
$this->entities = array();
$this->custom = array();
$this->evCnt = 1;
@ -68,76 +58,99 @@ class PocketMinecraftServer{
$this->scheduleCnt = 1;
$this->description = "";
$this->whitelist = false;
$this->memoryStats = array();
$this->clients = array();
$this->spawn = array("x" => 128.5,"y" => 100,"z" => 128.5);
$this->time = 0;
$this->timePerSecond = 10;
$this->spawn = false;
$this->saveEnabled = true;
$this->tickMeasure = array_fill(0, 40, 0);
$this->setType("normal");
$this->interface = new MinecraftInterface("255.255.255.255", $this->port, true, false);
$this->interface = new MinecraftInterface($this, "255.255.255.255", $this->port, true, false, $this->serverip);
$this->reloadConfig();
console("[INFO] Server Name: \x1b[36m".$this->name."\x1b[0m");
console("[DEBUG] Server ID: ".$this->serverID, true, true, 2);
$this->stop = false;
$this->ticks = 0;
if(!defined("NO_THREADS")){
$this->asyncThread = new AsyncMultipleQueue();
}
}
function __construct($name, $gamemode = CREATIVE, $seed = false, $port = 19132, $serverID = false, $serverip = "0.0.0.0"){
$this->port = (int) $port; //19132 - 19135
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 = $serverID;
$this->serverID = false;
$this->seed = $seed;
$this->serverip = $serverip;
$this->load();
}
public function getTPS(){
/**
* @return float
*/
public function getTPS(){
$v = array_values($this->tickMeasure);
$tps = 40 / ($v[39] - $v[0]);
return round($tps, 4);
}
public function titleTick(){
if(ENABLE_ANSI === true){
echo "\x1b]0;PocketMine-MP ".MAJOR_VERSION." | Online ". count($this->clients)." | RAM ".round((memory_get_usage(true) / 1024) / 1024, 2)."MB | TPS ".$this->getTPS()."\x07";
$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->action(1500000, '$this->titleTick();');
$this->schedule(30, array($this, "titleTick"), array(), true);
}
$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 * 15, 'if($this->getTPS() < 15){console("[WARNING] Can\'t keep up! Is the server overloaded?");}');
$this->action(1000000 * 60 * 10, '$this->custom = array();');
if($this->api instanceof ServerAPI){
$this->action(1000000 * 80, '$cnt = count($this->clients); if($cnt > 1){$this->api->chat->broadcast("Online (".$cnt."): ".implode(", ",$this->api->player->online()));}');
$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 (clientID INTEGER PRIMARY KEY, EID NUMERIC, ip TEXT, port NUMERIC, name TEXT UNIQUE COLLATE NOCASE);");
$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 tileentities (ID INTEGER PRIMARY KEY, class TEXT, x NUMERIC, y NUMERIC, z NUMERIC, spawnable NUMERIC);");
$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("PRAGMA synchronous = OFF;");
$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->updateActions = $this->database->prepare("UPDATE actions SET last = :time 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){
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)){
if($fetch === true and ($result instanceof SQLite3Result)){
$result = $result->fetchArray(SQLITE3_ASSOC);
}
return $result;
@ -150,10 +163,12 @@ class PocketMinecraftServer{
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["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"];
@ -167,31 +182,33 @@ class PocketMinecraftServer{
return $info;
}
public function close($reason = "stop"){
/**
* @param string $reason
*/
public function close($reason = "server stop"){
if($this->stop !== true){
if(is_int($reason)){
$reason = "signal stop";
}
if(($this->api instanceof ServerAPI) === true){
if(($this->api->chat instanceof ChatAPI) === true){
$this->api->chat->send(false, "Stopping server...");
$this->api->chat->broadcast("Stopping server...");
}
}
//$this->ticker->stop = true;
$this->save(true);
$this->stop = true;
$this->trigger("server.close", $reason);
$this->interface->close();
if(!defined("NO_THREADS")){
@$this->asyncThread->stop = true;
}
}
}
public function chat($owner, $text, $target = false){
$this->api->chat->send($owner, $text, $target);
}
public function setType($type = "normal"){
switch($type){
switch(trim(strtolower($type))){
case "normal":
case "demo":
$this->serverType = "MCCPP;Demo;";
break;
case "minecon":
@ -200,8 +217,74 @@ class PocketMinecraftServer{
}
}
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){
/**
* @param string $event
* @param callable $callable
* @param integer $priority
*
* @return boolean
*/
public function addHandler($event,callable $callable, $priority = 5){
if(!is_callable($callable)){
return false;
}elseif(isset(Deprecation::$events[$event])){
@ -218,6 +301,10 @@ class PocketMinecraftServer{
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();
@ -225,8 +312,7 @@ class PocketMinecraftServer{
$this->preparedSQL->selectHandlers->bindValue(":name", $event, SQLITE3_TEXT);
$handlers = $this->preparedSQL->selectHandlers->execute();
$result = null;
if($handlers !== false and $handlers !== true){
console("[INTERNAL] Handling ".$event, true, true, 3);
if($handlers instanceof SQLite3Result){
$call = array();
while(($hn = $handlers->fetchArray(SQLITE3_ASSOC)) !== false){
$call[(int) $hn["ID"]] = true;
@ -266,46 +352,10 @@ class PocketMinecraftServer{
}
}
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->getGamemode()."\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->getGamemode()."\x1b[0m");
}
}
public function getGamemode(){
/**
* @return string
*/
public function getGamemode(){
switch($this->gamemode){
case SURVIVAL:
return "survival";
@ -313,142 +363,57 @@ class PocketMinecraftServer{
return "creative";
case ADVENTURE:
return "adventure";
case VIEW:
return "view";
}
}
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],
));
}elseif($entity["id"] === OBJECT_PAINTING){ //Painting
$e = $this->api->entity->add(ENTITY_OBJECT, $entity["id"], $entity);
$e->setPosition($entity["Pos"][0], $entity["Pos"][1], $entity["Pos"][2], $entity["Rotation"][0], $entity["Rotation"][1]);
$e->setHealth($entity["Health"]);
}else{
$e = $this->api->entity->add(ENTITY_MOB, $entity["id"], $entity);
$e->setPosition($entity["Pos"][0], $entity["Pos"][1], $entity["Pos"][2], $entity["Rotation"][0], $entity["Rotation"][1]);
$e->setHealth($entity["Health"]);
}
}
}
$tiles = unserialize(file_get_contents($this->mapDir."tileEntities.dat"));
foreach($tiles as $tile){
if(!isset($tile["id"])){
break;
}
$t = $this->api->tileentity->add($tile["id"], $tile["x"], $tile["y"], $tile["z"], $tile);
}
$this->action(1000000 * 60 * 25, '$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);
$this->trigger("server.save", $final);
console("[INFO] Saving entities...");
if(count($this->entities) > 0){
$entities = array();
foreach($this->entities as $entity){
if($entity->class === ENTITY_MOB){
$entities[] = array(
"id" => $entity->type,
"Color" => @$entity->data["Color"],
"Sheared" => @$entity->data["Sheared"],
"Health" => $entity->health,
"Pos" => array(
0 => $entity->x,
1 => $entity->y,
2 => $entity->z,
),
"Rotation" => array(
0 => $entity->yaw,
1 => $entity->pitch,
),
);
}elseif($entity->class === ENTITY_OBJECT){
$entities[] = array(
"id" => $entity->type,
"TileX" => $entity->x,
"TileX" => $entity->y,
"TileX" => $entity->z,
"Health" => $entity->health,
"Motive" => $entity->data["Motive"],
"Pos" => array(
0 => $entity->x,
1 => $entity->y,
2 => $entity->z,
),
"Rotation" => array(
0 => $entity->yaw,
1 => $entity->pitch,
),
);
}elseif($entity->class === ENTITY_ITEM){
$entities[] = array(
"id" => 64,
"Item" => array(
"id" => $entity->type,
"Damage" => $entity->meta,
"Count" => $entity->stack,
),
"Health" => $entity->health,
"Pos" => array(
0 => $entity->x,
1 => $entity->y,
2 => $entity->z,
),
"Rotation" => array(
0 => 0,
1 => 0,
),
);
}
}
file_put_contents($this->mapDir."entities.dat", serialize($entities));
}
if(count($this->tileEntities) > 0){
$tiles = array();
foreach($this->tileEntities as $tile){
$tiles[] = $tile->data;
}
file_put_contents($this->mapDir."tileEntities.dat", serialize($tiles));
}
}
}
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);
public function init(){
register_tick_function(array($this, "tick"));
console("[DEBUG] Starting internal ticker calculation", true, true, 2);
$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")){
@ -456,24 +421,30 @@ class PocketMinecraftServer{
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] Server started!");
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 = "# PocketMine-MP Error Dump ".date("D M j H:i:s T Y")."\r\n";
$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);
$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 .= "[".($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 .= "PocketMine-MP version: ".$version." #".$version->getNumber()." [Protocol ".CURRENT_PROTOCOL."; API ".CURRENT_API_VERSION."]\r\n";
$dump .= "Git commit: ".GIT_COMMIT."\r\n";
$dump .= "Source SHA1 sum: ".SOURCE_SHA1SUM."\r\n";
$dump .= "uname -a: ".php_uname("a")."\r\n";
$dump .= "PHP Version: " .phpversion()."\r\n";
$dump .= "Zend version: ".zend_version()."\r\n";
@ -481,68 +452,67 @@ class PocketMinecraftServer{
$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";
if($this->api->plugin instanceof PluginAPI){
$dump .= "Loaded plugins: ".var_export($this->api->plugin->getList(), true)."\r\n\r\n\r\n";
$p = $this->api->getProperties();
if($p["rcon.password"] != ""){
$p["rcon.password"] = "******";
}
$dump .= "Loaded Modules: ".var_export(get_loaded_extensions(), true)."\r\n\r\n";
$name = "error_dump_".time();
$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 \"logs/{$name}.log\" file to the Bug Reporting page. Give as much info as you can.", true, true, 0);
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(){
/*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;
unset($this->tickMeasure[key($this->tickMeasure)]);
++$this->ticks;
$this->tickerFunction($time);
$this->trigger("server.tick", $time);
}
}
public function clientID($ip, $port){
return md5($ip . $port, true);
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 = $this->clientID($packet["ip"], $packet["port"]);
$CID = PocketMinecraftServer::clientID($packet["ip"], $packet["port"]);
if(isset($this->clients[$CID])){
$this->clients[$CID]->handle($packet["pid"], $data);
$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,
MAGIC,
RAKNET_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;
}
@ -555,42 +525,24 @@ class PocketMinecraftServer{
$this->send(0x1c, array(
$data[0],
$this->serverID,
MAGIC,
$this->serverType. $this->name . " [".($this->gamemode === CREATIVE ? "C":($this->gamemode === ADVENTURE ? "A":"S")).($this->whitelist !== false ? "W":"")." ".count($this->clients)."/".$this->maxClients."] ".$txt,
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:
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_STRUCTURE){
console("[DEBUG] Incorrect structure #$version from ".$packet["ip"].":".$packet["port"], true, true, 2);
$this->send(0x1a, array(
CURRENT_STRUCTURE,
MAGIC,
RAKNET_MAGIC,
$this->serverID,
), false, $packet["ip"], $packet["port"]);
}else{
$this->send(0x06, array(
MAGIC,
RAKNET_MAGIC,
$this->serverID,
0,
strlen($packet["raw"]),
@ -598,45 +550,49 @@ class PocketMinecraftServer{
}
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"]);
if($this->invisible === true){
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);
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){
$this->interface->writePacket($pid, $data, $raw, $dest, $port);
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{
usleep(1);
++$lastLoop;
if($lastLoop < 16){
usleep(1);
}elseif($lastLoop < 128){
usleep(100);
}elseif($lastLoop < 256){
usleep(512);
}else{
usleep(10000);
}
}
}
}
@ -664,46 +620,44 @@ class PocketMinecraftServer{
}
}
public function schedule($ticks,callable $callback, $data = array(), $repeat = false, $eventName = "server.schedule"){
public function schedule($ticks, callable $callback, $data = array(), $repeat = false, $eventName = "server.schedule"){
if(!is_callable($callback)){
return false;
}
$add = "";
$chcnt = $this->scheduleCnt++;
if($repeat === false){
$add = '$this->schedule['.$chcnt.']=null;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])){$this->schedule['.$chcnt.']=null;unset($this->schedule['.$chcnt.']);return false;}return call_user_func($schedule[0],$schedule[1],$schedule[2]);', (bool) $repeat);
$this->query("INSERT INTO actions (ID, interval, last, repeat) VALUES(".$chcnt.", ".($ticks / 20).", ".microtime(true).", ".(((bool) $repeat) === true ? 1:0).");");
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"].";");
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();
}
$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,callable $func){

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

@ -0,0 +1,284 @@
#!/bin/bash
COMPILER_VERSION="0.14"
PHP_VERSION="5.5.8"
ZEND_VM="GOTO"
LIBEDIT_VERSION="0.3"
ZLIB_VERSION="1.2.8"
PTHREADS_VERSION="0.0.45"
CURL_VERSION="curl-7_34_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"
if [ $(uname -m) == "x86_64" ]; then
CFLAGS="-mx32 $CFLAGS"
fi
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"
CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-opcache=no"
fi
./configure $OPTIMIZATION--prefix="$DIR/php5" \
--exec-prefix="$DIR/php5" \
--with-curl="$HAVE_CURL" \
--with-zlib="$DIR/install_data/php/ext/zlib" \
--with-zlib-dir="$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-debug \
--disable-phar \
--disable-pdo \
--without-pear \
--without-iconv \
--without-pdo-sqlite \
--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 \
--enable-zip \
--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 work, please send the \"install.log\" file to the Bug Tracker."

View File

@ -1,37 +1,54 @@
<?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/
*
*
*/
set_time_limit(0);
date_default_timezone_set(@date_default_timezone_get());
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(substr($date[0], 2, 1), trim($date[0])));
$offset = round((mktime($i[0], $i[1], 0, $j[1], $j[0], $j[2]) - $time) / 60) * 60;
}else{
exec("date +%s", $t);
$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);
error_reporting(E_ALL | E_STRICT);
ini_set("allow_url_fopen", 1);
ini_set("display_errors", 1);
ini_set('default_charset', 'utf-8');
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{
@ -39,13 +56,17 @@ if(defined("POCKETMINE_COMPILE") and POCKETMINE_COMPILE === true){
}
set_include_path(get_include_path() . PATH_SEPARATOR . FILE_PATH);
ini_set("memory_limit", "256M"); //Default
ini_set("memory_limit", "128M"); //Default
define("LOG", true);
define("MAGIC", "\x00\xff\xff\x00\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\x12\x34\x56\x78");
define("TEST_MD5", "ffe889db5932db1e3371d48773590e59");
define("MAJOR_VERSION", "Alpha_1.2.2");
define("CURRENT_STRUCTURE", 5);
define("CURRENT_PROTOCOL", 9);
define("CURRENT_MINECRAFT_VERSION", "v0.6.1 alpha");
define("CURRENT_API_VERSION", 5);
define("CURRENT_PHP_VERSION", "5.4.13");
define("START_TIME", microtime(true));
define("MAJOR_VERSION", "Alpha_1.3.11");
define("CODENAME", "甘いビートルート");
define("CURRENT_MINECRAFT_VERSION", "v0.8.1 alpha");
define("CURRENT_API_VERSION", 11);
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));
}

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/
*
*
*/
define("AIR", 0);
@ -34,6 +28,7 @@ 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);
@ -50,7 +45,7 @@ define("WOOD", 17);
define("TRUNK", 17);
define("LEAVES", 18);
define("LEAVE", 18);
define("SPONGE", 19);
define("GLASS", 20);
define("LAPIS_ORE", 21);
define("LAPIS_BLOCK", 22);
@ -88,6 +83,8 @@ define("FIRE", 51);
define("WOOD_STAIRS", 53);
define("WOODEN_STAIRS", 53);
define("OAK_WOOD_STAIRS", 53);
define("OAK_WOODEN_STAIRS", 53);
define("CHEST", 54);
define("DIAMOND_ORE", 56);
@ -121,23 +118,32 @@ 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("PUMPKIN", 86);
define("NETHERRACK", 87);
define("SOUL_SAND", 88);
define("GLOWSTONE", 89);
define("GLOWSTONE_BLOCK", 89);
define("LIT_PUMPKIN", 91);
define("JACK_O_LANTERN", 91);
define("CAKE_BLOCK", 92);
define("TRAPDOOR", 96);
define("STONE_BRICKS", 98);
define("STONE_BRICK", 98);
define("IRON_BAR", 101);
define("IRON_BARS", 101);
define("GLASS_PANE", 102);
define("GLASS_PANEL", 102);
define("MELON_BLOCK", 103);
define("PUMPKIN_STEM", 104);
define("MELON_STEM", 105);
define("FENCE_GATE", 107);
@ -145,14 +151,43 @@ 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("SPRUCE_WOOD_STAIRS", 134);
define("SPRUCE_WOODEN_STAIRS", 134);
define("BIRCH_WOOD_STAIRS", 135);
define("BIRCH_WOODEN_STAIRS", 135);
define("JUNGLE_WOOD_STAIRS", 136);
define("JUNGLE_WOODEN_STAIRS", 136);
define("COBBLE_WALL", 139);
define("STONE_WALL", 139);
define("COBBLESTONE_WALL", 139);
define("CARROT_BLOCK", 141);
define("POTATO_BLOCK", 142);
define("QUARTZ_BLOCK", 155);
define("QUARTZ_STAIRS", 156);
define("DOUBLE_WOOD_SLAB", 157);
define("DOUBLE_WOODEN_SLAB", 157);
define("DOUBLE_WOOD_SLABS", 157);
define("DOUBLE_WOODEN_SLABS", 157);
define("WOOD_SLAB", 158);
define("WOODEN_SLAB", 158);
define("WOOD_SLABS", 158);
define("WOODEN_SLABS", 158);
define("HAY_BALE", 170);
define("CARPET", 171);
define("COAL_BLOCK", 173);
define("BEETROOT_BLOCK", 244);
define("STONECUTTER", 245);
define("GLOWING_OBSIDIAN", 246);
define("NETHER_REACTOR", 247);

View File

@ -1,31 +1,80 @@
<?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/
*
*
*/
define("PMF_LEVEL_DEFLATE_LEVEL", 6);
//Gamemodes
define("SURVIVAL", 0);
define("CREATIVE", 1);
define("ADVENTURE", 2);
define("ADVENTURE", 2);
define("VIEW", 3);
define("VIEWER", 3);
//Players
define("MAX_CHUNK_RATE", 20 / arg("max-chunks-per-second", 4)); //Default rate ~256 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_PRIMEDTNT", 65);
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);

View File

@ -1,34 +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/
*
*
*/
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);
@ -37,10 +32,10 @@ define("DIAMOND", 264);//Implemented
define("IRON_INGOT", 265);//Implemented
define("GOLD_INGOT", 266);//Implemented
define("IRON_SWORD", 267);
define("WOODEN_SWORD", 268);
define("WOODEN_SHOVEL", 269);
define("WOODEN_PICKAXE", 270);
define("WOODEN_AXE", 271);
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);
@ -50,12 +45,17 @@ 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);
@ -64,6 +64,7 @@ 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);
@ -74,19 +75,19 @@ define("LEATHER_PANTS", 300);
define("LEATHER_BOOTS", 301);
define("CHAIN_HELMET", 302);
define("CHAIN_CHESTPLATE", 303);
define("CHAIN_LEGGINS", 304);
define("CHAIN_LEGGINGS", 304);
define("CHAIN_BOOTS", 305);
define("IRON_HELMET", 306);
define("IRON_CHESTPLATE", 307);
define("IRON_LEGGINS", 308);
define("IRON_LEGGINGS", 308);
define("IRON_BOOTS", 309);
define("DIAMOND_HELMET", 310);
define("DIAMOND_CHESTPLATE", 311);
define("DIAMOND_LEGGINS", 312);
define("DIAMOND_LEGGINGS", 312);
define("DIAMOND_BOOTS", 313);
define("GOLD_HELMET", 314);
define("GOLD_CHESTPLATE", 315);
define("GOLD_LEGGINS", 316);
define("GOLD_LEGGINGS", 316);
define("GOLD_BOOTS", 317);
define("FLINT", 318);
define("RAW_PORKCHOP", 319);
@ -95,9 +96,13 @@ define("PAINTING", 321);
define("GOLDEN_APPLE", 322);
define("SIGN", 323);
define("WOODEN_DOOR", 324);
define("BUCKET", 325);
define("MINECART", 329);
define("IRON_DOOR", 330);
define("REDSTONE", 331);
define("REDSTONE_DUST", 331);
define("SNOWBALL", 332);
define("LEATHER", 334);
@ -113,23 +118,24 @@ define("SLIMEBALL", 341);
define("EGG", 344);
define("COMPASS", 345);
define("CLOCK", 347);
define("GLOWSTONE_DUST", 348);
define("RAW_FISH", 349);
define("COOKED_FISH", 350);
//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("COOKIE", 357);
define("SHEARS", 359);
define("MELON", 360);
define("MELON_SLICE", 360);
define("PUMPKIN_SEEDS", 361);
define("MELON_SEEDS", 362);
define("RAW_BEEF", 363);
define("STEAK", 364);
@ -138,8 +144,23 @@ define("COOKED_BEEF", 364);
define("RAW_CHICKEN", 365);
define("COOKED_CHICKEN", 366);
define("SPAWN_EGG", 383);
define("CARROT", 391);
define("CARROTS", 391);
define("POTATO", 392);
define("POTATOES", 392);//@shoghicp Why the heck do we need plural redundant Item ID here????
define("BAKED_POTATO", 393);
define("BAKED_POTATOES", 393);
define("PUMPKIN_PIE", 400);
define("NETHER_BRICK", 405);
define("QUARTZ", 406);
define("NETHER_QUARTZ", 406);
define("CAMERA", 456);
define("CAMERA", 456);
define("BEETROOT", 457);
define("BEETROOT_SEEDS", 458);
define("BEETROOT_SEED", 458);
define("BEETROOT_SOUP", 459);

View File

@ -1,346 +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("MC_KEEP_ALIVE", 0x00);
define("MC_CLIENT_CONNECT", 0x09);
define("MC_SERVER_HANDSHAKE", 0x10);
define("MC_CLIENT_HANDSHAKE", 0x13);
define("MC_DISCONNECT", 0x15);
define("MC_LOGIN", 0x82);
define("MC_LOGIN_STATUS", 0x83);
define("MC_READY", 0x84);
define("MC_CHAT", 0x85);
define("MC_SET_TIME", 0x86);
define("MC_START_GAME", 0x87);
define("MC_ADD_MOB", 0x88);
define("MC_ADD_PLAYER", 0x89);
//define("MC_REMOVE_PLAYER", 0x8a);
define("MC_ADD_ENTITY", 0x8c);
define("MC_REMOVE_ENTITY", 0x8d);
define("MC_ADD_ITEM_ENTITY", 0x8e);
define("MC_TAKE_ITEM_ENTITY", 0x8f);
define("MC_MOVE_ENTITY", 0x90);
define("MC_MOVE_ENTITY_POSROT", 0x93);
define("MC_MOVE_PLAYER", 0x94);
define("MC_PLACE_BLOCK", 0x95);
define("MC_REMOVE_BLOCK", 0x96);
define("MC_UPDATE_BLOCK", 0x97);
define("MC_ADD_PAINTING", 0x98);
define("MC_EXPLOSION", 0x99);
define("MC_LEVEL_EVENT", 0x9a);
//define("MC_TILE_EVENT", 0x9b);
define("MC_ENTITY_EVENT", 0x9c);
define("MC_REQUEST_CHUNK", 0x9d);
define("MC_CHUNK_DATA", 0x9e);
define("MC_PLAYER_EQUIPMENT", 0x9f);
define("MC_PLAYER_ARMOR_EQUIPMENT", 0xa0);
define("MC_INTERACT", 0xa1);
define("MC_USE_ITEM", 0xa2);
define("MC_PLAYER_ACTION", 0xa3);
define("MC_HURT_ARMOR", 0xa5);
define("MC_SET_ENTITY_DATA", 0xa6);
define("MC_SET_ENTITY_MOTION", 0xa7);
define("MC_SET_HEALTH", 0xa8);
define("MC_SET_SPAWN_POSITION", 0xa9);
define("MC_ANIMATE", 0xaa);
define("MC_RESPAWN", 0xab);
define("MC_SEND_INVENTORY", 0xac);
define("MC_DROP_ITEM", 0xad);
define("MC_CONTAINER_OPEN", 0xae);
define("MC_CONTAINER_CLOSE", 0xaf);
define("MC_CONTAINER_SET_SLOT", 0xb0);
//define("MC_CONTAINER_SET_DATA", 0xb1);
//define("MC_CONTAINER_SET_CONTENT", 0xb2);
//define("MC_CONTAINER_ACK", 0xb3);
define("MC_CLIENT_MESSAGE", 0xb4);
define("MC_SIGN_UPDATE", 0xb5);
define("MC_ADVENTURE_SETTINGS", 0xb6);
class Protocol{
public static $dataName = array(
MC_KEEP_ALIVE => "Keep Alive",
MC_CLIENT_CONNECT => "Client Connect",
MC_SERVER_HANDSHAKE => "Server Handshake",
MC_CLIENT_HANDSHAKE => "Client Handshake",
MC_DISCONNECT => "Disconnect",
0x18 => "Unknown",
MC_LOGIN => "Login",
MC_LOGIN_STATUS => "Login Status",
MC_READY => "Ready",
MC_CHAT => "Chat",
MC_SET_TIME => "Set Time",
MC_START_GAME => "Start Game",
MC_ADD_MOB => "Add Mob",
MC_ADD_PLAYER => "Add Player",
MC_ADD_ENTITY => "Add Entity",
MC_REMOVE_ENTITY => "Remove Entity",
MC_ADD_ITEM_ENTITY => "Add Item",
MC_TAKE_ITEM_ENTITY => "Take Item",
MC_MOVE_ENTITY => "Move Entity",
MC_MOVE_ENTITY_POSROT => "Move Entity PosRot",
MC_MOVE_PLAYER => "Move Player",
MC_PLACE_BLOCK => "Place Block",
MC_REMOVE_BLOCK => "Remove Block",
MC_UPDATE_BLOCK => "Update Block",
MC_ADD_PAINTING => "Add Painting",
MC_EXPLOSION => "Explosion",
MC_LEVEL_EVENT => "Level Event",
MC_ENTITY_EVENT => "Entity Event",
MC_REQUEST_CHUNK => "Chunk Request",
MC_CHUNK_DATA => "Chunk Data",
MC_PLAYER_EQUIPMENT => "Player Equipment",
MC_PLAYER_ARMOR_EQUIPMENT => "Player Armor",
MC_INTERACT => "Interact",
MC_USE_ITEM => "Use Item",
MC_PLAYER_ACTION => "Player Action",
MC_SET_ENTITY_DATA => "Entity Data",
MC_SET_ENTITY_MOTION => "Entity Motion",
MC_HURT_ARMOR => "Hurt Armor",
MC_SET_HEALTH => "Set Health",
MC_SET_SPAWN_POSITION => "Set Spawn Position",
MC_ANIMATE => "Animate",
MC_RESPAWN => "Respawn",
MC_SEND_INVENTORY => "Send Inventory",
MC_DROP_ITEM => "Drop Item",
MC_CONTAINER_OPEN => "Open Container",
MC_CONTAINER_CLOSE => "Close Container",
MC_CONTAINER_SET_SLOT => "Set Container Slot",
MC_CLIENT_MESSAGE => "Client Message",
MC_SIGN_UPDATE => "Sign Update",
MC_ADVENTURE_SETTINGS => "Adventure Settings",
);
public static $packetName = array(
0x02 => "ID_UNCONNECTED_PING_OPEN_CONNECTIONS", //RakNet
0x05 => "ID_OPEN_CONNECTION_REQUEST_1", //RakNet
0x06 => "ID_OPEN_CONNECTION_REPLY_1", //RakNet
0x07 => "ID_OPEN_CONNECTION_REQUEST_2", //RakNet
0x08 => "ID_OPEN_CONNECTION_REPLY_2", //RakNet
0x1a => "ID_INCOMPATIBLE_PROTOCOL_VERSION", //RakNet
0x1c => "ID_UNCONNECTED_PONG", //RakNet
0x1d => "ID_ADVERTISE_SYSTEM", //RakNet
0x80 => "Custom Packet", //Minecraft Implementation
0x84 => "Custom Packet", //Minecraft Implementation
0x88 => "Custom Packet", //Minecraft Implementation
0x8c => "Custom Packet", //Minecraft Implementation
0xa0 => "NACK", //Minecraft Implementation
0xc0 => "ACK", //Minecraft Implementation
);
public static $raknet = array(
0x02 => array(
"long", //Ping ID
"magic",
),
0x05 => array(
"magic",
"byte", //Protocol Version
"special1", //MTU Size Null Lenght
),
0x06 => array(
"magic",
"long", //Server GUID
"byte", //Server Security
"short", //MTU Size
),
0x07 => array(
"magic",
5, //Security Cookie (idk why it's sent here)
"short", //Server UDP Port
"short", //MTU Size
"long", //Client GUID
),
0x08 => array(
"magic",
"long", //Server GUID
"short", //Client UDP Port
"short", //MTU Size
"byte", //Security
),
0x1a => array(
"byte", //Server Version
"magic",
"long", //Server GUID
),
0x1c => array(
"long", //Ping ID
"long", //Server GUID
"magic",
"string", //Data
),
0x1d => array(
"long", //Ping ID
"long", //Server GUID
"magic",
"string", //Data
),
0x80 => array(
"itriad",
"ubyte",
"customData",
),
0x81 => array(
"itriad",
"ubyte",
"customData",
),
0x82 => array(
"itriad",
"ubyte",
"customData",
),
0x83 => array(
"itriad",
"ubyte",
"customData",
),
0x84 => array(
"itriad",
"ubyte",
"customData",
),
0x85 => array(
"itriad",
"ubyte",
"customData",
),
0x86 => array(
"itriad",
"ubyte",
"customData",
),
0x87 => array(
"itriad",
"ubyte",
"customData",
),
0x88 => array(
"itriad",
"ubyte",
"customData",
),
0x89 => array(
"itriad",
"ubyte",
"customData",
),
0x8a => array(
"itriad",
"ubyte",
"customData",
),
0x8b => array(
"itriad",
"ubyte",
"customData",
),
0x8c => array(
"itriad",
"ubyte",
"customData",
),
0x8d => array(
"itriad",
"ubyte",
"customData",
),
0x8e => array(
"itriad",
"ubyte",
"customData",
),
0x8f => array(
"itriad",
"ubyte",
"customData",
),
0xa0 => array(
"short",
"bool",
"itriad",
"special1",
),
0xc0 => array(
"short",
"bool",
"itriad",
"special1",
),
);
}

View File

@ -1,42 +1,38 @@
<?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/
*
*
*/
/***REM_START***/
require_once(dirname(__FILE__)."/config.php");
require_once(FILE_PATH."/src/utils/TextFormat.php");
require_once(FILE_PATH."/src/functions.php");
/***REM_END***/
define(DATA_PATH, realpath(arg("data-path", FILE_PATH))."/");
define("DATA_PATH", realpath(arg("data-path", FILE_PATH))."/");
if(strpos(strtoupper(php_uname("s")), "WIN") === false or arg("enable-ansi", false) === true){
if(arg("enable-ansi", strpos(strtoupper(php_uname("s")), "WIN") === 0 ? false:true) === true and arg("disable-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);
set_error_handler("error_handler", E_ALL);
$errors = 0;
@ -45,12 +41,6 @@ if(version_compare("5.4.0", PHP_VERSION) > 0){
++$errors;
}
if(version_compare(CURRENT_PHP_VERSION, PHP_VERSION) > 0){
console("[NOTICE] PocketMine-MP hasn't been tested with PHP < ".CURRENT_PHP_VERSION, true, true, 0);
}elseif(version_compare(CURRENT_PHP_VERSION, PHP_VERSION) < 0){
console("[NOTICE] PocketMine-MP hasn't been tested with PHP > ".CURRENT_PHP_VERSION, true, true, 0);
}
if(php_sapi_name() !== "cli"){
console("[ERROR] You must run PocketMine-MP using the CLI.", true, true, 0);
++$errors;
@ -81,16 +71,27 @@ if(!extension_loaded("zlib") and @dl((PHP_SHLIB_SUFFIX === "dll" ? "php_":"") .
++$errors;
}
if(!extension_loaded("gmp") and @dl((PHP_SHLIB_SUFFIX === "dll" ? "php_":"") . "gmp." . PHP_SHLIB_SUFFIX) === false){
console("[ERROR] Unable to find the GMP 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
}
$sha1sum = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
/***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***/
$inc = get_included_files();
$inc[] = array_shift($inc);
$srcdir = realpath(FILE_PATH."src/");
foreach($inc as $s){
if(strpos(realpath(dirname($s)), $srcdir) === false and strtolower(basename($s)) !== "pocketmine-mp.php"){
continue;
}
$sha1sum ^= sha1_file($s, true);
}
/***REM_END***/
define("SOURCE_SHA1SUM", bin2hex($sha1sum));

View File

@ -1,45 +1,82 @@
<?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");
}
}
@ -85,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)){
@ -131,7 +142,7 @@ function arguments ( $args ){
array_shift( $args );
$args = join( $args, ' ' );
preg_match_all('/ (--[\w\-]+ (?:[= ] [^-]+ [^\s-] )? ) | (-\w+) | (\w+) /x', $args, $match );
preg_match_all('/ (--[\w\-]+ (?:[= ] [^-\s]+ )? ) | (-\w+) | (\w+) /x', $args, $match );
$args = array_shift( $match );
$ret = array(
@ -171,34 +182,34 @@ function arguments ( $args ){
function console($message, $EOL = true, $log = true, $level = 1){
if(!defined("DEBUG") or DEBUG >= $level){
$message .= $EOL === true ? PHP_EOL:"";
$time = (ENABLE_ANSI === true ? "\x1b[36m".date("H:i:s")."\x1b[0m":date("H:i:s")) . " ";
$replaced = preg_replace('/\x1b\[[0-9;]*m/', "", $time . $message);
$time = (ENABLE_ANSI === true ? FORMAT_AQUA . date("H:i:s") . FORMAT_RESET:date("H:i:s")) . " ";
$replaced = TextFormat::clean(preg_replace('/\x1b\[[0-9;]*m/', "", $time . $message));
if($log === true and (!defined("LOG") or LOG === true)){
logg($replaced, "console", false, $level);
logg(date("Y-m-d")." ".$replaced, "console", false, $level);
}
if(ENABLE_ANSI === true){
$add = "";
if(preg_match("/\[([a-zA-Z0-9]*)\]/", $message, $matches) > 0){
$add = "\x1b";
switch($matches[1]){
case "ERROR":
$add .= "[31;1m";
$add .= FORMAT_RED;
break;
case "INTERNAL":
case "DEBUG":
$add .= "[30;1m";
$add .= FORMAT_GRAY;
break;
case "WARNING":
$add .= "[33;1m";
$add .= FORMAT_YELLOW;
break;
case "NOTICE":
$add .= "[37;1m";
$add .= FORMAT_AQUA;
break;
default:
$add = "";
break;
}
$message = $time . $add . $message . "\x1b[0m";
}
$message = TextFormat::toANSI($time . $add . $message . FORMAT_RESET);
}else{
$message = $replaced;
}
@ -206,9 +217,12 @@ function console($message, $EOL = true, $log = true, $level = 1){
}
}
function fatal_handler($errno, $errstr, $errfile, $errline){
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);
return false;
return true;
}
function logg($message, $name, $EOL = true, $level = 2, $close = false){
@ -219,7 +233,7 @@ function logg($message, $name, $EOL = true, $level = 2, $close = false){
$fpointers = array();
}
if(!isset($fpointers[$name]) or $fpointers[$name] === false){
$fpointers[$name] = @fopen(DATA_PATH."logs/".$name.".log", "ab");
$fpointers[$name] = @fopen(DATA_PATH."/".$name.".log", "ab");
}
@fwrite($fpointers[$name], $message);
if($close === true){

View File

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

View File

@ -1,35 +1,25 @@
<?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/
*
*
*/
/***REM_START***/
require_once(FILE_PATH."/src/math/Vector3.php");
/***REM_END***/
abstract class Block extends Vector3{
abstract class Block extends Position{
public static $class = array(
AIR => "AirBlock",
STONE => "StoneBlock",
@ -50,6 +40,7 @@ abstract class Block extends Vector3{
COAL_ORE => "CoalOreBlock",
WOOD => "WoodBlock",
LEAVES => "LeavesBlock",
SPONGE => "SpongeBlock",
GLASS => "GlassBlock",
LAPIS_ORE => "LapisOreBlock",
LAPIS_BLOCK => "LapisBlock",
@ -104,18 +95,22 @@ abstract class Block extends Vector3{
SUGARCANE_BLOCK => "SugarcaneBlock",
FENCE => "FenceBlock",
PUMPKIN => "PumpkinBlock",
NETHERRACK => "NetherrackBlock",
SOUL_SAND => "SoulSandBlock",
GLOWSTONE_BLOCK => "GlowstoneBlock",
LIT_PUMPKIN => "LitPumpkinBlock",
CAKE_BLOCK => "CakeBlock",
TRAPDOOR => "TrapdoorBlock",
STONE_BRICKS => "StoneBricksBlock",
IRON_BARS => "IronBarsBlock",
GLASS_PANE => "GlassPaneBlock",
MELON_BLOCK => "MelonBlock",
PUMPKIN_STEM => "PumpkinStemBlock",
MELON_STEM => "MelonStemBlock",
FENCE_GATE => "FenceGateBlock",
@ -127,10 +122,26 @@ abstract class Block extends Vector3{
NETHER_BRICKS_STAIRS => "NetherBricksStairsBlock",
SANDSTONE_STAIRS => "SandstoneStairsBlock",
SPRUCE_WOOD_STAIRS => "SpruceWoodStairsBlock",
BIRCH_WOOD_STAIRS => "BirchWoodStairsBlock",
JUNGLE_WOOD_STAIRS => "JungleWoodStairsBlock",
STONE_WALL => "StoneWallBlock",
CARROT_BLOCK => "CarrotBlock",
POTATO_BLOCK => "PotatoBlock",
QUARTZ_BLOCK => "QuartzBlock",
QUARTZ_STAIRS => "QuartzStairsBlock",
DOUBLE_WOOD_SLAB => "DoubleWoodSlabBlock",
WOOD_SLAB => "WoodSlabBlock",
HAY_BALE => "HayBaleBlock",
CARPET => "CarpetBlock",
COAL_BLOCK => "CoalBlock",
BEETROOT_BLOCK => "BeetrootBlock",
STONECUTTER => "StonecutterBlock",
GLOWING_OBSIDIAN => "GlowingObsidianBlock",
NETHER_REACTOR => "NetherReactorBlock",
@ -139,27 +150,35 @@ abstract class Block extends Vector3{
protected $meta;
protected $name;
protected $breakTime;
protected $hardness;
public $isActivable = false;
public $breakable = true;
public $isFlowable = false;
public $isSolid = true;
public $isTransparent = false;
public $isReplaceable = false;
public $isPlaceable = true;
public $inWorld = false;
public $level = false;
public $hasPhysics = false;
public $isLiquid = false;
public $x;
public $y;
public $z;
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.25;
$this->breakTime = 0.20;
$this->hardness = 10;
}
public function getName(){
final public function getHardness(){
return ($this->hardness);
}
final public function getName(){
return $this->name;
}
@ -171,8 +190,8 @@ abstract class Block extends Vector3{
return $this->meta & 0x0F;
}
final public function position(Vector3 $v){
$this->inWorld = true;
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;
@ -189,25 +208,33 @@ abstract class Block extends Vector3{
}
public function getBreakTime(Item $item, Player $player){
if($player->gamemode === CREATIVE){
return 0.25;
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(BlockAPI $level, Item $item, Player $player);
abstract function onBreak(Item $item, Player $player);
abstract function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz);
abstract function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz);
abstract function onActivate(BlockAPI $level, Item $item, Player $player);
abstract function onActivate(Item $item, Player $player);
abstract function onUpdate(BlockAPI $level, $type);
abstract function onUpdate($type);
}
/***REM_START***/

View File

@ -1,42 +1,45 @@
<?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 Item{
public static $class = array(
SUGARCANE => "SugarcaneItem",
WHEAT_SEEDS => "WheatSeedsItem",
PUMPKIN_SEEDS => "PumpkinSeedsItem",
MELON_SEEDS => "MelonSeedsItem",
MUSHROOM_STEW => "MushroomStewItem",
BEETROOT_SOUP => "BeetrootSoupItem",
CARROT => "CarrotItem",
POTATO => "PotatoItem",
BEETROOT_SEEDS => "BeetrootSeedsItem",
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",
@ -48,6 +51,11 @@ class Item{
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;
@ -67,17 +75,20 @@ class Item{
$this->block = BlockAPI::get($this->id, $this->meta);
$this->name = $this->block->getName();
}
if($this->isTool() !== false){
$this->maxStackSize = 1;
}
}
public function getName(){
final public function getName(){
return $this->name;
}
public function isPlaceable(){
final public function isPlaceable(){
return (($this->block instanceof Block) and $this->block->isPlaceable === true);
}
public function getBlock(){
final public function getBlock(){
if($this->block instanceof Block){
return $this->block;
}else{
@ -85,30 +96,158 @@ class Item{
}
}
public function getID(){
final public function getID(){
return $this->id;
}
public function getMetadata(){
final public function getMetadata(){
return $this->meta;
}
public function getMaxStackSize(){
final public function getMaxStackSize(){
return $this->maxStackSize;
}
public function isPickaxe(){ //Returns false or level of the pickaxe
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;
}elseif($this->isHoe()){
if(($object instanceof Block) and ($object->getID() === GRASS or $object->getID() === DIRT)){
$this->meta++;
}
}
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 3;
return 4;
case WOODEN_PICKAXE:
return 1;
case STONE_PICKAXE:
return 2;
case DIAMOND_PICKAXE:
return 4;
case GOLD_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;
}
@ -126,6 +265,10 @@ class Item{
return false;
}
}
public function isShears(){
return ($this->id === SHEARS);
}
final public function __toString(){
return "Item ". $this->name ." (".$this->id.":".$this->meta.")";
@ -135,8 +278,8 @@ class Item{
return 1;
}
public function onActivate(BlockAPI $level, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
public function onActivate(Level $level, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
return false;
}
}
}

View File

@ -1,39 +1,69 @@
<?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 DoorBlock extends TransparentBlock{
public function __construct($id, $meta = 0, $name = "Unknown"){
/**
* @param int $id
* @param int $meta
* @param string $name
*/
public function __construct($id, $meta = 0, $name = "Unknown"){
parent::__construct($id, $meta, $name);
$this->isSolid = false;
}
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
if($block->inWorld === true and $face === 1){
$blockUp = $level->getBlockFace($block, 1);
$blockDown = $level->getBlockFace($block, 0);
/**
* @param int $type
*
* @return bool|int
*/
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->getID() === AIR){ //Replace with 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;
}
/**
* @param Item $item
* @param Player $player
* @param Block $block
* @param Block $target
* @param integer $face
* @param integer $fx
* @param integer $fy
* @param integer $fz
*
* @return boolean
*/
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;
}
@ -44,52 +74,79 @@ class DoorBlock extends TransparentBlock{
2 => 2,
3 => 5,
);
$next = $level->getBlockFace($block, $face[(($direction + 2) % 4)]);
$next2 = $level->getBlockFace($block, $face[$direction]);
$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;
}
$level->setBlock($blockUp, $this->id, $metaUp); //Top
$this->level->setBlock($blockUp, BlockAPI::get($this->id, $metaUp), true, false, true); //Top
$this->meta = $direction & 0x03;
$level->setBlock($block, $this->id, $this->meta); //Bottom
$this->level->setBlock($block, $this, true, false, true); //Bottom
return true;
}
return false;
}
public function onBreak(BlockAPI $level, Item $item, Player $player){
if($this->inWorld === true){
if(($this->meta & 0x08) === 0x08){
$down = $level->getBlockFace($this, 0);
if($down->getID() === $this->id){
$level->setBlock($down, 0, 0);
}
}else{
$up = $level->getBlockFace($this, 1);
if($up->getID() === $this->id){
$level->setBlock($up, 0, 0);
}
/**
* @param Item $item
* @param Player $player
*
* @return boolean
*/
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(), true, false, true);
}
}else{
$up = $this->getSide(1);
if($up->getID() === $this->id){
$this->level->setBlock($up, new AirBlock(), true, false, true);
}
$level->setBlock($this, 0, 0);
return true;
}
return false;
$this->level->setBlock($this, new AirBlock(), true, false, true);
return true;
}
public function onActivate(BlockAPI $level, Item $item, Player $player){
/**
* @param Item $item
* @param Player $player
*
* @return boolean
*/
public function onActivate(Item $item, Player $player){
if(($this->meta & 0x08) === 0x08){ //Top
$down = $level->getBlockFace($this, 0);
$down = $this->getSide(0);
if($down->getID() === $this->id){
$meta = $down->getMetadata() ^ 0x04;
$level->setBlock($down, $this->id, $meta);
$this->level->setBlock($down, BlockAPI::get($this->id, $meta), true, false, true);
$players = ServerAPI::request()->api->player->getAll($this->level);
unset($players[$player->CID]);
ServerAPI::request()->api->player->broadcastPacket($players, MC_LEVEL_EVENT, array(
"x" => $this->x,
"y" => $this->y,
"z" => $this->z,
"evid" => 1003,
"data" => 0
));
return true;
}
return false;
}else{
$this->meta ^= 0x04;
$level->setBlock($this, $this->id, $this->meta);
$this->level->setBlock($this, $this, true, false, true);
$players = ServerAPI::request()->api->player->getAll($this->level);
unset($players[$player->CID]);
ServerAPI::request()->api->player->broadcastPacket($players, MC_LEVEL_EVENT, array(
"x" => $this->x,
"y" => $this->y,
"z" => $this->z,
"evid" => 1003,
"data" => 0
));
}
return true;
}

View File

@ -1,33 +1,50 @@
<?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 FallableBlock extends GenericBlock{
public function __construct($id, $meta = 0, $name = "Unknown"){
class FallableBlock extends SolidBlock{
/**
* @param int $id
* @param int $meta
* @param string $name
*/
public function __construct($id, $meta = 0, $name = "Unknown"){
parent::__construct($id, $meta, $name);
$this->hasPhysics = true;
}
/**
* @param Item $item
* @param Player $player
* @param Block $block
* @param Block $target
* @param int $face
* @param int $fx
* @param int $fy
* @param int $fz
*
* @return mixed
*/
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

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

View File

@ -1,59 +1,104 @@
<?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 GenericBlock extends Block{
public function __construct($id, $meta = 0, $name = "Unknown"){
/**
* @param int $id
* @param int $meta
* @param string $name
*/
public function __construct($id, $meta = 0, $name = "Unknown"){
parent::__construct($id, $meta, $name);
}
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
if($block->inWorld === true){
$level->setBlock($block, $this->id, $this->getMetadata());
return true;
}
/**
* @param Item $item
* @param Player $player
* @param Block $block
* @param Block $target
* @param integer $face
* @param integer $fx
* @param integer $fy
* @param integer $fz
*
* @return mixed
*/
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
return $this->level->setBlock($this, $this, true, false, true);
}
/**
* @param Item $item
* @param Player $player
*
* @return boolean
*/
public function isBreakable(Item $item, Player $player){
return ($this->breakable);
}
/**
* @param Item $item
* @param Player $player
*
* @return mixed
*/
public function onBreak(Item $item, Player $player){
return $this->level->setBlock($this, new AirBlock(), true, false, true);
}
/**
* @param integer $type
*
* @return boolean
*/
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 isBreakable(Item $item, Player $player){
return $this->breakable;
}
public function onBreak(BlockAPI $level, Item $item, Player $player){
if($this->inWorld === true){
$level->setBlock($this, AIR, 0);
return true;
}
return false;
}
public function onUpdate(BlockAPI $level, $type){
return false;
}
public function onActivate(BlockAPI $level, Item $item, Player $player){
return false;
/**
* @param Item $item
* @param Player $player
*
* @return boolean
*/
public function onActivate(Item $item, Player $player){
return $this->isActivable;
}
}

View File

@ -1,35 +1,36 @@
<?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 LiquidBlock extends TransparentBlock{
public function __construct($id, $meta = 0, $name = "Unknown"){
/**
* @param int $id
* @param int $meta
* @param string $name
*/
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

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

View File

@ -1,56 +1,80 @@
<?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 StairBlock extends TransparentBlock{
public function __construct($id, $meta = 0, $name = "Unknown"){
/**
* @param int $id
* @param int $meta
* @param string $name
*/
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;
}
$this->hardness = 30;
}
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
if($block->inWorld === true){
$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
}
$level->setBlock($block, $this->id, $this->meta);
return true;
}
return false;
}
public function getDrops(Item $item, Player $player){
return array(
array($this->id, 0, 1),
/**
* @param Item $item
* @param Player $player
* @param Block $block
* @param Block $target
* @param int $face
* @param int $fx
* @param int $fy
* @param int $fz
*
* @return bool|mixed
*/
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, true, false, true);
return true;
}
/**
* @param Item $item
* @param Player $player
*
* @return array
*/
public function getDrops(Item $item, Player $player){
if($item->isPickaxe() >= 1){
return array(
array($this->id, 0, 1),
);
}else{
return array();
}
}
}

View File

@ -1,38 +1,38 @@
<?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 TransparentBlock extends GenericBlock{
public function __construct($id, $meta = 0, $name = "Unknown"){
/**
* @param int $id
* @param int $meta
* @param string $name
*/
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->isPlaceable = true;
$this->isSolid = true;
}
}

View File

@ -1,49 +1,59 @@
<?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 LadderBlock extends TransparentBlock{
public function __construct($meta = 0){
parent::__construct(LADDER, $meta, "Ladder");
$this->isSolid = false;
$this->isFullBlock = false;
$this->hardness = 2;
}
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
if($block->inWorld === true){
if($target->isTransparent === 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,
);
$level->setBlock($block, $this->id, $faces[$face]);
if(isset($faces[$face])){
$this->meta = $faces[$face];
$this->level->setBlock($block, $this, true, false, true);
return true;
}
}
return false;
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->getID() === AIR){ //Replace with common break method
ServerAPI::request()->api->entity->drop($this, BlockAPI::getItem(LADDER, 0, 1));
$this->level->setBlock($this, new AirBlock(), true, true, true);
return BLOCK_UPDATE_NORMAL;
}
}
return false;
}
public function getDrops(Item $item, Player $player){
return array(
array($this->id, 0, 1),

View File

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

View File

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

View File

@ -1,38 +1,37 @@
<?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 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;
}
$this->hardness = 15;
}
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
if($block->inWorld === true){
if($target->isTransparent === false and $face !== 0 and $face !== 1){
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,
@ -43,20 +42,18 @@ class TrapdoorBlock extends TransparentBlock{
if($fy > 0.5){
$this->meta |= 0x08;
}
$level->setBlock($block, $this->id, $this->meta);
$this->level->setBlock($block, $this, true, false, true);
return true;
}
}
return false;
}
public function getDrops(Item $item, Player $player){
return array(
array($this->id, 0, 1),
);
}
public function onActivate(BlockAPI $level, Item $item, Player $player){
public function onActivate(Item $item, Player $player){
$this->meta ^= 0x04;
$level->setBlock($this, $this->id, $this->meta);
$this->level->setBlock($this, $this, true, false, true);
return true;
}
}

View File

@ -1,68 +1,34 @@
<?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 WallSignBlock extends TransparentBlock{
/***REM_START***/
require_once("SignPost.php");
/***REM_END***/
class WallSignBlock extends SignPostBlock{
public function __construct($meta = 0){
parent::__construct(WALL_SIGN, $meta, "Wall Sign");
TransparentBlock::__construct(WALL_SIGN, $meta, "Wall Sign");
}
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
if($block->inWorld === true and $face !== 0){
if($face !== 0){
$faces = array(
2 => 2,
3 => 3,
4 => 4,
5 => 5,
);
if(!isset($faces[$face])){
$level->setBlock($block, SIGN_POST, 0);
return true;
}else{
$level->setBlock($block, WALL_SIGN, $faces[$face]);
return true;
}
}
}
public function onUpdate($type){
return false;
}
public function onBreak(BlockAPI $level, Item $item, Player $player){
if($this->inWorld === true){
$level->setBlock($this, AIR, 0, true, true);
return true;
}
return false;
}
public function getDrops(Item $item, Player $player){
return array(
array(SIGN, 0, 1),
);
}
}

View File

@ -1,33 +1,142 @@
<?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 LavaBlock extends LiquidBlock{
public function __construct($meta = 0){
parent::__construct(LAVA, $meta, "Lava");
$this->hardness = 0;
}
}
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, 40, BLOCK_UPDATE_NORMAL);
return $ret;
}
public function getSourceCount(){
$count = 0;
for($side = 2; $side <= 5; ++$side){
if($this->getSide($side) instanceof LavaBlock ){
$b = $this->getSide($side);
$level = $b->meta & 0x07;
if($level == 0x00){
$count++;
}
}
}
return $count;
}
public function checkWater(){
for($side = 1; $side <= 5; ++$side){
$b = $this->getSide($side);
if($b instanceof WaterBlock){
$level = $this->meta & 0x07;
if($level == 0x00){
$this->level->setBlock($this, new ObsidianBlock(), false, false, true);
}else{
$this->level->setBlock($this, new CobblestoneBlock(), false, false, true);
}
}
}
}
public function getFrom(){
for($side = 0; $side <= 5; ++$side){
$b = $this->getSide($side);
if($b instanceof LavaBlock){
$tlevel = $b->meta & 0x07;
$level = $this->meta & 0x07;
if( ($tlevel + 2) == $level || ($side == 0x01 && $level == 0x01 ) || ($tlevel == 6 && $level == 7 )){
return $b;
}
}
}
return null;
}
public function onUpdate($type){
//return false;
$newId = $this->id;
$level = $this->meta & 0x07;
if($type !== BLOCK_UPDATE_NORMAL){
return false;
}
if( $this->checkWater()){
return;
}
$falling = $this->meta >> 3;
$down = $this->getSide(0);
$from = $this->getFrom();
if($from !== null || $level == 0x00){
if($level !== 0x07){
if($down instanceof AirBlock || $down instanceof LavaBlock){
$this->level->setBlock($down, new LavaBlock(0x01), false, false, true);
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($down, 0, 0, $this->level), 40, BLOCK_UPDATE_NORMAL);
}else{
for($side = 2; $side <= 5; ++$side){
$b = $this->getSide($side);
if($b instanceof LavaBlock){
}else if($b->isFlowable === true){
$this->level->setBlock($b, new LavaBlock( min($level + 2,7) ), false, false, true);
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($b, 0, 0, $this->level), 40, BLOCK_UPDATE_NORMAL);
}
}
}
}
}else{
//Extend Remove for Left Lavas
for($side = 2; $side <= 5; ++$side){
$sb = $this->getSide($side);
if($sb instanceof LavaBlock){
$tlevel = $sb->meta & 0x07;
if($tlevel != 0x00){
for ($s = 0; $s <= 5; $s++) {
$ssb = $sb->getSide($s);
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($ssb, 0, 0, $this->level), 40, BLOCK_UPDATE_NORMAL);
}
$this->level->setBlock($sb, new AirBlock(), false, false, true);
}
}
$b = $this->getSide(0)->getSide($side);
if($b instanceof LavaBlock){
$tlevel = $b->meta & 0x07;
if($tlevel != 0x00){
for ($s = 0; $s <= 5; $s++) {
$ssb = $sb->getSide($s);
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($ssb, 0, 0, $this->level), 40, BLOCK_UPDATE_NORMAL);
}
$this->level->setBlock($b, new AirBlock(), false, false, true);
}
}
//ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($b, 0, 0, $this->level), 10, BLOCK_UPDATE_NORMAL);
}
$this->level->setBlock($this, new AirBlock(), false, false, true);
}
return false;
}
}

View File

@ -1,33 +1,28 @@
<?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 StillLavaBlock extends LiquidBlock{
public function __construct($meta = 0){
parent::__construct(STILL_LAVA, $meta, "Still Lava");
$this->hardness = 500;
}
}

View File

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

View File

@ -1,33 +1,146 @@
<?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 WaterBlock extends LiquidBlock{
public function __construct($meta = 0){
parent::__construct(WATER, $meta, "Water");
$this->hardness = 500;
}
}
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 getSourceCount(){
$count = 0;
for($side = 2; $side <= 5; ++$side){
if( $this->getSide($side) instanceof WaterBlock ){
$b = $this->getSide($side);
$level = $b->meta & 0x07;
if($level == 0x00){
$count++;
}
}
}
return $count;
}
public function checkLava(){
for($side = 0; $side <= 5; ++$side){
if($side == 1){
continue;
}
$b = $this->getSide($side);
if($b instanceof LavaBlock){
$level = $b->meta & 0x07;
if($level == 0x00){
$this->level->setBlock($b, new ObsidianBlock(), false, false, true);
}else{
$this->level->setBlock($b, new CobblestoneBlock(), false, false, true);
}
return true;
}
}
return false;
}
public function getFrom(){
for($side = 0; $side <= 5; ++$side){
$b = $this->getSide($side);
if($b instanceof WaterBlock){
$tlevel = $b->meta & 0x07;
$level = $this->meta & 0x07;
if( ($tlevel + 1) == $level || ($side == 0x01 && $level == 0x01 )){
return $b;
}
}
}
return null;
}
public function onUpdate($type){
//return false;
$newId = $this->id;
$level = $this->meta & 0x07;
if($type !== BLOCK_UPDATE_NORMAL){
return false;
}
$this->checkLava();
$falling = $this->meta >> 3;
$down = $this->getSide(0);
$from = $this->getFrom();
//Has Source or Its Source
if($from !== null || $level == 0x00){
if($level !== 0x07){
if($down instanceof AirBlock || $down instanceof WaterBlock){
$this->level->setBlock($down, new WaterBlock(0x01), false, false, true);
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($down, 0, 0, $this->level), 10, BLOCK_UPDATE_NORMAL);
}else{
for($side = 2; $side <= 5; ++$side){
$b = $this->getSide($side);
if($b instanceof WaterBlock){
if( $this->getSourceCount() >= 2 && $level != 0x00){
$this->level->setBlock($this, new WaterBlock(0), false, false, true);
}
}elseif($b->isFlowable === true){
$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);
}
}
}
}
}else{
//Extend Remove for Left Waters
for($side = 2; $side <= 5; ++$side){
$sb = $this->getSide($side);
if($sb instanceof WaterBlock){
$tlevel = $sb->meta & 0x07;
if($tlevel != 0x00){
for ($s = 0; $s <= 5; $s++) {
$ssb = $sb->getSide($s);
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($ssb, 0, 0, $this->level), 10, BLOCK_UPDATE_NORMAL);
}
$this->level->setBlock($sb, new AirBlock(), false, false, true);
}
}
$b = $this->getSide(0)->getSide($side);
if($b instanceof WaterBlock){
$tlevel = $b->meta & 0x07;
if($tlevel != 0x00){
for ($s = 0; $s <= 5; $s++) {
$ssb = $sb->getSide($s);
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($ssb, 0, 0, $this->level), 10, BLOCK_UPDATE_NORMAL);
}
$this->level->setBlock($b, new AirBlock(), false, false, true);
}
}
//ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($b, 0, 0, $this->level), 10, BLOCK_UPDATE_NORMAL);
}
$this->level->setBlock($this, new AirBlock(), false, false, true);
}
return false;
}
}

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 AirBlock extends TransparentBlock{
@ -34,8 +28,11 @@ class AirBlock extends TransparentBlock{
$this->isTransparent = true;
$this->isReplaceable = true;
$this->isPlaceable = false;
$this->inWorld = false;
$this->hasPhysics = false;
$this->isSolid = false;
$this->isFullBlock = true;
$this->hardness = 0;
}
}

View File

@ -1,39 +1,73 @@
<?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 BedBlock extends TransparentBlock{
public function __construct($type = 0){
parent::__construct(BED_BLOCK, $type, "Bed Block");
$this->isActivable = true;
$this->isFullBlock = false;
$this->hardness = 1;
}
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
if($block->inWorld === true){
$down = $level->getBlockFace($block, 0);
public function onActivate(Item $item, Player $player){
if(ServerAPI::request()->api->time->getPhase($player->level) !== "night"){
$player->dataPacket(MC_CLIENT_MESSAGE, array(
"message" => "You can only sleep at night"
));
return true;
}
$blockNorth = $this->getSide(2); //Gets the blocks around them
$blockSouth = $this->getSide(3);
$blockEast = $this->getSide(5);
$blockWest = $this->getSide(4);
if(($this->meta & 0x08) === 0x08){ //This is the Top part of bed
$b = $this;
}else{ //Bottom Part of Bed
if($blockNorth->getID() === $this->id and ($blockNorth->meta & 0x08) === 0x08){
$b = $blockNorth;
}elseif($blockSouth->getID() === $this->id and ($blockSouth->meta & 0x08) === 0x08){
$b = $blockSouth;
}elseif($blockEast->getID() === $this->id and ($blockEast->meta & 0x08) === 0x08){
$b = $blockEast;
}elseif($blockWest->getID() === $this->id and ($blockWest->meta & 0x08) === 0x08){
$b = $blockWest;
}else{
$player->dataPacket(MC_CLIENT_MESSAGE, array(
"message" => "The bed is incomplete"
));
return true;
}
}
if($player->sleepOn($b) === false){
$player->dataPacket(MC_CLIENT_MESSAGE, array(
"message" => "This bed is occupied"
));
}
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,
@ -42,55 +76,47 @@ class BedBlock extends TransparentBlock{
3 => 5,
);
$d = $player->entity->getDirection();
$next = $level->getBlockFace($block, $faces[(($d + 3) % 4)]);
$downNext = $level->getBlockFace($next, 0);
$next = $this->getSide($faces[(($d + 3) % 4)]);
$downNext = $this->getSide(0);
if($next->isReplaceable === true and $downNext->isTransparent === false){
$meta = (($d + 3) % 4) & 0x03;
$level->setBlock($block, $this->id, $meta);
$level->setBlock($next, $this->id, $meta | 0x08);
$this->level->setBlock($block, BlockAPI::get($this->id, $meta), true, false, true);
$this->level->setBlock($next, BlockAPI::get($this->id, $meta | 0x08), true, false, true);
return true;
}
}
}
return false;
}
public function onBreak(BlockAPI $level, Item $item, Player $player){
if($this->inWorld === true){//Checks if the block was in the world or not. Just in case
$blockNorth = $level->getBlockFace($this, 2); //Gets the blocks around them
$blockSouth = $level->getBlockFace($this, 3);
$blockEast = $level->getBlockFace($this, 5);
$blockWest = $level->getBlockFace($this, 4);
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
$level->setBlock($blockNorth, 0, 0);
$this->level->setBlock($blockNorth, new AirBlock(), true, false, true);
}elseif($blockSouth->getID() === $this->id and $blockSouth->meta !== 0x08){
$level->setBlock($blockSouth, 0, 0);
$this->level->setBlock($blockSouth, new AirBlock(), true, false, true);
}elseif($blockEast->getID() === $this->id and $blockEast->meta !== 0x08){
$level->setBlock($blockEast, 0, 0);
$this->level->setBlock($blockEast, new AirBlock(), true, false, true);
}elseif($blockWest->getID() === $this->id and $blockWest->meta !== 0x08){
$level->setBlock($blockWest, 0, 0);
}else{
return false;
$this->level->setBlock($blockWest, new AirBlock(), true, false, true);
}
return true;
}else{ //Bottom Part of Bed
if($blockNorth->getID() === $this->id and ($blockNorth->meta & 0x08) === 0x08){
$level->setBlock($blockNorth, 0, 0);
$this->level->setBlock($blockNorth, new AirBlock(), true, false, true);
}elseif($blockSouth->getID() === $this->id and ($blockSouth->meta & 0x08) === 0x08){
$level->setBlock($blockSouth, 0, 0);
$this->level->setBlock($blockSouth, new AirBlock(), true, false, true);
}elseif($blockEast->getID() === $this->id and ($blockEast->meta & 0x08) === 0x08){
$level->setBlock($blockEast, 0, 0);
$this->level->setBlock($blockEast, new AirBlock(), true, false, true);
}elseif($blockWest->getID() === $this->id and ($blockWest->meta & 0x08) === 0x08){
$level->setBlock($blockWest, 0, 0);
}else{
return false;
}
return true;
$this->level->setBlock($blockWest, new AirBlock(), true, false, true);
}
}
return false;
}
$this->level->setBlock($this, new AirBlock(), true, false, true);
return true;
}
public function getDrops(Item $item, Player $player){

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 FireBlock extends FlowableBlock{
@ -30,6 +24,31 @@ class FireBlock extends FlowableBlock{
parent::__construct(FIRE, $meta, "Fire");
$this->isReplaceable = true;
$this->breakable = false;
$this->isFullBlock = true;
$this->hardness = 0;
}
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(), true, false, true);
return BLOCK_UPDATE_NORMAL;
}elseif($type === BLOCK_UPDATE_RANDOM){
if($this->getSide(0)->getID() !== NETHERRACK){
$this->level->setBlock($this, new AirBlock(), true, false, true);
return BLOCK_UPDATE_NORMAL;
}
}
return false;
}
}

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 NetherReactorBlock extends SolidBlock{

View File

@ -1,46 +1,48 @@
<?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 TNTBlock extends SolidBlock{
public function __construct(){
parent::__construct(TNT, 0, "TNT");
$this->hardness = 0;
$this->isActivable = true;
}
public function getDrops(Item $item, Player $player){
if($this->inWorld === true){
$player->dataPacket(MC_EXPLOSION, array(
"x" => $this->x,
"y" => $this->y,
"z" => $this->z,
"radius" => 2,
"records" => array(),
));
public function onActivate(Item $item, Player $player){
if($item->getID() === FLINT_STEEL){
if(($player->gamemode & 0x01) === 0){
$item->useOn($this);
}
$data = array(
"x" => $this->x + 0.5,
"y" => $this->y + 0.5,
"z" => $this->z + 0.5,
"power" => 4,
"fuse" => 20 * 4, //4 seconds
);
$this->level->setBlock($this, new AirBlock(), false, false, true);
$e = ServerAPI::request()->api->entity->add($this->level, ENTITY_OBJECT, OBJECT_PRIMEDTNT, $data);
ServerAPI::request()->api->entity->spawnToAll($e);
return true;
}
return array(
array(TNT, 0, 1),
);
}
return false;
}
}

View File

@ -0,0 +1,68 @@
<?php
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
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;
$this->hardness = 2.5;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
$down = $this->getSide(0);
if($down->getID() !== AIR){
$this->level->setBlock($block, $this, true, false, true);
return true;
}
return false;
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->getID() === AIR){ //Replace with common break method
$this->level->setBlock($this, new AirBlock(), true, false, true);
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(), true, false, true);
}else{
$this->level->setBlock($this, $this, true, false, true);
}
return true;
}
return false;
}
}

View File

@ -0,0 +1,69 @@
<?php
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
class CarpetBlock extends FlowableBlock{
public function __construct($meta = 0){
parent::__construct(CARPET, $meta, "Carpet");
$names = array(
0 => "White Carpet",
1 => "Orange Carpet",
2 => "Magenta Carpet",
3 => "Light Blue Carpet",
4 => "Yellow Carpet",
5 => "Lime Carpet",
6 => "Pink Carpet",
7 => "Gray Carpet",
8 => "Light Gray Carpet",
9 => "Cyan Carpet",
10 => "Purple Carpet",
11 => "Blue Carpet",
12 => "Brown Carpet",
13 => "Green Carpet",
14 => "Red Carpet",
15 => "Black Carpet",
);
$this->name = $names[$this->meta];
$this->hardness = 0;
$this->isFullBlock = false;
$this->isSolid = true;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
$down = $this->getSide(0);
if($down->getID() !== AIR){
$this->level->setBlock($block, $this, true, false, true);
return true;
}
return false;
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->getID() === AIR){ //Replace with common break method
ServerAPI::request()->api->entity->drop($this, BlockAPI::getItem($this->id, $this->meta, 1));
$this->level->setBlock($this, new AirBlock(), true, false, true);
return BLOCK_UPDATE_NORMAL;
}
}
return false;
}
}

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

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 FenceBlock extends TransparentBlock{
public function __construct(){
parent::__construct(FENCE, 0, "Fence");
$this->isFullBlock = false;
$this->hardness = 15;
}
}

View File

@ -0,0 +1,65 @@
<?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;
}
$this->hardness = 15;
}
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, true, false, true);
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);
if(($this->meta & 0x04) === 0x04){
$this->isFullBlock = true;
}else{
$this->isFullBlock = false;
}
$this->level->setBlock($this, $this, true, false, true);
return true;
}
}

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 GlassPaneBlock extends TransparentBlock{
public function __construct(){
parent::__construct(GLASS_PANE, 0, "Glass Pane");
$this->isFullBlock = false;
$this->isSolid = false;
}
}

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 IronBarsBlock extends TransparentBlock{
public function __construct(){
parent::__construct(IRON_BARS, 0, "Iron Bars");
$this->isFullBlock = false;
$this->isSolid = false;
}
}

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 IronDoorBlock extends DoorBlock{
public function __construct($meta = 0){
parent::__construct(IRON_DOOR_BLOCK, $meta, "Iron Door Block");
//$this->isActivable = true;
$this->hardness = 25;
}
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,114 @@
<?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 => "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;
}
$this->hardness = 30;
}
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), true, false, true);
return true;
}elseif($block->getID() === SLAB and ($block->getMetadata() & 0x07) === ($this->meta & 0x07)){
$this->level->setBlock($block, BlockAPI::get(DOUBLE_SLAB, $this->meta), true, false, true);
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), true, false, true);
return true;
}elseif($block->getID() === SLAB and ($block->getMetadata() & 0x07) === ($this->meta & 0x07)){
$this->level->setBlock($block, BlockAPI::get(DOUBLE_SLAB, $this->meta), true, false, true);
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), true, false, true);
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, true, false, true);
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,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 SnowLayerBlock extends FlowableBlock{
public function __construct($meta = 0){
parent::__construct(SNOW_LAYER, $meta, "Snow Layer");
$this->isReplaceable = true;
$this->isSolid = false;
$this->isFullBlock = false;
$this->hardness = 0.5;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
$down = $this->getSide(0);
if($down instanceof SolidBlock){
$this->level->setBlock($block, $this, true, false, true);
return true;
}
return false;
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->getID() === AIR){ //Replace with common break method
$this->level->setBlock($this, new AirBlock(), true, false, true);
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,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/
*
*
*/
class StoneWallBlock extends TransparentBlock{
public function __construct($meta = 0){
$meta &= 0x01;
parent::__construct(STONE_WALL, $meta, "Cobblestone Wall");
if($meta === 1){
$this->name = "Mossy Cobblestone Wall";
}
$this->isFullBlock = false;
$this->isSolid = false;
$this->hardness = 30;
}
}

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/
*
*
*/
class WoodDoorBlock extends DoorBlock{
public function __construct($meta = 0){
parent::__construct(WOOD_DOOR_BLOCK, $meta, "Wood Door Block");
$this->isActivable = true;
$this->hardness = 15;
}
public function getDrops(Item $item, Player $player){
return array(
array(WOODEN_DOOR, 0, 1),
);
}
}

View File

@ -0,0 +1,107 @@
<?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 WoodSlabBlock extends TransparentBlock{
public function __construct($meta = 0){
parent::__construct(WOOD_SLAB, $meta, "Wooden Slab");
$names = array(
0 => "Oak",
1 => "Spruce",
2 => "Birch",
3 => "Jungle",
);
$this->name = (($this->meta & 0x08) === 0x08 ? "Upper ":"") . $names[$this->meta & 0x07] . " Wooden Slab";
if(($this->meta & 0x08) === 0x08){
$this->isFullBlock = true;
}else{
$this->isFullBlock = false;
}
$this->hardness = 15;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
$this->meta &= 0x07;
if($face === 0){
if($target->getID() === WOOD_SLAB and ($target->getMetadata() & 0x08) === 0x08 and ($target->getMetadata() & 0x07) === ($this->meta & 0x07)){
$this->level->setBlock($target, BlockAPI::get(DOUBLE_WOOD_SLAB, $this->meta), true, false, true);
return true;
}elseif($block->getID() === WOOD_SLAB and ($block->getMetadata() & 0x07) === ($this->meta & 0x07)){
$this->level->setBlock($block, BlockAPI::get(DOUBLE_WOOD_SLAB, $this->meta), true, false, true);
return true;
}else{
$this->meta |= 0x08;
}
}elseif($face === 1){
if($target->getID() === WOOD_SLAB and ($target->getMetadata() & 0x08) === 0 and ($target->getMetadata() & 0x07) === ($this->meta & 0x07)){
$this->level->setBlock($target, BlockAPI::get(DOUBLE_WOOD_SLAB, $this->meta), true, false, true);
return true;
}elseif($block->getID() === WOOD_SLAB and ($block->getMetadata() & 0x07) === ($this->meta & 0x07)){
$this->level->setBlock($block, BlockAPI::get(DOUBLE_WOOD_SLAB, $this->meta), true, false, true);
return true;
}
}elseif(!$player->entity->inBlock($block)){
if($block->getID() === WOOD_SLAB){
if(($block->getMetadata() & 0x07) === ($this->meta & 0x07)){
$this->level->setBlock($block, BlockAPI::get(DOUBLE_WOOD_SLAB, $this->meta), true, false, true);
return true;
}
return false;
}else{
if($fy > 0.5){
$this->meta |= 0x08;
}
}
}else{
return false;
}
if($block->getID() === WOOD_SLAB and ($target->getMetadata() & 0x07) !== ($this->meta & 0x07)){
return false;
}
$this->level->setBlock($block, $this, true, false, true);
return true;
}
public function getBreakTime(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0x01){
return 0.20;
}
switch($item->isAxe()){
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 3;
}
}
public function getDrops(Item $item, Player $player){
return array(
array($this->id, $this->meta & 0x07, 1),
);
}
}

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/
*
*
*/
class BirchWoodStairsBlock extends StairBlock{
public function __construct($meta = 0){
parent::__construct(BIRCH_WOOD_STAIRS, $meta, "Birch Wood Stairs");
}
public function getDrops(Item $item, Player $player){
return array(
array($this->id, 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,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/
*
*
*/
class JungleWoodStairsBlock extends StairBlock{
public function __construct($meta = 0){
parent::__construct(JUNGLE_WOOD_STAIRS, $meta, "Jungle Wood Stairs");
}
public function getDrops(Item $item, Player $player){
return array(
array($this->id, 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 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,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/
*
*
*/
class SpruceWoodStairsBlock extends StairBlock{
public function __construct($meta = 0){
parent::__construct(SPRUCE_WOOD_STAIRS, $meta, "Spruce Wood Stairs");
}
public function getDrops(Item $item, Player $player){
return array(
array($this->id, 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 StoneBrickStairsBlock extends StairBlock{
public function __construct($meta = 0){
parent::__construct(STONE_BRICK_STAIRS, $meta, "Stone Brick Stairs");
}
}

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 WoodStairsBlock extends StairBlock{
public function __construct($meta = 0){
parent::__construct(WOOD_STAIRS, $meta, "Wood Stairs");
}
public function getBreakTime(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0x01){
return 0.20;
}
switch($item->isAxe()){
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 3;
}
}
public function getDrops(Item $item, Player $player){
return array(
array($this->id, 0, 1),
);
}
}

View File

@ -1,39 +1,54 @@
<?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 CoalOreBlock extends SolidBlock{
public function __construct(){
parent::__construct(COAL_ORE, 0, "Coal Ore");
$this->hardness = 15;
}
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(263, 0, 1), //Coal
array(COAL, 0, 1),
);
}else{
return array();

View File

@ -1,42 +1,51 @@
<?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 DiamondOreBlock extends SolidBlock{
public function __construct(){
parent::__construct(DIAMOND_ORE, 0, "Diamond Ore");
$this->hardness = 15;
}
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() >= 3){
if($item->isPickaxe() >= 4){
return array(
array(264, 0, 1),
array(DIAMOND, 0, 1),
);
}else{
return array();
}
}
}
}

View File

@ -1,33 +1,63 @@
<?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 GlowingRedstoneOreBlock extends SolidBlock{
public function __construct(){
parent::__construct(GLOWING_REDSTONE_ORE, 0, "Glowing Redstone Ore");
$this->hardness = 15;
}
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, false, true);
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(REDSTONE_DUST, 0, mt_rand(4, 5)),
);
}else{
return array();
}
}
}

View File

@ -1,33 +1,51 @@
<?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 GoldOreBlock extends SolidBlock{
public function __construct(){
parent::__construct(GOLD_ORE, 0, "Gold Ore");
$this->hardness = 15;
}
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

@ -1,33 +1,53 @@
<?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 IronOreBlock extends SolidBlock{
public function __construct(){
parent::__construct(IRON_ORE, 0, "Iron Ore");
$this->hardness = 15;
}
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();
}
}
}

View File

@ -1,39 +1,50 @@
<?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 LapisOreBlock extends SolidBlock{
public function __construct(){
parent::__construct(LAPIS_ORE, 0, "Lapis Ore");
$this->hardness = 15;
}
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() >= 2){
if($item->isPickaxe() >= 3){
return array(
array(351, 4, mt_rand(4, 8)),
array(DYE, 4, mt_rand(4, 8)),
);
}else{
return array();

View File

@ -1,38 +1,43 @@
<?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 RedstoneOreBlock extends SolidBlock{
public function __construct(){
parent::__construct(REDSTONE_ORE, 0, "Redstone Ore");
$this->hardness = 15;
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL or $type === BLOCK_UPDATE_TOUCH){
$this->level->setBlock($this, BlockAPI::get(GLOWING_REDSTONE_ORE, $this->meta), false, false, true);
$this->level->scheduleBlockUpdate(new Position($this, 0, 0, $this->level), Utils::getRandomUpdateTicks(), BLOCK_UPDATE_RANDOM);
return BLOCK_UPDATE_WEAK;
}
return false;
}
public function getDrops(Item $item, Player $player){
if($item->isPickaxe() >= 2){
return array(
//array(331, 4, mt_rand(4, 5)),
array(REDSTONE_DUST, 0, mt_rand(4, 5)),
);
}else{
return array();

View File

@ -0,0 +1,82 @@
<?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 BeetrootBlock extends FlowableBlock{
public function __construct($meta = 0){
parent::__construct(BEETROOT_BLOCK, $meta, "Beetroot Block");
$this->isActivable = true;
$this->hardness = 0;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
$down = $this->getSide(0);
if($down->getID() === FARMLAND){
$this->level->setBlock($block, $this, true, false, true);
$this->level->scheduleBlockUpdate(new Position($this, 0, 0, $this->level), Utils::getRandomUpdateTicks(), BLOCK_UPDATE_RANDOM);
return true;
}
return false;
}
public function onActivate(Item $item, Player $player){
if($item->getID() === DYE and $item->getMetadata() === 0x0F){ //Bonemeal
$this->meta = 0x07;
$this->level->setBlock($this, $this, true, false, true);
if(($player->gamemode & 0x01) === 0){
$item->count--;
}
return true;
}
return false;
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
ServerAPI::request()->api->entity->drop($this, BlockAPI::getItem(BEETROOT_SEEDS, 0, 1));
$this->level->setBlock($this, new AirBlock(), false, false, true);
return BLOCK_UPDATE_NORMAL;
}
}elseif($type === BLOCK_UPDATE_RANDOM){
if(mt_rand(0, 2) == 1){
if($this->meta < 0x07){
++$this->meta;
$this->level->setBlock($this, $this, true, false, true);
return BLOCK_UPDATE_RANDOM;
}
}else{
return BLOCK_UPDATE_RANDOM;
}
}
return false;
}
public function getDrops(Item $item, Player $player){
$drops = array();
if($this->meta >= 0x07){
$drops[] = array(BEETROOT, 0, 1);
$drops[] = array(BEETROOT_SEEDS, 0, mt_rand(0, 3));
}else{
$drops[] = array(BEETROOT_SEEDS, 0, 1);
}
return $drops;
}
}

View File

@ -1,44 +1,47 @@
<?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 BrownMushroomBlock extends FlowableBlock{
public function __construct(){
parent::__construct(BROWN_MUSHROOM, 0, "Brown Mushroom");
$this->isFlowable = true;
$this->hardness = 0;
}
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
if($block->inWorld === true){
$down = $level->getBlockFace($block, 0);
if($down->isTransparent === false){
$level->setBlock($block, $this->id, $this->getMetadata());
return true;
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
ServerAPI::request()->api->entity->drop($this, BlockAPI::getItem($this->id));
$this->level->setBlock($this, new AirBlock(), false, false, true);
return BLOCK_UPDATE_NORMAL;
}
}
return false;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
$down = $this->getSide(0);
if($down->isTransparent === false){
$this->level->setBlock($block, $this, true, false, true);
return true;
}
return false;
}
}

View File

@ -1,50 +1,80 @@
<?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 CactusBlock extends TransparentBlock{
public function __construct(){
parent::__construct(CACTUS, 0, "Cactus");
public function __construct($meta = 0){
parent::__construct(CACTUS, $meta, "Cactus");
$this->isFullBlock = false;
$this->hardness = 2;
}
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
if($block->inWorld === true){
$down = $level->getBlockFace($block, 0);
if($down->getID() === SAND or $down->getID() === CACTUS){
$block0 = $level->getBlockFace($block, 2);
$block1 = $level->getBlockFace($block, 3);
$block2 = $level->getBlockFace($block, 4);
$block3 = $level->getBlockFace($block, 5);
if($block0->isFlowable === true and $block1->isFlowable === true and $block2->isFlowable === true and $block3->isFlowable === true){
$level->setBlock($block, $this->id, 0);
return true;
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
$down = $this->getSide(0);
if($down->getID() !== SAND and $down->getID() !== CACTUS){ //Replace with common break method
$this->level->setBlock($this, new AirBlock(), false);
ServerAPI::request()->api->entity->drop($this, BlockAPI::getItem($this->id));
return BLOCK_UPDATE_NORMAL;
}
}elseif($type === BLOCK_UPDATE_RANDOM){
if($this->getSide(0)->getID() !== CACTUS){
if($this->meta == 0x0F){
for($y = 1; $y < 3; ++$y){
$b = $this->level->getBlock(new Vector3($this->x, $this->y + $y, $this->z));
if($b->getID() === AIR){
$this->level->setBlock($b, new CactusBlock(), true, false, true);
break;
}
}
$this->meta = 0;
$this->level->setBlock($this, $this, false);
}else{
++$this->meta;
$this->level->setBlock($this, $this, false);
}
return BLOCK_UPDATE_RANDOM;
}
}
return false;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
$down = $this->getSide(0);
if($down->getID() === SAND or $down->getID() === CACTUS){
$block0 = $this->getSide(2);
$block1 = $this->getSide(3);
$block2 = $this->getSide(4);
$block3 = $this->getSide(5);
if($block0->isTransparent === true and $block1->isTransparent === true and $block2->isTransparent === true and $block3->isTransparent === true){
$this->level->setBlock($this, $this, true, false, true);
$this->level->scheduleBlockUpdate(new Position($this, 0, 0, $this->level), Utils::getRandomUpdateTicks(), BLOCK_UPDATE_RANDOM);
return true;
}
}
return false;
}
public function getDrops(Item $item, Player $player){
return array(
array($this->id, 0, 1),
);
}
}

View File

@ -0,0 +1,81 @@
<?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 CarrotBlock extends FlowableBlock{
public function __construct($meta = 0){
parent::__construct(CARROT_BLOCK, $meta, "Carrot Block");
$this->isActivable = true;
$this->hardness = 0;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
$down = $this->getSide(0);
if($down->getID() === FARMLAND){
$this->level->setBlock($block, $this, true, false, true);
$this->level->scheduleBlockUpdate(new Position($this, 0, 0, $this->level), Utils::getRandomUpdateTicks(), BLOCK_UPDATE_RANDOM);
return true;
}
return false;
}
public function onActivate(Item $item, Player $player){
if($item->getID() === DYE and $item->getMetadata() === 0x0F){ //Bonemeal
$this->meta = 0x07;
$this->level->setBlock($this, $this, true, false, true);
if(($player->gamemode & 0x01) === 0){
$item->count--;
}
return true;
}
return false;
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
ServerAPI::request()->api->entity->drop($this, BlockAPI::getItem(CARROT, 0, 1));
$this->level->setBlock($this, new AirBlock(), false, false, true);
return BLOCK_UPDATE_NORMAL;
}
}elseif($type === BLOCK_UPDATE_RANDOM){
if(mt_rand(0, 2) == 1){
if($this->meta < 0x07){
++$this->meta;
$this->level->setBlock($this, $this, true, false, true);
return BLOCK_UPDATE_RANDOM;
}
}else{
return BLOCK_UPDATE_RANDOM;
}
}
return false;
}
public function getDrops(Item $item, Player $player){
$drops = array();
if($this->meta >= 0x07){
$drops[] = array(CARROT, 0, mt_rand(1, 4));
}else{
$drops[] = array(CARROT, 0, 1);
}
return $drops;
}
}

View File

@ -1,43 +1,47 @@
<?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 CyanFlowerBlock extends FlowableBlock{
public function __construct(){
parent::__construct(CYAN_FLOWER, 0, "Cyan Flower");
$this->isFlowable = true;
$this->hardness = 0;
}
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
if($block->inWorld === true){
$down = $level->getBlockFace($block, 0);
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
$down = $this->getSide(0);
if($down->getID() === 2 or $down->getID() === 3 or $down->getID() === 60){
$level->setBlock($block, $this->id, $this->getMetadata());
$this->level->setBlock($block, $this, true, false, true);
return true;
}
return false;
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
ServerAPI::request()->api->entity->drop($this, BlockAPI::getItem($this->id));
$this->level->setBlock($this, new AirBlock(), false, false, true);
return BLOCK_UPDATE_NORMAL;
}
}
return false;
}
}
}

View File

@ -1,43 +1,47 @@
<?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 DandelionBlock extends FlowableBlock{
public function __construct(){
parent::__construct(DANDELION, 0, "Dandelion");
$this->isFlowable = true;
$this->hardness = 0;
}
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
if($block->inWorld === true){
$down = $level->getBlockFace($block, 0);
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
$down = $this->getSide(0);
if($down->getID() === 2 or $down->getID() === 3 or $down->getID() === 60){
$level->setBlock($block, $this->id, $this->getMetadata());
$this->level->setBlock($block, $this, true, false, true);
return true;
}
return false;
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
ServerAPI::request()->api->entity->drop($this, BlockAPI::getItem($this->id));
$this->level->setBlock($this, new AirBlock(), false, false, true);
return BLOCK_UPDATE_NORMAL;
}
}
return false;
}
}
}

View File

@ -1,35 +1,39 @@
<?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 DeadBushBlock extends FlowableBlock{
public function __construct(){
parent::__construct(DEAD_BUSH, 0, "Dead Bush");
$this->isFlowable = true;
$this->isReplaceable = true;
//$this->isReplaceable = true;
$this->hardness = 0;
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
$this->level->setBlock($this, new AirBlock(), false, false, true);
return BLOCK_UPDATE_NORMAL;
}
}
return false;
}
}

View File

@ -1,49 +1,79 @@
<?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 MelonStemBlock extends TransparentBlock{
class MelonStemBlock extends FlowableBlock{
public function __construct($meta = 0){
parent::__construct(MELON_STEM, $meta, "Melon Stem");
$this->isActivable = true;
$this->hardness = 0;
}
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
if($block->inWorld === true){
$down = $level->getBlockFace($block, 0);
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
$down = $this->getSide(0);
if($down->getID() === FARMLAND){
$level->setBlock($block, $this->id, $this->getMetadata());
$this->level->setBlock($block, $this, true, false, true);
$this->level->scheduleBlockUpdate(new Position($this, 0, 0, $this->level), Utils::getRandomUpdateTicks(), BLOCK_UPDATE_RANDOM);
return true;
}
return false;
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
ServerAPI::request()->api->entity->drop($this, BlockAPI::getItem(MELON_SEEDS, 0, mt_rand(0, 2)));
$this->level->setBlock($this, new AirBlock(), false, false, true);
return BLOCK_UPDATE_NORMAL;
}
}elseif($type === BLOCK_UPDATE_RANDOM){
if(mt_rand(0, 2) == 1){
if($this->meta < 0x07){
++$this->meta;
$this->level->setBlock($this, $this, true, false, true);
return BLOCK_UPDATE_RANDOM;
}else{
for($side = 2; $side <= 5; ++$side){
$b = $this->getSide($side);
if($b->getID() === MELON_BLOCK){
return BLOCK_UPDATE_RANDOM;
}
}
$side = $this->getSide(mt_rand(2,5));
$d = $side->getSide(0);
if($side->getID() === AIR and ($d->getID() === FARMLAND or $d->getID() === GRASS or $d->getID() === DIRT)){
$this->level->setBlock($side, new MelonBlock(), true, false, true);
}
}
}
return BLOCK_UPDATE_RANDOM;
}
return false;
}
public function onActivate(BlockAPI $level, Item $item, Player $player){
public function onActivate(Item $item, Player $player){
if($item->getID() === DYE and $item->getMetadata() === 0x0F){ //Bonemeal
$level->setBlock($this, $this->id, 0x07);
$this->meta = 0x07;
$this->level->setBlock($this, $this, true, false, true);
if(($player->gamemode & 0x01) === 0){
$item->count--;
}
return true;
}
return false;

View File

@ -0,0 +1,81 @@
<?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 PotatoBlock extends FlowableBlock{
public function __construct($meta = 0){
parent::__construct(POTATO_BLOCK, $meta, "Potato Block");
$this->isActivable = true;
$this->hardness = 0;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
$down = $this->getSide(0);
if($down->getID() === FARMLAND){
$this->level->setBlock($block, $this, true, false, true);
$this->level->scheduleBlockUpdate(new Position($this, 0, 0, $this->level), Utils::getRandomUpdateTicks(), BLOCK_UPDATE_RANDOM);
return true;
}
return false;
}
public function onActivate(Item $item, Player $player){
if($item->getID() === DYE and $item->getMetadata() === 0x0F){ //Bonemeal
$this->meta = 0x07;
$this->level->setBlock($this, $this, true, false, true);
if(($player->gamemode & 0x01) === 0){
$item->count--;
}
return true;
}
return false;
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
ServerAPI::request()->api->entity->drop($this, BlockAPI::getItem(POTATO, 0, 1));
$this->level->setBlock($this, new AirBlock(), false, false, true);
return BLOCK_UPDATE_NORMAL;
}
}elseif($type === BLOCK_UPDATE_RANDOM){
if(mt_rand(0, 2) == 1){
if($this->meta < 0x07){
++$this->meta;
$this->level->setBlock($this, $this, true, false, true);
return BLOCK_UPDATE_RANDOM;
}
}else{
return BLOCK_UPDATE_RANDOM;
}
}
return false;
}
public function getDrops(Item $item, Player $player){
$drops = array();
if($this->meta >= 0x07){
$drops[] = array(POTATO, 0, mt_rand(1, 4));
}else{
$drops[] = array(POTATO, 0, 1);
}
return $drops;
}
}

View File

@ -0,0 +1,87 @@
<?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 PumpkinStemBlock extends FlowableBlock{
public function __construct($meta = 0){
parent::__construct(PUMPKIN_STEM, $meta, "Pumpkin Stem");
$this->isActivable = true;
$this->hardness = 0;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
$down = $this->getSide(0);
if($down->getID() === FARMLAND){
$this->level->setBlock($block, $this, true, false, true);
$this->level->scheduleBlockUpdate(new Position($this, 0, 0, $this->level), Utils::getRandomUpdateTicks(), BLOCK_UPDATE_RANDOM);
return true;
}
return false;
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
ServerAPI::request()->api->entity->drop($this, BlockAPI::getItem(PUMPKIN_SEEDS, 0, mt_rand(0, 2)));
$this->level->setBlock($this, new AirBlock(), false, false, true);
return BLOCK_UPDATE_NORMAL;
}
}elseif($type === BLOCK_UPDATE_RANDOM){
if(mt_rand(0, 2) == 1){
if($this->meta < 0x07){
++$this->meta;
$this->level->setBlock($this, $this, true, false, true);
return BLOCK_UPDATE_RANDOM;
}else{
for($side = 2; $side <= 5; ++$side){
$b = $this->getSide($side);
if($b->getID() === PUMPKIN){
return BLOCK_UPDATE_RANDOM;
}
}
$side = $this->getSide(mt_rand(2,5));
$d = $side->getSide(0);
if($side->getID() === AIR and ($d->getID() === FARMLAND or $d->getID() === GRASS or $d->getID() === DIRT)){
$this->level->setBlock($side, new PumpkinBlock(), true, false, true);
}
}
}
return BLOCK_UPDATE_RANDOM;
}
return false;
}
public function onActivate(Item $item, Player $player){
if($item->getID() === DYE and $item->getMetadata() === 0x0F){ //Bonemeal
$this->meta = 0x07;
$this->level->setBlock($this, $this, true, false, true);
if(($player->gamemode & 0x01) === 0){
$item->count--;
}
return true;
}
return false;
}
public function getDrops(Item $item, Player $player){
return array(
array(PUMPKIN_SEEDS, 0, mt_rand(0, 2)),
);
}
}

View File

@ -1,44 +1,47 @@
<?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 RedMushroomBlock extends FlowableBlock{
public function __construct(){
parent::__construct(RED_MUSHROOM, 0, "Red Mushroom");
$this->isFlowable = true;
$this->hardness = 0;
}
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
if($block->inWorld === true){
$down = $level->getBlockFace($block, 0);
if($down->isTransparent === false){
$level->setBlock($block, $this->id, $this->getMetadata());
return true;
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
ServerAPI::request()->api->entity->drop($this, BlockAPI::getItem($this->id));
$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){
$down = $this->getSide(0);
if($down->isTransparent === false){
$this->level->setBlock($block, $this, true, false, true);
return true;
}
return false;
}
}

View File

@ -1,79 +1,83 @@
<?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 SaplingBlock extends TransparentBlock{
class SaplingBlock extends FlowableBlock{
const OAK = 0;
const SPRUCE = 1;
const BIRCH = 2;
const JUNGLE = 3;
const BURN_TIME = 5;
public function __construct($meta = Sapling::OAK){
parent::__construct(SAPLING, $meta, "Sapling");
$this->isActivable = true;
$this->isFlowable = true;
$names = array(
0 => "Oak Sapling",
1 => "Spruce Sapling",
2 => "Birch Sapling",
3 => "Jungle Sapling",
);
$this->name = $names[$this->meta & 0x03];
$this->hardness = 0;
}
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
if($block->inWorld === true){
$down = $level->getBlockFace($block, 0);
if($down->getID() === GRASS or $down->getID() === DIRT or $down->getID() === FARMLAND){
$level->setBlock($block, $this->id, $this->getMetadata());
return true;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
$down = $this->getSide(0);
if($down->getID() === GRASS or $down->getID() === DIRT or $down->getID() === FARMLAND){
$this->level->setBlock($block, $this, true, false, true);
$this->level->scheduleBlockUpdate(new Position($this, 0, 0, $this->level), Utils::getRandomUpdateTicks(), BLOCK_UPDATE_RANDOM);
return true;
}
return false;
}
public function onActivate(BlockAPI $level, Item $item, Player $player){
public function onActivate(Item $item, Player $player){
if($item->getID() === DYE and $item->getMetadata() === 0x0F){ //Bonemeal
TreeObject::growTree($level, $this);
TreeObject::growTree($this->level, $this, new Random(), $this->meta & 0x03);
if(($player->gamemode & 0x01) === 0){
$item->count--;
}
return true;
}
return false;
}
public function onUpdate(BlockAPI $level, $type){
if($this->inWorld !== true){
return false;
}
if($type === BLOCK_UPDATE_RANDOM and mt_rand(0,2) === 0){ //Growth
if(($this->meta & 0x08) === 0x08){
TreeObject::growTree($level, $this);
}else{
$this->meta |= 0x08;
$this->level->setBlock($this->x, $this->y, $this->z, $this->id, $this->meta);
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
ServerAPI::request()->api->entity->drop($this, BlockAPI::getItem($this->id));
$this->level->setBlock($this, new AirBlock(), false, false, true);
return BLOCK_UPDATE_NORMAL;
}
}elseif($type === BLOCK_UPDATE_RANDOM){ //Growth
if(mt_rand(1,7) === 1){
if(($this->meta & 0x08) === 0x08){
TreeObject::growTree($this->level, $this, new Random(), $this->meta & 0x03);
}else{
$this->meta |= 0x08;
$this->level->setBlock($this, $this, true, false, true);
return BLOCK_UPDATE_RANDOM;
}
}else{
return BLOCK_UPDATE_RANDOM;
}
return true;
}
return false;
}

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