mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-12 04:20:17 +00:00
Compare commits
274 Commits
Alpha_1.3.
...
Alpha_1.3.
Author | SHA1 | Date | |
---|---|---|---|
6a7b03e1bf | |||
8c648fc6f7 | |||
6c5356fc80 | |||
70445bdeba | |||
65767312a3 | |||
2551bd64ca | |||
1f360c8bfb | |||
65a7560185 | |||
860f723518 | |||
969f0f05b0 | |||
1ce7366cc3 | |||
3ed2155c5b | |||
1cc12616e8 | |||
e3d3f91c54 | |||
039edead18 | |||
a141ea5018 | |||
b63e49acf8 | |||
5dc52ad97d | |||
5eed43ddd0 | |||
9137a36b55 | |||
5623fa3601 | |||
78d72201ce | |||
d4057a2113 | |||
1eab1e382a | |||
351ac0d7af | |||
b457e63d20 | |||
7bc9500484 | |||
6d4472a339 | |||
050d3424f0 | |||
01e9ca7852 | |||
e2298d861c | |||
a8f2225c4c | |||
1a7e916928 | |||
2b0fdd5062 | |||
af8b380d10 | |||
90e598bb2c | |||
4d0eb5e529 | |||
02dc06c58b | |||
c23fc0057a | |||
1693f5655e | |||
565fe70c7e | |||
7cf662fb81 | |||
894325aef6 | |||
423ead6b64 | |||
a0a7042d43 | |||
14e1dda327 | |||
3cffa66490 | |||
2b28e26392 | |||
8543c06db4 | |||
adcf95f486 | |||
736c233e76 | |||
fd2eb7b230 | |||
bad8365e28 | |||
e9e59c33cc | |||
8532f53f8e | |||
230a3c00fc | |||
d515da8963 | |||
f5d69e6905 | |||
bcf6571cc2 | |||
7d0ff5e073 | |||
5e2de356bf | |||
2d67af6fbd | |||
bd8110edab | |||
25cd58bd99 | |||
a6cd8ece1b | |||
0bac7418db | |||
a4e38689db | |||
f3f61e7a4a | |||
bc48e70d6c | |||
b21ee37c07 | |||
2f7e5688e2 | |||
0d6ae6067c | |||
3337e5980e | |||
493b7532df | |||
bd0d708274 | |||
5ad72b4f49 | |||
7b9edffa47 | |||
6e9b70c9cb | |||
0f01570d01 | |||
cf5bc916c0 | |||
35119befd9 | |||
02150da862 | |||
2044269d86 | |||
2d3ba111e0 | |||
98097b0703 | |||
c4ba06b58c | |||
3e12a41a91 | |||
daaa9394c4 | |||
71a1986980 | |||
3352c36ba4 | |||
d2fa06cb64 | |||
0e9458fafc | |||
75e4174a2b | |||
509e67bfb7 | |||
0d25118eef | |||
c798a33363 | |||
5fc192b730 | |||
286b30cf4e | |||
a0fac71385 | |||
273a74d566 | |||
aefcab9a49 | |||
f5989d461c | |||
68076fedc8 | |||
2339525478 | |||
62f5f0d325 | |||
0ac81968b7 | |||
b8763a7a3f | |||
249e83db91 | |||
e6f855abbd | |||
75e1a6e97e | |||
fb9f7891c7 | |||
03e71ee3ff | |||
9cf91ca3fa | |||
fc7c14ae16 | |||
5ac0907aeb | |||
2f3817322b | |||
624219f680 | |||
646390812a | |||
7190d444e3 | |||
bfe0d04663 | |||
44d63c74dd | |||
d7d5e66de6 | |||
eb7d8a3240 | |||
698feccd54 | |||
d3e8cba132 | |||
2621aab2ef | |||
6ab29f993d | |||
d11cf83a47 | |||
336a40ae90 | |||
a8055eb59a | |||
2b920033ff | |||
8665035381 | |||
e0021b8927 | |||
44a9639150 | |||
e700179bb0 | |||
f8d8052ec3 | |||
0dc783f285 | |||
7cd5c5cde1 | |||
3968f3b298 | |||
9105e59f2a | |||
5ac92ee0db | |||
b5a53c04ac | |||
a93798719f | |||
1eda0d72a8 | |||
1331c8aeb2 | |||
b9e2576208 | |||
c25607588b | |||
ff8363e2ae | |||
64f7a78329 | |||
f377eacc0f | |||
8e452831e1 | |||
2483614459 | |||
53fd9cb466 | |||
1c5b473b36 | |||
918fb62ce9 | |||
1350e1bc4e | |||
5d53c259cf | |||
5a71043ab0 | |||
6ff6a5fc91 | |||
6de602a174 | |||
3ff4b9eae0 | |||
ae8c934b5f | |||
5803a4e649 | |||
78f7964d57 | |||
78f9e40730 | |||
a0ca572d1f | |||
af66e5a444 | |||
1ad00a453b | |||
5fa6c5962e | |||
de98dd920b | |||
1a0bccf288 | |||
e4221b8552 | |||
ba7c9503d8 | |||
3d53b9eb3a | |||
f32f379e97 | |||
809ca802b3 | |||
719df75886 | |||
14a40ac11e | |||
c973abc36f | |||
54d37a432e | |||
c7168a6c64 | |||
079d24055d | |||
b1748b5393 | |||
dafb12c3d3 | |||
b66f34b308 | |||
1cb711d32d | |||
94a9b7b431 | |||
7acdb0dd3f | |||
fe70fa467d | |||
d4a5e4e5c4 | |||
db289f9871 | |||
b822b314cb | |||
77ca6da14c | |||
9373c93737 | |||
cb47bf82c9 | |||
3498c876df | |||
df01e92ab6 | |||
1f1f955eef | |||
0e471ab38c | |||
9f211bd7fb | |||
af486917a1 | |||
c197a58a3a | |||
ca0d682d87 | |||
70ec644658 | |||
a860f16f4a | |||
9ac72026b9 | |||
0ad0071107 | |||
386b2cb0ef | |||
58fce0e939 | |||
780f60554d | |||
4aa0ae86fb | |||
f005b82a70 | |||
c35c004827 | |||
e179de1613 | |||
3354df0360 | |||
d8cfc06d3a | |||
3b0e553e17 | |||
c53ea830ea | |||
0c1afe15fd | |||
6a24700f6e | |||
000dfc8601 | |||
a011ad8fb6 | |||
d41c30945b | |||
b3c51c6d2e | |||
4ccaccc126 | |||
8aef462a68 | |||
c4a5a9c849 | |||
275e27f7a9 | |||
1abe7626bf | |||
7c9255e21e | |||
0c6eaa0609 | |||
1bc3b66afd | |||
df174d1b8e | |||
f56dd60708 | |||
2271d0b6fc | |||
6d2eea8887 | |||
fb2bcdb722 | |||
c8dd85de75 | |||
a00375b1a9 | |||
e7e05d37b3 | |||
6ac54925ff | |||
555da94612 | |||
774debb299 | |||
9b63a0b0bf | |||
397b47d719 | |||
5952e34995 | |||
0ddc48ca80 | |||
24211764ce | |||
4a2e3d3611 | |||
e5841e623e | |||
215141d552 | |||
94f8cfb59b | |||
41b1a0f991 | |||
08d93fa021 | |||
ce65801d14 | |||
bb9923d210 | |||
ccac35d5a2 | |||
c11ee468a2 | |||
e48126a0c9 | |||
b56ee69f0d | |||
4a46d8fd9c | |||
f29181a8ee | |||
8515e7ff33 | |||
9db1b741a7 | |||
401c201a97 | |||
fc3fb651b2 | |||
b4bfceeb6d | |||
a965103a03 | |||
f569587764 | |||
1a9641e93a | |||
b297ba16ed | |||
809076b7d7 | |||
56d829eec6 | |||
7f15b27ff0 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,6 +3,7 @@ worlds/*
|
||||
plugins/*
|
||||
logs/*
|
||||
bin/*
|
||||
.idea/*
|
||||
*.log
|
||||
*.pmf
|
||||
*.txt
|
||||
|
@ -1,14 +1,13 @@
|
||||

|
||||
|
||||
# PocketMine-MP Contribution Gidelines
|
||||
# PocketMine-MP Contribution Guidelines
|
||||
|
||||
Before contributing to PocketMine-MP, please read this.
|
||||
|
||||
|
||||
## I've a question
|
||||
* For questions, please refer to the _#mcpedevs_ IRC
|
||||
channel on Freenode. There is a [WebIRC](http://webchat.freenode.net?channels=mcpedevs&uio=d4) if you want.
|
||||
* You can ask directly to _[@PocketMine](https://twitter.com/PocketMine)_ in Twitter.
|
||||
* For questions, please refer to the _#pocketmine_ or _#mcpedevs_ IRC channel on Freenode. There is a [WebIRC](http://webchat.freenode.net?channels=pockdetmine,mcpedevs&uio=d4) if you want.
|
||||
* You can ask directly to _[@PocketMine](https://twitter.com/PocketMine)_ in Twitter, but don't expect an inmediate reply.
|
||||
|
||||
## I want to create an issue
|
||||
* First, use the [Issue Search](https://github.com/PocketMine/PocketMine-MP/search?ref=cmdform&type=Issues) to check if anyone has reported it.
|
||||
@ -19,9 +18,56 @@ Before contributing to PocketMine-MP, please read this.
|
||||
|
||||
## I want to contribute code
|
||||
* Use the [Pull Request](https://github.com/PocketMine/PocketMine-MP/pull/new) system, your request will be checked and discussed.
|
||||
* __Create a single branch for that pull request__
|
||||
* If you want to be part of PocketMine-MP, we will ask you to.
|
||||
* Code using the syntax as in PocketMine-MP.
|
||||
* Code using the syntax as in PocketMine-MP. See below for an example.
|
||||
* The code must be clear and written in English, comments included.
|
||||
|
||||
|
||||
__Thanks for contributing to PocketMine-MP!__
|
||||
|
||||
|
||||
|
||||
|
||||
#### Code syntax
|
||||
|
||||
It is mainly [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md) with a few exceptions.
|
||||
* Opening braces MUST go on the same line.
|
||||
* `else if` MUST be written as `elseif`. _(It is in PSR-2, but using a SHOULD)_
|
||||
* Control structure keywords or opening braces MUST NOT have one space after them.
|
||||
* Code MUST use tabs for indenting.
|
||||
* Long arrays MAY be split across multiple lines, where each subsequent line is indented once.
|
||||
* Files MUST use only the `<?php` tag.
|
||||
* Files MUST NOT have an ending `?>` tag.
|
||||
* Code MUST NOT use namespaces. _(This restriction will be lifted on the Alpha_1.4 code)_
|
||||
* Strings SHOULD use the double quote `"` except when the single quote is required.
|
||||
* Arrays SHOULD be declared using `array()`, not the `[]` shortcut.
|
||||
* Argument lists MAY NOT be split across multiple lines, except long arrays.
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
class ExampleClass{
|
||||
const EXAMPLE_CLASS_CONSTANT = 1;
|
||||
public $examplePublicVariable = "defaultValue";
|
||||
private $examplePrivateVariable;
|
||||
|
||||
public function __construct($firstArgument, &$secondArgument = null){
|
||||
if($firstArgument === "exampleValue"){ //Remember to use === instead == when possible
|
||||
//do things
|
||||
}elseif($firstArgument === "otherValue"){
|
||||
$secondArgument = function(){
|
||||
return array(
|
||||
0 => "value1",
|
||||
1 => "value2",
|
||||
2 => "value3",
|
||||
3 => "value4",
|
||||
4 => "value5",
|
||||
5 => "value6",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
```
|
@ -22,6 +22,7 @@
|
||||
|
||||
/***REM_START***/
|
||||
require_once(dirname(__FILE__)."/src/config.php");
|
||||
|
||||
require_once(FILE_PATH."/src/functions.php");
|
||||
require_once(FILE_PATH."/src/dependencies.php");
|
||||
/***REM_END***/
|
||||
@ -30,4 +31,4 @@ $server = new ServerAPI();
|
||||
$server->start();
|
||||
|
||||
kill(getmypid()); //Fix for ConsoleAPI being blocked
|
||||
exit(0);
|
||||
exit(0);
|
||||
|
@ -33,8 +33,8 @@ The entire server is done in PHP, and has been tested, profiled and optimized to
|
||||
|
||||
### [Twitter @PocketMine](https://twitter.com/PocketMine)
|
||||
|
||||
## IRC #pocketmine (or #mcpedevs) @ irc.freenode.net
|
||||
* [WebIRC](http://webchat.freenode.net?channels=pocketmine,mcpedevs&uio=d4)
|
||||
## IRC Chat #pocketmine (or #mcpedevs) @ irc.freenode.net
|
||||
[#pocketmine + #mcpedevs channel WebIRC](http://webchat.freenode.net/?channels=pocketmine,mcpedevs)
|
||||
|
||||
|
||||
## Third-party Libraries/Protocols Used
|
||||
@ -43,8 +43,8 @@ The entire server is done in PHP, and has been tested, profiled and optimized to
|
||||
* __[PHP BCMath](http://php.net/manual/en/book.bc.php)__
|
||||
* __[PHP pthreads](https://github.com/krakjoe/pthreads)__ by _[krakjoe](https://github.com/krakjoe)_: Threading for PHP - Share Nothing, Do Everything.
|
||||
* __[Spyc](https://github.com/mustangostang/spyc/blob/master/Spyc.php)__ by _[Vlad Andersen](https://github.com/mustangostang)_: A simple YAML loader/dumper class for PHP.
|
||||
* __[ANSICON](https://github.com/adoxa/ansicon)__ by _[Jason Hood](https://github.com/adoxa)_: Process ANSI escape sequences for Windows console programs.
|
||||
* __[mintty](https://code.google.com/p/mintty/)__ : xterm Terminal Emulator
|
||||
* __[cURL](http://curl.haxx.se/)__: cURL is a command line tool for transferring data with URL syntax
|
||||
* __[Zlib](http://www.zlib.net/)__: A Massively Spiffy Yet Delicately Unobtrusive Compression Library
|
||||
* __[Source RCON Protocol](https://developer.valvesoftware.com/wiki/Source_RCON_Protocol)__
|
||||
* __[UT3 Query Protocol](http://wiki.unrealadmin.org/UT3_query_protocol)__
|
||||
* __[UT3 Query Protocol](http://wiki.unrealadmin.org/UT3_query_protocol)__
|
||||
|
164
src/API/AchievementAPI.php
Normal file
164
src/API/AchievementAPI.php
Normal file
@ -0,0 +1,164 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
class AchievementAPI{
|
||||
public static $achievements = array(
|
||||
/*"openInventory" => array(
|
||||
"name" => "Taking Inventory",
|
||||
"requires" => array(),
|
||||
),*/
|
||||
"mineWood" => array(
|
||||
"name" => "Getting Wood",
|
||||
"requires" => array(
|
||||
//"openInventory",
|
||||
),
|
||||
),
|
||||
"buildWorkBench" => array(
|
||||
"name" => "Benchmarking",
|
||||
"requires" => array(
|
||||
"mineWood",
|
||||
),
|
||||
),
|
||||
"buildPickaxe" => array(
|
||||
"name" => "Time to Mine!",
|
||||
"requires" => array(
|
||||
"buildWorkBench",
|
||||
),
|
||||
),
|
||||
"buildFurnace" => array(
|
||||
"name" => "Hot Topic",
|
||||
"requires" => array(
|
||||
"buildPickaxe",
|
||||
),
|
||||
),
|
||||
"acquireIron" => array(
|
||||
"name" => "Acquire hardware",
|
||||
"requires" => array(
|
||||
"buildFurnace",
|
||||
),
|
||||
),
|
||||
"buildHoe" => array(
|
||||
"name" => "Time to Farm!",
|
||||
"requires" => array(
|
||||
"buildWorkBench",
|
||||
),
|
||||
),
|
||||
"makeBread" => array(
|
||||
"name" => "Bake Bread",
|
||||
"requires" => array(
|
||||
"buildHoe",
|
||||
),
|
||||
),
|
||||
"bakeCake" => array(
|
||||
"name" => "The Lie",
|
||||
"requires" => array(
|
||||
"buildHoe",
|
||||
),
|
||||
),
|
||||
"buildBetterPickaxe" => array(
|
||||
"name" => "Getting an Upgrade",
|
||||
"requires" => array(
|
||||
"buildPickaxe",
|
||||
),
|
||||
),
|
||||
"buildSword" => array(
|
||||
"name" => "Time to Strike!",
|
||||
"requires" => array(
|
||||
"buildWorkBench",
|
||||
),
|
||||
),
|
||||
"diamonds" => array(
|
||||
"name" => "DIAMONDS!",
|
||||
"requires" => array(
|
||||
"acquireIron",
|
||||
),
|
||||
),
|
||||
|
||||
);
|
||||
|
||||
function __construct(){
|
||||
}
|
||||
|
||||
public static function broadcastAchievement(Player $player, $achievementId){
|
||||
if(isset(self::$achievements[$achievementId])){
|
||||
$result = ServerAPI::request()->api->dhandle("achievement.broadcast", array("player" => $player, "achievementId" => $achievementId));
|
||||
if($result !== false and $result !== true){
|
||||
if(ServerAPI::request()->api->getProperty("announce-player-achievements") == true){
|
||||
ServerAPI::request()->api->chat->broadcast($player->username." has just earned the achievement ".self::$achievements[$achievementId]["name"]);
|
||||
}else{
|
||||
$player->sendChat("You have just earned the achievement ".self::$achievements[$achievementId]["name"]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function addAchievement($achievementId, $achievementName, array $requires = array()){
|
||||
if(!isset(self::$achievements[$achievementId])){
|
||||
self::$achievements[$achievementId] = array(
|
||||
"name" => $achievementName,
|
||||
"requires" => $requires,
|
||||
);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function hasAchievement(Player $player, $achievementId){
|
||||
if(!isset(self::$achievements[$achievementId]) or !isset($player->achievements)){
|
||||
$player->achievements = array();
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!isset($player->achievements[$achievementId]) or $player->achievements[$achievementId] == false){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function grantAchievement(Player $player, $achievementId){
|
||||
if(isset(self::$achievements[$achievementId]) and !self::hasAchievement($player, $achievementId)){
|
||||
foreach(self::$achievements[$achievementId]["requires"] as $requerimentId){
|
||||
if(!self::hasAchievement($player, $requerimentId)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(ServerAPI::request()->api->dhandle("achievement.grant", array("player" => $player, "achievementId" => $achievementId)) !== false){
|
||||
$player->achievements[$achievementId] = true;
|
||||
self::broadcastAchievement($player, $achievementId);
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function removeAchievement(Player $player, $achievementId){
|
||||
if(self::hasAchievement($player, $achievementId)){
|
||||
$player->achievements[$achievementId] = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function init(){
|
||||
}
|
||||
}
|
@ -21,9 +21,16 @@
|
||||
|
||||
class BanAPI{
|
||||
private $server;
|
||||
/*
|
||||
* I would use PHPDoc Template here but PHPStorm does not recognise it. - @sekjun9878
|
||||
*/
|
||||
/** @var Config */
|
||||
private $whitelist;
|
||||
/** @var Config */
|
||||
private $banned;
|
||||
/** @var Config */
|
||||
private $ops;
|
||||
/** @var Config */
|
||||
private $bannedIPs;
|
||||
private $cmdWL = array();//Command WhiteList
|
||||
function __construct(){
|
||||
@ -51,12 +58,20 @@ class BanAPI{
|
||||
$this->server->addHandler("player.block.place", array($this, "permissionsCheck"), 1);//Event handler for blocks
|
||||
$this->server->addHandler("player.flying", array($this, "permissionsCheck"), 1);//Flying Event
|
||||
}
|
||||
|
||||
public function cmdWhitelist($cmd){//Whitelists a CMD so everyone can issue it - Even non OPs.
|
||||
|
||||
/**
|
||||
* @param string $cmd Command to Whitelist
|
||||
*/
|
||||
public function cmdWhitelist($cmd){//Whitelists a CMD so everyone can issue it - Even non OPs.
|
||||
$this->cmdWhitelist[strtolower(trim($cmd))] = true;
|
||||
}
|
||||
|
||||
public function isOp($username){//Is a player op?
|
||||
|
||||
/**
|
||||
* @param string $username
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isOp($username){//Is a player op?
|
||||
$username = strtolower($username);
|
||||
if($this->server->api->dhandle("op.check", $username) === true){
|
||||
return true;
|
||||
@ -65,8 +80,14 @@ class BanAPI{
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function permissionsCheck($data, $event){
|
||||
|
||||
/**
|
||||
* @param mixed $data
|
||||
* @param string $event
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function permissionsCheck($data, $event){
|
||||
switch($event){
|
||||
case "player.flying"://OPs can fly around the server.
|
||||
if($this->isOp($data->iusername)){
|
||||
@ -100,8 +121,16 @@ class BanAPI{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function commandHandler($cmd, $params, $issuer, $alias){
|
||||
|
||||
/**
|
||||
* @param string $cmd
|
||||
* @param array $params
|
||||
* @param string $issuer
|
||||
* @param string $alias
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function commandHandler($cmd, $params, $issuer, $alias){
|
||||
$output = "";
|
||||
switch($cmd){
|
||||
case "sudo":
|
||||
@ -132,14 +161,14 @@ class BanAPI{
|
||||
$user = strtolower($params[0]);
|
||||
$player = $this->server->api->player->get($user);
|
||||
if(!($player instanceof Player)){
|
||||
$this->ops->set($user, false);
|
||||
$this->ops->save($user);
|
||||
$this->ops->remove($user);
|
||||
$this->ops->save();
|
||||
$output .= $user." is no longer op\n";
|
||||
break;
|
||||
}
|
||||
$this->ops->remove($player->iusername);
|
||||
$this->ops->save();
|
||||
$output .= $player->iusername." is not longer op\n";
|
||||
$output .= $player->iusername." is no longer op\n";
|
||||
$this->server->api->chat->sendTo(false, "You are no longer op.", $player->iusername);
|
||||
break;
|
||||
case "kick":
|
||||
@ -153,7 +182,9 @@ class BanAPI{
|
||||
}else{
|
||||
$reason = implode(" ", $params);
|
||||
$reason = $reason == "" ? "No reason":$reason;
|
||||
$player->close("You have been kicked: ".$reason);
|
||||
|
||||
$this->server->schedule(60, array($player, "close"), "You have been kicked: ".$reason); //Forces a kick
|
||||
$player->blocked = true;
|
||||
if($issuer instanceof Player){
|
||||
$this->server->api->chat->broadcast($player->username." has been kicked by ".$issuer->username.": $reason\n");
|
||||
}else{
|
||||
@ -274,24 +305,40 @@ class BanAPI{
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function ban($username){
|
||||
|
||||
/**
|
||||
* @param string $username
|
||||
*/
|
||||
public function ban($username){
|
||||
$this->commandHandler("ban", array("add", $username), "console", "");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $username
|
||||
*/
|
||||
public function pardon($username){
|
||||
$this->commandHandler("ban", array("pardon", $username), "console", "");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $ip
|
||||
*/
|
||||
public function banIP($ip){
|
||||
$this->commandHandler("banip", array("add", $ip), "console", "");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $ip
|
||||
*/
|
||||
public function pardonIP($ip){
|
||||
$this->commandHandler("banip", array("pardon", $ip), "console", "");
|
||||
}
|
||||
|
||||
public function kick($username, $reason = "No Reason"){
|
||||
|
||||
/**
|
||||
* @param string $username
|
||||
* @param string $reason
|
||||
*/
|
||||
public function kick($username, $reason = "No Reason"){
|
||||
$this->commandHandler("kick", array($username, $reason), "console", "");
|
||||
}
|
||||
|
||||
@ -300,33 +347,54 @@ class BanAPI{
|
||||
$this->commandHandler("banip", array("reload"), "console", "");
|
||||
$this->commandHandler("whitelist", array("reload"), "console", "");
|
||||
}
|
||||
|
||||
public function isIPBanned($ip){
|
||||
|
||||
/**
|
||||
* @param string $ip
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isIPBanned($ip){
|
||||
if($this->server->api->dhandle("api.ban.ip.check", $ip) === false){
|
||||
return true;
|
||||
}elseif($this->bannedIPs->exists($ip)){
|
||||
}elseif($this->bannedIPs->exists($ip, true)){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function isBanned($username){
|
||||
|
||||
/**
|
||||
* @param string $username
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isBanned($username){
|
||||
$username = strtolower($username);
|
||||
if($this->server->api->dhandle("api.ban.check", $username) === false){
|
||||
return true;
|
||||
}elseif($this->banned->exists($username)){
|
||||
}elseif($this->banned->exists($username, true)){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function inWhitelist($username){
|
||||
|
||||
/**
|
||||
* @param string $username
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function inWhitelist($username){
|
||||
$username = strtolower($username);
|
||||
if($this->isOp($username)){
|
||||
return true;
|
||||
}elseif($this->server->api->dhandle("api.ban.whitelist.check", $username) === false){
|
||||
return true;
|
||||
}elseif($this->whitelist->exists($username)){
|
||||
}elseif($this->whitelist->exists($username, true)){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -24,14 +24,20 @@ class BlockAPI{
|
||||
private $scheduledUpdates = array();
|
||||
private $randomUpdates = array();
|
||||
public static $creative = array(
|
||||
|
||||
//Building
|
||||
array(STONE, 0),
|
||||
array(COBBLESTONE, 0),
|
||||
array(STONE_BRICKS, 0),
|
||||
array(STONE_BRICKS, 1),
|
||||
array(STONE_BRICKS, 2),
|
||||
array(MOSS_STONE, 0),
|
||||
array(WOODEN_PLANKS, 0),
|
||||
array(WOODEN_PLANKS, 1),
|
||||
array(WOODEN_PLANKS, 2),
|
||||
array(WOODEN_PLANKS, 3),
|
||||
array(BRICKS, 0),
|
||||
array(STONE, 0),
|
||||
|
||||
array(DIRT, 0),
|
||||
array(GRASS, 0),
|
||||
array(CLAY_BLOCK, 0),
|
||||
@ -43,10 +49,15 @@ class BlockAPI{
|
||||
array(TRUNK, 0),
|
||||
array(TRUNK, 1),
|
||||
array(TRUNK, 2),
|
||||
array(TRUNK, 3),
|
||||
array(NETHER_BRICKS, 0),
|
||||
array(NETHERRACK, 0),
|
||||
array(BEDROCK, 0),
|
||||
array(COBBLESTONE_STAIRS, 0),
|
||||
array(WOODEN_STAIRS, 0),
|
||||
array(OAK_WOODEN_STAIRS, 0),
|
||||
array(SPRUCE_WOODEN_STAIRS, 0),
|
||||
array(BIRCH_WOODEN_STAIRS, 0),
|
||||
array(JUNGLE_WOODEN_STAIRS, 0),
|
||||
array(BRICK_STAIRS, 0),
|
||||
array(SANDSTONE_STAIRS, 0),
|
||||
array(STONE_BRICK_STAIRS, 0),
|
||||
@ -54,7 +65,10 @@ class BlockAPI{
|
||||
array(QUARTZ_STAIRS, 0),
|
||||
array(SLAB, 0),
|
||||
array(SLAB, 1),
|
||||
array(SLAB, 2),
|
||||
array(WOODEN_SLAB, 0),
|
||||
array(WOODEN_SLAB, 1),
|
||||
array(WOODEN_SLAB, 2),
|
||||
array(WOODEN_SLAB, 3),
|
||||
array(SLAB, 3),
|
||||
array(SLAB, 4),
|
||||
array(SLAB, 5),
|
||||
@ -68,12 +82,19 @@ class BlockAPI{
|
||||
array(DIAMOND_ORE, 0),
|
||||
array(LAPIS_ORE, 0),
|
||||
array(REDSTONE_ORE, 0),
|
||||
array(OBSIDIAN, 0),
|
||||
array(ICE, 0),
|
||||
array(SNOW_BLOCK, 0),
|
||||
|
||||
//Decoration
|
||||
array(COBBLESTONE_WALL, 0),
|
||||
array(COBBLESTONE_WALL, 1),
|
||||
array(GOLD_BLOCK, 0),
|
||||
array(IRON_BLOCK, 0),
|
||||
array(DIAMOND_BLOCK, 0),
|
||||
array(LAPIS_BLOCK, 0),
|
||||
array(OBSIDIAN, 0),
|
||||
array(SNOW_BLOCK, 0),
|
||||
array(COAL_BLOCK, 0),
|
||||
array(SNOW_LAYER, 0),
|
||||
array(GLASS, 0),
|
||||
array(GLOWSTONE_BLOCK, 0),
|
||||
array(NETHER_REACTOR, 0),
|
||||
@ -94,15 +115,13 @@ class BlockAPI{
|
||||
array(WOOL, 9),
|
||||
array(WOOL, 8),
|
||||
array(LADDER, 0),
|
||||
array(TORCH, 0),
|
||||
array(SPONGE, 0),
|
||||
array(GLASS_PANE, 0),
|
||||
array(BUCKET, 0),
|
||||
array(BUCKET, 8),
|
||||
array(BUCKET, 10),
|
||||
array(WOODEN_DOOR, 0),
|
||||
array(TRAPDOOR, 0),
|
||||
array(FENCE, 0),
|
||||
array(FENCE_GATE, 0),
|
||||
array(IRON_BARS, 0),
|
||||
array(BED, 0),
|
||||
array(BOOKSHELF, 0),
|
||||
array(PAINTING, 0),
|
||||
@ -110,33 +129,94 @@ class BlockAPI{
|
||||
array(STONECUTTER, 0),
|
||||
array(CHEST, 0),
|
||||
array(FURNACE, 0),
|
||||
array(TNT, 0),
|
||||
array(DANDELION, 0),
|
||||
array(CYAN_FLOWER, 0),
|
||||
array(BROWN_MUSHROOM, 0),
|
||||
array(RED_MUSHROOM, 0),
|
||||
array(CACTUS, 0),
|
||||
array(MELON_BLOCK, 0),
|
||||
array(SUGARCANE, 0),
|
||||
array(PUMPKIN, 0),
|
||||
array(LIT_PUMPKIN, 0),
|
||||
array(COBWEB, 0),
|
||||
array(HAY_BALE, 0),
|
||||
array(TALL_GRASS, 1),
|
||||
array(TALL_GRASS, 2),
|
||||
array(DEAD_BUSH, 0),
|
||||
array(SAPLING, 0),
|
||||
array(SAPLING, 1),
|
||||
array(SAPLING, 2),
|
||||
array(SAPLING, 3),
|
||||
array(LEAVES, 0),
|
||||
array(LEAVES, 1),
|
||||
array(LEAVES, 2),
|
||||
array(SEEDS, 0),
|
||||
array(MELON_SEEDS, 0),
|
||||
array(DYE, 15), //Bonemeal
|
||||
array(IRON_HOE, 0),
|
||||
array(LEAVES, 3),
|
||||
array(CAKE, 0),
|
||||
array(EGG, 0),
|
||||
array(SIGN, 0),
|
||||
array(CARPET, 0),
|
||||
array(CARPET, 7),
|
||||
array(CARPET, 6),
|
||||
array(CARPET, 5),
|
||||
array(CARPET, 4),
|
||||
array(CARPET, 3),
|
||||
array(CARPET, 2),
|
||||
array(CARPET, 1),
|
||||
array(CARPET, 15),
|
||||
array(CARPET, 14),
|
||||
array(CARPET, 13),
|
||||
array(CARPET, 12),
|
||||
array(CARPET, 11),
|
||||
array(CARPET, 10),
|
||||
array(CARPET, 9),
|
||||
array(CARPET, 8),
|
||||
|
||||
//Tools
|
||||
//array(RAILS, 0),
|
||||
//array(POWERED_RAILS, 0),
|
||||
array(TORCH, 0),
|
||||
array(BUCKET, 0),
|
||||
array(BUCKET, 8),
|
||||
array(BUCKET, 10),
|
||||
array(TNT, 0),
|
||||
array(IRON_HOE, 0),
|
||||
array(IRON_SWORD, 0),
|
||||
array(BOW, 0),
|
||||
array(SIGN, 0),
|
||||
array(SHEARS, 0),
|
||||
array(FLINT_AND_STEEL, 0),
|
||||
array(CLOCK, 0),
|
||||
array(COMPASS, 0),
|
||||
array(MINECART, 0),
|
||||
array(SPAWN_EGG, MOB_CHICKEN),
|
||||
array(SPAWN_EGG, MOB_COW),
|
||||
array(SPAWN_EGG, MOB_PIG),
|
||||
array(SPAWN_EGG, MOB_SHEEP),
|
||||
array(SPAWN_EGG, MOB_SHEEP),
|
||||
|
||||
//Seeds
|
||||
array(SUGARCANE, 0),
|
||||
array(WHEAT, 0),
|
||||
array(SEEDS, 0),
|
||||
array(MELON_SEEDS, 0),
|
||||
array(PUMPKIN_SEEDS, 0),
|
||||
array(CARROT, 0),
|
||||
array(POTATO, 0),
|
||||
array(BEETROOT_SEEDS, 0),
|
||||
array(EGG, 0),
|
||||
array(DYE, 0),
|
||||
array(DYE, 7),
|
||||
array(DYE, 6),
|
||||
array(DYE, 5),
|
||||
array(DYE, 4),
|
||||
array(DYE, 3),
|
||||
array(DYE, 2),
|
||||
array(DYE, 1),
|
||||
array(DYE, 15),
|
||||
array(DYE, 14),
|
||||
array(DYE, 13),
|
||||
array(DYE, 12),
|
||||
array(DYE, 11),
|
||||
array(DYE, 10),
|
||||
array(DYE, 9),
|
||||
array(DYE, 8),
|
||||
|
||||
);
|
||||
|
||||
public static function fromString($str, $multiple = false){
|
||||
@ -167,12 +247,11 @@ class BlockAPI{
|
||||
}
|
||||
|
||||
public static function get($id, $meta = 0, $v = false){
|
||||
$id = (int) $id;
|
||||
if(isset(Block::$class[$id])){
|
||||
$classname = Block::$class[$id];
|
||||
$b = new $classname($meta);
|
||||
}else{
|
||||
$b = new GenericBlock($id, $meta);
|
||||
$b = new GenericBlock((int) $id, $meta);
|
||||
}
|
||||
if($v instanceof Position){
|
||||
$b->position($v);
|
||||
@ -270,7 +349,7 @@ class BlockAPI{
|
||||
if($target->onBreak($item, $player) === false){
|
||||
return $this->cancelAction($target, $player, false);
|
||||
}
|
||||
if($item->useOn($target) and ($player->gamemode & 0x01) === 0 and $item->getMetadata() >= $item->getMaxDurability()){
|
||||
if(($player->gamemode & 0x01) === 0 and $item->useOn($target) and $item->getMetadata() >= $item->getMaxDurability()){
|
||||
$player->setSlot($player->slot, new Item(AIR, 0, 0), false);
|
||||
}
|
||||
}else{
|
||||
@ -340,6 +419,12 @@ class BlockAPI{
|
||||
return $this->cancelAction($block, $player, false);
|
||||
}
|
||||
|
||||
if($target->isReplaceable === true){
|
||||
$block = $target;
|
||||
$hand->position($block);
|
||||
$face = -1;
|
||||
}
|
||||
|
||||
if($hand->isSolid === true and $player->entity->inBlock($block)){
|
||||
return $this->cancelAction($block, $player, false); //Entity in block
|
||||
}
|
||||
|
@ -32,8 +32,16 @@ class ChatAPI{
|
||||
$this->server->api->ban->cmdWhitelist("tell");
|
||||
$this->server->api->ban->cmdWhitelist("me");
|
||||
}
|
||||
|
||||
public function commandHandler($cmd, $params, $issuer, $alias){
|
||||
|
||||
/**
|
||||
* @param string $cmd
|
||||
* @param array $params
|
||||
* @param string $issuer
|
||||
* @param string $alias
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function commandHandler($cmd, $params, $issuer, $alias){
|
||||
$output = "";
|
||||
switch($cmd){
|
||||
case "say":
|
||||
@ -73,7 +81,7 @@ class ChatAPI{
|
||||
$target = $target->username;
|
||||
}else{
|
||||
$target = strtolower($n);
|
||||
if($t === "server" or $t === "console" or $t === "rcon"){
|
||||
if($target === "server" or $target === "console" or $target === "rcon"){
|
||||
$target = "Console";
|
||||
}
|
||||
}
|
||||
@ -82,21 +90,37 @@ class ChatAPI{
|
||||
if($target !== "Console" and $target !== "Rcon"){
|
||||
$this->sendTo(false, "[".$sender." -> me] ".$mes, $target);
|
||||
}
|
||||
console("[INFO] [".$sender." -> ".$target."] ".$mes);
|
||||
if($target === "Console" or $sender === "Console"){
|
||||
console("[INFO] [".$sender." -> ".$target."] ".$mes);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function broadcast($message){
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
*/
|
||||
public function broadcast($message){
|
||||
$this->send(false, $message);
|
||||
}
|
||||
|
||||
public function sendTo($owner, $text, $player){
|
||||
|
||||
/**
|
||||
* @param string $owner
|
||||
* @param string $text
|
||||
* @param mixed $player Can be either Player object or string username. Boolean false for broadcast.
|
||||
*/
|
||||
public function sendTo($owner, $text, $player){
|
||||
$this->send($owner, $text, array($player));
|
||||
}
|
||||
|
||||
public function send($owner, $text, $whitelist = false, $blacklist = false){
|
||||
|
||||
/**
|
||||
* @param mixed $owner Can be either Player object or string username. Boolean false for broadcast.
|
||||
* @param string $text
|
||||
* @param $whitelist
|
||||
* @param $blacklist
|
||||
*/
|
||||
public function send($owner, $text, $whitelist = false, $blacklist = false){
|
||||
$message = array(
|
||||
"player" => $owner,
|
||||
"message" => $text,
|
||||
|
@ -128,7 +128,7 @@ class ConsoleAPI{
|
||||
|
||||
$max = ceil(count($cmds) / 5);
|
||||
$page = (int) (isset($params[0]) ? min($max, max(1, intval($params[0]))):1);
|
||||
$output .= "- Showing help page $page of $max (/help <page>) -\n";
|
||||
$output .= "\x1b[31;1m-\x1b[0m Showing help page $page of $max (/help <page>) \x1b[31;1m-\x1b[0m\n";
|
||||
$current = 1;
|
||||
foreach($cmds as $c => $h){
|
||||
$curpage = (int) ceil($current / 5);
|
||||
@ -175,9 +175,9 @@ class ConsoleAPI{
|
||||
return $this->run($this->alias[$cmd] . ($params !== "" ? " " .$params:""), $issuer, $cmd);
|
||||
}
|
||||
if($issuer instanceof Player){
|
||||
console("[DEBUG] \x1b[33m".$issuer->username."\x1b[0m issued server command: ".ltrim("$alias ")."/$cmd ".$params, true, true, 2);
|
||||
console("[DEBUG] ".FORMAT_AQUA.$issuer->username.FORMAT_RESET." issued server command: ".ltrim("$alias ")."/$cmd ".$params, true, true, 2);
|
||||
}else{
|
||||
console("[DEBUG] \x1b[33m*".$issuer."\x1b[0m issued server command: ".ltrim("$alias ")."/$cmd ".$params, true, true, 2);
|
||||
console("[DEBUG] ".FORMAT_YELLOW."*".$issuer.FORMAT_RESET." issued server command: ".ltrim("$alias ")."/$cmd ".$params, true, true, 2);
|
||||
}
|
||||
|
||||
if(preg_match_all('#@([@a-z]{1,})#', $params, $matches, PREG_OFFSET_CAPTURE) > 0){
|
||||
@ -204,9 +204,26 @@ class ConsoleAPI{
|
||||
break;
|
||||
case "a":
|
||||
case "all":
|
||||
$output = "";
|
||||
foreach($this->server->api->player->getAll() as $p){
|
||||
$output .= $this->run($cmd . " ". substr_replace($params, $p->username, $selector[1] + $offsetshift - 1, strlen($selector[0]) + 1), $issuer, $alias);
|
||||
if($issuer instanceof Player)
|
||||
{
|
||||
if($this->server->api->ban->isOp($issuer->username))
|
||||
{
|
||||
$output = "";
|
||||
foreach($this->server->api->player->getAll() as $p){
|
||||
$output .= $this->run($cmd . " ". substr_replace($params, $p->username, $selector[1] + $offsetshift - 1, strlen($selector[0]) + 1), $issuer, $alias);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$issuer->sendChat("You don't have permissions to use this command.\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$output = "";
|
||||
foreach($this->server->api->player->getAll() as $p){
|
||||
$output .= $this->run($cmd . " ". substr_replace($params, $p->username, $selector[1] + $offsetshift - 1, strlen($selector[0]) + 1), $issuer, $alias);
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
case "r":
|
||||
@ -256,7 +273,7 @@ class ConsoleAPI{
|
||||
return;
|
||||
}
|
||||
if($this->loop->line !== false){
|
||||
$line = trim($this->loop->line);
|
||||
$line = preg_replace("#\\x1b\\x5b([^\\x1b]*\\x7e|[\\x40-\\x50])#", "", trim($this->loop->line));
|
||||
$this->loop->line = false;
|
||||
$output = $this->run($line, "console");
|
||||
if($output != ""){
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
/**
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
@ -237,4 +237,9 @@ class LevelAPI{
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public function getAll()
|
||||
{
|
||||
return $this->levels;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
/**
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
@ -15,456 +15,470 @@
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*
|
||||
*/
|
||||
|
||||
class PlayerAPI{
|
||||
private $server;
|
||||
function __construct(){
|
||||
$this->server = ServerAPI::request();
|
||||
}
|
||||
private $server;
|
||||
function __construct(){
|
||||
$this->server = ServerAPI::request();
|
||||
}
|
||||
|
||||
public function init(){
|
||||
$this->server->schedule(20 * 15, array($this, "handle"), 1, true, "server.regeneration");
|
||||
$this->server->addHandler("player.death", array($this, "handle"), 1);
|
||||
$this->server->api->console->register("list", "", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("kill", "<player>", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("gamemode", "<mode> [player]", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("tp", "[target player] <destination player|w:world> OR /tp [target player] <x> <y> <z>", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("spawnpoint", "[player] [x] [y] [z]", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("spawn", "", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("ping", "", array($this, "commandHandler"));
|
||||
$this->server->api->console->alias("lag", "ping");
|
||||
$this->server->api->console->alias("suicide", "kill");
|
||||
$this->server->api->console->alias("tppos", "tp");
|
||||
$this->server->api->ban->cmdWhitelist("list");
|
||||
$this->server->api->ban->cmdWhitelist("ping");
|
||||
$this->server->api->ban->cmdWhitelist("spawn");
|
||||
$this->server->preparedSQL->selectPlayersToHeal = $this->server->database->prepare("SELECT EID FROM entities WHERE class = ".ENTITY_PLAYER." AND health < 20;");
|
||||
}
|
||||
public function init(){
|
||||
$this->server->schedule(20 * 15, array($this, "handle"), 1, true, "server.regeneration");
|
||||
$this->server->addHandler("player.death", array($this, "handle"), 1);
|
||||
$this->server->api->console->register("list", "", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("kill", "<player>", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("gamemode", "<mode> [player]", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("tp", "[target player] <destination player|w:world> OR /tp [target player] <x> <y> <z>", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("spawnpoint", "[player] [x] [y] [z]", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("spawn", "", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("ping", "", array($this, "commandHandler"));
|
||||
$this->server->api->console->alias("lag", "ping");
|
||||
$this->server->api->console->alias("suicide", "kill");
|
||||
$this->server->api->console->alias("tppos", "tp");
|
||||
$this->server->api->ban->cmdWhitelist("list");
|
||||
$this->server->api->ban->cmdWhitelist("ping");
|
||||
$this->server->api->ban->cmdWhitelist("spawn");
|
||||
$this->server->preparedSQL->selectPlayersToHeal = $this->server->database->prepare("SELECT EID FROM entities WHERE class = ".ENTITY_PLAYER." AND health < 20;");
|
||||
}
|
||||
|
||||
public function handle($data, $event){
|
||||
switch($event){
|
||||
case "server.regeneration":
|
||||
if($this->server->difficulty === 0){
|
||||
$result = $this->server->preparedSQL->selectPlayersToHeal->execute();
|
||||
if($result !== false){
|
||||
while(($player = $result->fetchArray()) !== false){
|
||||
if(($player = $this->server->api->entity->get($player["EID"])) !== false){
|
||||
if($player->getHealth() <= 0){
|
||||
continue;
|
||||
}
|
||||
$player->setHealth(min(20, $player->getHealth() + $data), "regeneration");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "player.death":
|
||||
if(is_numeric($data["cause"])){
|
||||
$e = $this->server->api->entity->get($data["cause"]);
|
||||
if($e instanceof Entity){
|
||||
switch($e->class){
|
||||
case ENTITY_PLAYER:
|
||||
$message = " was killed by ".$e->name;
|
||||
break;
|
||||
default:
|
||||
$message = " was killed";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
switch($data["cause"]){
|
||||
case "cactus":
|
||||
$message = " was pricked to death";
|
||||
break;
|
||||
case "lava":
|
||||
$message = " tried to swim in lava";
|
||||
break;
|
||||
case "fire":
|
||||
$message = " went up in flames";
|
||||
break;
|
||||
case "burning":
|
||||
$message = " burned to death";
|
||||
break;
|
||||
case "suffocation":
|
||||
$message = " suffocated in a wall";
|
||||
break;
|
||||
case "water":
|
||||
$message = " drowned";
|
||||
break;
|
||||
case "void":
|
||||
$message = " fell out of the world";
|
||||
break;
|
||||
case "fall":
|
||||
$message = " hit the ground too hard";
|
||||
break;
|
||||
default:
|
||||
$message = " died";
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->server->api->chat->broadcast($data["player"]->username . $message);
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
public function handle($data, $event){
|
||||
switch($event){
|
||||
case "server.regeneration":
|
||||
if($this->server->difficulty === 0){
|
||||
$result = $this->server->preparedSQL->selectPlayersToHeal->execute();
|
||||
if($result !== false){
|
||||
while(($player = $result->fetchArray()) !== false){
|
||||
if(($player = $this->server->api->entity->get($player["EID"])) !== false){
|
||||
if($player->getHealth() <= 0){
|
||||
continue;
|
||||
}
|
||||
$player->setHealth(min(20, $player->getHealth() + $data), "regeneration");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "player.death":
|
||||
if(is_numeric($data["cause"])){
|
||||
$e = $this->server->api->entity->get($data["cause"]);
|
||||
if($e instanceof Entity){
|
||||
switch($e->class){
|
||||
case ENTITY_PLAYER:
|
||||
$message = " was killed by ".$e->name;
|
||||
break;
|
||||
default:
|
||||
$message = " was killed";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
switch($data["cause"]){
|
||||
case "cactus":
|
||||
$message = " was pricked to death";
|
||||
break;
|
||||
case "lava":
|
||||
$message = " tried to swim in lava";
|
||||
break;
|
||||
case "fire":
|
||||
$message = " went up in flames";
|
||||
break;
|
||||
case "burning":
|
||||
$message = " burned to death";
|
||||
break;
|
||||
case "suffocation":
|
||||
$message = " suffocated in a wall";
|
||||
break;
|
||||
case "water":
|
||||
$message = " drowned";
|
||||
break;
|
||||
case "void":
|
||||
$message = " fell out of the world";
|
||||
break;
|
||||
case "fall":
|
||||
$message = " hit the ground too hard";
|
||||
break;
|
||||
case "explosion":
|
||||
$message = " blew up";
|
||||
break;
|
||||
default:
|
||||
$message = " died";
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->server->api->chat->broadcast($data["player"]->username . $message);
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function commandHandler($cmd, $params, $issuer, $alias){
|
||||
$output = "";
|
||||
switch($cmd){
|
||||
case "spawnpoint":
|
||||
if(!($issuer instanceof Player)){
|
||||
$output .= "Please run this command in-game.\n";
|
||||
break;
|
||||
}
|
||||
public function commandHandler($cmd, $params, $issuer, $alias){
|
||||
$output = "";
|
||||
switch($cmd){
|
||||
case "spawnpoint":
|
||||
if(!($issuer instanceof Player)){
|
||||
$output .= "Please run this command in-game.\n";
|
||||
break;
|
||||
}
|
||||
|
||||
if(count($params) === 1 or count($params) === 4){
|
||||
$target = $this->server->api->player->get(array_shift($params));
|
||||
}else{
|
||||
$target = $issuer;
|
||||
}
|
||||
|
||||
if(!($target instanceof Player)){
|
||||
$output .= "That player cannot be found.\n";
|
||||
break;
|
||||
}
|
||||
|
||||
if(count($params) === 3){
|
||||
$spawn = new Position(floatval(array_shift($params)), floatval(array_shift($params)), floatval(array_shift($params)), $issuer->level);
|
||||
}else{
|
||||
$spawn = new Position($issuer->entity->x, $issuer->entity->y, $issuer->entity->z, $issuer->entity->level);
|
||||
}
|
||||
|
||||
$target->setSpawn($spawn);
|
||||
|
||||
$output .= "Spawnpoint set correctly!\n";
|
||||
break;
|
||||
case "spawn":
|
||||
if(!($issuer instanceof Player)){
|
||||
$output .= "Please run this command in-game.\n";
|
||||
break;
|
||||
}
|
||||
$issuer->teleport($this->server->spawn);
|
||||
break;
|
||||
case "ping":
|
||||
if(!($issuer instanceof Player)){
|
||||
$output .= "Please run this command in-game.\n";
|
||||
break;
|
||||
}
|
||||
$output .= "ping ".round($issuer->getLag(), 2)."ms, packet loss ".round($issuer->getPacketLoss() * 100, 2)."%, ".round($issuer->getBandwidth() / 1024, 2)." KB/s\n";
|
||||
break;
|
||||
case "gamemode":
|
||||
$player = false;
|
||||
$gms = array(
|
||||
"0" => SURVIVAL,
|
||||
"survival" => SURVIVAL,
|
||||
"s" => SURVIVAL,
|
||||
"1" => CREATIVE,
|
||||
"creative" => CREATIVE,
|
||||
"c" => CREATIVE,
|
||||
"2" => ADVENTURE,
|
||||
"adventure" => ADVENTURE,
|
||||
"a" => ADVENTURE,
|
||||
"3" => VIEW,
|
||||
"view" => VIEW,
|
||||
"viewer" => VIEW,
|
||||
"spectator" => VIEW,
|
||||
"v" => VIEW,
|
||||
);
|
||||
if($issuer instanceof Player){
|
||||
$player = $issuer;
|
||||
}
|
||||
if(isset($params[1])){
|
||||
$player = $this->server->api->player->get($params[1]);
|
||||
}
|
||||
if(!($player instanceof Player) or !isset($gms[strtolower($params[0])])){
|
||||
$output .= "Usage: /$cmd <mode> [player]\n";
|
||||
break;
|
||||
}
|
||||
if($player->setGamemode($gms[strtolower($params[0])])){
|
||||
$output .= "Gamemode of ".$player->username." changed to ".$player->getGamemode()."\n";
|
||||
}
|
||||
break;
|
||||
case "tp":
|
||||
if(count($params) <= 2 or substr($params[0], 0, 2) === "w:" or substr($params[1], 0, 2) === "w:"){
|
||||
if((!isset($params[1]) or substr($params[0], 0, 2) === "w:") and isset($params[0]) and ($issuer instanceof Player)){
|
||||
$name = $issuer->username;
|
||||
$target = implode(" ", $params);
|
||||
}elseif(isset($params[1]) and isset($params[0])){
|
||||
$name = array_shift($params);
|
||||
$target = implode(" ", $params);
|
||||
}else{
|
||||
$output .= "Usage: /$cmd [target player] <destination player>\n";
|
||||
break;
|
||||
}
|
||||
if($this->teleport($name, $target) !== false){
|
||||
$output .= "\"$name\" teleported to \"$target\"\n";
|
||||
}else{
|
||||
$output .= "Couldn't teleport.\n";
|
||||
}
|
||||
}else{
|
||||
if(!isset($params[3]) and isset($params[2]) and isset($params[1]) and isset($params[0]) and ($issuer instanceof Player)){
|
||||
$name = $issuer->username;
|
||||
$x = $params[0];
|
||||
$y = $params[1];
|
||||
$z = $params[2];
|
||||
}elseif(isset($params[3]) and isset($params[2]) and isset($params[1]) and isset($params[0])){
|
||||
$name = $params[0];
|
||||
$x = $params[1];
|
||||
$y = $params[2];
|
||||
$z = $params[3];
|
||||
}else{
|
||||
$output .= "Usage: /$cmd [player] <x> <y> <z>\n";
|
||||
break;
|
||||
}
|
||||
if($this->tppos($name, $x, $y, $z)){
|
||||
$output .= "\"$name\" teleported to ($x, $y, $z)\n";
|
||||
}else{
|
||||
$output .= "Couldn't teleport.\n";
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "kill":
|
||||
case "suicide":
|
||||
if(!isset($params[0]) and ($issuer instanceof Player)){
|
||||
$player = $issuer;
|
||||
}else{
|
||||
$player = $this->get($params[0]);
|
||||
}
|
||||
if($player instanceof Player){
|
||||
$player->entity->harm(1000, "console", true);
|
||||
$player->sendChat("Ouch. That looks like it hurt.\n");
|
||||
}else{
|
||||
$output .= "Usage: /$cmd [player]\n";
|
||||
}
|
||||
break;
|
||||
case "list":
|
||||
$output .= "There are ".count($this->server->clients)."/".$this->server->maxClients." players online:\n";
|
||||
if(count($this->server->clients) == 0){
|
||||
break;
|
||||
}
|
||||
foreach($this->server->clients as $c){
|
||||
$output .= $c->username.", ";
|
||||
}
|
||||
$output = substr($output, 0, -2)."\n";
|
||||
break;
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
if(count($params) === 1 or count($params) === 4){
|
||||
$target = $this->server->api->player->get(array_shift($params));
|
||||
}else{
|
||||
$target = $issuer;
|
||||
}
|
||||
|
||||
public function teleport(&$name, &$target){
|
||||
if(substr($target, 0, 2) === "w:"){
|
||||
$lv = $this->server->api->level->get(substr($target, 2));
|
||||
if($lv instanceof Level){
|
||||
$origin = $this->get($name);
|
||||
if($origin instanceof Player){
|
||||
$name = $origin->username;
|
||||
return $origin->teleport($lv->getSafeSpawn());
|
||||
}
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$player = $this->get($target);
|
||||
if(($player instanceof Player) and ($player->entity instanceof Entity)){
|
||||
$target = $player->username;
|
||||
$origin = $this->get($name);
|
||||
if($origin instanceof Player){
|
||||
$name = $origin->username;
|
||||
return $origin->teleport($player->entity);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if(!($target instanceof Player)){
|
||||
$output .= "That player cannot be found.\n";
|
||||
break;
|
||||
}
|
||||
|
||||
public function tppos(&$name, &$x, &$y, &$z){
|
||||
$player = $this->get($name);
|
||||
if(($player instanceof Player) and ($player->entity instanceof Entity)){
|
||||
$name = $player->username;
|
||||
$x = $x{0} === "~" ? $player->entity->x + floatval(substr($x, 1)):floatval($x);
|
||||
$y = $y{0} === "~" ? $player->entity->y + floatval(substr($y, 1)):floatval($y);
|
||||
$z = $z{0} === "~" ? $player->entity->z + floatval(substr($z, 1)):floatval($z);
|
||||
$player->teleport(new Vector3($x, $y, $z));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if(count($params) === 3){
|
||||
$spawn = new Position(floatval(array_shift($params)), floatval(array_shift($params)), floatval(array_shift($params)), $issuer->level);
|
||||
}else{
|
||||
$spawn = new Position($issuer->entity->x, $issuer->entity->y, $issuer->entity->z, $issuer->entity->level);
|
||||
}
|
||||
|
||||
public function get($name, $alike = true){
|
||||
$name = trim(strtolower($name));
|
||||
if($name === ""){
|
||||
return false;
|
||||
}
|
||||
$CID = $this->server->query("SELECT ip,port FROM players WHERE name ".($alike === true ? "LIKE '%".$name."%'":"= '".$name."'").";", true);
|
||||
$CID = PocketMinecraftServer::clientID($CID["ip"], $CID["port"]);
|
||||
if(isset($this->server->clients[$CID])){
|
||||
return $this->server->clients[$CID];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
$target->setSpawn($spawn);
|
||||
|
||||
public function getAll($level = null){
|
||||
if($level instanceof Level){
|
||||
$clients = array();
|
||||
$l = $this->server->query("SELECT EID FROM entities WHERE level = '".$level->getName()."' AND class = '".ENTITY_PLAYER."';");
|
||||
if($l !== false and $l !== true){
|
||||
while(($e = $l->fetchArray(SQLITE3_ASSOC)) !== false){
|
||||
$e = $this->getByEID($e["EID"]);
|
||||
if($e instanceof Player){
|
||||
$clients[$e->CID] = $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $clients;
|
||||
}
|
||||
return $this->server->clients;
|
||||
}
|
||||
|
||||
public function broadcastPacket(array $players, $id, $data = array()){
|
||||
$data = new CustomPacketHandler($id, "", $data, true);
|
||||
$packet = array("raw" => chr($id).$data->raw);
|
||||
foreach($players as $p){
|
||||
$p->dataPacket(false, $packet);
|
||||
}
|
||||
}
|
||||
$output .= "Spawnpoint set correctly!\n";
|
||||
break;
|
||||
case "spawn":
|
||||
if(!($issuer instanceof Player)){
|
||||
$output .= "Please run this command in-game.\n";
|
||||
break;
|
||||
}
|
||||
$issuer->teleport($this->server->spawn);
|
||||
break;
|
||||
case "ping":
|
||||
if(!($issuer instanceof Player)){
|
||||
$output .= "Please run this command in-game.\n";
|
||||
break;
|
||||
}
|
||||
$output .= "ping ".round($issuer->getLag(), 2)."ms, packet loss ".round($issuer->getPacketLoss() * 100, 2)."%, ".round($issuer->getBandwidth() / 1024, 2)." KB/s\n";
|
||||
break;
|
||||
case "gamemode":
|
||||
$player = false;
|
||||
$setgm = false;
|
||||
$gms = array(
|
||||
"0" => SURVIVAL,
|
||||
"survival" => SURVIVAL,
|
||||
"s" => SURVIVAL,
|
||||
"1" => CREATIVE,
|
||||
"creative" => CREATIVE,
|
||||
"c" => CREATIVE,
|
||||
"2" => ADVENTURE,
|
||||
"adventure" => ADVENTURE,
|
||||
"a" => ADVENTURE,
|
||||
"3" => VIEW,
|
||||
"view" => VIEW,
|
||||
"viewer" => VIEW,
|
||||
"spectator" => VIEW,
|
||||
"v" => VIEW,
|
||||
);
|
||||
if($issuer instanceof Player){
|
||||
$player = $issuer;
|
||||
}
|
||||
if(isset($params[1])){
|
||||
if($this->server->api->player->get($params[1]) instanceof Player){
|
||||
$player = $this->server->api->player->get($params[1]);
|
||||
$setgm = $params[0];
|
||||
}elseif($this->server->api->player->get($params[0]) instanceof Player){
|
||||
$player = $this->server->api->player->get($params[0]);
|
||||
$setgm = $params[1];
|
||||
}else{
|
||||
$output .= "Usage: /$cmd <mode> [player] or /$cmd [player] <mode>\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!($player instanceof Player) or !isset($gms[strtolower($setgm)])){
|
||||
$output .= "Usage: /$cmd <mode> [player] or /$cmd [player] <mode>\n";
|
||||
break;
|
||||
}
|
||||
if($player->setGamemode($gms[strtolower($setgm)])){
|
||||
$output .= "Gamemode of ".$player->username." changed to ".$player->getGamemode()."\n";
|
||||
}
|
||||
break;
|
||||
case "tp":
|
||||
if(count($params) <= 2 or substr($params[0], 0, 2) === "w:" or substr($params[1], 0, 2) === "w:"){
|
||||
if((!isset($params[1]) or substr($params[0], 0, 2) === "w:") and isset($params[0]) and ($issuer instanceof Player)){
|
||||
$name = $issuer->username;
|
||||
$target = implode(" ", $params);
|
||||
}elseif(isset($params[1]) and isset($params[0])){
|
||||
$name = array_shift($params);
|
||||
$target = implode(" ", $params);
|
||||
}else{
|
||||
$output .= "Usage: /$cmd [target player] <destination player>\n";
|
||||
break;
|
||||
}
|
||||
if($this->teleport($name, $target) !== false){
|
||||
$output .= "\"$name\" teleported to \"$target\"\n";
|
||||
}else{
|
||||
$output .= "Couldn't teleport.\n";
|
||||
}
|
||||
}else{
|
||||
if(!isset($params[3]) and isset($params[2]) and isset($params[1]) and isset($params[0]) and ($issuer instanceof Player)){
|
||||
$name = $issuer->username;
|
||||
$x = $params[0];
|
||||
$y = $params[1];
|
||||
$z = $params[2];
|
||||
}elseif(isset($params[3]) and isset($params[2]) and isset($params[1]) and isset($params[0])){
|
||||
$name = $params[0];
|
||||
$x = $params[1];
|
||||
$y = $params[2];
|
||||
$z = $params[3];
|
||||
}else{
|
||||
$output .= "Usage: /$cmd [player] <x> <y> <z>\n";
|
||||
break;
|
||||
}
|
||||
if($this->tppos($name, $x, $y, $z)){
|
||||
$output .= "\"$name\" teleported to ($x, $y, $z)\n";
|
||||
}else{
|
||||
$output .= "Couldn't teleport.\n";
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "kill":
|
||||
case "suicide":
|
||||
if(!isset($params[0]) and ($issuer instanceof Player)){
|
||||
$player = $issuer;
|
||||
}else{
|
||||
$player = $this->get($params[0]);
|
||||
}
|
||||
if($player instanceof Player){
|
||||
$player->entity->harm(1000, "console", true);
|
||||
$player->sendChat("Ouch. That looks like it hurt.\n");
|
||||
}else{
|
||||
$output .= "Usage: /$cmd [player]\n";
|
||||
}
|
||||
break;
|
||||
case "list":
|
||||
$output .= "There are ".count($this->server->clients)."/".$this->server->maxClients." players online:\n";
|
||||
if(count($this->server->clients) == 0){
|
||||
break;
|
||||
}
|
||||
foreach($this->server->clients as $c){
|
||||
$output .= $c->username.", ";
|
||||
}
|
||||
$output = substr($output, 0, -2)."\n";
|
||||
break;
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function getByEID($eid){
|
||||
$eid = (int) $eid;
|
||||
$CID = $this->server->query("SELECT ip,port FROM players WHERE EID = '".$eid."';", true);
|
||||
$CID = PocketMinecraftServer::clientID($CID["ip"], $CID["port"]);
|
||||
if(isset($this->server->clients[$CID])){
|
||||
return $this->server->clients[$CID];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public function teleport(&$name, &$target){
|
||||
if(substr($target, 0, 2) === "w:"){
|
||||
$lv = $this->server->api->level->get(substr($target, 2));
|
||||
if($lv instanceof Level){
|
||||
$origin = $this->get($name);
|
||||
if($origin instanceof Player){
|
||||
$name = $origin->username;
|
||||
return $origin->teleport($lv->getSafeSpawn());
|
||||
}
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$player = $this->get($target);
|
||||
if(($player instanceof Player) and ($player->entity instanceof Entity)){
|
||||
$target = $player->username;
|
||||
$origin = $this->get($name);
|
||||
if($origin instanceof Player){
|
||||
$name = $origin->username;
|
||||
return $origin->teleport($player->entity);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function online(){
|
||||
$o = array();
|
||||
foreach($this->server->clients as $p){
|
||||
if($p->auth === true){
|
||||
$o[] = $p->username;
|
||||
}
|
||||
}
|
||||
return $o;
|
||||
}
|
||||
public function tppos(&$name, &$x, &$y, &$z){
|
||||
$player = $this->get($name);
|
||||
if(($player instanceof Player) and ($player->entity instanceof Entity)){
|
||||
$name = $player->username;
|
||||
$x = $x{0} === "~" ? $player->entity->x + floatval(substr($x, 1)):floatval($x);
|
||||
$y = $y{0} === "~" ? $player->entity->y + floatval(substr($y, 1)):floatval($y);
|
||||
$z = $z{0} === "~" ? $player->entity->z + floatval(substr($z, 1)):floatval($z);
|
||||
$player->teleport(new Vector3($x, $y, $z));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function add($CID){
|
||||
if(isset($this->server->clients[$CID])){
|
||||
$player = $this->server->clients[$CID];
|
||||
$player->data = $this->getOffline($player->username);
|
||||
$player->gamemode = $player->data->get("gamemode");
|
||||
if(($player->level = $this->server->api->level->get($player->data->get("position")["level"])) === false){
|
||||
$player->level = $this->server->api->level->getDefault();
|
||||
$player->data->set("position", array(
|
||||
"level" => $player->level->getName(),
|
||||
"x" => $player->level->getSpawn()->x,
|
||||
"y" => $player->level->getSpawn()->y,
|
||||
"z" => $player->level->getSpawn()->z,
|
||||
));
|
||||
}
|
||||
$this->server->query("INSERT OR REPLACE INTO players (CID, ip, port, name) VALUES (".$player->CID.", '".$player->ip."', ".$player->port.", '".strtolower($player->username)."');");
|
||||
}
|
||||
}
|
||||
|
||||
public function spawnAllPlayers(Player $player){
|
||||
foreach($this->getAll() as $p){
|
||||
if($p !== $player and ($p->entity instanceof Entity)){
|
||||
$p->entity->spawn($player);
|
||||
if($p->level !== $player->level){
|
||||
$player->dataPacket(MC_MOVE_ENTITY_POSROT, array(
|
||||
"eid" => $p->entity->eid,
|
||||
"x" => -256,
|
||||
"y" => 128,
|
||||
"z" => -256,
|
||||
"yaw" => 0,
|
||||
"pitch" => 0,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function spawnToAllPlayers(Player $player){
|
||||
foreach($this->getAll() as $p){
|
||||
if($p !== $player and ($p->entity instanceof Entity)){
|
||||
$player->entity->spawn($p);
|
||||
if($p->level !== $player->level){
|
||||
$p->dataPacket(MC_MOVE_ENTITY_POSROT, array(
|
||||
"eid" => $player->entity->eid,
|
||||
"x" => -256,
|
||||
"y" => 128,
|
||||
"z" => -256,
|
||||
"yaw" => 0,
|
||||
"pitch" => 0,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public function get($name, $alike = true){
|
||||
$name = trim(strtolower($name));
|
||||
if($name === ""){
|
||||
return false;
|
||||
}
|
||||
$CID = $this->server->query("SELECT ip,port FROM players WHERE name ".($alike === true ? "LIKE '%".$name."%'":"= '".$name."'").";", true);
|
||||
$CID = PocketMinecraftServer::clientID($CID["ip"], $CID["port"]);
|
||||
if(isset($this->server->clients[$CID])){
|
||||
return $this->server->clients[$CID];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function remove($CID){
|
||||
if(isset($this->server->clients[$CID])){
|
||||
$player = $this->server->clients[$CID];
|
||||
unset($this->server->clients[$CID]);
|
||||
$player->close();
|
||||
if($player->username != "" and ($player->data instanceof Config)){
|
||||
$this->saveOffline($player->data);
|
||||
}
|
||||
$this->server->query("DELETE FROM players WHERE name = '".$player->username."';");
|
||||
if($player->entity instanceof Entity){
|
||||
unset($player->entity->player);
|
||||
unset($player->entity);
|
||||
}
|
||||
$this->server->api->entity->remove($player->eid);
|
||||
$player = null;
|
||||
unset($player);
|
||||
}
|
||||
}
|
||||
public function getAll($level = null){
|
||||
if($level instanceof Level){
|
||||
$clients = array();
|
||||
$l = $this->server->query("SELECT EID FROM entities WHERE level = '".$level->getName()."' AND class = '".ENTITY_PLAYER."';");
|
||||
if($l !== false and $l !== true){
|
||||
while(($e = $l->fetchArray(SQLITE3_ASSOC)) !== false){
|
||||
$e = $this->getByEID($e["EID"]);
|
||||
if($e instanceof Player){
|
||||
$clients[$e->CID] = $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $clients;
|
||||
}
|
||||
return $this->server->clients;
|
||||
}
|
||||
|
||||
public function getOffline($name){
|
||||
$iname = strtolower($name);
|
||||
$default = array(
|
||||
"caseusername" => $name,
|
||||
"position" => array(
|
||||
"level" => $this->server->spawn->level->getName(),
|
||||
"x" => $this->server->spawn->x,
|
||||
"y" => $this->server->spawn->y,
|
||||
"z" => $this->server->spawn->z,
|
||||
),
|
||||
"spawn" => array(
|
||||
"level" => $this->server->spawn->level->getName(),
|
||||
"x" => $this->server->spawn->x,
|
||||
"y" => $this->server->spawn->y,
|
||||
"z" => $this->server->spawn->z,
|
||||
),
|
||||
"inventory" => array_fill(0, PLAYER_SURVIVAL_SLOTS, array(AIR, 0, 0)),
|
||||
"armor" => array_fill(0, 4, array(AIR, 0)),
|
||||
"gamemode" => $this->server->gamemode,
|
||||
"health" => 20,
|
||||
"lastIP" => "",
|
||||
"lastID" => 0,
|
||||
);
|
||||
|
||||
if(!file_exists(DATA_PATH."players/".$iname.".yml")){
|
||||
console("[NOTICE] Player data not found for \"".$iname."\", creating new profile");
|
||||
$data = new Config(DATA_PATH."players/".$iname.".yml", CONFIG_YAML, $default);
|
||||
$data->save();
|
||||
}else{
|
||||
$data = new Config(DATA_PATH."players/".$iname.".yml", CONFIG_YAML, $default);
|
||||
}
|
||||
public function broadcastPacket(array $players, $id, $data = array()){
|
||||
$data = new CustomPacketHandler($id, "", $data, true);
|
||||
$packet = array("raw" => chr($id).$data->raw);
|
||||
foreach($players as $p){
|
||||
$p->dataPacket(false, $packet);
|
||||
}
|
||||
}
|
||||
|
||||
if(($data->get("gamemode") & 0x01) === 1){
|
||||
$data->set("health", 20);
|
||||
}
|
||||
$this->server->handle("player.offline.get", $data);
|
||||
return $data;
|
||||
}
|
||||
public function getByEID($eid){
|
||||
$eid = (int) $eid;
|
||||
$CID = $this->server->query("SELECT ip,port FROM players WHERE EID = '".$eid."';", true);
|
||||
$CID = PocketMinecraftServer::clientID($CID["ip"], $CID["port"]);
|
||||
if(isset($this->server->clients[$CID])){
|
||||
return $this->server->clients[$CID];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function saveOffline(Config $data){
|
||||
$this->server->handle("player.offline.save", $data);
|
||||
$data->save();
|
||||
}
|
||||
public function online(){
|
||||
$o = array();
|
||||
foreach($this->server->clients as $p){
|
||||
if($p->auth === true){
|
||||
$o[] = $p->username;
|
||||
}
|
||||
}
|
||||
return $o;
|
||||
}
|
||||
|
||||
public function add($CID){
|
||||
if(isset($this->server->clients[$CID])){
|
||||
$player = $this->server->clients[$CID];
|
||||
$player->data = $this->getOffline($player->username);
|
||||
$player->gamemode = $player->data->get("gamemode");
|
||||
if(($player->level = $this->server->api->level->get($player->data->get("position")["level"])) === false){
|
||||
$player->level = $this->server->api->level->getDefault();
|
||||
$player->data->set("position", array(
|
||||
"level" => $player->level->getName(),
|
||||
"x" => $player->level->getSpawn()->x,
|
||||
"y" => $player->level->getSpawn()->y,
|
||||
"z" => $player->level->getSpawn()->z,
|
||||
));
|
||||
}
|
||||
$this->server->query("INSERT OR REPLACE INTO players (CID, ip, port, name) VALUES (".$player->CID.", '".$player->ip."', ".$player->port.", '".strtolower($player->username)."');");
|
||||
}
|
||||
}
|
||||
|
||||
public function spawnAllPlayers(Player $player){
|
||||
foreach($this->getAll() as $p){
|
||||
if($p !== $player and ($p->entity instanceof Entity)){
|
||||
$p->entity->spawn($player);
|
||||
if($p->level !== $player->level){
|
||||
$player->dataPacket(MC_MOVE_ENTITY_POSROT, array(
|
||||
"eid" => $p->entity->eid,
|
||||
"x" => -256,
|
||||
"y" => 128,
|
||||
"z" => -256,
|
||||
"yaw" => 0,
|
||||
"pitch" => 0,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function spawnToAllPlayers(Player $player){
|
||||
foreach($this->getAll() as $p){
|
||||
if($p !== $player and ($p->entity instanceof Entity) and ($player->entity instanceof Entity)){
|
||||
$player->entity->spawn($p);
|
||||
if($p->level !== $player->level){
|
||||
$p->dataPacket(MC_MOVE_ENTITY_POSROT, array(
|
||||
"eid" => $player->entity->eid,
|
||||
"x" => -256,
|
||||
"y" => 128,
|
||||
"z" => -256,
|
||||
"yaw" => 0,
|
||||
"pitch" => 0,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function remove($CID){
|
||||
if(isset($this->server->clients[$CID])){
|
||||
$player = $this->server->clients[$CID];
|
||||
unset($this->server->clients[$CID]);
|
||||
$player->close();
|
||||
if($player->username != "" and ($player->data instanceof Config)){
|
||||
$this->saveOffline($player->data);
|
||||
}
|
||||
$this->server->query("DELETE FROM players WHERE name = '".$player->username."';");
|
||||
if($player->entity instanceof Entity){
|
||||
unset($player->entity->player);
|
||||
unset($player->entity);
|
||||
}
|
||||
$this->server->api->entity->remove($player->eid);
|
||||
$player = null;
|
||||
unset($player);
|
||||
}
|
||||
}
|
||||
|
||||
public function getOffline($name){
|
||||
$iname = strtolower($name);
|
||||
$default = array(
|
||||
"caseusername" => $name,
|
||||
"position" => array(
|
||||
"level" => $this->server->spawn->level->getName(),
|
||||
"x" => $this->server->spawn->x,
|
||||
"y" => $this->server->spawn->y,
|
||||
"z" => $this->server->spawn->z,
|
||||
),
|
||||
"spawn" => array(
|
||||
"level" => $this->server->spawn->level->getName(),
|
||||
"x" => $this->server->spawn->x,
|
||||
"y" => $this->server->spawn->y,
|
||||
"z" => $this->server->spawn->z,
|
||||
),
|
||||
"inventory" => array_fill(0, PLAYER_SURVIVAL_SLOTS, array(AIR, 0, 0)),
|
||||
"armor" => array_fill(0, 4, array(AIR, 0)),
|
||||
"gamemode" => $this->server->gamemode,
|
||||
"health" => 20,
|
||||
"lastIP" => "",
|
||||
"lastID" => 0,
|
||||
"achievements" => array(),
|
||||
);
|
||||
|
||||
if(!file_exists(DATA_PATH."players/".$iname.".yml")){
|
||||
console("[NOTICE] Player data not found for \"".$iname."\", creating new profile");
|
||||
$data = new Config(DATA_PATH."players/".$iname.".yml", CONFIG_YAML, $default);
|
||||
$data->save();
|
||||
}else{
|
||||
$data = new Config(DATA_PATH."players/".$iname.".yml", CONFIG_YAML, $default);
|
||||
}
|
||||
|
||||
if(($data->get("gamemode") & 0x01) === 1){
|
||||
$data->set("health", 20);
|
||||
}
|
||||
$this->server->handle("player.offline.get", $data);
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function saveOffline(Config $data){
|
||||
$this->server->handle("player.offline.save", $data);
|
||||
$data->save();
|
||||
}
|
||||
}
|
@ -22,8 +22,10 @@
|
||||
class PluginAPI extends stdClass{
|
||||
private $server;
|
||||
private $plugins = array();
|
||||
private $randomNonce;
|
||||
public function __construct(){
|
||||
$this->server = ServerAPI::request();
|
||||
$this->randomNonce = Utils::getRandomBytes(16, false);
|
||||
}
|
||||
|
||||
public function getList(){
|
||||
@ -33,17 +35,16 @@ class PluginAPI extends stdClass{
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
public function getInfo($className){
|
||||
$className = strtolower($className);
|
||||
if(!isset($this->plugins[$className])){
|
||||
return false;
|
||||
}
|
||||
$plugin = $this->plugins[$className];
|
||||
return array($plugin[1], get_class_methods($plugin[0]));
|
||||
|
||||
public function getAll(){
|
||||
return $this->plugins;
|
||||
}
|
||||
|
||||
public function load($file){
|
||||
if(is_link($file) or is_dir($file) or !file_exists($file)){
|
||||
console("[ERROR] ".basename($file)." is not a file");
|
||||
return false;
|
||||
}
|
||||
if(strtolower(substr($file, -3)) === "pmf"){
|
||||
$pmf = new PMFPlugin($file);
|
||||
$info = $pmf->getPluginInfo();
|
||||
@ -79,13 +80,13 @@ class PluginAPI extends stdClass{
|
||||
console("[ERROR] Failed parsing of ".basename($file));
|
||||
return false;
|
||||
}
|
||||
console("[INFO] Loading plugin \"\x1b[32m".$info["name"]."\x1b[0m\" \x1b[35m".$info["version"]." \x1b[0mby \x1b[36m".$info["author"]."\x1b[0m");
|
||||
console("[INFO] Loading plugin \"".FORMAT_GREEN.$info["name"].FORMAT_RESET."\" ".FORMAT_AQUA.$info["version"].FORMAT_RESET." by ".FORMAT_AQUA.$info["author"].FORMAT_RESET);
|
||||
if($info["class"] !== "none" and class_exists($info["class"])){
|
||||
console("[ERROR] Failed loading plugin: class already exists");
|
||||
return false;
|
||||
}
|
||||
if(eval($info["code"]) === false or ($info["class"] !== "none" and !class_exists($info["class"]))){
|
||||
console("[ERROR] Failed loading plugin: evaluation error");
|
||||
if(((!isset($pmf) and (include $file) === false) or (isset($pmf) and eval($info["code"]) === false)) and $info["class"] !== "none" and !class_exists($info["class"])){
|
||||
console("[ERROR] Failed loading {$info['name']}: evaluation error");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -95,39 +96,60 @@ class PluginAPI extends stdClass{
|
||||
console("[WARNING] Plugin \"".$info["name"]."\" may not be compatible with the API (".$info["apiversion"]." != ".CURRENT_API_VERSION.")! It can crash or corrupt the server!");
|
||||
}
|
||||
|
||||
$identifier = $this->getIdentifier($info["name"], $info["author"]);
|
||||
|
||||
if($info["class"] !== "none"){
|
||||
$object = new $className($this->server->api, false);
|
||||
if(!($object instanceof Plugin)){
|
||||
console("[ERROR] Plugin \"\x1b[36m".$info["name"]."\x1b[0m\" doesn't use the Plugin Interface");
|
||||
console("[ERROR] Plugin \"".$info["name"]."\" doesn't use the Plugin Interface");
|
||||
if(method_exists($object, "__destruct")){
|
||||
$object->__destruct();
|
||||
}
|
||||
$object = null;
|
||||
unset($object);
|
||||
}else{
|
||||
$this->plugins[$className] = array($object, $info);
|
||||
$this->plugins[$identifier] = array($object, $info);
|
||||
}
|
||||
}else{
|
||||
$this->plugins[md5($info["name"])] = array(new DummyPlugin($this->server->api, false), $info);
|
||||
$this->plugins[$identifier] = array(new DummyPlugin($this->server->api, false), $info);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function get(Plugin $plugin){
|
||||
foreach($this->plugins as &$p){
|
||||
if($p[0] === $plugin){
|
||||
return $p;
|
||||
public function getIdentifier($name, $author){
|
||||
return sha1(trim(strtolower($name)), true) ^ sha1(trim(strtolower($author)), true) ^ sha1($this->randomNonce, true);
|
||||
}
|
||||
|
||||
public function get($identifier){
|
||||
if($identifier instanceof Plugin){
|
||||
foreach($this->plugins as $p){
|
||||
if($p[0] === $identifier){
|
||||
return $p;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if(isset($this->plugins[$identifier])){
|
||||
return $this->plugins[$identifier];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function pluginsPath(){
|
||||
$path = join(DIRECTORY_SEPARATOR, array(DATA_PATH."plugins", ""));
|
||||
@mkdir($path);
|
||||
return $path;
|
||||
}
|
||||
|
||||
|
||||
public function configPath(Plugin $plugin){
|
||||
$p = $this->get($plugin);
|
||||
$identifier = $this->getIdentifier($p[1]["name"], $p[1]["author"]);
|
||||
if($p === false){
|
||||
return false;
|
||||
}
|
||||
$path = DATA_PATH."plugins/".$p[1]["name"]."/";
|
||||
$this->plugins[$p[1]["class"]][1]["path"] = $path;
|
||||
$path = $this->pluginsPath() . $p[1]["name"] . DIRECTORY_SEPARATOR;
|
||||
$this->plugins[$identifier][1]["path"] = $path;
|
||||
@mkdir($path);
|
||||
return $path;
|
||||
}
|
||||
@ -169,13 +191,13 @@ class PluginAPI extends stdClass{
|
||||
$this->loadAll();
|
||||
}
|
||||
|
||||
public function loadAll(){
|
||||
$dir = dir(DATA_PATH."plugins/");
|
||||
private function loadAll(){
|
||||
$dir = dir($this->pluginsPath());
|
||||
while(false !== ($file = $dir->read())){
|
||||
if($file{0} !== "."){
|
||||
$ext = strtolower(substr($file, -3));
|
||||
if($ext === "php" or $ext === "pmf"){
|
||||
$this->load(DATA_PATH."plugins/" . $file);
|
||||
$this->load($dir->path . $file);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -205,4 +227,4 @@ class DummyPlugin implements Plugin{
|
||||
|
||||
public function __destruct(){
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,57 @@ class ServerAPI{
|
||||
private $asyncCnt = 0;
|
||||
private $rcon;
|
||||
private $query;
|
||||
|
||||
|
||||
//TODO: Instead of hard-coding functions, use PHPDoc-compatible methods to load APIs.
|
||||
|
||||
/**
|
||||
* @var ConsoleAPI
|
||||
*/
|
||||
public $console;
|
||||
|
||||
/**
|
||||
* @var LevelAPI
|
||||
*/
|
||||
public $level;
|
||||
|
||||
/**
|
||||
* @var BlockAPI
|
||||
*/
|
||||
public $block;
|
||||
|
||||
/**
|
||||
* @var ChatAPI
|
||||
*/
|
||||
public $chat;
|
||||
|
||||
/**
|
||||
* @var BanAPI
|
||||
*/
|
||||
public $ban;
|
||||
|
||||
/**
|
||||
* @var EntityAPI
|
||||
*/
|
||||
public $entity;
|
||||
|
||||
/**
|
||||
* @var TimeAPI
|
||||
*/
|
||||
public $time;
|
||||
|
||||
/**
|
||||
* @var PlayerAPI
|
||||
*/
|
||||
public $player;
|
||||
|
||||
/**
|
||||
* @var TileAPI
|
||||
*/
|
||||
public $tile;
|
||||
|
||||
/**
|
||||
* @return PocketMinecraftServer
|
||||
*/
|
||||
public static function request(){
|
||||
return self::$serverRequest;
|
||||
}
|
||||
@ -48,7 +98,7 @@ class ServerAPI{
|
||||
@mkdir(DATA_PATH."worlds/", 0755);
|
||||
@mkdir(DATA_PATH."plugins/", 0755);
|
||||
$version = new VersionString();
|
||||
console("[INFO] Starting Minecraft PE server version \x1b[36;1m".CURRENT_MINECRAFT_VERSION);
|
||||
console("[INFO] Starting Minecraft PE server version ".FORMAT_AQUA.CURRENT_MINECRAFT_VERSION);
|
||||
|
||||
console("[INFO] Loading properties...");
|
||||
$this->config = new Config(DATA_PATH . "server.properties", CONFIG_PROPERTIES, array(
|
||||
@ -61,6 +111,7 @@ class ServerAPI{
|
||||
"memory-limit" => "128M",
|
||||
"last-update" => false,
|
||||
"white-list" => false,
|
||||
"announce-player-achievements" => true,
|
||||
"spawn-protection" => 16,
|
||||
"view-distance" => 10,
|
||||
"max-players" => 20,
|
||||
@ -92,7 +143,7 @@ class ServerAPI{
|
||||
$this->server = new PocketMinecraftServer($this->getProperty("server-name"), $this->getProperty("gamemode"), ($seed = $this->getProperty("level-seed")) != "" ? (int) $seed:false, $this->getProperty("server-port"), ($ip = $this->getProperty("server-ip")) != "" ? $ip:"0.0.0.0");
|
||||
$this->server->api = $this;
|
||||
self::$serverRequest = $this->server;
|
||||
console("[INFO] This server is running PocketMine-MP version ".($version->isDev() ? "\x1b[31;1m":"").MAJOR_VERSION."\x1b[0m (MCPE: ".CURRENT_MINECRAFT_VERSION.") (API ".CURRENT_API_VERSION.")", true, true, 0);
|
||||
console("[INFO] This server is running PocketMine-MP version ".($version->isDev() ? FORMAT_YELLOW:"").MAJOR_VERSION.FORMAT_RESET." \"".CODENAME."\" (MCPE: ".CURRENT_MINECRAFT_VERSION.") (API ".CURRENT_API_VERSION.")", true, true, 0);
|
||||
console("[INFO] PocketMine-MP is distibuted under the LGPL License", true, true, 0);
|
||||
|
||||
if($this->getProperty("upnp-forwarding") === true){
|
||||
@ -102,39 +153,41 @@ class ServerAPI{
|
||||
|
||||
if($this->getProperty("last-update") === false or ($this->getProperty("last-update") + 3600) < time()){
|
||||
console("[INFO] Checking for new server version");
|
||||
console("[INFO] Last check: \x1b[36m".date("Y-m-d H:i:s", $this->getProperty("last-update"))."\x1b[0m");
|
||||
$info = json_decode(Utils::curl_get("http://www.pocketmine.net/latest"), true);
|
||||
console("[INFO] Last check: ".FORMAT_AQUA.date("Y-m-d H:i:s", $this->getProperty("last-update"))."\x1b[0m");
|
||||
if($this->server->version->isDev()){
|
||||
if($info === false or !isset($info["development"])){
|
||||
console("[ERROR] PocketMine API error");
|
||||
$info = json_decode(Utils::curl_get("https://api.github.com/repos/PocketMine/PocketMine-MP/commits"), true);
|
||||
if($info === false or !isset($info[0])){
|
||||
console("[ERROR] Github API error");
|
||||
}else{
|
||||
$last = $info["development"]["date"];
|
||||
if($last >= $this->getProperty("last-update") and $this->getProperty("last-update") !== false and GIT_COMMIT != $info["development"]["commit"]){
|
||||
console("[NOTICE] \x1b[33mA new DEVELOPMENT version of PocketMine-MP has been released");
|
||||
console("[NOTICE] \x1b[33mVersion \"".$info["development"]["version"]."\" [".substr($info["development"]["commit"], 0, 10)."]");
|
||||
console("[NOTICE] \x1b[36mGet it at PocketMine.net or ".$info["development"]["download"]);
|
||||
$last = new DateTime($info[0]["commit"]["committer"]["date"]);
|
||||
$last = $last->getTimestamp();
|
||||
if($last >= $this->getProperty("last-update") and $this->getProperty("last-update") !== false and GIT_COMMIT != $info[0]["sha"]){
|
||||
console("[NOTICE] ".FORMAT_YELLOW."A new DEVELOPMENT version of PocketMine-MP has been released!");
|
||||
console("[NOTICE] ".FORMAT_YELLOW."Commit \"".$info[0]["commit"]["message"]."\" [".substr($info[0]["sha"], 0, 10)."] by ".$info[0]["commit"]["committer"]["name"]);
|
||||
console("[NOTICE] ".FORMAT_YELLOW."Get it at PocketMine.net or at https://github.com/PocketMine/PocketMine-MP/archive/".$info[0]["sha"].".zip");
|
||||
console("[NOTICE] This message will dissapear after issuing the command \"/update-done\"");
|
||||
}else{
|
||||
$this->setProperty("last-update", time());
|
||||
console("[INFO] \x1b[36mThis is the latest DEVELOPMENT version");
|
||||
console("[INFO] ".FORMAT_AQUA."This is the latest DEVELOPMENT version");
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if($info === false or !isset($info["stable"])){
|
||||
console("[ERROR] PocketMine API error");
|
||||
$info = json_decode(Utils::curl_get("https://api.github.com/repos/PocketMine/PocketMine-MP/tags"), true);
|
||||
if($info === false or !isset($info[0])){
|
||||
console("[ERROR] Github API error");
|
||||
}else{
|
||||
$newest = new VersionString(MAJOR_VERSION);
|
||||
$newestN = $newest->getNumber();
|
||||
$update = new VersionString($info["stable"]["version"]);
|
||||
$update = new VersionString($info[0]["name"]);
|
||||
$updateN = $update->getNumber();
|
||||
if($updateN > $newestN){
|
||||
console("[NOTICE] \x1b[33mA new STABLE version of PocketMine-MP has been released");
|
||||
console("[NOTICE] \x1b[36mVersion \"".$info["stable"]["version"]."\" #".$updateN);
|
||||
console("[NOTICE] Get it at PocketMine.net or ".$info["stable"]["download"]);
|
||||
console("[NOTICE] ".FORMAT_GREEN."A new STABLE version of PocketMine-MP has been released!");
|
||||
console("[NOTICE] ".FORMAT_GREEN."Version \"".$info[0]["name"]."\" #".$updateN);
|
||||
console("[NOTICE] Get it at PocketMine.net or at ".$info[0]["zipball_url"]);
|
||||
console("[NOTICE] This message will dissapear as soon as you update");
|
||||
}else{
|
||||
$this->setProperty("last-update", time());
|
||||
console("[INFO] \x1b[36mThis is the latest STABLE version");
|
||||
console("[INFO] ".FORMAT_AQUA."This is the latest STABLE version");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -276,6 +329,10 @@ class ServerAPI{
|
||||
}
|
||||
|
||||
public function init(){
|
||||
if(!(self::$serverRequest instanceof PocketMinecraftServer)){
|
||||
self::$serverRequest = $this->server;
|
||||
}
|
||||
|
||||
if($this->getProperty("send-usage") !== false){
|
||||
$this->server->schedule(6000, array($this, "sendUsage"), array(), true); //Send the info after 5 minutes have passed
|
||||
$this->sendUsage();
|
||||
|
362
src/Player.php
362
src/Player.php
@ -44,6 +44,7 @@ class Player{
|
||||
private $startAction = false;
|
||||
private $isSleeping = false;
|
||||
public $data;
|
||||
/** @var \Entity */
|
||||
public $entity = false;
|
||||
public $auth = false;
|
||||
public $CID;
|
||||
@ -58,6 +59,7 @@ class Player{
|
||||
public $windowCnt = 2;
|
||||
public $windows = array();
|
||||
public $blocked = true;
|
||||
public $achievements = array();
|
||||
public $chunksLoaded = array();
|
||||
private $chunksOrder = array();
|
||||
private $lastMeasure = 0;
|
||||
@ -77,6 +79,8 @@ class Player{
|
||||
private $chunkCount = array();
|
||||
private $received = array();
|
||||
public $realmsData = array();
|
||||
/** @var \Level */
|
||||
public $level;
|
||||
|
||||
public function __get($name){
|
||||
if(isset($this->{$name})){
|
||||
@ -84,7 +88,13 @@ class Player{
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param integer $clientID
|
||||
* @param string $ip
|
||||
* @param integer $port
|
||||
* @param integer $MTU
|
||||
*/
|
||||
public function __construct($clientID, $ip, $port, $MTU){
|
||||
$this->bigCnt = 0;
|
||||
$this->MTU = $MTU;
|
||||
@ -111,9 +121,12 @@ class Player{
|
||||
public function getSpawn(){
|
||||
return $this->spawnPosition;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Vector3 $pos
|
||||
*/
|
||||
public function setSpawn(Vector3 $pos){
|
||||
if(!($pos instanceof Level)){
|
||||
if(!($pos instanceof Position)){
|
||||
$level = $this->level;
|
||||
}else{
|
||||
$level = $pos->level;
|
||||
@ -216,6 +229,7 @@ class Player{
|
||||
|
||||
public function save(){
|
||||
if($this->entity instanceof Entity){
|
||||
$this->data->set("achievements", $this->achievements);
|
||||
$this->data->set("position", array(
|
||||
"level" => $this->entity->level->getName(),
|
||||
"x" => $this->entity->x,
|
||||
@ -252,6 +266,10 @@ class Player{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $reason Reason for closing connection
|
||||
* @param boolean $msg Set to false to silently disconnect player. No broadcast.
|
||||
*/
|
||||
public function close($reason = "", $msg = true){
|
||||
if($this->connected === true){
|
||||
foreach($this->evid as $ev){
|
||||
@ -280,7 +298,7 @@ class Player{
|
||||
if($msg === true and $this->username != ""){
|
||||
$this->server->api->chat->broadcast($this->username." left the game");
|
||||
}
|
||||
console("[INFO] \x1b[33m".$this->username."\x1b[0m[/".$this->ip.":".$this->port."] logged out due to ".$reason);
|
||||
console("[INFO] ".FORMAT_AQUA.$this->username.FORMAT_RESET."[/".$this->ip.":".$this->port."] logged out due to ".$reason);
|
||||
$this->windows = array();
|
||||
$this->armor = array();
|
||||
$this->inventory = array();
|
||||
@ -291,17 +309,22 @@ class Player{
|
||||
$this->received = array();
|
||||
}
|
||||
}
|
||||
|
||||
public function sleepOn(Vector3 $pos){
|
||||
|
||||
/**
|
||||
* @param Vector3 $pos
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function sleepOn(Vector3 $pos){
|
||||
foreach($this->server->api->player->getAll($this->level) as $p){
|
||||
if($p->isSleeping instanceof Vector3){
|
||||
if($p->distance($pos) <= 0.1){
|
||||
if($pos->distance($p->isSleeping) <= 0.1){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->isSleeping = $pos;
|
||||
$this->teleport(new Position($pos->x, $pos->y, $pos->z, $this->level));
|
||||
$this->teleport(new Position($pos->x + 0.5, $pos->y + 1, $pos->z + 0.5, $this->level), false, false, false, false);
|
||||
if($this->entity instanceof Entity){
|
||||
$this->entity->updateMetadata();
|
||||
}
|
||||
@ -332,8 +355,15 @@ class Player{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function hasSpace($type, $damage, $count){
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @param $damage
|
||||
* @param $count
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasSpace($type, $damage, $count){
|
||||
$inv = $this->inventory;
|
||||
while($count > 0){
|
||||
$add = 0;
|
||||
@ -351,7 +381,7 @@ class Player{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if($add === 0){
|
||||
if($add <= 0){
|
||||
return false;
|
||||
}
|
||||
$count -= $add;
|
||||
@ -359,7 +389,15 @@ class Player{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function addItem($type, $damage, $count, $send = true){
|
||||
/**
|
||||
* @param $type
|
||||
* @param $damage
|
||||
* @param integer $count
|
||||
* @param boolean $send
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function addItem($type, $damage, $count, $send = true){
|
||||
while($count > 0){
|
||||
$add = 0;
|
||||
foreach($this->inventory as $s => $item){
|
||||
@ -382,7 +420,7 @@ class Player{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if($add === 0){
|
||||
if($add <= 0){
|
||||
return false;
|
||||
}
|
||||
$count -= $add;
|
||||
@ -407,23 +445,35 @@ class Player{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if($remove === 0){
|
||||
if($remove <= 0){
|
||||
return false;
|
||||
}
|
||||
$count -= $remove;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function setSlot($slot, Item $item, $send = true){
|
||||
|
||||
/**
|
||||
* @param integer $slot
|
||||
* @param Item $item
|
||||
* @param boolean $send
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function setSlot($slot, Item $item, $send = true){
|
||||
$this->inventory[(int) $slot] = $item;
|
||||
if($send === true){
|
||||
$this->sendInventorySlot((int) $slot);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getSlot($slot){
|
||||
|
||||
/**
|
||||
* @param integer $slot
|
||||
*
|
||||
* @return Item
|
||||
*/
|
||||
public function getSlot($slot){
|
||||
if(isset($this->inventory[(int) $slot])){
|
||||
return $this->inventory[(int) $slot];
|
||||
}else{
|
||||
@ -463,8 +513,13 @@ class Player{
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getArmor($slot){
|
||||
|
||||
/**
|
||||
* @param integer $slot
|
||||
*
|
||||
* @return Item
|
||||
*/
|
||||
public function getArmor($slot){
|
||||
if(isset($this->armor[(int) $slot])){
|
||||
return $this->armor[(int) $slot];
|
||||
}else{
|
||||
@ -480,8 +535,12 @@ class Player{
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function eventHandler($data, $event){
|
||||
|
||||
/**
|
||||
* @param mixed $data
|
||||
* @param string $event
|
||||
*/
|
||||
public function eventHandler($data, $event){
|
||||
switch($event){
|
||||
case "tile.update":
|
||||
if($data->level === $this->level){
|
||||
@ -534,6 +593,14 @@ class Player{
|
||||
if(($this->gamemode & 0x01) === 0x00){
|
||||
$this->addItem($data["entity"]->type, $data["entity"]->meta, $data["entity"]->stack, false);
|
||||
}
|
||||
switch($data["entity"]->type){
|
||||
case WOOD:
|
||||
AchievementAPI::grantAchievement($this, "mineWood");
|
||||
break;
|
||||
case DIAMOND:
|
||||
AchievementAPI::grantAchievement($this, "diamond");
|
||||
break;
|
||||
}
|
||||
}elseif($data["entity"]->level === $this->level){
|
||||
$this->dataPacket(MC_TAKE_ITEM_ENTITY, $data);
|
||||
}
|
||||
@ -607,8 +674,12 @@ class Player{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function sendChat($message, $author = ""){
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param string $author
|
||||
*/
|
||||
public function sendChat($message, $author = ""){
|
||||
$mes = explode("\n", $message);
|
||||
foreach($mes as $m){
|
||||
if(preg_match_all('#@([@A-Za-z_]{1,})#', $m, $matches, PREG_OFFSET_CAPTURE) > 0){
|
||||
@ -632,7 +703,7 @@ class Player{
|
||||
if($m !== ""){
|
||||
$this->dataPacket(MC_CHAT, array(
|
||||
"player" => ($author instanceof Player) ? $author->username:$author,
|
||||
"message" => $m,
|
||||
"message" => TextFormat::clean($m), //Colors not implemented :(
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -687,8 +758,15 @@ class Player{
|
||||
"flags" => $flags,
|
||||
));
|
||||
}
|
||||
|
||||
public function craftItems(array $craft, array $recipe, $type){
|
||||
|
||||
/**
|
||||
* @param array $craft
|
||||
* @param array $recipe
|
||||
* @param $type
|
||||
*
|
||||
* @return array|bool
|
||||
*/
|
||||
public function craftItems(array $craft, array $recipe, $type){
|
||||
$craftItem = array(0, true, 0);
|
||||
unset($craft[-1]);
|
||||
foreach($craft as $slot => $item){
|
||||
@ -726,6 +804,10 @@ class Player{
|
||||
}
|
||||
|
||||
if(is_array($res)){
|
||||
|
||||
if($this->server->api->dhandle("player.craft", array("player" => $this, "recipe" => $recipe, "craft" => $craft, "type" => $type)) === false){
|
||||
return false;
|
||||
}
|
||||
foreach($recipe as $slot => $item){
|
||||
$s = $this->getSlot($slot);
|
||||
$s->count -= $item->count;
|
||||
@ -740,13 +822,59 @@ class Player{
|
||||
}else{
|
||||
$this->setSlot($slot, BlockAPI::getItem($item->getID(), $item->getMetadata(), $s->count + $item->count), false);
|
||||
}
|
||||
|
||||
switch($item->getID()){
|
||||
case WORKBENCH:
|
||||
AchievementAPI::grantAchievement($this, "buildWorkBench");
|
||||
break;
|
||||
case WOODEN_PICKAXE:
|
||||
AchievementAPI::grantAchievement($this, "buildPickaxe");
|
||||
break;
|
||||
case FURNACE:
|
||||
AchievementAPI::grantAchievement($this, "buildFurnace");
|
||||
break;
|
||||
case WOODEN_HOE:
|
||||
AchievementAPI::grantAchievement($this, "buildHoe");
|
||||
break;
|
||||
case BREAD:
|
||||
AchievementAPI::grantAchievement($this, "makeBread");
|
||||
break;
|
||||
case CAKE:
|
||||
AchievementAPI::grantAchievement($this, "bakeCake");
|
||||
break;
|
||||
case STONE_PICKAXE:
|
||||
case GOLD_PICKAXE:
|
||||
case IRON_PICKAXE:
|
||||
case DIAMOND_PICKAXE:
|
||||
AchievementAPI::grantAchievement($this, "buildBetterPickaxe");
|
||||
break;
|
||||
case WOODEN_SWORD:
|
||||
AchievementAPI::grantAchievement($this, "buildSword");
|
||||
break;
|
||||
case DIAMOND:
|
||||
AchievementAPI::grantAchievement($this, "diamond");
|
||||
break;
|
||||
case CAKE:
|
||||
$this->addItem(BUCKET, 0, 3, false);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function teleport(Vector3 $pos, $yaw = false, $pitch = false, $terrain = true, $force = true){
|
||||
if($this->entity instanceof Entity){
|
||||
|
||||
/**
|
||||
* @param Vector3 $pos
|
||||
* @param float|boolean $yaw
|
||||
* @param float|boolean $pitch
|
||||
* @param float|boolean $terrain
|
||||
* @param float|boolean $force
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function teleport(Vector3 $pos, $yaw = false, $pitch = false, $terrain = true, $force = true){
|
||||
if($this->entity instanceof Entity and $this->level instanceof Level){
|
||||
$this->entity->check = false;
|
||||
if($yaw === false){
|
||||
$yaw = $this->entity->yaw;
|
||||
@ -852,8 +980,9 @@ class Player{
|
||||
"x" => $pos->x,
|
||||
"y" => $pos->y,
|
||||
"z" => $pos->z,
|
||||
"yaw" => $yaw,
|
||||
"bodyYaw" => $yaw,
|
||||
"pitch" => $pitch,
|
||||
"yaw" => $yaw,
|
||||
));
|
||||
}
|
||||
|
||||
@ -1099,10 +1228,10 @@ class Player{
|
||||
case MC_PONG:
|
||||
break;
|
||||
case MC_PING:
|
||||
$t = (int) (microtime(true) * 1000);
|
||||
$t = abs(microtime(true) * 1000);
|
||||
$this->dataPacket(MC_PONG, array(
|
||||
"ptime" => $data["time"],
|
||||
"time" => (int) (microtime(true) * 1000),
|
||||
"time" => $t,
|
||||
));
|
||||
$this->sendBuffer();
|
||||
break;
|
||||
@ -1167,7 +1296,7 @@ class Player{
|
||||
}
|
||||
$this->loggedIn = true;
|
||||
|
||||
$u = $this->server->api->player->get($this->iusername);
|
||||
$u = $this->server->api->player->get($this->iusername, false);
|
||||
if($u !== false){
|
||||
$u->close("logged in from another location");
|
||||
}
|
||||
@ -1199,6 +1328,7 @@ class Player{
|
||||
}
|
||||
$this->data->set("inventory", $inv);
|
||||
}
|
||||
$this->achievements = $this->data->get("achievements");
|
||||
$this->data->set("caseusername", $this->username);
|
||||
$this->inventory = array();
|
||||
foreach($this->data->get("inventory") as $slot => $item){
|
||||
@ -1216,9 +1346,8 @@ class Player{
|
||||
$this->data->set("lastIP", $this->ip);
|
||||
$this->data->set("lastID", $this->clientID);
|
||||
|
||||
if($this->data instanceof Config){
|
||||
$this->server->api->player->saveOffline($this->data);
|
||||
}
|
||||
$this->server->api->player->saveOffline($this->data);
|
||||
|
||||
$this->dataPacket(MC_LOGIN_STATUS, array(
|
||||
"status" => 0,
|
||||
));
|
||||
@ -1232,7 +1361,7 @@ class Player{
|
||||
"eid" => 0,
|
||||
));
|
||||
if(($this->gamemode & 0x01) === 0x01){
|
||||
$this->slot = -1;//7
|
||||
$this->slot = 0;
|
||||
}else{
|
||||
$this->slot = -1;//0
|
||||
}
|
||||
@ -1265,7 +1394,7 @@ class Player{
|
||||
$this->evid[] = $this->server->event("tile.update", array($this, "eventHandler"));
|
||||
$this->lastMeasure = microtime(true);
|
||||
$this->server->schedule(50, array($this, "measureLag"), array(), true);
|
||||
console("[INFO] \x1b[33m".$this->username."\x1b[0m[/".$this->ip.":".$this->port."] logged in with entity id ".$this->eid." at (".$this->entity->level->getName().", ".round($this->entity->x, 2).", ".round($this->entity->y, 2).", ".round($this->entity->z, 2).")");
|
||||
console("[INFO] ".FORMAT_AQUA.$this->username.FORMAT_RESET."[/".$this->ip.":".$this->port."] logged in with entity id ".$this->eid." at (".$this->entity->level->getName().", ".round($this->entity->x, 2).", ".round($this->entity->y, 2).", ".round($this->entity->z, 2).")");
|
||||
break;
|
||||
case MC_READY:
|
||||
if($this->loggedIn === false){
|
||||
@ -1284,6 +1413,7 @@ class Player{
|
||||
$this->server->api->entity->spawnToAll($this->entity);
|
||||
|
||||
$this->server->schedule(5, array($this->entity, "update"), array(), true);
|
||||
$this->server->schedule(2, array($this->entity, "updateMovement"), array(), true);
|
||||
$this->sendArmor();
|
||||
$this->sendChat($this->server->motd."\n");
|
||||
|
||||
@ -1297,16 +1427,32 @@ class Player{
|
||||
$this->dataPacket(MC_SET_TIME, array(
|
||||
"time" => $this->level->getTime(),
|
||||
));
|
||||
$this->teleport(new Position($this->data->get("position")["x"], $this->data->get("position")["y"], $this->data->get("position")["z"], $this->level));
|
||||
$this->server->schedule(10, array($this, "teleport"), new Position($this->data->get("position")["x"], $this->data->get("position")["y"], $this->data->get("position")["z"], $this->level));
|
||||
$this->server->schedule(20, array($this, "teleport"), new Position($this->data->get("position")["x"], $this->data->get("position")["y"], $this->data->get("position")["z"], $this->level));
|
||||
$this->server->schedule(30, array($this, "teleport"), new Position($this->data->get("position")["x"], $this->data->get("position")["y"], $this->data->get("position")["z"], $this->level));
|
||||
$pos = new Position($this->data->get("position")["x"], $this->data->get("position")["y"], $this->data->get("position")["z"], $this->level);
|
||||
$pos = $this->level->getSafeSpawn($pos);
|
||||
$this->teleport($pos);
|
||||
$this->server->schedule(10, array($this, "teleport"), $pos);
|
||||
$this->server->schedule(20, array($this, "teleport"), $pos);
|
||||
$this->server->schedule(30, array($this, "teleport"), $pos);
|
||||
$this->server->handle("player.spawn", $this);
|
||||
break;
|
||||
case 2://Chunk loaded?
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MC_ROTATE_HEAD:
|
||||
if($this->spawned === false){
|
||||
break;
|
||||
}
|
||||
if(($this->entity instanceof Entity)){
|
||||
if($this->blocked === true or $this->server->api->handle("player.move", $this->entity) === false){
|
||||
if($this->lastCorrect instanceof Vector3){
|
||||
$this->teleport($this->lastCorrect, $this->entity->yaw, $this->entity->pitch, false);
|
||||
}
|
||||
}else{
|
||||
$this->entity->setPosition($this->entity, $data["yaw"], $data["pitch"]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MC_MOVE_PLAYER:
|
||||
if($this->spawned === false){
|
||||
break;
|
||||
@ -1321,7 +1467,7 @@ class Player{
|
||||
}
|
||||
}
|
||||
$speed = $this->entity->getSpeedMeasure();
|
||||
if($this->blocked === true or ($this->server->api->getProperty("allow-flight") !== true and (($speed > 7 and ($this->gamemode & 0x01) === 0x00) or $speed > 15)) or $this->server->api->handle("player.move", $this->entity) === false){
|
||||
if($this->blocked === true or ($this->server->api->getProperty("allow-flight") !== true and (($speed > 9 and ($this->gamemode & 0x01) === 0x00) or $speed > 20)) or $this->server->api->handle("player.move", $this->entity) === false){
|
||||
if($this->lastCorrect instanceof Vector3){
|
||||
$this->teleport($this->lastCorrect, $this->entity->yaw, $this->entity->pitch, false);
|
||||
}
|
||||
@ -1341,7 +1487,7 @@ class Player{
|
||||
$data["eid"] = $this->eid;
|
||||
$data["player"] = $this;
|
||||
|
||||
if($data["slot"] === 0){
|
||||
if($data["slot"] === 0x28 or $data["slot"] === 0){ //0 for 0.8.0 compatibility
|
||||
$data["slot"] = -1;
|
||||
$data["item"] = BlockAPI::getItem(AIR, 0, 0);
|
||||
if($this->server->handle("player.equipment.change", $data) !== false){
|
||||
@ -1352,9 +1498,26 @@ class Player{
|
||||
$data["slot"] -= 9;
|
||||
}
|
||||
|
||||
$data["item"] = $this->getSlot($data["slot"]);
|
||||
if(!($data["item"] instanceof Item)){
|
||||
break;
|
||||
|
||||
if(($this->gamemode & 0x01) === SURVIVAL){
|
||||
$data["item"] = $this->getSlot($data["slot"]);
|
||||
if(!($data["item"] instanceof Item)){
|
||||
break;
|
||||
}
|
||||
}elseif(($this->gamemode & 0x01) === CREATIVE){
|
||||
$data["slot"] = false;
|
||||
foreach(BlockAPI::$creative as $i => $d){
|
||||
if($d[0] === $data["block"] and $d[1] === $data["meta"]){
|
||||
$data["slot"] = $i;
|
||||
}
|
||||
}
|
||||
if($data["slot"] !== false){
|
||||
$data["item"] = $this->getSlot($data["slot"]);
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
break;//?????
|
||||
}
|
||||
$data["block"] = $data["item"]->getID();
|
||||
$data["meta"] = $data["item"]->getMetadata();
|
||||
@ -1451,6 +1614,53 @@ class Player{
|
||||
"z" => $this->entity->z,
|
||||
);
|
||||
$e = $this->server->api->entity->add($this->level, ENTITY_OBJECT, OBJECT_ARROW, $d);
|
||||
$e->yaw = $this->entity->yaw;
|
||||
$e->pitch = $this->entity->pitch;
|
||||
$rotation = ($this->entity->yaw - 90) % 360;
|
||||
if($rotation < 0){
|
||||
$rotation = (360 + $rotation);
|
||||
}
|
||||
$rotation = ($rotation + 180);
|
||||
if($rotation >= 360){
|
||||
$rotation = ($rotation - 360);
|
||||
}
|
||||
$X = 1;
|
||||
$Z = 1;
|
||||
$overturn = false;
|
||||
if(0 <= $rotation and $rotation < 90){
|
||||
|
||||
}
|
||||
elseif(90 <= $rotation and $rotation < 180){
|
||||
$rotation -= 90;
|
||||
$X = (-1);
|
||||
$overturn = true;
|
||||
}
|
||||
elseif(180 <= $rotation and $rotation < 270){
|
||||
$rotation -= 180;
|
||||
$X = (-1);
|
||||
$Z = (-1);
|
||||
}
|
||||
elseif(270 <= $rotation and $rotation < 360){
|
||||
$rotation -= 270;
|
||||
$Z = (-1);
|
||||
$overturn = true;
|
||||
}
|
||||
$rad = deg2rad($rotation);
|
||||
$pitch = (-($this->entity->pitch));
|
||||
$speed = 80;
|
||||
$speedY = (sin(deg2rad($pitch)) * $speed);
|
||||
$speedXZ = (cos(deg2rad($pitch)) * $speed);
|
||||
if($overturn){
|
||||
$speedX = (sin($rad) * $speedXZ * $X);
|
||||
$speedZ = (cos($rad) * $speedXZ * $Z);
|
||||
}
|
||||
else{
|
||||
$speedX = (cos($rad) * $speedXZ * $X);
|
||||
$speedZ = (sin($rad) * $speedXZ * $Z);
|
||||
}
|
||||
$e->speedX = $speedX;
|
||||
$e->speedZ = $speedZ;
|
||||
$e->speedY = $speedY;
|
||||
$this->server->api->entity->spawnToAll($e);
|
||||
}
|
||||
}
|
||||
@ -1617,6 +1827,7 @@ class Player{
|
||||
}
|
||||
$this->craftingItems = array();
|
||||
$this->toCraft = array();
|
||||
$this->teleport($this->spawnPosition);
|
||||
if($this->entity instanceof Entity){
|
||||
$this->entity->fire = 0;
|
||||
$this->entity->air = 300;
|
||||
@ -1626,7 +1837,6 @@ class Player{
|
||||
break;
|
||||
}
|
||||
$this->sendInventory();
|
||||
$this->teleport($this->spawnPosition);
|
||||
$this->blocked = false;
|
||||
$this->server->handle("player.respawn", $this);
|
||||
break;
|
||||
@ -1648,6 +1858,7 @@ class Player{
|
||||
$items = array(
|
||||
APPLE => 2,
|
||||
MUSHROOM_STEW => 10,
|
||||
BEETROOT_SOUP => 10,
|
||||
BREAD => 5,
|
||||
RAW_PORKCHOP => 3,
|
||||
COOKED_PORKCHOP => 8,
|
||||
@ -1657,6 +1868,10 @@ class Player{
|
||||
RAW_CHICKEN => 2,
|
||||
MELON_SLICE => 2,
|
||||
GOLDEN_APPLE => 10,
|
||||
PUMPKIN_PIE => 8,
|
||||
CARROT => 4,
|
||||
POTATO => 1,
|
||||
BAKED_POTATO => 6,
|
||||
//COOKIE => 2,
|
||||
//COOKED_FISH => 5,
|
||||
//RAW_FISH => 2,
|
||||
@ -1672,6 +1887,9 @@ class Player{
|
||||
if($slot->count <= 0){
|
||||
$this->setSlot($this->slot, BlockAPI::getItem(AIR, 0, 0), false);
|
||||
}
|
||||
if($slot->getID() === MUSHROOM_STEW or $slot->getID() === BEETROOT_SOUP){
|
||||
$this->addItem(BOWL, 0, 1, false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1703,8 +1921,13 @@ class Player{
|
||||
if($message{0} === "/"){ //Command
|
||||
$this->server->api->console->run(substr($message, 1), $this);
|
||||
}else{
|
||||
if($this->server->api->dhandle("player.chat", array("player" => $this, "message" => $message)) !== false){
|
||||
$this->server->api->chat->send($this, $message);
|
||||
$data = array("player" => $this, "message" => $message);
|
||||
if($this->server->api->handle("player.chat", $data) !== false){
|
||||
if(isset($data["message"])){
|
||||
$this->server->api->chat->send($this, $data["message"]);
|
||||
}else{
|
||||
$this->server->api->chat->send($this, $message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1717,9 +1940,8 @@ class Player{
|
||||
$this->toCraft = array();
|
||||
if(isset($this->windows[$data["windowid"]])){
|
||||
if(is_array($this->windows[$data["windowid"]])){
|
||||
$all = $this->server->api->player->getAll($this->level);
|
||||
foreach($this->windows[$data["windowid"]] as $ob){
|
||||
$this->server->api->player->broadcastPacket($all, MC_TILE_EVENT, array(
|
||||
$this->server->api->player->broadcastPacket($this->level->players, MC_TILE_EVENT, array(
|
||||
"x" => $ob->x,
|
||||
"y" => $ob->y,
|
||||
"z" => $ob->z,
|
||||
@ -1876,6 +2098,15 @@ class Player{
|
||||
));
|
||||
break;
|
||||
}
|
||||
|
||||
if($tile->class === TILE_FURNACE and $data["slot"] == 2){
|
||||
switch($slot->getID()){
|
||||
case IRON_INGOT:
|
||||
AchievementAPI::grantAchievement($this, "acquireIron");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if($item->getID() !== AIR and $slot->getID() == $item->getID()){
|
||||
if($slot->count < $item->count){
|
||||
if($this->removeItem($item->getID(), $item->getMetadata(), $item->count - $slot->count, false) === false){
|
||||
@ -1925,8 +2156,11 @@ class Player{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function sendArmor($player = false){
|
||||
|
||||
/**
|
||||
* @param Player|string|boolean|void $player
|
||||
*/
|
||||
public function sendArmor($player = false){
|
||||
$data = array(
|
||||
"player" => $this,
|
||||
"eid" => $this->eid
|
||||
@ -1957,6 +2191,9 @@ class Player{
|
||||
}
|
||||
|
||||
public function sendInventory(){
|
||||
if(($this->gamemode & 0x01) === CREATIVE){
|
||||
return;
|
||||
}
|
||||
$this->dataPacket(MC_CONTAINER_SET_CONTENT, array(
|
||||
"windowid" => 0,
|
||||
"count" => count($this->inventory),
|
||||
@ -2025,7 +2262,13 @@ class Player{
|
||||
return array($count);
|
||||
}
|
||||
|
||||
public function dataPacket($id, $data = array()){
|
||||
/**
|
||||
* @param integer $id
|
||||
* @param array $data
|
||||
*
|
||||
* @return array|bool
|
||||
*/
|
||||
public function dataPacket($id, $data = array()){
|
||||
$data["id"] = $id;
|
||||
if($id === false){
|
||||
$raw = $data["raw"];
|
||||
@ -2045,8 +2288,11 @@ class Player{
|
||||
$this->buffer .= ($this->buffer === "" ? "":"\x40").Utils::writeShort($len << 3).strrev(Utils::writeTriad($this->counter[3]++)).$raw;
|
||||
return array();
|
||||
}
|
||||
|
||||
function __toString(){
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function __toString(){
|
||||
if($this->username != ""){
|
||||
return $this->username;
|
||||
}
|
||||
|
@ -21,14 +21,19 @@
|
||||
|
||||
class PocketMinecraftServer{
|
||||
public $tCnt;
|
||||
public $serverID, $interface, $database, $version, $invisible, $api, $tickMeasure, $preparedSQL, $seed, $gamemode, $name, $maxClients, $clients, $eidCnt, $custom, $description, $motd, $port, $saveEnabled;
|
||||
public $serverID, $interface, $database, $version, $invisible, $tickMeasure, $preparedSQL, $seed, $gamemode, $name, $maxClients, $clients, $eidCnt, $custom, $description, $motd, $port, $saveEnabled;
|
||||
private $serverip, $evCnt, $handCnt, $events, $eventsID, $handlers, $serverType, $lastTick, $ticks, $memoryStats, $async = array(), $asyncID = 0;
|
||||
|
||||
/**
|
||||
* @var ServerAPI
|
||||
*/
|
||||
public $api;
|
||||
|
||||
private function load(){
|
||||
$this->version = new VersionString();
|
||||
if(defined("DEBUG") and DEBUG >= 0){
|
||||
/*if(defined("DEBUG") and DEBUG >= 0){
|
||||
@cli_set_process_title("PocketMine-MP ".MAJOR_VERSION);
|
||||
}
|
||||
}*/
|
||||
console("[INFO] Starting Minecraft PE server on ".($this->serverip === "0.0.0.0" ? "*":$this->serverip).":".$this->port);
|
||||
define("BOOTUP_RANDOM", Utils::getRandomBytes(16));
|
||||
$this->serverID = $this->serverID === false ? Utils::readLong(Utils::getRandomBytes(8, false)):$this->serverID;
|
||||
@ -80,7 +85,10 @@ class PocketMinecraftServer{
|
||||
$this->load();
|
||||
}
|
||||
|
||||
public function getTPS(){
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getTPS(){
|
||||
$v = array_values($this->tickMeasure);
|
||||
$tps = 40 / ($v[39] - $v[0]);
|
||||
return round($tps, 4);
|
||||
@ -174,7 +182,10 @@ class PocketMinecraftServer{
|
||||
return $info;
|
||||
}
|
||||
|
||||
public function close($reason = "server stop"){
|
||||
/**
|
||||
* @param string $reason
|
||||
*/
|
||||
public function close($reason = "server stop"){
|
||||
if($this->stop !== true){
|
||||
if(is_int($reason)){
|
||||
$reason = "signal stop";
|
||||
@ -266,7 +277,14 @@ class PocketMinecraftServer{
|
||||
}
|
||||
}
|
||||
|
||||
public function addHandler($event,callable $callable, $priority = 5){
|
||||
/**
|
||||
* @param string $event
|
||||
* @param callable $callable
|
||||
* @param integer $priority
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function addHandler($event,callable $callable, $priority = 5){
|
||||
if(!is_callable($callable)){
|
||||
return false;
|
||||
}elseif(isset(Deprecation::$events[$event])){
|
||||
@ -334,7 +352,10 @@ class PocketMinecraftServer{
|
||||
}
|
||||
}
|
||||
|
||||
public function getGamemode(){
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getGamemode(){
|
||||
switch($this->gamemode){
|
||||
case SURVIVAL:
|
||||
return "survival";
|
||||
@ -421,8 +442,9 @@ class PocketMinecraftServer{
|
||||
}
|
||||
$dump .= "\r\n\r\n";
|
||||
$version = new VersionString();
|
||||
$dump .= "PM Version: ".$version." #".$version->getNumber()." [Protocol ".CURRENT_PROTOCOL."]\r\n";
|
||||
$dump .= "Commit: ".GIT_COMMIT."\r\n";
|
||||
$dump .= "PocketMine-MP version: ".$version." #".$version->getNumber()." [Protocol ".CURRENT_PROTOCOL."; API ".CURRENT_API_VERSION."]\r\n";
|
||||
$dump .= "Git commit: ".GIT_COMMIT."\r\n";
|
||||
$dump .= "Source SHA1 sum: ".SOURCE_SHA1SUM."\r\n";
|
||||
$dump .= "uname -a: ".php_uname("a")."\r\n";
|
||||
$dump .= "PHP Version: " .phpversion()."\r\n";
|
||||
$dump .= "Zend version: ".zend_version()."\r\n";
|
||||
|
@ -1,13 +1,13 @@
|
||||
#!/bin/bash
|
||||
COMPILER_VERSION="0.13"
|
||||
COMPILER_VERSION="0.14"
|
||||
|
||||
PHP_VERSION="5.5.3"
|
||||
PHP_VERSION="5.5.8"
|
||||
ZEND_VM="GOTO"
|
||||
|
||||
LIBEDIT_VERSION="0.3"
|
||||
ZLIB_VERSION="1.2.8"
|
||||
PTHREADS_VERSION="0.0.44"
|
||||
CURL_VERSION="curl-7_32_0"
|
||||
PTHREADS_VERSION="0.0.45"
|
||||
CURL_VERSION="curl-7_34_0"
|
||||
|
||||
echo "[PocketMine] PHP installer and compiler for Linux & Mac"
|
||||
DIR="$(pwd)"
|
||||
@ -78,6 +78,9 @@ elif [ "$1" == "crosscompile" ]; then
|
||||
fi
|
||||
else
|
||||
echo "[INFO] Compiling for current machine"
|
||||
if [ $(uname -m) == "x86_64" ]; then
|
||||
CFLAGS="-mx32 $CFLAGS"
|
||||
fi
|
||||
fi
|
||||
|
||||
type $CC >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"$CC\""; read -p "Press [Enter] to continue..."; exit 1; }
|
||||
@ -231,6 +234,7 @@ fi
|
||||
--exec-prefix="$DIR/php5" \
|
||||
--with-curl="$HAVE_CURL" \
|
||||
--with-zlib="$DIR/install_data/php/ext/zlib" \
|
||||
--with-zlib-dir="$DIR/install_data/php/ext/zlib" \
|
||||
$HAVE_LIBEDIT \
|
||||
--disable-libxml \
|
||||
--disable-xml \
|
||||
@ -240,9 +244,12 @@ $HAVE_LIBEDIT \
|
||||
--disable-xmlwriter \
|
||||
--disable-cgi \
|
||||
--disable-session \
|
||||
--disable-zip \
|
||||
--disable-debug \
|
||||
--disable-phar \
|
||||
--disable-pdo \
|
||||
--without-pear \
|
||||
--without-iconv \
|
||||
--without-pdo-sqlite \
|
||||
--enable-ctype \
|
||||
--enable-sockets \
|
||||
--enable-shared=no \
|
||||
@ -255,10 +262,7 @@ $HAVE_LIBEDIT \
|
||||
--enable-embedded-mysqli \
|
||||
--enable-bcmath \
|
||||
--enable-cli \
|
||||
--without-pear \
|
||||
--without-iconv \
|
||||
--disable-pdo \
|
||||
--without-pdo-sqlite \
|
||||
--enable-zip \
|
||||
--with-zend-vm=$ZEND_VM \
|
||||
$CONFIGURE_FLAGS >> "$DIR/install.log" 2>&1
|
||||
echo -n " compiling..."
|
||||
@ -276,5 +280,5 @@ mv php5/bin/php bin/php
|
||||
rm -r -f php5/ >> "$DIR/install.log" 2>&1
|
||||
date >> "$DIR/install.log" 2>&1
|
||||
echo " done!"
|
||||
echo "[PocketMine] You should start the server now using \"./start.sh\""
|
||||
echo "[PocketMine] If it doesn't works, please send the \"install.log\" file to the Bug Tracker"
|
||||
echo "[PocketMine] You should start the server now using \"./start.sh.\""
|
||||
echo "[PocketMine] If it doesn't work, please send the \"install.log\" file to the Bug Tracker."
|
||||
|
@ -28,7 +28,7 @@ if(strpos(" ".strtoupper(php_uname("s")), " WIN") !== false){
|
||||
exec("time.exe /T", $hour);
|
||||
$i = array_map("intval", explode(":", trim($hour[0])));
|
||||
exec("date.exe /T", $date);
|
||||
$j = array_map("intval", explode("/", trim($date[0])));
|
||||
$j = array_map("intval", explode(substr($date[0], 2, 1), trim($date[0])));
|
||||
$offset = round((mktime($i[0], $i[1], 0, $j[1], $j[0], $j[2]) - $time) / 60) * 60;
|
||||
}else{
|
||||
exec("date +%s", $t);
|
||||
@ -44,7 +44,7 @@ if($daylight === 0){
|
||||
date_default_timezone_set(timezone_name_from_abbr("", $offset, $daylight));
|
||||
|
||||
gc_enable();
|
||||
error_reporting(E_ALL ^ E_NOTICE);
|
||||
error_reporting(E_ALL | E_STRICT);
|
||||
ini_set("allow_url_fopen", 1);
|
||||
ini_set("display_errors", 1);
|
||||
ini_set("display_startup_errors", 1);
|
||||
@ -59,13 +59,14 @@ set_include_path(get_include_path() . PATH_SEPARATOR . FILE_PATH);
|
||||
ini_set("memory_limit", "128M"); //Default
|
||||
define("LOG", true);
|
||||
define("START_TIME", microtime(true));
|
||||
define("MAJOR_VERSION", "Alpha_1.3.8");
|
||||
define("CURRENT_MINECRAFT_VERSION", "0.7.5 alpha");
|
||||
define("CURRENT_API_VERSION", 10);
|
||||
define("MAJOR_VERSION", "Alpha_1.3.11");
|
||||
define("CODENAME", "甘いビートルート");
|
||||
define("CURRENT_MINECRAFT_VERSION", "v0.8.1 alpha");
|
||||
define("CURRENT_API_VERSION", 11);
|
||||
define("CURRENT_PHP_VERSION", "5.5");
|
||||
$gitsha1 = false;
|
||||
if(file_exists(FILE_PATH.".git/refs/heads/master")){ //Found Git information!
|
||||
define(GIT_COMMIT, strtolower(trim(file_get_contents(FILE_PATH.".git/refs/heads/master"))));
|
||||
define("GIT_COMMIT", strtolower(trim(file_get_contents(FILE_PATH.".git/refs/heads/master"))));
|
||||
}else{ //Unknown :(
|
||||
define(GIT_COMMIT, str_repeat("00", 20));
|
||||
define("GIT_COMMIT", str_repeat("00", 20));
|
||||
}
|
@ -45,7 +45,7 @@ define("WOOD", 17);
|
||||
define("TRUNK", 17);
|
||||
define("LEAVES", 18);
|
||||
define("LEAVE", 18);
|
||||
|
||||
define("SPONGE", 19);
|
||||
define("GLASS", 20);
|
||||
define("LAPIS_ORE", 21);
|
||||
define("LAPIS_BLOCK", 22);
|
||||
@ -83,6 +83,8 @@ define("FIRE", 51);
|
||||
|
||||
define("WOOD_STAIRS", 53);
|
||||
define("WOODEN_STAIRS", 53);
|
||||
define("OAK_WOOD_STAIRS", 53);
|
||||
define("OAK_WOODEN_STAIRS", 53);
|
||||
define("CHEST", 54);
|
||||
|
||||
define("DIAMOND_ORE", 56);
|
||||
@ -120,12 +122,15 @@ define("REEDS", 83);
|
||||
define("SUGARCANE_BLOCK", 83);
|
||||
|
||||
define("FENCE", 85);
|
||||
|
||||
define("PUMPKIN", 86);
|
||||
define("NETHERRACK", 87);
|
||||
define("SOUL_SAND", 88);
|
||||
define("GLOWSTONE", 89);
|
||||
define("GLOWSTONE_BLOCK", 89);
|
||||
|
||||
|
||||
define("LIT_PUMPKIN", 91);
|
||||
define("JACK_O_LANTERN", 91);
|
||||
define("CAKE_BLOCK", 92);
|
||||
|
||||
define("TRAPDOOR", 96);
|
||||
@ -133,10 +138,12 @@ define("TRAPDOOR", 96);
|
||||
define("STONE_BRICKS", 98);
|
||||
define("STONE_BRICK", 98);
|
||||
|
||||
define("IRON_BAR", 101);
|
||||
define("IRON_BARS", 101);
|
||||
define("GLASS_PANE", 102);
|
||||
define("GLASS_PANEL", 102);
|
||||
define("MELON_BLOCK", 103);
|
||||
|
||||
define("PUMPKIN_STEM", 104);
|
||||
define("MELON_STEM", 105);
|
||||
|
||||
define("FENCE_GATE", 107);
|
||||
@ -150,9 +157,37 @@ define("NETHER_BRICKS_STAIRS", 114);
|
||||
|
||||
define("SANDSTONE_STAIRS", 128);
|
||||
|
||||
define("SPRUCE_WOOD_STAIRS", 134);
|
||||
define("SPRUCE_WOODEN_STAIRS", 134);
|
||||
define("BIRCH_WOOD_STAIRS", 135);
|
||||
define("BIRCH_WOODEN_STAIRS", 135);
|
||||
define("JUNGLE_WOOD_STAIRS", 136);
|
||||
define("JUNGLE_WOODEN_STAIRS", 136);
|
||||
|
||||
define("COBBLE_WALL", 139);
|
||||
define("STONE_WALL", 139);
|
||||
define("COBBLESTONE_WALL", 139);
|
||||
|
||||
define("CARROT_BLOCK", 141);
|
||||
define("POTATO_BLOCK", 142);
|
||||
|
||||
define("QUARTZ_BLOCK", 155);
|
||||
define("QUARTZ_STAIRS", 156);
|
||||
define("DOUBLE_WOOD_SLAB", 157);
|
||||
define("DOUBLE_WOODEN_SLAB", 157);
|
||||
define("DOUBLE_WOOD_SLABS", 157);
|
||||
define("DOUBLE_WOODEN_SLABS", 157);
|
||||
define("WOOD_SLAB", 158);
|
||||
define("WOODEN_SLAB", 158);
|
||||
define("WOOD_SLABS", 158);
|
||||
define("WOODEN_SLABS", 158);
|
||||
|
||||
define("HAY_BALE", 170);
|
||||
define("CARPET", 171);
|
||||
|
||||
define("COAL_BLOCK", 173);
|
||||
|
||||
define("BEETROOT_BLOCK", 244);
|
||||
define("STONECUTTER", 245);
|
||||
define("GLOWING_OBSIDIAN", 246);
|
||||
define("NETHER_REACTOR", 247);
|
||||
|
@ -62,6 +62,7 @@ define("ENTITY_MOB", 2);
|
||||
define("MOB_PIGMAN", 36);
|
||||
|
||||
define("ENTITY_OBJECT", 3);
|
||||
define("OBJECT_PRIMEDTNT", 65);
|
||||
define("OBJECT_ARROW", 80);
|
||||
define("OBJECT_PAINTING", 83);
|
||||
|
||||
|
@ -98,9 +98,11 @@ define("SIGN", 323);
|
||||
define("WOODEN_DOOR", 324);
|
||||
define("BUCKET", 325);
|
||||
|
||||
define("MINECART", 329);
|
||||
|
||||
define("IRON_DOOR", 330);
|
||||
|
||||
define("REDSTONE", 331);
|
||||
define("REDSTONE_DUST", 331);
|
||||
define("SNOWBALL", 332);
|
||||
|
||||
define("LEATHER", 334);
|
||||
@ -116,6 +118,7 @@ define("SLIMEBALL", 341);
|
||||
define("EGG", 344);
|
||||
define("COMPASS", 345);
|
||||
|
||||
define("CLOCK", 347);
|
||||
define("GLOWSTONE_DUST", 348);
|
||||
//define("RAW_FISH", 349);
|
||||
//define("COOKED_FISH", 350);
|
||||
@ -132,7 +135,7 @@ define("BED", 355);
|
||||
define("SHEARS", 359);
|
||||
define("MELON", 360);
|
||||
define("MELON_SLICE", 360);
|
||||
|
||||
define("PUMPKIN_SEEDS", 361);
|
||||
define("MELON_SEEDS", 362);
|
||||
define("RAW_BEEF", 363);
|
||||
define("STEAK", 364);
|
||||
@ -143,8 +146,21 @@ define("COOKED_CHICKEN", 366);
|
||||
|
||||
define("SPAWN_EGG", 383);
|
||||
|
||||
define("CARROT", 391);
|
||||
define("CARROTS", 391);
|
||||
define("POTATO", 392);
|
||||
define("POTATOES", 392);//@shoghicp Why the heck do we need plural redundant Item ID here????
|
||||
define("BAKED_POTATO", 393);
|
||||
define("BAKED_POTATOES", 393);
|
||||
|
||||
define("PUMPKIN_PIE", 400);
|
||||
|
||||
define("NETHER_BRICK", 405);
|
||||
define("QUARTZ", 406);
|
||||
define("NETHER_QUARTZ", 406);
|
||||
|
||||
define("CAMERA", 456);
|
||||
define("BEETROOT", 457);
|
||||
define("BEETROOT_SEEDS", 458);
|
||||
define("BEETROOT_SEED", 458);
|
||||
define("BEETROOT_SOUP", 459);
|
@ -21,11 +21,12 @@
|
||||
|
||||
/***REM_START***/
|
||||
require_once(dirname(__FILE__)."/config.php");
|
||||
require_once(FILE_PATH."/src/utils/TextFormat.php");
|
||||
require_once(FILE_PATH."/src/functions.php");
|
||||
/***REM_END***/
|
||||
define(DATA_PATH, realpath(arg("data-path", FILE_PATH))."/");
|
||||
define("DATA_PATH", realpath(arg("data-path", FILE_PATH))."/");
|
||||
|
||||
if(arg("enable-ansi", strpos(strtoupper(php_uname("s")), "WIN") === false ? true:false) === true){
|
||||
if(arg("enable-ansi", strpos(strtoupper(php_uname("s")), "WIN") === 0 ? false:true) === true and arg("disable-ansi", false) !== true){
|
||||
define("ENABLE_ANSI", true);
|
||||
}else{
|
||||
define("ENABLE_ANSI", false);
|
||||
@ -75,10 +76,22 @@ if($errors > 0){
|
||||
exit(1); //Exit with error
|
||||
}
|
||||
|
||||
$sha1sum = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
|
||||
/***REM_START***/
|
||||
require_once(FILE_PATH."/src/math/Vector3.php");
|
||||
require_once(FILE_PATH."/src/world/Position.php");
|
||||
require_once(FILE_PATH."/src/pmf/PMF.php");
|
||||
|
||||
require_all(FILE_PATH . "src/");
|
||||
/***REM_END***/
|
||||
|
||||
$inc = get_included_files();
|
||||
$inc[] = array_shift($inc);
|
||||
$srcdir = realpath(FILE_PATH."src/");
|
||||
foreach($inc as $s){
|
||||
if(strpos(realpath(dirname($s)), $srcdir) === false and strtolower(basename($s)) !== "pocketmine-mp.php"){
|
||||
continue;
|
||||
}
|
||||
$sha1sum ^= sha1_file($s, true);
|
||||
}
|
||||
/***REM_END***/
|
||||
define("SOURCE_SHA1SUM", bin2hex($sha1sum));
|
@ -142,7 +142,7 @@ function arguments ( $args ){
|
||||
array_shift( $args );
|
||||
$args = join( $args, ' ' );
|
||||
|
||||
preg_match_all('/ (--[\w\-]+ (?:[= ] [^-]+ [^\s-] )? ) | (-\w+) | (\w+) /x', $args, $match );
|
||||
preg_match_all('/ (--[\w\-]+ (?:[= ] [^-\s]+ )? ) | (-\w+) | (\w+) /x', $args, $match );
|
||||
$args = array_shift( $match );
|
||||
|
||||
$ret = array(
|
||||
@ -182,35 +182,34 @@ function arguments ( $args ){
|
||||
function console($message, $EOL = true, $log = true, $level = 1){
|
||||
if(!defined("DEBUG") or DEBUG >= $level){
|
||||
$message .= $EOL === true ? PHP_EOL:"";
|
||||
$time = (ENABLE_ANSI === true ? "\x1b[36m".date("H:i:s")."\x1b[0m":date("H:i:s")) . " ";
|
||||
$replaced = preg_replace('/\x1b\[[0-9;]*m/', "", $time . $message);
|
||||
$time = (ENABLE_ANSI === true ? FORMAT_AQUA . date("H:i:s") . FORMAT_RESET:date("H:i:s")) . " ";
|
||||
$replaced = TextFormat::clean(preg_replace('/\x1b\[[0-9;]*m/', "", $time . $message));
|
||||
if($log === true and (!defined("LOG") or LOG === true)){
|
||||
logg(date("Y-m-d")." ".$replaced, "console", false, $level);
|
||||
}
|
||||
if(ENABLE_ANSI === true){
|
||||
$add = "";
|
||||
if(preg_match("/\[([a-zA-Z0-9]*)\]/", $message, $matches) > 0){
|
||||
$add .= "\x1b";
|
||||
switch($matches[1]){
|
||||
case "ERROR":
|
||||
$add .= "[31;1m";
|
||||
$add .= FORMAT_RED;
|
||||
break;
|
||||
case "INTERNAL":
|
||||
case "DEBUG":
|
||||
$add .= "[30;1m";
|
||||
$add .= FORMAT_GRAY;
|
||||
break;
|
||||
case "WARNING":
|
||||
$add .= "[33;1m";
|
||||
$add .= FORMAT_YELLOW;
|
||||
break;
|
||||
case "NOTICE":
|
||||
$add .= "[37;1m";
|
||||
$add .= FORMAT_AQUA;
|
||||
break;
|
||||
default:
|
||||
$add = "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
$message = $time . $add . $message . "\x1b[0m";
|
||||
$message = TextFormat::toANSI($time . $add . $message . FORMAT_RESET);
|
||||
}else{
|
||||
$message = $replaced;
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ abstract class Block extends Position{
|
||||
COAL_ORE => "CoalOreBlock",
|
||||
WOOD => "WoodBlock",
|
||||
LEAVES => "LeavesBlock",
|
||||
SPONGE => "SpongeBlock",
|
||||
GLASS => "GlassBlock",
|
||||
LAPIS_ORE => "LapisOreBlock",
|
||||
LAPIS_BLOCK => "LapisBlock",
|
||||
@ -94,20 +95,22 @@ abstract class Block extends Position{
|
||||
SUGARCANE_BLOCK => "SugarcaneBlock",
|
||||
|
||||
FENCE => "FenceBlock",
|
||||
|
||||
PUMPKIN => "PumpkinBlock",
|
||||
NETHERRACK => "NetherrackBlock",
|
||||
SOUL_SAND => "SoulSandBlock",
|
||||
GLOWSTONE_BLOCK => "GlowstoneBlock",
|
||||
|
||||
LIT_PUMPKIN => "LitPumpkinBlock",
|
||||
CAKE_BLOCK => "CakeBlock",
|
||||
|
||||
TRAPDOOR => "TrapdoorBlock",
|
||||
|
||||
STONE_BRICKS => "StoneBricksBlock",
|
||||
|
||||
IRON_BARS => "IronBarsBlock",
|
||||
GLASS_PANE => "GlassPaneBlock",
|
||||
MELON_BLOCK => "MelonBlock",
|
||||
|
||||
PUMPKIN_STEM => "PumpkinStemBlock",
|
||||
MELON_STEM => "MelonStemBlock",
|
||||
|
||||
FENCE_GATE => "FenceGateBlock",
|
||||
@ -119,10 +122,26 @@ abstract class Block extends Position{
|
||||
NETHER_BRICKS_STAIRS => "NetherBricksStairsBlock",
|
||||
|
||||
SANDSTONE_STAIRS => "SandstoneStairsBlock",
|
||||
|
||||
SPRUCE_WOOD_STAIRS => "SpruceWoodStairsBlock",
|
||||
BIRCH_WOOD_STAIRS => "BirchWoodStairsBlock",
|
||||
JUNGLE_WOOD_STAIRS => "JungleWoodStairsBlock",
|
||||
STONE_WALL => "StoneWallBlock",
|
||||
|
||||
CARROT_BLOCK => "CarrotBlock",
|
||||
POTATO_BLOCK => "PotatoBlock",
|
||||
|
||||
QUARTZ_BLOCK => "QuartzBlock",
|
||||
QUARTZ_STAIRS => "QuartzStairsBlock",
|
||||
|
||||
DOUBLE_WOOD_SLAB => "DoubleWoodSlabBlock",
|
||||
WOOD_SLAB => "WoodSlabBlock",
|
||||
|
||||
HAY_BALE => "HayBaleBlock",
|
||||
CARPET => "CarpetBlock",
|
||||
|
||||
COAL_BLOCK => "CoalBlock",
|
||||
|
||||
BEETROOT_BLOCK => "BeetrootBlock",
|
||||
STONECUTTER => "StonecutterBlock",
|
||||
GLOWING_OBSIDIAN => "GlowingObsidianBlock",
|
||||
NETHER_REACTOR => "NetherReactorBlock",
|
||||
@ -131,6 +150,7 @@ abstract class Block extends Position{
|
||||
protected $meta;
|
||||
protected $name;
|
||||
protected $breakTime;
|
||||
protected $hardness;
|
||||
public $isActivable = false;
|
||||
public $breakable = true;
|
||||
public $isFlowable = false;
|
||||
@ -151,6 +171,11 @@ abstract class Block extends Position{
|
||||
$this->meta = (int) $meta;
|
||||
$this->name = $name;
|
||||
$this->breakTime = 0.20;
|
||||
$this->hardness = 10;
|
||||
}
|
||||
|
||||
final public function getHardness(){
|
||||
return ($this->hardness);
|
||||
}
|
||||
|
||||
final public function getName(){
|
||||
|
@ -23,7 +23,13 @@ class Item{
|
||||
public static $class = array(
|
||||
SUGARCANE => "SugarcaneItem",
|
||||
WHEAT_SEEDS => "WheatSeedsItem",
|
||||
PUMPKIN_SEEDS => "PumpkinSeedsItem",
|
||||
MELON_SEEDS => "MelonSeedsItem",
|
||||
MUSHROOM_STEW => "MushroomStewItem",
|
||||
BEETROOT_SOUP => "BeetrootSoupItem",
|
||||
CARROT => "CarrotItem",
|
||||
POTATO => "PotatoItem",
|
||||
BEETROOT_SEEDS => "BeetrootSeedsItem",
|
||||
SIGN => "SignItem",
|
||||
WOODEN_DOOR => "WoodenDoorItem",
|
||||
BUCKET => "BucketItem",
|
||||
@ -137,6 +143,10 @@ class Item{
|
||||
$this->meta++;
|
||||
}
|
||||
return true;
|
||||
}elseif($this->isHoe()){
|
||||
if(($object instanceof Block) and ($object->getID() === GRASS or $object->getID() === DIRT)){
|
||||
$this->meta++;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -20,12 +20,22 @@
|
||||
*/
|
||||
|
||||
class DoorBlock extends TransparentBlock{
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
/**
|
||||
* @param int $id
|
||||
* @param int $meta
|
||||
* @param string $name
|
||||
*/
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
parent::__construct($id, $meta, $name);
|
||||
$this->isSolid = false;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
/**
|
||||
* @param int $type
|
||||
*
|
||||
* @return bool|int
|
||||
*/
|
||||
public function onUpdate($type){
|
||||
if($type === BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->getID() === AIR){ //Replace with common break method
|
||||
$this->level->setBlock($this, new AirBlock(), false);
|
||||
@ -38,7 +48,19 @@ class DoorBlock extends TransparentBlock{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
/**
|
||||
* @param Item $item
|
||||
* @param Player $player
|
||||
* @param Block $block
|
||||
* @param Block $target
|
||||
* @param integer $face
|
||||
* @param integer $fx
|
||||
* @param integer $fy
|
||||
* @param integer $fz
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
if($face === 1){
|
||||
$blockUp = $this->getSide(1);
|
||||
$blockDown = $this->getSide(0);
|
||||
@ -66,8 +88,14 @@ class DoorBlock extends TransparentBlock{
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onBreak(Item $item, Player $player){
|
||||
|
||||
/**
|
||||
* @param Item $item
|
||||
* @param Player $player
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function onBreak(Item $item, Player $player){
|
||||
if(($this->meta & 0x08) === 0x08){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === $this->id){
|
||||
@ -82,19 +110,43 @@ class DoorBlock extends TransparentBlock{
|
||||
$this->level->setBlock($this, new AirBlock(), true, false, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player){
|
||||
|
||||
/**
|
||||
* @param Item $item
|
||||
* @param Player $player
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function onActivate(Item $item, Player $player){
|
||||
if(($this->meta & 0x08) === 0x08){ //Top
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === $this->id){
|
||||
$meta = $down->getMetadata() ^ 0x04;
|
||||
$this->level->setBlock($down, BlockAPI::get($this->id, $meta), true, false, true);
|
||||
$players = ServerAPI::request()->api->player->getAll($this->level);
|
||||
unset($players[$player->CID]);
|
||||
ServerAPI::request()->api->player->broadcastPacket($players, MC_LEVEL_EVENT, array(
|
||||
"x" => $this->x,
|
||||
"y" => $this->y,
|
||||
"z" => $this->z,
|
||||
"evid" => 1003,
|
||||
"data" => 0
|
||||
));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}else{
|
||||
$this->meta ^= 0x04;
|
||||
$this->level->setBlock($this, $this, true, false, true);
|
||||
$players = ServerAPI::request()->api->player->getAll($this->level);
|
||||
unset($players[$player->CID]);
|
||||
ServerAPI::request()->api->player->broadcastPacket($players, MC_LEVEL_EVENT, array(
|
||||
"x" => $this->x,
|
||||
"y" => $this->y,
|
||||
"z" => $this->z,
|
||||
"evid" => 1003,
|
||||
"data" => 0
|
||||
));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -20,12 +20,29 @@
|
||||
*/
|
||||
|
||||
class FallableBlock extends SolidBlock{
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
/**
|
||||
* @param int $id
|
||||
* @param int $meta
|
||||
* @param string $name
|
||||
*/
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
parent::__construct($id, $meta, $name);
|
||||
$this->hasPhysics = true;
|
||||
}
|
||||
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
|
||||
/**
|
||||
* @param Item $item
|
||||
* @param Player $player
|
||||
* @param Block $block
|
||||
* @param Block $target
|
||||
* @param int $face
|
||||
* @param int $fx
|
||||
* @param int $fy
|
||||
* @param int $fz
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
$ret = $this->level->setBlock($this, $this, true, false, true);
|
||||
ServerAPI::request()->api->block->blockUpdate(clone $this, BLOCK_UPDATE_NORMAL);
|
||||
return $ret;
|
||||
|
@ -20,7 +20,12 @@
|
||||
*/
|
||||
|
||||
class FlowableBlock extends TransparentBlock{
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
/**
|
||||
* @param int $id
|
||||
* @param int $meta
|
||||
* @param string $name
|
||||
*/
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
parent::__construct($id, $meta, $name);
|
||||
$this->isFlowable = true;
|
||||
$this->isFullBlock = false;
|
||||
|
@ -21,22 +21,57 @@
|
||||
|
||||
|
||||
class GenericBlock extends Block{
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
/**
|
||||
* @param int $id
|
||||
* @param int $meta
|
||||
* @param string $name
|
||||
*/
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
parent::__construct($id, $meta, $name);
|
||||
}
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Item $item
|
||||
* @param Player $player
|
||||
* @param Block $block
|
||||
* @param Block $target
|
||||
* @param integer $face
|
||||
* @param integer $fx
|
||||
* @param integer $fy
|
||||
* @param integer $fz
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
return $this->level->setBlock($this, $this, true, false, true);
|
||||
}
|
||||
|
||||
public function isBreakable(Item $item, Player $player){
|
||||
|
||||
/**
|
||||
* @param Item $item
|
||||
* @param Player $player
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isBreakable(Item $item, Player $player){
|
||||
return ($this->breakable);
|
||||
}
|
||||
|
||||
public function onBreak(Item $item, Player $player){
|
||||
|
||||
/**
|
||||
* @param Item $item
|
||||
* @param Player $player
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function onBreak(Item $item, Player $player){
|
||||
return $this->level->setBlock($this, new AirBlock(), true, false, true);
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
|
||||
/**
|
||||
* @param integer $type
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function onUpdate($type){
|
||||
if($this->hasPhysics === true and $type === BLOCK_UPDATE_NORMAL){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === AIR or ($down instanceof LiquidBlock)){
|
||||
@ -57,7 +92,13 @@ class GenericBlock extends Block{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player){
|
||||
/**
|
||||
* @param Item $item
|
||||
* @param Player $player
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function onActivate(Item $item, Player $player){
|
||||
return $this->isActivable;
|
||||
}
|
||||
}
|
@ -20,7 +20,12 @@
|
||||
*/
|
||||
|
||||
class LiquidBlock extends TransparentBlock{
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
/**
|
||||
* @param int $id
|
||||
* @param int $meta
|
||||
* @param string $name
|
||||
*/
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
parent::__construct($id, $meta, $name);
|
||||
$this->isLiquid = true;
|
||||
$this->breakable = false;
|
||||
|
@ -20,7 +20,12 @@
|
||||
*/
|
||||
|
||||
class SolidBlock extends GenericBlock{
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
/**
|
||||
* @param int $id
|
||||
* @param int $meta
|
||||
* @param string $name
|
||||
*/
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
parent::__construct($id, $meta, $name);
|
||||
$this->isSolid = true;
|
||||
$this->isFullBlock = true;
|
||||
|
@ -20,16 +20,34 @@
|
||||
*/
|
||||
|
||||
class StairBlock extends TransparentBlock{
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
/**
|
||||
* @param int $id
|
||||
* @param int $meta
|
||||
* @param string $name
|
||||
*/
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
parent::__construct($id, $meta, $name);
|
||||
if(($this->meta & 0x04) === 0x04){
|
||||
$this->isFullBlock = true;
|
||||
}else{
|
||||
$this->isFullBlock = false;
|
||||
}
|
||||
$this->hardness = 30;
|
||||
}
|
||||
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
/**
|
||||
* @param Item $item
|
||||
* @param Player $player
|
||||
* @param Block $block
|
||||
* @param Block $target
|
||||
* @param int $face
|
||||
* @param int $fx
|
||||
* @param int $fy
|
||||
* @param int $fz
|
||||
*
|
||||
* @return bool|mixed
|
||||
*/
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
$faces = array(
|
||||
0 => 0,
|
||||
1 => 2,
|
||||
@ -43,8 +61,14 @@ class StairBlock extends TransparentBlock{
|
||||
$this->level->setBlock($block, $this, true, false, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
|
||||
/**
|
||||
* @param Item $item
|
||||
* @param Player $player
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDrops(Item $item, Player $player){
|
||||
if($item->isPickaxe() >= 1){
|
||||
return array(
|
||||
array($this->id, 0, 1),
|
||||
|
@ -20,7 +20,12 @@
|
||||
*/
|
||||
|
||||
class TransparentBlock extends GenericBlock{
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
/**
|
||||
* @param int $id
|
||||
* @param int $meta
|
||||
* @param string $name
|
||||
*/
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
parent::__construct($id, $meta, $name);
|
||||
$this->isActivable = false;
|
||||
$this->breakable = true;
|
||||
|
@ -24,6 +24,7 @@ class LadderBlock extends TransparentBlock{
|
||||
parent::__construct(LADDER, $meta, "Ladder");
|
||||
$this->isSolid = false;
|
||||
$this->isFullBlock = false;
|
||||
$this->hardness = 2;
|
||||
}
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
if($target->isTransparent === false){
|
||||
@ -41,6 +42,18 @@ class LadderBlock extends TransparentBlock{
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->getID() === AIR){ //Replace with common break method
|
||||
ServerAPI::request()->api->entity->drop($this, BlockAPI::getItem(LADDER, 0, 1));
|
||||
$this->level->setBlock($this, new AirBlock(), true, true, true);
|
||||
return BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
return array(
|
||||
array($this->id, 0, 1),
|
||||
|
@ -24,6 +24,7 @@ class SignPostBlock extends TransparentBlock{
|
||||
parent::__construct(SIGN_POST, $meta, "Sign Post");
|
||||
$this->isSolid = false;
|
||||
$this->isFullBlock = false;
|
||||
$this->hardness = 5;
|
||||
}
|
||||
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
|
@ -22,6 +22,7 @@
|
||||
class TorchBlock extends FlowableBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(TORCH, $meta, "Torch");
|
||||
$this->hardness = 0;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
|
@ -28,6 +28,7 @@ class TrapdoorBlock extends TransparentBlock{
|
||||
}else{
|
||||
$this->isFullBlock = true;
|
||||
}
|
||||
$this->hardness = 15;
|
||||
}
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
if(($target->isTransparent === false or $target->getID() === SLAB) and $face !== 0 and $face !== 1){
|
||||
|
@ -22,6 +22,121 @@
|
||||
class LavaBlock extends LiquidBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(LAVA, $meta, "Lava");
|
||||
$this->hardness = 0;
|
||||
}
|
||||
|
||||
}
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
$ret = $this->level->setBlock($this, $this, true, false, true);
|
||||
ServerAPI::request()->api->block->scheduleBlockUpdate(clone $this, 40, BLOCK_UPDATE_NORMAL);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function getSourceCount(){
|
||||
$count = 0;
|
||||
for($side = 2; $side <= 5; ++$side){
|
||||
if($this->getSide($side) instanceof LavaBlock ){
|
||||
$b = $this->getSide($side);
|
||||
$level = $b->meta & 0x07;
|
||||
if($level == 0x00){
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
public function checkWater(){
|
||||
for($side = 1; $side <= 5; ++$side){
|
||||
$b = $this->getSide($side);
|
||||
if($b instanceof WaterBlock){
|
||||
$level = $this->meta & 0x07;
|
||||
if($level == 0x00){
|
||||
$this->level->setBlock($this, new ObsidianBlock(), false, false, true);
|
||||
}else{
|
||||
$this->level->setBlock($this, new CobblestoneBlock(), false, false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getFrom(){
|
||||
for($side = 0; $side <= 5; ++$side){
|
||||
$b = $this->getSide($side);
|
||||
if($b instanceof LavaBlock){
|
||||
$tlevel = $b->meta & 0x07;
|
||||
$level = $this->meta & 0x07;
|
||||
if( ($tlevel + 2) == $level || ($side == 0x01 && $level == 0x01 ) || ($tlevel == 6 && $level == 7 )){
|
||||
return $b;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
//return false;
|
||||
$newId = $this->id;
|
||||
$level = $this->meta & 0x07;
|
||||
if($type !== BLOCK_UPDATE_NORMAL){
|
||||
return false;
|
||||
}
|
||||
|
||||
if( $this->checkWater()){
|
||||
return;
|
||||
}
|
||||
|
||||
$falling = $this->meta >> 3;
|
||||
$down = $this->getSide(0);
|
||||
|
||||
$from = $this->getFrom();
|
||||
if($from !== null || $level == 0x00){
|
||||
if($level !== 0x07){
|
||||
if($down instanceof AirBlock || $down instanceof LavaBlock){
|
||||
$this->level->setBlock($down, new LavaBlock(0x01), false, false, true);
|
||||
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($down, 0, 0, $this->level), 40, BLOCK_UPDATE_NORMAL);
|
||||
}else{
|
||||
for($side = 2; $side <= 5; ++$side){
|
||||
$b = $this->getSide($side);
|
||||
if($b instanceof LavaBlock){
|
||||
|
||||
}else if($b->isFlowable === true){
|
||||
$this->level->setBlock($b, new LavaBlock( min($level + 2,7) ), false, false, true);
|
||||
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($b, 0, 0, $this->level), 40, BLOCK_UPDATE_NORMAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
//Extend Remove for Left Lavas
|
||||
for($side = 2; $side <= 5; ++$side){
|
||||
$sb = $this->getSide($side);
|
||||
if($sb instanceof LavaBlock){
|
||||
$tlevel = $sb->meta & 0x07;
|
||||
if($tlevel != 0x00){
|
||||
for ($s = 0; $s <= 5; $s++) {
|
||||
$ssb = $sb->getSide($s);
|
||||
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($ssb, 0, 0, $this->level), 40, BLOCK_UPDATE_NORMAL);
|
||||
}
|
||||
$this->level->setBlock($sb, new AirBlock(), false, false, true);
|
||||
}
|
||||
}
|
||||
$b = $this->getSide(0)->getSide($side);
|
||||
if($b instanceof LavaBlock){
|
||||
$tlevel = $b->meta & 0x07;
|
||||
if($tlevel != 0x00){
|
||||
for ($s = 0; $s <= 5; $s++) {
|
||||
$ssb = $sb->getSide($s);
|
||||
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($ssb, 0, 0, $this->level), 40, BLOCK_UPDATE_NORMAL);
|
||||
}
|
||||
$this->level->setBlock($b, new AirBlock(), false, false, true);
|
||||
}
|
||||
}
|
||||
//ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($b, 0, 0, $this->level), 10, BLOCK_UPDATE_NORMAL);
|
||||
}
|
||||
|
||||
$this->level->setBlock($this, new AirBlock(), false, false, true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
class StillLavaBlock extends LiquidBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(STILL_LAVA, $meta, "Still Lava");
|
||||
$this->hardness = 500;
|
||||
}
|
||||
|
||||
}
|
@ -27,6 +27,7 @@ require_once("Water.php");
|
||||
class StillWaterBlock extends WaterBlock{
|
||||
public function __construct($meta = 0){
|
||||
LiquidBlock::__construct(STILL_WATER, $meta, "Still Water");
|
||||
$this->hardness = 500;
|
||||
}
|
||||
|
||||
}
|
@ -22,91 +22,125 @@
|
||||
class WaterBlock extends LiquidBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(WATER, $meta, "Water");
|
||||
}
|
||||
$this->hardness = 500;
|
||||
}
|
||||
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
$ret = $this->level->setBlock($this, $this, true, false, true);
|
||||
ServerAPI::request()->api->block->scheduleBlockUpdate(clone $this, 10, BLOCK_UPDATE_NORMAL);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
|
||||
public function getSourceCount(){
|
||||
$count = 0;
|
||||
for($side = 2; $side <= 5; ++$side){
|
||||
if( $this->getSide($side) instanceof WaterBlock ){
|
||||
$b = $this->getSide($side);
|
||||
$level = $b->meta & 0x07;
|
||||
if($level == 0x00){
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
public function checkLava(){
|
||||
for($side = 0; $side <= 5; ++$side){
|
||||
if($side == 1){
|
||||
continue;
|
||||
}
|
||||
$b = $this->getSide($side);
|
||||
if($b instanceof LavaBlock){
|
||||
$level = $b->meta & 0x07;
|
||||
if($level == 0x00){
|
||||
$this->level->setBlock($b, new ObsidianBlock(), false, false, true);
|
||||
}else{
|
||||
$this->level->setBlock($b, new CobblestoneBlock(), false, false, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getFrom(){
|
||||
for($side = 0; $side <= 5; ++$side){
|
||||
$b = $this->getSide($side);
|
||||
if($b instanceof WaterBlock){
|
||||
$tlevel = $b->meta & 0x07;
|
||||
$level = $this->meta & 0x07;
|
||||
if( ($tlevel + 1) == $level || ($side == 0x01 && $level == 0x01 )){
|
||||
return $b;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
//return false;
|
||||
$newId = $this->id;
|
||||
$level = $this->meta & 0x07;
|
||||
if($type !== BLOCK_UPDATE_NORMAL){
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->checkLava();
|
||||
|
||||
$falling = $this->meta >> 3;
|
||||
$down = $this->getSide(0);
|
||||
|
||||
if($falling === 0){
|
||||
$countSources = 0;
|
||||
$maxLevel = $level;
|
||||
$hasPath = false;
|
||||
for($side = 2; $side <= 5; ++$side){
|
||||
$b = $this->getSide($side);
|
||||
if($b->isFlowable === true and $level < 0x07){
|
||||
$d = $b->getSide(0);
|
||||
$this->level->setBlock($b, new WaterBlock($level + 1), false, false, true);
|
||||
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($b, 0, 0, $this->level), 10, BLOCK_UPDATE_NORMAL);
|
||||
}elseif($b instanceof WaterBlock){
|
||||
$oLevel = $b->getMetadata();
|
||||
$oFalling = $oLevel >> 3;
|
||||
$oLevel &= 0x07;
|
||||
if($oFalling === 0){
|
||||
if($oLevel === 0){
|
||||
++$countSources;
|
||||
$maxLevel = 1;
|
||||
$hasPath = true;
|
||||
}elseif($oLevel < 0x07 and ($oLevel + 1) <= $maxLevel){
|
||||
$maxLevel = $oLevel + 1;
|
||||
$hasPath = true;
|
||||
}elseif(($level + 1) < $oLevel){
|
||||
$from = $this->getFrom();
|
||||
//Has Source or Its Source
|
||||
if($from !== null || $level == 0x00){
|
||||
if($level !== 0x07){
|
||||
if($down instanceof AirBlock || $down instanceof WaterBlock){
|
||||
$this->level->setBlock($down, new WaterBlock(0x01), false, false, true);
|
||||
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($down, 0, 0, $this->level), 10, BLOCK_UPDATE_NORMAL);
|
||||
}else{
|
||||
for($side = 2; $side <= 5; ++$side){
|
||||
$b = $this->getSide($side);
|
||||
if($b instanceof WaterBlock){
|
||||
if( $this->getSourceCount() >= 2 && $level != 0x00){
|
||||
$this->level->setBlock($this, new WaterBlock(0), false, false, true);
|
||||
}
|
||||
}elseif($b->isFlowable === true){
|
||||
$this->level->setBlock($b, new WaterBlock($level + 1), false, false, true);
|
||||
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($b, 0, 0, $this->level), 10, BLOCK_UPDATE_NORMAL);
|
||||
}elseif($level === $oLevel){
|
||||
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($b, 0, 0, $this->level), 10, BLOCK_UPDATE_NORMAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if($countSources >= 2){
|
||||
$level = 0; //Source block
|
||||
}elseif($maxLevel < $level){
|
||||
$level = $maxLevel;
|
||||
}elseif($maxLevel === $level and $level > 0 and $hasPath === false){
|
||||
if($level < 0x07){
|
||||
++$level;
|
||||
}else{
|
||||
$newId = AIR;
|
||||
$level = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($down->isFlowable){
|
||||
$this->level->setBlock($down, new WaterBlock(0b1001), false, false, true);
|
||||
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($down, 0, 0, $this->level), 5, BLOCK_UPDATE_NORMAL);
|
||||
return false;
|
||||
}elseif($down instanceof LiquidBlock){
|
||||
if($down instanceof WaterBlock and ($down->getMetadata() >> 3) === 0){
|
||||
$this->level->setBlock($down, new WaterBlock(0b1000 & min($down->getMetadata(), 1)), false, false, true);
|
||||
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($down, 0, 0, $this->level), 5, BLOCK_UPDATE_NORMAL);
|
||||
}
|
||||
}else{
|
||||
$falling = 0;
|
||||
}
|
||||
|
||||
$newMeta = ($falling << 0x03) | $level;
|
||||
if($newMeta !== $this->meta or $newId !== $this->id){
|
||||
$this->id = $newId;
|
||||
$this->meta = $newMeta;
|
||||
$this->level->setBlock($this, $this, false, false, true);
|
||||
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($this, 0, 0, $this->level), 10, BLOCK_UPDATE_NORMAL);
|
||||
return false;
|
||||
//Extend Remove for Left Waters
|
||||
for($side = 2; $side <= 5; ++$side){
|
||||
$sb = $this->getSide($side);
|
||||
if($sb instanceof WaterBlock){
|
||||
$tlevel = $sb->meta & 0x07;
|
||||
if($tlevel != 0x00){
|
||||
for ($s = 0; $s <= 5; $s++) {
|
||||
$ssb = $sb->getSide($s);
|
||||
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($ssb, 0, 0, $this->level), 10, BLOCK_UPDATE_NORMAL);
|
||||
}
|
||||
$this->level->setBlock($sb, new AirBlock(), false, false, true);
|
||||
}
|
||||
}
|
||||
$b = $this->getSide(0)->getSide($side);
|
||||
if($b instanceof WaterBlock){
|
||||
$tlevel = $b->meta & 0x07;
|
||||
if($tlevel != 0x00){
|
||||
for ($s = 0; $s <= 5; $s++) {
|
||||
$ssb = $sb->getSide($s);
|
||||
ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($ssb, 0, 0, $this->level), 10, BLOCK_UPDATE_NORMAL);
|
||||
}
|
||||
$this->level->setBlock($b, new AirBlock(), false, false, true);
|
||||
}
|
||||
}
|
||||
//ServerAPI::request()->api->block->scheduleBlockUpdate(new Position($b, 0, 0, $this->level), 10, BLOCK_UPDATE_NORMAL);
|
||||
}
|
||||
$this->level->setBlock($this, new AirBlock(), false, false, true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ class AirBlock extends TransparentBlock{
|
||||
$this->hasPhysics = false;
|
||||
$this->isSolid = false;
|
||||
$this->isFullBlock = true;
|
||||
$this->hardness = 0;
|
||||
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@ class BedBlock extends TransparentBlock{
|
||||
parent::__construct(BED_BLOCK, $type, "Bed Block");
|
||||
$this->isActivable = true;
|
||||
$this->isFullBlock = false;
|
||||
$this->hardness = 1;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player){
|
||||
@ -33,7 +34,31 @@ class BedBlock extends TransparentBlock{
|
||||
));
|
||||
return true;
|
||||
}
|
||||
if($player->sleepOn($this) === false){
|
||||
|
||||
$blockNorth = $this->getSide(2); //Gets the blocks around them
|
||||
$blockSouth = $this->getSide(3);
|
||||
$blockEast = $this->getSide(5);
|
||||
$blockWest = $this->getSide(4);
|
||||
if(($this->meta & 0x08) === 0x08){ //This is the Top part of bed
|
||||
$b = $this;
|
||||
}else{ //Bottom Part of Bed
|
||||
if($blockNorth->getID() === $this->id and ($blockNorth->meta & 0x08) === 0x08){
|
||||
$b = $blockNorth;
|
||||
}elseif($blockSouth->getID() === $this->id and ($blockSouth->meta & 0x08) === 0x08){
|
||||
$b = $blockSouth;
|
||||
}elseif($blockEast->getID() === $this->id and ($blockEast->meta & 0x08) === 0x08){
|
||||
$b = $blockEast;
|
||||
}elseif($blockWest->getID() === $this->id and ($blockWest->meta & 0x08) === 0x08){
|
||||
$b = $blockWest;
|
||||
}else{
|
||||
$player->dataPacket(MC_CLIENT_MESSAGE, array(
|
||||
"message" => "The bed is incomplete"
|
||||
));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if($player->sleepOn($b) === false){
|
||||
$player->dataPacket(MC_CLIENT_MESSAGE, array(
|
||||
"message" => "This bed is occupied"
|
||||
));
|
||||
|
@ -25,6 +25,7 @@ class FireBlock extends FlowableBlock{
|
||||
$this->isReplaceable = true;
|
||||
$this->breakable = false;
|
||||
$this->isFullBlock = true;
|
||||
$this->hardness = 0;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
|
@ -22,5 +22,27 @@
|
||||
class TNTBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(TNT, 0, "TNT");
|
||||
$this->hardness = 0;
|
||||
$this->isActivable = true;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player){
|
||||
if($item->getID() === FLINT_STEEL){
|
||||
if(($player->gamemode & 0x01) === 0){
|
||||
$item->useOn($this);
|
||||
}
|
||||
$data = array(
|
||||
"x" => $this->x + 0.5,
|
||||
"y" => $this->y + 0.5,
|
||||
"z" => $this->z + 0.5,
|
||||
"power" => 4,
|
||||
"fuse" => 20 * 4, //4 seconds
|
||||
);
|
||||
$this->level->setBlock($this, new AirBlock(), false, false, true);
|
||||
$e = ServerAPI::request()->api->entity->add($this->level, ENTITY_OBJECT, OBJECT_PRIMEDTNT, $data);
|
||||
ServerAPI::request()->api->entity->spawnToAll($e);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -25,6 +25,16 @@ class CakeBlock extends TransparentBlock{
|
||||
$this->isFullBlock = false;
|
||||
$this->isActivable = true;
|
||||
$this->meta = $meta & 0x07;
|
||||
$this->hardness = 2.5;
|
||||
}
|
||||
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() !== AIR){
|
||||
$this->level->setBlock($block, $this, true, false, true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
|
69
src/material/block/nonfull/Carpet.php
Normal file
69
src/material/block/nonfull/Carpet.php
Normal file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
class CarpetBlock extends FlowableBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(CARPET, $meta, "Carpet");
|
||||
$names = array(
|
||||
0 => "White Carpet",
|
||||
1 => "Orange Carpet",
|
||||
2 => "Magenta Carpet",
|
||||
3 => "Light Blue Carpet",
|
||||
4 => "Yellow Carpet",
|
||||
5 => "Lime Carpet",
|
||||
6 => "Pink Carpet",
|
||||
7 => "Gray Carpet",
|
||||
8 => "Light Gray Carpet",
|
||||
9 => "Cyan Carpet",
|
||||
10 => "Purple Carpet",
|
||||
11 => "Blue Carpet",
|
||||
12 => "Brown Carpet",
|
||||
13 => "Green Carpet",
|
||||
14 => "Red Carpet",
|
||||
15 => "Black Carpet",
|
||||
);
|
||||
$this->name = $names[$this->meta];
|
||||
$this->hardness = 0;
|
||||
$this->isFullBlock = false;
|
||||
$this->isSolid = true;
|
||||
}
|
||||
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() !== AIR){
|
||||
$this->level->setBlock($block, $this, true, false, true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->getID() === AIR){ //Replace with common break method
|
||||
ServerAPI::request()->api->entity->drop($this, BlockAPI::getItem($this->id, $this->meta, 1));
|
||||
$this->level->setBlock($this, new AirBlock(), true, false, true);
|
||||
return BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -24,6 +24,7 @@ class CobwebBlock extends FlowableBlock{
|
||||
parent::__construct(COBWEB, 0, "Cobweb");
|
||||
$this->isSolid = true;
|
||||
$this->isFullBlock = false;
|
||||
$this->hardness = 25;
|
||||
}
|
||||
public function getDrops(Item $item, Player $player){
|
||||
return array();
|
||||
|
@ -23,6 +23,7 @@ class FenceBlock extends TransparentBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(FENCE, 0, "Fence");
|
||||
$this->isFullBlock = false;
|
||||
$this->hardness = 15;
|
||||
}
|
||||
|
||||
}
|
@ -28,6 +28,7 @@ class FenceGateBlock extends TransparentBlock{
|
||||
}else{
|
||||
$this->isFullBlock = false;
|
||||
}
|
||||
$this->hardness = 15;
|
||||
}
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
$faces = array(
|
||||
|
@ -22,6 +22,8 @@
|
||||
class GlassPaneBlock extends TransparentBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(GLASS_PANE, 0, "Glass Pane");
|
||||
$this->isFullBlock = false;
|
||||
$this->isSolid = false;
|
||||
}
|
||||
|
||||
}
|
29
src/material/block/nonfull/IronBars.php
Normal file
29
src/material/block/nonfull/IronBars.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
class IronBarsBlock extends TransparentBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(IRON_BARS, 0, "Iron Bars");
|
||||
$this->isFullBlock = false;
|
||||
$this->isSolid = false;
|
||||
}
|
||||
|
||||
}
|
@ -23,6 +23,7 @@ class IronDoorBlock extends DoorBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(IRON_DOOR_BLOCK, $meta, "Iron Door Block");
|
||||
//$this->isActivable = true;
|
||||
$this->hardness = 25;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item, Player $player){
|
||||
|
@ -29,7 +29,6 @@ class SlabBlock extends TransparentBlock{
|
||||
3 => "Cobblestone",
|
||||
4 => "Brick",
|
||||
5 => "Stone Brick",
|
||||
//6 => "Nether Brick",
|
||||
6 => "Quartz",
|
||||
);
|
||||
$this->name = (($this->meta & 0x08) === 0x08 ? "Upper ":"") . $names[$this->meta & 0x07] . " Slab";
|
||||
@ -37,7 +36,8 @@ class SlabBlock extends TransparentBlock{
|
||||
$this->isFullBlock = true;
|
||||
}else{
|
||||
$this->isFullBlock = false;
|
||||
}
|
||||
}
|
||||
$this->hardness = 30;
|
||||
}
|
||||
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
@ -46,6 +46,9 @@ class SlabBlock extends TransparentBlock{
|
||||
if($target->getID() === SLAB and ($target->getMetadata() & 0x08) === 0x08 and ($target->getMetadata() & 0x07) === ($this->meta & 0x07)){
|
||||
$this->level->setBlock($target, BlockAPI::get(DOUBLE_SLAB, $this->meta), true, false, true);
|
||||
return true;
|
||||
}elseif($block->getID() === SLAB and ($block->getMetadata() & 0x07) === ($this->meta & 0x07)){
|
||||
$this->level->setBlock($block, BlockAPI::get(DOUBLE_SLAB, $this->meta), true, false, true);
|
||||
return true;
|
||||
}else{
|
||||
$this->meta |= 0x08;
|
||||
}
|
||||
@ -53,6 +56,9 @@ class SlabBlock extends TransparentBlock{
|
||||
if($target->getID() === SLAB and ($target->getMetadata() & 0x08) === 0 and ($target->getMetadata() & 0x07) === ($this->meta & 0x07)){
|
||||
$this->level->setBlock($target, BlockAPI::get(DOUBLE_SLAB, $this->meta), true, false, true);
|
||||
return true;
|
||||
}elseif($block->getID() === SLAB and ($block->getMetadata() & 0x07) === ($this->meta & 0x07)){
|
||||
$this->level->setBlock($block, BlockAPI::get(DOUBLE_SLAB, $this->meta), true, false, true);
|
||||
return true;
|
||||
}
|
||||
}elseif(!$player->entity->inBlock($block)){
|
||||
if($block->getID() === SLAB){
|
||||
|
@ -25,6 +25,16 @@ class SnowLayerBlock extends FlowableBlock{
|
||||
$this->isReplaceable = true;
|
||||
$this->isSolid = false;
|
||||
$this->isFullBlock = false;
|
||||
$this->hardness = 0.5;
|
||||
}
|
||||
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
$down = $this->getSide(0);
|
||||
if($down instanceof SolidBlock){
|
||||
$this->level->setBlock($block, $this, true, false, true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
|
34
src/material/block/nonfull/StoneWall.php
Normal file
34
src/material/block/nonfull/StoneWall.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
class StoneWallBlock extends TransparentBlock{
|
||||
public function __construct($meta = 0){
|
||||
$meta &= 0x01;
|
||||
parent::__construct(STONE_WALL, $meta, "Cobblestone Wall");
|
||||
if($meta === 1){
|
||||
$this->name = "Mossy Cobblestone Wall";
|
||||
}
|
||||
$this->isFullBlock = false;
|
||||
$this->isSolid = false;
|
||||
$this->hardness = 30;
|
||||
}
|
||||
|
||||
}
|
@ -23,6 +23,7 @@ class WoodDoorBlock extends DoorBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(WOOD_DOOR_BLOCK, $meta, "Wood Door Block");
|
||||
$this->isActivable = true;
|
||||
$this->hardness = 15;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
|
107
src/material/block/nonfull/WoodSlab.php
Normal file
107
src/material/block/nonfull/WoodSlab.php
Normal file
@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
class WoodSlabBlock extends TransparentBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(WOOD_SLAB, $meta, "Wooden Slab");
|
||||
$names = array(
|
||||
0 => "Oak",
|
||||
1 => "Spruce",
|
||||
2 => "Birch",
|
||||
3 => "Jungle",
|
||||
);
|
||||
$this->name = (($this->meta & 0x08) === 0x08 ? "Upper ":"") . $names[$this->meta & 0x07] . " Wooden Slab";
|
||||
if(($this->meta & 0x08) === 0x08){
|
||||
$this->isFullBlock = true;
|
||||
}else{
|
||||
$this->isFullBlock = false;
|
||||
}
|
||||
$this->hardness = 15;
|
||||
}
|
||||
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
$this->meta &= 0x07;
|
||||
if($face === 0){
|
||||
if($target->getID() === WOOD_SLAB and ($target->getMetadata() & 0x08) === 0x08 and ($target->getMetadata() & 0x07) === ($this->meta & 0x07)){
|
||||
$this->level->setBlock($target, BlockAPI::get(DOUBLE_WOOD_SLAB, $this->meta), true, false, true);
|
||||
return true;
|
||||
}elseif($block->getID() === WOOD_SLAB and ($block->getMetadata() & 0x07) === ($this->meta & 0x07)){
|
||||
$this->level->setBlock($block, BlockAPI::get(DOUBLE_WOOD_SLAB, $this->meta), true, false, true);
|
||||
return true;
|
||||
}else{
|
||||
$this->meta |= 0x08;
|
||||
}
|
||||
}elseif($face === 1){
|
||||
if($target->getID() === WOOD_SLAB and ($target->getMetadata() & 0x08) === 0 and ($target->getMetadata() & 0x07) === ($this->meta & 0x07)){
|
||||
$this->level->setBlock($target, BlockAPI::get(DOUBLE_WOOD_SLAB, $this->meta), true, false, true);
|
||||
return true;
|
||||
}elseif($block->getID() === WOOD_SLAB and ($block->getMetadata() & 0x07) === ($this->meta & 0x07)){
|
||||
$this->level->setBlock($block, BlockAPI::get(DOUBLE_WOOD_SLAB, $this->meta), true, false, true);
|
||||
return true;
|
||||
}
|
||||
}elseif(!$player->entity->inBlock($block)){
|
||||
if($block->getID() === WOOD_SLAB){
|
||||
if(($block->getMetadata() & 0x07) === ($this->meta & 0x07)){
|
||||
$this->level->setBlock($block, BlockAPI::get(DOUBLE_WOOD_SLAB, $this->meta), true, false, true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}else{
|
||||
if($fy > 0.5){
|
||||
$this->meta |= 0x08;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
if($block->getID() === WOOD_SLAB and ($target->getMetadata() & 0x07) !== ($this->meta & 0x07)){
|
||||
return false;
|
||||
}
|
||||
$this->level->setBlock($block, $this, true, false, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item, Player $player){
|
||||
if(($player->gamemode & 0x01) === 0x01){
|
||||
return 0.20;
|
||||
}
|
||||
switch($item->isAxe()){
|
||||
case 5:
|
||||
return 0.4;
|
||||
case 4:
|
||||
return 0.5;
|
||||
case 3:
|
||||
return 0.75;
|
||||
case 2:
|
||||
return 0.25;
|
||||
case 1:
|
||||
return 1.5;
|
||||
default:
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
return array(
|
||||
array($this->id, $this->meta & 0x07, 1),
|
||||
);
|
||||
}
|
||||
}
|
32
src/material/block/nonfull/stairs/BirchWoodStairs.php
Normal file
32
src/material/block/nonfull/stairs/BirchWoodStairs.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
class BirchWoodStairsBlock extends StairBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(BIRCH_WOOD_STAIRS, $meta, "Birch Wood Stairs");
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
return array(
|
||||
array($this->id, 0, 1),
|
||||
);
|
||||
}
|
||||
}
|
32
src/material/block/nonfull/stairs/JungleWoodStairs.php
Normal file
32
src/material/block/nonfull/stairs/JungleWoodStairs.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
class JungleWoodStairsBlock extends StairBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(JUNGLE_WOOD_STAIRS, $meta, "Jungle Wood Stairs");
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
return array(
|
||||
array($this->id, 0, 1),
|
||||
);
|
||||
}
|
||||
}
|
32
src/material/block/nonfull/stairs/SpruceWoodStairs.php
Normal file
32
src/material/block/nonfull/stairs/SpruceWoodStairs.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
class SpruceWoodStairsBlock extends StairBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(SPRUCE_WOOD_STAIRS, $meta, "Spruce Wood Stairs");
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
return array(
|
||||
array($this->id, 0, 1),
|
||||
);
|
||||
}
|
||||
}
|
@ -23,5 +23,30 @@ class WoodStairsBlock extends StairBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(WOOD_STAIRS, $meta, "Wood Stairs");
|
||||
}
|
||||
|
||||
|
||||
public function getBreakTime(Item $item, Player $player){
|
||||
if(($player->gamemode & 0x01) === 0x01){
|
||||
return 0.20;
|
||||
}
|
||||
switch($item->isAxe()){
|
||||
case 5:
|
||||
return 0.4;
|
||||
case 4:
|
||||
return 0.5;
|
||||
case 3:
|
||||
return 0.75;
|
||||
case 2:
|
||||
return 0.25;
|
||||
case 1:
|
||||
return 1.5;
|
||||
default:
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
return array(
|
||||
array($this->id, 0, 1),
|
||||
);
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@
|
||||
class CoalOreBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(COAL_ORE, 0, "Coal Ore");
|
||||
$this->hardness = 15;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item, Player $player){
|
||||
|
@ -22,6 +22,7 @@
|
||||
class DiamondOreBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(DIAMOND_ORE, 0, "Diamond Ore");
|
||||
$this->hardness = 15;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item, Player $player){
|
||||
|
@ -22,6 +22,7 @@
|
||||
class GlowingRedstoneOreBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(GLOWING_REDSTONE_ORE, 0, "Glowing Redstone Ore");
|
||||
$this->hardness = 15;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
@ -52,7 +53,7 @@ class GlowingRedstoneOreBlock extends SolidBlock{
|
||||
public function getDrops(Item $item, Player $player){
|
||||
if($item->isPickaxe() >= 4){
|
||||
return array(
|
||||
//array(331, 4, mt_rand(4, 5)),
|
||||
array(REDSTONE_DUST, 0, mt_rand(4, 5)),
|
||||
);
|
||||
}else{
|
||||
return array();
|
||||
|
@ -22,6 +22,7 @@
|
||||
class GoldOreBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(GOLD_ORE, 0, "Gold Ore");
|
||||
$this->hardness = 15;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item, Player $player){
|
||||
|
@ -22,6 +22,7 @@
|
||||
class IronOreBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(IRON_ORE, 0, "Iron Ore");
|
||||
$this->hardness = 15;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item, Player $player){
|
||||
|
@ -22,6 +22,7 @@
|
||||
class LapisOreBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(LAPIS_ORE, 0, "Lapis Ore");
|
||||
$this->hardness = 15;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item, Player $player){
|
||||
|
@ -22,6 +22,7 @@
|
||||
class RedstoneOreBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(REDSTONE_ORE, 0, "Redstone Ore");
|
||||
$this->hardness = 15;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
@ -36,7 +37,7 @@ class RedstoneOreBlock extends SolidBlock{
|
||||
public function getDrops(Item $item, Player $player){
|
||||
if($item->isPickaxe() >= 2){
|
||||
return array(
|
||||
//array(331, 4, mt_rand(4, 5)),
|
||||
array(REDSTONE_DUST, 0, mt_rand(4, 5)),
|
||||
);
|
||||
}else{
|
||||
return array();
|
||||
|
82
src/material/block/plant/Beetroot.php
Normal file
82
src/material/block/plant/Beetroot.php
Normal file
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
class BeetrootBlock extends FlowableBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(BEETROOT_BLOCK, $meta, "Beetroot Block");
|
||||
$this->isActivable = true;
|
||||
$this->hardness = 0;
|
||||
}
|
||||
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === FARMLAND){
|
||||
$this->level->setBlock($block, $this, true, false, true);
|
||||
$this->level->scheduleBlockUpdate(new Position($this, 0, 0, $this->level), Utils::getRandomUpdateTicks(), BLOCK_UPDATE_RANDOM);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player){
|
||||
if($item->getID() === DYE and $item->getMetadata() === 0x0F){ //Bonemeal
|
||||
$this->meta = 0x07;
|
||||
$this->level->setBlock($this, $this, true, false, true);
|
||||
if(($player->gamemode & 0x01) === 0){
|
||||
$item->count--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
|
||||
ServerAPI::request()->api->entity->drop($this, BlockAPI::getItem(BEETROOT_SEEDS, 0, 1));
|
||||
$this->level->setBlock($this, new AirBlock(), false, false, true);
|
||||
return BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}elseif($type === BLOCK_UPDATE_RANDOM){
|
||||
if(mt_rand(0, 2) == 1){
|
||||
if($this->meta < 0x07){
|
||||
++$this->meta;
|
||||
$this->level->setBlock($this, $this, true, false, true);
|
||||
return BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
}else{
|
||||
return BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
$drops = array();
|
||||
if($this->meta >= 0x07){
|
||||
$drops[] = array(BEETROOT, 0, 1);
|
||||
$drops[] = array(BEETROOT_SEEDS, 0, mt_rand(0, 3));
|
||||
}else{
|
||||
$drops[] = array(BEETROOT_SEEDS, 0, 1);
|
||||
}
|
||||
return $drops;
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@
|
||||
class BrownMushroomBlock extends FlowableBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(BROWN_MUSHROOM, 0, "Brown Mushroom");
|
||||
$this->hardness = 0;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
|
@ -23,6 +23,7 @@ class CactusBlock extends TransparentBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(CACTUS, $meta, "Cactus");
|
||||
$this->isFullBlock = false;
|
||||
$this->hardness = 2;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
|
81
src/material/block/plant/Carrot.php
Normal file
81
src/material/block/plant/Carrot.php
Normal file
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
class CarrotBlock extends FlowableBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(CARROT_BLOCK, $meta, "Carrot Block");
|
||||
$this->isActivable = true;
|
||||
$this->hardness = 0;
|
||||
}
|
||||
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === FARMLAND){
|
||||
$this->level->setBlock($block, $this, true, false, true);
|
||||
$this->level->scheduleBlockUpdate(new Position($this, 0, 0, $this->level), Utils::getRandomUpdateTicks(), BLOCK_UPDATE_RANDOM);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player){
|
||||
if($item->getID() === DYE and $item->getMetadata() === 0x0F){ //Bonemeal
|
||||
$this->meta = 0x07;
|
||||
$this->level->setBlock($this, $this, true, false, true);
|
||||
if(($player->gamemode & 0x01) === 0){
|
||||
$item->count--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
|
||||
ServerAPI::request()->api->entity->drop($this, BlockAPI::getItem(CARROT, 0, 1));
|
||||
$this->level->setBlock($this, new AirBlock(), false, false, true);
|
||||
return BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}elseif($type === BLOCK_UPDATE_RANDOM){
|
||||
if(mt_rand(0, 2) == 1){
|
||||
if($this->meta < 0x07){
|
||||
++$this->meta;
|
||||
$this->level->setBlock($this, $this, true, false, true);
|
||||
return BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
}else{
|
||||
return BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
$drops = array();
|
||||
if($this->meta >= 0x07){
|
||||
$drops[] = array(CARROT, 0, mt_rand(1, 4));
|
||||
}else{
|
||||
$drops[] = array(CARROT, 0, 1);
|
||||
}
|
||||
return $drops;
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@
|
||||
class CyanFlowerBlock extends FlowableBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(CYAN_FLOWER, 0, "Cyan Flower");
|
||||
$this->hardness = 0;
|
||||
}
|
||||
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
|
@ -22,6 +22,7 @@
|
||||
class DandelionBlock extends FlowableBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(DANDELION, 0, "Dandelion");
|
||||
$this->hardness = 0;
|
||||
}
|
||||
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
|
@ -22,7 +22,8 @@
|
||||
class DeadBushBlock extends FlowableBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(DEAD_BUSH, 0, "Dead Bush");
|
||||
$this->isReplaceable = true;
|
||||
//$this->isReplaceable = true;
|
||||
$this->hardness = 0;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
|
@ -23,6 +23,7 @@ class MelonStemBlock extends FlowableBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(MELON_STEM, $meta, "Melon Stem");
|
||||
$this->isActivable = true;
|
||||
$this->hardness = 0;
|
||||
}
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
$down = $this->getSide(0);
|
||||
|
81
src/material/block/plant/PotatoBlock.php
Normal file
81
src/material/block/plant/PotatoBlock.php
Normal file
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
class PotatoBlock extends FlowableBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(POTATO_BLOCK, $meta, "Potato Block");
|
||||
$this->isActivable = true;
|
||||
$this->hardness = 0;
|
||||
}
|
||||
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === FARMLAND){
|
||||
$this->level->setBlock($block, $this, true, false, true);
|
||||
$this->level->scheduleBlockUpdate(new Position($this, 0, 0, $this->level), Utils::getRandomUpdateTicks(), BLOCK_UPDATE_RANDOM);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player){
|
||||
if($item->getID() === DYE and $item->getMetadata() === 0x0F){ //Bonemeal
|
||||
$this->meta = 0x07;
|
||||
$this->level->setBlock($this, $this, true, false, true);
|
||||
if(($player->gamemode & 0x01) === 0){
|
||||
$item->count--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
|
||||
ServerAPI::request()->api->entity->drop($this, BlockAPI::getItem(POTATO, 0, 1));
|
||||
$this->level->setBlock($this, new AirBlock(), false, false, true);
|
||||
return BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}elseif($type === BLOCK_UPDATE_RANDOM){
|
||||
if(mt_rand(0, 2) == 1){
|
||||
if($this->meta < 0x07){
|
||||
++$this->meta;
|
||||
$this->level->setBlock($this, $this, true, false, true);
|
||||
return BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
}else{
|
||||
return BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
$drops = array();
|
||||
if($this->meta >= 0x07){
|
||||
$drops[] = array(POTATO, 0, mt_rand(1, 4));
|
||||
}else{
|
||||
$drops[] = array(POTATO, 0, 1);
|
||||
}
|
||||
return $drops;
|
||||
}
|
||||
}
|
87
src/material/block/plant/PumpkinStem.php
Normal file
87
src/material/block/plant/PumpkinStem.php
Normal file
@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
class PumpkinStemBlock extends FlowableBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(PUMPKIN_STEM, $meta, "Pumpkin Stem");
|
||||
$this->isActivable = true;
|
||||
$this->hardness = 0;
|
||||
}
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === FARMLAND){
|
||||
$this->level->setBlock($block, $this, true, false, true);
|
||||
$this->level->scheduleBlockUpdate(new Position($this, 0, 0, $this->level), Utils::getRandomUpdateTicks(), BLOCK_UPDATE_RANDOM);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
|
||||
ServerAPI::request()->api->entity->drop($this, BlockAPI::getItem(PUMPKIN_SEEDS, 0, mt_rand(0, 2)));
|
||||
$this->level->setBlock($this, new AirBlock(), false, false, true);
|
||||
return BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}elseif($type === BLOCK_UPDATE_RANDOM){
|
||||
if(mt_rand(0, 2) == 1){
|
||||
if($this->meta < 0x07){
|
||||
++$this->meta;
|
||||
$this->level->setBlock($this, $this, true, false, true);
|
||||
return BLOCK_UPDATE_RANDOM;
|
||||
}else{
|
||||
for($side = 2; $side <= 5; ++$side){
|
||||
$b = $this->getSide($side);
|
||||
if($b->getID() === PUMPKIN){
|
||||
return BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
}
|
||||
$side = $this->getSide(mt_rand(2,5));
|
||||
$d = $side->getSide(0);
|
||||
if($side->getID() === AIR and ($d->getID() === FARMLAND or $d->getID() === GRASS or $d->getID() === DIRT)){
|
||||
$this->level->setBlock($side, new PumpkinBlock(), true, false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
return BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player){
|
||||
if($item->getID() === DYE and $item->getMetadata() === 0x0F){ //Bonemeal
|
||||
$this->meta = 0x07;
|
||||
$this->level->setBlock($this, $this, true, false, true);
|
||||
if(($player->gamemode & 0x01) === 0){
|
||||
$item->count--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
return array(
|
||||
array(PUMPKIN_SEEDS, 0, mt_rand(0, 2)),
|
||||
);
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@
|
||||
class RedMushroomBlock extends FlowableBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(RED_MUSHROOM, 0, "Red Mushroom");
|
||||
$this->hardness = 0;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
|
@ -23,6 +23,7 @@ class SaplingBlock extends FlowableBlock{
|
||||
const OAK = 0;
|
||||
const SPRUCE = 1;
|
||||
const BIRCH = 2;
|
||||
const JUNGLE = 3;
|
||||
const BURN_TIME = 5;
|
||||
|
||||
public function __construct($meta = Sapling::OAK){
|
||||
@ -32,8 +33,10 @@ class SaplingBlock extends FlowableBlock{
|
||||
0 => "Oak Sapling",
|
||||
1 => "Spruce Sapling",
|
||||
2 => "Birch Sapling",
|
||||
3 => "Jungle Sapling",
|
||||
);
|
||||
$this->name = $names[$this->meta & 0x03];
|
||||
$this->hardness = 0;
|
||||
}
|
||||
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
|
@ -22,6 +22,7 @@
|
||||
class SugarcaneBlock extends FlowableBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(SUGARCANE_BLOCK, $meta, "Sugarcane");
|
||||
$this->hardness = 0;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
@ -29,6 +30,27 @@ class SugarcaneBlock extends FlowableBlock{
|
||||
array(SUGARCANE, 0, 1),
|
||||
);
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player){
|
||||
if($item->getID() === DYE and $item->getMetadata() === 0x0F){ //Bonemeal
|
||||
if($this->getSide(0)->getID() !== SUGARCANE_BLOCK){
|
||||
for($y = 1; $y < 3; ++$y){
|
||||
$b = $this->level->getBlock(new Vector3($this->x, $this->y + $y, $this->z));
|
||||
if($b->getID() === AIR){
|
||||
$this->level->setBlock($b, new SugarcaneBlock(), true, false, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->meta = 0;
|
||||
$this->level->setBlock($this, $this, true, false, true);
|
||||
}
|
||||
if(($player->gamemode & 0x01) === 0){
|
||||
$item->count--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === BLOCK_UPDATE_NORMAL){
|
||||
|
@ -22,13 +22,14 @@
|
||||
class TallGrassBlock extends FlowableBlock{
|
||||
public function __construct($meta = 1){
|
||||
parent::__construct(TALL_GRASS, $meta, "Tall Grass");
|
||||
$this->isReplaceable = true;
|
||||
//$this->isReplaceable = true;
|
||||
$names = array(
|
||||
0 => "Dead Shrub",
|
||||
1 => "Tall Grass",
|
||||
2 => "Fern",
|
||||
);
|
||||
$this->name = $names[$this->meta & 0x03];
|
||||
$this->hardness = 0;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
@ -43,8 +44,24 @@ class TallGrassBlock extends FlowableBlock{
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
$drops = array();
|
||||
if(mt_rand(1,10) === 1){//Seeds
|
||||
$drops[] = array(WHEAT_SEEDS, 0, 1);
|
||||
$possibleDrops = array(
|
||||
array(WHEAT_SEEDS, 0, 1),
|
||||
array(CARROT, 0, 1),
|
||||
array(POTATO, 0, 1),
|
||||
array(BEETROOT_SEEDS, 0, 1),
|
||||
array(MELON_SEEDS, 0, 1),
|
||||
array(PUMPKIN_SEEDS, 0, 1),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
);
|
||||
if(($item = $possibleDrops[mt_rand(0, count($possibleDrops) - 1)]) !== 0){
|
||||
$drops[] = $item;
|
||||
}
|
||||
return $drops;
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ class WheatBlock extends FlowableBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(WHEAT_BLOCK, $meta, "Wheat Block");
|
||||
$this->isActivable = true;
|
||||
$this->hardness = 0;
|
||||
}
|
||||
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
|
@ -23,6 +23,7 @@ class BedrockBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(BEDROCK, 0, "Bedrock");
|
||||
$this->breakable = false;
|
||||
$this->hardness = 18000000;
|
||||
}
|
||||
|
||||
public function isBreakable(Item $item, Player $player){
|
||||
|
@ -22,6 +22,7 @@
|
||||
class BookshelfBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(BOOKSHELF, 0, "Bookshelf");
|
||||
$this->hardness = 7.5;
|
||||
}
|
||||
|
||||
}
|
@ -22,6 +22,7 @@
|
||||
class BricksBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(BRICKS_BLOCK, 0, "Bricks");
|
||||
$this->hardness = 30;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item, Player $player){
|
||||
|
@ -23,6 +23,7 @@ class BurningFurnaceBlock extends SolidBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(BURNING_FURNACE, $meta, "Burning Furnace");
|
||||
$this->isActivable = true;
|
||||
$this->hardness = 17.5;
|
||||
}
|
||||
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
|
@ -23,6 +23,7 @@ class ChestBlock extends TransparentBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(CHEST, $meta, "Chest");
|
||||
$this->isActivable = true;
|
||||
$this->hardness = 15;
|
||||
}
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
$server = ServerAPI::request();
|
||||
|
@ -22,6 +22,7 @@
|
||||
class ClayBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(CLAY_BLOCK, 0, "Clay Block");
|
||||
$this->hardness = 3;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
|
57
src/material/block/solid/Coal.php
Normal file
57
src/material/block/solid/Coal.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
class CoalBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(COAL_BLOCK, 0, "Coal Block");
|
||||
$this->hardness = 30;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item, Player $player){
|
||||
if(($player->gamemode & 0x01) === 0x01){
|
||||
return 0.20;
|
||||
}
|
||||
switch($item->isPickaxe()){
|
||||
case 5:
|
||||
return 0.95;
|
||||
case 4:
|
||||
return 1.25;
|
||||
case 3:
|
||||
return 1.9;
|
||||
case 2:
|
||||
return 0.65;
|
||||
case 1:
|
||||
return 3.75;
|
||||
default:
|
||||
return 25;
|
||||
}
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
if($item->isPickaxe() >= 1){
|
||||
return array(
|
||||
array(COAL_BLOCK, 0, 1),
|
||||
);
|
||||
}else{
|
||||
return array();
|
||||
}
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@
|
||||
class CobblestoneBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(COBBLESTONE, 0, "Cobblestone");
|
||||
$this->hardness = 30;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item, Player $player){
|
||||
|
@ -22,6 +22,7 @@
|
||||
class DiamondBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(DIAMOND_BLOCK, 0, "Diamond Block");
|
||||
$this->hardness = 30;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item, Player $player){
|
||||
|
@ -23,6 +23,7 @@ class DirtBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(DIRT, 0, "Dirt");
|
||||
$this->isActivable = true;
|
||||
$this->hardness = 2.5;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player){
|
||||
|
@ -29,10 +29,10 @@ class DoubleSlabBlock extends SolidBlock{
|
||||
3 => "Cobblestone",
|
||||
4 => "Brick",
|
||||
5 => "Stone Brick",
|
||||
6 => "Nether Brick",
|
||||
7 => "Quartz",
|
||||
6 => "Quartz",
|
||||
);
|
||||
$this->name = "Double " . $names[$this->meta & 0x07] . " Slab";
|
||||
$this->hardness = 30;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item, Player $player){
|
||||
|
61
src/material/block/solid/DoubleWoodSlab.php
Normal file
61
src/material/block/solid/DoubleWoodSlab.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
class DoubleWoodSlabBlock extends SolidBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(DOUBLE_WOOD_SLAB, $meta, "Double Wooden Slab");
|
||||
$names = array(
|
||||
0 => "Oak",
|
||||
1 => "Spruce",
|
||||
2 => "Birch",
|
||||
3 => "Jungle",
|
||||
);
|
||||
$this->name = "Double " . $names[$this->meta & 0x07] . " Wooden Slab";
|
||||
$this->hardness = 15;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item, Player $player){
|
||||
if(($player->gamemode & 0x01) === 0x01){
|
||||
return 0.20;
|
||||
}
|
||||
switch($item->isAxe()){
|
||||
case 5:
|
||||
return 0.4;
|
||||
case 4:
|
||||
return 0.5;
|
||||
case 3:
|
||||
return 0.75;
|
||||
case 2:
|
||||
return 0.25;
|
||||
case 1:
|
||||
return 1.5;
|
||||
default:
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
return array(
|
||||
array(WOOD_SLAB, $this->meta & 0x07, 2),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -22,6 +22,7 @@
|
||||
class FarmlandBlock extends SolidBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(FARMLAND, $meta, "Farmland");
|
||||
$this->hardness = 3;
|
||||
}
|
||||
public function getDrops(Item $item, Player $player){
|
||||
return array(
|
||||
|
@ -22,6 +22,7 @@
|
||||
class GlassBlock extends TransparentBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(GLASS, 0, "Glass");
|
||||
$this->hardness = 1.5;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
|
@ -22,6 +22,7 @@
|
||||
class GlowstoneBlock extends TransparentBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(GLOWSTONE_BLOCK, 0, "Glowstone");
|
||||
$this->hardness = 1.5;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
|
@ -22,6 +22,7 @@
|
||||
class GoldBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(GOLD_BLOCK, 0, "Gold Block");
|
||||
$this->hardness = 30;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item, Player $player){
|
||||
|
@ -23,6 +23,7 @@ class GrassBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(GRASS, 0, "Grass");
|
||||
$this->isActivable = true;
|
||||
$this->hardness = 3;
|
||||
}
|
||||
public function getDrops(Item $item, Player $player){
|
||||
return array(
|
||||
@ -35,7 +36,7 @@ class GrassBlock extends SolidBlock{
|
||||
if(($player->gamemode & 0x01) === 0){
|
||||
$item->count--;
|
||||
}
|
||||
TallGrassObject::growGrass($this->level, $this, new Random());
|
||||
TallGrassObject::growGrass($this->level, $this, new Random(), 8, 2);
|
||||
return true;
|
||||
}elseif($item->isHoe()){
|
||||
if(($player->gamemode & 0x01) === 0){
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user