Compare commits

..

850 Commits

Author SHA1 Message Date
05a42712bf Added non-packaged plugins & pocketmine warnings 2014-04-01 04:59:44 +02:00
207c2c4aba Fixed namespaces paths 2014-04-01 04:47:04 +02:00
3605bc36c5 Fixed PluginManager::parseYamlCommands() 2014-04-01 02:12:05 +02:00
9cae532d7e Remove compile script DEBUG trap on php.ini generation 2014-04-01 01:47:28 +02:00
e8477fec53 Added /difficulty, removed old API files 2014-04-01 01:37:43 +02:00
760695e4bc Added Phar plugins 2014-03-31 23:49:43 +02:00
e8c4507ac6 Re-added kill 2014-03-31 22:51:00 +02:00
c167defa72 Fixed plugin dataFolder 2014-03-31 22:35:42 +02:00
5dafe8e7f0 Fixed lots of errors, added auto-save 2014-03-31 20:42:58 +02:00
8571796611 Load correct plugin permissions 2014-03-31 18:24:59 +02:00
b03ef8b61c More flexible match on plugin registration 2014-03-31 17:29:47 +02:00
0422540114 New automatic event listener plugin declaration 2014-03-31 17:01:56 +02:00
00d777a68d Fixed commands, NBT Player saving 2014-03-31 15:42:08 +02:00
2f03251795 Added /list, Player::canSee(), Player::showPlayer(), Player::hidePlayer(), removed RealHuman 2014-03-31 15:18:50 +02:00
f9a7385b47 Added /me and /say, fixed a bunch of things, chat working 2014-03-31 06:51:34 +02:00
22b5255421 Formatting 2014-03-31 05:53:51 +02:00
befe1c606f Added /ban, /ban-ip, /pardon, /pardon-ip 2014-03-31 05:51:42 +02:00
1ff381ebf4 Things are working ヽ༼ຈل͜ຈ༽ノ 2014-03-31 05:04:36 +02:00
2b8df410d1 Player is instanceof CommandSender 2014-03-31 02:53:37 +02:00
5bb909adf1 Fixed case 2014-03-30 23:51:41 +02:00
f789e6e6e3 Lots of new things added 2014-03-30 18:04:56 +02:00
ccec74076b Fixed PluginBase::getServer() 2014-03-30 14:35:58 +02:00
de6e8f6fe1 Removed WeakRef 2014-03-29 04:39:45 +01:00
7599fb436d Fixed #1365 2014-03-29 04:35:12 +01:00
e03c8ed32e Updated compiler 2014-03-29 03:27:29 +01:00
0d30dca5aa Updated pthreads to 2.0.4 2014-03-28 23:50:09 +01:00
7e03109576 Moved default level registration 2014-03-28 13:07:36 +01:00
38809f7da2 Reformatting, removing unused imports 2014-03-28 12:57:08 +01:00
fd8e5b27e5 Added new global autoloader 2014-03-28 05:04:34 +01:00
b59926bece Added Recursive class loading in FolderPluginLoader 2014-03-28 04:25:17 +01:00
a7269c7900 Added /tell 2014-03-28 03:40:12 +01:00
2f20d95e5d Added new Event system 2014-03-28 02:13:03 +01:00
9e8cf2d42c Update CONTRIBUTING.md 2014-03-27 22:32:00 +01:00
926afa3903 New Task scheduler 2014-03-27 22:16:09 +01:00
9a2934b85b More unloading 2014-03-27 19:40:05 +01:00
1c341337a3 Set default console color at start 2014-03-27 18:58:36 +01:00
f60b526c9e Changed default log path 2014-03-27 18:53:20 +01:00
3bc3db0740 Added /stop, plugin disable / unload, remaining TaskCanceller classes 2014-03-27 18:49:43 +01:00
2385b94ba3 Added PluginBase::getCommand() 2014-03-27 14:56:02 +01:00
605231251a Fire plugin onLoad() 2014-03-27 14:35:44 +01:00
1c7be84703 Added CommandExecutor interface to PluginBase 2014-03-27 05:25:47 +01:00
530d705d39 Fully loadable plugins 2014-03-27 04:59:18 +01:00
120efad01f Colors fix D: 2014-03-26 20:23:04 +01:00
9fe68003eb Added Help command 2014-03-26 20:11:53 +01:00
76438e78d2 Changed Command inheritance 2014-03-26 18:10:49 +01:00
2112de42ad removed travis on Core-Rewrite 2014-03-26 16:50:36 +01:00
92a0ddb4fe Threaded networking :D 2014-03-26 16:48:27 +01:00
7ea9e4c862 It runs :O (Added more Permissions, executors and such things) 2014-03-26 04:14:53 +01:00
b1b8c89227 Removed SQLite3 from Recipe, converted to a lookup table 2014-03-25 18:53:39 +01:00
b6e0905c3e Implemented scheduler classes 2014-03-25 13:19:15 +01:00
af80c056c7 Added pthreads / yaml documentation stubs 2014-03-25 01:13:35 +01:00
5b90c4a716 safe_var_dump() now supports any amount of parameters 2014-03-23 21:56:50 +01:00
1429a74beb Player event 2014-03-23 15:14:11 +01:00
ee265d44bd Added more new Events 2014-03-23 13:41:45 +01:00
fd0fcecb46 Oops, seems like Utils::readInt() is reading an unsigned long because of PHP silliness 2014-03-23 01:55:26 +01:00
d18952a06e Removed not necessary code from Utils::readInt() and Utils::readLInt() 2014-03-23 01:50:15 +01:00
f03ab9a587 Removed Deprecation 2014-03-23 00:43:45 +01:00
80cfa7cc84 Formatting code 2014-03-23 00:32:05 +01:00
af14c87572 Added new Plugin and Permissions stuff :D 2014-03-23 00:22:14 +01:00
28c5443b0d Changed player achievement method names 2014-03-23 00:21:51 +01:00
08c6c1c1ac Updated compile scripts 2014-03-23 00:19:54 +01:00
cb2b08b248 Fixed Level generators 2014-03-23 00:19:11 +01:00
63f1f7581f Renamed Stackable to Threaded 2014-03-18 01:00:35 +01:00
d53656b2a8 pthreads 2.0.2 \(^.^)/ 2014-03-18 00:50:03 +01:00
28e17fe808 Added PHP WeakRef 2014-03-15 13:19:48 +01:00
6f0f86dc0c More docs 2014-03-14 03:11:23 +01:00
3ff8ddc652 Fixed a few errors in new Events 2014-03-14 02:02:31 +01:00
68abafef7a Added multiple Player events using the new system 2014-03-14 01:51:10 +01:00
279472b01a Added generic block relative place/break on Level 2014-03-13 23:04:49 +01:00
91c4cbfedb Moved Player::buffer 2014-03-13 10:51:38 +01:00
b24120a863 Updated all undefined constants/classes, place resent packets to the recovery queue for NACK 2014-03-13 10:48:33 +01:00
3c3b346fd3 Use NBT Compounds instead of a NBT codec in PMF level data 2014-03-12 22:54:32 +01:00
63542a2f13 Updated NBT library to remove read overhead 2014-03-12 22:40:19 +01:00
cc5a30a0c2 Fixed ANSI color codes on Windows 2014-03-12 14:07:14 +01:00
8f990472c6 Fixed PHP 5.4 issues 2014-03-12 14:03:42 +01:00
18117b91ed Fixed issues with CPU loop 2014-03-12 03:25:50 +01:00
e033af0e72 Added -s (static) flag to compiler 2014-03-12 02:41:49 +01:00
69c829c302 Use pthreads 1.0.1 2014-03-11 21:58:40 +01:00
a84f756fd5 Optimize Imports 2014-03-11 20:47:31 +01:00
b3a2d3164f Finally, I can spawn AGAIN! 2014-03-11 20:45:53 +01:00
b4df7c9456 Moved compile scripts 2014-03-08 18:16:55 +01:00
19d98869fd Modified compile.sh 2014-03-08 05:33:11 +01:00
099716920b Updated permissions 2014-03-08 04:43:15 +01:00
cbc64462e6 New directory structure. More powerful startup scripts 2014-03-08 04:41:43 +01:00
8d75bff34b Merge branch 'master' into Core-Rewrite
Conflicts:
	src/level/LevelImport.php
	src/pmf/LevelFormat.php
2014-03-08 03:34:53 +01:00
ababc879b5 Removed warning message about not-bundled PHP 2014-03-08 03:28:00 +01:00
a817234aa8 Do not generate Phar utilities by default, only generate extension 2014-03-07 23:29:28 +01:00
e246e10a82 Added NEON optimizations to iOS 2014-03-07 20:04:18 +01:00
5ad511cd11 Disabled phar cmdtools generation on crosscompile 2014-03-07 19:12:06 +01:00
47ad8b6fac Added PHP_VAR_NAME to crosscompile 2014-03-07 18:26:12 +01:00
a74f5809c7 Added -lresolv 2014-03-07 17:38:36 +01:00
8c02555a8d Added sed -i ".backup" 2014-03-07 17:02:05 +01:00
612cf98a08 typo fix 2014-03-07 16:42:18 +01:00
971e18d9b0 Added php.ini Phar directives 2014-03-07 16:33:29 +01:00
4a2dea4e45 Added correct toolchain for iOS 2014-03-07 16:25:40 +01:00
2916b0f049 Added Phar extension to PHP 2014-03-07 16:22:16 +01:00
bfe746235f Removed iOS -arch 2014-03-07 16:20:17 +01:00
604f068112 Added iOS flags 2014-03-07 15:41:08 +01:00
c7854a3417 Added arm flags 2014-03-07 15:33:32 +01:00
8bfd22c9ac Added arch-specific compile optimizations 2014-03-07 13:34:31 +01:00
052f641715 Fixed levels not being read properly 2014-03-07 06:29:35 +01:00
ee51f75c78 Fixed issues with zlib 2014-03-07 05:15:01 +01:00
73b78e1455 Updated helper scripts PHP version to 5.5.10 2014-03-07 04:49:26 +01:00
7ad7398f2b Updated PHP version to 5.5.10 2014-03-07 04:47:15 +01:00
e81f4430cb Fixed mac 32-bit compilation 2014-03-07 04:29:47 +01:00
c12c6f1f18 Added remaining env. vars to compile.sh 2014-03-07 04:24:41 +01:00
a375a17d17 New compile script 2014-03-07 04:21:21 +01:00
801e924783 Comments 2014-03-06 23:38:46 +01:00
993620341a Added Villager class and NPC interface 2014-03-06 23:33:35 +01:00
59246dd5ec Added API Docs link 2014-03-06 22:03:30 +01:00
f7c7eac05a Updated README.md 2014-03-06 21:48:06 +01:00
331a26931f It staaaarts! 2014-03-06 20:41:04 +01:00
56d3b89f57 Updated class constants 2014-03-06 19:31:41 +01:00
80356d8794 fixed syntax error 2014-03-06 19:29:33 +01:00
028adce245 Used namespacer to identify moved files 2014-03-06 19:28:20 +01:00
a54d33957e Added multiple comments and info 2014-03-06 18:52:23 +01:00
5c00b415a5 typos 2014-03-06 17:24:26 +01:00
18443c0cd7 Reformatted code 2014-03-06 17:17:45 +01:00
6a736aa822 Used namespacer on Blocks and Items 2014-03-06 17:16:05 +01:00
d490972a42 fix typo 2014-03-06 17:14:54 +01:00
6f74ef80f9 Added Block and Item namespaces 2014-03-06 17:14:15 +01:00
2e0d9153b3 used namespacer 2014-03-06 15:15:50 +01:00
64a9650765 fixed typo 2014-03-06 15:12:52 +01:00
419f246e68 Added Item namespace 2014-03-06 15:11:46 +01:00
e3f1db0f45 Added Network\Handler namespace 2014-03-06 13:19:00 +01:00
c08bf3ef86 Removed code remove comments 2014-03-06 13:16:44 +01:00
bbd66e6ad1 Removed code remove comments 2014-03-06 13:05:54 +01:00
a14deae634 Removed code remove comments 2014-03-06 12:58:54 +01:00
42ae544d0d Used namespacer tool 2014-03-06 05:47:00 +01:00
c9c6d5a5f4 Added Ores to objects 2014-03-06 05:43:40 +01:00
eeb8244f26 Fixed Normal generator name 2014-03-06 05:35:17 +01:00
e0267799fb Fixed class namespaces 2014-03-06 05:33:04 +01:00
da4bc302c4 Fixed Utils endianness 2014-03-06 04:10:07 +01:00
5109566c9f Updated .gitignore 2014-03-06 03:53:59 +01:00
5de9fa77d7 Moved objects 2014-03-06 03:16:03 +01:00
ee53e21159 small fixes 2014-03-06 03:03:42 +01:00
dd2d229f74 renamed PocketMine\PMF\Level to PocketMine\PMF\LevelFormat 2014-03-06 02:45:09 +01:00
e3c0ea6be5 fixed typo 2014-03-06 02:40:19 +01:00
5b02666828 fixed typo 2014-03-06 02:38:57 +01:00
bc0c185cb5 fixed typo 2014-03-06 02:36:30 +01:00
928519f226 fixed typo 2014-03-06 02:30:16 +01:00
edf0d44416 fixed typo 2014-03-06 02:27:28 +01:00
3465a5f7e8 fixed typo 2014-03-06 02:26:17 +01:00
024e219292 fixed typo 2014-03-06 02:22:52 +01:00
42b5af23db Moved files 2014-03-06 01:18:55 +01:00
5ea31b57ce First step to namespaces 2014-03-05 23:43:16 +01:00
23b8fc32ff removed DocBlock header for logo 2014-03-05 11:15:47 +01:00
5f53f61121 Faster NBT parsing 2014-03-05 10:37:14 +01:00
98c0dfef43 Removed entity.motion from Player 2014-03-05 10:17:22 +01:00
d69fe5d5e7 New events, item methods 2014-03-05 10:16:08 +01:00
2bdc8c400e EventHandler code cleanup 2014-03-05 03:42:22 +01:00
ccdf587135 go away E_NOTICEs 2014-03-05 02:53:20 +01:00
b00da18f41 faster packet decode using pure-PHP functions instead of core-PHP ones :P. WTF PHP 2014-03-05 02:49:40 +01:00
9c38ead76d fixed time not being sent correctly on creative mode the first time 2014-03-05 01:25:53 +01:00
274f8a6113 Block placement fixes 2014-03-05 01:19:05 +01:00
a529e7566a Removed not needed network steps, corrected slot methods 2014-03-05 00:54:12 +01:00
bf412b1c20 Do not sleep on main Thread when actions are being done 2014-03-04 20:37:15 +01:00
980ee223d0 Save correct NBT Compound tag on Level chunk save 2014-03-04 19:52:52 +01:00
5241d8ff13 Fixed derp x3 2014-03-04 19:49:39 +01:00
c6c0b75eae Fixed derp x2 2014-03-04 19:46:47 +01:00
547ca74feb Fixed derp 2014-03-04 19:46:06 +01:00
4697d9d4ed Added player NBT save format, auto-upgrade 2014-03-04 19:41:56 +01:00
4449af2213 Implemented InventorySourceEntity into HumanEntity 2014-03-04 19:40:30 +01:00
f6589db064 Send Entity motion, update on schedule 2014-03-03 00:27:44 +01:00
c904e8bc0e Remove ANSI characters on clean 2014-03-03 00:26:33 +01:00
12ddf530b1 Added AxisAlignedBB::getMixedBoundingBox() (?) 2014-03-02 23:32:48 +01:00
df20467f3b Added Player block place/break (to be rewritten soon) 2014-03-02 17:56:54 +01:00
9cc9de8dae New Random block update tick 2014-03-02 17:56:24 +01:00
f6daaf76c8 Update CONTRIBUTING.md 2014-03-02 02:05:40 +01:00
ca308f8159 Merge branch 'master' into Core-Rewrite
Conflicts:
	src/pmf/PMFLevel.php
2014-03-01 22:12:22 +01:00
11f5691104 Fixed Pocket format importing 2014-03-01 22:08:28 +01:00
c8deefdb12 derp 2014-03-01 21:55:10 +01:00
75b34b6c2a Merged master into Core-Rewrite 2014-03-01 21:48:09 +01:00
5bf440d820 Fixed level upgrade and direct save on load 2014-03-01 21:45:07 +01:00
4d9e781f27 Tuned PMFLevel version upgrade 2014-03-01 21:43:55 +01:00
2a23eadbb6 Fixed things 2014-03-01 21:42:40 +01:00
573fe0e5cc Save player position, removed several methods from PluginAPI 2014-03-01 20:32:49 +01:00
f8d91b5888 Rolling chunk load 2014-03-01 19:13:08 +01:00
fdbefa0571 Added index to Level::getUsingChunk() 2014-03-01 19:04:18 +01:00
c2ad811451 Added chunk move spawning logic 2014-03-01 19:01:24 +01:00
dad2f21888 Players are fully spawnable and can see each other! 2014-03-01 18:23:38 +01:00
9d02ed9a28 New chunk indexing and sending algorithm 2014-03-01 17:35:44 +01:00
8403a34eb3 Removed entities, tiles, players SQLite3 tables 2014-03-01 14:07:27 +01:00
648b02bc79 Added Entity level switch, global Player static container 2014-03-01 14:05:45 +01:00
914098310c Guess NBTTag_List components type automatically 2014-03-01 11:26:19 +01:00
734b066131 removed debug messages 2014-02-28 22:03:09 +01:00
5651fc1cb1 Fixed level block and chunk sending 2014-02-28 20:39:59 +01:00
f08bedf2fe Added Biome methods to Level 2014-02-28 20:04:41 +01:00
6ac5647e2c Fixed load order 2014-02-28 20:04:31 +01:00
c488c19db9 I can spawn!! 2014-02-28 19:47:08 +01:00
f1d6726615 Added TextFormat::toHTML() 2014-02-28 16:08:33 +01:00
573c3ea377 Added /msg alias to /tell :P 2014-02-28 16:08:19 +01:00
16eb45925a Remove non-implemented chat colors from player messages 2014-02-28 00:12:57 +01:00
6d5e2648cf extra changes 2014-02-28 00:00:04 +01:00
2bf3f0de73 Removed EntityAPI 2014-02-27 16:47:49 +01:00
e314f46b5b Added biome saving to PMFLevel version 2 2014-02-27 15:34:00 +01:00
dc8cc2ab9f fixed empty world generation 2014-02-27 15:17:45 +01:00
6bd91cf39e fixes, new Tile update algorithm 2014-02-27 15:12:05 +01:00
c9dfdc288d Updated global Tile code 2014-02-27 12:23:22 +01:00
44b9d33b65 removed debug code 2014-02-27 00:24:43 +01:00
9acc867a94 fix 2014-02-27 00:14:05 +01:00
103d0bf2ea Updated TextFormat constants 2014-02-27 00:11:06 +01:00
4a2852bb90 Reworked Level things to handle new NBT structure 2014-02-27 00:03:53 +01:00
398fbbfb31 Added array things to NBT 2014-02-27 00:03:27 +01:00
4ffdb029f0 Removed TileAPI 2014-02-27 00:02:59 +01:00
b7ca8aac5c New Tile structure 2014-02-27 00:02:28 +01:00
b374783486 Allow direct property naming on NBT TAG_Compound 2014-02-26 17:55:17 +01:00
3864630bcd New PMF level (uses NBT Entity and TileEntity) 2014-02-26 17:15:31 +01:00
38c5174da7 Merged branch master into Core-Rewrite (includes new NBT changes) 2014-02-26 16:26:59 +01:00
21671b133a New NBT library finished 2014-02-26 15:20:16 +01:00
9cfa49c112 Added core NBT modifications 2014-02-26 15:12:58 +01:00
0231bf406e new NBT fixes 2014-02-26 13:53:50 +01:00
28d1da1286 New NBT tags 2014-02-26 13:08:53 +01:00
85f8613803 Fix RCON packet structure #1278 2014-02-24 20:13:15 +01:00
8e1cd2d6bd Check for block changes each 2 ticks instead of each 15 ticks 2014-02-23 13:47:30 +01:00
24722e3c9a Added #1196 async function queuing
Type ID: ASYNC_FUNCTION
Params: array("function" => $functionName, "arguments" => array
$argumentArray)
2014-02-23 13:39:57 +01:00
13274ebefa send-usage is now an advanced property :P 2014-02-23 13:39:56 +01:00
378e9c8720 Merge pull request #1274 from iksaku/patch-1
/sudo param help more descriptive
2014-02-23 13:37:49 +01:00
ba761faf74 Update BanAPI.php
/sudo help more descriptive?
2014-02-22 22:43:58 -06:00
734abf2fbb Fix E_STRICT errors 2014-02-20 23:43:42 +01:00
46ff7d43f4 Forgot to remove crash debug code. Fix #1260 2014-02-20 23:41:36 +01:00
8208fd2389 Changed class name 2014-02-20 17:22:51 +01:00
fded039485 Fixed #1258 2014-02-20 13:13:46 +01:00
9bc69f4c17 Update memory data on crash 2014-02-20 11:24:48 +01:00
eb40c34547 Fix error dump not dumped on memory problems 2014-02-20 10:57:42 +01:00
772fa2b9e3 Query token now depends on the source IP 2014-02-20 09:00:17 +01:00
7bdc48509e things 2014-02-19 17:41:12 +01:00
be13d0a921 Merge remote-tracking branch 'origin/PluginAPI-Rewrite' into Entities 2014-02-19 15:59:01 +01:00
7a44e8041f Entity $chunkIndex 2014-02-19 15:37:59 +01:00
b36d754e5b Merge remote-tracking branch 'origin/master' into Entities 2014-02-19 15:28:23 +01:00
62ef1f6b20 Added more entities 2014-02-19 12:41:19 +01:00
d12ce8fd6c small fixes 2014-02-19 02:23:45 +01:00
dd177b689b Added -mmacosx-version-min=10.5 to compile.sh 2014-02-19 02:09:02 +01:00
b4c6a0bf22 oops, typo 2014-02-19 01:56:25 +01:00
f1b5f83fd4 Lots of typos fixed, undefined variables, unused code 2014-02-19 01:55:42 +01:00
3d3111fef6 Changed preg_match() code in Player username handling 2014-02-19 00:49:07 +01:00
a1b2cf4b34 Added -undefined dynamic_lookup 2014-02-18 21:36:52 +01:00
1961e82645 Downgrade OpenSSL to 0.9.8y 2014-02-18 21:31:04 +01:00
15881d328d Added -weak-lSystem to MacOS x86_64 2014-02-18 20:41:54 +01:00
80e2a7e486 Update installer.sh 2014-02-18 19:46:39 +01:00
08c1dbe3a7 fix fix* 2014-02-18 18:52:27 +01:00
0cfb5aa720 fixed typo 2014-02-18 18:42:41 +01:00
60cf2c824f This should do for MacOS x86 2014-02-18 18:22:27 +01:00
f8dc01ccb3 Fixed things compile.sh 2014-02-18 17:47:40 +01:00
2c9337f200 Revert "Added $WITH_OPENSSL again to PHP"
This reverts commit c290b07382.
2014-02-18 17:31:12 +01:00
c290b07382 Added $WITH_OPENSSL again to PHP 2014-02-18 17:26:36 +01:00
0e5c532f5e Changed Android OpenSSL target 2014-02-18 17:24:46 +01:00
9006e5afad Added custom zlib to OpenSSL 2014-02-18 17:13:36 +01:00
bd3544e917 Added DYLD_LIBRARY_PATH 2014-02-18 16:28:30 +01:00
f384dfc40a Changed @loader_path to @executable_path on MacOS 2014-02-18 15:33:32 +01:00
2ee76182ad Compile OpenSSL on MacOS 2014-02-18 15:16:10 +01:00
c7acc3f221 Updated -rpath for MacOS 2014-02-18 15:00:29 +01:00
4573389840 Use Github URL for zlib 2014-02-18 14:48:51 +01:00
ea2fc1fb03 MacOS 32-bit compilation 2014-02-18 14:37:56 +01:00
0245ebe9f6 Update jenkins.sh 2014-02-18 13:00:33 +01:00
d38ae3c230 Added tar.gz files to jenkins.sh 2014-02-18 11:58:34 +01:00
daf27f46be Update installer.sh 2014-02-18 11:54:33 +01:00
2e2990fe33 Update compile.sh 2014-02-18 11:25:01 +01:00
aae66930b6 Update compile.sh to remove unused data 2014-02-18 10:27:32 +01:00
7472238510 Updated installer to handle full paths right and discard warnings on PHP checking 2014-02-17 19:10:28 +01:00
943e038772 Remove OpenSSL from PHP build :P 2014-02-17 18:37:37 +01:00
42e7467dba Added OpenSSL to Jenkins 2014-02-17 18:32:02 +01:00
697d96e60c Updated compile script to handle shared libraries 2014-02-17 18:30:18 +01:00
5b5dcd6d77 Removed not used code in compile.sh 2014-02-17 14:43:58 +01:00
0e39131e76 *fix 2014-02-17 13:26:51 +01:00
109f97ae00 Added ODROID detection to installer.sh 2014-02-17 13:20:28 +01:00
8b4abcc558 Generate OpenSSL shared binaries 2014-02-17 03:09:58 +01:00
5f3772d14a fixed cURL SSL for Darwin 2014-02-17 02:13:35 +01:00
98c50f9a9c OpenSSL is now not enforced compile.sh 2014-02-17 01:46:28 +01:00
6b2bca10a3 Added PHP check on installer.sh 2014-02-16 22:51:25 +01:00
5f6c9b7fad Normal compile.sh 2014-02-16 20:47:32 +01:00
696792cd2a Pre-sed 2014-02-16 20:21:42 +01:00
7e979f40cb Use full path on compile.sh 2014-02-16 20:05:21 +01:00
b0a6631b8e Update jenkins.sh 2014-02-16 19:45:09 +01:00
bb680e6e67 Fix compile.sh things 2014-02-16 18:52:55 +01:00
e999de22d5 oh my god. well, this should do. works for 32 and 64 bit FINALLY 2014-02-16 18:16:17 +01:00
bab5a36d39 Well, I found what broke everything 2014-02-16 17:10:04 +01:00
1a7cdc5cea No OpenSSL for PHP :( 2014-02-16 17:03:36 +01:00
7497e32042 Update jenkins.sh 2014-02-16 16:56:19 +01:00
d0c5f27ed3 OpenSSL make depend :S 2014-02-16 16:54:48 +01:00
65940719c2 OpenSSL + cURL 2014-02-16 16:44:07 +01:00
9847f38a9f Include OpenSSL in builds 2014-02-16 16:10:05 +01:00
e22b70296f Update compile.sh 2014-02-16 13:52:10 +01:00
5725b5a1a8 Update compile.sh 2014-02-16 13:36:13 +01:00
e7565e4183 Update jenkins.sh 2014-02-16 13:34:41 +01:00
878c3a3e3a Update compile.sh 2014-02-16 13:27:29 +01:00
0915e751c4 Update jenkins.sh 2014-02-16 13:11:15 +01:00
e740124b43 Update jenkins.sh 2014-02-16 13:03:31 +01:00
b6ad889057 Trying to fix libssl.so.10 error, re-added libedit 2014-02-16 12:46:26 +01:00
0e4b7f85c4 */ 2014-02-15 20:19:33 +01:00
905fa23d18 methods* 2014-02-15 12:17:17 +01:00
d699a97bb7 small things 2014-02-15 01:39:37 +01:00
9301c04e1f Added pre-compiled Linux binaries to installer 2014-02-14 23:09:29 +01:00
12141fe2b1 Updated jenkins.sh 2014-02-14 22:41:50 +01:00
5d1c79379b *and 2014-02-14 21:49:26 +01:00
08149fa4b3 Fixed #1229 2014-02-14 20:56:00 +01:00
dfe7269019 Fixed #1193 using #1194 2014-02-14 20:53:15 +01:00
2b15c440ee Send inventory on invalid crafting/invalid movement of item 2014-02-14 19:54:14 +01:00
daf3198136 Tall Grass can be replaced 2014-02-14 19:37:57 +01:00
fdf519398a Do not unload spawn chunks 2014-02-14 19:37:39 +01:00
f0ff420659 Fixed negative chunk indexes on PMFLevel 2014-02-14 18:25:06 +01:00
4acb4541ab Infinite player chunk sending (not yet visible :( ) 2014-02-14 17:59:34 +01:00
7ea0bf5067 Merge remote-tracking branch 'origin/master' into Entities 2014-02-14 17:16:51 +01:00
cbe07a1fa0 Fixed PMFLevel infinite loop 2014-02-14 14:21:28 +01:00
47893ed765 Generate backtrace on error/crash 2014-02-14 14:21:13 +01:00
63f4f87d37 Fixed PMFLevel bugs, crashes and weird methods 2014-02-14 13:17:05 +01:00
c1251a25bd Removed water PMFLevel update that caused locks 2014-02-14 01:36:10 +01:00
da554fbf23 Fixed Trees 2014-02-14 00:25:44 +01:00
715e51b7c5 Automatic population on side loading 2014-02-14 00:19:26 +01:00
5d7198396d Added TallGrassPopulator 2014-02-13 22:39:53 +01:00
4fecbc2dbc Added water sand and gravel 2014-02-13 22:05:50 +01:00
9600d61454 Modified max-chunks-per-second default value 2014-02-13 20:48:50 +01:00
5929b510d5 Better, faster world generation. Needs more things 2014-02-13 20:44:15 +01:00
4eebbba5bf PHP 5.4, PHP 5.5 and PHP 5.6 on Travis CI 2014-02-13 11:06:55 +01:00
1bbf211a37 Set a world spawnpoint using /spawnpoint w:WORLD x y z 2014-02-13 09:47:30 +01:00
acece47a37 Merge remote-tracking branch 'origin/master' into Entities 2014-02-13 09:30:21 +01:00
4d1adb98a8 Removed $i on WorldGenerator 2014-02-13 09:29:50 +01:00
c3a6149b29 added protocol number to /version 2014-02-13 08:52:27 +01:00
89e556755d Updated WorldGenerator to use correct generation variables 2014-02-13 08:38:23 +01:00
ab5c6341fe Added /plugins and /version 2014-02-13 08:37:54 +01:00
d0af367395 Use integers instead of booleans 2014-02-13 01:59:08 +01:00
4523b15991 do not send chunk updates on chunk generation 2014-02-13 01:53:30 +01:00
bd73cced6e Do not send block changes during chunk generation 2014-02-13 01:47:18 +01:00
e4c8142681 Removed var_dump() 2014-02-13 01:41:40 +01:00
c9a2a0ea50 Updated API version 2014-02-13 01:34:42 +01:00
268e8c1164 Force PMF save on PMF Level upgrade 2014-02-13 01:34:41 +01:00
e83e424671 Removed entity limits 2014-02-13 01:34:39 +01:00
3e68972253 fix an include 2014-02-13 01:34:37 +01:00
7f86746cbe woo :D 2014-02-13 01:34:36 +01:00
1ab90b1409 PMFLevel upgrade tested 2014-02-13 01:34:35 +01:00
b7ed2f765c Added PMFLevel upgrade 2014-02-13 01:34:33 +01:00
f7b8ad0e37 Infinite generation, in-place chunk creation working. New PMF Format 2014-02-13 01:34:32 +01:00
8377416f48 Nice generation :D 2014-02-13 01:34:30 +01:00
f91e2a5cfe Better parameters ^^ 2014-02-13 01:34:29 +01:00
2d88739005 normalize 2014-02-13 01:34:27 +01:00
4e820ab89f Use single Perlin noise 2014-02-13 01:34:26 +01:00
1bc54dbc44 Such noise 2014-02-13 01:34:24 +01:00
26772082da Random generator with signed int/float methods 2014-02-13 01:34:23 +01:00
3cbcb4871a Changed a few packet things 2014-02-13 01:14:14 +01:00
ac50577255 Typo and fixed a filename 2014-02-12 19:28:33 +01:00
aff2b9882a Merge pull request #1214 from nno88551/patch-2
fixed disconnected message
2014-02-12 11:14:29 +01:00
4352fce82d fixed disconnected message 2014-02-12 19:12:07 +09:00
df865d3456 Entity changes 2014-02-11 20:50:09 +01:00
b392a357e9 More classes 2014-02-11 20:49:38 +01:00
aab0cfb0d8 Added AxisAlignedBB bounding box for entities 2014-02-11 19:37:04 +01:00
a373a581c5 Better fix for #1201 (case-insensitive) 2014-02-11 16:57:45 +01:00
fccca5827f Moar 2014-02-11 16:20:51 +01:00
1206cbf993 Basic Entity structure 2014-02-11 13:31:48 +01:00
89a0e84404 Fixed handlerPriority order 2014-02-11 12:47:28 +01:00
755cafa600 Alpha_1.4dev 2014-02-11 12:47:18 +01:00
c09bc259fc Added #1142 OP players can bypass the player limit 2014-02-11 10:27:53 +01:00
8b23568fe7 Changed codename to new scheme. Alpha_1.3.12 ready \o/ 2014-02-11 02:31:41 +01:00
ad3bf0998f Halt NBT parsing if end of data is found 2014-02-11 01:41:04 +01:00
9cd5c1581b oops x4 2014-02-10 21:38:32 +01:00
94f2da1e38 Oops x3 2014-02-10 20:52:10 +01:00
b635a54b13 Oops x2 2014-02-10 20:47:21 +01:00
5057a3965e Ooops, ;) 2014-02-10 20:46:47 +01:00
5bdb61117f Merge pull request #1188 from PocketMine/Faster-Network
Merge Faster-Network into master. Added new Networking system, new Event system
2014-02-10 19:07:12 +01:00
0bf74d4139 Two packet event types ;) 2014-02-10 18:46:58 +01:00
a2ec9d6688 Moved a file 2014-02-10 18:10:51 +01:00
4b14d5d900 Final structure with example events 2014-02-10 18:08:25 +01:00
a4cbb2f938 Added PluginEvent 2014-02-10 17:33:12 +01:00
9ab993c817 Basic event system written 2014-02-10 17:23:35 +01:00
830530d868 Basic Event types (extended from Bukkit) 2014-02-10 16:09:32 +01:00
7c12f6ce8a Implemented QueryPacket and QueryHandler 2014-02-10 15:05:12 +01:00
b9aa3a0e70 Removed old code for property migration 2014-02-10 13:29:21 +01:00
d925640f03 Moved max-chunks-per-second to server.properties, increased to 8 2014-02-10 13:28:54 +01:00
7e174eac5a Decreased SO_SNDBUF 2014-02-10 13:26:09 +01:00
8de39db59d Updated chunk packet field names 2014-02-09 14:39:17 +01:00
f1245a551e Increased UDP buffer size 2014-02-09 13:30:06 +01:00
11c9972eb9 Fixed RotateHeadPacket not having pitch 2014-02-09 05:53:16 +01:00
8739017002 Check if the specified length is correct 2014-02-09 05:37:40 +01:00
5c1550e116 Set max movement distance, disallows teleport cheat 2014-02-09 05:30:15 +01:00
072d0589d2 Fixed undefined $data on RotateHeadPacket 2014-02-09 05:08:32 +01:00
7ebaf7e552 Added Android, BSD detection to Utils::getOS() 2014-02-09 04:44:45 +01:00
0e1c099906 Added iOS detection to Utils::getOS() 2014-02-09 03:20:09 +01:00
c2d4dd093a Updated repo name on installer 2014-02-09 03:19:39 +01:00
6046b263dd Possible fix #1189 2014-02-08 23:44:58 +01:00
dfa28d9a9e WTF null packets crash the server?? 2014-02-08 23:29:42 +01:00
7f0693e7e7 Updated packet handling to eliminate loops 2014-02-08 23:01:22 +01:00
3fed63b248 Split packet handling verified 2014-02-08 22:49:13 +01:00
a8b26a3caf Halt parsing when invalid packets are found 2014-02-08 21:16:51 +01:00
296c6904b9 Hide leave messages from non-spawned players 2014-02-08 20:54:50 +01:00
dfd5733969 Handle unknown packets more gracefully 2014-02-08 19:21:45 +01:00
0ff647015c Handle all kind of unknown data packets 2014-02-08 19:17:49 +01:00
f255948eb6 Updated Query to new packet format 2014-02-08 17:56:48 +01:00
d8aea544f3 Fixed DoorBlock crashing the server 2014-02-08 16:55:20 +01:00
1c7539b51a Fixed data packets being sent on player disconnect 2014-02-08 14:52:06 +01:00
1f8e25710d Fixed set up wizard not updating the memory 2014-02-08 14:46:08 +01:00
b107191fdb Renamed ExplosionPacket to ExplodePacket 2014-02-08 13:39:41 +01:00
f77d5dcefd Fixed UseItemPacket 2014-02-08 13:34:05 +01:00
2c3ab612f2 Fixed AddEntityPacket 2014-02-08 13:02:10 +01:00
b8ff5716c7 Packets are cloned on broadcast 2014-02-08 11:47:52 +01:00
8b87733082 Faster-Network now usable! 2014-02-08 01:30:08 +01:00
1f5ff78f06 Fixed a few wrong fields 2014-02-08 01:25:03 +01:00
f6ecf51516 Added RakNetDataPacket::reset() to all the packets 2014-02-08 00:48:00 +01:00
580ef46513 Added packet pid to buffer by default 2014-02-08 00:36:30 +01:00
c40b00288b Merge remote-tracking branch 'origin/master' into Faster-Network 2014-02-08 00:31:14 +01:00
28a753ba60 Fixed split packet sending 2014-02-08 00:29:20 +01:00
5dd7727548 Reverted 8e37627bc0 2014-02-08 00:05:36 +01:00
61953b5507 Fixed online functions on Android - do not use DNS 2014-02-07 22:56:15 +01:00
d4791ceb6c removed time warning 2014-02-07 20:53:29 +01:00
bcee4e7c21 bypass a few errors on installer.sh 2014-02-07 19:23:16 +01:00
af6174508d MacOS fix 2014-02-07 19:15:00 +01:00
d8e34e9ac5 Added iOS support 2014-02-07 18:46:50 +01:00
951ac08703 Updated installer.sh 2014-02-07 18:13:19 +01:00
2562d8fc41 Fixed position error 2014-02-07 18:06:50 +01:00
ac3472eff4 Fixed spawning problems because of packets 2014-02-07 18:03:11 +01:00
84638098d0 Entity spawn packets 2014-02-07 17:24:50 +01:00
083bfcc83c More classes updated 2014-02-07 17:07:57 +01:00
95bff304e4 Changed all Player packets to new network 2014-02-07 16:44:10 +01:00
20f2ef0e82 Updated PHP binaries on the installer 2014-02-07 11:45:12 +01:00
1728656836 PHP 5.5.9 2014-02-07 11:21:31 +01:00
eb375be550 PocketMinecraftServer client join protocol 2014-02-07 01:06:49 +01:00
dbbfbdffaa RakNet data packet codec 2014-02-07 00:56:40 +01:00
c048564981 Server listing working 2014-02-07 00:46:04 +01:00
45a3b54d32 Fixed basic stuff around 2014-02-07 00:16:39 +01:00
0af197a0f7 New packet writing done 2014-02-06 23:30:09 +01:00
415c9f16f4 wow. much packet. many code. such classes 2014-02-06 22:49:13 +01:00
82a486169f Merge remote-tracking branch 'origin/master' into Faster-Network 2014-02-06 15:22:08 +01:00
14a7e0a201 Call Plugin::__destruct() on PluginAPI::__destruct() 2014-02-06 15:21:12 +01:00
84cdc3bde1 RakNetInfo 2014-02-06 15:19:15 +01:00
5700235f80 Merge remote-tracking branch 'origin/master' into Faster-Network 2014-02-06 14:48:00 +01:00
85438aff0d Added verbose error level names 2014-02-06 14:14:08 +01:00
a5efe15030 Fixed #1173 #486 #466 #483 ignore E_NOTICE unpack() errors 2014-02-06 14:13:37 +01:00
55216ae65b Typo 2014-02-06 14:06:08 +01:00
e4b475218b Fixed #1152 get correct timezone from abbr. 2014-02-06 14:02:27 +01:00
bf6e759d97 Added multiple player selection and exact match by default (fixes #1167) 2014-02-06 13:14:10 +01:00
8e37627bc0 Change spawnpoint to setspawn for bukkit compatibility 2014-02-06 21:31:04 +10:30
e2a77b05b7 Remove redundant closing tag 2014-02-06 21:20:29 +10:30
1694e8622d Updated installer languages 2014-02-06 11:45:31 +01:00
112c35c3a1 Fixed #1171 2014-02-05 18:50:04 +01:00
1b5dc2db4d Reset cache timer when used 2014-02-05 17:29:11 +01:00
61ecf3418e fix installer :s 2014-02-05 12:10:32 +01:00
838147c4eb Merge branch 'master' of github.com:PocketMine/PocketMine-MP 2014-02-05 12:08:46 +01:00
3ac90dec47 New Raspbian build, fixes #1168 #1165 2014-02-05 12:07:03 +01:00
5030dc0bd1 Updated cURL 2014-02-05 11:57:27 +01:00
c80a64650b Merge pull request #1172 from pemapmodder/master
Added BOOK id
2014-02-05 11:11:39 +01:00
77ab494b70 BOOK ID missing? 2014-02-05 16:42:15 +08:00
5762d70414 Updayed ARMv7 Android flags 2014-02-04 14:08:54 +01:00
96d579e90f why is this so hard! 2014-02-04 14:04:07 +01:00
1ac14dba29 new -mtune 2014-02-04 14:01:42 +01:00
fc6515c37f -mtune=none 2014-02-04 12:58:09 +01:00
8bc60ca36f Removed -mtune 2014-02-04 12:56:23 +01:00
28af0e9f87 Updated compile.sh Android parameters 2014-02-04 12:40:16 +01:00
3bf812b3b3 Updated march for Android 2014-02-04 10:11:27 +01:00
0aeed7f458 Updated ARM toolchain to arm-unknown-linux-uclibcgnueabi 2014-02-04 07:50:28 +01:00
6325a2298e Fixed #1161 PluginAPI::readYAML() and PluginAPI::writeYAML() 2014-02-03 19:13:39 +01:00
34378b5776 Show player name on bad username kick 2014-02-03 01:10:30 +01:00
5cd2362c13 Added libtool 2014-02-02 19:12:51 +01:00
24ac7aa931 Added --target=arm-apple-darwin10 2014-02-02 19:09:03 +01:00
e39dad15e5 Added iOS sdk path 2014-02-02 19:06:35 +01:00
a1996063b6 llvm-? 2014-02-02 19:03:33 +01:00
11593ac96c Added experimental iOS cross-compile support 2014-02-02 19:02:29 +01:00
f9adbf33ec Fixed undefined chunk on PMFLevel::getMiniCHunk() 2014-02-02 12:05:35 +01:00
8bbc0af9b5 Fixed #1150 invalid Entity positions on startup 2014-02-02 02:30:21 +01:00
d299e39649 Fixed invalid array when a player has been kicked 2014-02-02 02:27:59 +01:00
5f3829692d Fixed unknown and impossible crash 2014-02-01 16:26:40 +01:00
dbde770fce Fixed typo o.O 2014-02-01 16:19:56 +01:00
cf1c2b3633 nope 2014-02-01 13:19:42 +01:00
df41f04d0f arm-none-linux-uclibceabi, maybe? 2014-02-01 12:53:59 +01:00
4ae7ccff9f Try with arm-none-linux-uclibcgnueabi 2014-02-01 12:50:41 +01:00
17d565e950 Added --enable-static-link for Android 2014-02-01 12:42:18 +01:00
ca99d60f53 Static uclibc linking 2014-02-01 12:32:12 +01:00
b867be9c9d Save install_data on jenkins 2014-02-01 12:15:22 +01:00
60a43df5c7 Removed gcc -pipe on normal build 2014-02-01 12:12:42 +01:00
fbbb114fc6 Removed gcc -pipe on test 2014-02-01 12:11:26 +01:00
e2b9e3d665 Fixed ARMv7 compilation 2014-02-01 11:28:10 +01:00
25d5ea367d Updated installer binaries 2014-02-01 11:27:56 +01:00
0329735712 Added $HAVE_MYSQLI 2014-02-01 01:27:59 +01:00
a9d0716bde Added $CONFIGURE_FLAGS to YAML compilation 2014-02-01 01:21:30 +01:00
6ba6aa5b61 Fixed jenkins script on places where cURL is not installed 2014-02-01 01:11:47 +01:00
9cc624b74e Force Entity health change on respawn 2014-02-01 01:06:05 +01:00
e619ebad61 such fix ¬¬ 2014-01-31 23:55:43 +01:00
e69da264dc Added prefix to libtool compilation 2014-01-31 23:53:48 +01:00
33bbbba806 Move libtoolize ¬¬ 2014-01-31 23:50:06 +01:00
666418752f fix 92dcb90804 2014-01-31 23:45:19 +01:00
92dcb90804 Added libtoolize env. variable 2014-01-31 23:42:48 +01:00
80376d3a4d Move libtool to correct location on jenkins Mac 2014-01-31 23:36:26 +01:00
0a10e76ff9 fixed typo 2014-01-31 23:31:42 +01:00
d313f82984 Added export to libtool 2014-01-31 23:30:59 +01:00
ab845c5dab Added libtool compilation on Mac for install.sh 2014-01-31 23:30:23 +01:00
951e9efb5e Updated installer.sh to include OPCache 2014-01-31 23:14:50 +01:00
329788e506 Save artifacts even when the build fails jenkins.sh 2014-01-31 21:15:12 +01:00
74ad2ddcdd Added cURL on Mac OSX Jenkins build 2014-01-31 21:05:13 +01:00
09cf39b9d5 Added quotes to URLs 2014-01-31 21:03:28 +01:00
d00b489e1d Added universal installer.sh 2014-01-31 17:51:48 +01:00
cf554c67f2 Be sure to respawn players correctly 2014-01-31 17:24:03 +01:00
331904691d Added cURL shared extension to php.ini 2014-01-31 16:21:07 +01:00
dd7c2c850b Updated jenkins.sh to include all binary files generated 2014-01-31 16:09:52 +01:00
263c580fe1 Removed curl from jenkins.sh for Mac 2014-01-31 16:00:36 +01:00
b9ee3fb185 Updated curl path 2014-01-31 16:00:09 +01:00
5e079b740c Modified cURL building 2014-01-31 15:55:16 +01:00
74d4b95a70 Changed jenkins.sh 2014-01-31 14:31:55 +01:00
ee3b1dc11a Added jenkins.sh 2014-01-31 13:55:06 +01:00
126f149f0b Increased hearts restored by Apples 2014-01-31 13:33:49 +01:00
e12290202b Fixed #1135 Entity despawn race condition 2014-01-31 13:30:30 +01:00
974862996b replaced download_file 2014-01-31 13:26:04 +01:00
bcd312ea16 Removed OPCache when cross-compiling 2014-01-31 01:50:59 +01:00
5ff34b22b5 Include OPCache and generate default php.ini 2014-01-31 01:43:57 +01:00
8a9dcbb646 Calculate time offset only if date.timezone is not set 2014-01-31 01:19:51 +01:00
b7c0e08b7d such debug. much fix 2014-01-31 00:45:16 +01:00
13bf17925f compile.sh now supports cURL client 2014-01-31 00:43:47 +01:00
b56a56df2b Merge remote-tracking branch 'origin/master' into Faster-Network 2014-01-30 10:10:20 +01:00
7403516aab Added extra machine data to Utils::getUniqueID() 2014-01-30 01:13:58 +01:00
7560a5416e Replaced printf with echo 2014-01-30 00:42:10 +01:00
eca8fbce30 Fixed undefined index on Slab 2014-01-30 00:42:01 +01:00
f7af625407 Well... printf "\n" | 2014-01-30 00:39:32 +01:00
e15509c352 Removed Spyc 2014-01-30 00:36:51 +01:00
b481c94f45 Added new PHP YAML extension 2014-01-30 00:36:44 +01:00
d8f4e88e5d Fixed Entities not being despawned on restart if they were off-limits 2014-01-29 23:53:58 +01:00
60bc72c6cb Fixed undefined indexes on cases where plugins did things wrong 2014-01-29 20:41:57 +01:00
cd52cb9ae6 Added exec to start.sh 2014-01-29 20:02:16 +01:00
eeeb6d42c2 Added --with-mysqli=mysqlnd to compile script 2014-01-29 19:43:26 +01:00
e799376559 such fail :S 2014-01-29 19:11:47 +01:00
e7aea41f80 More changes ;). Start.sh now supports the new compile path 2014-01-29 19:07:43 +01:00
55f4811847 Oops ;) 2014-01-29 18:56:21 +01:00
ac2abccf41 Compile all PHP binaries 2014-01-29 18:43:13 +01:00
09720a59ec Added Utils::getUniqueID(), returns a machine ID and a even more variable machine ID 2014-01-29 17:07:01 +01:00
7e8ae3a1e1 Main source for ticks is in the packet loop, and PHP ticks as a secondary backup one 2014-01-29 16:22:58 +01:00
73db6cbb96 Removed BitDeli 2014-01-29 12:43:59 +01:00
f2703f5cfb Move BitDeli Badge. 2014-01-29 20:49:53 +10:30
0703145155 Merge pull request #1129 from bitdeli-chef/master
Add a Bitdeli Badge to README
2014-01-29 02:18:42 -08:00
aadef6e2d3 Add a Bitdeli badge to README 2014-01-29 10:20:50 +00:00
edd2331b40 Added GCC -pipe and changed optimization to -O2 2014-01-29 03:27:31 +01:00
079db8d234 Added option to skip save in ServerAPI::serProperty() 2014-01-29 02:36:21 +01:00
c88b1c97b3 Added advanced caching (enable-advanced-cache) 2014-01-29 02:24:02 +01:00
b4971abe91 Added base Cache class for integrated caching 2014-01-29 02:23:27 +01:00
a297574656 Level::unloadChunk() now uses the saveEnabled property 2014-01-28 21:46:29 +01:00
4bcea9b3e5 ¬¬ world 2014-01-28 12:57:46 +01:00
0a27783604 Fixed offset calculation 2014-01-28 12:50:53 +01:00
9a4bae7d64 Improved crash dumps 2014-01-28 12:50:42 +01:00
f8b270e33f such fix. I even made a regular expression to find these 2014-01-28 12:50:24 +01:00
1526c6cae9 Fixed "Take this ridiculously retarded IF formatting!" by @sekjun9878 2014-01-28 11:37:29 +01:00
4002d3013d More OCD 2014-01-28 11:36:18 +01:00
763adb0360 OCD. Blame @sekjun9878 for making me shout in the train 2014-01-28 11:27:55 +01:00
439c0e8280 Removed obsolete Java Random 2014-01-28 11:25:12 +01:00
4aa7b3eaf8 Allow custom arch. build on compiler 2014-01-27 19:28:29 +01:00
cdefcbd72a Fixed #823 /help outputs ansi colors 2014-01-27 18:19:45 +01:00
101402fe56 Fixed #854 return not-safe spawn when safe spawn is not available 2014-01-27 18:16:28 +01:00
c52f6c9376 Fix #1117 fix 2014-01-27 17:46:41 +01:00
76e4bf6d5f Fixed #1117 enforce new pthreads version 2014-01-27 17:41:42 +01:00
431c06073d Updated Travis-CI to PHP 5.5.x and pthreads to 0.1.0 2014-01-27 15:22:12 +01:00
ac8f2646a7 pthreads 0.1.0 and Thread::kill(). Needs fix 2014-01-27 15:18:20 +01:00
b7cf5d08cc Save and send hotbar history 2014-01-27 14:00:53 +01:00
624eb93058 Save and send last slot used by player 2014-01-27 04:00:26 +01:00
01015d0db3 Fixed #1114 Furnace item duplication cheat 2014-01-27 01:13:59 +01:00
f95e8a2c51 Merge pull request #1109 from pemapmodder/master
Include level in $data for event item.drop
2014-01-26 15:36:24 -08:00
d94239771e Merge pull request #1112 from JWhy/patch-2
/op command: Show usage info if no user specified
2014-01-26 11:27:11 -08:00
49e5d930f1 Level included in data for event item.drop 2014-01-26 20:44:26 +08:00
1b227153a9 /op command: Show usage info if no user specified 2014-01-26 13:21:51 +01:00
ec70dd476a Updated Korean, Dutch and Chinese set-up wizard translations 2014-01-25 01:15:56 +01:00
f432f110a4 Fixed invalid Position object on teleport 2014-01-23 19:02:09 +01:00
9f4b5a40e1 Merge remote-tracking branch 'origin/master' into Faster-Network 2014-01-22 23:13:43 +01:00
4ae1709196 Fixed #1100 Item multiplication cheat 2014-01-22 22:11:54 +01:00
edfcdd0c17 Fixed #1031 Correct face when block is replaced 2014-01-22 17:31:23 +01:00
dcd9dbd1dd Fixed #1032 undefined index on PrimedTNT entities 2014-01-22 17:29:23 +01:00
f4d96e3a9b Temp. fix for Ladders popping out 2014-01-22 13:09:27 +01:00
cfb3bbfbf2 Fixed #1058 2014-01-22 01:36:30 +01:00
e659f435df Merge pull request #1099 from repeat83/patch-1
Fixed invalid indexes for Tile Entities
2014-01-21 12:28:55 -08:00
c7d33ee267 hmmm it's feature? 2014-01-21 23:04:02 +03:00
bede216762 Added Chinese to the language list 2014-01-19 01:07:57 +01:00
c13cc7c91d Added Chinese, updated Korean, Russian 2014-01-18 20:48:04 +01:00
0977daa3b4 Fixes #519 #861 #940 #505 #590 #761 #129 compilation on 64-bit systems 2014-01-18 12:44:17 +01:00
218fb5df3e Trying to fix issue #519 2014-01-18 12:23:45 +01:00
c9ab5ee0e9 API version is now 12 2014-01-17 22:31:22 +01:00
cc57475f91 Added player.block.place.bypass and player.block.break.bypass 2014-01-16 23:09:56 +01:00
6cf8698826 Updated German 2014-01-16 22:33:50 +01:00
718c858632 Added French, updated Korean and German 2014-01-16 16:27:04 +01:00
7a2d90c6d0 Updated German, Korean and Japanese 2014-01-16 12:52:10 +01:00
ee7d2f4ebf Updated Japanese 2014-01-16 00:33:39 +01:00
b5406af32e Updated Russian 2014-01-15 23:30:19 +01:00
0949734d38 Updated Russian and Italian 2014-01-15 22:36:24 +01:00
a3d62056d8 Fixed extra \n 2014-01-15 20:53:10 +01:00
40bdfd33ac Added Japanese, Italian 2014-01-15 20:51:38 +01:00
c0b247dd72 Update nl_NL.ini
Dutch translation fixed
2014-01-15 20:26:34 +01:00
f7ac3f5e8a Updated German 2014-01-15 20:10:57 +01:00
36c416fada Use DejaVu Sans Mono for the MinTTY console 2014-01-15 19:57:46 +01:00
81d938cc53 Removed wizard from Travis 2014-01-15 18:09:09 +01:00
609544b1ec Removed debug instruction 2014-01-15 18:07:55 +01:00
e2c678c8a6 Added set-up Wizard 2014-01-15 18:07:35 +01:00
5fe8141ba0 Alpha_1.3.12 "Henteko Minecart" Development 2014-01-15 18:07:23 +01:00
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
a0019bfa73 redeclare fix ;) 2013-12-17 12:03:01 +01:00
de5a3175bc Data Packet initial parsing 2013-12-17 12:00:26 +01:00
e6aeb03ec5 Merge remote-tracking branch 'origin/master' into Faster-Network 2013-12-17 11:01:12 +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
3ef2471041 More Changes 2013-12-16 15:49:28 +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
e0b8527560 First changes 2013-12-16 13:06:01 +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
3248066a37 Increased error level 2013-12-13 15:52:17 +01:00
a0b93ed5ff Added Source SHA1 sum 2013-12-13 15:52:08 +01:00
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
545 changed files with 38029 additions and 16954 deletions

1
.gitattributes vendored
View File

@ -5,6 +5,7 @@
*.txt text eol=lf
*.properties text eol=lf
*.bat text eol=crlf
*.cmd text eol=crlf
# Custom for Visual Studio
*.cs diff=csharp

9
.gitignore vendored
View File

@ -1,18 +1,13 @@
players/*
worlds/*
plugins/*
logs/*
bin/*
.idea/*
*.log
*.pmf
*.txt
*.phar
server.properties
############
## Windows
############
# Windows image file caches
Thumbs.db

View File

@ -2,12 +2,19 @@ language: php
php:
- 5.4
- 5.5
- 5.6
branches:
except:
- Core-Rewrite
before_script:
- pecl install channel://pecl.php.net/pthreads-0.0.44
- pecl install channel://pecl.php.net/pthreads-2.0.4
- echo | pecl install channel://pecl.php.net/yaml-1.1.1
script:
- php src/tests/ServerSuiteTest.php
- php src/tests/ServerSuiteTest.php --no-wizard
notifications:
email: false

View File

@ -1,14 +1,13 @@
![](http://www.pocketmine.net/favicon.png)
![](http://cdn.pocketmine.net/img/PocketMine-MP-h.png)
# PocketMine-MP Contribution Gidelines
# PocketMine-MP Contribution Guidelines
Before contributing to PocketMine-MP, please read this.
Before contributing to PocketMine-MP, please read this. Also, take a look if your contribution fits the PocketMine-MP goals below.
## 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=pocketmine,mcpedevs&uio=d4) if you want.
* You can ask directly to _[@PocketMine](https://twitter.com/PocketMine)_ in Twitter, but don't expect an inmediate reply.
## 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,57 @@ 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 use namespaces.
* Strings SHOULD use the double quote `"` except when the single quote is required.
* Arrays SHOULD be declared using `array()`, not the `[]` shortcut.
* Argument lists MAY NOT be split across multiple lines, except long arrays.
```php
<?php
namespace pocketmine\Example;
class ExampleClass{
const EXAMPLE_CLASS_CONSTANT = 1;
public $examplePublicVariable = "defaultValue";
private $examplePrivateVariable;
public function __construct($firstArgument, &$secondArgument = null){
if($firstArgument === "exampleValue"){ //Remember to use === instead == when possible
//do things
}elseif($firstArgument === "otherValue"){
$secondArgument = function(){
return array(
0 => "value1",
1 => "value2",
2 => "value3",
3 => "value4",
4 => "value5",
5 => "value6",
);
}
}
}
}
```

View File

@ -1,25 +1,23 @@
![](http://www.pocketmine.net/favicon.png)
# ![PocketMine-MP](http://cdn.pocketmine.net/img/PocketMine-MP-h.png)
# PocketMine-MP [![Build Status](https://travis-ci.org/PocketMine/PocketMine-MP.png?branch=master)](https://travis-ci.org/PocketMine/PocketMine-MP)
```
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
```
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
__PocketMine-MP is a sofware for creating Minecraft Pocket Edition servers__. It has a Plugin API that enables a developer to extend it and add new features, or change default ones.
The entire server is done in PHP, and has been tested, profiled and optimized to run smoothly.
__PocketMine-MP is a Minecraft: PE server software.__
The entire server is written in PHP, and has been tested, profiled and optimized to run smoothly.
### [Homepage](http://www.pocketmine.net/)
@ -29,22 +27,25 @@ The entire server is done in PHP, and has been tested, profiled and optimized to
### [FAQ: Frequently Asked Questions](https://github.com/PocketMine/PocketMine-MP/wiki/Frequently-Asked-Questions)
### API Documentation
* [Doxygen generated](http://docs.pocketmine.net/)
* [PHPDoc generated](http://docs.pocketmine.net/phpdoc/)
### [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
* __[PHP Sockets](http://php.net/manual/en/book.sockets.php)__
* __[PHP SQLite3](http://php.net/manual/en/book.sqlite3.php)__
* __[PHP BCMath](http://php.net/manual/en/book.bc.php)__
* __[PHP pthreads](https://github.com/krakjoe/pthreads)__ by _[krakjoe](https://github.com/krakjoe)_: Threading for PHP - Share Nothing, Do Everything.
* __[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.
* __[PHP pthreads](http://pthreads.org/)__ by _[krakjoe](https://github.com/krakjoe)_: Threading for PHP - Share Nothing, Do Everything.
* __[PHP YAML](https://code.google.com/p/php-yaml/)__ by _Bryan Davis_: The Yaml PHP Extension provides a wrapper to the LibYAML library.
* __[LibYAML](http://pyyaml.org/wiki/LibYAML)__ by _Kirill Simonov_: A YAML 1.1 parser and emitter written in C.
* __[mintty](https://code.google.com/p/mintty/)__ : xterm Terminal Emulator
* __[cURL](http://curl.haxx.se/)__: cURL is a command line tool for transferring data with URL syntax
* __[Zlib](http://www.zlib.net/)__: A Massively Spiffy Yet Delicately Unobtrusive Compression Library
* __[Source RCON Protocol](https://developer.valvesoftware.com/wiki/Source_RCON_Protocol)__
* __[UT3 Query Protocol](http://wiki.unrealadmin.org/UT3_query_protocol)__
* __[UT3 Query Protocol](http://wiki.unrealadmin.org/UT3_query_protocol)__

View File

@ -1,825 +0,0 @@
<?php
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
class BlockAPI{
private $server;
private $scheduledUpdates = array();
private $randomUpdates = array();
public static $creative = array(
array(COBBLESTONE, 0),
array(STONE_BRICKS, 0),
array(STONE_BRICKS, 1),
array(STONE_BRICKS, 2),
array(MOSS_STONE, 0),
array(WOODEN_PLANKS, 0),
array(BRICKS, 0),
array(STONE, 0),
array(DIRT, 0),
array(GRASS, 0),
array(CLAY_BLOCK, 0),
array(SANDSTONE, 0),
array(SANDSTONE, 1),
array(SANDSTONE, 2),
array(SAND, 0),
array(GRAVEL, 0),
array(TRUNK, 0),
array(TRUNK, 1),
array(TRUNK, 2),
array(NETHER_BRICKS, 0),
array(NETHERRACK, 0),
array(COBBLESTONE_STAIRS, 0),
array(WOODEN_STAIRS, 0),
array(BRICK_STAIRS, 0),
array(SANDSTONE_STAIRS, 0),
array(STONE_BRICK_STAIRS, 0),
array(NETHER_BRICKS_STAIRS, 0),
array(QUARTZ_STAIRS, 0),
array(SLAB, 0),
array(SLAB, 1),
array(SLAB, 2),
array(SLAB, 3),
array(SLAB, 4),
array(SLAB, 5),
array(SLAB, 6),
array(QUARTZ_BLOCK, 0),
array(QUARTZ_BLOCK, 1),
array(QUARTZ_BLOCK, 2),
array(COAL_ORE, 0),
array(IRON_ORE, 0),
array(GOLD_ORE, 0),
array(DIAMOND_ORE, 0),
array(LAPIS_ORE, 0),
array(REDSTONE_ORE, 0),
array(GOLD_BLOCK, 0),
array(IRON_BLOCK, 0),
array(DIAMOND_BLOCK, 0),
array(LAPIS_BLOCK, 0),
array(OBSIDIAN, 0),
array(SNOW_BLOCK, 0),
array(GLASS, 0),
array(GLOWSTONE_BLOCK, 0),
array(NETHER_REACTOR, 0),
array(WOOL, 0),
array(WOOL, 7),
array(WOOL, 6),
array(WOOL, 5),
array(WOOL, 4),
array(WOOL, 3),
array(WOOL, 2),
array(WOOL, 1),
array(WOOL, 15),
array(WOOL, 14),
array(WOOL, 13),
array(WOOL, 12),
array(WOOL, 11),
array(WOOL, 10),
array(WOOL, 9),
array(WOOL, 8),
array(LADDER, 0),
array(TORCH, 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(BED, 0),
array(BOOKSHELF, 0),
array(PAINTING, 0),
array(WORKBENCH, 0),
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(SAPLING, 0),
array(SAPLING, 1),
array(SAPLING, 2),
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(CAKE, 0),
array(EGG, 0),
array(IRON_SWORD, 0),
array(BOW, 0),
array(SIGN, 0),
array(SPAWN_EGG, MOB_CHICKEN),
array(SPAWN_EGG, MOB_COW),
array(SPAWN_EGG, MOB_PIG),
array(SPAWN_EGG, MOB_SHEEP),
);
public static function fromString($str, $multiple = false){
if($multiple === true){
$blocks = array();
foreach(explode(",",$str) as $b){
$blocks[] = BlockAPI::fromString($b, false);
}
return $blocks;
}else{
$b = explode(":", str_replace(" ", "_", trim($str)));
if(!isset($b[1])){
$meta = 0;
}else{
$meta = ((int) $b[1]) & 0xFFFF;
}
if(defined(strtoupper($b[0]))){
$item = BlockAPI::getItem(constant(strtoupper($b[0])), $meta);
if($item->getID() === AIR and strtoupper($b[0]) !== "AIR"){
$item = BlockAPI::getItem(((int) $b[0]) & 0xFFFF, $meta);
}
}else{
$item = BlockAPI::getItem(((int) $b[0]) & 0xFFFF, $meta);
}
return $item;
}
}
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);
}
if($v instanceof Position){
$b->position($v);
}
return $b;
}
public static function getItem($id, $meta = 0, $count = 1){
$id = (int) $id;
if(isset(Item::$class[$id])){
$classname = Item::$class[$id];
$i = new $classname($meta, $count);
}else{
$i = new Item($id, $meta, $count);
}
return $i;
}
function __construct(){
$this->server = ServerAPI::request();
}
public function init(){
$this->server->schedule(1, array($this, "blockUpdateTick"), array(), true);
$this->server->api->console->register("give", "<player> <item[:damage]> [amount]", array($this, "commandHandler"));
}
public function commandHandler($cmd, $params, $issuer, $alias){
$output = "";
switch($cmd){
case "give":
if(!isset($params[0]) or !isset($params[1])){
$output .= "Usage: /give <player> <item[:damage]> [amount]\n";
break;
}
$player = $this->server->api->player->get($params[0]);
$item = BlockAPI::fromString($params[1]);
if(!isset($params[2])){
$item->count = $item->getMaxStackSize();
}else{
$item->count = (int) $params[2];
}
if($player instanceof Player){
if(($player->gamemode & 0x01) === 0x01){
$output .= "Player is in creative mode.\n";
break;
}
if($item->getID() == 0) {
$output .= "You cannot give an air block to a player.\n";
break;
}
$player->addItem($item->getID(), $item->getMetadata(), $item->count);
$output .= "Giving ".$item->count." of ".$item->getName()." (".$item->getID().":".$item->getMetadata().") to ".$player->username."\n";
}else{
$output .= "Unknown player.\n";
}
break;
}
return $output;
}
private function cancelAction(Block $block, Player $player, $send = true){
$player->dataPacket(MC_UPDATE_BLOCK, array(
"x" => $block->x,
"y" => $block->y,
"z" => $block->z,
"block" => $block->getID(),
"meta" => $block->getMetadata()
));
if($send === true){
$player->sendInventorySlot($player->slot);
}
return false;
}
public function playerBlockBreak(Player $player, Vector3 $vector){
$target = $player->level->getBlock($vector);
$item = $player->getSlot($player->slot);
if($this->server->api->dhandle("player.block.touch", array("type" => "break", "player" => $player, "target" => $target, "item" => $item)) === false){
return $this->cancelAction($target, $player, false);
}
if((!$target->isBreakable($item, $player) and $this->server->api->dhandle("player.block.break.invalid", array("player" => $player, "target" => $target, "item" => $item)) !== true) or ($player->gamemode & 0x02) === 0x02 or (($player->lastBreak - $player->getLag() / 1000) + $target->getBreakTime($item, $player) - 0.1) >= microtime(true)){
return $this->cancelAction($target, $player, false);
}
$player->lastBreak = microtime(true);
if($this->server->api->dhandle("player.block.break", array("player" => $player, "target" => $target, "item" => $item)) !== false){
$drops = $target->getDrops($item, $player);
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()){
$player->setSlot($player->slot, new Item(AIR, 0, 0), false);
}
}else{
return $this->cancelAction($target, $player, false);
}
if(($player->gamemode & 0x01) === 0x00 and count($drops) > 0){
foreach($drops as $drop){
$this->server->api->entity->drop(new Position($target->x + 0.5, $target->y, $target->z + 0.5, $target->level), BlockAPI::getItem($drop[0] & 0xFFFF, $drop[1] & 0xFFFF, $drop[2]));
}
}
return false;
}
public function playerBlockAction(Player $player, Vector3 $vector, $face, $fx, $fy, $fz){
if($face < 0 or $face > 5){
return false;
}
$target = $player->level->getBlock($vector);
$block = $target->getSide($face);
$item = $player->getSlot($player->slot);
if($target->getID() === AIR and $this->server->api->dhandle("player.block.place.invalid", array("player" => $player, "block" => $block, "target" => $target, "item" => $item)) !== true){ //If no block exists or not allowed in CREATIVE
$this->cancelAction($target, $player);
return $this->cancelAction($block, $player);
}
if($this->server->api->dhandle("player.block.touch", array("type" => "place", "player" => $player, "block" => $block, "target" => $target, "item" => $item)) === false){
return $this->cancelAction($block, $player);
}
$this->blockUpdate($target, BLOCK_UPDATE_TOUCH);
if($target->isActivable === true){
if($this->server->api->dhandle("player.block.activate", array("player" => $player, "block" => $block, "target" => $target, "item" => $item)) !== false and $target->onActivate($item, $player) === true){
return false;
}
}
if(($player->gamemode & 0x02) === 0x02){ //Adventure mode!!
return $this->cancelAction($block, $player, false);
}
if($block->y > 127 or $block->y < 0){
return false;
}
if($item->isActivable === true and $item->onActivate($player->level, $player, $block, $target, $face, $fx, $fy, $fz) === true){
if($item->count <= 0){
$player->setSlot($player->slot, BlockAPI::getItem(AIR, 0, 0), false);
}
return false;
}
if($item->isPlaceable()){
$hand = $item->getBlock();
$hand->position($block);
}elseif($block->getID() === FIRE){
$player->level->setBlock($block, new AirBlock(), true, false, true);
return false;
}else{
return $this->cancelAction($block, $player, false);
}
if(!($block->isReplaceable === true or ($hand->getID() === SLAB and $block->getID() === SLAB))){
return $this->cancelAction($block, $player, false);
}
if($hand->isSolid === true and $player->entity->inBlock($block)){
return $this->cancelAction($block, $player, false); //Entity in block
}
if($this->server->api->dhandle("player.block.place", array("player" => $player, "block" => $block, "target" => $target, "item" => $item)) === false){
return $this->cancelAction($block, $player);
}elseif($hand->place($item, $player, $block, $target, $face, $fx, $fy, $fz) === false){
return $this->cancelAction($block, $player, false);
}
if($hand->getID() === SIGN_POST or $hand->getID() === WALL_SIGN){
$t = $this->server->api->tile->addSign($player->level, $block->x, $block->y, $block->z);
$t->data["creator"] = $player->username;
}
if(($player->gamemode & 0x01) === 0x00){
--$item->count;
if($item->count <= 0){
$player->setSlot($player->slot, BlockAPI::getItem(AIR, 0, 0), false);
}
}
return false;
}
/*
public function flowLavaOn($source, $face){
$down = 0;
if($face === BlockFace::BOTTOM){
$level = 0;
$down = 1;
}else{
$level = ($source[1] & 0x07) + 2;
if($level > 0x07){
return false;
}
}
$spread = $this->server->api->level->getBlockFace($source, $face);
if(($source[0] === 10 or $source[0] === 11) and $spread[0] === 10){
if($level < ($spread[1] & 0x07)){
$this->server->schedule(20, array($this, "blockScheduler"), array(
"x" => $spread[2][0],
"y" => $spread[2][1],
"z" => $spread[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], $spread[0], $level | $down, false);
return true;
}
}elseif($spread[0] === 9 or $spread[0] === 8){
if($source[0] === 11){
$this->server->api->level->setBlock($source[2][0], $source[2][1], $source[2][2], 49, 0);
}elseif($face === 0){
$this->server->api->level->setBlock($source[2][0], $source[2][1], $source[2][2], 1, 0);
}else{
$this->server->api->level->setBlock($source[2][0], $source[2][1], $source[2][2], 4, 0);
}
return true;
}elseif(isset(Material::$flowable[$spread[0]])){
$this->server->schedule(20, array($this, "blockScheduler"), array(
"x" => $spread[2][0],
"y" => $spread[2][1],
"z" => $spread[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], 10, $level | $down, false);
return true;
}elseif(($source[1] & 0x08) === 0x08){
$this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], $source[0], $source[1] & 0x07, false);
return true;
}
return false;
}
public function flowWaterOn($source, $face, &$spread = null){
$down = 0;
if($face === BlockFace::BOTTOM){
$level = 0;
$down = 1;
}else{
$level = ($source[1] & 0x07) + 1;
if($level > 0x07){
return false;
}
}
$spread = $this->server->api->level->getBlockFace($source, $face);
if(($source[0] === 8 or $source[0] === 9) and $spread[0] === 8){
if($level < ($spread[1] & 0x07)){
$this->server->schedule(10, array($this, "blockScheduler"), array(
"x" => $spread[2][0],
"y" => $spread[2][1],
"z" => $spread[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], $spread[0], $level | $down, false);
return true;
}
}elseif($spread[0] === 11){
$this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], 49, 0, true);
return true;
}elseif($spread[0] === 10){
if($face === 0 or ($spread[1] & 0x08) === 0){
$this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], 4, 0, true);
return true;
}
}elseif(isset(Material::$flowable[$spread[0]])){
$this->server->schedule(10, array($this, "blockScheduler"), array(
"x" => $spread[2][0],
"y" => $spread[2][1],
"z" => $spread[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], 8, $level | $down, false);
return true;
}elseif(($source[1] & 0x08) === 0x08){
$this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], $source[0], $source[1] & 0x07, false);
return true;
}
return false;
}
public function updateBlock($x, $y, $z, $type = BLOCK_UPDATE_NORMAL){
$block = $this->server->api->level->getBlock($x, $y, $z);
$changed = false;
switch($block[0]){
case 8:
case 9:
$faces = array();
if(!$this->flowWaterOn($block, 0, $floor) or $block[0] === 9){
$this->flowWaterOn($block, 2, $faces[0]);
$this->flowWaterOn($block, 3, $faces[1]);
$this->flowWaterOn($block, 4, $faces[2]);
$this->flowWaterOn($block, 5, $faces[3]);
}
if($block[0] === 8){
//Source creation
if(!isset(Material::$flowable[$floor[0]])){
$sources = 0;
foreach($faces as $i => $b){
if($b[0] === 9){
++$sources;
}
}
if($sources >= 2){
$this->server->api->level->setBlock($block[2][0], $block[2][1], $block[2][2], 9, 0, false);
$this->server->schedule(10, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1],
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
break;
}
}
$drained = true;
$level = $block[1] & 0x07;
$up = $this->server->api->level->getBlockFace($block, BlockFace::UP);
if($up[0] === 8 or $up[0] === 9){
$drained = false;
}else{
$b = $this->server->api->level->getBlockFace($block, BlockFace::NORTH);
if($b[0] === 9 or ($b[0] === 8 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
$drained = false;
}else{
$b = $this->server->api->level->getBlockFace($block, BlockFace::SOUTH);
if($b[0] === 9 or ($b[0] === 8 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
$drained = false;
}else{
$b = $this->server->api->level->getBlockFace($block, BlockFace::EAST);
if($b[0] === 9 or ($b[0] === 8 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
$drained = false;
}else{
$b = $this->server->api->level->getBlockFace($block, BlockFace::WEST);
if($b[0] === 9 or ($b[0] === 8 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
$drained = false;
}
}
}
}
}
if($drained === true){
++$level;
if($level > 0x07){
$this->server->schedule(10, array($this, "blockScheduler"), array(
"x" => $block[2][0] + 1,
"y" => $block[2][1],
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(10, array($this, "blockScheduler"), array(
"x" => $block[2][0] - 1,
"y" => $block[2][1],
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(10, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1],
"z" => $block[2][2] + 1,
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(10, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1],
"z" => $block[2][2] - 1,
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(10, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1] - 1,
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->api->level->setBlock($block[2][0], $block[2][1], $block[2][2], 0, 0, false);
}else{
$block[1] = ($block[1] & 0x08) | $level;
$this->server->schedule(10, array($this, "blockScheduler"), array(
"x" => $block[2][0] + 1,
"y" => $block[2][1],
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(10, array($this, "blockScheduler"), array(
"x" => $block[2][0] - 1,
"y" => $block[2][1],
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(10, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1],
"z" => $block[2][2] + 1,
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(10, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1],
"z" => $block[2][2] - 1,
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(10, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1] - 1,
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(10, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1],
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->api->level->setBlock($block[2][0], $block[2][1], $block[2][2], $block[0], $block[1], false);
}
}
}
break;
case 10:
case 11:
if(!$this->flowLavaOn($block, 0) or $block[0] === 11){
$this->flowLavaOn($block, 2);
$this->flowLavaOn($block, 3);
$this->flowLavaOn($block, 4);
$this->flowLavaOn($block, 5);
}
if($block[0] === 10){
$drained = true;
$level = $block[1] & 0x07;
$up = $this->server->api->level->getBlockFace($block, BlockFace::UP);
if($up[0] === 10 or $up[0] === 11){
$drained = false;
}else{
$b = $this->server->api->level->getBlockFace($block, BlockFace::NORTH);
if($b[0] === 11 or ($b[0] === 10 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
$drained = false;
}else{
$b = $this->server->api->level->getBlockFace($block, BlockFace::SOUTH);
if($b[0] === 11 or ($b[0] === 10 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
$drained = false;
}else{
$b = $this->server->api->level->getBlockFace($block, BlockFace::EAST);
if($b[0] === 11 or ($b[0] === 10 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
$drained = false;
}else{
$b = $this->server->api->level->getBlockFace($block, BlockFace::WEST);
if($b[0] === 11 or ($b[0] === 10 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
$drained = false;
}
}
}
}
}
if($drained === true){
++$level;
if($level > 0x07){
$this->server->schedule(20, array($this, "blockScheduler"), array(
"x" => $block[2][0] + 1,
"y" => $block[2][1],
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(20, array($this, "blockScheduler"), array(
"x" => $block[2][0] - 1,
"y" => $block[2][1],
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(20, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1],
"z" => $block[2][2] + 1,
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(20, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1],
"z" => $block[2][2] - 1,
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(20, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1] - 1,
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->api->level->setBlock($block[2][0], $block[2][1], $block[2][2], 0, 0, false);
}else{
$block[1] = ($block[1] & 0x08) | $level;
$this->server->schedule(20, array($this, "blockScheduler"), array(
"x" => $block[2][0] + 1,
"y" => $block[2][1],
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(20, array($this, "blockScheduler"), array(
"x" => $block[2][0] - 1,
"y" => $block[2][1],
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(20, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1],
"z" => $block[2][2] + 1,
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(20, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1],
"z" => $block[2][2] - 1,
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(20, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1] - 1,
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(20, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1],
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->api->level->setBlock($block[2][0], $block[2][1], $block[2][2], $block[0], $block[1], false);
}
}
}
break;
}
if($type === BLOCK_TYPE_SCHEDULED){
$type = BLOCK_UPDATE_WEAK;
}
if($changed === true){
$this->updateBlocksAround($x, $y, $z, $type);
}
}*/
public function blockUpdateAround(Position $pos, $type = BLOCK_UPDATE_NORMAL, $delay = false){
if($delay !== false){
$this->scheduleBlockUpdate($pos->getSide(0), $delay, $type);
$this->scheduleBlockUpdate($pos->getSide(1), $delay, $type);
$this->scheduleBlockUpdate($pos->getSide(2), $delay, $type);
$this->scheduleBlockUpdate($pos->getSide(3), $delay, $type);
$this->scheduleBlockUpdate($pos->getSide(4), $delay, $type);
$this->scheduleBlockUpdate($pos->getSide(5), $delay, $type);
}else{
$this->blockUpdate($pos->getSide(0), $type);
$this->blockUpdate($pos->getSide(1), $type);
$this->blockUpdate($pos->getSide(2), $type);
$this->blockUpdate($pos->getSide(3), $type);
$this->blockUpdate($pos->getSide(4), $type);
$this->blockUpdate($pos->getSide(5), $type);
}
}
public function blockUpdate(Position $pos, $type = BLOCK_UPDATE_NORMAL){
if(!($pos instanceof Block)){
$block = $pos->level->getBlock($pos);
}else{
$pos = new Position($pos->x, $pos->y, $pos->z, $pos->level);
$block = $pos->level->getBlock($pos);
}
if($block === false){
return false;
}
$level = $block->onUpdate($type);
if($level === BLOCK_UPDATE_NORMAL){
$this->blockUpdateAround($block, $level);
$this->server->api->entity->updateRadius($pos, 1);
}elseif($level === BLOCK_UPDATE_RANDOM){
$this->nextRandomUpdate($pos);
}
return $level;
}
public function scheduleBlockUpdate(Position $pos, $delay, $type = BLOCK_UPDATE_SCHEDULED){
$type = (int) $type;
if($delay < 0){
return false;
}
$index = $pos->x.".".$pos->y.".".$pos->z.".".$pos->level->getName().".".$type;
$delay = microtime(true) + $delay * 0.05;
if(!isset($this->scheduledUpdates[$index])){
$this->scheduledUpdates[$index] = $pos;
$this->server->query("INSERT INTO blockUpdates (x, y, z, level, type, delay) VALUES (".$pos->x.", ".$pos->y.", ".$pos->z.", '".$pos->level->getName()."', ".$type.", ".$delay.");");
return true;
}
return false;
}
public function nextRandomUpdate(Position $pos){
if(!isset($this->scheduledUpdates[$pos->x.".".$pos->y.".".$pos->z.".".$pos->level->getName().".".BLOCK_UPDATE_RANDOM])){
$X = (($pos->x >> 4) << 4);
$Y = (($pos->y >> 4) << 4);
$Z = (($pos->z >> 4) << 4);
$time = microtime(true);
$i = 0;
$offset = 0;
while(true){
$t = $offset + Utils::getRandomUpdateTicks() * 0.05;
$update = $this->server->query("SELECT COUNT(*) FROM blockUpdates WHERE level = '".$pos->level->getName()."' AND type = ".BLOCK_UPDATE_RANDOM." AND delay >= ".($time + $t - 1)." AND delay <= ".($time + $t + 1).";");
if($update instanceof SQLite3Result){
$update = $update->fetchArray(SQLITE3_NUM);
if($update[0] < 3){
break;
}
}else{
break;
}
$offset += mt_rand(25, 75);
}
$this->scheduleBlockUpdate($pos, $t / 0.05, BLOCK_UPDATE_RANDOM);
}
}
public function blockUpdateTick(){
$time = microtime(true);
if(count($this->scheduledUpdates) > 0){
$update = $this->server->query("SELECT x,y,z,level,type FROM blockUpdates WHERE delay <= ".$time.";");
if($update instanceof SQLite3Result){
$upp = array();
while(($up = $update->fetchArray(SQLITE3_ASSOC)) !== false){
$index = $up["x"].".".$up["y"].".".$up["z"].".".$up["level"].".".$up["type"];
if(isset($this->scheduledUpdates[$index])){
$upp[] = array((int) $up["type"], $this->scheduledUpdates[$index]);
unset($this->scheduledUpdates[$index]);
}
}
$this->server->query("DELETE FROM blockUpdates WHERE delay <= ".$time.";");
foreach($upp as $b){
$this->blockUpdate($b[1], $b[0]);
}
}
}
}
}

View File

@ -1,123 +0,0 @@
<?php
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
class ChatAPI{
private $server;
function __construct(){
$this->server = ServerAPI::request();
}
public function init(){
$this->server->api->console->register("tell", "<player> <private message ...>", array($this, "commandHandler"));
$this->server->api->console->register("me", "<action ...>", array($this, "commandHandler"));
$this->server->api->console->register("say", "<message ...>", array($this, "commandHandler"));
$this->server->api->ban->cmdWhitelist("tell");
$this->server->api->ban->cmdWhitelist("me");
}
public function commandHandler($cmd, $params, $issuer, $alias){
$output = "";
switch($cmd){
case "say":
$s = implode(" ", $params);
if(trim($s) == ""){
$output .= "Usage: /say <message>\n";
break;
}
$sender = ($issuer instanceof Player) ? "Server":ucfirst($issuer);
$this->server->api->chat->broadcast("[$sender] ".$s);
break;
case "me":
if(!($issuer instanceof Player)){
if($issuer === "rcon"){
$sender = "Rcon";
}else{
$sender = ucfirst($issuer);
}
}else{
$sender = $issuer->username;
}
$this->broadcast("* $sender ".implode(" ", $params));
break;
case "tell":
if(!isset($params[0]) or !isset($params[1])){
$output .= "Usage: /$cmd <player> <message>\n";
break;
}
if(!($issuer instanceof Player)){
$sender = ucfirst($issuer);
}else{
$sender = $issuer->username;
}
$n = array_shift($params);
$target = $this->server->api->player->get($n);
if($target instanceof Player){
$target = $target->username;
}else{
$target = strtolower($n);
if($t === "server" or $t === "console" or $t === "rcon"){
$target = "Console";
}
}
$mes = implode(" ", $params);
$output .= "[me -> ".$target."] ".$mes."\n";
if($target !== "Console" and $target !== "Rcon"){
$this->sendTo(false, "[".$sender." -> me] ".$mes, $target);
}
console("[INFO] [".$sender." -> ".$target."] ".$mes);
break;
}
return $output;
}
public function broadcast($message){
$this->send(false, $message);
}
public function sendTo($owner, $text, $player){
$this->send($owner, $text, array($player));
}
public function send($owner, $text, $whitelist = false, $blacklist = false){
$message = array(
"player" => $owner,
"message" => $text,
);
if($owner !== false){
if($owner instanceof Player){
if($whitelist === false){
console("[INFO] <".$owner->username."> ".$text);
}
}else{
if($whitelist === false){
console("[INFO] <".$owner."> ".$text);
}
}
}else{
if($whitelist === false){
console("[INFO] $text");
}
$message["player"] = "";
}
$this->server->handle("server.chat", new Container($message, $whitelist, $blacklist));
}
}

View File

@ -1,319 +0,0 @@
<?php
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
class ConsoleAPI{
private $loop, $server, $event, $help, $cmds, $alias;
function __construct(){
$this->help = array();
$this->cmds = array();
$this->alias = array();
$this->server = ServerAPI::request();
$this->last = microtime(true);
}
public function init(){
$this->server->schedule(2, array($this, "handle"), array(), true);
if(!defined("NO_THREADS")){
$this->loop = new ConsoleLoop();
}
$this->register("help", "[page|command name]", array($this, "defaultCommands"));
$this->register("status", "", array($this, "defaultCommands"));
$this->register("difficulty", "<0|1|2|3>", array($this, "defaultCommands"));
$this->register("stop", "", array($this, "defaultCommands"));
$this->register("defaultgamemode", "<mode>", array($this, "defaultCommands"));
$this->server->api->ban->cmdWhitelist("help");
}
function __destruct(){
$this->server->deleteEvent($this->event);
if(!defined("NO_THREADS")){
$this->loop->stop();
$this->loop->notify();
//$this->loop->join();
}
}
public function defaultCommands($cmd, $params, $issuer, $alias){
$output = "";
switch($cmd){
case "defaultgamemode":
$gms = array(
"0" => SURVIVAL,
"survival" => SURVIVAL,
"s" => SURVIVAL,
"1" => CREATIVE,
"creative" => CREATIVE,
"c" => CREATIVE,
"2" => ADVENTURE,
"adventure" => ADVENTURE,
"a" => ADVENTURE,
"3" => VIEW,
"view" => VIEW,
"viewer" => VIEW,
"spectator" => VIEW,
"v" => VIEW,
);
if(!isset($gms[strtolower($params[0])])){
$output .= "Usage: /$cmd <mode>\n";
break;
}
$this->server->api->setProperty("gamemode", $gms[strtolower($params[0])]);
$output .= "Default Gamemode is now ".strtoupper($this->server->getGamemode()).".\n";
break;
case "status":
if(!($issuer instanceof Player) and $issuer === "console"){
$this->server->debugInfo(true);
}
$info = $this->server->debugInfo();
$output .= "TPS: ".$info["tps"].", Memory usage: ".$info["memory_usage"]." (Peak ".$info["memory_peak_usage"].")\n";
break;
case "update-done":
$this->server->api->setProperty("last-update", time());
break;
case "stop":
$this->loop->stop = true;
$output .= "Stopping the server\n";
$this->server->close();
break;
case "difficulty":
$s = trim(array_shift($params));
if($s === "" or (((int) $s) > 3 and ((int) $s) < 0)){
$output .= "Usage: /difficulty <0|1|2|3>\n";
break;
}
$this->server->api->setProperty("difficulty", (int) $s);
$output .= "Difficulty changed to ".$this->server->difficulty."\n";
break;
case "?":
if($issuer !== "console" and $issuer !== "rcon"){
break;
}
case "help":
if(isset($params[0]) and !is_numeric($params[0])){
$c = trim(strtolower($params[0]));
if(isset($this->help[$c]) or isset($this->alias[$c])){
$c = isset($this->help[$c]) ? $c : $this->alias[$c];
if($this->server->api->dhandle("console.command.".$c, array("cmd" => $c, "parameters" => array(), "issuer" => $issuer, "alias" => false)) === false or $this->server->api->dhandle("console.command", array("cmd" => $c, "parameters" => array(), "issuer" => $issuer, "alias" => false)) === false){
break;
}
$output .= "Usage: /$c ".$this->help[$c]."\n";
break;
}
}
$cmds = array();
foreach($this->help as $c => $h){
if($this->server->api->dhandle("console.command.".$c, array("cmd" => $c, "parameters" => array(), "issuer" => $issuer, "alias" => false)) === false or $this->server->api->dhandle("console.command", array("cmd" => $c, "parameters" => array(), "issuer" => $issuer, "alias" => false)) === false){
continue;
}
$cmds[$c] = $h;
}
$max = ceil(count($cmds) / 5);
$page = (int) (isset($params[0]) ? min($max, max(1, intval($params[0]))):1);
$output .= "\x1b[31;1m-\x1b[0m Showing help page $page of $max (/help <page>) \x1b[31;1m-\x1b[0m\n";
$current = 1;
foreach($cmds as $c => $h){
$curpage = (int) ceil($current / 5);
if($curpage === $page){
$output .= "/$c ".$h."\n";
}elseif($curpage > $page){
break;
}
++$current;
}
break;
default:
$output .= "Command doesn't exist! Use /help\n";
break;
}
return $output;
}
public function alias($alias, $cmd){
$this->alias[strtolower(trim($alias))] = trim($cmd);
return true;
}
public function register($cmd, $help, $callback){
if(!is_callable($callback)){
return false;
}
$cmd = strtolower(trim($cmd));
$this->cmds[$cmd] = $callback;
$this->help[$cmd] = $help;
ksort($this->help, SORT_NATURAL | SORT_FLAG_CASE);
}
public function run($line = "", $issuer = "console", $alias = false){
if($line != ""){
$output = "";
$end = strpos($line, " ");
if($end === false){
$end = strlen($line);
}
$cmd = strtolower(substr($line, 0, $end));
$params = (string) substr($line, $end + 1);
if(isset($this->alias[$cmd])){
return $this->run($this->alias[$cmd] . ($params !== "" ? " " .$params:""), $issuer, $cmd);
}
if($issuer instanceof Player){
console("[DEBUG] ".FORMAT_AQUA.$issuer->username.FORMAT_RESET." issued server command: ".ltrim("$alias ")."/$cmd ".$params, true, true, 2);
}else{
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){
$offsetshift = 0;
foreach($matches[1] as $selector){
if($selector[0]{0} === "@"){ //Escape!
$params = substr_replace($params, $selector[0], $selector[1] + $offsetshift - 1, strlen($selector[0]) + 1);
--$offsetshift;
continue;
}
switch(strtolower($selector[0])){
case "u":
case "player":
case "username":
$p = ($issuer instanceof Player) ? $issuer->username:$issuer;
$params = substr_replace($params, $p, $selector[1] + $offsetshift - 1, strlen($selector[0]) + 1);
$offsetshift -= strlen($selector[0]) - strlen($p) + 1;
break;
case "w":
case "world":
$p = ($issuer instanceof Player) ? $issuer->level->getName():$this->server->api->level->getDefault()->getName();
$params = substr_replace($params, $p, $selector[1] + $offsetshift - 1, strlen($selector[0]) + 1);
$offsetshift -= strlen($selector[0]) - strlen($p) + 1;
break;
case "a":
case "all":
$output = "";
foreach($this->server->api->player->getAll() as $p){
$output .= $this->run($cmd . " ". substr_replace($params, $p->username, $selector[1] + $offsetshift - 1, strlen($selector[0]) + 1), $issuer, $alias);
}
return $output;
case "r":
case "random":
$l = array();
foreach($this->server->api->player->getAll() as $p){
if($p !== $issuer){
$l[] = $p;
}
}
if(count($l) === 0){
return;
}
$p = $l[mt_rand(0, count($l) - 1)]->username;
$params = substr_replace($params, $p, $selector[1] + $offsetshift - 1, strlen($selector[0]) + 1);
$offsetshift -= strlen($selector[0]) - strlen($p) + 1;
break;
}
}
}
$params = explode(" ", $params);
if(count($params) === 1 and $params[0] === ""){
$params = array();
}
if(($d1 = $this->server->api->dhandle("console.command.".$cmd, array("cmd" => $cmd, "parameters" => $params, "issuer" => $issuer, "alias" => $alias))) === false
or ($d2 = $this->server->api->dhandle("console.command", array("cmd" => $cmd, "parameters" => $params, "issuer" => $issuer, "alias" => $alias))) === false){
$output = "You don't have permissions to use this command.\n";
}elseif($d1 !== true and $d2 !== true){
if(isset($this->cmds[$cmd]) and is_callable($this->cmds[$cmd])){
$output = @call_user_func($this->cmds[$cmd], $cmd, $params, $issuer, $alias);
}elseif($this->server->api->dhandle("console.command.unknown", array("cmd" => $cmd, "params" => $params, "issuer" => $issuer, "alias" => $alias)) !== false){
$output = $this->defaultCommands($cmd, $params, $issuer, $alias);
}
}
if($output != "" and ($issuer instanceof Player)){
$issuer->sendChat(trim($output));
}
return $output;
}
}
public function handle($time){
if(defined("NO_THREADS")){
return;
}
if($this->loop->line !== false){
$line = trim($this->loop->line);
$this->loop->line = false;
$output = $this->run($line, "console");
if($output != ""){
$mes = explode("\n", trim($output));
foreach($mes as $m){
console("[CMD] ".$m);
}
}
}else{
$this->loop->notify();
}
}
}
class ConsoleLoop extends Thread{
public $line;
public $stop;
public $base;
public $ev;
public $fp;
public function __construct(){
$this->line = false;
$this->stop = false;
$this->start();
}
public function stop(){
$this->stop = true;
}
private function readLine(){
if($this->fp){
$line = trim(fgets($this->fp));
}else{
$line = trim(readline(""));
if($line != ""){
readline_add_history( $line );
}
}
return $line;
}
public function run(){
if(!extension_loaded("readline")){
$this->fp = fopen( "php://stdin", "r" );
}
while($this->stop === false){
$this->line = $this->readLine();
$this->wait();
$this->line = false;
}
if(!$this->haveReadline){
@fclose($fp);
}
exit(0);
}
}

View File

@ -1,173 +0,0 @@
<?php
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
class EntityAPI{
private $server;
private $entities;
private $eCnt = 1;
function __construct(){
$this->entities = array();
$this->server = ServerAPI::request();
}
public function get($eid){
if(isset($this->entities[$eid])){
return $this->entities[$eid];
}
return false;
}
public function init(){
$this->server->schedule(25, array($this, "updateEntities"), array(), true);
}
public function updateEntities(){
$l = $this->server->query("SELECT EID FROM entities WHERE hasUpdate = 1;");
if($l !== false and $l !== true){
while(($e = $l->fetchArray(SQLITE3_ASSOC)) !== false){
$e = $this->get($e["EID"]);
if($e instanceof Entity){
$e->update();
$this->server->query("UPDATE entities SET hasUpdate = 0 WHERE EID = ".$e->eid.";");
}
}
}
}
public function updateRadius(Position $center, $radius = 15, $class = false){
$this->server->query("UPDATE entities SET hasUpdate = 1 WHERE level = '".$center->level->getName()."' ".($class !== false ? "AND class = $class ":"")."AND abs(x - {$center->x}) <= $radius AND abs(y - {$center->y}) <= $radius AND abs(z - {$center->z}) <= $radius;");
}
public function getRadius(Position $center, $radius = 15, $class = false){
$entities = array();
$l = $this->server->query("SELECT EID FROM entities WHERE level = '".$center->level->getName()."' ".($class !== false ? "AND class = $class ":"")."AND abs(x - {$center->x}) <= $radius AND abs(y - {$center->y}) <= $radius AND abs(z - {$center->z}) <= $radius;");
if($l !== false and $l !== true){
while(($e = $l->fetchArray(SQLITE3_ASSOC)) !== false){
$e = $this->get($e["EID"]);
if($e instanceof Entity){
$entities[$e->eid] = $e;
}
}
}
return $entities;
}
public function getAll($level = null){
if($level instanceof Level){
$entities = array();
$l = $this->server->query("SELECT EID FROM entities WHERE level = '".$level->getName()."';");
if($l !== false and $l !== true){
while(($e = $l->fetchArray(SQLITE3_ASSOC)) !== false){
$e = $this->get($e["EID"]);
if($e instanceof Entity){
$entities[$e->eid] = $e;
}
}
}
return $entities;
}
return $this->entities;
}
public function heal($eid, $heal = 1, $cause){
$this->harm($eid, -$heal, $cause);
}
public function harm($eid, $attack = 1, $cause, $force = false){
$e = $this->get($eid);
if($e === false or $e->dead === true){
return false;
}
$e->setHealth($e->getHealth() - $attack, $cause, $force);
}
public function add(Level $level, $class, $type = 0, $data = array()){
$eid = $this->eCnt++;
$this->entities[$eid] = new Entity($level, $eid, $class, $type, $data);
$this->server->handle("entity.add", $this->entities[$eid]);
return $this->entities[$eid];
}
public function spawnToAll(Entity $e){
foreach($this->server->api->player->getAll($e->level) as $player){
if($player->eid !== false and $player->eid !== $e->eid and $e->class !== ENTITY_PLAYER){
$e->spawn($player);
}
}
}
public function drop(Position $pos, Item $item){
if($item->getID() === AIR or $item->count <= 0){
return;
}
$data = array(
"x" => $pos->x + mt_rand(-10, 10) / 50,
"y" => $pos->y + 0.19,
"z" => $pos->z + mt_rand(-10, 10) / 50,
//"speedX" => mt_rand(-3, 3) / 8,
"speedY" => mt_rand(5, 8) / 2,
//"speedZ" => mt_rand(-3, 3) / 8,
"item" => $item,
);
if($this->server->api->handle("item.drop", $data) !== false){
for($count = $item->count; $count > 0; ){
$item->count = min($item->getMaxStackSize(), $count);
$count -= $item->count;
$e = $this->add($pos->level, ENTITY_ITEM, $item->getID(), $data);
$this->spawnToAll($e);
$this->server->api->handle("entity.motion", $e);
}
}
}
public function spawnAll(Player $player){
foreach($this->getAll($player->level) as $e){
if($e->class !== ENTITY_PLAYER){
$e->spawn($player);
}
}
}
public function remove($eid){
if(isset($this->entities[$eid])){
$entity = $this->entities[$eid];
$this->entities[$eid] = null;
unset($this->entities[$eid]);
$entity->closed = true;
$this->server->query("DELETE FROM entities WHERE EID = ".$eid.";");
if($entity->class === ENTITY_PLAYER){
$this->server->api->player->broadcastPacket($this->server->api->player->getAll(), MC_REMOVE_PLAYER, array(
"clientID" => 0,
"eid" => $entity->eid,
));
}else{
$this->server->api->player->broadcastPacket($this->server->api->player->getAll($entity->level), MC_REMOVE_ENTITY, array(
"eid" => $entity->eid,
));
}
$this->server->api->dhandle("entity.remove", $entity);
$entity = null;
unset($entity);
}
}
}

View File

@ -1,240 +0,0 @@
<?php
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
class LevelAPI{
private $server, $levels, $default;
public function __construct(){
$this->server = ServerAPI::request();
$this->levels = array();
}
public function get($name){
if(isset($this->levels[$name])){
return $this->levels[$name];
}
return false;
}
public function getDefault(){
return $this->levels[$this->default];
}
public function init(){
$this->server->api->console->register("seed", "[world]", array($this, "commandHandler"));
$this->server->api->console->register("save-all", "", array($this, "commandHandler"));
$this->server->api->console->register("save-on", "", array($this, "commandHandler"));
$this->server->api->console->register("save-off", "", array($this, "commandHandler"));
$this->default = $this->server->api->getProperty("level-name");
if($this->loadLevel($this->default) === false){
$this->generateLevel($this->default, $this->server->seed);
$this->loadLevel($this->default);
}
$this->server->spawn = $this->getDefault()->getSafeSpawn();
}
public function commandHandler($cmd, $params, $issuer, $alias){
$output = "";
switch($cmd){
case "save-all":
$save = $this->server->saveEnabled;
$this->server->saveEnabled = true;
$this->saveAll();
$this->server->saveEnabled = $save;
break;
case "save-on":
$this->server->saveEnabled = true;
break;
case "save-off":
$this->server->saveEnabled = false;
break;
case "seed":
if(!isset($params[0]) and ($issuer instanceof Player)){
$output .= "Seed: ".$issuer->level->getSeed()."\n";
}elseif(isset($params[0])){
if(($lv = $this->server->api->level->get(trim(implode(" ", $params)))) !== false){
$output .= "Seed: ".$lv->getSeed()."\n";
}
}else{
$output .= "Seed: ".$this->server->api->level->getDefault()->getSeed()."\n";
}
}
return $output;
}
public function generateLevel($name, $seed = false, $generator = false){
if($this->levelExists($name)){
return false;
}
$options = array();
if($this->server->api->getProperty("generator-settings") !== false and trim($this->server->api->getProperty("generator-settings")) != ""){
$options["preset"] = $this->server->api->getProperty("generator-settings");
}
if($generator !== false and class_exists($generator)){
$generator = new $generator($options);
}else{
if(strtoupper($this->server->api->getProperty("level-type")) == "FLAT"){
$generator = new SuperflatGenerator($options);
}else{
$generator = new TemporalGenerator($options);
}
}
$gen = new WorldGenerator($generator, $name, $seed === false ? Utils::readInt(Utils::getRandomBytes(4, false)):(int) $seed);
$gen->generate();
$gen->close();
return true;
}
public function levelExists($name){
if($name === ""){
return false;
}
$path = DATA_PATH."worlds/".$name."/";
if($this->get($name) === false and !file_exists($path."level.pmf")){
$level = new LevelImport($path);
if($level->import() === false){
return false;
}
}
return true;
}
public function unloadLevel(Level $level, $force = false){
$name = $level->getName();
if($name === $this->default and $force !== true){
return false;
}
console("[INFO] Unloading level \"".$name."\"");
$level->nextSave = PHP_INT_MAX;
$level->save();
foreach($this->server->api->player->getAll($level) as $player){
$player->teleport($this->server->spawn);
}
foreach($this->server->api->entity->getAll($level) as $entity){
if($entity->class !== ENTITY_PLAYER){
$entity->close();
}
}
foreach($this->server->api->tile->getAll($level) as $tile){
$tile->close();
}
$level->close();
unset($this->levels[$name]);
return true;
}
public function loadLevel($name){
if($this->get($name) !== false){
return true;
}elseif($this->levelExists($name) === false){
console("[NOTICE] Level \"".$name."\" not found");
return false;
}
$path = DATA_PATH."worlds/".$name."/";
console("[INFO] Preparing level \"".$name."\"");
$level = new PMFLevel($path."level.pmf");
$entities = new Config($path."entities.yml", CONFIG_YAML);
if(file_exists($path."tileEntities.yml")){
@rename($path."tileEntities.yml", $path."tiles.yml");
}
$tiles = new Config($path."tiles.yml", CONFIG_YAML);
$blockUpdates = new Config($path."bupdates.yml", CONFIG_YAML);
$this->levels[$name] = new Level($level, $entities, $tiles, $blockUpdates, $name);
foreach($entities->getAll() as $entity){
if(!isset($entity["id"])){
break;
}
if($entity["id"] === 64){ //Item Drop
$e = $this->server->api->entity->add($this->levels[$name], ENTITY_ITEM, $entity["Item"]["id"], array(
"meta" => $entity["Item"]["Damage"],
"stack" => $entity["Item"]["Count"],
"x" => $entity["Pos"][0],
"y" => $entity["Pos"][1],
"z" => $entity["Pos"][2],
"yaw" => $entity["Rotation"][0],
"pitch" => $entity["Rotation"][1],
));
}elseif($entity["id"] === FALLING_SAND){
$e = $this->server->api->entity->add($this->levels[$name], ENTITY_FALLING, $entity["id"], $entity);
$e->setPosition(new Vector3($entity["Pos"][0], $entity["Pos"][1], $entity["Pos"][2]), $entity["Rotation"][0], $entity["Rotation"][1]);
$e->setHealth($entity["Health"]);
}elseif($entity["id"] === OBJECT_PAINTING or $entity["id"] === OBJECT_ARROW){ //Painting
$e = $this->server->api->entity->add($this->levels[$name], ENTITY_OBJECT, $entity["id"], $entity);
$e->setPosition(new Vector3($entity["Pos"][0], $entity["Pos"][1], $entity["Pos"][2]), $entity["Rotation"][0], $entity["Rotation"][1]);
$e->setHealth(1);
}else{
$e = $this->server->api->entity->add($this->levels[$name], ENTITY_MOB, $entity["id"], $entity);
$e->setPosition(new Vector3($entity["Pos"][0], $entity["Pos"][1], $entity["Pos"][2]), $entity["Rotation"][0], $entity["Rotation"][1]);
$e->setHealth($entity["Health"]);
}
}
foreach($tiles->getAll() as $tile){
if(!isset($tile["id"])){
break;
}
$t = $this->server->api->tile->add($this->levels[$name], $tile["id"], $tile["x"], $tile["y"], $tile["z"], $tile);
}
$timeu = microtime(true);
foreach($blockUpdates->getAll() as $bupdate){
$this->server->api->block->scheduleBlockUpdate(new Position((int) $bupdate["x"],(int) $bupdate["y"],(int) $bupdate["z"], $this->levels[$name]), (float) $bupdate["delay"], (int) $bupdate["type"]);
}
return true;
}
public function handle($data, $event){
switch($event){
}
}
public function saveAll(){
foreach($this->levels as $level){
$level->save();
}
}
public function __destruct(){
$this->saveAll();
foreach($this->levels as $level){
$this->unloadLevel($level, true);
}
}
public function getSpawn(){
return $this->server->spawn;
}
public function loadMap(){
if($this->mapName !== false and trim($this->mapName) !== ""){
if(!file_exists($this->mapDir."level.pmf")){
$level = new LevelImport($this->mapDir);
$level->import();
}
$this->level = new PMFLevel($this->mapDir."level.pmf");
console("[INFO] Preparing level \"".$this->level->getData("name")."\"");
$this->time = (int) $this->level->getData("time");
$this->seed = (int) $this->level->getData("seed");
$this->spawn = $this->level->getSpawn();
}
}
}

View File

@ -1,470 +0,0 @@
<?php
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
class PlayerAPI{
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 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 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;
}
public function teleport(&$name, &$target){
if(substr($target, 0, 2) === "w:"){
$lv = $this->server->api->level->get(substr($target, 2));
if($lv instanceof Level){
$origin = $this->get($name);
if($origin instanceof Player){
$name = $origin->username;
return $origin->teleport($lv->getSafeSpawn());
}
}else{
return false;
}
}
$player = $this->get($target);
if(($player instanceof Player) and ($player->entity instanceof Entity)){
$target = $player->username;
$origin = $this->get($name);
if($origin instanceof Player){
$name = $origin->username;
return $origin->teleport($player->entity);
}
}
return false;
}
public function tppos(&$name, &$x, &$y, &$z){
$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 get($name, $alike = true){
$name = trim(strtolower($name));
if($name === ""){
return false;
}
$CID = $this->server->query("SELECT ip,port FROM players WHERE name ".($alike === true ? "LIKE '%".$name."%'":"= '".$name."'").";", true);
$CID = PocketMinecraftServer::clientID($CID["ip"], $CID["port"]);
if(isset($this->server->clients[$CID])){
return $this->server->clients[$CID];
}
return false;
}
public function getAll($level = null){
if($level instanceof Level){
$clients = array();
$l = $this->server->query("SELECT EID FROM entities WHERE level = '".$level->getName()."' AND class = '".ENTITY_PLAYER."';");
if($l !== false and $l !== true){
while(($e = $l->fetchArray(SQLITE3_ASSOC)) !== false){
$e = $this->getByEID($e["EID"]);
if($e instanceof Player){
$clients[$e->CID] = $e;
}
}
}
return $clients;
}
return $this->server->clients;
}
public function broadcastPacket(array $players, $id, $data = array()){
$data = new CustomPacketHandler($id, "", $data, true);
$packet = array("raw" => chr($id).$data->raw);
foreach($players as $p){
$p->dataPacket(false, $packet);
}
}
public function getByEID($eid){
$eid = (int) $eid;
$CID = $this->server->query("SELECT ip,port FROM players WHERE EID = '".$eid."';", true);
$CID = PocketMinecraftServer::clientID($CID["ip"], $CID["port"]);
if(isset($this->server->clients[$CID])){
return $this->server->clients[$CID];
}
return false;
}
public function online(){
$o = array();
foreach($this->server->clients as $p){
if($p->auth === true){
$o[] = $p->username;
}
}
return $o;
}
public function add($CID){
if(isset($this->server->clients[$CID])){
$player = $this->server->clients[$CID];
$player->data = $this->getOffline($player->username);
$player->gamemode = $player->data->get("gamemode");
if(($player->level = $this->server->api->level->get($player->data->get("position")["level"])) === false){
$player->level = $this->server->api->level->getDefault();
$player->data->set("position", array(
"level" => $player->level->getName(),
"x" => $player->level->getSpawn()->x,
"y" => $player->level->getSpawn()->y,
"z" => $player->level->getSpawn()->z,
));
}
$this->server->query("INSERT OR REPLACE INTO players (CID, ip, port, name) VALUES (".$player->CID.", '".$player->ip."', ".$player->port.", '".strtolower($player->username)."');");
}
}
public function spawnAllPlayers(Player $player){
foreach($this->getAll() as $p){
if($p !== $player and ($p->entity instanceof Entity)){
$p->entity->spawn($player);
if($p->level !== $player->level){
$player->dataPacket(MC_MOVE_ENTITY_POSROT, array(
"eid" => $p->entity->eid,
"x" => -256,
"y" => 128,
"z" => -256,
"yaw" => 0,
"pitch" => 0,
));
}
}
}
}
public function spawnToAllPlayers(Player $player){
foreach($this->getAll() as $p){
if($p !== $player and ($p->entity instanceof Entity)){
$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,
);
if(!file_exists(DATA_PATH."players/".$iname.".yml")){
console("[NOTICE] Player data not found for \"".$iname."\", creating new profile");
$data = new Config(DATA_PATH."players/".$iname.".yml", CONFIG_YAML, $default);
$data->save();
}else{
$data = new Config(DATA_PATH."players/".$iname.".yml", CONFIG_YAML, $default);
}
if(($data->get("gamemode") & 0x01) === 1){
$data->set("health", 20);
}
$this->server->handle("player.offline.get", $data);
return $data;
}
public function saveOffline(Config $data){
$this->server->handle("player.offline.save", $data);
$data->save();
}
}

View File

@ -1,208 +0,0 @@
<?php
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
class PluginAPI extends stdClass{
private $server;
private $plugins = array();
public function __construct(){
$this->server = ServerAPI::request();
}
public function getList(){
$list = array();
foreach($this->plugins as $p){
$list[] = $p[1];
}
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 load($file){
if(strtolower(substr($file, -3)) === "pmf"){
$pmf = new PMFPlugin($file);
$info = $pmf->getPluginInfo();
}else{
$content = file_get_contents($file);
$info = strstr($content, "*/", true);
$content = str_repeat(PHP_EOL, substr_count($info, "\n")).substr(strstr($content, "*/"),2);
if(preg_match_all('#([a-zA-Z0-9\-_]*)=([^\r\n]*)#u', $info, $matches) == 0){ //false or 0 matches
console("[ERROR] Failed parsing of ".basename($file));
return false;
}
$info = array();
foreach($matches[1] as $k => $i){
$v = $matches[2][$k];
switch(strtolower($v)){
case "on":
case "true":
case "yes":
$v = true;
break;
case "off":
case "false":
case "no":
$v = false;
break;
}
$info[$i] = $v;
}
$info["code"] = $content;
$info["class"] = trim(strtolower($info["class"]));
}
if(!isset($info["name"]) or !isset($info["version"]) or !isset($info["class"]) or !isset($info["author"])){
console("[ERROR] Failed parsing of ".basename($file));
return false;
}
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");
return false;
}
$className = $info["class"];
$apiversion = array_map("intval", explode(",", (string) $info["apiversion"]));
if(!in_array((string) CURRENT_API_VERSION, $apiversion)){
console("[WARNING] Plugin \"".$info["name"]."\" may not be compatible with the API (".$info["apiversion"]." != ".CURRENT_API_VERSION.")! It can crash or corrupt the server!");
}
if($info["class"] !== "none"){
$object = new $className($this->server->api, false);
if(!($object instanceof Plugin)){
console("[ERROR] Plugin \"".$info["name"]."\" doesn't use the Plugin Interface");
if(method_exists($object, "__destruct")){
$object->__destruct();
}
$object = null;
unset($object);
}else{
$this->plugins[$className] = array($object, $info);
}
}else{
$this->plugins[md5($info["name"])] = array(new DummyPlugin($this->server->api, false), $info);
}
}
public function get(Plugin $plugin){
foreach($this->plugins as &$p){
if($p[0] === $plugin){
return $p;
}
}
return false;
}
public function configPath(Plugin $plugin){
$p = $this->get($plugin);
if($p === false){
return false;
}
$path = DATA_PATH."plugins/".$p[1]["name"]."/";
$this->plugins[$p[1]["class"]][1]["path"] = $path;
@mkdir($path);
return $path;
}
public function createConfig(Plugin $plugin, $default = array()){
$p = $this->get($plugin);
if($p === false){
return false;
}
$path = $this->configPath($plugin);
$cnf = new Config($path."config.yml", CONFIG_YAML, $default);
$cnf->save();
return $path;
}
private function fillDefaults($default, &$yaml){
foreach($default as $k => $v){
if(is_array($v)){
if(!isset($yaml[$k]) or !is_array($yaml[$k])){
$yaml[$k] = array();
}
$this->fillDefaults($v, $yaml[$k]);
}elseif(!isset($yaml[$k])){
$yaml[$k] = $v;
}
}
}
public function readYAML($file){
return Spyc::YAMLLoad(file_get_contents($file));
}
public function writeYAML($file, $data){
return file_put_contents($file, Spyc::YAMLDump($data));
}
public function init(){
$this->server->event("server.start", array($this, "initAll"));
$this->loadAll();
}
public function loadAll(){
$dir = dir(DATA_PATH."plugins/");
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);
}
}
}
}
public function initAll(){
console("[INFO] Starting plugins...");
foreach($this->plugins as $p){
$p[0]->init(); //ARGHHH!!! Plugin loading randomly fails!!
}
}
}
interface Plugin{
public function __construct(ServerAPI $api, $server = false);
public function init();
public function __destruct();
}
class DummyPlugin implements Plugin{
public function __construct(ServerAPI $api, $server = false){
}
public function init(){
}
public function __destruct(){
}
}

View File

@ -1,420 +0,0 @@
<?php
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
class ServerAPI{
public $restart = false;
private static $serverRequest = false;
private $asyncCalls = array();
private $server;
private $config;
private $apiList = array();
private $asyncCnt = 0;
private $rcon;
private $query;
public static function request(){
return self::$serverRequest;
}
public function start(){
return $this->run();
}
public function run(){
$this->load();
return $this->init();
}
public function load(){
@mkdir(DATA_PATH."players/", 0755);
@mkdir(DATA_PATH."worlds/", 0755);
@mkdir(DATA_PATH."plugins/", 0755);
$version = new VersionString();
console("[INFO] Starting Minecraft PE server version ".FORMAT_AQUA.CURRENT_MINECRAFT_VERSION);
console("[INFO] Loading properties...");
$this->config = new Config(DATA_PATH . "server.properties", CONFIG_PROPERTIES, array(
"server-name" => "Minecraft: PE Server",
"description" => "Server made using PocketMine-MP",
"motd" => "Welcome @player to this server!",
"server-ip" => "",
"server-port" => 19132,
"server-type" => "normal",
"memory-limit" => "128M",
"last-update" => false,
"white-list" => false,
"spawn-protection" => 16,
"view-distance" => 10,
"max-players" => 20,
"allow-flight" => false,
"spawn-animals" => true,
"spawn-mobs" => true,
"gamemode" => SURVIVAL,
"hardcore" => false,
"pvp" => true,
"difficulty" => 1,
"generator-settings" => "",
"level-name" => "world",
"level-seed" => "",
"level-type" => "DEFAULT",
"enable-query" => true,
"enable-rcon" => false,
"rcon.password" => substr(base64_encode(Utils::getRandomBytes(20, false)), 3, 10),
"send-usage" => true,
"auto-save" => true,
));
$this->parseProperties();
define("DEBUG", $this->getProperty("debug", 1));
if($this->getProperty("port") !== false){
$this->setProperty("server-port", $this->getProperty("port"));
$this->config->remove("port");
$this->config->remove("invisible");
}
$this->server = new PocketMinecraftServer($this->getProperty("server-name"), $this->getProperty("gamemode"), ($seed = $this->getProperty("level-seed")) != "" ? (int) $seed:false, $this->getProperty("server-port"), ($ip = $this->getProperty("server-ip")) != "" ? $ip:"0.0.0.0");
$this->server->api = $this;
self::$serverRequest = $this->server;
console("[INFO] This server is running PocketMine-MP version ".($version->isDev() ? FORMAT_YELLOW:"").MAJOR_VERSION.FORMAT_RESET." (MCPE: ".CURRENT_MINECRAFT_VERSION.") (API ".CURRENT_API_VERSION.")", true, true, 0);
console("[INFO] PocketMine-MP is distibuted under the LGPL License", true, true, 0);
if($this->getProperty("upnp-forwarding") === true){
console("[INFO] [UPnP] Trying to port forward...");
UPnP_PortForward($this->getProperty("server-port"));
}
if($this->getProperty("last-update") === false or ($this->getProperty("last-update") + 3600) < time()){
console("[INFO] Checking for new server version");
console("[INFO] Last check: ".FORMAT_AQUA.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);
if($this->server->version->isDev()){
if($info === false or !isset($info["development"])){
console("[ERROR] PocketMine 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] ".FORMAT_YELLOW."A new DEVELOPMENT version of PocketMine-MP has been released");
console("[NOTICE] ".FORMAT_YELLOW."Version \"".$info["development"]["version"]."\" [".substr($info["development"]["commit"], 0, 10)."]");
console("[NOTICE] ".FORMAT_YELLOW."Get it at PocketMine.net or ".$info["development"]["download"]);
console("[NOTICE] This message will dissapear after issuing the command \"/update-done\"");
}else{
$this->setProperty("last-update", time());
console("[INFO] ".FORMAT_AQUA."This is the latest DEVELOPMENT version");
}
}
}else{
if($info === false or !isset($info["stable"])){
console("[ERROR] PocketMine API error");
}else{
$newest = new VersionString(MAJOR_VERSION);
$newestN = $newest->getNumber();
$update = new VersionString($info["stable"]["version"]);
$updateN = $update->getNumber();
if($updateN > $newestN){
console("[NOTICE] ".FORMAT_GREEN."A new STABLE version of PocketMine-MP has been released");
console("[NOTICE] ".FORMAT_GREEN."Version \"".$info["stable"]["version"]."\" #".$updateN);
console("[NOTICE] Get it at PocketMine.net or ".$info["stable"]["download"]);
console("[NOTICE] This message will dissapear as soon as you update");
}else{
$this->setProperty("last-update", time());
console("[INFO] ".FORMAT_AQUA."This is the latest STABLE version");
}
}
}
}
$this->loadProperties();
$this->loadAPI("console", "ConsoleAPI");
$this->loadAPI("level", "LevelAPI");
$this->loadAPI("block", "BlockAPI");
$this->loadAPI("chat", "ChatAPI");
$this->loadAPI("ban", "BanAPI");
$this->loadAPI("entity", "EntityAPI");
$this->loadAPI("tile", "TileAPI");
$this->loadAPI("player", "PlayerAPI");
$this->loadAPI("time", "TimeAPI");
foreach($this->apiList as $ob){
if(is_callable(array($ob, "init"))){
$ob->init(); //Fails sometimes!!!
}
}
$this->loadAPI("plugin", "PluginAPI"); //fix :(
$this->plugin->init();
}
public function async(callable $callable, $params = array(), $remove = false){
$cnt = $this->asyncCnt++;
$this->asyncCalls[$cnt] = new Async($callable, $params);
return $remove === true ? $this->getAsync($cnt):$cnt;
}
public function getAsync($id){
if(!isset($this->asyncCalls[$id])){
return false;
}
$ob = $this->asyncCalls[$id];
unset($this->asyncCalls[$id]);
return $ob;
}
public function autoSave(){
console("[DEBUG] Saving....", true, true, 2);
$this->server->api->level->saveAll();
}
public function sendUsage(){
console("[DEBUG] Sending usage data...", true, true, 2);
$plist = "";
foreach($this->plugin->getList() as $p){
$plist .= str_replace(array(";", ":"), "", $p["name"]).":".str_replace(array(";", ":"), "", $p["version"]).";";
}
$this->asyncOperation(ASYNC_CURL_POST, array(
"url" => "http://stats.pocketmine.net/usage.php",
"data" => array(
"serverid" => $this->server->serverID,
"port" => $this->server->port,
"os" => Utils::getOS(),
"memory_total" => $this->getProperty("memory-limit"),
"memory_usage" => memory_get_usage(true),
"php_version" => PHP_VERSION,
"version" => MAJOR_VERSION,
"mc_version" => CURRENT_MINECRAFT_VERSION,
"protocol" => CURRENT_PROTOCOL,
"online" => count($this->server->clients),
"max" => $this->server->maxClients,
"plugins" => $plist,
),
), NULL);
}
public function __destruct(){
foreach($this->apiList as $i => $ob){
if(method_exists($ob, "__destruct")){
$ob->__destruct();
unset($this->apiList[$i]);
}
}
}
private function loadProperties(){
if(($memory = str_replace("B", "", strtoupper($this->getProperty("memory-limit")))) !== false){
$value = array("M" => 1, "G" => 1024);
$real = ((int) substr($memory, 0, -1)) * $value[substr($memory, -1)];
if($real < 128){
console("[WARNING] PocketMine-MP may not work right with less than 128MB of RAM", true, true, 0);
}
@ini_set("memory_limit", $memory);
}else{
$this->setProperty("memory-limit", "128M");
}
if($this->server instanceof PocketMinecraftServer){
$this->server->setType($this->getProperty("server-type"));
$this->server->maxClients = $this->getProperty("max-players");
$this->server->description = $this->getProperty("description");
$this->server->motd = $this->getProperty("motd");
$this->server->gamemode = $this->getProperty("gamemode");
$this->server->difficulty = $this->getProperty("difficulty");
$this->server->whitelist = $this->getProperty("white-list");
$this->server->reloadConfig();
}
}
private function writeProperties(){
$this->config->save();
}
private function parseProperties(){
foreach($this->config->getAll() as $n => $v){
switch($n){
case "last-update":
if($v === false){
$v = time();
}else{
$v = (int) $v;
}
break;
case "gamemode":
case "max-players":
case "server-port":
case "debug":
case "difficulty":
$v = (int) $v;
break;
case "server-id":
if($v !== false){
$v = preg_match("/[^0-9\-]/", $v) > 0 ? Utils::readInt(substr(md5($v, true), 0, 4)):$v;
}
break;
}
$this->config->set($n, $v);
}
if($this->getProperty("hardcore") == 1 and $this->getProperty("difficulty") < 3){
$this->setProperty("difficulty", 3);
}
}
public function init(){
if($this->getProperty("send-usage") !== false){
$this->server->schedule(6000, array($this, "sendUsage"), array(), true); //Send the info after 5 minutes have passed
$this->sendUsage();
}
if($this->getProperty("auto-save") === true){
$this->server->schedule(18000, array($this, "autoSave"), array(), true);
}
if(!defined("NO_THREADS") and $this->getProperty("enable-rcon") === true){
$this->rcon = new RCON($this->getProperty("rcon.password", ""), $this->getProperty("rcon.port", $this->getProperty("server-port")), ($ip = $this->getProperty("server-ip")) != "" ? $ip:"0.0.0.0", $this->getProperty("rcon.threads", 1), $this->getProperty("rcon.clients-per-thread", 50));
}
if($this->getProperty("enable-query") === true){
$this->query = new Query();
}
CraftingRecipes::init();
$this->server->init();
unregister_tick_function(array($this->server, "tick"));
$this->console->__destruct();
if($this->rcon instanceof RCON){
$this->rcon->stop();
}
$this->__destruct();
if($this->getProperty("upnp-forwarding") === true ){
console("[INFO] [UPnP] Removing port forward...");
UPnP_RemovePortForward($this->getProperty("server-port"));
}
return $this->restart;
}
/*-------------------------------------------------------------*/
public function asyncOperation($t, $d, $c = null){
return $this->server->asyncOperation($t, $d, $c);
}
public function addHandler($e, $c, $p = 5){
return $this->server->addHandler($e, $c, $p);
}
public function dhandle($e, $d){
return $this->server->handle($e, $d);
}
public function handle($e, &$d){
return $this->server->handle($e, $d);
}
public function schedule($t, $c, $d, $r = false, $e = "server.schedule"){
return $this->server->schedule($t, $c, $d, $r, $e);
}
public function event($e, $d){
return $this->server->event($e, $d);
}
public function trigger($e, $d){
return $this->server->trigger($e, $d);
}
public function deleteEvent($id){
return $this->server->deleteEvent($id);
}
public function getProperties(){
return $this->config->getAll();
}
public function getProperty($name, $default = false){
if(($v = arg($name)) !== false){ //Allow for command-line arguments
switch(strtolower(trim($v))){
case "on":
case "true":
case "yes":
$v = true;
break;
case "off":
case "false":
case "no":
$v = false;
break;
}
switch($name){
case "last-update":
if($v === false){
$v = time();
}else{
$v = (int) $v;
}
break;
case "gamemode":
case "max-players":
case "server-port":
case "debug":
case "difficulty":
case "time-per-second":
$v = (int) $v;
break;
case "server-id":
if($v !== false){
$v = preg_match("/[^0-9\-]/", $v) > 0 ? Utils::readInt(substr(md5($v, true), 0, 4)):$v;
}
break;
}
return $v;
}
return ($this->config->exists($name) ? $this->config->get($name):$default);
}
public function setProperty($name, $value){
$this->config->set($name, $value);
$this->writeProperties();
$this->loadProperties();
}
public function getList(){
return $this->apiList;
}
public function loadAPI($name, $class, $dir = false){
if(isset($this->$name)){
return false;
}elseif(!class_exists($class)){
$internal = false;
if($dir === false){
$internal = true;
$dir = FILE_PATH."src/API/";
}
$file = $dir.$class.".php";
if(!file_exists($file)){
console("[ERROR] API ".$name." [".$class."] in ".$dir." doesn't exist", true, true, 0);
return false;
}
require_once($file);
}else{
$internal = true;
}
$this->$name = new $class();
$this->apiList[] = $this->$name;
console("[".($internal === true ? "INTERNAL":"DEBUG")."] API \x1b[36m".$name."\x1b[0m [\x1b[30;1m".$class."\x1b[0m] loaded", true, true, ($internal === true ? 3:2));
}
}

View File

@ -1,116 +0,0 @@
<?php
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
class TileAPI{
private $server;
private $tiles;
private $tCnt = 1;
function __construct(){
$this->tiles = array();
$this->server = ServerAPI::request();
}
public function get(Position $pos){
$tile = $this->server->query("SELECT * FROM tiles WHERE level = '".$pos->level->getName()."' AND x = {$pos->x} AND y = {$pos->y} AND z = {$pos->z};", true);
if($tile !== false and $tile !== true and ($tile = $this->getByID($tile["ID"])) !== false){
return $tile;
}
return false;
}
public function getByID($id){
if($id instanceof Tile){
return $id;
}elseif(isset($this->tiles[$id])){
return $this->tiles[$id];
}
return false;
}
public function init(){
}
public function getAll($level = null){
if($level instanceof Level){
$tiles = array();
$l = $this->server->query("SELECT ID FROM tiles WHERE level = '".$level->getName()."';");
if($l !== false and $l !== true){
while(($t = $l->fetchArray(SQLITE3_ASSOC)) !== false){
$t = $this->getByID($t["ID"]);
if($t instanceof Tile){
$tiles[$t->id] = $t;
}
}
}
return $tiles;
}
return $this->tiles;
}
public function add(Level $level, $class, $x, $y, $z, $data = array()){
$id = $this->tCnt++;
$this->tiles[$id] = new Tile($level, $id, $class, $x, $y, $z, $data);
$this->spawnToAll($this->tiles[$id]);
return $this->tiles[$id];
}
public function addSign(Level $level, $x, $y, $z, $lines = array("", "", "", "")){
return $this->add($level, TILE_SIGN, $x, $y, $z, $data = array(
"id" => "Sign",
"x" => $x,
"y" => $y,
"z" => $z,
"Text1" => $lines[0],
"Text2" => $lines[1],
"Text3" => $lines[2],
"Text4" => $lines[3],
));
}
public function spawnToAll(Tile $t){
foreach($this->server->api->player->getAll($t->level) as $player){
if($player->eid !== false){
$t->spawn($player);
}
}
}
public function spawnAll(Player $player){
foreach($this->getAll($player->level) as $t){
$t->spawn($player);
}
}
public function remove($id){
if(isset($this->tiles[$id])){
$t = $this->tiles[$id];
$this->tiles[$id] = null;
unset($this->tiles[$id]);
$t->closed = true;
$t->close();
$this->server->query("DELETE FROM tiles WHERE ID = ".$id.";");
$this->server->api->dhandle("tile.remove", $t);
$t = null;
unset($t);
}
}
}

1063
src/EntityOLD.php Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,134 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
*
*
*/
namespace pocketmine;
use pocketmine\utils\TextFormat;
/**
* Handles the achievement list and a bit more
*/
abstract class Achievement{
/**
* @var array[]
*/
public static $list = 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",
),
),
);
public static function broadcast(Player $player, $achievementId){
if(isset(Achievement::$list[$achievementId])){
if(Server::getInstance()->getConfigString("announce-player-achievements", true) === true){
Server::getInstance()->broadcastMessage($player->getDisplayName() . " has just earned the achievement " . TextFormat::GREEN . Achievement::$list[$achievementId]["name"]);
}else{
$player->sendMessage("You have just earned the achievement " . TextFormat::GREEN . Achievement::$list[$achievementId]["name"]);
}
return true;
}
return false;
}
public static function add($achievementId, $achievementName, array $requires = array()){
if(!isset(Achievement::$list[$achievementId])){
Achievement::$list[$achievementId] = array(
"name" => $achievementName,
"requires" => $requires,
);
return true;
}
return false;
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,145 +19,187 @@
*
*/
namespace pocketmine;
use pocketmine\level\Level;
use pocketmine\math\Vector2;
use pocketmine\utils\Config;
class BanAPI{
private $server;
/*
* I would use PHPDoc Template here but PHPStorm does not recognise it. - @sekjun9878
*/
/** @var Config */
private $whitelist;
/** @var Config */
private $banned;
/** @var Config */
private $ops;
/** @var Config */
private $bannedIPs;
private $cmdWL = array();//Command WhiteList
private $cmdWhitelist = array(); //Command WhiteList
function __construct(){
$this->server = ServerAPI::request();
$this->server = Server::getInstance();
}
public function init(){
$this->whitelist = new Config(DATA_PATH."white-list.txt", CONFIG_LIST);//Open whitelist list file
$this->bannedIPs = new Config(DATA_PATH."banned-ips.txt", CONFIG_LIST);//Open Banned IPs list file
$this->banned = new Config(DATA_PATH."banned.txt", CONFIG_LIST);//Open Banned Usernames list file
$this->ops = new Config(DATA_PATH."ops.txt", CONFIG_LIST);//Open list of OPs
$this->whitelist = new Config(\pocketmine\DATA . "white-list.txt", Config::ENUM); //Open whitelist list file
$this->bannedIPs = new Config(\pocketmine\DATA . "banned-ips.txt", Config::ENUM); //Open Banned IPs list file
$this->banned = new Config(\pocketmine\DATA . "banned.txt", Config::ENUM); //Open Banned Usernames list file
$this->ops = new Config(\pocketmine\DATA . "ops.txt", Config::ENUM); //Open list of OPs
$this->server->api->console->register("banip", "<add|remove|list|reload> [IP|player]", array($this, "commandHandler"));
$this->server->api->console->register("ban", "<add|remove|list|reload> [username]", array($this, "commandHandler"));
$this->server->api->console->register("kick", "<player> [reason ...]", array($this, "commandHandler"));
$this->server->api->console->register("whitelist", "<on|off|list|add|remove|reload> [username]", array($this, "commandHandler"));
$this->server->api->console->register("op", "<player>", array($this, "commandHandler"));
$this->server->api->console->register("deop", "<player>", array($this, "commandHandler"));
$this->server->api->console->register("sudo", "<player>", array($this, "commandHandler"));
$this->server->api->console->register("sudo", "<player> <command>", array($this, "commandHandler"));
$this->server->api->console->alias("ban-ip", "banip add");
$this->server->api->console->alias("banlist", "ban list");
$this->server->api->console->alias("pardon", "ban remove");
$this->server->api->console->alias("pardon-ip", "banip remove");
$this->server->addHandler("console.command", array($this, "permissionsCheck"), 1);//Event handler when commands are issued. Used to check permissions of commands that go through the server.
$this->server->addHandler("player.block.break", array($this, "permissionsCheck"), 1);//Event handler for blocks
$this->server->addHandler("player.block.place", array($this, "permissionsCheck"), 1);//Event handler for blocks
$this->server->addHandler("player.flying", array($this, "permissionsCheck"), 1);//Flying Event
$this->server->addHandler("console.command", array($this, "permissionsCheck"), 1); //Event handler when commands are issued. Used to check permissions of commands that go through the server.
$this->server->addHandler("player.block.break", array($this, "permissionsCheck"), 1); //Event handler for blocks
$this->server->addHandler("player.block.place", array($this, "permissionsCheck"), 1); //Event handler for blocks
$this->server->addHandler("player.flying", array($this, "permissionsCheck"), 1); //Flying Event
}
public function cmdWhitelist($cmd){//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;
}elseif($this->ops->exists($username)){
return true;
}
return false;
return false;
}
/**
* @param mixed $data
* @param string $event
*
* @return boolean
*/
public function permissionsCheck($data, $event){
switch($event){
case "player.flying"://OPs can fly around the server.
if($this->isOp($data->iusername)){
case "player.flying": //OPs can fly around the server.
if($this->isOp($data->getName())){
return true;
}
break;
case "player.block.break":
case "player.block.place"://Spawn protection detection. Allows OPs to place/break blocks in the spawn area.
if(!$this->isOp($data["player"]->iusername)){
case "player.block.place": //Spawn protection detection. Allows OPs to place/break blocks in the spawn area.
if(!$this->isOp($data["player"]->getName())){
$t = new Vector2($data["target"]->x, $data["target"]->z);
$s = new Vector2($this->server->spawn->x, $this->server->spawn->z);
if($t->distance($s) <= $this->server->api->getProperty("spawn-protection") and $this->server->api->dhandle($event.".spawn", $data) !== true){
$s = new Vector2(Level::getDefault()->getSpawn()->x, Level::getDefault()->getSpawn()->z);
if($t->distance($s) <= $this->server->api->getProperty("spawn-protection") and $this->server->api->dhandle($event . ".spawn", $data) !== true){
return false;
}
}
return;
break;
case "console.command"://Checks if a command is allowed with the current user permissions.
case "console.command": //Checks if a command is allowed with the current user permissions.
if(isset($this->cmdWhitelist[$data["cmd"]])){
return;
}
if($data["issuer"] instanceof Player){
if($this->server->api->handle("console.check", $data) === true or $this->isOp($data["issuer"]->iusername)){
if($this->server->api->handle("console.check", $data) === true or $this->isOp($data["issuer"]->getName())){
return;
}
}elseif($data["issuer"] === "console" or $data["issuer"] === "rcon"){
return;
}
return false;
break;
}
}
/**
* @param string $cmd
* @param array $params
* @param string $issuer
* @param string $alias
*
* @return string
*/
public function commandHandler($cmd, $params, $issuer, $alias){
$output = "";
switch($cmd){
case "sudo":
$target = strtolower(array_shift($params));
$player = $this->server->api->player->get($target);
$player = Player::get($target);
if(!($player instanceof Player)){
$output .= "Player not connected.\n";
break;
}
$this->server->api->console->run(implode(" ", $params), $player);
$output .= "Command ran as ".$player->username.".\n";
$output .= "Command ran as " . $player->getName() . ".\n";
break;
case "op":
$user = strtolower($params[0]);
$player = $this->server->api->player->get($user);
if(!($player instanceof Player)){
$this->ops->set($user);
$this->ops->save($user);
$output .= $user." is now op\n";
if($user == null){
$output .= "Usage: /op <player>\n";
break;
}
$this->ops->set($player->iusername);
$player = Player::get($user);
if(!($player instanceof Player)){
$this->ops->set($user);
$this->ops->save();
$output .= $user . " is now op\n";
break;
}
$this->ops->set(strtolower($player->getName()));
$this->ops->save();
$output .= $player->iusername." is now op\n";
$this->server->api->chat->sendTo(false, "You are now op.", $player->iusername);
$output .= $player->getName() . " is now op\n";
$player->sendMessage("You are now op.");
break;
case "deop":
$user = strtolower($params[0]);
$player = $this->server->api->player->get($user);
$player = Player::get($user);
if(!($player instanceof Player)){
$this->ops->set($user, false);
$this->ops->save($user);
$output .= $user." is no longer op\n";
$this->ops->remove($user);
$this->ops->save();
$output .= $user . " is no longer op\n";
break;
}
$this->ops->remove($player->iusername);
$this->ops->remove(strtolower($player->getName()));
$this->ops->save();
$output .= $player->iusername." is not longer op\n";
$this->server->api->chat->sendTo(false, "You are no longer op.", $player->iusername);
$output .= $player->getName() . " is no longer op\n";
$player->sendMessage("You are no longer op.");
break;
case "kick":
if(!isset($params[0])){
$output .= "Usage: /kick <player> [reason ...]\n";
}else{
$name = strtolower(array_shift($params));
$player = $this->server->api->player->get($name);
$player = Player::get($name);
if($player === false){
$output .= "Player \"".$name."\" does not exist\n";
$output .= "Player \"" . $name . "\" does not exist\n";
}else{
$reason = implode(" ", $params);
$reason = $reason == "" ? "No reason":$reason;
$player->close("You have been kicked: ".$reason);
$reason = $reason == "" ? "No reason" : $reason;
$this->server->schedule(60, array($player, "close"), "You have been kicked: " . $reason); //Forces a kick
$player->blocked = true;
if($issuer instanceof Player){
$this->server->api->chat->broadcast($player->username." has been kicked by ".$issuer->username.": $reason\n");
Player::broadcastMessage($player->getName() . " has been kicked by " . $issuer->getName() . ": $reason\n");
}else{
$this->server->api->chat->broadcast($player->username." has been kicked: $reason\n");
Player::broadcastMessage($player->getName() . " has been kicked: $reason\n");
}
}
}
@ -178,10 +220,10 @@ class BanAPI{
$output .= "Player \"$user\" added to white-list\n";
break;
case "reload":
$this->whitelist = new Config(DATA_PATH."white-list.txt", CONFIG_LIST);
$this->whitelist = new Config(\pocketmine\DATA . "white-list.txt", Config::ENUM);
break;
case "list":
$output .= "White-list: ".implode(", ", $this->whitelist->getAll(true))."\n";
$output .= "White-list: " . implode(", ", $this->whitelist->getAll(true)) . "\n";
break;
case "on":
case "true":
@ -213,20 +255,20 @@ class BanAPI{
case "add":
case "ban":
$ip = strtolower($params[0]);
$player = $this->server->api->player->get($ip);
$player = Player::get($ip);
if($player instanceof Player){
$ip = $player->ip;
$player->close("banned");
$ip = $player->getIP();
$player->kick("You are banned");
}
$this->bannedIPs->set($ip);
$this->bannedIPs->save();
$output .= "IP \"$ip\" added to ban list\n";
break;
case "reload":
$this->bannedIPs = new Config(DATA_PATH."banned-ips.txt", CONFIG_LIST);
$this->bannedIPs = new Config(\pocketmine\DATA . "banned-ips.txt", Config::ENUM);
break;
case "list":
$output .= "IP ban list: ".implode(", ", $this->bannedIPs->getAll(true))."\n";
$output .= "IP ban list: " . implode(", ", $this->bannedIPs->getAll(true)) . "\n";
break;
default:
$output .= "Usage: /banip <add|remove|list|reload> [IP|player]\n";
@ -248,23 +290,23 @@ class BanAPI{
$user = strtolower($params[0]);
$this->banned->set($user);
$this->banned->save();
$player = $this->server->api->player->get($user);
$player = Player::get($user);
if($player !== false){
$player->close("You have been banned");
$player->kick("You are banned");
}
if($issuer instanceof Player){
$this->server->api->chat->broadcast($user." has been banned by ".$issuer->username."\n");
Player::broadcastMessage($user . " has been banned by " . $issuer->getName() . "\n");
}else{
$this->server->api->chat->broadcast($user." has been banned\n");
Player::broadcastMessage($user . " has been banned\n");
}
$this->kick($user, "Banned");
$output .= "Player \"$user\" added to ban list\n";
break;
case "reload":
$this->banned = new Config(DATA_PATH."banned.txt", CONFIG_LIST);
$this->banned = new Config(\pocketmine\DATA . "banned.txt", Config::ENUM);
break;
case "list":
$output .= "Ban list: ".implode(", ", $this->banned->getAll(true))."\n";
$output .= "Ban list: " . implode(", ", $this->banned->getAll(true)) . "\n";
break;
default:
$output .= "Usage: /ban <add|remove|list|reload> [username]\n";
@ -272,63 +314,98 @@ class BanAPI{
}
break;
}
return $output;
}
/**
* @param string $username
*/
public function ban($username){
$this->commandHandler("ban", array("add", $username), "console", "");
}
/**
* @param string $username
*/
public function pardon($username){
$this->commandHandler("ban", array("pardon", $username), "console", "");
}
/**
* @param string $ip
*/
public function banIP($ip){
$this->commandHandler("banip", array("add", $ip), "console", "");
}
/**
* @param string $ip
*/
public function pardonIP($ip){
$this->commandHandler("banip", array("pardon", $ip), "console", "");
}
/**
* @param string $username
* @param string $reason
*/
public function kick($username, $reason = "No Reason"){
$this->commandHandler("kick", array($username, $reason), "console", "");
}
public function reload(){
$this->commandHandler("ban", array("reload"), "console", "");
$this->commandHandler("banip", array("reload"), "console", "");
$this->commandHandler("whitelist", array("reload"), "console", "");
}
/**
* @param string $ip
*
* @return boolean
*/
public function isIPBanned($ip){
if($this->server->api->dhandle("api.ban.ip.check", $ip) === false){
return true;
}elseif($this->bannedIPs->exists($ip)){
}elseif($this->bannedIPs->exists($ip, true)){
return true;
}else{
return false;
}
return false;
}
/**
* @param string $username
*
* @return boolean
*/
public function isBanned($username){
$username = strtolower($username);
if($this->server->api->dhandle("api.ban.check", $username) === false){
return true;
}elseif($this->banned->exists($username)){
}elseif($this->banned->exists($username, true)){
return true;
}else{
return false;
}
return false;
}
/**
* @param string $username
*
* @return boolean
*/
public function inWhitelist($username){
$username = strtolower($username);
if($this->isOp($username)){
return true;
}elseif($this->server->api->dhandle("api.ban.whitelist.check", $username) === false){
return true;
}elseif($this->whitelist->exists($username)){
}elseif($this->whitelist->exists($username, true)){
return true;
}
return false;
return false;
}
}

352
src/PocketMine/BlockAPI.php Normal file
View File

@ -0,0 +1,352 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine;
use pocketmine\Block;
use pocketmine\item\Item;
use pocketmine\level\Level;
use pocketmine\level\Position;
class BlockAPI{
private $server;
private $scheduledUpdates = array();
public static $creative = array(
//Building
[Item::STONE, 0],
[Item::COBBLESTONE, 0],
[Item::STONE_BRICKS, 0],
[Item::STONE_BRICKS, 1],
[Item::STONE_BRICKS, 2],
[Item::MOSS_STONE, 0],
[Item::WOODEN_PLANKS, 0],
[Item::WOODEN_PLANKS, 1],
[Item::WOODEN_PLANKS, 2],
[Item::WOODEN_PLANKS, 3],
[Item::BRICKS, 0],
[Item::DIRT, 0],
[Item::GRASS, 0],
[Item::CLAY_BLOCK, 0],
[Item::SANDSTONE, 0],
[Item::SANDSTONE, 1],
[Item::SANDSTONE, 2],
[Item::SAND, 0],
[Item::GRAVEL, 0],
[Item::TRUNK, 0],
[Item::TRUNK, 1],
[Item::TRUNK, 2],
[Item::TRUNK, 3],
[Item::NETHER_BRICKS, 0],
[Item::NETHERRACK, 0],
[Item::BEDROCK, 0],
[Item::COBBLESTONE_STAIRS, 0],
[Item::OAK_WOODEN_STAIRS, 0],
[Item::SPRUCE_WOODEN_STAIRS, 0],
[Item::BIRCH_WOODEN_STAIRS, 0],
[Item::JUNGLE_WOODEN_STAIRS, 0],
[Item::BRICK_STAIRS, 0],
[Item::SANDSTONE_STAIRS, 0],
[Item::STONE_BRICK_STAIRS, 0],
[Item::NETHER_BRICKS_STAIRS, 0],
[Item::QUARTZ_STAIRS, 0],
[Item::SLAB, 0],
[Item::SLAB, 1],
[Item::WOODEN_SLAB, 0],
[Item::WOODEN_SLAB, 1],
[Item::WOODEN_SLAB, 2],
[Item::WOODEN_SLAB, 3],
[Item::SLAB, 3],
[Item::SLAB, 4],
[Item::SLAB, 5],
[Item::SLAB, 6],
[Item::QUARTZ_BLOCK, 0],
[Item::QUARTZ_BLOCK, 1],
[Item::QUARTZ_BLOCK, 2],
[Item::COAL_ORE, 0],
[Item::IRON_ORE, 0],
[Item::GOLD_ORE, 0],
[Item::DIAMOND_ORE, 0],
[Item::LAPIS_ORE, 0],
[Item::REDSTONE_ORE, 0],
[Item::OBSIDIAN, 0],
[Item::ICE, 0],
[Item::SNOW_BLOCK, 0],
//Decoration
[Item::COBBLESTONE_WALL, 0],
[Item::COBBLESTONE_WALL, 1],
[Item::GOLD_BLOCK, 0],
[Item::IRON_BLOCK, 0],
[Item::DIAMOND_BLOCK, 0],
[Item::LAPIS_BLOCK, 0],
[Item::COAL_BLOCK, 0],
[Item::SNOW_LAYER, 0],
[Item::GLASS, 0],
[Item::GLOWSTONE_BLOCK, 0],
[Item::NETHER_REACTOR, 0],
[Item::WOOL, 0],
[Item::WOOL, 7],
[Item::WOOL, 6],
[Item::WOOL, 5],
[Item::WOOL, 4],
[Item::WOOL, 3],
[Item::WOOL, 2],
[Item::WOOL, 1],
[Item::WOOL, 15],
[Item::WOOL, 14],
[Item::WOOL, 13],
[Item::WOOL, 12],
[Item::WOOL, 11],
[Item::WOOL, 10],
[Item::WOOL, 9],
[Item::WOOL, 8],
[Item::LADDER, 0],
[Item::SPONGE, 0],
[Item::GLASS_PANE, 0],
[Item::WOODEN_DOOR, 0],
[Item::TRAPDOOR, 0],
[Item::FENCE, 0],
[Item::FENCE_GATE, 0],
[Item::IRON_BARS, 0],
[Item::BED, 0],
[Item::BOOKSHELF, 0],
[Item::PAINTING, 0],
[Item::WORKBENCH, 0],
[Item::STONECUTTER, 0],
[Item::CHEST, 0],
[Item::FURNACE, 0],
[Item::DANDELION, 0],
[Item::CYAN_FLOWER, 0],
[Item::BROWN_MUSHROOM, 0],
[Item::RED_MUSHROOM, 0],
[Item::CACTUS, 0],
[Item::MELON_BLOCK, 0],
[Item::PUMPKIN, 0],
[Item::LIT_PUMPKIN, 0],
[Item::COBWEB, 0],
[Item::HAY_BALE, 0],
[Item::TALL_GRASS, 1],
[Item::TALL_GRASS, 2],
[Item::DEAD_BUSH, 0],
[Item::SAPLING, 0],
[Item::SAPLING, 1],
[Item::SAPLING, 2],
[Item::SAPLING, 3],
[Item::LEAVES, 0],
[Item::LEAVES, 1],
[Item::LEAVES, 2],
[Item::LEAVES, 3],
[Item::CAKE, 0],
[Item::SIGN, 0],
[Item::CARPET, 0],
[Item::CARPET, 7],
[Item::CARPET, 6],
[Item::CARPET, 5],
[Item::CARPET, 4],
[Item::CARPET, 3],
[Item::CARPET, 2],
[Item::CARPET, 1],
[Item::CARPET, 15],
[Item::CARPET, 14],
[Item::CARPET, 13],
[Item::CARPET, 12],
[Item::CARPET, 11],
[Item::CARPET, 10],
[Item::CARPET, 9],
[Item::CARPET, 8],
//Tools
//[Item::RAILS, 0],
//[Item::POWERED_RAILS, 0],
[Item::TORCH, 0],
[Item::BUCKET, 0],
[Item::BUCKET, 8],
[Item::BUCKET, 10],
[Item::TNT, 0],
[Item::IRON_HOE, 0],
[Item::IRON_SWORD, 0],
[Item::BOW, 0],
[Item::SHEARS, 0],
[Item::FLINT_AND_STEEL, 0],
[Item::CLOCK, 0],
[Item::COMPASS, 0],
[Item::MINECART, 0],
[Item::SPAWN_EGG, 10], //Chicken
[Item::SPAWN_EGG, 11], //Cow
[Item::SPAWN_EGG, 12], //Pig
[Item::SPAWN_EGG, 13], //Sheep
//TODO: Replace with Entity constants
//Seeds
[Item::SUGARCANE, 0],
[Item::WHEAT, 0],
[Item::SEEDS, 0],
[Item::MELON_SEEDS, 0],
[Item::PUMPKIN_SEEDS, 0],
[Item::CARROT, 0],
[Item::POTATO, 0],
[Item::BEETROOT_SEEDS, 0],
[Item::EGG, 0],
[Item::DYE, 0],
[Item::DYE, 7],
[Item::DYE, 6],
[Item::DYE, 5],
[Item::DYE, 4],
[Item::DYE, 3],
[Item::DYE, 2],
[Item::DYE, 1],
[Item::DYE, 15],
[Item::DYE, 14],
[Item::DYE, 13],
[Item::DYE, 12],
[Item::DYE, 11],
[Item::DYE, 10],
[Item::DYE, 9],
[Item::DYE, 8],
);
function __construct(){
$this->server = Server::getInstance();
}
public function init(){
$this->server->schedule(1, array($this, "blockUpdateTick"), array(), true);
$this->server->api->console->register("give", "<player> <item[:damage]> [amount]", array($this, "commandHandler"));
}
public function commandHandler($cmd, $params, $issuer, $alias){
$output = "";
switch($cmd){
case "give":
if(!isset($params[0]) or !isset($params[1])){
$output .= "Usage: /give <player> <item[:damage]> [amount]\n";
break;
}
$player = Player::get($params[0]);
$item = Item::fromString($params[1]);
if(!isset($params[2])){
$item->setCount($item->getMaxStackSize());
}else{
$item->setCount((int) $params[2]);
}
if($player instanceof Player){
if(($player->gamemode & 0x01) === 0x01){
$output .= "Player is in creative mode.\n";
break;
}
if($item->getID() == 0){
$output .= "You cannot give an air block to a player.\n";
break;
}
$player->addItem(clone $item);
$output .= "Giving " . $item->getCount() . " of " . $item->getName() . " (" . $item->getID() . ":" . $item->getMetadata() . ") to " . $player->getName() . "\n";
}else{
$output .= "Unknown player.\n";
}
break;
}
return $output;
}
public function blockUpdateAround(Position $pos, $type = Level::BLOCK_UPDATE_NORMAL, $delay = false){
if($delay !== false){
$this->scheduleBlockUpdate($pos->getSide(0), $delay, $type);
$this->scheduleBlockUpdate($pos->getSide(1), $delay, $type);
$this->scheduleBlockUpdate($pos->getSide(2), $delay, $type);
$this->scheduleBlockUpdate($pos->getSide(3), $delay, $type);
$this->scheduleBlockUpdate($pos->getSide(4), $delay, $type);
$this->scheduleBlockUpdate($pos->getSide(5), $delay, $type);
}else{
$this->blockUpdate($pos->getSide(0), $type);
$this->blockUpdate($pos->getSide(1), $type);
$this->blockUpdate($pos->getSide(2), $type);
$this->blockUpdate($pos->getSide(3), $type);
$this->blockUpdate($pos->getSide(4), $type);
$this->blockUpdate($pos->getSide(5), $type);
}
}
public function blockUpdate(Position $pos, $type = Level::BLOCK_UPDATE_NORMAL){
if(!($pos instanceof block\Block)){
$block = $pos->level->getBlock($pos);
}else{
$pos = new Position($pos->x, $pos->y, $pos->z, $pos->level);
$block = $pos->level->getBlock($pos);
}
if($block === false){
return false;
}
$level = $block->onUpdate($type);
if($level === Level::BLOCK_UPDATE_NORMAL){
$this->blockUpdateAround($block, $level);
}
return $level;
}
public function scheduleBlockUpdate(Position $pos, $delay, $type = Level::BLOCK_UPDATE_SCHEDULED){
$type = (int) $type;
if($delay < 0){
return false;
}
$index = $pos->x . "." . $pos->y . "." . $pos->z . "." . $pos->level->getName() . "." . $type;
$delay = microtime(true) + $delay * 0.05;
if(!isset($this->scheduledUpdates[$index])){
$this->scheduledUpdates[$index] = $pos;
$this->server->query("INSERT INTO blockUpdates (x, y, z, level, type, delay) VALUES (" . $pos->x . ", " . $pos->y . ", " . $pos->z . ", '" . $pos->level->getName() . "', " . $type . ", " . $delay . ");");
return true;
}
return false;
}
public function blockUpdateTick(){
$time = microtime(true);
if(count($this->scheduledUpdates) > 0){
$update = $this->server->query("SELECT x,y,z,level,type FROM blockUpdates WHERE delay <= " . $time . ";");
if($update instanceof \SQLite3Result){
$upp = array();
while(($up = $update->fetchArray(SQLITE3_ASSOC)) !== false){
$index = $up["x"] . "." . $up["y"] . "." . $up["z"] . "." . $up["level"] . "." . $up["type"];
if(isset($this->scheduledUpdates[$index])){
$upp[] = array((int) $up["type"], $this->scheduledUpdates[$index]);
unset($this->scheduledUpdates[$index]);
}
}
$this->server->query("DELETE FROM blockUpdates WHERE delay <= " . $time . ";");
foreach($upp as $b){
$this->blockUpdate($b[1], $b[0]);
}
}
}
}
}

View File

@ -0,0 +1,66 @@
<?php
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine;
use pocketmine\level\Level;
class LevelAPI{
private $server;
public function __construct(){
$this->server = Server::getInstance();
}
public function init(){
$this->server->api->console->register("save-all", "", array($this, "commandHandler"));
$this->server->api->console->register("save-on", "", array($this, "commandHandler"));
$this->server->api->console->register("save-off", "", array($this, "commandHandler"));
}
public function commandHandler($cmd, $params, $issuer, $alias){
$output = "";
switch($cmd){
case "save-all":
$save = $this->server->saveEnabled;
$this->server->saveEnabled = true;
Level::saveAll();
$this->server->saveEnabled = $save;
break;
case "save-on":
$this->server->saveEnabled = true;
break;
case "save-off":
$this->server->saveEnabled = false;
break;
}
return $output;
}
public function __destruct(){
Level::saveAll();
foreach(Level::getAll() as $level){
$level->unload(true);
}
}
}

2736
src/PocketMine/Player.php Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,345 @@
<?php
/**
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine;
use pocketmine\entity\Entity;
use pocketmine\level\Level;
use pocketmine\level\Position;
use pocketmine\math\Vector3 as Vector3;
class PlayerAPI{
private $server;
function __construct(){
$this->server = Server::getInstance();
}
public function init(){
$this->server->schedule(20 * 15, array($this, "handle"), 1, true, "server.regeneration");
$this->server->addHandler("player.death", array($this, "handle"), 1);
$this->server->api->console->register("list", "", array($this, "commandHandler"));
$this->server->api->console->register("kill", "<player>", array($this, "commandHandler"));
$this->server->api->console->register("gamemode", "<mode> [player]", array($this, "commandHandler"));
$this->server->api->console->register("tp", "[target player] <destination player | w:world> OR /tp [target player] <x> <y> <z>", array($this, "commandHandler"));
$this->server->api->console->register("spawnpoint", "[player | w:world] [x] [y] [z]", array($this, "commandHandler"));
$this->server->api->console->register("spawn", "", array($this, "commandHandler"));
$this->server->api->console->register("ping", "", array($this, "commandHandler"));
$this->server->api->console->alias("lag", "ping");
$this->server->api->console->alias("suicide", "kill");
$this->server->api->console->alias("tppos", "tp");
$this->server->api->ban->cmdWhitelist("list");
$this->server->api->ban->cmdWhitelist("ping");
$this->server->api->ban->cmdWhitelist("spawn");
}
public function handle($data, $event){
switch($event){
case "server.regeneration":
/*if($this->server->difficulty === 0){
$result = $this->server->preparedSQL->selectPlayersToHeal->execute();
if($result !== false){
while(($player = $result->fetchArray()) !== false){
if(($player = Entity::get($player["EID"])) !== false){
if($player->getHealth() <= 0){
continue;
}
$player->setHealth(min(20, $player->getHealth() + $data), "regeneration");
}
}
return true;
}
}*/
break;
case "player.death":
if(is_numeric($data["cause"])){
$e = Entity::get($data["cause"]);
if($e instanceof Entity){
switch($e->class){
case ENTITY_PLAYER:
$message = " was killed by " . $e->name;
break;
default:
$message = " was killed";
break;
}
}
}else{
switch($data["cause"]){
case "cactus":
$message = " was pricked to death";
break;
case "lava":
$message = " tried to swim in lava";
break;
case "fire":
$message = " went up in flames";
break;
case "burning":
$message = " burned to death";
break;
case "suffocation":
$message = " suffocated in a wall";
break;
case "water":
$message = " drowned";
break;
case "void":
$message = " fell out of the world";
break;
case "fall":
$message = " hit the ground too hard";
break;
case "explosion":
$message = " blew up";
break;
default:
$message = " died";
break;
}
}
Player::broadcastMessage($data["player"]->getName() . $message);
return true;
}
return;
}
public function commandHandler($cmd, $params, $issuer, $alias){
$output = "";
switch($cmd){
case "spawnpoint":
if(count($params) === 0){
$output .= "Usage: /$cmd [player | w:world] [x] [y] [z]\n";
break;
}
if(!($issuer instanceof Player) and count($params) < 4){
$output .= "Please run this command in-game.\n";
break;
}
if(count($params) === 1 or count($params) === 4){
$tg = array_shift($params);
if(count($params) === 3 and substr($tg, 0, 2) === "w:"){
$target = Level::get(substr($tg, 2));
}else{
$target = Player::get($tg);
}
}else{
$target = $issuer;
}
if(!($target instanceof Player) and !($target instanceof Level)){
$output .= "That player cannot be found.\n";
break;
}
if(count($params) === 3){
if($target instanceof Level){
$spawn = new Vector3(floatval(array_shift($params)), floatval(array_shift($params)), floatval(array_shift($params)));
}else{
$spawn = new Position(floatval(array_shift($params)), floatval(array_shift($params)), floatval(array_shift($params)), $issuer->level);
}
}else{
$spawn = new Position($issuer->entity->x, $issuer->entity->y, $issuer->entity->z, $issuer->entity->level);
}
$target->setSpawn($spawn);
if($target instanceof Level){
$output .= "Spawnpoint of world " . $target->getName() . " set correctly!\n";
}elseif($target !== $issuer){
$output .= "Spawnpoint of " . $target->getName() . " set correctly!\n";
}else{
$output .= "Spawnpoint set correctly!\n";
}
break;
case "spawn":
if(!($issuer instanceof Player)){
$output .= "Please run this command in-game.\n";
break;
}
$issuer->teleport(Level::getDefault()->getSafeSpawn());
break;
case "ping":
if(!($issuer instanceof Player)){
$output .= "Please run this command in-game.\n";
break;
}
$output .= "ping " . round($issuer->getLag(), 2) . "ms, packet loss " . round($issuer->getPacketLoss() * 100, 2) . "%, " . round($issuer->getBandwidth() / 1024, 2) . " KB/s\n";
break;
case "gamemode":
$player = false;
$setgm = false;
$gms = array(
"0" => 0,
"survival" => 0,
"s" => 0,
"1" => 1,
"creative" => 1,
"c" => 1,
"2" => 2,
"adventure" => 2,
"a" => 2,
"3" => 3,
"view" => 3,
"viewer" => 3,
"spectator" => 3,
"v" => 3,
);
if(isset($params[1])){
if(Player::get($params[1]) instanceof Player){
$player = Player::get($params[1]);
$setgm = $params[0];
}elseif(Player::get($params[0]) instanceof Player){
$player = Player::get($params[0]);
$setgm = $params[1];
}else{
$output .= "Usage: /$cmd <mode> [player] or /$cmd [player] <mode>\n";
break;
}
}elseif(isset($params[0])){
if(!(Player::get($params[0]) instanceof Player)){
if($issuer instanceof Player){
$setgm = $params[0];
$player = $issuer;
}
}
}
if(!($player instanceof Player) or !isset($gms[strtolower($setgm)])){
$output .= "Usage: /$cmd <mode> [player] or /$cmd [player] <mode>\n";
break;
}
if($player->setGamemode($gms[strtolower($setgm)])){
$output .= "Gamemode of " . $player->getName() . " changed to " . $player->getGamemode() . "\n";
}
break;
case "tp":
if(count($params) <= 2 or substr($params[0], 0, 2) === "w:" or substr($params[1], 0, 2) === "w:"){
if((!isset($params[1]) or substr($params[0], 0, 2) === "w:") and isset($params[0]) and ($issuer instanceof Player)){
$name = $issuer->getName();
$target = implode(" ", $params);
}elseif(isset($params[1]) and isset($params[0])){
$name = array_shift($params);
$target = implode(" ", $params);
}else{
$output .= "Usage: /$cmd [target player] <destination player | w:world>\n";
break;
}
if($this->teleport($name, $target) !== false){
$output .= "\"$name\" teleported to \"$target\"\n";
}else{
$output .= "Couldn't teleport.\n";
}
}else{
if(!isset($params[3]) and isset($params[2]) and isset($params[1]) and isset($params[0]) and ($issuer instanceof Player)){
$name = $issuer->getName();
$x = $params[0];
$y = $params[1];
$z = $params[2];
}elseif(isset($params[3]) and isset($params[2]) and isset($params[1]) and isset($params[0])){
$name = $params[0];
$x = $params[1];
$y = $params[2];
$z = $params[3];
}else{
$output .= "Usage: /$cmd [player] <x> <y> <z>\n";
break;
}
if($this->tppos($name, $x, $y, $z)){
$output .= "\"$name\" teleported to ($x, $y, $z)\n";
}else{
$output .= "Couldn't teleport.\n";
}
}
break;
case "kill":
case "suicide":
if(!isset($params[0]) and ($issuer instanceof Player)){
$player = $issuer;
}else{
$player = Player::get($params[0]);
}
if($player instanceof Player){
$player->harm(1000, "console", true);
$player->sendMessage("Ouch. That looks like it hurt.\n");
}else{
$output .= "Usage: /$cmd [player]\n";
}
break;
case "list":
$output .= "There are " . count(Player::$list) . "/" . $this->server->maxClients . " players online:\n";
if(count(Player::$list) == 0){
break;
}
foreach(Player::$list as $c){
$output .= $c->getName() . ", ";
}
$output = substr($output, 0, -2) . "\n";
break;
}
return $output;
}
public function teleport(&$name, &$target){
if(substr($target, 0, 2) === "w:"){
$lv = Level::get(substr($target, 2));
if($lv instanceof Level){
$origin = Player::get($name);
if($origin instanceof Player){
$name = $origin->getName();
return $origin->teleport($lv->getSafeSpawn());
}
}else{
return false;
}
}
$player = Player::get($target);
if($player instanceof Player and $player->spawned === true){
$target = $player->getName();
$origin = Player::get($name);
if($origin instanceof Player){
$name = $origin->getName();
return $origin->teleport($player->entity);
}
}
return false;
}
public function tppos(&$name, &$x, &$y, &$z){
$player = Player::get($name);
if($player instanceof Player and $player->spawned === true){
$name = $player->getName();
$x = $x{0} === "~" ? $player->x + floatval(substr($x, 1)) : floatval($x);
$y = $y{0} === "~" ? $player->y + floatval(substr($y, 1)) : floatval($y);
$z = $z{0} === "~" ? $player->z + floatval(substr($z, 1)) : floatval($z);
$player->teleport(new Vector3($x, $y, $z));
return true;
}
return false;
}
}

View File

@ -0,0 +1,369 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
*
*
*/
namespace {
/**
* Output text to the console, can contain Minecraft-formatted text.
*
* @param string $message
* @param bool $EOL
* @param bool $log
* @param int $level
*/
function console($message, $EOL = true, $log = true, $level = 1){
pocketmine\console($message, $EOL, $log, $level);
}
function safe_var_dump(){
static $cnt = 0;
foreach(func_get_args() as $var){
switch(true){
case is_array($var):
echo str_repeat(" ", $cnt) . "array(" . count($var) . ") {" . PHP_EOL;
foreach($var as $key => $value){
echo str_repeat(" ", $cnt + 1) . "[" . (is_integer($key) ? $key : '"' . $key . '"') . "]=>" . PHP_EOL;
++$cnt;
safe_var_dump($value);
--$cnt;
}
echo str_repeat(" ", $cnt) . "}" . PHP_EOL;
break;
case is_integer($var):
echo str_repeat(" ", $cnt) . "int(" . $var . ")" . PHP_EOL;
break;
case is_float($var):
echo str_repeat(" ", $cnt) . "float(" . $var . ")" . PHP_EOL;
break;
case is_bool($var):
echo str_repeat(" ", $cnt) . "bool(" . ($var === true ? "true" : "false") . ")" . PHP_EOL;
break;
case is_string($var):
echo str_repeat(" ", $cnt) . "string(" . strlen($var) . ") \"$var\"" . PHP_EOL;
break;
case is_resource($var):
echo str_repeat(" ", $cnt) . "resource() of type (" . get_resource_type($var) . ")" . PHP_EOL;
break;
case is_object($var):
echo str_repeat(" ", $cnt) . "object(" . get_class($var) . ")" . PHP_EOL;
break;
case is_null($var):
echo str_repeat(" ", $cnt) . "NULL" . PHP_EOL;
break;
}
}
}
function dummy(){
}
}
namespace pocketmine {
use pocketmine\utils\TextFormat;
use pocketmine\utils\Utils;
use pocketmine\wizard\Installer;
const VERSION = "Alpha_1.4dev";
const API_VERSION = "1.0.0";
const CODENAME = "絶好(Zekkou)ケーキ(Cake)";
const MINECRAFT_VERSION = "v0.8.1 alpha";
const PHP_VERSION = "5.5";
@define("pocketmine\\PATH", \getcwd() . DIRECTORY_SEPARATOR);
if(!class_exists("SplClassLoader", false)){
require_once(\pocketmine\PATH . "src/spl/SplClassLoader.php");
}
$autoloader = new \SplClassLoader();
$autoloader->add("pocketmine", array(
\pocketmine\PATH . "src"
));
$autoloader->register(true);
//Startup code. Do not look at it, it can harm you. Most of them are hacks to fix date-related bugs, or basic functions used after this
set_time_limit(0); //Who set it to 30 seconds?!?!
if(ini_get("date.timezone") == ""){ //No Timezone set
date_default_timezone_set("GMT");
if(strpos(" " . strtoupper(php_uname("s")), " WIN") !== false){
$time = time();
$time -= $time % 60;
//TODO: Parse different time & date formats by region. ¬¬ world
//Example: USA
exec("time.exe /T", $hour);
$i = array_map("intval", explode(":", trim($hour[0])));
exec("date.exe /T", $date);
$j = array_map("intval", explode(substr($date[0], 2, 1), trim($date[0])));
$offset = round((mktime($i[0], $i[1], 0, $j[1], $j[0], $j[2]) - $time) / 60) * 60;
}else{
exec("date +%s", $t);
$offset = round((intval(trim($t[0])) - time()) / 60) * 60;
}
$daylight = (int) date("I");
$d = timezone_name_from_abbr("", $offset, $daylight);
@ini_set("date.timezone", $d);
date_default_timezone_set($d);
}else{
$d = @date_default_timezone_get();
if(strpos($d, "/") === false){
$d = timezone_name_from_abbr($d);
@ini_set("date.timezone", $d);
date_default_timezone_set($d);
}
}
gc_enable();
error_reporting(E_ALL | E_STRICT);
ini_set("allow_url_fopen", 1);
ini_set("display_errors", 1);
ini_set("display_startup_errors", 1);
ini_set("default_charset", "utf-8");
ini_set("memory_limit", "128M"); //Default
define("pocketmine\\START_TIME", microtime(true));
$opts = getopt("", array("enable-ansi", "disable-ansi", "data:", "plugins:", "no-wizard"));
define("pocketmine\\DATA", isset($opts["data"]) ? realpath($opts["data"]) . DIRECTORY_SEPARATOR : \getcwd() . DIRECTORY_SEPARATOR);
define("pocketmine\\PLUGIN_PATH", isset($opts["plugins"]) ? realpath($opts["plugins"]) . DIRECTORY_SEPARATOR : \getcwd() . DIRECTORY_SEPARATOR . "plugins" . DIRECTORY_SEPARATOR);
if((strpos(strtoupper(php_uname("s")), "WIN") === false or isset($opts["enable-ansi"])) and !isset($opts["disable-ansi"])){
define("pocketmine\\ANSI", true);
}else{
define("pocketmine\\ANSI", false);
}
function kill($pid){
switch(Utils::getOS()){
case "win":
exec("taskkill.exe /F /PID " . ((int) $pid) . " > NUL");
break;
case "mac":
case "linux":
default:
exec("kill -9 " . ((int) $pid) . " > /dev/null 2>&1");
}
}
/**
* Output text to the console, can contain Minecraft-formatted text.
*
* @param $message
* @param bool $EOL
* @param bool $log
* @param int $level
*/
function console($message, $EOL = true, $log = true, $level = 1){
if(!defined("pocketmine\\DEBUG") or \pocketmine\DEBUG >= $level){
$message .= $EOL === true ? PHP_EOL : "";
if($message{0} !== "["){
$message = "[INFO] $message";
}
$time = (\pocketmine\ANSI === true ? TextFormat::AQUA . date("H:i:s") . TextFormat::RESET : date("H:i:s")) . " ";
$replaced = TextFormat::clean(preg_replace('/\x1b\[[0-9;]*m/', "", $time . $message));
if($log === true and (!defined("LOG") or LOG === true)){
log(date("Y-m-d") . " " . $replaced, "server", false, $level);
}
if(\pocketmine\ANSI === true){
$add = "";
if(preg_match("/^\\[([a-zA-Z0-9]*)\\]/", $message, $matches) > 0){
switch($matches[1]){
case "ERROR":
case "SEVERE":
$add .= TextFormat::RED;
break;
case "TRACE":
case "INTERNAL":
case "DEBUG":
$add .= TextFormat::GRAY;
break;
case "WARNING":
$add .= TextFormat::YELLOW;
break;
case "NOTICE":
$add .= TextFormat::AQUA;
break;
default:
$add = "";
break;
}
}
$message = TextFormat::toANSI($time . $add . $message . TextFormat::RESET);
}else{
$message = $replaced;
}
echo $message;
}
}
function getTrace($start = 1){
$e = new \Exception();
$trace = $e->getTrace();
$messages = array();
$j = 0;
for($i = (int) $start; isset($trace[$i]); ++$i, ++$j){
$params = "";
if(isset($trace[$i]["args"])){
foreach($trace[$i]["args"] as $name => $value){
$params .= (is_object($value) ? get_class($value) . " " . (method_exists($value, "__toString") ? $value->__toString() : "object") : gettype($value) . " " . @strval($value)) . ", ";
}
}
$messages[] = "#$j " . (isset($trace[$i]["file"]) ? $trace[$i]["file"] : "") . "(" . (isset($trace[$i]["line"]) ? $trace[$i]["line"] : "") . "): " . (isset($trace[$i]["class"]) ? $trace[$i]["class"] . $trace[$i]["type"] : "") . $trace[$i]["function"] . "(" . substr($params, 0, -2) . ")";
}
return $messages;
}
function error_handler($errno, $errstr, $errfile, $errline){
if(error_reporting() === 0){ //@ error-control
return false;
}
$errorConversion = array(
E_ERROR => "E_ERROR",
E_WARNING => "E_WARNING",
E_PARSE => "E_PARSE",
E_NOTICE => "E_NOTICE",
E_CORE_ERROR => "E_CORE_ERROR",
E_CORE_WARNING => "E_CORE_WARNING",
E_COMPILE_ERROR => "E_COMPILE_ERROR",
E_COMPILE_WARNING => "E_COMPILE_WARNING",
E_USER_ERROR => "E_USER_ERROR",
E_USER_WARNING => "E_USER_WARNING",
E_USER_NOTICE => "E_USER_NOTICE",
E_STRICT => "E_STRICT",
E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR",
E_DEPRECATED => "E_DEPRECATED",
E_USER_DEPRECATED => "E_USER_DEPRECATED",
);
$type = ($errno === E_ERROR or $errno === E_WARNING or $errno === E_USER_ERROR or $errno === E_USER_WARNING) ? "ERROR" : "NOTICE";
$errno = isset($errorConversion[$errno]) ? $errorConversion[$errno] : $errno;
console("[$type] A $errno error happened: \"$errstr\" in \"$errfile\" at line $errline", true, true, 0);
foreach(getTrace() as $i => $line){
console("[TRACE] $line");
}
return true;
}
function log($message, $name, $EOL = true, $level = 2, $close = false){
global $fpointers;
if((!defined("pocketmine\\DEBUG") or \pocketmine\DEBUG >= $level) and (!defined("pocketmine\\LOG") or \pocketmine\LOG === true)){
$message .= $EOL === true ? PHP_EOL : "";
if(!isset($fpointers)){
$fpointers = array();
}
if(!isset($fpointers[$name]) or $fpointers[$name] === false){
$fpointers[$name] = @fopen(\pocketmine\DATA . "/" . $name . ".log", "ab");
}
@fwrite($fpointers[$name], $message);
if($close === true){
fclose($fpointers[$name]);
unset($fpointers[$name]);
}
}
}
set_error_handler("\\pocketmine\\error_handler", E_ALL);
$errors = 0;
if(version_compare("5.4.0", PHP_VERSION) > 0){
console("[ERROR] Use PHP >= 5.4.0", true, true, 0);
++$errors;
}
if(php_sapi_name() !== "cli"){
console("[ERROR] You must run PocketMine-MP using the CLI.", true, true, 0);
++$errors;
}
if(!extension_loaded("sockets")){
console("[ERROR] Unable to find the Socket extension.", true, true, 0);
++$errors;
}
if(!extension_loaded("pthreads")){
console("[ERROR] Unable to find the pthreads extension.", true, true, 0);
++$errors;
}else{
$pthreads_version = phpversion("pthreads");
if(substr_count($pthreads_version, ".") < 2){
$pthreads_version = "0.$pthreads_version";
}
if(version_compare($pthreads_version, "2.0.4") < 0){
console("[ERROR] pthreads >= 2.0.4 is required, while you have $pthreads_version.", true, true, 0);
++$errors;
}
}
if(!extension_loaded("curl")){
console("[ERROR] Unable to find the cURL extension.", true, true, 0);
++$errors;
}
if(!extension_loaded("sqlite3")){
console("[ERROR] Unable to find the SQLite3 extension.", true, true, 0);
++$errors;
}
if(!extension_loaded("yaml")){
console("[ERROR] Unable to find the YAML extension.", true, true, 0);
++$errors;
}
if(!extension_loaded("zlib")){
console("[ERROR] Unable to find the Zlib extension.", true, true, 0);
++$errors;
}
if($errors > 0){
console("[ERROR] Please use the installer provided on the homepage, or recompile PHP again.", true, true, 0);
exit(1); //Exit with error
}
if(file_exists(\pocketmine\PATH . ".git/refs/heads/master")){ //Found Git information!
define("pocketmine\\GIT_COMMIT", strtolower(trim(file_get_contents(\pocketmine\PATH . ".git/refs/heads/master"))));
}else{ //Unknown :(
define("pocketmine\\GIT_COMMIT", str_repeat("00", 20));
}
@ini_set("opcache.mmap_base", bin2hex(Utils::getRandomBytes(8, false))); //Fix OPCache address errors
if(!file_exists(\pocketmine\DATA . "server.properties") and !isset($opts["no-wizard"])){
new Installer();
}
if(substr(__FILE__, 0, 7) !== "phar"){
console("[WARNING] Non-packaged PocketMine-MP installation detected, do not use on production.");
}
$server = new Server($autoloader, \pocketmine\PATH, \pocketmine\DATA, \pocketmine\PLUGIN_PATH);
$server->start();
kill(getmypid());
exit(0);
}

1113
src/PocketMine/Server.php Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,363 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine;
use pocketmine\network\query\QueryHandler;
use pocketmine\network\rcon\RCON;
use pocketmine\network\upnp\UPnP;
use pocketmine\plugin\PluginManager;
use pocketmine\utils\Config;
use pocketmine\utils\TextFormat;
use pocketmine\utils\Utils;
use pocketmine\utils\VersionString;
class ServerAPI{
public $restart = false;
private static $serverRequest = false;
private $asyncCalls = array();
private $server;
private $config;
private $apiList = array();
private $asyncCnt = 0;
private $rcon;
public $query;
//TODO: Instead of hard-coding functions, use PHPDoc-compatible methods to load APIs.
/** @var ConsoleAPI */
public $console;
/** @var LevelAPI */
public $level;
/** @var BlockAPI */
public $block;
/** @var ChatAPI */
public $chat;
/** @var BanAPI */
public $ban;
/** @var TimeAPI */
public $time;
/** @var PlayerAPI */
public $player;
/**
* @return Server
*/
public static function request(){
return self::$serverRequest;
}
public function start(){
return $this->run();
}
public function run(){
$this->load();
return $this->init();
}
public function load(){
@mkdir(\pocketmine\DATA . "players/", 0755);
@mkdir(\pocketmine\DATA . "worlds/", 0755);
@mkdir(\pocketmine\DATA . "plugins/", 0755);
$version = new VersionString();
console("[INFO] Starting Minecraft: PE server version " . TextFormat::AQUA . MINECRAFT_VERSION);
console("[INFO] Loading properties...");
$this->config = new Config(\pocketmine\DATA . "server.properties", Config::PROPERTIES, array(
"server-name" => "Minecraft: PE Server",
"description" => "Server made using PocketMine-MP",
"motd" => "Welcome @player to this server!",
"server-port" => 19132,
"server-type" => "normal",
"memory-limit" => "128M",
"last-update" => false,
"white-list" => false,
"announce-player-achievements" => true,
"spawn-protection" => 16,
"view-distance" => 8,
"max-players" => 20,
"allow-flight" => false,
"spawn-animals" => true,
"spawn-mobs" => true,
"gamemode" => 0,
"hardcore" => false,
"pvp" => true,
"difficulty" => 1,
"generator-settings" => "",
"level-name" => "world",
"level-seed" => "",
"level-type" => "DEFAULT",
"enable-query" => true,
"enable-rcon" => false,
"rcon.password" => substr(base64_encode(Utils::getRandomBytes(20, false)), 3, 10),
"auto-save" => true,
));
$this->parseProperties();
//Load advanced properties
define("pocketmine\\DEBUG", $this->getProperty("debug", 1));
define("ADVANCED_CACHE", $this->getProperty("enable-advanced-cache", false));
define("MAX_CHUNK_RATE", 20 / $this->getProperty("max-chunks-per-second", 7)); //Default rate ~448 kB/s
if(ADVANCED_CACHE == true){
console("[INFO] Advanced cache enabled");
}
if($this->getProperty("upnp-forwarding") == true){
console("[INFO] [UPnP] Trying to port forward...");
UPnP::PortForward($this->getProperty("server-port"));
}
$this->server = new Server($this->getProperty("server-name"), $this->getProperty("gamemode"), ($seed = $this->getProperty("level-seed")) != "" ? (int) $seed : false, $this->getProperty("server-port"), ($ip = $this->getProperty("server-ip")) != "" ? $ip : "0.0.0.0");
$this->server->api = $this;
self::$serverRequest = $this->server;
console("[INFO] This server is running PocketMine-MP version " . ($version->isDev() ? TextFormat::YELLOW : "") . VERSION . TextFormat::RESET . " \"" . CODENAME . "\" (API " . API_VERSION . ")", true, true, 0);
console("[INFO] PocketMine-MP is distributed under the LGPL License", true, true, 0);
if($this->getProperty("last-update") === false or ($this->getProperty("last-update") + 3600) < time()){
console("[INFO] Checking for new server version");
console("[INFO] Last check: " . TextFormat::AQUA . date("Y-m-d H:i:s", $this->getProperty("last-update")) . "\x1b[0m");
if($this->server->version->isDev()){
$info = json_decode(Utils::getURL("https://api.github.com/repos/PocketMine/PocketMine-MP/commits"), true);
if($info === false or !isset($info[0])){
console("[ERROR] Github API error");
}else{
$last = new \DateTime($info[0]["commit"]["committer"]["date"]);
$last = $last->getTimestamp();
if($last >= $this->getProperty("last-update") and $this->getProperty("last-update") !== false and \pocketmine\GIT_COMMIT != $info[0]["sha"]){
console("[NOTICE] " . TextFormat::YELLOW . "A new DEVELOPMENT version of PocketMine-MP has been released!");
console("[NOTICE] " . TextFormat::YELLOW . "Commit \"" . $info[0]["commit"]["message"] . "\" [" . substr($info[0]["sha"], 0, 10) . "] by " . $info[0]["commit"]["committer"]["name"]);
console("[NOTICE] " . TextFormat::YELLOW . "Get it at PocketMine.net or at https://github.com/PocketMine/PocketMine-MP/archive/" . $info[0]["sha"] . ".zip");
console("[NOTICE] This message will disappear after issuing the command \"/update-done\"");
}else{
$this->setProperty("last-update", time());
console("[INFO] " . TextFormat::AQUA . "This is the latest DEVELOPMENT version");
}
}
}else{
$info = json_decode(Utils::getURL("https://api.github.com/repos/PocketMine/PocketMine-MP/tags"), true);
if($info === false or !isset($info[0])){
console("[ERROR] Github API error");
}else{
$newest = new VersionString(VERSION);
$newestN = $newest->getNumber();
$update = new VersionString($info[0]["name"]);
$updateN = $update->getNumber();
if($updateN > $newestN){
console("[NOTICE] " . TextFormat::GREEN . "A new STABLE version of PocketMine-MP has been released!");
console("[NOTICE] " . TextFormat::GREEN . "Version \"" . $info[0]["name"] . "\" #" . $updateN);
console("[NOTICE] Get it at PocketMine.net or at " . $info[0]["zipball_url"]);
console("[NOTICE] This message will disappear as soon as you update");
}else{
$this->setProperty("last-update", time());
console("[INFO] " . TextFormat::AQUA . "This is the latest STABLE version");
}
}
}
}
$this->loadProperties();
$this->apiList[] = $this->console = new ConsoleAPI();
$this->apiList[] = $this->level = new LevelAPI();
$this->apiList[] = $this->block = new BlockAPI();
$this->apiList[] = $this->chat = new ChatAPI();
$this->apiList[] = $this->ban = new BanAPI();
$this->apiList[] = $this->player = new PlayerAPI();
$this->apiList[] = $this->time = new TimeAPI();
foreach($this->apiList as $ob){
if(is_callable(array($ob, "init"))){
$ob->init(); //Fails sometimes!!!
}
}
console("[INFO] Loaded " . count(PluginManager::loadPlugins(\pocketmine\DATA . "plugins/")) . " plugin(s).");
}
public function async(callable $callable, $params = array(), $remove = false){
$cnt = $this->asyncCnt++;
$this->asyncCalls[$cnt] = new \Async($callable, $params);
return $remove === true ? $this->getAsync($cnt) : $cnt;
}
public function getAsync($id){
if(!isset($this->asyncCalls[$id])){
return false;
}
$ob = $this->asyncCalls[$id];
unset($this->asyncCalls[$id]);
return $ob;
}
public function __destruct(){
foreach($this->apiList as $i => $ob){
if(method_exists($ob, "__destruct")){
$ob->__destruct();
unset($this->apiList[$i]);
}
}
}
private function writeProperties(){
$this->config->save();
}
public function init(){
if(!(self::$serverRequest instanceof Server)){
self::$serverRequest = $this->server;
}
if($this->getProperty("send-usage", true) !== false){
$this->server->schedule(6000, array($this, "sendUsage"), array(), true); //Send the info after 5 minutes have passed
$this->sendUsage();
}
if($this->getProperty("auto-save") === true){
$this->server->schedule(18000, array($this, "autoSave"), array(), true);
}
if(!defined("NO_THREADS") and $this->getProperty("enable-rcon") === true){
$this->rcon = new RCON($this->getProperty("rcon.password", ""), $this->getProperty("rcon.port", $this->getProperty("server-port")), ($ip = $this->getProperty("server-ip")) != "" ? $ip : "0.0.0.0", $this->getProperty("rcon.threads", 1), $this->getProperty("rcon.clients-per-thread", 50));
}
if($this->getProperty("enable-query") === true){
$this->query = new QueryHandler();
}
$this->schedule(2, array($this, "checkTickUpdates"), array(), true);
$this->server->init();
unregister_tick_function(array($this->server, "tick"));
$this->console->__destruct();
if($this->rcon instanceof RCON){
$this->rcon->stop();
}
$this->__destruct();
if($this->getProperty("upnp-forwarding") === true){
console("[INFO] [UPnP] Removing port forward...");
UPnP::RemovePortForward($this->getProperty("server-port"));
}
return $this->restart;
}
/*-------------------------------------------------------------*/
public function asyncOperation($t, $d, $c = null){
return $this->server->asyncOperation($t, $d, $c);
}
public function addHandler($e, $c, $p = 5){
return $this->server->addHandler($e, $c, $p);
}
public function dhandle($e, $d){
return $this->server->handle($e, $d);
}
public function handle($e, &$d){
return $this->server->handle($e, $d);
}
public function schedule($t, $c, $d, $r = false, $e = "server.schedule"){
return $this->server->schedule($t, $c, $d, $r, $e);
}
public function event($e, $d){
return $this->server->event($e, $d);
}
public function trigger($e, $d){
return $this->server->trigger($e, $d);
}
public function deleteEvent($id){
return $this->server->deleteEvent($id);
}
public function getProperties(){
return $this->config->getAll();
}
public function getProperty($name, $default = false){
$v = getopt("", array("$name::"));
if(isset($v[$name]) !== false){ //Allow for command-line arguments
$v = $v[$name];
switch(strtolower(trim($v))){
case "":
case "on":
case "true":
case "yes":
$v = true;
break;
case "off":
case "false":
case "no":
$v = false;
break;
}
switch($name){
case "last-update":
if($v === false){
$v = time();
}else{
$v = (int) $v;
}
break;
case "gamemode":
case "max-players":
case "server-port":
case "debug":
case "difficulty":
$v = (int) $v;
break;
}
return $v;
}
return ($this->config->exists($name) ? $this->config->get($name) : $default);
}
public function setProperty($name, $value, $save = true){
$this->config->set($name, $value);
if($save == true){
$this->writeProperties();
}
$this->loadProperties();
}
public function getList(){
return $this->apiList;
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,20 +19,87 @@
*
*/
class PocketMinecraftServer{
/**
* PocketMine-MP is the Minecraft: PE multiplayer server software
* Homepage: http://www.pocketmine.net/
*/
namespace pocketmine;
use pocketmine\entity\Entity;
use pocketmine\network\Packet;
use pocketmine\network\protocol\Info;
use pocketmine\network\raknet\Info as RakNetInfo;
use pocketmine\network\raknet\Packet as RakNetPacket;
use pocketmine\plugin\PluginManager;
use pocketmine\utils\Utils;
use pocketmine\utils\VersionString;
class ServerOld{
/** @var Server */
private static $instance;
public $tCnt;
public $serverID, $interface, $database, $version, $invisible, $api, $tickMeasure, $preparedSQL, $seed, $gamemode, $name, $maxClients, $clients, $eidCnt, $custom, $description, $motd, $port, $saveEnabled;
private $serverip, $evCnt, $handCnt, $events, $eventsID, $handlers, $serverType, $lastTick, $ticks, $memoryStats, $async = array(), $asyncID = 0;
public $serverID;
public $interface;
public $database;
public $version;
public $invisible;
public $tickMeasure;
public $preparedSQL;
public $spawn;
public $whitelist;
public $seed;
public $stop;
public $gamemode;
public $difficulty;
public $name;
public $maxClients;
public $eidCnt;
public $custom;
public $description;
public $motd;
public $port;
public $saveEnabled;
private $rcon;
private $query;
private $serverip;
private $evCnt;
private $handCnt;
private $events;
private $eventsID;
private $handlers;
private $serverType;
private $lastTick;
private $doTick;
private $ticks;
private $memoryStats;
private $schedule;
private $asyncThread;
private $async = array();
private $asyncID = 0;
/**
* @return Server
*/
public static function getInstance(){
if(isset(self::$instance)){
return self::$instance;
}
return null;
}
private function load(){
$this->version = new VersionString();
/*if(defined("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);
if(defined("pocketmine\\DEBUG") and \pocketmine\DEBUG >= 0 and function_exists("cli_set_process_title")){
@cli_set_process_title("PocketMine-MP " . \pocketmine\VERSION);
}
console("[INFO] Starting Minecraft PE server on " . ($this->serverip === "0.0.0.0" ? "*" : $this->serverip) . ":" . $this->port);
define("BOOTUP_RANDOM", Utils::getRandomBytes(16));
$this->serverID = $this->serverID === false ? Utils::readLong(Utils::getRandomBytes(8, false)):$this->serverID;
$this->seed = $this->seed === false ? Utils::readInt(Utils::getRandomBytes(4, false)):$this->seed;
$this->serverID = $this->serverID === false ? Utils::readLong(substr(Utils::getUniqueID(true, $this->serverip . $this->port), 8)) : $this->serverID;
$this->seed = $this->seed === false ? Utils::readInt(Utils::getRandomBytes(4, false)) : $this->seed;
$this->startDatabase();
$this->api = false;
$this->tCnt = 1;
@ -40,10 +107,7 @@ class PocketMinecraftServer{
$this->eventsID = array();
$this->handlers = array();
$this->invisible = false;
$this->levelData = false;
$this->difficulty = 1;
$this->tiles = array();
$this->entities = array();
$this->custom = array();
$this->evCnt = 1;
$this->handCnt = 1;
@ -52,66 +116,70 @@ class PocketMinecraftServer{
$this->schedule = array();
$this->scheduleCnt = 1;
$this->description = "";
$this->whitelist = false;
$this->memoryStats = array();
$this->clients = array();
$this->spawn = false;
$this->saveEnabled = true;
$this->whitelist = false;
$this->tickMeasure = array_fill(0, 40, 0);
$this->setType("normal");
$this->interface = new MinecraftInterface($this, "255.255.255.255", $this->port, true, false, $this->serverip);
$this->reloadConfig();
$this->interface = new Handler("255.255.255.255", $this->port, $this->serverip);
$this->stop = false;
$this->ticks = 0;
if(!defined("NO_THREADS")){
$this->asyncThread = new AsyncMultipleQueue();
$this->asyncThread = new \AsyncMultipleQueue();
}
}
function __construct($name, $gamemode = SURVIVAL, $seed = false, $port = 19132, $serverip = "0.0.0.0"){
function __construct($name, $gamemode = 0, $seed = false, $port = 19132, $serverip = "0.0.0.0"){
$this->port = (int) $port;
$this->doTick = true;
$this->gamemode = (int) $gamemode;
$this->name = $name;
$this->motd = "Welcome to ".$name;
$this->motd = "Welcome to " . $name;
$this->serverID = false;
$this->seed = $seed;
$this->serverip = $serverip;
self::$instance = $this;
$this->load();
}
/**
* @return float
*/
public function getTPS(){
$v = array_values($this->tickMeasure);
$tps = 40 / ($v[39] - $v[0]);
return round($tps, 4);
}
public function titleTick(){
$time = microtime(true);
if(defined("DEBUG") and DEBUG >= 0 and ENABLE_ANSI === true){
echo "\x1b]0;PocketMine-MP ".MAJOR_VERSION." | Online ". count($this->clients)."/".$this->maxClients." | RAM ".round((memory_get_usage() / 1024) / 1024, 2)."MB | U ".round(($this->interface->bandwidth[1] / max(1, $time - $this->interface->bandwidth[2])) / 1024, 2)." D ".round(($this->interface->bandwidth[0] / max(1, $time - $this->interface->bandwidth[2])) / 1024, 2)." kB/s | TPS ".$this->getTPS()."\x07";
if(defined("pocketmine\\DEBUG") and \pocketmine\DEBUG >= 0 and \pocketmine\ANSI === true){
echo "\x1b]0;PocketMine-MP " . VERSION . " | Online " . count(Player::$list) . "/" . $this->maxClients . " | RAM " . round((memory_get_usage() / 1024) / 1024, 2) . "MB | U " . round(($this->interface->bandwidth[1] / max(1, $time - $this->interface->bandwidth[2])) / 1024, 2) . " D " . round(($this->interface->bandwidth[0] / max(1, $time - $this->interface->bandwidth[2])) / 1024, 2) . " kB/s | TPS " . $this->getTPS() . "\x07";
}
$this->interface->bandwidth = array(0, 0, $time);
}
public function loadEvents(){
if(ENABLE_ANSI === true){
if(\pocketmine\ANSI === true){
$this->schedule(30, array($this, "titleTick"), array(), true);
}
$this->schedule(20 * 15, array($this, "checkTicks"), array(), true);
$this->schedule(20 * 60, array($this, "checkMemory"), array(), true);
$this->schedule(20 * 45, "pocketmine\\utils\\Cache::cleanup", array(), true);
$this->schedule(20, array($this, "asyncOperationChecker"), array(), true);
}
public function checkTicks(){
if($this->getTPS() < 12){
console("[WARNING] Can't keep up! Is the server overloaded?");
}
}
public function checkMemory(){
$info = $this->debugInfo();
$data = $info["memory_usage"].",".$info["players"].",".$info["entities"];
$data = $info["memory_usage"] . "," . $info["players"] . "," . $info["entities"];
$i = count($this->memoryStats) - 1;
if($i < 0 or $this->memoryStats[$i] !== $data){
$this->memoryStats[] = $data;
@ -119,15 +187,12 @@ class PocketMinecraftServer{
}
public function startDatabase(){
$this->preparedSQL = new stdClass();
$this->preparedSQL->entity = new stdClass();
$this->database = new SQLite3(":memory:");
$this->preparedSQL = new \stdClass();
$this->preparedSQL->entity = new \stdClass();
$this->database = new \SQLite3(":memory:", SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE);
$this->query("PRAGMA journal_mode = OFF;");
$this->query("PRAGMA encoding = \"UTF-8\";");
$this->query("PRAGMA secure_delete = OFF;");
$this->query("CREATE TABLE players (CID INTEGER PRIMARY KEY, EID NUMERIC, ip TEXT, port NUMERIC, name TEXT UNIQUE COLLATE NOCASE);");
$this->query("CREATE TABLE entities (EID INTEGER PRIMARY KEY, level TEXT, type NUMERIC, class NUMERIC, hasUpdate NUMERIC, name TEXT, x NUMERIC, y NUMERIC, z NUMERIC, yaw NUMERIC, pitch NUMERIC, health NUMERIC);");
$this->query("CREATE TABLE tiles (ID INTEGER PRIMARY KEY, level TEXT, class TEXT, x NUMERIC, y NUMERIC, z NUMERIC, spawnable NUMERIC);");
$this->query("CREATE TABLE actions (ID INTEGER PRIMARY KEY, interval NUMERIC, last NUMERIC, code TEXT, repeat NUMERIC);");
$this->query("CREATE TABLE handlers (ID INTEGER PRIMARY KEY, name TEXT, priority NUMERIC);");
$this->query("CREATE TABLE blockUpdates (level TEXT, x INTEGER, y INTEGER, z INTEGER, type INTEGER, delay NUMERIC);");
@ -136,31 +201,24 @@ class PocketMinecraftServer{
$this->preparedSQL->selectHandlers = $this->database->prepare("SELECT DISTINCT ID FROM handlers WHERE name = :name ORDER BY priority DESC;");
$this->preparedSQL->selectActions = $this->database->prepare("SELECT ID,code,repeat FROM actions WHERE last <= (:time - interval);");
$this->preparedSQL->updateAction = $this->database->prepare("UPDATE actions SET last = :time WHERE ID = :id;");
$this->preparedSQL->entity->setPosition = $this->database->prepare("UPDATE entities SET x = :x, y = :y, z = :z, pitch = :pitch, yaw = :yaw WHERE EID = :eid ;");
$this->preparedSQL->entity->setLevel = $this->database->prepare("UPDATE entities SET level = :level WHERE EID = :eid ;");
}
public function query($sql, $fetch = false){
$result = $this->database->query($sql) or console("[ERROR] [SQL Error] ".$this->database->lastErrorMsg().". Query: ".$sql, true, true, 0);
if($fetch === true and ($result instanceof SQLite3Result)){
$result = $this->database->query($sql) or console("[ERROR] [SQL Error] " . $this->database->lastErrorMsg() . ". Query: " . $sql, true, true, 0);
if($fetch === true and ($result instanceof \SQLite3Result)){
$result = $result->fetchArray(SQLITE3_ASSOC);
}
return $result;
}
public function reloadConfig(){
}
public function debugInfo($console = false){
$info = array();
$info["tps"] = $this->getTPS();
$info["memory_usage"] = round((memory_get_usage() / 1024) / 1024, 2)."MB";
$info["memory_peak_usage"] = round((memory_get_peak_usage() / 1024) / 1024, 2)."MB";
$info["entities"] = $this->query("SELECT count(EID) as count FROM entities;", true);
$info["entities"] = $info["entities"]["count"];
$info["players"] = $this->query("SELECT count(CID) as count FROM players;", true);
$info["players"] = $info["players"]["count"];
$info["memory_usage"] = round((memory_get_usage() / 1024) / 1024, 2) . "MB";
$info["memory_peak_usage"] = round((memory_get_peak_usage() / 1024) / 1024, 2) . "MB";
$info["entities"] = count(Entity::$list);
$info["players"] = count(Player::$list);
$info["events"] = count($this->eventsID);
$info["handlers"] = $this->query("SELECT count(ID) as count FROM handlers;", true);
$info["handlers"] = $info["handlers"]["count"];
@ -169,11 +227,15 @@ class PocketMinecraftServer{
$info["garbage"] = gc_collect_cycles();
$this->handle("server.debug", $info);
if($console === true){
console("[DEBUG] TPS: ".$info["tps"].", Memory usage: ".$info["memory_usage"]." (Peak ".$info["memory_peak_usage"]."), Entities: ".$info["entities"].", Events: ".$info["events"].", Handlers: ".$info["handlers"].", Actions: ".$info["actions"].", Garbage: ".$info["garbage"], true, true, 2);
console("[DEBUG] TPS: " . $info["tps"] . ", Memory usage: " . $info["memory_usage"] . " (Peak " . $info["memory_peak_usage"] . "), Entities: " . $info["entities"] . ", Events: " . $info["events"] . ", Handlers: " . $info["handlers"] . ", Actions: " . $info["actions"] . ", Garbage: " . $info["garbage"], true, true, 2);
}
return $info;
}
/**
* @param string $reason
*/
public function close($reason = "server stop"){
if($this->stop !== true){
if(is_int($reason)){
@ -181,13 +243,13 @@ class PocketMinecraftServer{
}
if(($this->api instanceof ServerAPI) === true){
if(($this->api->chat instanceof ChatAPI) === true){
$this->api->chat->broadcast("Stopping server...");
Player::broadcastMessage("Stopping server...");
}
}
$this->stop = true;
$this->trigger("server.close", $reason);
$this->interface->close();
if(!defined("NO_THREADS")){
@$this->asyncThread->stop = true;
}
@ -206,7 +268,7 @@ class PocketMinecraftServer{
}
}
public function asyncOperation($type, array $data, callable $callable = null){
if(defined("NO_THREADS")){
return false;
@ -215,24 +277,29 @@ class PocketMinecraftServer{
$type = (int) $type;
switch($type){
case ASYNC_CURL_GET:
$d .= Utils::writeShort(strlen($data["url"])).$data["url"].(isset($data["timeout"]) ? Utils::writeShort($data["timeout"]) : Utils::writeShort(10));
$d .= Utils::writeShort(strlen($data["url"])) . $data["url"] . (isset($data["timeout"]) ? Utils::writeShort($data["timeout"]) : Utils::writeShort(10));
break;
case ASYNC_CURL_POST:
$d .= Utils::writeShort(strlen($data["url"])).$data["url"].(isset($data["timeout"]) ? Utils::writeShort($data["timeout"]) : Utils::writeShort(10));
$d .= Utils::writeShort(strlen($data["url"])) . $data["url"] . (isset($data["timeout"]) ? Utils::writeShort($data["timeout"]) : Utils::writeShort(10));
$d .= Utils::writeShort(count($data["data"]));
foreach($data["data"] as $key => $value){
$d .= Utils::writeShort(strlen($key)).$key . Utils::writeInt(strlen($value)).$value;
$d .= Utils::writeShort(strlen($key)) . $key . Utils::writeInt(strlen($value)) . $value;
}
break;
case ASYNC_FUNCTION:
$params = serialize($data["arguments"]);
$d .= Utils::writeShort(strlen($data["function"])) . $data["function"] . Utils::writeInt(strlen($params)) . $params;
break;
default:
return false;
}
$ID = $this->asyncID++;
$this->async[$ID] = $callable;
$this->asyncThread->input .= Utils::writeInt($ID).Utils::writeShort($type).$d;
$this->asyncThread->input .= Utils::writeInt($ID) . Utils::writeShort($type) . $d;
return $ID;
}
public function asyncOperationChecker(){
if(defined("NO_THREADS")){
return false;
@ -252,6 +319,12 @@ class PocketMinecraftServer{
$data["result"] = substr($this->asyncThread->output, $offset, $len);
$offset += $len;
break;
case ASYNC_FUNCTION:
$len = Utils::readInt(substr($this->asyncThread->output, $offset, 4));
$offset += 4;
$data["result"] = unserialize(substr($this->asyncThread->output, $offset, $len));
$offset += $len;
break;
}
$this->asyncThread->output = substr($this->asyncThread->output, $offset);
if(isset($this->async[$ID]) and $this->async[$ID] !== null and is_callable($this->async[$ID])){
@ -266,24 +339,26 @@ 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])){
$sub = "";
if(Deprecation::$events[$event] !== false){
$sub = " Substitute \"".Deprecation::$events[$event]."\" found.";
}
console("[ERROR] Event \"$event\" has been deprecated.$sub [Adding handle to ".(is_array($callable) ? get_class($callable[0])."::".$callable[1]:$callable)."]");
}
$priority = (int) $priority;
$hnid = $this->handCnt++;
$this->handlers[$hnid] = $callable;
$this->query("INSERT INTO handlers (ID, name, priority) VALUES (".$hnid.", '".str_replace("'", "\\'", $event)."', ".$priority.");");
console("[INTERNAL] New handler ".(is_array($callable) ? get_class($callable[0])."::".$callable[1]:$callable)." to special event ".$event." (ID ".$hnid.")", true, true, 3);
$this->query("INSERT INTO handlers (ID, name, priority) VALUES (" . $hnid . ", '" . str_replace("'", "\\'", $event) . "', " . $priority . ");");
console("[INTERNAL] New handler " . (is_array($callable) ? get_class($callable[0]) . "::" . $callable[1] : $callable) . " to special event " . $event . " (ID " . $hnid . ")", true, true, 3);
return $hnid;
}
public function dhandle($e, $d){
return $this->handle($e, $d);
}
@ -294,7 +369,7 @@ class PocketMinecraftServer{
$this->preparedSQL->selectHandlers->bindValue(":name", $event, SQLITE3_TEXT);
$handlers = $this->preparedSQL->selectHandlers->execute();
$result = null;
if($handlers instanceof SQLite3Result){
if($handlers instanceof \SQLite3Result){
$call = array();
while(($hn = $handlers->fetchArray(SQLITE3_ASSOC)) !== false){
$call[(int) $hn["ID"]] = true;
@ -302,7 +377,6 @@ class PocketMinecraftServer{
$handlers->finalize();
foreach($call as $hnid => $boolean){
if($result !== false and $result !== true){
$called[$hnid] = true;
$handler = $this->handlers[$hnid];
if(is_array($handler)){
$method = $handler[1];
@ -314,17 +388,12 @@ class PocketMinecraftServer{
break;
}
}
}elseif(isset(Deprecation::$events[$event])){
$sub = "";
if(Deprecation::$events[$event] !== false){
$sub = " Substitute \"".Deprecation::$events[$event]."\" found.";
}
console("[ERROR] Event \"$event\" has been deprecated.$sub [Handler]");
}
if($result !== false){
$this->trigger($event, $data);
}
return $result;
}
@ -334,63 +403,27 @@ class PocketMinecraftServer{
}
}
/**
* TODO
* @return string
*/
public function getGamemode(){
switch($this->gamemode){
case SURVIVAL:
case 0:
return "survival";
case CREATIVE:
case 1:
return "creative";
case ADVENTURE:
case 2:
return "adventure";
case VIEW:
case 3:
return "view";
}
}
public function init(){
public function init(){
register_tick_function(array($this, "tick"));
console("[DEBUG] Starting internal ticker calculation", true, true, 2);
$t = 0;
while(true){
switch($t){
case 0:
declare(ticks=100);
break;
case 1:
declare(ticks=60);
break;
case 2:
declare(ticks=40);
break;
case 3:
declare(ticks=30);
break;
case 4:
declare(ticks=20);
break;
case 5:
declare(ticks=15);
break;
default:
declare(ticks=10);
break;
}
if($t > 5){
break;
}
$this->ticks = 0;
while($this->ticks < 20){
usleep(1);
}
if($this->getTPS() < 19.5){
++$t;
}else{
break;
}
}
declare(ticks = 5000); //Minimum TPS for main thread locks
$this->loadEvents();
register_shutdown_function(array($this, "dumpError"));
@ -400,9 +433,9 @@ class PocketMinecraftServer{
pcntl_signal(SIGINT, array($this, "close"));
pcntl_signal(SIGHUP, array($this, "close"));
}
console("[INFO] Default game type: ".strtoupper($this->getGamemode()));
console("[INFO] Default game type: " . strtoupper($this->getGamemode()));
$this->trigger("server.start", microtime(true));
console('[INFO] Done ('.round(microtime(true) - START_TIME, 3).'s)! For help, type "help" or "?"');
console('[INFO] Done (' . round(microtime(true) - \pocketmine\START_TIME, 3) . 's)! For help, type "help" or "?"');
$this->process();
}
@ -410,49 +443,84 @@ class PocketMinecraftServer{
if($this->stop === true){
return;
}
console("[ERROR] An Unrecovereable has ocurred and the server has Crashed. Creating an Error Dump");
$dump = "```\r\n# PocketMine-MP Error Dump ".date("D M j H:i:s T Y")."\r\n";
ini_set("memory_limit", "-1"); //Fix error dump not dumped on memory problems
console("[SEVERE] An unrecovereable has ocurred and the server has crashed. Creating an error dump");
$dump = "```\r\n# PocketMine-MP Error Dump " . date("D M j H:i:s T Y") . "\r\n";
$er = error_get_last();
$dump .= "Error: ".var_export($er, true)."\r\n\r\n";
$errorConversion = array(
E_ERROR => "E_ERROR",
E_WARNING => "E_WARNING",
E_PARSE => "E_PARSE",
E_NOTICE => "E_NOTICE",
E_CORE_ERROR => "E_CORE_ERROR",
E_CORE_WARNING => "E_CORE_WARNING",
E_COMPILE_ERROR => "E_COMPILE_ERROR",
E_COMPILE_WARNING => "E_COMPILE_WARNING",
E_USER_ERROR => "E_USER_ERROR",
E_USER_WARNING => "E_USER_WARNING",
E_USER_NOTICE => "E_USER_NOTICE",
E_STRICT => "E_STRICT",
E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR",
E_DEPRECATED => "E_DEPRECATED",
E_USER_DEPRECATED => "E_USER_DEPRECATED",
);
$er["type"] = isset($errorConversion[$er["type"]]) ? $errorConversion[$er["type"]] : $er["type"];
$dump .= "Error: " . var_export($er, true) . "\r\n\r\n";
if(stripos($er["file"], "plugin") !== false){
$dump .= "THIS ERROR WAS CAUSED BY A PLUGIN. REPORT IT TO THE PLUGIN DEVELOPER.\r\n";
}
$dump .= "Code: \r\n";
$file = @file($er["file"], FILE_IGNORE_NEW_LINES);
for($l = max(0, $er["line"] - 10); $l < $er["line"] + 10; ++$l){
$dump .= "[".($l + 1)."] ".@$file[$l]."\r\n";
$dump .= "[" . ($l + 1) . "] " . @$file[$l] . "\r\n";
}
$dump .= "\r\n\r\n";
$dump .= "Backtrace: \r\n";
foreach(getTrace() as $line){
$dump .= "$line\r\n";
}
$dump .= "\r\n\r\n";
$version = new VersionString();
$dump .= "PM Version: ".$version." #".$version->getNumber()." [Protocol ".CURRENT_PROTOCOL."]\r\n";
$dump .= "Commit: ".GIT_COMMIT."\r\n";
$dump .= "uname -a: ".php_uname("a")."\r\n";
$dump .= "PHP Version: " .phpversion()."\r\n";
$dump .= "Zend version: ".zend_version()."\r\n";
$dump .= "OS : " .PHP_OS.", ".Utils::getOS()."\r\n";
$dump .= "Debug Info: ".var_export($this->debugInfo(false), true)."\r\n\r\n\r\n";
$dump .= "PocketMine-MP version: " . $version . " #" . $version->getNumber() . " [Protocol " . Info::CURRENT_PROTOCOL . "; API " . API_VERSION . "]\r\n";
$dump .= "Git commit: " . GIT_COMMIT . "\r\n";
$dump .= "uname -a: " . php_uname("a") . "\r\n";
$dump .= "PHP Version: " . phpversion() . "\r\n";
$dump .= "Zend version: " . zend_version() . "\r\n";
$dump .= "OS : " . PHP_OS . ", " . Utils::getOS() . "\r\n";
$dump .= "Debug Info: " . var_export($this->debugInfo(false), true) . "\r\n\r\n\r\n";
global $arguments;
$dump .= "Parameters: ".var_export($arguments, true)."\r\n\r\n\r\n";
$dump .= "Parameters: " . var_export($arguments, true) . "\r\n\r\n\r\n";
$p = $this->api->getProperties();
if($p["rcon.password"] != ""){
$p["rcon.password"] = "******";
}
$dump .= "server.properties: ".var_export($p, true)."\r\n\r\n\r\n";
if($this->api->plugin instanceof PluginAPI){
$plist = $this->api->plugin->getList();
$dump .= "server.properties: " . var_export($p, true) . "\r\n\r\n\r\n";
if(class_exists("pocketmine\\plugin\\PluginManager", false)){
$dump .= "Loaded plugins:\r\n";
foreach($plist as $p){
$dump .= $p["name"]." ".$p["version"]." by ".$p["author"]."\r\n";
foreach(PluginManager::getPlugins() as $p){
$d = $p->getDescription();
$dump .= $d->getName() . " " . $d->getVersion() . " by " . implode(", ", $d->getAuthors()) . "\r\n";
}
$dump .= "\r\n\r\n";
}
$dump .= "Loaded Modules: ".var_export(get_loaded_extensions(), true)."\r\n";
$dump .= "Memory Usage Tracking: \r\n".chunk_split(base64_encode(gzdeflate(implode(";", $this->memoryStats), 9)))."\r\n";
$extensions = array();
foreach(get_loaded_extensions() as $ext){
$extensions[$ext] = phpversion($ext);
}
$dump .= "Loaded Modules: " . var_export($extensions, true) . "\r\n";
$this->checkMemory();
$dump .= "Memory Usage Tracking: \r\n" . chunk_split(base64_encode(gzdeflate(implode(";", $this->memoryStats), 9))) . "\r\n";
ob_start();
phpinfo();
$dump .= "\r\nphpinfo(): \r\n".chunk_split(base64_encode(gzdeflate(ob_get_contents(), 9)))."\r\n";
$dump .= "\r\nphpinfo(): \r\n" . chunk_split(base64_encode(gzdeflate(ob_get_contents(), 9))) . "\r\n";
ob_end_clean();
$dump .= "\r\n```";
$name = "Error_Dump_".date("D_M_j-H.i.s-T_Y");
logg($dump, $name, true, 0, true);
console("[ERROR] Please submit the \"{$name}.log\" file to the Bug Reporting page. Give as much info as you can.", true, true, 0);
$name = "Error_Dump_" . date("D_M_j-H.i.s-T_Y");
log($dump, $name, true, 0, true);
console("[SEVERE] Please submit the \"{$name}.log\" file to the Bug Reporting page. Give as much info as you can.", true, true, 0);
}
public function tick(){
@ -461,115 +529,114 @@ class PocketMinecraftServer{
$this->tickMeasure[] = $this->lastTick = $time;
unset($this->tickMeasure[key($this->tickMeasure)]);
++$this->ticks;
$this->tickerFunction($time);
return $this->tickerFunction($time);
}
return 0;
}
public static function clientID($ip, $port){
//faster than string indexes in PHP
return crc32($ip . $port) ^ crc32($port . $ip . BOOTUP_RANDOM);
//return $ip . ":" . $port;
}
public function packetHandler($packet){
$data =& $packet["data"];
$CID = PocketMinecraftServer::clientID($packet["ip"], $packet["port"]);
if(isset($this->clients[$CID])){
$this->clients[$CID]->handlePacket($packet["pid"], $data);
}else{
if($this->handle("server.noauthpacket", $packet) === false){
return;
public function packetHandler(Packet $packet){
$data =& $packet;
$CID = Server::clientID($packet->ip, $packet->port);
if(isset(Player::$list[$CID])){
if($packet instanceof RakNetPacket){
Player::$list[$CID]->handlePacket($packet);
}
switch($packet["pid"]){
case 0x01:
case 0x02:
}else{
switch($packet->pid()){
case RakNetInfo::UNCONNECTED_PING:
case RakNetInfo::UNCONNECTED_PING_OPEN_CONNECTIONS:
if($this->invisible === true){
$this->send(0x1c, array(
$data[0],
$this->serverID,
RAKNET_MAGIC,
$this->serverType,
), false, $packet["ip"], $packet["port"]);
$pk = new RakNetPacket(RakNetInfo::UNCONNECTED_PONG);
$pk->pingID = $packet->pingID;
$pk->serverID = $this->serverID;
$pk->serverType = $this->serverType;
$pk->ip = $packet->ip;
$pk->port = $packet->port;
$this->send($pk);
break;
}
if(!isset($this->custom["times_".$CID])){
$this->custom["times_".$CID] = 0;
if(!isset($this->custom["times_" . $CID])){
$this->custom["times_" . $CID] = 0;
}
$ln = 15;
if($this->description == "" or substr($this->description, -1) != " "){
if($this->description == "" or substr($this->description, -1) != " "){
$this->description .= " ";
}
$txt = substr($this->description, $this->custom["times_".$CID], $ln);
$txt = substr($this->description, $this->custom["times_" . $CID], $ln);
$txt .= substr($this->description, 0, $ln - strlen($txt));
$this->send(0x1c, array(
$data[0],
$this->serverID,
RAKNET_MAGIC,
$this->serverType. $this->name . " [".count($this->clients)."/".$this->maxClients."] ".$txt,
), false, $packet["ip"], $packet["port"]);
$this->custom["times_".$CID] = ($this->custom["times_".$CID] + 1) % strlen($this->description);
$pk = new RakNetPacket(RakNetInfo::UNCONNECTED_PONG);
$pk->pingID = $packet->pingID;
$pk->serverID = $this->serverID;
$pk->serverType = $this->serverType . $this->name . " [" . count(Player::$list) . "/" . $this->maxClients . "] " . $txt;
$pk->ip = $packet->ip;
$pk->port = $packet->port;
$this->send($pk);
$this->custom["times_" . $CID] = ($this->custom["times_" . $CID] + 1) % strlen($this->description);
break;
case 0x05:
$version = $data[1];
$size = strlen($data[2]);
if($version !== CURRENT_STRUCTURE){
console("[DEBUG] Incorrect structure #$version from ".$packet["ip"].":".$packet["port"], true, true, 2);
$this->send(0x1a, array(
CURRENT_STRUCTURE,
RAKNET_MAGIC,
$this->serverID,
), false, $packet["ip"], $packet["port"]);
case RakNetInfo::OPEN_CONNECTION_REQUEST_1:
if($packet->structure !== RakNetInfo::STRUCTURE){
console("[DEBUG] Incorrect structure #" . $packet->structure . " from " . $packet->ip . ":" . $packet->port, true, true, 2);
$pk = new RakNetPacket(RakNetInfo::INCOMPATIBLE_PROTOCOL_VERSION);
$pk->serverID = $this->serverID;
$pk->ip = $packet->ip;
$pk->port = $packet->port;
$this->send($pk);
}else{
$this->send(0x06, array(
RAKNET_MAGIC,
$this->serverID,
0,
strlen($packet["raw"]),
), false, $packet["ip"], $packet["port"]);
$pk = new RakNetPacket(RakNetInfo::OPEN_CONNECTION_REPLY_1);
$pk->serverID = $this->serverID;
$pk->mtuSize = strlen($packet->buffer);
$pk->ip = $packet->ip;
$pk->port = $packet->port;
$this->send($pk);
}
break;
case 0x07:
case RakNetInfo::OPEN_CONNECTION_REQUEST_2:
if($this->invisible === true){
break;
}
$port = $data[2];
$MTU = $data[3];
$clientID = $data[4];
if(count($this->clients) < $this->maxClients){
$this->clients[$CID] = new Player($clientID, $packet["ip"], $packet["port"], $MTU); //New Session!
$this->send(0x08, array(
RAKNET_MAGIC,
$this->serverID,
$this->port,
$data[3],
0,
), false, $packet["ip"], $packet["port"]);
}
new Player($packet->clientID, $packet->ip, $packet->port, $packet->mtuSize); //New Session!
$pk = new RakNetPacket(RakNetInfo::OPEN_CONNECTION_REPLY_2);
$pk->serverID = $this->serverID;
$pk->serverPort = $this->port;
$pk->mtuSize = $packet->mtuSize;
$pk->ip = $packet->ip;
$pk->port = $packet->port;
$this->send($pk);
break;
}
}
}
public function send($pid, $data = array(), $raw = false, $dest = false, $port = false){
return $this->interface->writePacket($pid, $data, $raw, $dest, $port);
public function send(Packet $packet){
return $this->interface->writePacket($packet);
}
public function process(){
$lastLoop = 0;
while($this->stop === false){
$packet = $this->interface->readPacket();
if($packet !== false){
if($packet instanceof Packet){
$this->packetHandler($packet);
$lastLoop = 0;
}else{
}
if(($ticks = $this->tick()) === 0){
++$lastLoop;
if($lastLoop < 16){
usleep(1);
}elseif($lastLoop < 128){
usleep(100);
usleep(1000);
}elseif($lastLoop < 256){
usleep(512);
usleep(2000);
}else{
usleep(10000);
usleep(4000);
}
}
}
@ -589,12 +656,6 @@ class PocketMinecraftServer{
$ev($data, $event);
}
}
}elseif(isset(Deprecation::$events[$event])){
$sub = "";
if(Deprecation::$events[$event] !== false){
$sub = " Substitute \"".Deprecation::$events[$event]."\" found.";
}
console("[ERROR] Event \"$event\" has been deprecated.$sub [Trigger]");
}
}
@ -604,7 +665,8 @@ class PocketMinecraftServer{
}
$chcnt = $this->scheduleCnt++;
$this->schedule[$chcnt] = array($callback, $data, $eventName);
$this->query("INSERT INTO actions (ID, interval, last, repeat) VALUES(".$chcnt.", ".($ticks / 20).", ".microtime(true).", ".(((bool) $repeat) === true ? 1:0).");");
$this->query("INSERT INTO actions (ID, interval, last, repeat) VALUES(" . $chcnt . ", " . ($ticks / 20) . ", " . microtime(true) . ", " . (((bool) $repeat) === true ? 1 : 0) . ");");
return $chcnt;
}
@ -614,39 +676,36 @@ class PocketMinecraftServer{
$this->preparedSQL->selectActions->bindValue(":time", $time, SQLITE3_FLOAT);
$actions = $this->preparedSQL->selectActions->execute();
if($actions instanceof SQLite3Result){
$actionCount = 0;
if($actions instanceof \SQLite3Result){
while(($action = $actions->fetchArray(SQLITE3_ASSOC)) !== false){
$cid = $action["ID"];
$this->preparedSQL->updateAction->reset();
$this->preparedSQL->updateAction->bindValue(":time", $time, SQLITE3_FLOAT);
$this->preparedSQL->updateAction->bindValue(":id", $cid, SQLITE3_INTEGER);
$this->preparedSQL->updateAction->execute();
$schedule = $this->schedule[$cid];
if(!is_callable($schedule[0])){
if(!@is_callable($this->schedule[$cid][0])){
$return = false;
}else{
$return = call_user_func($schedule[0], $schedule[1], $schedule[2]);
++$actionCount;
$return = call_user_func($this->schedule[$cid][0], $this->schedule[$cid][1], $this->schedule[$cid][2]);
}
if($action["repeat"] == 0 or $return === false){
$this->query("DELETE FROM actions WHERE ID = ".$action["ID"].";");
$this->query("DELETE FROM actions WHERE ID = " . $action["ID"] . ";");
$this->schedule[$cid] = null;
unset($this->schedule[$cid]);
}
}
$actions->finalize();
}
return $actionCount;
}
public function event($event,callable $func){
public function event($event, callable $func){
if(!is_callable($func)){
return false;
}elseif(isset(Deprecation::$events[$event])){
$sub = "";
if(Deprecation::$events[$event] !== false){
$sub = " Substitute \"".Deprecation::$events[$event]."\" found.";
}
console("[ERROR] Event \"$event\" has been deprecated.$sub [Attach to ".(is_array($func) ? get_class($func[0])."::".$func[1]:$func)."]");
}
$evid = $this->evCnt++;
if(!isset($this->events[$event])){
@ -654,7 +713,8 @@ class PocketMinecraftServer{
}
$this->events[$event][$evid] = $func;
$this->eventsID[$evid] = $event;
console("[INTERNAL] Attached ".(is_array($func) ? get_class($func[0])."::".$func[1]:$func)." to event ".$event." (ID ".$evid.")", true, true, 3);
console("[INTERNAL] Attached " . (is_array($func) ? get_class($func[0]) . "::" . $func[1] : $func) . " to event " . $event . " (ID " . $evid . ")", true, true, 3);
return $evid;
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,6 +19,10 @@
*
*/
namespace pocketmine;
use pocketmine\level\Level;
class TimeAPI{
public static $phases = array(
"day" => 0,
@ -27,8 +31,9 @@ class TimeAPI{
"sunrise" => 17800,
);
private $server;
function __construct(){
$this->server = ServerAPI::request();
$this->server = Server::getInstance();
}
public function init(){
@ -46,19 +51,19 @@ class TimeAPI{
$p = strtolower(array_shift($params));
switch($p){
case "check":
$output .= "Time: ".$this->getDate($level).", ".$this->getPhase($level)." (".$this->get(true, $level).")\n";
$output .= "Time: " . $this->getDate($level) . ", " . $this->getPhase($level) . " (" . $this->get(true, $level) . ")\n";
break;
case "add":
$output .= "Set the time to ".$this->add(array_shift($params), $level)."\n";
$output .= "Set the time to " . $this->add(array_shift($params), $level) . "\n";
break;
case "set":
$output .= "Set the time to ".$this->set(array_shift($params), $level)."\n";
$output .= "Set the time to " . $this->set(array_shift($params), $level) . "\n";
break;
case "sunrise":
case "day":
case "sunset":
case "night":
$output .= "Set the time to ".$this->set($p, $level)."\n";
$output .= "Set the time to " . $this->set($p, $level) . "\n";
break;
default:
$output .= "Usage: /time <check|set|add> [time]\n";
@ -66,43 +71,49 @@ class TimeAPI{
}
break;
}
return $output;
}
public function night(){
return $this->set("night");
}
public function day(){
return $this->set("day");
}
public function sunrise(){
return $this->set("sunrise");
}
public function sunset(){
return $this->set("sunset");
}
public function get($raw = false, $level = false){
if(!($level instanceof Level)){
$level = $this->server->api->level->getDefault();
$level = Level::getDefault();
}
return $raw === true ? $level->getTime():abs($level->getTime()) % 19200;
return $raw === true ? $level->getTime() : abs($level->getTime()) % 19200;
}
public function add($time, $level = false){
if(!($level instanceof Level)){
$level = $this->server->api->level->getDefault();
$level = Level::getDefault();
}
$level->setTime($level->getTime() + (int) $time);
}
public function getDate($time = false){
$time = !is_integer($time) ? $this->get(false, $time):$time;
return str_pad(strval((floor($time /800) + 6) % 24), 2, "0", STR_PAD_LEFT).":".str_pad(strval(floor(($time % 800) / 13.33)), 2, "0", STR_PAD_LEFT);
$time = !is_integer($time) ? $this->get(false, $time) : $time;
return str_pad(strval((floor($time / 800) + 6) % 24), 2, "0", STR_PAD_LEFT) . ":" . str_pad(strval(floor(($time % 800) / 13.33)), 2, "0", STR_PAD_LEFT);
}
public function getPhase($time = false){
$time = !is_integer($time) ? $this->get(false, $time):$time;
$time = !is_integer($time) ? $this->get(false, $time) : $time;
if($time < TimeAPI::$phases["sunset"]){
$time = "day";
}elseif($time < TimeAPI::$phases["night"]){
@ -112,18 +123,20 @@ class TimeAPI{
}else{
$time = "sunrise";
}
return $time;
}
public function set($time, $level = false){
if(!($level instanceof Level)){
$level = $this->server->api->level->getDefault();
$level = Level::getDefault();
}
if(is_string($time) and isset(TimeAPI::$phases[$time])){
$level->setTime(TimeAPI::$phases[$time]);
}else{
$level->setTime((int) $time);
}
return $level->getTime();
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,9 +19,15 @@
*
*/
class AirBlock extends TransparentBlock{
namespace pocketmine\block;
/**
* Air block
*/
class Air extends Transparent{
public function __construct(){
parent::__construct(AIR, 0, "Air");
parent::__construct(self::AIR, 0, "Air");
$this->isActivable = false;
$this->breakable = false;
$this->isFlowable = true;
@ -31,7 +37,8 @@ class AirBlock extends TransparentBlock{
$this->hasPhysics = false;
$this->isSolid = false;
$this->isFullBlock = true;
$this->hardness = 0;
}
}

View File

@ -0,0 +1,141 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\network\protocol\ChatPacket;
use pocketmine\Player;
use pocketmine\Server;
class Bed extends Transparent{
public function __construct($type = 0){
parent::__construct(self::BED_BLOCK, $type, "Bed Block");
$this->isActivable = true;
$this->isFullBlock = false;
$this->hardness = 1;
}
public function onActivate(Item $item, Player $player = null){
if($player instanceof Player and Server::getInstance()->api->time->getPhase($this->level) !== "night"){
$pk = new ChatPacket;
$pk->message = "You can only sleep at night";
$player->dataPacket($pk);
return true;
}
$blockNorth = $this->getSide(2); //Gets the blocks around them
$blockSouth = $this->getSide(3);
$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;
}elseif($player instanceof Player){
$pk = new ChatPacket;
$pk->message = "This bed is incomplete";
$player->dataPacket($pk);
return true;
}
}
if($player instanceof Player and $player->sleepOn($b) === false){
$pk = new ChatPacket;
$pk->message = "This bed is occupied";
$player->dataPacket($pk);
}
return true;
}
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
$down = $this->getSide(0);
if($down->isTransparent === false){
$faces = array(
0 => 3,
1 => 4,
2 => 2,
3 => 5,
);
$d = $player instanceof Player ? $player->getDirection() : 0;
$next = $this->getSide($faces[(($d + 3) % 4)]);
$downNext = $this->getSide(0);
if($next->isReplaceable === true and $downNext->isTransparent === false){
$meta = (($d + 3) % 4) & 0x03;
$this->level->setBlock($block, Block::get($this->id, $meta), true, false, true);
$this->level->setBlock($next, Block::get($this->id, $meta | 0x08), true, false, true);
return true;
}
}
return false;
}
public function onBreak(Item $item){
$blockNorth = $this->getSide(2); //Gets the blocks around them
$blockSouth = $this->getSide(3);
$blockEast = $this->getSide(5);
$blockWest = $this->getSide(4);
if(($this->meta & 0x08) === 0x08){ //This is the Top part of bed
if($blockNorth->getID() === $this->id and $blockNorth->meta !== 0x08){ //Checks if the block ID and meta are right
$this->level->setBlock($blockNorth, new Air(), true, false, true);
}elseif($blockSouth->getID() === $this->id and $blockSouth->meta !== 0x08){
$this->level->setBlock($blockSouth, new Air(), true, false, true);
}elseif($blockEast->getID() === $this->id and $blockEast->meta !== 0x08){
$this->level->setBlock($blockEast, new Air(), true, false, true);
}elseif($blockWest->getID() === $this->id and $blockWest->meta !== 0x08){
$this->level->setBlock($blockWest, new Air(), true, false, true);
}
}else{ //Bottom Part of Bed
if($blockNorth->getID() === $this->id and ($blockNorth->meta & 0x08) === 0x08){
$this->level->setBlock($blockNorth, new Air(), true, false, true);
}elseif($blockSouth->getID() === $this->id and ($blockSouth->meta & 0x08) === 0x08){
$this->level->setBlock($blockSouth, new Air(), true, false, true);
}elseif($blockEast->getID() === $this->id and ($blockEast->meta & 0x08) === 0x08){
$this->level->setBlock($blockEast, new Air(), true, false, true);
}elseif($blockWest->getID() === $this->id and ($blockWest->meta & 0x08) === 0x08){
$this->level->setBlock($blockWest, new Air(), true, false, true);
}
}
$this->level->setBlock($this, new Air(), true, false, true);
return true;
}
public function getDrops(Item $item){
return array(
array(Item::BED, 0, 1),
);
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,17 +19,19 @@
*
*/
class BedrockBlock extends SolidBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
class Bedrock extends Solid{
public function __construct(){
parent::__construct(BEDROCK, 0, "Bedrock");
parent::__construct(self::BEDROCK, 0, "Bedrock");
$this->breakable = false;
$this->hardness = 18000000;
}
public function isBreakable(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0x01){
return true;
}
public function isBreakable(Item $item){
return false;
}
}

View File

@ -0,0 +1,94 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\level\Level;
use pocketmine\Player;
class Beetroot extends Flowable{
public function __construct($meta = 0){
parent::__construct(self::BEETROOT_BLOCK, $meta, "Beetroot Block");
$this->isActivable = true;
$this->hardness = 0;
}
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
$down = $this->getSide(0);
if($down->getID() === self::FARMLAND){
$this->level->setBlock($block, $this, true, false, true);
return true;
}
return false;
}
public function onActivate(Item $item, Player $player = null){
if($item->getID() === Item::DYE and $item->getMetadata() === 0x0F){ //Bonemeal
$this->meta = 0x07;
$this->level->setBlock($this, $this, true, false, true);
$item->count--;
return true;
}
return false;
}
public function onUpdate($type){
if($type === Level::BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
//TODO
//Server::getInstance()->api->entity->drop($this, Item::get(BEETROOT_SEEDS, 0, 1));
$this->level->setBlock($this, new Air(), false, false, true);
return Level::BLOCK_UPDATE_NORMAL;
}
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
if(mt_rand(0, 2) == 1){
if($this->meta < 0x07){
++$this->meta;
$this->level->setBlock($this, $this, true, false, true);
return Level::BLOCK_UPDATE_RANDOM;
}
}else{
return Level::BLOCK_UPDATE_RANDOM;
}
}
return false;
}
public function getDrops(Item $item){
$drops = array();
if($this->meta >= 0x07){
$drops[] = array(Item::BEETROOT, 0, 1);
$drops[] = array(Item::BEETROOT_SEEDS, 0, mt_rand(0, 3));
}else{
$drops[] = array(Item::BEETROOT_SEEDS, 0, 1);
}
return $drops;
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,9 +19,18 @@
*
*/
class NetherBricksStairsBlock extends StairBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
class BirchWoodStairs extends Stair{
public function __construct($meta = 0){
parent::__construct(NETHER_BRICKS_STAIRS, $meta, "Nether Bricks Stairs");
parent::__construct(self::BIRCH_WOOD_STAIRS, $meta, "Birch Wood Stairs");
}
public function getDrops(Item $item){
return array(
array($this->id, 0, 1),
);
}
}

View File

@ -0,0 +1,543 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
/**
* All Block classes are in here
*/
namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\level\Level;
use pocketmine\level\Position;
use pocketmine\Player;
abstract class Block extends Position{
const AIR = 0;
const STONE = 1;
const GRASS = 2;
const DIRT = 3;
const COBBLESTONE = 4;
const COBBLE = 4;
const PLANK = 5;
const PLANKS = 5;
const WOODEN_PLANK = 5;
const WOODEN_PLANKS = 5;
const SAPLING = 6;
const SAPLINGS = 6;
const BEDROCK = 7;
const WATER = 8;
const STILL_WATER = 9;
const LAVA = 10;
const STILL_LAVA = 11;
const SAND = 12;
const GRAVEL = 13;
const GOLD_ORE = 14;
const IRON_ORE = 15;
const COAL_ORE = 16;
const WOOD = 17;
const TRUNK = 17;
const LOG = 17;
const LEAVES = 18;
const LEAVE = 18;
const SPONGE = 19;
const GLASS = 20;
const LAPIS_ORE = 21;
const LAPIS_BLOCK = 22;
const SANDSTONE = 24;
const BED_BLOCK = 26;
const COBWEB = 30;
const TALL_GRASS = 31;
const BUSH = 32;
const DEAD_BUSH = 32;
const WOOL = 35;
const DANDELION = 37;
const ROSE = 38;
const CYAN_FLOWER = 38;
const BROWN_MUSHROOM = 39;
const RED_MUSHROOM = 40;
const GOLD_BLOCK = 41;
const IRON_BLOCK = 42;
const DOUBLE_SLAB = 43;
const DOUBLE_SLABS = 43;
const SLAB = 44;
const SLABS = 44;
const BRICKS = 45;
const BRICKS_BLOCK = 45;
const TNT = 46;
const BOOKSHELF = 47;
const MOSS_STONE = 48;
const MOSSY_STONE = 48;
const OBSIDIAN = 49;
const TORCH = 50;
const FIRE = 51;
const WOOD_STAIRS = 53;
const WOODEN_STAIRS = 53;
const OAK_WOOD_STAIRS = 53;
const OAK_WOODEN_STAIRS = 53;
const CHEST = 54;
const DIAMOND_ORE = 56;
const DIAMOND_BLOCK = 57;
const CRAFTING_TABLE = 58;
const WORKBENCH = 58;
const WHEAT_BLOCK = 59;
const FARMLAND = 60;
const FURNACE = 61;
const BURNING_FURNACE = 62;
const LIT_FURNACE = 62;
const SIGN_POST = 63;
const DOOR_BLOCK = 64;
const WOODEN_DOOR_BLOCK = 64;
const WOOD_DOOR_BLOCK = 64;
const LADDER = 65;
const COBBLE_STAIRS = 67;
const COBBLESTONE_STAIRS = 67;
const WALL_SIGN = 68;
const IRON_DOOR_BLOCK = 71;
const REDSTONE_ORE = 73;
const GLOWING_REDSTONE_ORE = 74;
const LIT_REDSTONE_ORE = 74;
const SNOW = 78;
const SNOW_LAYER = 78;
const ICE = 79;
const SNOW_BLOCK = 80;
const CACTUS = 81;
const CLAY_BLOCK = 82;
const REEDS = 83;
const SUGARCANE_BLOCK = 83;
const FENCE = 85;
const PUMPKIN = 86;
const NETHERRACK = 87;
const SOUL_SAND = 88;
const GLOWSTONE = 89;
const GLOWSTONE_BLOCK = 89;
const LIT_PUMPKIN = 91;
const JACK_O_LANTERN = 91;
const CAKE_BLOCK = 92;
const TRAPDOOR = 96;
const STONE_BRICKS = 98;
const STONE_BRICK = 98;
const IRON_BAR = 101;
const IRON_BARS = 101;
const GLASS_PANE = 102;
const GLASS_PANEL = 102;
const MELON_BLOCK = 103;
const PUMPKIN_STEM = 104;
const MELON_STEM = 105;
const FENCE_GATE = 107;
const BRICK_STAIRS = 108;
const STONE_BRICK_STAIRS = 109;
const NETHER_BRICKS = 112;
const NETHER_BRICK_BLOCK = 112;
const NETHER_BRICKS_STAIRS = 114;
const SANDSTONE_STAIRS = 128;
const SPRUCE_WOOD_STAIRS = 134;
const SPRUCE_WOODEN_STAIRS = 134;
const BIRCH_WOOD_STAIRS = 135;
const BIRCH_WOODEN_STAIRS = 135;
const JUNGLE_WOOD_STAIRS = 136;
const JUNGLE_WOODEN_STAIRS = 136;
const COBBLE_WALL = 139;
const STONE_WALL = 139;
const COBBLESTONE_WALL = 139;
const CARROT_BLOCK = 141;
const POTATO_BLOCK = 142;
const QUARTZ_BLOCK = 155;
const QUARTZ_STAIRS = 156;
const DOUBLE_WOOD_SLAB = 157;
const DOUBLE_WOODEN_SLAB = 157;
const DOUBLE_WOOD_SLABS = 157;
const DOUBLE_WOODEN_SLABS = 157;
const WOOD_SLAB = 158;
const WOODEN_SLAB = 158;
const WOOD_SLABS = 158;
const WOODEN_SLABS = 158;
const HAY_BALE = 170;
const CARPET = 171;
const COAL_BLOCK = 173;
const BEETROOT_BLOCK = 244;
const STONECUTTER = 245;
const GLOWING_OBSIDIAN = 246;
const NETHER_REACTOR = 247;
public static $list = array();
protected $id;
protected $meta;
protected $name;
protected $breakTime;
protected $hardness;
public $isActivable = false;
public $breakable = true;
public $isFlowable = false;
public $isSolid = true;
public $isTransparent = false;
public $isReplaceable = false;
public $isPlaceable = true;
public $level = false;
public $hasPhysics = false;
public $isLiquid = false;
public $isFullBlock = true;
public $x = 0;
public $y = 0;
public $z = 0;
public static function init(){
if(count(self::$list) === 0){
self::$list = array(
self::AIR => new Air(),
self::STONE => new Stone(),
self::GRASS => new Grass(),
self::DIRT => new Dirt(),
self::COBBLESTONE => new Cobblestone(),
self::PLANKS => new Planks(),
self::SAPLING => new Sapling(),
self::BEDROCK => new Bedrock(),
self::WATER => new Water(),
self::STILL_WATER => new StillWater(),
self::LAVA => new Lava(),
self::STILL_LAVA => new StillLava(),
self::SAND => new Sand(),
self::GRAVEL => new Gravel(),
self::GOLD_ORE => new GoldOre(),
self::IRON_ORE => new IronOre(),
self::COAL_ORE => new CoalOre(),
self::WOOD => new Wood(),
self::LEAVES => new Leaves(),
self::SPONGE => new Sponge(),
self::GLASS => new Glass(),
self::LAPIS_ORE => new LapisOre(),
self::LAPIS_BLOCK => new Lapis(),
self::SANDSTONE => new Sandstone(),
self::BED_BLOCK => new Bed(),
self::COBWEB => new Cobweb(),
self::TALL_GRASS => new TallGrass(),
self::DEAD_BUSH => new DeadBush(),
self::WOOL => new Wool(),
self::DANDELION => new Dandelion(),
self::CYAN_FLOWER => new CyanFlower(),
self::BROWN_MUSHROOM => new BrownMushroom(),
self::RED_MUSHROOM => new RedMushroom(),
self::GOLD_BLOCK => new Gold(),
self::IRON_BLOCK => new Iron(),
self::DOUBLE_SLAB => new DoubleSlab(),
self::SLAB => new Slab(),
self::BRICKS_BLOCK => new Bricks(),
self::TNT => new TNT(),
self::BOOKSHELF => new Bookshelf(),
self::MOSS_STONE => new MossStone(),
self::OBSIDIAN => new Obsidian(),
self::TORCH => new Torch(),
self::FIRE => new Fire(),
self::WOOD_STAIRS => new WoodStairs(),
self::CHEST => new Chest(),
self::DIAMOND_ORE => new DiamondOre(),
self::DIAMOND_BLOCK => new Diamond(),
self::WORKBENCH => new Workbench(),
self::WHEAT_BLOCK => new Wheat(),
self::FARMLAND => new Farmland(),
self::FURNACE => new Furnace(),
self::BURNING_FURNACE => new BurningFurnace(),
self::SIGN_POST => new SignPost(),
self::WOOD_DOOR_BLOCK => new WoodDoor(),
self::LADDER => new Ladder(),
self::COBBLESTONE_STAIRS => new CobblestoneStairs(),
self::WALL_SIGN => new WallSign(),
self::IRON_DOOR_BLOCK => new IronDoor(),
self::REDSTONE_ORE => new RedstoneOre(),
self::GLOWING_REDSTONE_ORE => new GlowingRedstoneOre(),
self::SNOW_LAYER => new SnowLayer(),
self::ICE => new Ice(),
self::SNOW_BLOCK => new Snow(),
self::CACTUS => new Cactus(),
self::CLAY_BLOCK => new Clay(),
self::SUGARCANE_BLOCK => new Sugarcane(),
self::FENCE => new Fence(),
self::PUMPKIN => new Pumpkin(),
self::NETHERRACK => new Netherrack(),
self::SOUL_SAND => new SoulSand(),
self::GLOWSTONE_BLOCK => new Glowstone(),
self::LIT_PUMPKIN => new LitPumpkin(),
self::CAKE_BLOCK => new Cake(),
self::TRAPDOOR => new Trapdoor(),
self::STONE_BRICKS => new StoneBricks(),
self::IRON_BARS => new IronBars(),
self::GLASS_PANE => new GlassPane(),
self::MELON_BLOCK => new Melon(),
self::PUMPKIN_STEM => new PumpkinStem(),
self::MELON_STEM => new MelonStem(),
self::FENCE_GATE => new FenceGate(),
self::BRICK_STAIRS => new BrickStairs(),
self::STONE_BRICK_STAIRS => new StoneBrickStairs(),
self::NETHER_BRICKS => new NetherBrick(),
self::NETHER_BRICKS_STAIRS => new NetherBrickStairs(),
self::SANDSTONE_STAIRS => new SandstoneStairs(),
self::SPRUCE_WOOD_STAIRS => new SpruceWoodStairs(),
self::BIRCH_WOOD_STAIRS => new BirchWoodStairs(),
self::JUNGLE_WOOD_STAIRS => new JungleWoodStairs(),
self::STONE_WALL => new StoneWall(),
self::CARROT_BLOCK => new Carrot(),
self::POTATO_BLOCK => new Potato(),
self::QUARTZ_BLOCK => new Quartz(),
self::QUARTZ_STAIRS => new QuartzStairs(),
self::DOUBLE_WOOD_SLAB => new DoubleWoodSlab(),
self::WOOD_SLAB => new WoodSlab(),
self::HAY_BALE => new HayBale(),
self::CARPET => new Carpet(),
self::COAL_BLOCK => new Coal(),
self::BEETROOT_BLOCK => new Beetroot(),
self::STONECUTTER => new Stonecutter(),
self::GLOWING_OBSIDIAN => new GlowingObsidian(),
);
}
}
/**
* @param int $id
* @param int $meta
* @param Position $pos
*
* @return Block
*/
public static function get($id, $meta = 0, Position $pos = null){
if(isset(self::$list[$id])){
$block = clone self::$list[$id];
$block->setMetadata($meta);
}else{
$block = new Generic($id, $meta);
}
if($pos instanceof Position){
$block->position($pos);
}
return $block;
}
/**
* @param int $id
* @param int $meta
* @param string $name
*/
public function __construct($id, $meta = 0, $name = "Unknown"){
$this->id = (int) $id;
$this->meta = (int) $meta;
$this->name = $name;
$this->breakTime = 0.20;
$this->hardness = 10;
}
/**
* @return int
*/
final public function getHardness(){
return $this->hardness;
}
/**
* @return string
*/
final public function getName(){
return $this->name;
}
/**
* @return int
*/
final public function getID(){
return $this->id;
}
/**
* @return int
*/
final public function getMetadata(){
return $this->meta;
}
/**
* @param int $meta
*/
final public function setMetadata($meta){
$this->meta = $meta & 0x0F;
}
/**
* Sets the block position to a new Position object
*
* @param Position $v
*/
final public function position(Position $v){
$this->level = $v->level;
$this->x = (int) $v->x;
$this->y = (int) $v->y;
$this->z = (int) $v->z;
}
/**
* Returns an array of Item objects to be dropped
*
* @param Item $item
*
* @return array
*/
public function getDrops(Item $item){
if(!isset(self::$list[$this->id])){ //Unknown blocks
return array();
}else{
return array(
array($this->id, $this->meta, 1),
);
}
}
/**
* Returns the seconds that this block takes to be broken using an specific Item
*
* @param Item $item
*
* @return float
*/
public function getBreakTime(Item $item){
return $this->breakTime;
}
/**
* Returns the Block on the side $side, works like Vector3::side()
*
* @param int $side
*
* @return Block
*/
public function getSide($side){
$v = parent::getSide($side);
if($this->level instanceof Level){
return $this->level->getBlock($v);
}
return $v;
}
/**
* @return string
*/
final public function __toString(){
return "Block " . $this->name . " (" . $this->id . ":" . $this->meta . ")";
}
/**
* Returns if the item can be broken with an specific Item
*
* @param Item $item
*
* @return bool
*/
abstract function isBreakable(Item $item);
/**
* Do the actions needed so the block is broken with the Item
*
* @param Item $item
*
* @return mixed
*/
abstract function onBreak(Item $item);
/**
* Places the Block, using block space and block target, and side. Returns if the block has been placed.
*
* @param Item $item
* @param Block $block
* @param Block $target
* @param int $face
* @param float $fx
* @param float $fy
* @param float $fz
* @param Player $player = null
*
* @return bool
*/
abstract function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null);
/**
* Do actions when activated by Item. Returns if it has done anything
*
* @param Item $item
* @param Player $player
*
* @return bool
*/
abstract function onActivate(Item $item, Player $player = null);
/**
* Fires a block update on the Block
*
* @param int $type
*
* @return void
*/
abstract function onUpdate($type);
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,9 +19,13 @@
*
*/
class BookshelfBlock extends SolidBlock{
namespace pocketmine\block;
class Bookshelf extends Solid{
public function __construct(){
parent::__construct(BOOKSHELF, 0, "Bookshelf");
parent::__construct(self::BOOKSHELF, 0, "Bookshelf");
$this->hardness = 7.5;
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,9 +19,12 @@
*
*/
class BrickStairsBlock extends StairBlock{
namespace pocketmine\block;
class BrickStairs extends Stair{
public function __construct($meta = 0){
parent::__construct(BRICK_STAIRS, $meta, "Brick Stairs");
parent::__construct(self::BRICK_STAIRS, $meta, "Brick Stairs");
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,15 +19,17 @@
*
*/
class BricksBlock extends SolidBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
class Bricks extends Solid{
public function __construct(){
parent::__construct(BRICKS_BLOCK, 0, "Bricks");
parent::__construct(self::BRICKS_BLOCK, 0, "Bricks");
$this->hardness = 30;
}
public function getBreakTime(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0x01){
return 0.20;
}
public function getBreakTime(Item $item){
switch($item->isPickaxe()){
case 5:
return 0.4;
@ -43,11 +45,11 @@ class BricksBlock extends SolidBlock{
return 10;
}
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
if($item->isPickaxe() >= 1){
return array(
array(BRICKS_BLOCK, 0, 1),
array(Item::BRICKS_BLOCK, 0, 1),
);
}else{
return array();

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,28 +19,40 @@
*
*/
class DandelionBlock extends FlowableBlock{
public function __construct(){
parent::__construct(DANDELION, 0, "Dandelion");
}
namespace pocketmine\block;
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
$down = $this->getSide(0);
if($down->getID() === 2 or $down->getID() === 3 or $down->getID() === 60){
$this->level->setBlock($block, $this, true, false, true);
return true;
}
return false;
use pocketmine\item\Item;
use pocketmine\level\Level;
use pocketmine\Player;
class BrownMushroom extends Flowable{
public function __construct(){
parent::__construct(self::BROWN_MUSHROOM, 0, "Brown Mushroom");
$this->hardness = 0;
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
if($type === Level::BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
ServerAPI::request()->api->entity->drop($this, BlockAPI::getItem($this->id));
$this->level->setBlock($this, new AirBlock(), false, false, true);
return BLOCK_UPDATE_NORMAL;
//TODO
//Server::getInstance()->api->entity->drop($this, Item::get($this->id));
$this->level->setBlock($this, new Air(), false, false, true);
return Level::BLOCK_UPDATE_NORMAL;
}
}
return false;
}
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
$down = $this->getSide(0);
if($down->isTransparent === false){
$this->level->setBlock($block, $this, true, false, true);
return true;
}
return false;
}
}

View File

@ -0,0 +1,131 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\Compound;
use pocketmine\nbt\tag\Enum;
use pocketmine\nbt\tag\Int;
use pocketmine\nbt\tag\String;
use pocketmine\Player;
use pocketmine\tile\Furnace;
use pocketmine\tile\Tile;
class BurningFurnace extends Solid{
public function __construct($meta = 0){
parent::__construct(self::BURNING_FURNACE, $meta, "Burning Furnace");
$this->isActivable = true;
$this->hardness = 17.5;
}
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
$faces = array(
0 => 4,
1 => 2,
2 => 5,
3 => 3,
);
$this->meta = $faces[$player instanceof Player ? $player->getDirection() : 0];
$this->level->setBlock($block, $this, true, false, true);
$nbt = new Compound(false, array(
new Enum("Items", array()),
new String("id", Tile::FURNACE),
new Int("x", $this->x),
new Int("y", $this->y),
new Int("z", $this->z)
));
$nbt->Items->setTagType(NBT::TAG_Compound);
new Furnace($this->level, $nbt);
return true;
}
public function onBreak(Item $item){
$this->level->setBlock($this, new Air(), true, true, true);
return true;
}
public function onActivate(Item $item, Player $player = null){
if($player instanceof Player){
$t = $this->level->getTile($this);
$furnace = false;
if($t instanceof Furnace){
$furnace = $t;
}else{
$nbt = new Compound(false, array(
new Enum("Items", array()),
new String("id", Tile::FURNACE),
new Int("x", $this->x),
new Int("y", $this->y),
new Int("z", $this->z)
));
$nbt->Items->setTagType(NBT::TAG_Compound);
$furnace = new Furnace($this->level, $nbt);
}
if(($player->getGamemode() & 0x01) === 0x01){
return true;
}
$furnace->openInventory($player);
}
return true;
}
public function getBreakTime(Item $item){
switch($item->isPickaxe()){
case 5:
return 0.7;
case 4:
return 0.9;
case 3:
return 1.35;
case 2:
return 0.45;
case 1:
return 2.65;
default:
return 17.5;
}
}
public function getDrops(Item $item){
$drops = array();
if($item->isPickaxe() >= 1){
$drops[] = array(Item::FURNACE, 0, 1);
}
$t = $this->level->getTile($this);
if($t instanceof Furnace){
for($s = 0; $s < Furnace::SLOTS; ++$s){
$slot = $t->getSlot($s);
if($slot->getID() > Item::AIR and $slot->getCount() > 0){
$drops[] = array($slot->getID(), $slot->getMetadata(), $slot->getCount());
}
}
}
return $drops;
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,27 +19,37 @@
*
*/
class CactusBlock extends TransparentBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\level\Level;
use pocketmine\math\Vector3 as Vector3;
use pocketmine\Player;
use pocketmine\Server;
class Cactus extends Transparent{
public function __construct($meta = 0){
parent::__construct(CACTUS, $meta, "Cactus");
parent::__construct(self::CACTUS, $meta, "Cactus");
$this->isFullBlock = false;
$this->hardness = 2;
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
if($type === Level::BLOCK_UPDATE_NORMAL){
$down = $this->getSide(0);
if($down->getID() !== SAND and $down->getID() !== CACTUS){ //Replace with common break method
$this->level->setBlock($this, new AirBlock(), false);
ServerAPI::request()->api->entity->drop($this, BlockAPI::getItem($this->id));
return BLOCK_UPDATE_NORMAL;
if($down->getID() !== self::SAND and $down->getID() !== self::CACTUS){ //Replace with common break method
$this->level->setBlock($this, new Air(), false);
Server::getInstance()->api->entity->drop($this, Item::get($this->id));
return Level::BLOCK_UPDATE_NORMAL;
}
}elseif($type === BLOCK_UPDATE_RANDOM){
if($this->getSide(0)->getID() !== CACTUS){
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
if($this->getSide(0)->getID() !== self::CACTUS){
if($this->meta == 0x0F){
for($y = 1; $y < 3; ++$y){
$b = $this->level->getBlock(new Vector3($this->x, $this->y + $y, $this->z));
if($b->getID() === AIR){
$this->level->setBlock($b, new CactusBlock(), true, false, true);
if($b->getID() === self::AIR){
$this->level->setBlock($b, new Cactus(), true, false, true);
break;
}
}
@ -49,29 +59,32 @@ class CactusBlock extends TransparentBlock{
++$this->meta;
$this->level->setBlock($this, $this, false);
}
return BLOCK_UPDATE_RANDOM;
return Level::BLOCK_UPDATE_RANDOM;
}
}
return false;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
$down = $this->getSide(0);
if($down->getID() === SAND or $down->getID() === CACTUS){
if($down->getID() === self::SAND or $down->getID() === self::CACTUS){
$block0 = $this->getSide(2);
$block1 = $this->getSide(3);
$block2 = $this->getSide(4);
$block3 = $this->getSide(5);
if($block0->isTransparent === true and $block1->isTransparent === true and $block2->isTransparent === true and $block3->isTransparent === true){
$this->level->setBlock($this, $this, true, false, true);
$this->level->scheduleBlockUpdate(new Position($this, 0, 0, $this->level), Utils::getRandomUpdateTicks(), BLOCK_UPDATE_RANDOM);
return true;
}
}
return false;
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
return array(
array($this->id, 0, 1),
);

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,40 +19,62 @@
*
*/
class CakeBlock extends TransparentBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\level\Level;
use pocketmine\Player;
class Cake extends Transparent{
public function __construct($meta = 0){
parent::__construct(CAKE_BLOCK, 0, "Cake Block");
parent::__construct(self::CAKE_BLOCK, 0, "Cake Block");
$this->isFullBlock = false;
$this->isActivable = true;
$this->meta = $meta & 0x07;
$this->hardness = 2.5;
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->getID() === AIR){ //Replace with common break method
$this->level->setBlock($this, new AirBlock(), true, false, true);
return BLOCK_UPDATE_NORMAL;
}
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
$down = $this->getSide(0);
if($down->getID() !== self::AIR){
$this->level->setBlock($block, $this, true, false, true);
return true;
}
return false;
}
public function getDrops(Item $item, Player $player){
public function onUpdate($type){
if($type === Level::BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->getID() === self::AIR){ //Replace with common break method
$this->level->setBlock($this, new Air(), true, false, true);
return Level::BLOCK_UPDATE_NORMAL;
}
}
return false;
}
public function getDrops(Item $item){
return array();
}
public function onActivate(Item $item, Player $player){
if($player->entity->getHealth() < 20){
public function onActivate(Item $item, Player $player = null){
if($player instanceof Player and $player->getHealth() < 20){
++$this->meta;
$player->entity->heal(3, "cake");
$player->heal(3, "cake");
if($this->meta >= 0x06){
$this->level->setBlock($this, new AirBlock(), true, false, true);
$this->level->setBlock($this, new Air(), true, false, true);
}else{
$this->level->setBlock($this, $this, true, false, true);
}
return true;
}
return false;
}
}

View File

@ -0,0 +1,80 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\level\Level;
use pocketmine\Player;
class Carpet extends Flowable{
public function __construct($meta = 0){
parent::__construct(self::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, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
$down = $this->getSide(0);
if($down->getID() !== self::AIR){
$this->level->setBlock($block, $this, true, false, true);
return true;
}
return false;
}
public function onUpdate($type){
if($type === Level::BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->getID() === self::AIR){ //Replace with common break method
//TODO
//Server::getInstance()->api->entity->drop($this, Item::get($this->id, $this->meta, 1));
$this->level->setBlock($this, new Air(), true, false, true);
return Level::BLOCK_UPDATE_NORMAL;
}
}
return false;
}
}

View File

@ -0,0 +1,93 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\level\Level;
use pocketmine\Player;
class Carrot extends Flowable{
public function __construct($meta = 0){
parent::__construct(self::CARROT_BLOCK, $meta, "Carrot Block");
$this->isActivable = true;
$this->hardness = 0;
}
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
$down = $this->getSide(0);
if($down->getID() === self::FARMLAND){
$this->level->setBlock($block, $this, true, false, true);
return true;
}
return false;
}
public function onActivate(Item $item, Player $player = null){
if($item->getID() === Item::DYE and $item->getMetadata() === 0x0F){ //Bonemeal
$this->meta = 0x07;
$this->level->setBlock($this, $this, true, false, true);
$item->count--;
return true;
}
return false;
}
public function onUpdate($type){
if($type === Level::BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
//TODO
//Server::getInstance()->api->entity->drop($this, Item::get(CARROT, 0, 1));
$this->level->setBlock($this, new Air(), false, false, true);
return Level::BLOCK_UPDATE_NORMAL;
}
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
if(mt_rand(0, 2) == 1){
if($this->meta < 0x07){
++$this->meta;
$this->level->setBlock($this, $this, true, false, true);
return Level::BLOCK_UPDATE_RANDOM;
}
}else{
return Level::BLOCK_UPDATE_RANDOM;
}
}
return false;
}
public function getDrops(Item $item){
$drops = array();
if($this->meta >= 0x07){
$drops[] = array(Item::CARROT, 0, mt_rand(1, 4));
}else{
$drops[] = array(Item::CARROT, 0, 1);
}
return $drops;
}
}

View File

@ -0,0 +1,149 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\Compound;
use pocketmine\nbt\tag\Enum;
use pocketmine\nbt\tag\Int;
use pocketmine\nbt\tag\String;
use pocketmine\Player;
use pocketmine\tile\Chest as TileChest;
use pocketmine\tile\Tile;
class Chest extends Transparent{
const SLOTS = 27;
public function __construct($meta = 0){
parent::__construct(self::CHEST, $meta, "Chest");
$this->isActivable = true;
$this->hardness = 15;
}
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
$faces = array(
0 => 4,
1 => 2,
2 => 5,
3 => 3,
);
$chest = false;
$this->meta = $faces[$player instanceof Player ? $player->getDirection() : 0];
for($side = 2; $side <= 5; ++$side){
if(($this->meta === 4 or $this->meta === 5) and ($side === 4 or $side === 5)){
continue;
}elseif(($this->meta === 3 or $this->meta === 2) and ($side === 2 or $side === 3)){
continue;
}
$c = $this->getSide($side);
if(($c instanceof TileChest) and $c->getMetadata() === $this->meta){
if((($tile = $this->level->getTile($c)) instanceof TileChest) and !$tile->isPaired()){
$chest = $tile;
break;
}
}
}
$this->level->setBlock($block, $this, true, false, true);
$nbt = new Compound(false, array(
new Enum("Items", array()),
new String("id", Tile::CHEST),
new Int("x", $this->x),
new Int("y", $this->y),
new Int("z", $this->z)
));
$nbt->Items->setTagType(NBT::TAG_Compound);
$tile = new TileChest($this->level, $nbt);
if($chest instanceof TileChest){
$chest->pairWith($tile);
$tile->pairWith($chest);
}
return true;
}
public function onBreak(Item $item){
$t = $this->level->getTile($this);
if($t instanceof TileChest){
$t->unpair();
}
$this->level->setBlock($this, new Air(), true, true, true);
return true;
}
public function onActivate(Item $item, Player $player = null){
if($player instanceof Player){
$top = $this->getSide(1);
if($top->isTransparent !== true){
return true;
}
$t = $this->level->getTile($this);
$chest = false;
if($t instanceof TileChest){
$chest = $t;
}else{
$nbt = new Compound(false, array(
new Enum("Items", array()),
new String("id", Tile::CHEST),
new Int("x", $this->x),
new Int("y", $this->y),
new Int("z", $this->z)
));
$nbt->Items->setTagType(NBT::TAG_Compound);
$chest = new TileChest($this->level, $nbt);
}
if(($player->gamemode & 0x01) === 0x01){
return true;
}
$chest->openInventory($player);
}
return true;
}
public function getDrops(Item $item){
$drops = array(
array($this->id, 0, 1),
);
$t = $this->level->getTile($this);
if($t instanceof Chest){
for($s = 0; $s < Chest::SLOTS; ++$s){
$slot = $t->getSlot($s);
if($slot->getID() > Item::AIR and $slot->getCount() > 0){
$drops[] = array($slot->getID(), $slot->getMetadata(), $slot->getCount());
}
}
}
return $drops;
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,14 +19,19 @@
*
*/
class ClayBlock extends SolidBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
class Clay extends Solid{
public function __construct(){
parent::__construct(CLAY_BLOCK, 0, "Clay Block");
parent::__construct(self::CLAY_BLOCK, 0, "Clay Block");
$this->hardness = 3;
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
return array(
array(CLAY, 0, 4),
array(Item::CLAY, 0, 4),
);
}
}

View File

@ -0,0 +1,58 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
use pocketmine\item\Item;
class Coal extends Solid{
public function __construct(){
parent::__construct(self::COAL_BLOCK, 0, "Coal Block");
$this->hardness = 30;
}
public function getBreakTime(Item $item){
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){
if($item->isPickaxe() >= 1){
return array(
array(Item::COAL_BLOCK, 0, 1),
);
}else{
return array();
}
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,15 +19,17 @@
*
*/
class CoalOreBlock extends SolidBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
class CoalOre extends Solid{
public function __construct(){
parent::__construct(COAL_ORE, 0, "Coal Ore");
parent::__construct(self::COAL_ORE, 0, "Coal Ore");
$this->hardness = 15;
}
public function getBreakTime(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0x01){
return 0.20;
}
public function getBreakTime(Item $item){
switch($item->isPickaxe()){
case 5:
return 0.6;
@ -43,15 +45,15 @@ class CoalOreBlock extends SolidBlock{
return 15;
}
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
if($item->isPickaxe() >= 1){
return array(
array(COAL, 0, 1),
array(Item::COAL, 0, 1),
);
}else{
return array();
}
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,15 +19,17 @@
*
*/
class CobblestoneBlock extends SolidBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
class Cobblestone extends Solid{
public function __construct(){
parent::__construct(COBBLESTONE, 0, "Cobblestone");
parent::__construct(self::COBBLESTONE, 0, "Cobblestone");
$this->hardness = 30;
}
public function getBreakTime(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0x01){
return 0.20;
}
public function getBreakTime(Item $item){
switch($item->isPickaxe()){
case 5:
return 0.4;
@ -43,11 +45,11 @@ class CobblestoneBlock extends SolidBlock{
return 10;
}
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
if($item->isPickaxe() >= 1){
return array(
array(COBBLESTONE, 0, 1),
array(Item::COBBLESTONE, 0, 1),
);
}else{
return array();

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,9 +19,12 @@
*
*/
class CobblestoneStairsBlock extends StairBlock{
namespace pocketmine\block;
class CobblestoneStairs extends Stair{
public function __construct($meta = 0){
parent::__construct(COBBLESTONE_STAIRS, $meta, "Cobblestone Stairs");
parent::__construct(self::COBBLESTONE_STAIRS, $meta, "Cobblestone Stairs");
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,13 +19,19 @@
*
*/
class CobwebBlock extends FlowableBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
class Cobweb extends Flowable{
public function __construct(){
parent::__construct(COBWEB, 0, "Cobweb");
parent::__construct(self::COBWEB, 0, "Cobweb");
$this->isSolid = true;
$this->isFullBlock = false;
$this->hardness = 25;
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
return array();
}
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,28 +19,40 @@
*
*/
class BrownMushroomBlock extends FlowableBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\level\Level;
use pocketmine\Player;
class CyanFlower extends Flowable{
public function __construct(){
parent::__construct(BROWN_MUSHROOM, 0, "Brown Mushroom");
parent::__construct(self::CYAN_FLOWER, 0, "Cyan Flower");
$this->hardness = 0;
}
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
$down = $this->getSide(0);
if($down->getID() === 2 or $down->getID() === 3 or $down->getID() === 60){
$this->level->setBlock($block, $this, true, false, true);
return true;
}
return false;
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
if($type === Level::BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
ServerAPI::request()->api->entity->drop($this, BlockAPI::getItem($this->id));
$this->level->setBlock($this, new AirBlock(), false, false, true);
return BLOCK_UPDATE_NORMAL;
//TODO
//Server::getInstance()->api->entity->drop($this, Item::get($this->id));
$this->level->setBlock($this, new Air(), false, false, true);
return Level::BLOCK_UPDATE_NORMAL;
}
}
return false;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
$down = $this->getSide(0);
if($down->isTransparent === false){
$this->level->setBlock($block, $this, true, false, true);
return true;
}
return false;
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,28 +19,40 @@
*
*/
class CyanFlowerBlock extends FlowableBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\level\Level;
use pocketmine\Player;
class Dandelion extends Flowable{
public function __construct(){
parent::__construct(CYAN_FLOWER, 0, "Cyan Flower");
parent::__construct(self::DANDELION, 0, "Dandelion");
$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() === 2 or $down->getID() === 3 or $down->getID() === 60){
$this->level->setBlock($block, $this, true, false, true);
return true;
}
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
$down = $this->getSide(0);
if($down->getID() === 2 or $down->getID() === 3 or $down->getID() === 60){
$this->level->setBlock($block, $this, true, false, true);
return true;
}
return false;
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
if($type === Level::BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
ServerAPI::request()->api->entity->drop($this, BlockAPI::getItem($this->id));
$this->level->setBlock($this, new AirBlock(), false, false, true);
return BLOCK_UPDATE_NORMAL;
//TODO
//Server::getInstance()->api->entity->drop($this, Item::get($this->id));
$this->level->setBlock($this, new Air(), false, false, true);
return Level::BLOCK_UPDATE_NORMAL;
}
}
return false;
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,20 +19,27 @@
*
*/
class DeadBushBlock extends FlowableBlock{
namespace pocketmine\block;
use pocketmine\level\Level;
class DeadBush extends Flowable{
public function __construct(){
parent::__construct(DEAD_BUSH, 0, "Dead Bush");
$this->isReplaceable = true;
parent::__construct(self::DEAD_BUSH, 0, "Dead Bush");
//$this->isReplaceable = true;
$this->hardness = 0;
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
if($type === Level::BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
$this->level->setBlock($this, new AirBlock(), false, false, true);
return BLOCK_UPDATE_NORMAL;
$this->level->setBlock($this, new Air(), false, false, true);
return Level::BLOCK_UPDATE_NORMAL;
}
}
return false;
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,15 +19,17 @@
*
*/
class DiamondBlock extends SolidBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
class Diamond extends Solid{
public function __construct(){
parent::__construct(DIAMOND_BLOCK, 0, "Diamond Block");
parent::__construct(self::DIAMOND_BLOCK, 0, "Diamond Block");
$this->hardness = 30;
}
public function getBreakTime(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0x01){
return 0.20;
}
public function getBreakTime(Item $item){
switch($item->isPickaxe()){
case 5:
return 0.95;
@ -37,11 +39,11 @@ class DiamondBlock extends SolidBlock{
return 25;
}
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
if($item->isPickaxe() >= 4){
return array(
array(DIAMOND_BLOCK, 0, 1),
array(Item::DIAMOND_BLOCK, 0, 1),
);
}else{
return array();

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,15 +19,17 @@
*
*/
class DiamondOreBlock extends SolidBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
class DiamondOre extends Solid{
public function __construct(){
parent::__construct(DIAMOND_ORE, 0, "Diamond Ore");
parent::__construct(self::DIAMOND_ORE, 0, "Diamond Ore");
$this->hardness = 15;
}
public function getBreakTime(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0x01){
return 0.20;
}
public function getBreakTime(Item $item){
switch($item->isPickaxe()){
case 5:
return 0.6;
@ -37,11 +39,11 @@ class DiamondOreBlock extends SolidBlock{
return 15;
}
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
if($item->isPickaxe() >= 4){
return array(
array(DIAMOND, 0, 1),
array(Item::DIAMOND, 0, 1),
);
}else{
return array();

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,20 +19,26 @@
*
*/
class DirtBlock extends SolidBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\Player;
class Dirt extends Solid{
public function __construct(){
parent::__construct(DIRT, 0, "Dirt");
parent::__construct(self::DIRT, 0, "Dirt");
$this->isActivable = true;
$this->hardness = 2.5;
}
public function onActivate(Item $item, Player $player){
public function onActivate(Item $item, Player $player = null){
if($item->isHoe()){
if(($player->gamemode & 0x01) === 0){
$item->useOn($this);
}
$this->level->setBlock($this, BlockAPI::get(FARMLAND, 0), true, false, true);
$item->useOn($this);
$this->level->setBlock($this, Block::get(Item::FARMLAND, 0), true, false, true);
return true;
}
return false;
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,33 +19,43 @@
*
*/
class DoorBlock extends TransparentBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\level\Level;
use pocketmine\network\protocol\LevelEventPacket;
use pocketmine\Player;
abstract class Door extends Transparent{
public function __construct($id, $meta = 0, $name = "Unknown"){
parent::__construct($id, $meta, $name);
$this->isSolid = false;
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->getID() === AIR){ //Replace with common break method
$this->level->setBlock($this, new AirBlock(), false);
if($this->getSide(1) instanceof DoorBlock){
$this->level->setBlock($this->getSide(1), new AirBlock(), false);
if($type === Level::BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->getID() === self::AIR){ //Replace with common break method
$this->level->setBlock($this, new Air(), false);
if($this->getSide(1) instanceof Door){
$this->level->setBlock($this->getSide(1), new Air(), false);
}
return BLOCK_UPDATE_NORMAL;
return Level::BLOCK_UPDATE_NORMAL;
}
}
return false;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
if($face === 1){
$blockUp = $this->getSide(1);
$blockDown = $this->getSide(0);
if($blockUp->isReplaceable === false or $blockDown->isTransparent === true){
return false;
}
$direction = $player->entity->getDirection();
$direction = $player instanceof Player ? $player->getDirection() : 0;
$face = array(
0 => 3,
1 => 4,
@ -58,44 +68,71 @@ class DoorBlock extends TransparentBlock{
if($next->getID() === $this->id or ($next2->isTransparent === false and $next->isTransparent === true)){ //Door hinge
$metaUp |= 0x01;
}
$this->level->setBlock($blockUp, BlockAPI::get($this->id, $metaUp), true, false, true); //Top
$this->meta = $direction & 0x03;
$this->level->setBlock($blockUp, Block::get($this->id, $metaUp), true, false, true); //Top
$this->meta = $player->getDirection() & 0x03;
$this->level->setBlock($block, $this, true, false, true); //Bottom
return true;
return true;
}
return false;
}
public function onBreak(Item $item, Player $player){
public function onBreak(Item $item){
if(($this->meta & 0x08) === 0x08){
$down = $this->getSide(0);
if($down->getID() === $this->id){
$this->level->setBlock($down, new AirBlock(), true, false, true);
$this->level->setBlock($down, new Air(), true, false, true);
}
}else{
$up = $this->getSide(1);
if($up->getID() === $this->id){
$this->level->setBlock($up, new AirBlock(), true, false, true);
$this->level->setBlock($up, new Air(), true, false, true);
}
}
$this->level->setBlock($this, new AirBlock(), true, false, true);
$this->level->setBlock($this, new Air(), true, false, true);
return true;
}
public function onActivate(Item $item, Player $player){
public function onActivate(Item $item, Player $player = null){
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);
$this->level->setBlock($down, Block::get($this->id, $meta), true, false, true);
$players = $this->level->getUsingChunk($this->x >> 4, $this->z >> 4);
if($player instanceof Player){
unset($players[$player->CID]);
}
$pk = new LevelEventPacket;
$pk->x = $this->x;
$pk->y = $this->y;
$pk->z = $this->z;
$pk->evid = 1003;
$pk->data = 0;
Player::broadcastPacket($players, $pk);
return true;
}
return false;
}else{
$this->meta ^= 0x04;
$this->level->setBlock($this, $this, true, false, true);
$players = $this->level->getUsingChunk($this->x >> 4, $this->z >> 4);
if($player instanceof Player){
unset($players[$player->CID]);
}
$pk = new LevelEventPacket;
$pk->x = $this->x;
$pk->y = $this->y;
$pk->z = $this->z;
$pk->evid = 1003;
$pk->data = 0;
Player::broadcastPacket($players, $pk);
}
return true;
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,9 +19,13 @@
*
*/
class DoubleSlabBlock extends SolidBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
class DoubleSlab extends Solid{
public function __construct($meta = 0){
parent::__construct(DOUBLE_SLAB, $meta, "Double Slab");
parent::__construct(self::DOUBLE_SLAB, $meta, "Double Slab");
$names = array(
0 => "Stone",
1 => "Sandstone",
@ -29,16 +33,13 @@ 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){
if(($player->gamemode & 0x01) === 0x01){
return 0.20;
}
public function getBreakTime(Item $item){
switch($item->isPickaxe()){
case 5:
return 0.4;
@ -54,15 +55,15 @@ class DoubleSlabBlock extends SolidBlock{
return 10;
}
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
if($item->isPickaxe() >= 1){
return array(
array(SLAB, $this->meta & 0x07, 2),
array(Item::SLAB, $this->meta & 0x07, 2),
);
}else{
return array();
}
}
}

View File

@ -0,0 +1,62 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
use pocketmine\item\Item;
class DoubleWoodSlab extends Solid{
public function __construct($meta = 0){
parent::__construct(self::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){
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){
return array(
array(Item::WOOD_SLAB, $this->meta & 0x07, 2),
);
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,15 +19,24 @@
*
*/
class FallableBlock extends SolidBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\level\Level;
use pocketmine\Player;
use pocketmine\Server;
class Fallable extends Solid{
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){
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
$ret = $this->level->setBlock($this, $this, true, false, true);
ServerAPI::request()->api->block->blockUpdate(clone $this, BLOCK_UPDATE_NORMAL);
Server::getInstance()->api->block->blockUpdate(clone $this, Level::BLOCK_UPDATE_NORMAL);
return $ret;
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,13 +19,19 @@
*
*/
class FarmlandBlock extends SolidBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
class Farmland extends Solid{
public function __construct($meta = 0){
parent::__construct(FARMLAND, $meta, "Farmland");
parent::__construct(self::FARMLAND, $meta, "Farmland");
$this->hardness = 3;
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
return array(
array(DIRT, 0, 1),
array(Item::DIRT, 0, 1),
);
}
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,10 +19,14 @@
*
*/
class FenceBlock extends TransparentBlock{
namespace pocketmine\block;
class Fence extends Transparent{
public function __construct(){
parent::__construct(FENCE, 0, "Fence");
parent::__construct(self::FENCE, 0, "Fence");
$this->isFullBlock = false;
$this->hardness = 15;
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,46 +19,57 @@
*
*/
class FenceGateBlock extends TransparentBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\Player;
class FenceGate extends Transparent{
public function __construct($meta = 0){
parent::__construct(FENCE_GATE, $meta, "Fence Gate");
parent::__construct(self::FENCE_GATE, $meta, "Fence Gate");
$this->isActivable = true;
if(($this->meta & 0x04) === 0x04){
$this->isFullBlock = true;
}else{
$this->isFullBlock = false;
}
$this->hardness = 15;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
$faces = array(
0 => 3,
1 => 0,
2 => 1,
3 => 2,
);
$this->meta = $faces[$player->entity->getDirection()] & 0x03;
$this->meta = $faces[$player instanceof Player ? $player->getDirection() : 0] & 0x03;
$this->level->setBlock($block, $this, true, false, true);
return true;
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
return array(
array($this->id, 0, 1),
);
}
public function onActivate(Item $item, Player $player){
public function onActivate(Item $item, Player $player = null){
$faces = array(
0 => 3,
1 => 0,
2 => 1,
3 => 2,
);
$this->meta = ($faces[$player->entity->getDirection()] & 0x03) | ((~$this->meta) & 0x04);
$this->meta = ($faces[$player instanceof Player ? $player->getDirection() : 0] & 0x03) | ((~$this->meta) & 0x04);
if(($this->meta & 0x04) === 0x04){
$this->isFullBlock = true;
}else{
$this->isFullBlock = false;
}
$this->level->setBlock($this, $this, true, false, true);
return true;
}
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,35 +19,44 @@
*
*/
class FireBlock extends FlowableBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\level\Level;
class Fire extends Flowable{
public function __construct($meta = 0){
parent::__construct(FIRE, $meta, "Fire");
parent::__construct(self::FIRE, $meta, "Fire");
$this->isReplaceable = true;
$this->breakable = false;
$this->isFullBlock = true;
$this->hardness = 0;
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
return array();
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
if($type === Level::BLOCK_UPDATE_NORMAL){
for($s = 0; $s <= 5; ++$s){
$side = $this->getSide($s);
if($side->getID() !== AIR and !($side instanceof LiquidBlock)){
if($side->getID() !== self::AIR and !($side instanceof Liquid)){
return false;
}
}
$this->level->setBlock($this, new AirBlock(), true, false, true);
return BLOCK_UPDATE_NORMAL;
}elseif($type === BLOCK_UPDATE_RANDOM){
if($this->getSide(0)->getID() !== NETHERRACK){
$this->level->setBlock($this, new AirBlock(), true, false, true);
return BLOCK_UPDATE_NORMAL;
$this->level->setBlock($this, new Air(), true, false, true);
return Level::BLOCK_UPDATE_NORMAL;
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
if($this->getSide(0)->getID() !== self::NETHERRACK){
$this->level->setBlock($this, new Air(), true, false, true);
return Level::BLOCK_UPDATE_NORMAL;
}
}
return false;
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,7 +19,10 @@
*
*/
class FlowableBlock extends TransparentBlock{
namespace pocketmine\block;
class Flowable extends Transparent{
public function __construct($id, $meta = 0, $name = "Unknown"){
parent::__construct($id, $meta, $name);
$this->isFlowable = true;

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,15 +19,13 @@
*
*/
/***REM_START***/
require_once("BurningFurnace.php");
/***REM_END***/
namespace pocketmine\block;
class FurnaceBlock extends BurningFurnaceBlock{
class Furnace extends BurningFurnace{
public function __construct($meta = 0){
parent::__construct($meta);
$this->id = FURNACE;
$this->id = self::FURNACE;
$this->name = "Furnace";
$this->isActivable = true;
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,45 +19,61 @@
*
*/
namespace pocketmine\block;
class GenericBlock extends Block{
use pocketmine\item\Item;
use pocketmine\level\Level;
use pocketmine\Player;
use pocketmine\Server;
class Generic extends Block{
/**
* @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){
}
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
return $this->level->setBlock($this, $this, true, false, true);
}
public function isBreakable(Item $item, Player $player){
return ($this->breakable);
public function isBreakable(Item $item){
return $this->breakable;
}
public function onBreak(Item $item, Player $player){
return $this->level->setBlock($this, new AirBlock(), true, false, true);
public function onBreak(Item $item){
return $this->level->setBlock($this, new Air(), true, false, true);
}
public function onUpdate($type){
if($this->hasPhysics === true and $type === BLOCK_UPDATE_NORMAL){
if($this->hasPhysics === true and $type === Level::BLOCK_UPDATE_NORMAL){
$down = $this->getSide(0);
if($down->getID() === AIR or ($down instanceof LiquidBlock)){
if($down->getID() === self::AIR or ($down instanceof Liquid)){
$data = array(
"x" => $this->x + 0.5,
"y" => $this->y + 0.5,
"z" => $this->z + 0.5,
"Tile" => $this->id,
);
$server = ServerAPI::request();
$this->level->setBlock($this, new AirBlock(), false, false, true);
$e = $server->api->entity->add($this->level, ENTITY_FALLING, FALLING_SAND, $data);
$server->api->entity->spawnToAll($e);
$server->api->block->blockUpdateAround(clone $this, BLOCK_UPDATE_NORMAL, 1);
$server = Server::getInstance();
$this->level->setBlock($this, new Air(), false, false, true);
//TODO
//$e = $server->api->entity->add($this->level, ENTITY_FALLING, FALLING_SAND, $data);
//$e->spawnToAll();
$server->api->block->blockUpdateAround(clone $this, Level::BLOCK_UPDATE_NORMAL, 1);
}
return false;
}
return false;
}
public function onActivate(Item $item, Player $player){
public function onActivate(Item $item, Player $player = null){
return $this->isActivable;
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,12 +19,17 @@
*
*/
class GlassBlock extends TransparentBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
class Glass extends Transparent{
public function __construct(){
parent::__construct(GLASS, 0, "Glass");
parent::__construct(self::GLASS, 0, "Glass");
$this->hardness = 1.5;
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
return array();
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,9 +19,14 @@
*
*/
class GlassPaneBlock extends TransparentBlock{
namespace pocketmine\block;
class GlassPane extends Transparent{
public function __construct(){
parent::__construct(GLASS_PANE, 0, "Glass Pane");
parent::__construct(self::GLASS_PANE, 0, "Glass Pane");
$this->isFullBlock = false;
$this->isSolid = false;
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,9 +19,12 @@
*
*/
class GlowingObsidianBlock extends SolidBlock{
namespace pocketmine\block;
class GlowingObsidian extends Solid{
public function __construct($meta = 0){
parent::__construct(GLOWING_OBSIDIAN, $meta, "Glowing Obsidian");
parent::__construct(self::GLOWING_OBSIDIAN, $meta, "Glowing Obsidian");
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,26 +19,29 @@
*
*/
class GlowingRedstoneOreBlock extends SolidBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\level\Level;
class GlowingRedstoneOre extends Solid{
public function __construct(){
parent::__construct(GLOWING_REDSTONE_ORE, 0, "Glowing Redstone Ore");
parent::__construct(self::GLOWING_REDSTONE_ORE, 0, "Glowing Redstone Ore");
$this->hardness = 15;
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_SCHEDULED or $type === BLOCK_UPDATE_RANDOM){
$this->level->setBlock($this, BlockAPI::get(REDSTONE_ORE, $this->meta), false, false, true);
return BLOCK_UPDATE_WEAK;
}else{
$this->level->scheduleBlockUpdate(new Position($this, 0, 0, $this->level), Utils::getRandomUpdateTicks(), BLOCK_UPDATE_RANDOM);
if($type === Level::BLOCK_UPDATE_SCHEDULED or $type === Level::BLOCK_UPDATE_RANDOM){
$this->level->setBlock($this, Block::get(Item::REDSTONE_ORE, $this->meta), false, false, true);
return Level::BLOCK_UPDATE_WEAK;
}
return false;
}
public function getBreakTime(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0x01){
return 0.20;
}
public function getBreakTime(Item $item){
switch($item->isPickaxe()){
case 5:
return 0.6;
@ -48,15 +51,15 @@ class GlowingRedstoneOreBlock extends SolidBlock{
return 15;
}
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
if($item->isPickaxe() >= 4){
return array(
//array(331, 4, mt_rand(4, 5)),
array(Item::REDSTONE_DUST, 0, mt_rand(4, 5)),
);
}else{
return array();
}
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,20 +19,19 @@
*
*/
class GravelBlock extends FallableBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
class Glowstone extends Transparent{
public function __construct(){
parent::__construct(GRAVEL, 0, "Gravel");
parent::__construct(self::GLOWSTONE_BLOCK, 0, "Glowstone");
$this->hardness = 1.5;
}
public function getDrops(Item $item, Player $player){
if(mt_rand(1,10) === 1){
return array(
array(FLINT, 0, 1),
);
}
public function getDrops(Item $item){
return array(
array(GRAVEL, 0, 1),
array(Item::GLOWSTONE_DUST, 0, mt_rand(2, 4)),
);
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,15 +19,17 @@
*
*/
class GoldBlock extends SolidBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
class Gold extends Solid{
public function __construct(){
parent::__construct(GOLD_BLOCK, 0, "Gold Block");
parent::__construct(self::GOLD_BLOCK, 0, "Gold Block");
$this->hardness = 30;
}
public function getBreakTime(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0x01){
return 0.20;
}
public function getBreakTime(Item $item){
switch($item->isPickaxe()){
case 5:
return 0.6;
@ -37,11 +39,11 @@ class GoldBlock extends SolidBlock{
return 15;
}
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
if($item->isPickaxe() >= 4){
return array(
array(GOLD_BLOCK, 0, 1),
array(Item::GOLD_BLOCK, 0, 1),
);
}else{
return array();

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,15 +19,17 @@
*
*/
class GoldOreBlock extends SolidBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
class GoldOre extends Solid{
public function __construct(){
parent::__construct(GOLD_ORE, 0, "Gold Ore");
parent::__construct(self::GOLD_ORE, 0, "Gold Ore");
$this->hardness = 15;
}
public function getBreakTime(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0x01){
return 0.20;
}
public function getBreakTime(Item $item){
switch($item->isPickaxe()){
case 5:
return 0.6;
@ -37,11 +39,11 @@ class GoldOreBlock extends SolidBlock{
return 15;
}
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
if($item->isPickaxe() >= 4){
return array(
array(GOLD_ORE, 0, 1),
array(Item::GOLD_ORE, 0, 1),
);
}else{
return array();

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,31 +19,39 @@
*
*/
class GrassBlock extends SolidBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\level\generator\object\TallGrass;
use pocketmine\Player;
use pocketmine\utils\Random;
class Grass extends Solid{
public function __construct(){
parent::__construct(GRASS, 0, "Grass");
parent::__construct(self::GRASS, 0, "Grass");
$this->isActivable = true;
$this->hardness = 3;
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
return array(
array(DIRT, 0, 1),
array(Item::DIRT, 0, 1),
);
}
public function onActivate(Item $item, Player $player){
if($item->getID() === DYE and $item->getMetadata() === 0x0F){
if(($player->gamemode & 0x01) === 0){
$item->count--;
}
TallGrassObject::growGrass($this->level, $this, new Random());
public function onActivate(Item $item, Player $player = null){
if($item->getID() === Item::DYE and $item->getMetadata() === 0x0F){
$item->count--;
TallGrass::growGrass($this->level, $this, new Random(), 8, 2);
return true;
}elseif($item->isHoe()){
if(($player->gamemode & 0x01) === 0){
$item->useOn($this);
}
$this->level->setBlock($this, new FarmlandBlock());
$item->useOn($this);
$this->level->setBlock($this, new Farmland());
return true;
}
return false;
}
}

View File

@ -0,0 +1,44 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
use pocketmine\item\Item;
class Gravel extends Fallable{
public function __construct(){
parent::__construct(self::GRAVEL, 0, "Gravel");
$this->hardness = 3;
}
public function getDrops(Item $item){
if(mt_rand(1, 10) === 1){
return array(
array(Item::FLINT, 0, 1),
);
}
return array(
array(Item::GRAVEL, 0, 1),
);
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,31 +19,37 @@
*
*/
class LadderBlock extends TransparentBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\Player;
class HayBale extends Solid{
public function __construct($meta = 0){
parent::__construct(LADDER, $meta, "Ladder");
$this->isSolid = false;
$this->isFullBlock = false;
parent::__construct(self::HAY_BALE, $meta, "Hay Bale");
$this->hardness = 10;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
if($target->isTransparent === false){
$faces = array(
2 => 2,
3 => 3,
4 => 4,
5 => 5,
);
if(isset($faces[$face])){
$this->meta = $faces[$face];
$this->level->setBlock($block, $this, true, false, true);
return true;
}
}
return false;
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
$faces = array(
0 => 0,
1 => 0,
2 => 0b1000,
3 => 0b1000,
4 => 0b0100,
5 => 0b0100,
);
$this->meta = ($this->meta & 0x03) | $faces[$face];
$this->level->setBlock($block, $this, true, false, true);
return true;
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
return array(
array($this->id, 0, 1),
);
}
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,24 +19,23 @@
*
*/
class IceBlock extends TransparentBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
class Ice extends Transparent{
public function __construct(){
parent::__construct(ICE, 0, "Ice");
parent::__construct(self::ICE, 0, "Ice");
$this->hardness = 2.5;
}
public function onBreak(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0){
$this->level->setBlock($this, new WaterBlock(), true, false, true);
}else{
$this->level->setBlock($this, new AirBlock(), true, false, true);
}
public function onBreak(Item $item){
$this->level->setBlock($this, new Water(), true, false, true);
return true;
}
public function getBreakTime(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0x01){
return 0.20;
}
public function getBreakTime(Item $item){
switch($item->isPickaxe()){
case 5:
return 0.1;
@ -53,7 +52,7 @@ class IceBlock extends TransparentBlock{
}
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
return array();
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,15 +19,17 @@
*
*/
class IronBlock extends SolidBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
class Iron extends Solid{
public function __construct(){
parent::__construct(IRON_BLOCK, 0, "Iron Block");
parent::__construct(self::IRON_BLOCK, 0, "Iron Block");
$this->hardness = 30;
}
public function getBreakTime(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0x01){
return 0.20;
}
public function getBreakTime(Item $item){
switch($item->isPickaxe()){
case 5:
return 0.95;
@ -39,11 +41,11 @@ class IronBlock extends SolidBlock{
return 25;
}
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
if($item->isPickaxe() >= 3){
return array(
array(IRON_BLOCK, 0, 1),
array(Item::IRON_BLOCK, 0, 1),
);
}else{
return array();

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,16 +19,14 @@
*
*/
define("WINDOW_CHEST", 0);
define("WINDOW_WORKBENCH", 1);
define("WINDOW_FURNACE", 2);
define("WINDOW_STONECUTTER", 3);
namespace pocketmine\block;
class Window{
private $server;
class IronBars extends Transparent{
public function __construct(){
$this->server = ServerAPI::request();
parent::__construct(self::IRON_BARS, 0, "Iron Bars");
$this->isFullBlock = false;
$this->isSolid = false;
}
}
?>
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,16 +19,18 @@
*
*/
class IronDoorBlock extends DoorBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
class IronDoor extends Door{
public function __construct($meta = 0){
parent::__construct(IRON_DOOR_BLOCK, $meta, "Iron Door Block");
parent::__construct(self::IRON_DOOR_BLOCK, $meta, "Iron Door Block");
//$this->isActivable = true;
$this->hardness = 25;
}
public function getBreakTime(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0x01){
return 0.20;
}
public function getBreakTime(Item $item){
switch($item->isPickaxe()){
case 5:
return 0.95;
@ -44,11 +46,11 @@ class IronDoorBlock extends DoorBlock{
return 25;
}
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
if($item->isPickaxe() >= 1){
return array(
array(IRON_DOOR, 0, 1),
array(Item::IRON_DOOR, 0, 1),
);
}else{
return array();

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,15 +19,17 @@
*
*/
class IronOreBlock extends SolidBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
class IronOre extends Solid{
public function __construct(){
parent::__construct(IRON_ORE, 0, "Iron Ore");
parent::__construct(self::IRON_ORE, 0, "Iron Ore");
$this->hardness = 15;
}
public function getBreakTime(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0x01){
return 0.20;
}
public function getBreakTime(Item $item){
switch($item->isPickaxe()){
case 5:
return 0.6;
@ -39,11 +41,11 @@ class IronOreBlock extends SolidBlock{
return 15;
}
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
if($item->isPickaxe() >= 3){
return array(
array(IRON_ORE, 0, 1),
array(Item::IRON_ORE, 0, 1),
);
}else{
return array();

View File

@ -0,0 +1,36 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
use pocketmine\item\Item;
class JungleWoodStairs extends Stair{
public function __construct($meta = 0){
parent::__construct(self::JUNGLE_WOOD_STAIRS, $meta, "Jungle Wood Stairs");
}
public function getDrops(Item $item){
return array(
array($this->id, 0, 1),
);
}
}

View File

@ -0,0 +1,72 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\level\Level;
use pocketmine\Player;
class Ladder extends Transparent{
public function __construct($meta = 0){
parent::__construct(self::LADDER, $meta, "Ladder");
$this->isSolid = false;
$this->isFullBlock = false;
$this->hardness = 2;
}
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
if($target->isTransparent === false){
$faces = array(
2 => 2,
3 => 3,
4 => 4,
5 => 5,
);
if(isset($faces[$face])){
$this->meta = $faces[$face];
$this->level->setBlock($block, $this, true, false, true);
return true;
}
}
return false;
}
public function onUpdate($type){
if($type === Level::BLOCK_UPDATE_NORMAL){
/*if($this->getSide(0)->getID() === self::AIR){ //Replace with common break method
Server::getInstance()->api->entity->drop($this, Item::get(LADDER, 0, 1));
$this->level->setBlock($this, new Air(), true, true, true);
return Level::BLOCK_UPDATE_NORMAL;
}*/
}
return false;
}
public function getDrops(Item $item){
return array(
array($this->id, 0, 1),
);
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,15 +19,17 @@
*
*/
class LapisBlock extends SolidBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
class Lapis extends Solid{
public function __construct(){
parent::__construct(LAPIS_BLOCK, 0, "Lapis Block");
parent::__construct(self::LAPIS_BLOCK, 0, "Lapis Block");
$this->hardness = 15;
}
public function getBreakTime(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0x01){
return 0.20;
}
public function getBreakTime(Item $item){
switch($item->isPickaxe()){
case 5:
return 0.6;
@ -39,11 +41,11 @@ class LapisBlock extends SolidBlock{
return 15;
}
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
if($item->isPickaxe() >= 3){
return array(
array(LAPIS_BLOCK, 0, 1),
array(Item::LAPIS_BLOCK, 0, 1),
);
}else{
return array();

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,15 +19,18 @@
*
*/
class LapisOreBlock extends SolidBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
class LapisOre extends Solid{
public function __construct(){
parent::__construct(LAPIS_ORE, 0, "Lapis Ore");
parent::__construct(self::LAPIS_ORE, 0, "Lapis Ore");
$this->hardness = 15;
}
public function getBreakTime(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0x01){
return 0.20;
}
public function getBreakTime(Item $item){
switch($item->isPickaxe()){
case 5:
return 0.6;
@ -40,14 +43,14 @@ class LapisOreBlock extends SolidBlock{
}
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
if($item->isPickaxe() >= 3){
return array(
array(DYE, 4, mt_rand(4, 8)),
array(Item::DYE, 4, mt_rand(4, 8)),
);
}else{
return array();
}
}
}

View File

@ -0,0 +1,154 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\level\Level;
use pocketmine\level\Position;
use pocketmine\Player;
use pocketmine\Server;
class Lava extends Liquid{
public function __construct($meta = 0){
parent::__construct(self::LAVA, $meta, "Lava");
$this->hardness = 0;
}
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
$ret = $this->level->setBlock($this, $this, true, false, true);
Server::getInstance()->api->block->scheduleBlockUpdate(clone $this, 40, Level::BLOCK_UPDATE_NORMAL);
return $ret;
}
public function getSourceCount(){
$count = 0;
for($side = 2; $side <= 5; ++$side){
if($this->getSide($side) instanceof Lava){
$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 Water){
$level = $this->meta & 0x07;
if($level == 0x00){
$this->level->setBlock($this, new Obsidian(), false, false, true);
}else{
$this->level->setBlock($this, new Cobblestone(), false, false, true);
}
}
}
}
public function getFrom(){
for($side = 0; $side <= 5; ++$side){
$b = $this->getSide($side);
if($b instanceof Lava){
$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 !== Level::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 Air || $down instanceof Lava){
$this->level->setBlock($down, new Lava(0x01), false, false, true);
Server::getInstance()->api->block->scheduleBlockUpdate(new Position($down, 0, 0, $this->level), 40, Level::BLOCK_UPDATE_NORMAL);
}else{
for($side = 2; $side <= 5; ++$side){
$b = $this->getSide($side);
if($b instanceof Lava){
}elseif($b->isFlowable === true){
$this->level->setBlock($b, new Lava(min($level + 2, 7)), false, false, true);
Server::getInstance()->api->block->scheduleBlockUpdate(Position::fromObject($b, $this->level), 40, Level::BLOCK_UPDATE_NORMAL);
}
}
}
}
}else{
//Extend Remove for Left Lavas
for($side = 2; $side <= 5; ++$side){
$sb = $this->getSide($side);
if($sb instanceof Lava){
$tlevel = $sb->meta & 0x07;
if($tlevel != 0x00){
for($s = 0; $s <= 5; $s++){
$ssb = $sb->getSide($s);
Server::getInstance()->api->block->scheduleBlockUpdate(Position::fromObject($ssb, $this->level), 40, Level::BLOCK_UPDATE_NORMAL);
}
$this->level->setBlock($sb, new Air(), false, false, true);
}
}
$b = $this->getSide(0)->getSide($side);
if($b instanceof Lava){
$tlevel = $b->meta & 0x07;
if($tlevel != 0x00){
for($s = 0; $s <= 5; $s++){
$ssb = $sb->getSide($s);
Server::getInstance()->api->block->scheduleBlockUpdate(Position::fromObject($ssb, $this->level), 40, Level::BLOCK_UPDATE_NORMAL);
}
$this->level->setBlock($b, new Air(), false, false, true);
}
}
//Server::getInstance()->api->block->scheduleBlockUpdate(Position::fromObject($b, $this->level), 10, Level::BLOCK_UPDATE_NORMAL);
}
$this->level->setBlock($this, new Air(), false, false, true);
}
return false;
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,33 +19,42 @@
*
*/
class LeavesBlock extends TransparentBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\level\Level;
use pocketmine\Player;
class Leaves extends Transparent{
const OAK = 0;
const SPRUCE = 1;
const BIRCH = 2;
const JUNGLE = 3;
public function __construct($meta = 0){
parent::__construct(LEAVES, $meta, "Leaves");
parent::__construct(self::LEAVES, $meta, "Leaves");
$names = array(
LeavesBlock::OAK => "Oak Leaves",
LeavesBlock::SPRUCE => "Spruce Leaves",
LeavesBlock::BIRCH => "Birch Leaves",
3 => "",
self::OAK => "Oak Leaves",
self::SPRUCE => "Spruce Leaves",
self::BIRCH => "Birch Leaves",
self::JUNGLE => "Jungle Leaves",
);
$this->name = $names[$this->meta & 0x03];
$this->hardness = 1;
}
private function findLog(Block $pos, array $visited, $distance, &$check, $fromSide = null){
++$check;
$index = $pos->x.".".$pos->y.".".$pos->z;
$index = $pos->x . "." . $pos->y . "." . $pos->z;
if(isset($visited[$index])){
return false;
}
if($pos->getID() === WOOD){
if($pos->getID() === self::WOOD){
return true;
}elseif($pos->getID() === LEAVES and $distance < 3){
}elseif($pos->getID() === self::LEAVES and $distance < 3){
$visited[$index] = true;
$down = $pos->getSide(0)->getID();
if($down === WOOD){
if($down === Item::WOOD){
return true;
}
if($fromSide === null){
@ -98,15 +107,14 @@ class LeavesBlock extends TransparentBlock{
return false;
}
public function onUpdate($type){
if($type === BLOCK_UPDATE_NORMAL){
if($type === Level::BLOCK_UPDATE_NORMAL){
if(($this->meta & 0b00001100) === 0){
$this->meta |= 0x08;
$this->level->setBlock($this, $this, false, false, true);
return BLOCK_UPDATE_RANDOM;
}
}elseif($type === BLOCK_UPDATE_RANDOM){
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
if(($this->meta & 0b00001100) === 0x08){
$this->meta &= 0x03;
$visited = array();
@ -114,37 +122,42 @@ class LeavesBlock extends TransparentBlock{
if($this->findLog($this, $visited, 0, $check) === true){
$this->level->setBlock($this, $this, false, false, true);
}else{
$this->level->setBlock($this, new AirBlock(), false, false, true);
if(mt_rand(1,20) === 1){ //Saplings
ServerAPI::request()->api->entity->drop($this, BlockAPI::getItem(SAPLING, $this->meta & 0x03, 1));
$this->level->setBlock($this, new Air(), false, false, true);
if(mt_rand(1, 20) === 1){ //Saplings
//TODO
//Server::getInstance()->api->entity->drop($this, Item::get(Item::SAPLING, $this->meta & 0x03, 1));
}
if(($this->meta & 0x03) === LeavesBlock::OAK and mt_rand(1,200) === 1){ //Apples
ServerAPI::request()->api->entity->drop($this, BlockAPI::getItem(APPLE, 0, 1));
if(($this->meta & 0x03) === self::OAK and mt_rand(1, 200) === 1){ //Apples
//TODO
//Server::getInstance()->api->entity->drop($this, Item::get(Item::APPLE, 0, 1));
}
return BLOCK_UPDATE_NORMAL;
return Level::BLOCK_UPDATE_NORMAL;
}
}
}
return false;
}
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
$this->meta |= 0x04;
$this->level->setBlock($this, $this, true, false, true);
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
$drops = array();
if($item->isShears()){
$drops[] = array(LEAVES, $this->meta & 0x03, 1);
$drops[] = array(Item::LEAVES, $this->meta & 0x03, 1);
}else{
if(mt_rand(1,20) === 1){ //Saplings
$drops[] = array(SAPLING, $this->meta & 0x03, 1);
if(mt_rand(1, 20) === 1){ //Saplings
$drops[] = array(Item::SAPLING, $this->meta & 0x03, 1);
}
if(($this->meta & 0x03) === LeavesBlock::OAK and mt_rand(1,200) === 1){ //Apples
$drops[] = array(APPLE, 0, 1);
if(($this->meta & 0x03) === self::OAK and mt_rand(1, 200) === 1){ //Apples
$drops[] = array(Item::APPLE, 0, 1);
}
}
return $drops;
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,7 +19,10 @@
*
*/
class LiquidBlock extends TransparentBlock{
namespace pocketmine\block;
class Liquid extends Transparent{
public function __construct($id, $meta = 0, $name = "Unknown"){
parent::__construct($id, $meta, $name);
$this->isLiquid = true;

View File

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

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,14 +19,19 @@
*
*/
class GlowstoneBlock extends TransparentBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
class Melon extends Transparent{
public function __construct(){
parent::__construct(GLOWSTONE_BLOCK, 0, "Glowstone");
parent::__construct(self::MELON_BLOCK, 0, "Melon Block");
$this->hardness = 5;
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
return array(
array(GLOWSTONE_DUST, 0, mt_rand(2, 4)),
array(Item::MELON_SLICE, 0, mt_rand(3, 7)),
);
}
}

View File

@ -0,0 +1,102 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\level\Level;
use pocketmine\Player;
class MelonStem extends Flowable{
public function __construct($meta = 0){
parent::__construct(self::MELON_STEM, $meta, "Melon Stem");
$this->isActivable = true;
$this->hardness = 0;
}
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
$down = $this->getSide(0);
if($down->getID() === self::FARMLAND){
$this->level->setBlock($block, $this, true, false, true);
return true;
}
return false;
}
public function onUpdate($type){
if($type === Level::BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
//TODO
//Server::getInstance()->api->entity->drop($this, Item::get(MELON_SEEDS, 0, mt_rand(0, 2)));
$this->level->setBlock($this, new Air(), false, false, true);
return Level::BLOCK_UPDATE_NORMAL;
}
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
if(mt_rand(0, 2) == 1){
if($this->meta < 0x07){
++$this->meta;
$this->level->setBlock($this, $this, true, false, true);
return Level::BLOCK_UPDATE_RANDOM;
}else{
for($side = 2; $side <= 5; ++$side){
$b = $this->getSide($side);
if($b->getID() === self::MELON_BLOCK){
return Level::BLOCK_UPDATE_RANDOM;
}
}
$side = $this->getSide(mt_rand(2, 5));
$d = $side->getSide(0);
if($side->getID() === self::AIR and ($d->getID() === self::FARMLAND or $d->getID() === self::GRASS or $d->getID() === self::DIRT)){
$this->level->setBlock($side, new Melon(), true, false, true);
}
}
}
return Level::BLOCK_UPDATE_RANDOM;
}
return false;
}
public function onActivate(Item $item, Player $player = null){
if($item->getID() === Item::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){
return array(
array(Item::MELON_SEEDS, 0, mt_rand(0, 2)),
);
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,15 +19,18 @@
*
*/
class MossStoneBlock extends SolidBlock{
public function __construct(){
parent::__construct(MOSS_STONE, 0, "Moss Stone");
namespace pocketmine\block;
use pocketmine\item\Item;
class MossStone extends Solid{
public function __construct($meta = 0){
parent::__construct(self::MOSS_STONE, $meta, "Moss Stone");
$this->hardness = 30;
}
public function getBreakTime(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0x01){
return 0.20;
}
public function getBreakTime(Item $item){
switch($item->isPickaxe()){
case 5:
return 0.4;
@ -43,11 +46,11 @@ class MossStoneBlock extends SolidBlock{
return 10;
}
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
if($item->isPickaxe() >= 1){
return array(
array(MOSS_STONE, 0, 1),
array(Item::MOSS_STONE, $this->meta, 1),
);
}else{
return array();

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,15 +19,18 @@
*
*/
class NetherBricksBlock extends SolidBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
class NetherBrick extends Solid{
public function __construct(){
parent::__construct(NETHER_BRICKS, 0, "Nether Bricks");
parent::__construct(self::NETHER_BRICKS, 0, "Nether Bricks");
$this->hardness = 30;
}
public function getBreakTime(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0x01){
return 0.20;
}
public function getBreakTime(Item $item){
switch($item->isPickaxe()){
case 5:
return 0.4;
@ -43,11 +46,11 @@ class NetherBricksBlock extends SolidBlock{
return 10;
}
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
if($item->isPickaxe() >= 1){
return array(
array(NETHER_BRICKS, 0, 1),
array(Item::NETHER_BRICKS, 0, 1),
);
}else{
return array();

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,9 +19,12 @@
*
*/
class WoodStairsBlock extends StairBlock{
namespace pocketmine\block;
class NetherBrickStairs extends Stair{
public function __construct($meta = 0){
parent::__construct(WOOD_STAIRS, $meta, "Wood Stairs");
parent::__construct(self::NETHER_BRICKS_STAIRS, $meta, "Nether Bricks Stairs");
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,10 +19,13 @@
*
*/
class NetherReactorBlock extends SolidBlock{
namespace pocketmine\block;
class NetherReactor extends Solid{
public function __construct($meta = 0){
parent::__construct(NETHER_REACTOR, $meta, "Nether Reactor");
parent::__construct(self::NETHER_REACTOR, $meta, "Nether Reactor");
$this->isActivable = true;
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,15 +19,18 @@
*
*/
class NetherrackBlock extends SolidBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
class Netherrack extends Solid{
public function __construct(){
parent::__construct(NETHERRACK, 0, "Netherrack");
parent::__construct(self::NETHERRACK, 0, "Netherrack");
$this->hardness = 2;
}
public function getBreakTime(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0x01){
return 0.20;
}
public function getBreakTime(Item $item){
switch($item->isPickaxe()){
case 5:
return 0.1;
@ -44,10 +47,10 @@ class NetherrackBlock extends SolidBlock{
}
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
if($item->isPickaxe() >= 1){
return array(
array(NETHERRACK, 0, 1),
array(Item::NETHERRACK, 0, 1),
);
}else{
return array();

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,27 +19,29 @@
*
*/
class ObsidianBlock extends SolidBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
class Obsidian extends Solid{
public function __construct(){
parent::__construct(OBSIDIAN, 0, "Obsidian");
parent::__construct(self::OBSIDIAN, 0, "Obsidian");
$this->hardness = 6000;
}
public function getBreakTime(Item $item, Player $player){
if(($player->gamemode & 0x01) === 0x01){
return 0.20;
}
public function getBreakTime(Item $item){
if($item->isPickaxe() >= 5){
return 9.4;
}else{
return 250;
}
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
if($item->isPickaxe() >= 5){
return array(
array(OBSIDIAN, 0, 1),
array(Item::OBSIDIAN, 0, 1),
);
}else{
return array();

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,20 +19,20 @@
*
*/
class WoodBlock extends SolidBlock{
const OAK = 0;
const SPRUCE = 1;
const BIRCH = 2;
namespace pocketmine\block;
class Planks extends Solid{
public function __construct($meta = 0){
parent::__construct(WOOD, $meta, "Wood");
parent::__construct(self::PLANKS, $meta, "Wooden Planks");
$names = array(
WoodBlock::OAK => "Oak Wood",
WoodBlock::SPRUCE => "Spruce Wood",
WoodBlock::BIRCH => "Birch Wood",
3 => "",
Wood::OAK => "Oak Wooden Planks",
Wood::SPRUCE => "Spruce Wooden Planks",
Wood::BIRCH => "Birch Wooden Planks",
Wood::JUNGLE => "Jungle Wooden Planks",
);
$this->meta &= 0x03;
$this->name = $names[$this->meta];
$this->name = $names[$this->meta & 0x03];
$this->hardness = 15;
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
@ -19,63 +19,77 @@
*
*/
class WheatBlock extends FlowableBlock{
namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\level\Level;
use pocketmine\Player;
class Potato extends Flowable{
public function __construct($meta = 0){
parent::__construct(WHEAT_BLOCK, $meta, "Wheat Block");
parent::__construct(self::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){
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
$down = $this->getSide(0);
if($down->getID() === FARMLAND){
if($down->getID() === self::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
public function onActivate(Item $item, Player $player = null){
if($item->getID() === Item::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($type === Level::BLOCK_UPDATE_NORMAL){
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
ServerAPI::request()->api->entity->drop($this, BlockAPI::getItem(WHEAT_SEEDS, 0, 1));
$this->level->setBlock($this, new AirBlock(), false, false, true);
return BLOCK_UPDATE_NORMAL;
//TODO
//Server::getInstance()->api->entity->drop($this, Item::get(POTATO, 0, 1));
$this->level->setBlock($this, new Air(), false, false, true);
return Level::BLOCK_UPDATE_NORMAL;
}
}elseif($type === BLOCK_UPDATE_RANDOM){
}elseif($type === Level::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;
return Level::BLOCK_UPDATE_RANDOM;
}
}else{
return BLOCK_UPDATE_RANDOM;
return Level::BLOCK_UPDATE_RANDOM;
}
}
return false;
}
public function getDrops(Item $item, Player $player){
public function getDrops(Item $item){
$drops = array();
if($this->meta >= 0x07){
$drops[] = array(WHEAT, 0, 1);
$drops[] = array(WHEAT_SEEDS, 0, mt_rand(0, 3));
$drops[] = array(Item::POTATO, 0, mt_rand(1, 4));
}else{
$drops[] = array(WHEAT_SEEDS, 0, 1);
$drops[] = array(Item::POTATO, 0, 1);
}
return $drops;
}
}

View File

@ -0,0 +1,31 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\block;
class Pumpkin extends Solid{
public function __construct(){
parent::__construct(self::PUMPKIN, "Pumpkin");
$this->hardness = 5;
}
}

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