Compare commits

..

274 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
164 changed files with 4143 additions and 1161 deletions

1
.gitignore vendored
View File

@ -3,6 +3,7 @@ worlds/*
plugins/*
logs/*
bin/*
.idea/*
*.log
*.pmf
*.txt

View File

@ -1,14 +1,13 @@
![](http://www.pocketmine.net/favicon.png)
# PocketMine-MP Contribution Gidelines
# PocketMine-MP Contribution Guidelines
Before contributing to PocketMine-MP, please read this.
## I've a question
* For questions, please refer to the _#mcpedevs_ IRC
channel on Freenode. There is a [WebIRC](http://webchat.freenode.net?channels=mcpedevs&uio=d4) if you want.
* You can ask directly to _[@PocketMine](https://twitter.com/PocketMine)_ in Twitter.
* 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.
@ -19,9 +18,56 @@ Before contributing to PocketMine-MP, please read this.
## 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.
* 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

@ -22,6 +22,7 @@
/***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***/
@ -30,4 +31,4 @@ $server = new ServerAPI();
$server->start();
kill(getmypid()); //Fix for ConsoleAPI being blocked
exit(0);
exit(0);

View File

@ -33,8 +33,8 @@ The entire server is done in PHP, and has been tested, profiled and optimized to
### [Twitter @PocketMine](https://twitter.com/PocketMine)
## IRC #pocketmine (or #mcpedevs) @ irc.freenode.net
* [WebIRC](http://webchat.freenode.net?channels=pocketmine,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/Protocols Used
@ -43,8 +43,8 @@ The entire server is done in PHP, and has been tested, profiled and optimized to
* __[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.
* __[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)__
* __[UT3 Query Protocol](http://wiki.unrealadmin.org/UT3_query_protocol)__

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

@ -21,9 +21,16 @@
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();//Command WhiteList
function __construct(){
@ -51,12 +58,20 @@ class BanAPI{
$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){//Whitelists a CMD so everyone can issue it - Even non OPs.
/**
* @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){//Is a player op?
/**
* @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;
@ -65,8 +80,14 @@ class BanAPI{
}
return false;
}
public function permissionsCheck($data, $event){
/**
* @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)){
@ -100,8 +121,16 @@ class BanAPI{
break;
}
}
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":
@ -132,14 +161,14 @@ class BanAPI{
$user = strtolower($params[0]);
$player = $this->server->api->player->get($user);
if(!($player instanceof Player)){
$this->ops->set($user, false);
$this->ops->save($user);
$this->ops->remove($user);
$this->ops->save();
$output .= $user." is no longer op\n";
break;
}
$this->ops->remove($player->iusername);
$this->ops->save();
$output .= $player->iusername." is not longer op\n";
$output .= $player->iusername." is no longer op\n";
$this->server->api->chat->sendTo(false, "You are no longer op.", $player->iusername);
break;
case "kick":
@ -153,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{
@ -274,24 +305,40 @@ class BanAPI{
}
return $output;
}
public function ban($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), "console", "");
}
/**
* @param string $ip
*/
public function banIP($ip){
$this->commandHandler("banip", array("add", $ip), "console", "");
}
/**
* @param string $ip
*/
public function pardonIP($ip){
$this->commandHandler("banip", array("pardon", $ip), "console", "");
}
public function kick($username, $reason = "No Reason"){
/**
* @param string $username
* @param string $reason
*/
public function kick($username, $reason = "No Reason"){
$this->commandHandler("kick", array($username, $reason), "console", "");
}
@ -300,33 +347,54 @@ class BanAPI{
$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->isOp($username)){
return true;
}elseif($this->server->api->dhandle("api.ban.whitelist.check", $username) === false){
return true;
}elseif($this->whitelist->exists($username)){
}elseif($this->whitelist->exists($username, true)){
return true;
}
return false;

View File

@ -24,14 +24,20 @@ class BlockAPI{
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(STONE, 0),
array(DIRT, 0),
array(GRASS, 0),
array(CLAY_BLOCK, 0),
@ -43,10 +49,15 @@ class BlockAPI{
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(WOODEN_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),
@ -54,7 +65,10 @@ class BlockAPI{
array(QUARTZ_STAIRS, 0),
array(SLAB, 0),
array(SLAB, 1),
array(SLAB, 2),
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),
@ -68,12 +82,19 @@ class BlockAPI{
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(OBSIDIAN, 0),
array(SNOW_BLOCK, 0),
array(COAL_BLOCK, 0),
array(SNOW_LAYER, 0),
array(GLASS, 0),
array(GLOWSTONE_BLOCK, 0),
array(NETHER_REACTOR, 0),
@ -94,15 +115,13 @@ class BlockAPI{
array(WOOL, 9),
array(WOOL, 8),
array(LADDER, 0),
array(TORCH, 0),
array(SPONGE, 0),
array(GLASS_PANE, 0),
array(BUCKET, 0),
array(BUCKET, 8),
array(BUCKET, 10),
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),
@ -110,33 +129,94 @@ class BlockAPI{
array(STONECUTTER, 0),
array(CHEST, 0),
array(FURNACE, 0),
array(TNT, 0),
array(DANDELION, 0),
array(CYAN_FLOWER, 0),
array(BROWN_MUSHROOM, 0),
array(RED_MUSHROOM, 0),
array(CACTUS, 0),
array(MELON_BLOCK, 0),
array(SUGARCANE, 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(SEEDS, 0),
array(MELON_SEEDS, 0),
array(DYE, 15), //Bonemeal
array(IRON_HOE, 0),
array(LEAVES, 3),
array(CAKE, 0),
array(EGG, 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(SIGN, 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),
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){
@ -167,12 +247,11 @@ 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 Position){
$b->position($v);
@ -270,7 +349,7 @@ class BlockAPI{
if($target->onBreak($item, $player) === false){
return $this->cancelAction($target, $player, false);
}
if($item->useOn($target) and ($player->gamemode & 0x01) === 0 and $item->getMetadata() >= $item->getMaxDurability()){
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{
@ -340,6 +419,12 @@ class BlockAPI{
return $this->cancelAction($block, $player, false);
}
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
}

View File

@ -32,8 +32,16 @@ class ChatAPI{
$this->server->api->ban->cmdWhitelist("tell");
$this->server->api->ban->cmdWhitelist("me");
}
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 "say":
@ -73,7 +81,7 @@ class ChatAPI{
$target = $target->username;
}else{
$target = strtolower($n);
if($t === "server" or $t === "console" or $t === "rcon"){
if($target === "server" or $target === "console" or $target === "rcon"){
$target = "Console";
}
}
@ -82,21 +90,37 @@ class ChatAPI{
if($target !== "Console" and $target !== "Rcon"){
$this->sendTo(false, "[".$sender." -> me] ".$mes, $target);
}
console("[INFO] [".$sender." -> ".$target."] ".$mes);
if($target === "Console" or $sender === "Console"){
console("[INFO] [".$sender." -> ".$target."] ".$mes);
}
break;
}
return $output;
}
public function broadcast($message){
/**
* @param string $message
*/
public function broadcast($message){
$this->send(false, $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){
/**
* @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,

View File

@ -128,7 +128,7 @@ class ConsoleAPI{
$max = ceil(count($cmds) / 5);
$page = (int) (isset($params[0]) ? min($max, max(1, intval($params[0]))):1);
$output .= "- Showing help page $page of $max (/help <page>) -\n";
$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);
@ -175,9 +175,9 @@ class ConsoleAPI{
return $this->run($this->alias[$cmd] . ($params !== "" ? " " .$params:""), $issuer, $cmd);
}
if($issuer instanceof Player){
console("[DEBUG] \x1b[33m".$issuer->username."\x1b[0m issued server command: ".ltrim("$alias ")."/$cmd ".$params, true, true, 2);
console("[DEBUG] ".FORMAT_AQUA.$issuer->username.FORMAT_RESET." issued server command: ".ltrim("$alias ")."/$cmd ".$params, true, true, 2);
}else{
console("[DEBUG] \x1b[33m*".$issuer."\x1b[0m issued server command: ".ltrim("$alias ")."/$cmd ".$params, true, true, 2);
console("[DEBUG] ".FORMAT_YELLOW."*".$issuer.FORMAT_RESET." issued server command: ".ltrim("$alias ")."/$cmd ".$params, true, true, 2);
}
if(preg_match_all('#@([@a-z]{1,})#', $params, $matches, PREG_OFFSET_CAPTURE) > 0){
@ -204,9 +204,26 @@ class ConsoleAPI{
break;
case "a":
case "all":
$output = "";
foreach($this->server->api->player->getAll() as $p){
$output .= $this->run($cmd . " ". substr_replace($params, $p->username, $selector[1] + $offsetshift - 1, strlen($selector[0]) + 1), $issuer, $alias);
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":
@ -256,7 +273,7 @@ class ConsoleAPI{
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;
$output = $this->run($line, "console");
if($output != ""){

View File

@ -2,11 +2,11 @@
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
@ -237,4 +237,9 @@ class LevelAPI{
}
}
}
public function getAll()
{
return $this->levels;
}
}

View File

@ -2,11 +2,11 @@
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
@ -15,456 +15,470 @@
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
*
*/
class PlayerAPI{
private $server;
function __construct(){
$this->server = ServerAPI::request();
}
private $server;
function __construct(){
$this->server = ServerAPI::request();
}
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 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":
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;
default:
$message = " died";
break;
}
}
$this->server->api->chat->broadcast($data["player"]->username . $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 "spawnpoint":
if(!($issuer instanceof Player)){
$output .= "Please run this command in-game.\n";
break;
}
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;
}
if(count($params) === 1 or count($params) === 4){
$target = $this->server->api->player->get(array_shift($params));
}else{
$target = $issuer;
}
if(!($target instanceof Player)){
$output .= "That player cannot be found.\n";
break;
}
if(count($params) === 3){
$spawn = new Position(floatval(array_shift($params)), floatval(array_shift($params)), floatval(array_shift($params)), $issuer->level);
}else{
$spawn = new Position($issuer->entity->x, $issuer->entity->y, $issuer->entity->z, $issuer->entity->level);
}
$target->setSpawn($spawn);
$output .= "Spawnpoint set correctly!\n";
break;
case "spawn":
if(!($issuer instanceof Player)){
$output .= "Please run this command in-game.\n";
break;
}
$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;
$gms = array(
"0" => SURVIVAL,
"survival" => SURVIVAL,
"s" => SURVIVAL,
"1" => CREATIVE,
"creative" => CREATIVE,
"c" => CREATIVE,
"2" => ADVENTURE,
"adventure" => ADVENTURE,
"a" => ADVENTURE,
"3" => VIEW,
"view" => VIEW,
"viewer" => VIEW,
"spectator" => VIEW,
"v" => VIEW,
);
if($issuer instanceof Player){
$player = $issuer;
}
if(isset($params[1])){
$player = $this->server->api->player->get($params[1]);
}
if(!($player instanceof Player) or !isset($gms[strtolower($params[0])])){
$output .= "Usage: /$cmd <mode> [player]\n";
break;
}
if($player->setGamemode($gms[strtolower($params[0])])){
$output .= "Gamemode of ".$player->username." changed to ".$player->getGamemode()."\n";
}
break;
case "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;
}
if(count($params) === 1 or count($params) === 4){
$target = $this->server->api->player->get(array_shift($params));
}else{
$target = $issuer;
}
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;
}
if(!($target instanceof Player)){
$output .= "That player cannot be found.\n";
break;
}
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;
}
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 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;
}
$target->setSpawn($spawn);
public function getAll($level = null){
if($level instanceof Level){
$clients = array();
$l = $this->server->query("SELECT EID FROM entities WHERE level = '".$level->getName()."' AND class = '".ENTITY_PLAYER."';");
if($l !== false and $l !== true){
while(($e = $l->fetchArray(SQLITE3_ASSOC)) !== false){
$e = $this->getByEID($e["EID"]);
if($e instanceof Player){
$clients[$e->CID] = $e;
}
}
}
return $clients;
}
return $this->server->clients;
}
public function broadcastPacket(array $players, $id, $data = array()){
$data = new CustomPacketHandler($id, "", $data, true);
$packet = array("raw" => chr($id).$data->raw);
foreach($players as $p){
$p->dataPacket(false, $packet);
}
}
$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 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 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];
$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)){
$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 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];
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 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(
"caseusername" => $name,
"position" => array(
"level" => $this->server->spawn->level->getName(),
"x" => $this->server->spawn->x,
"y" => $this->server->spawn->y,
"z" => $this->server->spawn->z,
),
"spawn" => array(
"level" => $this->server->spawn->level->getName(),
"x" => $this->server->spawn->x,
"y" => $this->server->spawn->y,
"z" => $this->server->spawn->z,
),
"inventory" => array_fill(0, PLAYER_SURVIVAL_SLOTS, array(AIR, 0, 0)),
"armor" => array_fill(0, 4, array(AIR, 0)),
"gamemode" => $this->server->gamemode,
"health" => 20,
"lastIP" => "",
"lastID" => 0,
);
if(!file_exists(DATA_PATH."players/".$iname.".yml")){
console("[NOTICE] Player data not found for \"".$iname."\", creating new profile");
$data = new Config(DATA_PATH."players/".$iname.".yml", CONFIG_YAML, $default);
$data->save();
}else{
$data = new Config(DATA_PATH."players/".$iname.".yml", CONFIG_YAML, $default);
}
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);
}
}
if(($data->get("gamemode") & 0x01) === 1){
$data->set("health", 20);
}
$this->server->handle("player.offline.get", $data);
return $data;
}
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 saveOffline(Config $data){
$this->server->handle("player.offline.save", $data);
$data->save();
}
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

@ -22,8 +22,10 @@
class PluginAPI extends stdClass{
private $server;
private $plugins = array();
private $randomNonce;
public function __construct(){
$this->server = ServerAPI::request();
$this->randomNonce = Utils::getRandomBytes(16, false);
}
public function getList(){
@ -33,17 +35,16 @@ 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();
@ -79,13 +80,13 @@ class PluginAPI extends stdClass{
console("[ERROR] Failed parsing of ".basename($file));
return false;
}
console("[INFO] Loading plugin \"\x1b[32m".$info["name"]."\x1b[0m\" \x1b[35m".$info["version"]." \x1b[0mby \x1b[36m".$info["author"]."\x1b[0m");
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 ($info["class"] !== "none" and !class_exists($info["class"]))){
console("[ERROR] 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;
}
@ -95,39 +96,60 @@ class PluginAPI extends stdClass{
console("[WARNING] Plugin \"".$info["name"]."\" may not be compatible with the API (".$info["apiversion"]." != ".CURRENT_API_VERSION.")! It can crash or corrupt the server!");
}
$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 \"\x1b[36m".$info["name"]."\x1b[0m\" doesn't use the Plugin Interface");
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[$className] = array($object, $info);
$this->plugins[$identifier] = array($object, $info);
}
}else{
$this->plugins[md5($info["name"])] = array(new DummyPlugin($this->server->api, false), $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;
}
@ -169,13 +191,13 @@ class PluginAPI extends stdClass{
$this->loadAll();
}
public function loadAll(){
$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);
}
}
}
@ -205,4 +227,4 @@ class DummyPlugin implements Plugin{
public function __destruct(){
}
}
}

View File

@ -29,7 +29,57 @@ class ServerAPI{
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;
}
@ -48,7 +98,7 @@ class ServerAPI{
@mkdir(DATA_PATH."worlds/", 0755);
@mkdir(DATA_PATH."plugins/", 0755);
$version = new VersionString();
console("[INFO] Starting Minecraft PE server version \x1b[36;1m".CURRENT_MINECRAFT_VERSION);
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(
@ -61,6 +111,7 @@ class ServerAPI{
"memory-limit" => "128M",
"last-update" => false,
"white-list" => false,
"announce-player-achievements" => true,
"spawn-protection" => 16,
"view-distance" => 10,
"max-players" => 20,
@ -92,7 +143,7 @@ class ServerAPI{
$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() ? "\x1b[31;1m":"").MAJOR_VERSION."\x1b[0m (MCPE: ".CURRENT_MINECRAFT_VERSION.") (API ".CURRENT_API_VERSION.")", true, true, 0);
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){
@ -102,39 +153,41 @@ class ServerAPI{
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 GIT_COMMIT != $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[36mGet it at PocketMine.net or ".$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\"");
}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] Get it at PocketMine.net or ".$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");
}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");
}
}
}
@ -276,6 +329,10 @@ class ServerAPI{
}
public function init(){
if(!(self::$serverRequest instanceof PocketMinecraftServer)){
self::$serverRequest = $this->server;
}
if($this->getProperty("send-usage") !== false){
$this->server->schedule(6000, array($this, "sendUsage"), array(), true); //Send the info after 5 minutes have passed
$this->sendUsage();

View File

@ -44,6 +44,7 @@ class Player{
private $startAction = false;
private $isSleeping = false;
public $data;
/** @var \Entity */
public $entity = false;
public $auth = false;
public $CID;
@ -58,6 +59,7 @@ class Player{
public $windowCnt = 2;
public $windows = array();
public $blocked = true;
public $achievements = array();
public $chunksLoaded = array();
private $chunksOrder = array();
private $lastMeasure = 0;
@ -77,6 +79,8 @@ class Player{
private $chunkCount = array();
private $received = array();
public $realmsData = array();
/** @var \Level */
public $level;
public function __get($name){
if(isset($this->{$name})){
@ -84,7 +88,13 @@ class Player{
}
return null;
}
/**
* @param integer $clientID
* @param string $ip
* @param integer $port
* @param integer $MTU
*/
public function __construct($clientID, $ip, $port, $MTU){
$this->bigCnt = 0;
$this->MTU = $MTU;
@ -111,9 +121,12 @@ class Player{
public function getSpawn(){
return $this->spawnPosition;
}
/**
* @param Vector3 $pos
*/
public function setSpawn(Vector3 $pos){
if(!($pos instanceof Level)){
if(!($pos instanceof Position)){
$level = $this->level;
}else{
$level = $pos->level;
@ -216,6 +229,7 @@ class Player{
public function save(){
if($this->entity instanceof Entity){
$this->data->set("achievements", $this->achievements);
$this->data->set("position", array(
"level" => $this->entity->level->getName(),
"x" => $this->entity->x,
@ -252,6 +266,10 @@ class Player{
}
}
/**
* @param string $reason Reason for closing connection
* @param boolean $msg Set to false to silently disconnect player. No broadcast.
*/
public function close($reason = "", $msg = true){
if($this->connected === true){
foreach($this->evid as $ev){
@ -280,7 +298,7 @@ class Player{
if($msg === true and $this->username != ""){
$this->server->api->chat->broadcast($this->username." left the game");
}
console("[INFO] \x1b[33m".$this->username."\x1b[0m[/".$this->ip.":".$this->port."] logged out due to ".$reason);
console("[INFO] ".FORMAT_AQUA.$this->username.FORMAT_RESET."[/".$this->ip.":".$this->port."] logged out due to ".$reason);
$this->windows = array();
$this->armor = array();
$this->inventory = array();
@ -291,17 +309,22 @@ class Player{
$this->received = array();
}
}
public function sleepOn(Vector3 $pos){
/**
* @param Vector3 $pos
*
* @return boolean
*/
public function sleepOn(Vector3 $pos){
foreach($this->server->api->player->getAll($this->level) as $p){
if($p->isSleeping instanceof Vector3){
if($p->distance($pos) <= 0.1){
if($pos->distance($p->isSleeping) <= 0.1){
return false;
}
}
}
$this->isSleeping = $pos;
$this->teleport(new Position($pos->x, $pos->y, $pos->z, $this->level));
$this->teleport(new Position($pos->x + 0.5, $pos->y + 1, $pos->z + 0.5, $this->level), false, false, false, false);
if($this->entity instanceof Entity){
$this->entity->updateMetadata();
}
@ -332,8 +355,15 @@ class Player{
}
}
}
public function hasSpace($type, $damage, $count){
/**
* @param $type
* @param $damage
* @param $count
*
* @return boolean
*/
public function hasSpace($type, $damage, $count){
$inv = $this->inventory;
while($count > 0){
$add = 0;
@ -351,7 +381,7 @@ class Player{
break;
}
}
if($add === 0){
if($add <= 0){
return false;
}
$count -= $add;
@ -359,7 +389,15 @@ class Player{
return true;
}
public function addItem($type, $damage, $count, $send = true){
/**
* @param $type
* @param $damage
* @param integer $count
* @param boolean $send
*
* @return boolean
*/
public function addItem($type, $damage, $count, $send = true){
while($count > 0){
$add = 0;
foreach($this->inventory as $s => $item){
@ -382,7 +420,7 @@ class Player{
break;
}
}
if($add === 0){
if($add <= 0){
return false;
}
$count -= $add;
@ -407,23 +445,35 @@ class Player{
break;
}
}
if($remove === 0){
if($remove <= 0){
return false;
}
$count -= $remove;
}
return true;
}
public function setSlot($slot, Item $item, $send = true){
/**
* @param integer $slot
* @param Item $item
* @param boolean $send
*
* @return boolean
*/
public function setSlot($slot, Item $item, $send = true){
$this->inventory[(int) $slot] = $item;
if($send === true){
$this->sendInventorySlot((int) $slot);
}
return true;
}
public function getSlot($slot){
/**
* @param integer $slot
*
* @return Item
*/
public function getSlot($slot){
if(isset($this->inventory[(int) $slot])){
return $this->inventory[(int) $slot];
}else{
@ -463,8 +513,13 @@ class Player{
}
return true;
}
public function getArmor($slot){
/**
* @param integer $slot
*
* @return Item
*/
public function getArmor($slot){
if(isset($this->armor[(int) $slot])){
return $this->armor[(int) $slot];
}else{
@ -480,8 +535,12 @@ class Player{
}
return false;
}
public function eventHandler($data, $event){
/**
* @param mixed $data
* @param string $event
*/
public function eventHandler($data, $event){
switch($event){
case "tile.update":
if($data->level === $this->level){
@ -534,6 +593,14 @@ class Player{
if(($this->gamemode & 0x01) === 0x00){
$this->addItem($data["entity"]->type, $data["entity"]->meta, $data["entity"]->stack, false);
}
switch($data["entity"]->type){
case WOOD:
AchievementAPI::grantAchievement($this, "mineWood");
break;
case DIAMOND:
AchievementAPI::grantAchievement($this, "diamond");
break;
}
}elseif($data["entity"]->level === $this->level){
$this->dataPacket(MC_TAKE_ITEM_ENTITY, $data);
}
@ -607,8 +674,12 @@ class Player{
break;
}
}
public function sendChat($message, $author = ""){
/**
* @param string $message
* @param string $author
*/
public function sendChat($message, $author = ""){
$mes = explode("\n", $message);
foreach($mes as $m){
if(preg_match_all('#@([@A-Za-z_]{1,})#', $m, $matches, PREG_OFFSET_CAPTURE) > 0){
@ -632,7 +703,7 @@ class Player{
if($m !== ""){
$this->dataPacket(MC_CHAT, array(
"player" => ($author instanceof Player) ? $author->username:$author,
"message" => $m,
"message" => TextFormat::clean($m), //Colors not implemented :(
));
}
}
@ -687,8 +758,15 @@ class Player{
"flags" => $flags,
));
}
public function craftItems(array $craft, array $recipe, $type){
/**
* @param array $craft
* @param array $recipe
* @param $type
*
* @return array|bool
*/
public function craftItems(array $craft, array $recipe, $type){
$craftItem = array(0, true, 0);
unset($craft[-1]);
foreach($craft as $slot => $item){
@ -726,6 +804,10 @@ class Player{
}
if(is_array($res)){
if($this->server->api->dhandle("player.craft", array("player" => $this, "recipe" => $recipe, "craft" => $craft, "type" => $type)) === false){
return false;
}
foreach($recipe as $slot => $item){
$s = $this->getSlot($slot);
$s->count -= $item->count;
@ -740,13 +822,59 @@ class Player{
}else{
$this->setSlot($slot, BlockAPI::getItem($item->getID(), $item->getMetadata(), $s->count + $item->count), false);
}
switch($item->getID()){
case WORKBENCH:
AchievementAPI::grantAchievement($this, "buildWorkBench");
break;
case WOODEN_PICKAXE:
AchievementAPI::grantAchievement($this, "buildPickaxe");
break;
case FURNACE:
AchievementAPI::grantAchievement($this, "buildFurnace");
break;
case WOODEN_HOE:
AchievementAPI::grantAchievement($this, "buildHoe");
break;
case BREAD:
AchievementAPI::grantAchievement($this, "makeBread");
break;
case CAKE:
AchievementAPI::grantAchievement($this, "bakeCake");
break;
case STONE_PICKAXE:
case GOLD_PICKAXE:
case IRON_PICKAXE:
case DIAMOND_PICKAXE:
AchievementAPI::grantAchievement($this, "buildBetterPickaxe");
break;
case WOODEN_SWORD:
AchievementAPI::grantAchievement($this, "buildSword");
break;
case DIAMOND:
AchievementAPI::grantAchievement($this, "diamond");
break;
case CAKE:
$this->addItem(BUCKET, 0, 3, false);
break;
}
}
}
return $res;
}
public function teleport(Vector3 $pos, $yaw = false, $pitch = false, $terrain = true, $force = true){
if($this->entity instanceof Entity){
/**
* @param Vector3 $pos
* @param float|boolean $yaw
* @param float|boolean $pitch
* @param float|boolean $terrain
* @param float|boolean $force
*
* @return boolean
*/
public function teleport(Vector3 $pos, $yaw = false, $pitch = false, $terrain = true, $force = true){
if($this->entity instanceof Entity and $this->level instanceof Level){
$this->entity->check = false;
if($yaw === false){
$yaw = $this->entity->yaw;
@ -852,8 +980,9 @@ class Player{
"x" => $pos->x,
"y" => $pos->y,
"z" => $pos->z,
"yaw" => $yaw,
"bodyYaw" => $yaw,
"pitch" => $pitch,
"yaw" => $yaw,
));
}
@ -1099,10 +1228,10 @@ class Player{
case MC_PONG:
break;
case MC_PING:
$t = (int) (microtime(true) * 1000);
$t = abs(microtime(true) * 1000);
$this->dataPacket(MC_PONG, array(
"ptime" => $data["time"],
"time" => (int) (microtime(true) * 1000),
"time" => $t,
));
$this->sendBuffer();
break;
@ -1167,7 +1296,7 @@ class Player{
}
$this->loggedIn = true;
$u = $this->server->api->player->get($this->iusername);
$u = $this->server->api->player->get($this->iusername, false);
if($u !== false){
$u->close("logged in from another location");
}
@ -1199,6 +1328,7 @@ class Player{
}
$this->data->set("inventory", $inv);
}
$this->achievements = $this->data->get("achievements");
$this->data->set("caseusername", $this->username);
$this->inventory = array();
foreach($this->data->get("inventory") as $slot => $item){
@ -1216,9 +1346,8 @@ class Player{
$this->data->set("lastIP", $this->ip);
$this->data->set("lastID", $this->clientID);
if($this->data instanceof Config){
$this->server->api->player->saveOffline($this->data);
}
$this->server->api->player->saveOffline($this->data);
$this->dataPacket(MC_LOGIN_STATUS, array(
"status" => 0,
));
@ -1232,7 +1361,7 @@ class Player{
"eid" => 0,
));
if(($this->gamemode & 0x01) === 0x01){
$this->slot = -1;//7
$this->slot = 0;
}else{
$this->slot = -1;//0
}
@ -1265,7 +1394,7 @@ class Player{
$this->evid[] = $this->server->event("tile.update", array($this, "eventHandler"));
$this->lastMeasure = microtime(true);
$this->server->schedule(50, array($this, "measureLag"), array(), true);
console("[INFO] \x1b[33m".$this->username."\x1b[0m[/".$this->ip.":".$this->port."] logged in with entity id ".$this->eid." at (".$this->entity->level->getName().", ".round($this->entity->x, 2).", ".round($this->entity->y, 2).", ".round($this->entity->z, 2).")");
console("[INFO] ".FORMAT_AQUA.$this->username.FORMAT_RESET."[/".$this->ip.":".$this->port."] logged in with entity id ".$this->eid." at (".$this->entity->level->getName().", ".round($this->entity->x, 2).", ".round($this->entity->y, 2).", ".round($this->entity->z, 2).")");
break;
case MC_READY:
if($this->loggedIn === false){
@ -1284,6 +1413,7 @@ class Player{
$this->server->api->entity->spawnToAll($this->entity);
$this->server->schedule(5, array($this->entity, "update"), array(), true);
$this->server->schedule(2, array($this->entity, "updateMovement"), array(), true);
$this->sendArmor();
$this->sendChat($this->server->motd."\n");
@ -1297,16 +1427,32 @@ class Player{
$this->dataPacket(MC_SET_TIME, array(
"time" => $this->level->getTime(),
));
$this->teleport(new Position($this->data->get("position")["x"], $this->data->get("position")["y"], $this->data->get("position")["z"], $this->level));
$this->server->schedule(10, array($this, "teleport"), new Position($this->data->get("position")["x"], $this->data->get("position")["y"], $this->data->get("position")["z"], $this->level));
$this->server->schedule(20, array($this, "teleport"), new Position($this->data->get("position")["x"], $this->data->get("position")["y"], $this->data->get("position")["z"], $this->level));
$this->server->schedule(30, array($this, "teleport"), new Position($this->data->get("position")["x"], $this->data->get("position")["y"], $this->data->get("position")["z"], $this->level));
$pos = new Position($this->data->get("position")["x"], $this->data->get("position")["y"], $this->data->get("position")["z"], $this->level);
$pos = $this->level->getSafeSpawn($pos);
$this->teleport($pos);
$this->server->schedule(10, array($this, "teleport"), $pos);
$this->server->schedule(20, array($this, "teleport"), $pos);
$this->server->schedule(30, array($this, "teleport"), $pos);
$this->server->handle("player.spawn", $this);
break;
case 2://Chunk loaded?
break;
}
break;
case MC_ROTATE_HEAD:
if($this->spawned === false){
break;
}
if(($this->entity instanceof Entity)){
if($this->blocked === true or $this->server->api->handle("player.move", $this->entity) === false){
if($this->lastCorrect instanceof Vector3){
$this->teleport($this->lastCorrect, $this->entity->yaw, $this->entity->pitch, false);
}
}else{
$this->entity->setPosition($this->entity, $data["yaw"], $data["pitch"]);
}
}
break;
case MC_MOVE_PLAYER:
if($this->spawned === false){
break;
@ -1321,7 +1467,7 @@ class Player{
}
}
$speed = $this->entity->getSpeedMeasure();
if($this->blocked === true or ($this->server->api->getProperty("allow-flight") !== true and (($speed > 7 and ($this->gamemode & 0x01) === 0x00) or $speed > 15)) or $this->server->api->handle("player.move", $this->entity) === false){
if($this->blocked === true or ($this->server->api->getProperty("allow-flight") !== true and (($speed > 9 and ($this->gamemode & 0x01) === 0x00) or $speed > 20)) or $this->server->api->handle("player.move", $this->entity) === false){
if($this->lastCorrect instanceof Vector3){
$this->teleport($this->lastCorrect, $this->entity->yaw, $this->entity->pitch, false);
}
@ -1341,7 +1487,7 @@ class Player{
$data["eid"] = $this->eid;
$data["player"] = $this;
if($data["slot"] === 0){
if($data["slot"] === 0x28 or $data["slot"] === 0){ //0 for 0.8.0 compatibility
$data["slot"] = -1;
$data["item"] = BlockAPI::getItem(AIR, 0, 0);
if($this->server->handle("player.equipment.change", $data) !== false){
@ -1352,9 +1498,26 @@ class Player{
$data["slot"] -= 9;
}
$data["item"] = $this->getSlot($data["slot"]);
if(!($data["item"] instanceof Item)){
break;
if(($this->gamemode & 0x01) === SURVIVAL){
$data["item"] = $this->getSlot($data["slot"]);
if(!($data["item"] instanceof Item)){
break;
}
}elseif(($this->gamemode & 0x01) === CREATIVE){
$data["slot"] = false;
foreach(BlockAPI::$creative as $i => $d){
if($d[0] === $data["block"] and $d[1] === $data["meta"]){
$data["slot"] = $i;
}
}
if($data["slot"] !== false){
$data["item"] = $this->getSlot($data["slot"]);
}else{
break;
}
}else{
break;//?????
}
$data["block"] = $data["item"]->getID();
$data["meta"] = $data["item"]->getMetadata();
@ -1451,6 +1614,53 @@ class Player{
"z" => $this->entity->z,
);
$e = $this->server->api->entity->add($this->level, ENTITY_OBJECT, OBJECT_ARROW, $d);
$e->yaw = $this->entity->yaw;
$e->pitch = $this->entity->pitch;
$rotation = ($this->entity->yaw - 90) % 360;
if($rotation < 0){
$rotation = (360 + $rotation);
}
$rotation = ($rotation + 180);
if($rotation >= 360){
$rotation = ($rotation - 360);
}
$X = 1;
$Z = 1;
$overturn = false;
if(0 <= $rotation and $rotation < 90){
}
elseif(90 <= $rotation and $rotation < 180){
$rotation -= 90;
$X = (-1);
$overturn = true;
}
elseif(180 <= $rotation and $rotation < 270){
$rotation -= 180;
$X = (-1);
$Z = (-1);
}
elseif(270 <= $rotation and $rotation < 360){
$rotation -= 270;
$Z = (-1);
$overturn = true;
}
$rad = deg2rad($rotation);
$pitch = (-($this->entity->pitch));
$speed = 80;
$speedY = (sin(deg2rad($pitch)) * $speed);
$speedXZ = (cos(deg2rad($pitch)) * $speed);
if($overturn){
$speedX = (sin($rad) * $speedXZ * $X);
$speedZ = (cos($rad) * $speedXZ * $Z);
}
else{
$speedX = (cos($rad) * $speedXZ * $X);
$speedZ = (sin($rad) * $speedXZ * $Z);
}
$e->speedX = $speedX;
$e->speedZ = $speedZ;
$e->speedY = $speedY;
$this->server->api->entity->spawnToAll($e);
}
}
@ -1617,6 +1827,7 @@ class Player{
}
$this->craftingItems = array();
$this->toCraft = array();
$this->teleport($this->spawnPosition);
if($this->entity instanceof Entity){
$this->entity->fire = 0;
$this->entity->air = 300;
@ -1626,7 +1837,6 @@ class Player{
break;
}
$this->sendInventory();
$this->teleport($this->spawnPosition);
$this->blocked = false;
$this->server->handle("player.respawn", $this);
break;
@ -1648,6 +1858,7 @@ class Player{
$items = array(
APPLE => 2,
MUSHROOM_STEW => 10,
BEETROOT_SOUP => 10,
BREAD => 5,
RAW_PORKCHOP => 3,
COOKED_PORKCHOP => 8,
@ -1657,6 +1868,10 @@ class Player{
RAW_CHICKEN => 2,
MELON_SLICE => 2,
GOLDEN_APPLE => 10,
PUMPKIN_PIE => 8,
CARROT => 4,
POTATO => 1,
BAKED_POTATO => 6,
//COOKIE => 2,
//COOKED_FISH => 5,
//RAW_FISH => 2,
@ -1672,6 +1887,9 @@ class Player{
if($slot->count <= 0){
$this->setSlot($this->slot, BlockAPI::getItem(AIR, 0, 0), false);
}
if($slot->getID() === MUSHROOM_STEW or $slot->getID() === BEETROOT_SOUP){
$this->addItem(BOWL, 0, 1, false);
}
}
break;
}
@ -1703,8 +1921,13 @@ class Player{
if($message{0} === "/"){ //Command
$this->server->api->console->run(substr($message, 1), $this);
}else{
if($this->server->api->dhandle("player.chat", array("player" => $this, "message" => $message)) !== false){
$this->server->api->chat->send($this, $message);
$data = array("player" => $this, "message" => $message);
if($this->server->api->handle("player.chat", $data) !== false){
if(isset($data["message"])){
$this->server->api->chat->send($this, $data["message"]);
}else{
$this->server->api->chat->send($this, $message);
}
}
}
}
@ -1717,9 +1940,8 @@ class Player{
$this->toCraft = array();
if(isset($this->windows[$data["windowid"]])){
if(is_array($this->windows[$data["windowid"]])){
$all = $this->server->api->player->getAll($this->level);
foreach($this->windows[$data["windowid"]] as $ob){
$this->server->api->player->broadcastPacket($all, MC_TILE_EVENT, array(
$this->server->api->player->broadcastPacket($this->level->players, MC_TILE_EVENT, array(
"x" => $ob->x,
"y" => $ob->y,
"z" => $ob->z,
@ -1876,6 +2098,15 @@ class Player{
));
break;
}
if($tile->class === TILE_FURNACE and $data["slot"] == 2){
switch($slot->getID()){
case IRON_INGOT:
AchievementAPI::grantAchievement($this, "acquireIron");
break;
}
}
if($item->getID() !== AIR and $slot->getID() == $item->getID()){
if($slot->count < $item->count){
if($this->removeItem($item->getID(), $item->getMetadata(), $item->count - $slot->count, false) === false){
@ -1925,8 +2156,11 @@ class Player{
break;
}
}
public function sendArmor($player = false){
/**
* @param Player|string|boolean|void $player
*/
public function sendArmor($player = false){
$data = array(
"player" => $this,
"eid" => $this->eid
@ -1957,6 +2191,9 @@ class Player{
}
public function sendInventory(){
if(($this->gamemode & 0x01) === CREATIVE){
return;
}
$this->dataPacket(MC_CONTAINER_SET_CONTENT, array(
"windowid" => 0,
"count" => count($this->inventory),
@ -2025,7 +2262,13 @@ class Player{
return array($count);
}
public function dataPacket($id, $data = array()){
/**
* @param integer $id
* @param array $data
*
* @return array|bool
*/
public function dataPacket($id, $data = array()){
$data["id"] = $id;
if($id === false){
$raw = $data["raw"];
@ -2045,8 +2288,11 @@ class Player{
$this->buffer .= ($this->buffer === "" ? "":"\x40").Utils::writeShort($len << 3).strrev(Utils::writeTriad($this->counter[3]++)).$raw;
return array();
}
function __toString(){
/**
* @return string
*/
function __toString(){
if($this->username != ""){
return $this->username;
}

View File

@ -21,14 +21,19 @@
class PocketMinecraftServer{
public $tCnt;
public $serverID, $interface, $database, $version, $invisible, $api, $tickMeasure, $preparedSQL, $seed, $gamemode, $name, $maxClients, $clients, $eidCnt, $custom, $description, $motd, $port, $saveEnabled;
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();
if(defined("DEBUG") and DEBUG >= 0){
/*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;
@ -80,7 +85,10 @@ class PocketMinecraftServer{
$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);
@ -174,7 +182,10 @@ class PocketMinecraftServer{
return $info;
}
public function close($reason = "server stop"){
/**
* @param string $reason
*/
public function close($reason = "server stop"){
if($this->stop !== true){
if(is_int($reason)){
$reason = "signal stop";
@ -266,7 +277,14 @@ class PocketMinecraftServer{
}
}
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])){
@ -334,7 +352,10 @@ class PocketMinecraftServer{
}
}
public function getGamemode(){
/**
* @return string
*/
public function getGamemode(){
switch($this->gamemode){
case SURVIVAL:
return "survival";
@ -421,8 +442,9 @@ class PocketMinecraftServer{
}
$dump .= "\r\n\r\n";
$version = new VersionString();
$dump .= "PM Version: ".$version." #".$version->getNumber()." [Protocol ".CURRENT_PROTOCOL."]\r\n";
$dump .= "Commit: ".GIT_COMMIT."\r\n";
$dump .= "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";

View File

@ -1,13 +1,13 @@
#!/bin/bash
COMPILER_VERSION="0.13"
COMPILER_VERSION="0.14"
PHP_VERSION="5.5.3"
PHP_VERSION="5.5.8"
ZEND_VM="GOTO"
LIBEDIT_VERSION="0.3"
ZLIB_VERSION="1.2.8"
PTHREADS_VERSION="0.0.44"
CURL_VERSION="curl-7_32_0"
PTHREADS_VERSION="0.0.45"
CURL_VERSION="curl-7_34_0"
echo "[PocketMine] PHP installer and compiler for Linux & Mac"
DIR="$(pwd)"
@ -78,6 +78,9 @@ elif [ "$1" == "crosscompile" ]; then
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; }
@ -231,6 +234,7 @@ fi
--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 \
@ -240,9 +244,12 @@ $HAVE_LIBEDIT \
--disable-xmlwriter \
--disable-cgi \
--disable-session \
--disable-zip \
--disable-debug \
--disable-phar \
--disable-pdo \
--without-pear \
--without-iconv \
--without-pdo-sqlite \
--enable-ctype \
--enable-sockets \
--enable-shared=no \
@ -255,10 +262,7 @@ $HAVE_LIBEDIT \
--enable-embedded-mysqli \
--enable-bcmath \
--enable-cli \
--without-pear \
--without-iconv \
--disable-pdo \
--without-pdo-sqlite \
--enable-zip \
--with-zend-vm=$ZEND_VM \
$CONFIGURE_FLAGS >> "$DIR/install.log" 2>&1
echo -n " compiling..."
@ -276,5 +280,5 @@ mv php5/bin/php bin/php
rm -r -f php5/ >> "$DIR/install.log" 2>&1
date >> "$DIR/install.log" 2>&1
echo " done!"
echo "[PocketMine] You should start the server now using \"./start.sh\""
echo "[PocketMine] If it doesn't works, please send the \"install.log\" file to the Bug Tracker"
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

@ -28,7 +28,7 @@ if(strpos(" ".strtoupper(php_uname("s")), " WIN") !== false){
exec("time.exe /T", $hour);
$i = array_map("intval", explode(":", trim($hour[0])));
exec("date.exe /T", $date);
$j = array_map("intval", explode("/", trim($date[0])));
$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);
@ -44,7 +44,7 @@ if($daylight === 0){
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("display_startup_errors", 1);
@ -59,13 +59,14 @@ set_include_path(get_include_path() . PATH_SEPARATOR . FILE_PATH);
ini_set("memory_limit", "128M"); //Default
define("LOG", true);
define("START_TIME", microtime(true));
define("MAJOR_VERSION", "Alpha_1.3.8");
define("CURRENT_MINECRAFT_VERSION", "0.7.5 alpha");
define("CURRENT_API_VERSION", 10);
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"))));
define("GIT_COMMIT", strtolower(trim(file_get_contents(FILE_PATH.".git/refs/heads/master"))));
}else{ //Unknown :(
define(GIT_COMMIT, str_repeat("00", 20));
define("GIT_COMMIT", str_repeat("00", 20));
}

View File

@ -45,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);
@ -83,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);
@ -120,12 +122,15 @@ 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);
@ -133,10 +138,12 @@ 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);
@ -150,9 +157,37 @@ 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

@ -62,6 +62,7 @@ define("ENTITY_MOB", 2);
define("MOB_PIGMAN", 36);
define("ENTITY_OBJECT", 3);
define("OBJECT_PRIMEDTNT", 65);
define("OBJECT_ARROW", 80);
define("OBJECT_PAINTING", 83);

View File

@ -98,9 +98,11 @@ 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);
@ -116,6 +118,7 @@ define("SLIMEBALL", 341);
define("EGG", 344);
define("COMPASS", 345);
define("CLOCK", 347);
define("GLOWSTONE_DUST", 348);
//define("RAW_FISH", 349);
//define("COOKED_FISH", 350);
@ -132,7 +135,7 @@ define("BED", 355);
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);
@ -143,8 +146,21 @@ 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("BEETROOT", 457);
define("BEETROOT_SEEDS", 458);
define("BEETROOT_SEED", 458);
define("BEETROOT_SOUP", 459);

View File

@ -21,11 +21,12 @@
/***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(arg("enable-ansi", strpos(strtoupper(php_uname("s")), "WIN") === false ? true: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);
@ -75,10 +76,22 @@ if($errors > 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

@ -142,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(
@ -182,35 +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(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;
}

View File

@ -40,6 +40,7 @@ abstract class Block extends Position{
COAL_ORE => "CoalOreBlock",
WOOD => "WoodBlock",
LEAVES => "LeavesBlock",
SPONGE => "SpongeBlock",
GLASS => "GlassBlock",
LAPIS_ORE => "LapisOreBlock",
LAPIS_BLOCK => "LapisBlock",
@ -94,20 +95,22 @@ abstract class Block extends Position{
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",
@ -119,10 +122,26 @@ abstract class Block extends Position{
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",
@ -131,6 +150,7 @@ abstract class Block extends Position{
protected $meta;
protected $name;
protected $breakTime;
protected $hardness;
public $isActivable = false;
public $breakable = true;
public $isFlowable = false;
@ -151,6 +171,11 @@ abstract class Block extends Position{
$this->meta = (int) $meta;
$this->name = $name;
$this->breakTime = 0.20;
$this->hardness = 10;
}
final public function getHardness(){
return ($this->hardness);
}
final public function getName(){

View File

@ -23,7 +23,13 @@ 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",
@ -137,6 +143,10 @@ class Item{
$this->meta++;
}
return true;
}elseif($this->isHoe()){
if(($object instanceof Block) and ($object->getID() === GRASS or $object->getID() === DIRT)){
$this->meta++;
}
}
return false;
}

View File

@ -20,12 +20,22 @@
*/
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 onUpdate($type){
/**
* @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);
@ -38,7 +48,19 @@ class DoorBlock extends TransparentBlock{
return false;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
/**
* @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);
@ -66,8 +88,14 @@ class DoorBlock extends TransparentBlock{
}
return false;
}
public function onBreak(Item $item, Player $player){
/**
* @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){
@ -82,19 +110,43 @@ class DoorBlock extends TransparentBlock{
$this->level->setBlock($this, new AirBlock(), true, false, true);
return true;
}
public function onActivate(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 = $this->getSide(0);
if($down->getID() === $this->id){
$meta = $down->getMetadata() ^ 0x04;
$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;
$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

@ -20,12 +20,29 @@
*/
class FallableBlock extends SolidBlock{
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->hasPhysics = true;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
/**
* @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

@ -20,7 +20,12 @@
*/
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;

View File

@ -21,22 +21,57 @@
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(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
}
/**
* @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);
}
public function isBreakable(Item $item, Player $player){
/**
* @param Item $item
* @param Player $player
*
* @return boolean
*/
public function isBreakable(Item $item, Player $player){
return ($this->breakable);
}
public function onBreak(Item $item, Player $player){
/**
* @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);
}
public function onUpdate($type){
/**
* @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)){
@ -57,7 +92,13 @@ class GenericBlock extends Block{
return false;
}
public function onActivate(Item $item, Player $player){
/**
* @param Item $item
* @param Player $player
*
* @return boolean
*/
public function onActivate(Item $item, Player $player){
return $this->isActivable;
}
}

View File

@ -20,7 +20,12 @@
*/
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;

View File

@ -20,7 +20,12 @@
*/
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

@ -20,16 +20,34 @@
*/
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(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
/**
* @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,
@ -43,8 +61,14 @@ class StairBlock extends TransparentBlock{
$this->level->setBlock($block, $this, true, false, true);
return true;
}
public function getDrops(Item $item, Player $player){
/**
* @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),

View File

@ -20,7 +20,12 @@
*/
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;

View File

@ -24,6 +24,7 @@ class LadderBlock extends TransparentBlock{
parent::__construct(LADDER, $meta, "Ladder");
$this->isSolid = false;
$this->isFullBlock = false;
$this->hardness = 2;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
if($target->isTransparent === false){
@ -41,6 +42,18 @@ class LadderBlock extends TransparentBlock{
}
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

@ -24,6 +24,7 @@ class SignPostBlock extends TransparentBlock{
parent::__construct(SIGN_POST, $meta, "Sign Post");
$this->isSolid = false;
$this->isFullBlock = false;
$this->hardness = 5;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){

View File

@ -22,6 +22,7 @@
class TorchBlock extends FlowableBlock{
public function __construct($meta = 0){
parent::__construct(TORCH, $meta, "Torch");
$this->hardness = 0;
}
public function onUpdate($type){

View File

@ -28,6 +28,7 @@ class TrapdoorBlock extends TransparentBlock{
}else{
$this->isFullBlock = true;
}
$this->hardness = 15;
}
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){

View File

@ -22,6 +22,121 @@
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

@ -22,6 +22,7 @@
class StillLavaBlock extends LiquidBlock{
public function __construct($meta = 0){
parent::__construct(STILL_LAVA, $meta, "Still Lava");
$this->hardness = 500;
}
}

View File

@ -27,6 +27,7 @@ require_once("Water.php");
class StillWaterBlock extends WaterBlock{
public function __construct($meta = 0){
LiquidBlock::__construct(STILL_WATER, $meta, "Still Water");
$this->hardness = 500;
}
}

View File

@ -22,91 +22,125 @@
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 onUpdate($type){
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);
if($falling === 0){
$countSources = 0;
$maxLevel = $level;
$hasPath = false;
for($side = 2; $side <= 5; ++$side){
$b = $this->getSide($side);
if($b->isFlowable === true and $level < 0x07){
$d = $b->getSide(0);
$this->level->setBlock($b, new WaterBlock($level + 1), false, false, true);
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($b, 0, 0, $this->level), 10, BLOCK_UPDATE_NORMAL);
}elseif($b instanceof WaterBlock){
$oLevel = $b->getMetadata();
$oFalling = $oLevel >> 3;
$oLevel &= 0x07;
if($oFalling === 0){
if($oLevel === 0){
++$countSources;
$maxLevel = 1;
$hasPath = true;
}elseif($oLevel < 0x07 and ($oLevel + 1) <= $maxLevel){
$maxLevel = $oLevel + 1;
$hasPath = true;
}elseif(($level + 1) < $oLevel){
$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);
}elseif($level === $oLevel){
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($b, 0, 0, $this->level), 10, BLOCK_UPDATE_NORMAL);
}
}
}
}
if($countSources >= 2){
$level = 0; //Source block
}elseif($maxLevel < $level){
$level = $maxLevel;
}elseif($maxLevel === $level and $level > 0 and $hasPath === false){
if($level < 0x07){
++$level;
}else{
$newId = AIR;
$level = 0;
}
}
}
if($down->isFlowable){
$this->level->setBlock($down, new WaterBlock(0b1001), false, false, true);
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($down, 0, 0, $this->level), 5, BLOCK_UPDATE_NORMAL);
return false;
}elseif($down instanceof LiquidBlock){
if($down instanceof WaterBlock and ($down->getMetadata() >> 3) === 0){
$this->level->setBlock($down, new WaterBlock(0b1000 & min($down->getMetadata(), 1)), false, false, true);
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($down, 0, 0, $this->level), 5, BLOCK_UPDATE_NORMAL);
}
}else{
$falling = 0;
}
$newMeta = ($falling << 0x03) | $level;
if($newMeta !== $this->meta or $newId !== $this->id){
$this->id = $newId;
$this->meta = $newMeta;
$this->level->setBlock($this, $this, false, false, true);
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($this, 0, 0, $this->level), 10, BLOCK_UPDATE_NORMAL);
return false;
//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

@ -31,6 +31,7 @@ class AirBlock extends TransparentBlock{
$this->hasPhysics = false;
$this->isSolid = false;
$this->isFullBlock = true;
$this->hardness = 0;
}

View File

@ -24,6 +24,7 @@ class BedBlock extends TransparentBlock{
parent::__construct(BED_BLOCK, $type, "Bed Block");
$this->isActivable = true;
$this->isFullBlock = false;
$this->hardness = 1;
}
public function onActivate(Item $item, Player $player){
@ -33,7 +34,31 @@ class BedBlock extends TransparentBlock{
));
return true;
}
if($player->sleepOn($this) === false){
$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"
));

View File

@ -25,6 +25,7 @@ class FireBlock extends FlowableBlock{
$this->isReplaceable = true;
$this->breakable = false;
$this->isFullBlock = true;
$this->hardness = 0;
}
public function getDrops(Item $item, Player $player){

View File

@ -22,5 +22,27 @@
class TNTBlock extends SolidBlock{
public function __construct(){
parent::__construct(TNT, 0, "TNT");
$this->hardness = 0;
$this->isActivable = true;
}
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 false;
}
}

View File

@ -25,6 +25,16 @@ class CakeBlock extends TransparentBlock{
$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){

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

@ -24,6 +24,7 @@ class CobwebBlock extends FlowableBlock{
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

@ -23,6 +23,7 @@ class FenceBlock extends TransparentBlock{
public function __construct(){
parent::__construct(FENCE, 0, "Fence");
$this->isFullBlock = false;
$this->hardness = 15;
}
}

View File

@ -28,6 +28,7 @@ class FenceGateBlock extends TransparentBlock{
}else{
$this->isFullBlock = false;
}
$this->hardness = 15;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
$faces = array(

View File

@ -22,6 +22,8 @@
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

@ -23,6 +23,7 @@ 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){

View File

@ -29,7 +29,6 @@ class SlabBlock extends TransparentBlock{
3 => "Cobblestone",
4 => "Brick",
5 => "Stone Brick",
//6 => "Nether Brick",
6 => "Quartz",
);
$this->name = (($this->meta & 0x08) === 0x08 ? "Upper ":"") . $names[$this->meta & 0x07] . " Slab";
@ -37,7 +36,8 @@ class SlabBlock extends TransparentBlock{
$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){
@ -46,6 +46,9 @@ class SlabBlock extends TransparentBlock{
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;
}
@ -53,6 +56,9 @@ class SlabBlock extends TransparentBlock{
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){

View File

@ -25,6 +25,16 @@ class SnowLayerBlock extends FlowableBlock{
$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){

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

@ -23,6 +23,7 @@ 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){

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,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,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

@ -23,5 +23,30 @@ 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

@ -22,6 +22,7 @@
class CoalOreBlock extends SolidBlock{
public function __construct(){
parent::__construct(COAL_ORE, 0, "Coal Ore");
$this->hardness = 15;
}
public function getBreakTime(Item $item, Player $player){

View File

@ -22,6 +22,7 @@
class DiamondOreBlock extends SolidBlock{
public function __construct(){
parent::__construct(DIAMOND_ORE, 0, "Diamond Ore");
$this->hardness = 15;
}
public function getBreakTime(Item $item, Player $player){

View File

@ -22,6 +22,7 @@
class GlowingRedstoneOreBlock extends SolidBlock{
public function __construct(){
parent::__construct(GLOWING_REDSTONE_ORE, 0, "Glowing Redstone Ore");
$this->hardness = 15;
}
public function onUpdate($type){
@ -52,7 +53,7 @@ class GlowingRedstoneOreBlock extends SolidBlock{
public function getDrops(Item $item, Player $player){
if($item->isPickaxe() >= 4){
return array(
//array(331, 4, mt_rand(4, 5)),
array(REDSTONE_DUST, 0, mt_rand(4, 5)),
);
}else{
return array();

View File

@ -22,6 +22,7 @@
class GoldOreBlock extends SolidBlock{
public function __construct(){
parent::__construct(GOLD_ORE, 0, "Gold Ore");
$this->hardness = 15;
}
public function getBreakTime(Item $item, Player $player){

View File

@ -22,6 +22,7 @@
class IronOreBlock extends SolidBlock{
public function __construct(){
parent::__construct(IRON_ORE, 0, "Iron Ore");
$this->hardness = 15;
}
public function getBreakTime(Item $item, Player $player){

View File

@ -22,6 +22,7 @@
class LapisOreBlock extends SolidBlock{
public function __construct(){
parent::__construct(LAPIS_ORE, 0, "Lapis Ore");
$this->hardness = 15;
}
public function getBreakTime(Item $item, Player $player){

View File

@ -22,6 +22,7 @@
class RedstoneOreBlock extends SolidBlock{
public function __construct(){
parent::__construct(REDSTONE_ORE, 0, "Redstone Ore");
$this->hardness = 15;
}
public function onUpdate($type){
@ -36,7 +37,7 @@ class RedstoneOreBlock extends SolidBlock{
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

@ -22,6 +22,7 @@
class BrownMushroomBlock extends FlowableBlock{
public function __construct(){
parent::__construct(BROWN_MUSHROOM, 0, "Brown Mushroom");
$this->hardness = 0;
}
public function onUpdate($type){

View File

@ -23,6 +23,7 @@ class CactusBlock extends TransparentBlock{
public function __construct($meta = 0){
parent::__construct(CACTUS, $meta, "Cactus");
$this->isFullBlock = false;
$this->hardness = 2;
}
public function onUpdate($type){

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

@ -22,6 +22,7 @@
class CyanFlowerBlock extends FlowableBlock{
public function __construct(){
parent::__construct(CYAN_FLOWER, 0, "Cyan Flower");
$this->hardness = 0;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){

View File

@ -22,6 +22,7 @@
class DandelionBlock extends FlowableBlock{
public function __construct(){
parent::__construct(DANDELION, 0, "Dandelion");
$this->hardness = 0;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){

View File

@ -22,7 +22,8 @@
class DeadBushBlock extends FlowableBlock{
public function __construct(){
parent::__construct(DEAD_BUSH, 0, "Dead Bush");
$this->isReplaceable = true;
//$this->isReplaceable = true;
$this->hardness = 0;
}
public function onUpdate($type){

View File

@ -23,6 +23,7 @@ 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(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
$down = $this->getSide(0);

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

@ -22,6 +22,7 @@
class RedMushroomBlock extends FlowableBlock{
public function __construct(){
parent::__construct(RED_MUSHROOM, 0, "Red Mushroom");
$this->hardness = 0;
}
public function onUpdate($type){

View File

@ -23,6 +23,7 @@ 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){
@ -32,8 +33,10 @@ class SaplingBlock extends FlowableBlock{
0 => "Oak Sapling",
1 => "Spruce Sapling",
2 => "Birch Sapling",
3 => "Jungle Sapling",
);
$this->name = $names[$this->meta & 0x03];
$this->hardness = 0;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){

View File

@ -22,6 +22,7 @@
class SugarcaneBlock extends FlowableBlock{
public function __construct($meta = 0){
parent::__construct(SUGARCANE_BLOCK, $meta, "Sugarcane");
$this->hardness = 0;
}
public function getDrops(Item $item, Player $player){
@ -29,6 +30,27 @@ class SugarcaneBlock extends FlowableBlock{
array(SUGARCANE, 0, 1),
);
}
public function onActivate(Item $item, Player $player){
if($item->getID() === DYE and $item->getMetadata() === 0x0F){ //Bonemeal
if($this->getSide(0)->getID() !== SUGARCANE_BLOCK){
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 SugarcaneBlock(), true, false, true);
break;
}
}
$this->meta = 0;
$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){

View File

@ -22,13 +22,14 @@
class TallGrassBlock extends FlowableBlock{
public function __construct($meta = 1){
parent::__construct(TALL_GRASS, $meta, "Tall Grass");
$this->isReplaceable = true;
//$this->isReplaceable = true;
$names = array(
0 => "Dead Shrub",
1 => "Tall Grass",
2 => "Fern",
);
$this->name = $names[$this->meta & 0x03];
$this->hardness = 0;
}
public function onUpdate($type){
@ -43,8 +44,24 @@ class TallGrassBlock extends FlowableBlock{
public function getDrops(Item $item, Player $player){
$drops = array();
if(mt_rand(1,10) === 1){//Seeds
$drops[] = array(WHEAT_SEEDS, 0, 1);
$possibleDrops = array(
array(WHEAT_SEEDS, 0, 1),
array(CARROT, 0, 1),
array(POTATO, 0, 1),
array(BEETROOT_SEEDS, 0, 1),
array(MELON_SEEDS, 0, 1),
array(PUMPKIN_SEEDS, 0, 1),
0,
0,
0,
0,
0,
0,
0,
0,
);
if(($item = $possibleDrops[mt_rand(0, count($possibleDrops) - 1)]) !== 0){
$drops[] = $item;
}
return $drops;
}

View File

@ -23,6 +23,7 @@ class WheatBlock extends FlowableBlock{
public function __construct($meta = 0){
parent::__construct(WHEAT_BLOCK, $meta, "Wheat Block");
$this->isActivable = true;
$this->hardness = 0;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){

View File

@ -23,6 +23,7 @@ class BedrockBlock extends SolidBlock{
public function __construct(){
parent::__construct(BEDROCK, 0, "Bedrock");
$this->breakable = false;
$this->hardness = 18000000;
}
public function isBreakable(Item $item, Player $player){

View File

@ -22,6 +22,7 @@
class BookshelfBlock extends SolidBlock{
public function __construct(){
parent::__construct(BOOKSHELF, 0, "Bookshelf");
$this->hardness = 7.5;
}
}

View File

@ -22,6 +22,7 @@
class BricksBlock extends SolidBlock{
public function __construct(){
parent::__construct(BRICKS_BLOCK, 0, "Bricks");
$this->hardness = 30;
}
public function getBreakTime(Item $item, Player $player){

View File

@ -23,6 +23,7 @@ class BurningFurnaceBlock extends SolidBlock{
public function __construct($meta = 0){
parent::__construct(BURNING_FURNACE, $meta, "Burning Furnace");
$this->isActivable = true;
$this->hardness = 17.5;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){

View File

@ -23,6 +23,7 @@ class ChestBlock extends TransparentBlock{
public function __construct($meta = 0){
parent::__construct(CHEST, $meta, "Chest");
$this->isActivable = true;
$this->hardness = 15;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
$server = ServerAPI::request();

View File

@ -22,6 +22,7 @@
class ClayBlock extends SolidBlock{
public function __construct(){
parent::__construct(CLAY_BLOCK, 0, "Clay Block");
$this->hardness = 3;
}
public function getDrops(Item $item, Player $player){

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 CoalBlock extends SolidBlock{
public function __construct(){
parent::__construct(COAL_BLOCK, 0, "Coal Block");
$this->hardness = 30;
}
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(COAL_BLOCK, 0, 1),
);
}else{
return array();
}
}
}

View File

@ -22,6 +22,7 @@
class CobblestoneBlock extends SolidBlock{
public function __construct(){
parent::__construct(COBBLESTONE, 0, "Cobblestone");
$this->hardness = 30;
}
public function getBreakTime(Item $item, Player $player){

View File

@ -22,6 +22,7 @@
class DiamondBlock extends SolidBlock{
public function __construct(){
parent::__construct(DIAMOND_BLOCK, 0, "Diamond Block");
$this->hardness = 30;
}
public function getBreakTime(Item $item, Player $player){

View File

@ -23,6 +23,7 @@ class DirtBlock extends SolidBlock{
public function __construct(){
parent::__construct(DIRT, 0, "Dirt");
$this->isActivable = true;
$this->hardness = 2.5;
}
public function onActivate(Item $item, Player $player){

View File

@ -29,10 +29,10 @@ class DoubleSlabBlock extends SolidBlock{
3 => "Cobblestone",
4 => "Brick",
5 => "Stone Brick",
6 => "Nether Brick",
7 => "Quartz",
6 => "Quartz",
);
$this->name = "Double " . $names[$this->meta & 0x07] . " Slab";
$this->hardness = 30;
}
public function getBreakTime(Item $item, Player $player){

View File

@ -0,0 +1,61 @@
<?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 DoubleWoodSlabBlock extends SolidBlock{
public function __construct($meta = 0){
parent::__construct(DOUBLE_WOOD_SLAB, $meta, "Double Wooden Slab");
$names = array(
0 => "Oak",
1 => "Spruce",
2 => "Birch",
3 => "Jungle",
);
$this->name = "Double " . $names[$this->meta & 0x07] . " Wooden Slab";
$this->hardness = 15;
}
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(WOOD_SLAB, $this->meta & 0x07, 2),
);
}
}

View File

@ -22,6 +22,7 @@
class FarmlandBlock extends SolidBlock{
public function __construct($meta = 0){
parent::__construct(FARMLAND, $meta, "Farmland");
$this->hardness = 3;
}
public function getDrops(Item $item, Player $player){
return array(

View File

@ -22,6 +22,7 @@
class GlassBlock extends TransparentBlock{
public function __construct(){
parent::__construct(GLASS, 0, "Glass");
$this->hardness = 1.5;
}
public function getDrops(Item $item, Player $player){

View File

@ -22,6 +22,7 @@
class GlowstoneBlock extends TransparentBlock{
public function __construct(){
parent::__construct(GLOWSTONE_BLOCK, 0, "Glowstone");
$this->hardness = 1.5;
}
public function getDrops(Item $item, Player $player){

View File

@ -22,6 +22,7 @@
class GoldBlock extends SolidBlock{
public function __construct(){
parent::__construct(GOLD_BLOCK, 0, "Gold Block");
$this->hardness = 30;
}
public function getBreakTime(Item $item, Player $player){

View File

@ -23,6 +23,7 @@ class GrassBlock extends SolidBlock{
public function __construct(){
parent::__construct(GRASS, 0, "Grass");
$this->isActivable = true;
$this->hardness = 3;
}
public function getDrops(Item $item, Player $player){
return array(
@ -35,7 +36,7 @@ class GrassBlock extends SolidBlock{
if(($player->gamemode & 0x01) === 0){
$item->count--;
}
TallGrassObject::growGrass($this->level, $this, new Random());
TallGrassObject::growGrass($this->level, $this, new Random(), 8, 2);
return true;
}elseif($item->isHoe()){
if(($player->gamemode & 0x01) === 0){

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