mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-11 12:08:05 +00:00
Compare commits
70 Commits
Author | SHA1 | Date | |
---|---|---|---|
d4851a8f1f | |||
480a513f30 | |||
4fd3bee360 | |||
41fd7545e3 | |||
82dddde159 | |||
bc709efb77 | |||
cd98e6a23e | |||
cb591a98f4 | |||
e9d1af0aee | |||
0f545c410a | |||
1c2ed0836f | |||
6cf30dc813 | |||
f7d9247d39 | |||
3380aa3ac2 | |||
6a9cad8fb7 | |||
c9e598cdb9 | |||
a6e5b6e158 | |||
22a6b817d7 | |||
2cdf97b7b5 | |||
836cb67850 | |||
ab37df4484 | |||
93969197f7 | |||
946a1036f1 | |||
43410cdafb | |||
a99e15012c | |||
b22a2ef914 | |||
f7f7be896e | |||
254281cd5e | |||
5dfceeea98 | |||
4b9a142a5d | |||
0bacf51729 | |||
33f6b441d8 | |||
11b59498d9 | |||
d71a543d10 | |||
5e0c3333cf | |||
0f941410f6 | |||
504cc3bf8b | |||
6bd1491b8b | |||
658786f2f6 | |||
d34f3f1af3 | |||
8650c187f9 | |||
4b4820cf53 | |||
d33acc4fd0 | |||
f7de6eb59f | |||
75a0627bf2 | |||
8752e363c9 | |||
9ed1b5ca7f | |||
1cbb31f1db | |||
1393b4c4e2 | |||
2921c86b3c | |||
9c3a929b65 | |||
9abaa42cd7 | |||
77b9feb3c0 | |||
e0e2e1775f | |||
d2d65ce6cc | |||
ff2e982f22 | |||
daf56e990b | |||
3f5e83a322 | |||
5ecc5ed7e0 | |||
cd80ae00d4 | |||
beb5d72299 | |||
0eef634aab | |||
0ea166a551 | |||
6417cff618 | |||
a71af952ba | |||
93dd05a03e | |||
98f903783c | |||
5d47ea4337 | |||
c242d6213a | |||
4ad1093fd7 |
@ -2,13 +2,14 @@ language: php
|
||||
|
||||
php:
|
||||
- 7.2
|
||||
- 7.3
|
||||
|
||||
before_script:
|
||||
# - pecl install channel://pecl.php.net/pthreads-3.1.6
|
||||
- echo | pecl install channel://pecl.php.net/yaml-2.0.2
|
||||
- echo | pecl install channel://pecl.php.net/yaml-2.0.4
|
||||
- git clone https://github.com/pmmp/pthreads.git
|
||||
- cd pthreads
|
||||
- git checkout c8cfacda84f21032d6014b53e72bf345ac901dac
|
||||
- git checkout 6ca019c58b4fa09ee2ff490f2444e34bef0773d0
|
||||
- phpize
|
||||
- ./configure
|
||||
- make
|
||||
|
@ -30,7 +30,8 @@
|
||||
"pocketmine/nbt": "^0.2.1",
|
||||
"pocketmine/math": "^0.2.0",
|
||||
"pocketmine/snooze": "^0.1.0",
|
||||
"daverandom/callback-validator": "dev-master"
|
||||
"daverandom/callback-validator": "dev-master",
|
||||
"adhocore/json-comment": "^0.0.7"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
108
composer.lock
generated
108
composer.lock
generated
@ -4,8 +4,52 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "2d120a3dd7d68958809c3662d1cb7c99",
|
||||
"content-hash": "d3fb809caf4d5a5c99054f47f28ff271",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/json-comment",
|
||||
"version": "v0.0.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/adhocore/php-json-comment.git",
|
||||
"reference": "135356c7e7336ef59924f1d921c770045f937a76"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/adhocore/php-json-comment/zipball/135356c7e7336ef59924f1d921c770045f937a76",
|
||||
"reference": "135356c7e7336ef59924f1d921c770045f937a76",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8 || ^5.7 || ^6.5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Ahc\\Json\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jitendra Adhikari",
|
||||
"email": "jiten.adhikary@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Lightweight JSON comment stripper library for PHP",
|
||||
"keywords": [
|
||||
"comment",
|
||||
"json",
|
||||
"strip-comment"
|
||||
],
|
||||
"time": "2018-08-01T12:27:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "daverandom/callback-validator",
|
||||
"version": "dev-master",
|
||||
@ -48,16 +92,16 @@
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/binaryutils",
|
||||
"version": "0.1.2",
|
||||
"version": "0.1.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/BinaryUtils.git",
|
||||
"reference": "2c1628f08a9cdeca4d3c682e13f24420944ca845"
|
||||
"reference": "3403751da9d39853b43426085cd242173baadd2b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/2c1628f08a9cdeca4d3c682e13f24420944ca845",
|
||||
"reference": "2c1628f08a9cdeca4d3c682e13f24420944ca845",
|
||||
"url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/3403751da9d39853b43426085cd242173baadd2b",
|
||||
"reference": "3403751da9d39853b43426085cd242173baadd2b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -75,23 +119,23 @@
|
||||
],
|
||||
"description": "Classes and methods for conveniently handling binary data",
|
||||
"support": {
|
||||
"source": "https://github.com/pmmp/BinaryUtils/tree/0.1.2",
|
||||
"source": "https://github.com/pmmp/BinaryUtils/tree/0.1.7",
|
||||
"issues": "https://github.com/pmmp/BinaryUtils/issues"
|
||||
},
|
||||
"time": "2018-12-22T12:29:30+00:00"
|
||||
"time": "2019-01-07T15:59:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/math",
|
||||
"version": "0.2.1",
|
||||
"version": "0.2.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/Math.git",
|
||||
"reference": "ee299f5c9c444ca526c9c691b920f321458cf0b6"
|
||||
"reference": "b755d3fb7025c4ddb7d9d6df0ba7e0b65125e51c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/Math/zipball/ee299f5c9c444ca526c9c691b920f321458cf0b6",
|
||||
"reference": "ee299f5c9c444ca526c9c691b920f321458cf0b6",
|
||||
"url": "https://api.github.com/repos/pmmp/Math/zipball/b755d3fb7025c4ddb7d9d6df0ba7e0b65125e51c",
|
||||
"reference": "b755d3fb7025c4ddb7d9d6df0ba7e0b65125e51c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -109,23 +153,23 @@
|
||||
],
|
||||
"description": "PHP library containing math related code used in PocketMine-MP",
|
||||
"support": {
|
||||
"source": "https://github.com/pmmp/Math/tree/0.2.1",
|
||||
"source": "https://github.com/pmmp/Math/tree/0.2.2",
|
||||
"issues": "https://github.com/pmmp/Math/issues"
|
||||
},
|
||||
"time": "2018-08-15T15:43:27+00:00"
|
||||
"time": "2019-01-04T15:42:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/nbt",
|
||||
"version": "0.2.3",
|
||||
"version": "0.2.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/NBT.git",
|
||||
"reference": "291bf5cc2a94500eada1edbda51d15bed25a1e1c"
|
||||
"reference": "0b290fa0f5b44835ebeea8146c9ac960cac833f5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/NBT/zipball/291bf5cc2a94500eada1edbda51d15bed25a1e1c",
|
||||
"reference": "291bf5cc2a94500eada1edbda51d15bed25a1e1c",
|
||||
"url": "https://api.github.com/repos/pmmp/NBT/zipball/0b290fa0f5b44835ebeea8146c9ac960cac833f5",
|
||||
"reference": "0b290fa0f5b44835ebeea8146c9ac960cac833f5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -150,23 +194,23 @@
|
||||
],
|
||||
"description": "PHP library for working with Named Binary Tags",
|
||||
"support": {
|
||||
"source": "https://github.com/pmmp/NBT/tree/0.2.3",
|
||||
"source": "https://github.com/pmmp/NBT/tree/0.2.5",
|
||||
"issues": "https://github.com/pmmp/NBT/issues"
|
||||
},
|
||||
"time": "2018-12-03T16:08:28+00:00"
|
||||
"time": "2019-01-07T17:28:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/raklib",
|
||||
"version": "0.12.0",
|
||||
"version": "0.12.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/RakLib.git",
|
||||
"reference": "922da28efd828e2af6c19db1676ea9b6a267071c"
|
||||
"reference": "334b469f2d0f070f17902d7ac584bea7c6149dc6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/RakLib/zipball/922da28efd828e2af6c19db1676ea9b6a267071c",
|
||||
"reference": "922da28efd828e2af6c19db1676ea9b6a267071c",
|
||||
"url": "https://api.github.com/repos/pmmp/RakLib/zipball/334b469f2d0f070f17902d7ac584bea7c6149dc6",
|
||||
"reference": "334b469f2d0f070f17902d7ac584bea7c6149dc6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -191,23 +235,23 @@
|
||||
],
|
||||
"description": "A RakNet server implementation written in PHP",
|
||||
"support": {
|
||||
"source": "https://github.com/pmmp/RakLib/tree/0.12.0",
|
||||
"source": "https://github.com/pmmp/RakLib/tree/0.12.1",
|
||||
"issues": "https://github.com/pmmp/RakLib/issues"
|
||||
},
|
||||
"time": "2018-06-13T10:06:14+00:00"
|
||||
"time": "2019-01-04T14:23:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/snooze",
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/Snooze.git",
|
||||
"reference": "3cc9d0164230889acb08e22cc126133809e9d346"
|
||||
"reference": "b7bd231bdb75e69300cac89ccd515fc731c38c40"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/Snooze/zipball/3cc9d0164230889acb08e22cc126133809e9d346",
|
||||
"reference": "3cc9d0164230889acb08e22cc126133809e9d346",
|
||||
"url": "https://api.github.com/repos/pmmp/Snooze/zipball/b7bd231bdb75e69300cac89ccd515fc731c38c40",
|
||||
"reference": "b7bd231bdb75e69300cac89ccd515fc731c38c40",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -225,10 +269,10 @@
|
||||
],
|
||||
"description": "Thread notification management library for code using the pthreads extension",
|
||||
"support": {
|
||||
"source": "https://github.com/pmmp/Snooze/tree/0.1.0",
|
||||
"source": "https://github.com/pmmp/Snooze/tree/0.1.1",
|
||||
"issues": "https://github.com/pmmp/Snooze/issues"
|
||||
},
|
||||
"time": "2018-06-13T09:36:11+00:00"
|
||||
"time": "2019-01-04T15:54:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/spl",
|
||||
@ -258,7 +302,7 @@
|
||||
],
|
||||
"description": "Standard library files required by PocketMine-MP and related projects",
|
||||
"support": {
|
||||
"source": "https://github.com/pmmp/SPL/tree/master"
|
||||
"source": "https://github.com/pmmp/SPL/tree/0.3.2"
|
||||
},
|
||||
"time": "2018-08-12T15:17:39+00:00"
|
||||
}
|
||||
|
@ -30,6 +30,55 @@ use pocketmine\plugin\PluginManager;
|
||||
use pocketmine\utils\Utils;
|
||||
use pocketmine\utils\VersionString;
|
||||
use raklib\RakLib;
|
||||
use function base64_encode;
|
||||
use function date;
|
||||
use function error_get_last;
|
||||
use function fclose;
|
||||
use function file;
|
||||
use function file_exists;
|
||||
use function file_get_contents;
|
||||
use function fopen;
|
||||
use function fwrite;
|
||||
use function get_loaded_extensions;
|
||||
use function implode;
|
||||
use function is_dir;
|
||||
use function is_resource;
|
||||
use function json_encode;
|
||||
use function json_last_error_msg;
|
||||
use function max;
|
||||
use function mkdir;
|
||||
use function ob_end_clean;
|
||||
use function ob_get_contents;
|
||||
use function ob_start;
|
||||
use function php_uname;
|
||||
use function phpinfo;
|
||||
use function phpversion;
|
||||
use function preg_replace;
|
||||
use function str_split;
|
||||
use function strpos;
|
||||
use function substr;
|
||||
use function time;
|
||||
use function zend_version;
|
||||
use function zlib_encode;
|
||||
use const E_COMPILE_ERROR;
|
||||
use const E_COMPILE_WARNING;
|
||||
use const E_CORE_ERROR;
|
||||
use const E_CORE_WARNING;
|
||||
use const E_DEPRECATED;
|
||||
use const E_ERROR;
|
||||
use const E_NOTICE;
|
||||
use const E_PARSE;
|
||||
use const E_RECOVERABLE_ERROR;
|
||||
use const E_STRICT;
|
||||
use const E_USER_DEPRECATED;
|
||||
use const E_USER_ERROR;
|
||||
use const E_USER_NOTICE;
|
||||
use const E_USER_WARNING;
|
||||
use const E_WARNING;
|
||||
use const FILE_IGNORE_NEW_LINES;
|
||||
use const JSON_UNESCAPED_SLASHES;
|
||||
use const PHP_EOL;
|
||||
use const PHP_OS;
|
||||
|
||||
class CrashDump{
|
||||
|
||||
@ -39,7 +88,11 @@ class CrashDump{
|
||||
* having their content changed, version format changing, etc.
|
||||
* It is not necessary to increase this when adding new fields.
|
||||
*/
|
||||
private const FORMAT_VERSION = 1;
|
||||
private const FORMAT_VERSION = 2;
|
||||
|
||||
private const PLUGIN_INVOLVEMENT_NONE = "none";
|
||||
private const PLUGIN_INVOLVEMENT_DIRECT = "direct";
|
||||
private const PLUGIN_INVOLVEMENT_INDIRECT = "indirect";
|
||||
|
||||
/** @var Server */
|
||||
private $server;
|
||||
@ -94,7 +147,11 @@ class CrashDump{
|
||||
$this->addLine("----------------------REPORT THE DATA BELOW THIS LINE-----------------------");
|
||||
$this->addLine();
|
||||
$this->addLine("===BEGIN CRASH DUMP===");
|
||||
$this->encodedData = zlib_encode(json_encode($this->data, JSON_UNESCAPED_SLASHES), ZLIB_ENCODING_DEFLATE, 9);
|
||||
$json = json_encode($this->data, JSON_UNESCAPED_SLASHES);
|
||||
if($json === false){
|
||||
throw new \RuntimeException("Failed to encode crashdump JSON: " . json_last_error_msg());
|
||||
}
|
||||
$this->encodedData = zlib_encode($json, ZLIB_ENCODING_DEFLATE, 9);
|
||||
foreach(str_split(base64_encode($this->encodedData), 76) as $line){
|
||||
$this->addLine($line);
|
||||
}
|
||||
@ -159,7 +216,7 @@ class CrashDump{
|
||||
$error = $lastExceptionError;
|
||||
}else{
|
||||
$error = (array) error_get_last();
|
||||
$error["trace"] = Utils::printableCurrentTrace(3); //Skipping CrashDump->baseCrash, CrashDump->construct, Server->crashDump
|
||||
$error["trace"] = Utils::currentTrace(3); //Skipping CrashDump->baseCrash, CrashDump->construct, Server->crashDump
|
||||
$errorConversion = [
|
||||
E_ERROR => "E_ERROR",
|
||||
E_WARNING => "E_WARNING",
|
||||
@ -186,6 +243,9 @@ class CrashDump{
|
||||
}
|
||||
|
||||
if(isset($lastError)){
|
||||
if(isset($lastError["trace"])){
|
||||
$lastError["trace"] = Utils::printableTrace($lastError["trace"]);
|
||||
}
|
||||
$this->data["lastError"] = $lastError;
|
||||
}
|
||||
|
||||
@ -197,24 +257,16 @@ class CrashDump{
|
||||
$this->addLine("Line: " . $error["line"]);
|
||||
$this->addLine("Type: " . $error["type"]);
|
||||
|
||||
if(strpos($error["file"], "src/pocketmine/") === false and strpos($error["file"], "vendor/pocketmine/") === false and file_exists($error["fullFile"])){
|
||||
$this->addLine();
|
||||
$this->addLine("THIS CRASH WAS CAUSED BY A PLUGIN");
|
||||
$this->data["plugin"] = true;
|
||||
|
||||
$reflection = new \ReflectionClass(PluginBase::class);
|
||||
$file = $reflection->getProperty("file");
|
||||
$file->setAccessible(true);
|
||||
foreach($this->server->getPluginManager()->getPlugins() as $plugin){
|
||||
$filePath = Utils::cleanPath($file->getValue($plugin));
|
||||
if(strpos($error["file"], $filePath) === 0){
|
||||
$this->data["plugin"] = $plugin->getName();
|
||||
$this->addLine("BAD PLUGIN: " . $plugin->getDescription()->getFullName());
|
||||
$this->data["plugin_involvement"] = self::PLUGIN_INVOLVEMENT_NONE;
|
||||
if(!$this->determinePluginFromFile($error["fullFile"], true)){ //fatal errors won't leave any stack trace
|
||||
foreach($error["trace"] as $frame){
|
||||
if(!isset($frame["file"])){
|
||||
continue; //PHP core
|
||||
}
|
||||
if($this->determinePluginFromFile($frame["file"], false)){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
$this->data["plugin"] = false;
|
||||
}
|
||||
|
||||
$this->addLine();
|
||||
@ -231,12 +283,40 @@ class CrashDump{
|
||||
|
||||
$this->addLine();
|
||||
$this->addLine("Backtrace:");
|
||||
foreach(($this->data["trace"] = $error["trace"]) as $line){
|
||||
foreach(($this->data["trace"] = Utils::printableTrace($error["trace"])) as $line){
|
||||
$this->addLine($line);
|
||||
}
|
||||
$this->addLine();
|
||||
}
|
||||
|
||||
private function determinePluginFromFile(string $filePath, bool $crashFrame) : bool{
|
||||
$frameCleanPath = Utils::cleanPath($filePath); //this will be empty in phar stub
|
||||
if($frameCleanPath !== "" and strpos($frameCleanPath, "src/pocketmine/") === false and strpos($frameCleanPath, "vendor/pocketmine/") === false and file_exists($filePath)){
|
||||
$this->addLine();
|
||||
if($crashFrame){
|
||||
$this->addLine("THIS CRASH WAS CAUSED BY A PLUGIN");
|
||||
$this->data["plugin_involvement"] = self::PLUGIN_INVOLVEMENT_DIRECT;
|
||||
}else{
|
||||
$this->addLine("A PLUGIN WAS INVOLVED IN THIS CRASH");
|
||||
$this->data["plugin_involvement"] = self::PLUGIN_INVOLVEMENT_INDIRECT;
|
||||
}
|
||||
|
||||
$reflection = new \ReflectionClass(PluginBase::class);
|
||||
$file = $reflection->getProperty("file");
|
||||
$file->setAccessible(true);
|
||||
foreach($this->server->getPluginManager()->getPlugins() as $plugin){
|
||||
$filePath = Utils::cleanPath($file->getValue($plugin));
|
||||
if(strpos($frameCleanPath, $filePath) === 0){
|
||||
$this->data["plugin"] = $plugin->getName();
|
||||
$this->addLine("BAD PLUGIN: " . $plugin->getDescription()->getFullName());
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function generalData(){
|
||||
$version = new VersionString(\pocketmine\BASE_VERSION, \pocketmine\IS_DEVELOPMENT_BUILD, \pocketmine\BUILD_NUMBER);
|
||||
$this->data["general"] = [];
|
||||
|
@ -28,6 +28,39 @@ use pocketmine\scheduler\DumpWorkerMemoryTask;
|
||||
use pocketmine\scheduler\GarbageCollectionTask;
|
||||
use pocketmine\timings\Timings;
|
||||
use pocketmine\utils\Utils;
|
||||
use function arsort;
|
||||
use function count;
|
||||
use function fclose;
|
||||
use function file_exists;
|
||||
use function file_put_contents;
|
||||
use function fopen;
|
||||
use function fwrite;
|
||||
use function gc_collect_cycles;
|
||||
use function gc_disable;
|
||||
use function gc_enable;
|
||||
use function get_class;
|
||||
use function get_declared_classes;
|
||||
use function implode;
|
||||
use function ini_get;
|
||||
use function ini_set;
|
||||
use function is_array;
|
||||
use function is_object;
|
||||
use function is_resource;
|
||||
use function is_string;
|
||||
use function json_encode;
|
||||
use function min;
|
||||
use function mkdir;
|
||||
use function preg_match;
|
||||
use function print_r;
|
||||
use function round;
|
||||
use function spl_object_hash;
|
||||
use function sprintf;
|
||||
use function strlen;
|
||||
use function strtoupper;
|
||||
use function substr;
|
||||
use const JSON_PRETTY_PRINT;
|
||||
use const JSON_UNESCAPED_SLASHES;
|
||||
use const SORT_NUMERIC;
|
||||
|
||||
class MemoryManager{
|
||||
|
||||
|
@ -160,6 +160,40 @@ use pocketmine\tile\Tile;
|
||||
use pocketmine\timings\Timings;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use pocketmine\utils\UUID;
|
||||
use function abs;
|
||||
use function array_merge;
|
||||
use function assert;
|
||||
use function base64_decode;
|
||||
use function ceil;
|
||||
use function count;
|
||||
use function explode;
|
||||
use function floor;
|
||||
use function fmod;
|
||||
use function get_class;
|
||||
use function gettype;
|
||||
use function implode;
|
||||
use function in_array;
|
||||
use function is_int;
|
||||
use function is_object;
|
||||
use function is_string;
|
||||
use function json_encode;
|
||||
use function json_last_error_msg;
|
||||
use function lcg_value;
|
||||
use function max;
|
||||
use function microtime;
|
||||
use function min;
|
||||
use function preg_match;
|
||||
use function round;
|
||||
use function spl_object_hash;
|
||||
use function strlen;
|
||||
use function strpos;
|
||||
use function strtolower;
|
||||
use function substr;
|
||||
use function trim;
|
||||
use function ucfirst;
|
||||
use const M_PI;
|
||||
use const M_SQRT3;
|
||||
use const PHP_INT_MAX;
|
||||
|
||||
|
||||
/**
|
||||
@ -327,6 +361,11 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
/** @var Form[] */
|
||||
protected $forms = [];
|
||||
|
||||
/** @var float */
|
||||
protected $lastRightClickTime = 0.0;
|
||||
/** @var Vector3|null */
|
||||
protected $lastRightClickPos = null;
|
||||
|
||||
/**
|
||||
* @return TranslationContainer|string
|
||||
*/
|
||||
@ -671,7 +710,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
public function sendCommandData(){
|
||||
$pk = new AvailableCommandsPacket();
|
||||
foreach($this->server->getCommandMap()->getCommands() as $name => $command){
|
||||
if(isset($pk->commandData[$command->getName()]) or $command->getName() === "help"){
|
||||
if(isset($pk->commandData[$command->getName()]) or $command->getName() === "help" or !$command->testPermissionSilent($this)){
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1037,6 +1076,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
$this->server->broadcastMessage($ev->getJoinMessage());
|
||||
}
|
||||
|
||||
$this->setImmobile(false);
|
||||
$this->noDamageTicks = 60;
|
||||
|
||||
foreach($this->usedChunks as $index => $c){
|
||||
@ -1073,8 +1113,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
|
||||
Timings::$playerChunkOrderTimer->startTiming();
|
||||
|
||||
$this->nextChunkOrderRun = 200;
|
||||
|
||||
$radius = $this->server->getAllowedViewDistance($this->viewDistance);
|
||||
$radiusSquared = $radius ** 2;
|
||||
|
||||
@ -1772,7 +1810,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
return;
|
||||
}
|
||||
|
||||
if($this->nextChunkOrderRun-- <= 0){
|
||||
if($this->nextChunkOrderRun !== PHP_INT_MAX and $this->nextChunkOrderRun-- <= 0){
|
||||
$this->nextChunkOrderRun = PHP_INT_MAX;
|
||||
$this->orderChunks();
|
||||
}
|
||||
|
||||
@ -2105,6 +2144,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
$this->setNameTagVisible();
|
||||
$this->setNameTagAlwaysVisible();
|
||||
$this->setCanClimb();
|
||||
$this->setImmobile(); //disable pre-spawn movement
|
||||
|
||||
$this->server->getLogger()->info($this->getServer()->getLanguage()->translateString("pocketmine.player.logIn", [
|
||||
TextFormat::AQUA . $this->username . TextFormat::WHITE,
|
||||
@ -2264,7 +2304,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
if($action !== null){
|
||||
$actions[] = $action;
|
||||
}
|
||||
}catch(\Exception $e){
|
||||
}catch(\UnexpectedValueException $e){
|
||||
$this->server->getLogger()->debug("Unhandled inventory action from " . $this->getName() . ": " . $e->getMessage());
|
||||
$this->sendAllInventories();
|
||||
return false;
|
||||
@ -2334,6 +2374,19 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
$type = $packet->trData->actionType;
|
||||
switch($type){
|
||||
case InventoryTransactionPacket::USE_ITEM_ACTION_CLICK_BLOCK:
|
||||
//TODO: start hack for client spam bug
|
||||
$spamBug = ($this->lastRightClickPos !== null and
|
||||
microtime(true) - $this->lastRightClickTime < 0.1 and //100ms
|
||||
$this->lastRightClickPos->distanceSquared($packet->trData->clickPos) < 0.00001 //signature spam bug has 0 distance, but allow some error
|
||||
);
|
||||
//get rid of continued spam if the player clicks and holds right-click
|
||||
$this->lastRightClickPos = clone $packet->trData->clickPos;
|
||||
$this->lastRightClickTime = microtime(true);
|
||||
if($spamBug){
|
||||
return true;
|
||||
}
|
||||
//TODO: end hack for client spam bug
|
||||
|
||||
$this->setUsingItem(false);
|
||||
|
||||
if(!$this->canInteract($blockVector->add(0.5, 0.5, 0.5), 13) or $this->isSpectator()){
|
||||
@ -3398,92 +3451,82 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
*/
|
||||
final public function close($message = "", string $reason = "generic reason", bool $notify = true) : void{
|
||||
if($this->isConnected() and !$this->closed){
|
||||
if($notify and strlen($reason) > 0){
|
||||
$pk = new DisconnectPacket();
|
||||
$pk->message = $reason;
|
||||
$this->directDataPacket($pk);
|
||||
}
|
||||
$this->interface->close($this, $notify ? $reason : "");
|
||||
$this->sessionAdapter = null;
|
||||
|
||||
try{
|
||||
if($notify and strlen($reason) > 0){
|
||||
$pk = new DisconnectPacket();
|
||||
$pk->message = $reason;
|
||||
$this->directDataPacket($pk);
|
||||
PermissionManager::getInstance()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_USERS, $this);
|
||||
PermissionManager::getInstance()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this);
|
||||
|
||||
$this->stopSleep();
|
||||
|
||||
if($this->spawned){
|
||||
$ev = new PlayerQuitEvent($this, $message, $reason);
|
||||
$ev->call();
|
||||
if($ev->getQuitMessage() != ""){
|
||||
$this->server->broadcastMessage($ev->getQuitMessage());
|
||||
}
|
||||
$this->interface->close($this, $notify ? $reason : "");
|
||||
$this->sessionAdapter = null;
|
||||
|
||||
PermissionManager::getInstance()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_USERS, $this);
|
||||
PermissionManager::getInstance()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this);
|
||||
$this->save();
|
||||
}
|
||||
|
||||
$this->stopSleep();
|
||||
|
||||
if($this->spawned){
|
||||
$ev = new PlayerQuitEvent($this, $message, $reason);
|
||||
$ev->call();
|
||||
if($ev->getQuitMessage() != ""){
|
||||
$this->server->broadcastMessage($ev->getQuitMessage());
|
||||
if($this->isValid()){
|
||||
foreach($this->usedChunks as $index => $d){
|
||||
Level::getXZ($index, $chunkX, $chunkZ);
|
||||
$this->level->unregisterChunkLoader($this, $chunkX, $chunkZ);
|
||||
foreach($this->level->getChunkEntities($chunkX, $chunkZ) as $entity){
|
||||
$entity->despawnFrom($this);
|
||||
}
|
||||
unset($this->usedChunks[$index]);
|
||||
}
|
||||
}
|
||||
$this->usedChunks = [];
|
||||
$this->loadQueue = [];
|
||||
|
||||
try{
|
||||
$this->save();
|
||||
}catch(\Throwable $e){
|
||||
$this->server->getLogger()->critical("Failed to save player data for " . $this->getName());
|
||||
$this->server->getLogger()->logException($e);
|
||||
if($this->loggedIn){
|
||||
$this->server->onPlayerLogout($this);
|
||||
foreach($this->server->getOnlinePlayers() as $player){
|
||||
if(!$player->canSee($this)){
|
||||
$player->showPlayer($this);
|
||||
}
|
||||
}
|
||||
$this->hiddenPlayers = [];
|
||||
}
|
||||
|
||||
if($this->isValid()){
|
||||
foreach($this->usedChunks as $index => $d){
|
||||
Level::getXZ($index, $chunkX, $chunkZ);
|
||||
$this->level->unregisterChunkLoader($this, $chunkX, $chunkZ);
|
||||
foreach($this->level->getChunkEntities($chunkX, $chunkZ) as $entity){
|
||||
$entity->despawnFrom($this);
|
||||
}
|
||||
unset($this->usedChunks[$index]);
|
||||
}
|
||||
}
|
||||
$this->usedChunks = [];
|
||||
$this->loadQueue = [];
|
||||
$this->removeAllWindows(true);
|
||||
$this->windows = [];
|
||||
$this->windowIndex = [];
|
||||
$this->cursorInventory = null;
|
||||
$this->craftingGrid = null;
|
||||
|
||||
if($this->loggedIn){
|
||||
$this->server->onPlayerLogout($this);
|
||||
foreach($this->server->getOnlinePlayers() as $player){
|
||||
if(!$player->canSee($this)){
|
||||
$player->showPlayer($this);
|
||||
}
|
||||
}
|
||||
$this->hiddenPlayers = [];
|
||||
}
|
||||
if($this->constructed){
|
||||
parent::close();
|
||||
}
|
||||
$this->spawned = false;
|
||||
|
||||
$this->removeAllWindows(true);
|
||||
$this->windows = [];
|
||||
$this->windowIndex = [];
|
||||
$this->cursorInventory = null;
|
||||
$this->craftingGrid = null;
|
||||
if($this->loggedIn){
|
||||
$this->loggedIn = false;
|
||||
$this->server->removeOnlinePlayer($this);
|
||||
}
|
||||
|
||||
if($this->constructed){
|
||||
parent::close();
|
||||
}
|
||||
$this->spawned = false;
|
||||
$this->server->removePlayer($this);
|
||||
|
||||
if($this->loggedIn){
|
||||
$this->loggedIn = false;
|
||||
$this->server->removeOnlinePlayer($this);
|
||||
}
|
||||
$this->server->getLogger()->info($this->getServer()->getLanguage()->translateString("pocketmine.player.logOut", [
|
||||
TextFormat::AQUA . $this->getName() . TextFormat::WHITE,
|
||||
$this->ip,
|
||||
$this->port,
|
||||
$this->getServer()->getLanguage()->translateString($reason)
|
||||
]));
|
||||
|
||||
$this->server->getLogger()->info($this->getServer()->getLanguage()->translateString("pocketmine.player.logOut", [
|
||||
TextFormat::AQUA . $this->getName() . TextFormat::WHITE,
|
||||
$this->ip,
|
||||
$this->port,
|
||||
$this->getServer()->getLanguage()->translateString($reason)
|
||||
]));
|
||||
$this->spawnPosition = null;
|
||||
|
||||
$this->spawnPosition = null;
|
||||
|
||||
if($this->perm !== null){
|
||||
$this->perm->clearPermissions();
|
||||
$this->perm = null;
|
||||
}
|
||||
}catch(\Throwable $e){
|
||||
$this->server->getLogger()->logException($e);
|
||||
}finally{
|
||||
$this->server->removePlayer($this);
|
||||
if($this->perm !== null){
|
||||
$this->perm->clearPermissions();
|
||||
$this->perm = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3584,10 +3627,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
}
|
||||
|
||||
protected function onDeathUpdate(int $tickDiff) : bool{
|
||||
if(parent::onDeathUpdate($tickDiff)){
|
||||
$this->despawnFromAll(); //non-player entities rely on close() to do this for them
|
||||
}
|
||||
|
||||
parent::onDeathUpdate($tickDiff);
|
||||
return false; //never flag players for despawn
|
||||
}
|
||||
|
||||
@ -3896,9 +3936,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
public function onChunkChanged(Chunk $chunk){
|
||||
if(isset($this->usedChunks[$hash = Level::chunkHash($chunk->getX(), $chunk->getZ())])){
|
||||
$this->usedChunks[$hash] = false;
|
||||
if(!$this->spawned){
|
||||
$this->nextChunkOrderRun = 0;
|
||||
}
|
||||
$this->nextChunkOrderRun = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ namespace pocketmine {
|
||||
use pocketmine\wizard\SetupWizard;
|
||||
|
||||
const NAME = "PocketMine-MP";
|
||||
const BASE_VERSION = "3.5.2";
|
||||
const BASE_VERSION = "3.5.6";
|
||||
const IS_DEVELOPMENT_BUILD = false;
|
||||
const BUILD_NUMBER = 0;
|
||||
|
||||
|
@ -98,7 +98,6 @@ use pocketmine\tile\Tile;
|
||||
use pocketmine\timings\Timings;
|
||||
use pocketmine\timings\TimingsHandler;
|
||||
use pocketmine\updater\AutoUpdater;
|
||||
use pocketmine\utils\Binary;
|
||||
use pocketmine\utils\Config;
|
||||
use pocketmine\utils\Internet;
|
||||
use pocketmine\utils\MainLogger;
|
||||
@ -106,6 +105,77 @@ use pocketmine\utils\Terminal;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use pocketmine\utils\Utils;
|
||||
use pocketmine\utils\UUID;
|
||||
use function array_filter;
|
||||
use function array_key_exists;
|
||||
use function array_shift;
|
||||
use function array_sum;
|
||||
use function asort;
|
||||
use function assert;
|
||||
use function base64_encode;
|
||||
use function bin2hex;
|
||||
use function class_exists;
|
||||
use function count;
|
||||
use function define;
|
||||
use function explode;
|
||||
use function extension_loaded;
|
||||
use function file_exists;
|
||||
use function file_get_contents;
|
||||
use function file_put_contents;
|
||||
use function filemtime;
|
||||
use function floor;
|
||||
use function function_exists;
|
||||
use function gc_collect_cycles;
|
||||
use function get_class;
|
||||
use function getmypid;
|
||||
use function getopt;
|
||||
use function gettype;
|
||||
use function implode;
|
||||
use function ini_get;
|
||||
use function ini_set;
|
||||
use function is_array;
|
||||
use function is_bool;
|
||||
use function is_dir;
|
||||
use function is_object;
|
||||
use function is_string;
|
||||
use function is_subclass_of;
|
||||
use function json_decode;
|
||||
use function max;
|
||||
use function microtime;
|
||||
use function min;
|
||||
use function mkdir;
|
||||
use function pcntl_signal;
|
||||
use function pcntl_signal_dispatch;
|
||||
use function preg_replace;
|
||||
use function random_bytes;
|
||||
use function random_int;
|
||||
use function realpath;
|
||||
use function register_shutdown_function;
|
||||
use function rename;
|
||||
use function round;
|
||||
use function scandir;
|
||||
use function sleep;
|
||||
use function spl_object_hash;
|
||||
use function sprintf;
|
||||
use function str_repeat;
|
||||
use function str_replace;
|
||||
use function stripos;
|
||||
use function strlen;
|
||||
use function strrpos;
|
||||
use function strtolower;
|
||||
use function substr;
|
||||
use function time;
|
||||
use function touch;
|
||||
use function trim;
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
use const INT32_MAX;
|
||||
use const INT32_MIN;
|
||||
use const PHP_EOL;
|
||||
use const PHP_INT_MAX;
|
||||
use const PTHREADS_INHERIT_NONE;
|
||||
use const SCANDIR_SORT_NONE;
|
||||
use const SIGHUP;
|
||||
use const SIGINT;
|
||||
use const SIGTERM;
|
||||
|
||||
/**
|
||||
* The class that manages everything
|
||||
@ -1059,7 +1129,7 @@ class Server{
|
||||
return false;
|
||||
}
|
||||
|
||||
$seed = $seed ?? Binary::readInt(random_bytes(4));
|
||||
$seed = $seed ?? random_int(INT32_MIN, INT32_MAX);
|
||||
|
||||
if(!isset($options["preset"])){
|
||||
$options["preset"] = $this->getConfigString("generator-settings", "");
|
||||
@ -1449,8 +1519,6 @@ class Server{
|
||||
"announce-player-achievements" => true,
|
||||
"spawn-protection" => 16,
|
||||
"max-players" => 20,
|
||||
"spawn-animals" => true,
|
||||
"spawn-mobs" => true,
|
||||
"gamemode" => 0,
|
||||
"force-gamemode" => false,
|
||||
"hardcore" => false,
|
||||
@ -1485,7 +1553,7 @@ class Server{
|
||||
return;
|
||||
}
|
||||
|
||||
if(((int) ini_get('zend.assertions')) > 0 and ((bool) $this->getProperty("debug.assertions.warn-if-enabled", true)) !== false){
|
||||
if(((int) ini_get('zend.assertions')) !== -1){
|
||||
$this->logger->warning("Debugging assertions are enabled, this may impact on performance. To disable them, set `zend.assertions = -1` in php.ini.");
|
||||
}
|
||||
|
||||
@ -1663,7 +1731,9 @@ class Server{
|
||||
GeneratorManager::registerDefaultGenerators();
|
||||
|
||||
foreach((array) $this->getProperty("worlds", []) as $name => $options){
|
||||
if(!is_array($options)){
|
||||
if($options === null){
|
||||
$options = [];
|
||||
}elseif(!is_array($options)){
|
||||
continue;
|
||||
}
|
||||
if(!$this->loadLevel($name)){
|
||||
@ -2173,7 +2243,7 @@ class Server{
|
||||
"fullFile" => $e->getFile(),
|
||||
"file" => $errfile,
|
||||
"line" => $errline,
|
||||
"trace" => Utils::printableTrace($trace)
|
||||
"trace" => $trace
|
||||
];
|
||||
|
||||
global $lastExceptionError, $lastError;
|
||||
@ -2212,7 +2282,7 @@ class Server{
|
||||
if(is_string($plugin)){
|
||||
$p = $this->pluginManager->getPlugin($plugin);
|
||||
if($p instanceof Plugin and !($p->getPluginLoader() instanceof PharPluginLoader)){
|
||||
$report = false;
|
||||
$this->logger->debug("Not sending crashdump due to caused by non-phar plugin");
|
||||
}
|
||||
}
|
||||
|
||||
@ -2254,6 +2324,7 @@ class Server{
|
||||
//Force minimum uptime to be >= 120 seconds, to reduce the impact of spammy crash loops
|
||||
$spacing = ((int) \pocketmine\START_TIME) - time() + 120;
|
||||
if($spacing > 0){
|
||||
echo "--- Waiting $spacing seconds to throttle automatic restart (you can kill the process safely now) ---" . PHP_EOL;
|
||||
sleep($spacing);
|
||||
}
|
||||
@Utils::kill(getmypid());
|
||||
@ -2491,9 +2562,7 @@ class Server{
|
||||
$this->logger->debug("Unhandled raw packet from $address $port: " . bin2hex($payload));
|
||||
}
|
||||
}catch(\Throwable $e){
|
||||
if(\pocketmine\DEBUG > 1){
|
||||
$this->logger->logException($e);
|
||||
}
|
||||
$this->logger->logException($e);
|
||||
|
||||
$this->getNetwork()->blockAddress($address, 600);
|
||||
}
|
||||
@ -2584,10 +2653,9 @@ class Server{
|
||||
|
||||
TimingsHandler::tick($this->currentTPS <= $this->profilingTickRate);
|
||||
|
||||
array_shift($this->tickAverage);
|
||||
$this->tickAverage[] = $this->currentTPS;
|
||||
array_shift($this->useAverage);
|
||||
$this->useAverage[] = $this->currentUse;
|
||||
$idx = $this->tickCounter % 20;
|
||||
$this->tickAverage[$idx] = $this->currentTPS;
|
||||
$this->useAverage[$idx] = $this->currentUse;
|
||||
|
||||
if(($this->nextTick - $tickTime) < -1){
|
||||
$this->nextTick = $tickTime;
|
||||
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine;
|
||||
|
||||
use pocketmine\utils\MainLogger;
|
||||
use function spl_object_hash;
|
||||
|
||||
class ThreadManager extends \Volatile{
|
||||
|
||||
|
@ -26,6 +26,13 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use function array_map;
|
||||
use function array_reverse;
|
||||
use function array_search;
|
||||
use function array_shift;
|
||||
use function count;
|
||||
use function implode;
|
||||
use function in_array;
|
||||
|
||||
abstract class BaseRail extends Flowable{
|
||||
|
||||
@ -98,7 +105,7 @@ abstract class BaseRail extends Flowable{
|
||||
$meta = array_search(array_reverse($connections), $lookup, true);
|
||||
}
|
||||
if($meta === false){
|
||||
throw new \InvalidArgumentException("No meta value matches connections " . implode(", ", array_map('dechex', $connections)));
|
||||
throw new \InvalidArgumentException("No meta value matches connections " . implode(", ", array_map('\dechex', $connections)));
|
||||
}
|
||||
|
||||
return $meta;
|
||||
|
@ -25,6 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use function mt_rand;
|
||||
|
||||
class Beetroot extends Crops{
|
||||
|
||||
|
@ -38,6 +38,8 @@ use pocketmine\metadata\Metadatable;
|
||||
use pocketmine\metadata\MetadataValue;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\plugin\Plugin;
|
||||
use function array_merge;
|
||||
use const PHP_INT_MAX;
|
||||
|
||||
class Block extends Position implements BlockIds, Metadatable{
|
||||
|
||||
|
@ -25,6 +25,10 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Position;
|
||||
use function file_get_contents;
|
||||
use function json_decode;
|
||||
use function max;
|
||||
use function min;
|
||||
|
||||
/**
|
||||
* Manages block registration and instance creation
|
||||
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use function mt_rand;
|
||||
|
||||
class BrownMushroomBlock extends RedMushroomBlock{
|
||||
|
||||
|
@ -25,6 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use function mt_rand;
|
||||
|
||||
class Carrot extends Crops{
|
||||
|
||||
|
@ -26,6 +26,7 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\TieredTool;
|
||||
use function mt_rand;
|
||||
|
||||
class CoalOre extends Solid{
|
||||
|
||||
|
@ -27,6 +27,7 @@ use pocketmine\event\block\BlockGrowEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use function mt_rand;
|
||||
|
||||
abstract class Crops extends Flowable{
|
||||
|
||||
|
@ -27,6 +27,7 @@ use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use function mt_rand;
|
||||
|
||||
class DeadBush extends Flowable{
|
||||
|
||||
|
@ -26,6 +26,7 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\TieredTool;
|
||||
use function mt_rand;
|
||||
|
||||
class DiamondOre extends Solid{
|
||||
|
||||
|
@ -27,6 +27,7 @@ use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use function mt_rand;
|
||||
|
||||
class DoublePlant extends Flowable{
|
||||
public const BITFLAG_TOP = 0x08;
|
||||
|
@ -26,6 +26,7 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\TieredTool;
|
||||
use function mt_rand;
|
||||
|
||||
class EmeraldOre extends Solid{
|
||||
|
||||
|
@ -31,6 +31,8 @@ use pocketmine\event\entity\EntityDamageByBlockEvent;
|
||||
use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Vector3;
|
||||
use function min;
|
||||
use function mt_rand;
|
||||
|
||||
class Fire extends Flowable{
|
||||
|
||||
|
@ -25,6 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use function mt_rand;
|
||||
|
||||
class Glowstone extends Transparent{
|
||||
|
||||
|
@ -32,6 +32,7 @@ use pocketmine\level\generator\object\TallGrass as TallGrassObject;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\utils\Random;
|
||||
use function mt_rand;
|
||||
|
||||
class Grass extends Solid{
|
||||
|
||||
|
@ -25,6 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use function mt_rand;
|
||||
|
||||
class Gravel extends Fallable{
|
||||
|
||||
|
@ -56,7 +56,7 @@ class Ice extends Transparent{
|
||||
}
|
||||
|
||||
public function onBreak(Item $item, Player $player = null) : bool{
|
||||
if(!$item->hasEnchantment(Enchantment::SILK_TOUCH)){
|
||||
if(($player === null or $player->isSurvival()) and !$item->hasEnchantment(Enchantment::SILK_TOUCH)){
|
||||
return $this->getLevel()->setBlock($this, BlockFactory::get(Block::WATER), true);
|
||||
}
|
||||
return parent::onBreak($item, $player);
|
||||
|
@ -28,6 +28,7 @@ use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\tile\ItemFrame as TileItemFrame;
|
||||
use pocketmine\tile\Tile;
|
||||
use function lcg_value;
|
||||
|
||||
class ItemFrame extends Flowable{
|
||||
protected $id = Block::ITEM_FRAME_BLOCK;
|
||||
|
@ -26,6 +26,7 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\TieredTool;
|
||||
use function mt_rand;
|
||||
|
||||
class LapisOre extends Solid{
|
||||
|
||||
|
@ -28,6 +28,7 @@ use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use function mt_rand;
|
||||
|
||||
class Leaves extends Transparent{
|
||||
public const OAK = 0;
|
||||
|
@ -31,6 +31,9 @@ use pocketmine\level\Level;
|
||||
use pocketmine\level\sound\FizzSound;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use function array_fill;
|
||||
use function lcg_value;
|
||||
use function min;
|
||||
|
||||
abstract class Liquid extends Transparent{
|
||||
|
||||
|
@ -25,6 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use function mt_rand;
|
||||
|
||||
class Melon extends Transparent{
|
||||
|
||||
|
@ -27,6 +27,7 @@ use pocketmine\event\block\BlockGrowEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\math\Vector3;
|
||||
use function mt_rand;
|
||||
|
||||
class MelonStem extends Crops{
|
||||
|
||||
|
@ -25,6 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\TieredTool;
|
||||
use function mt_rand;
|
||||
|
||||
class MonsterSpawner extends Transparent{
|
||||
|
||||
|
@ -27,6 +27,7 @@ use pocketmine\event\block\BlockSpreadEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\math\Vector3;
|
||||
use function mt_rand;
|
||||
|
||||
class Mycelium extends Solid{
|
||||
|
||||
|
@ -26,6 +26,7 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\TieredTool;
|
||||
use function mt_rand;
|
||||
|
||||
class NetherQuartzOre extends Solid{
|
||||
|
||||
|
@ -29,6 +29,7 @@ use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use function mt_rand;
|
||||
|
||||
class NetherWartPlant extends Flowable{
|
||||
protected $id = Block::NETHER_WART_PLANT;
|
||||
|
@ -25,6 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use function mt_rand;
|
||||
|
||||
class Potato extends Crops{
|
||||
|
||||
|
@ -27,6 +27,7 @@ use pocketmine\event\block\BlockGrowEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\math\Vector3;
|
||||
use function mt_rand;
|
||||
|
||||
class PumpkinStem extends Crops{
|
||||
|
||||
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use function mt_rand;
|
||||
|
||||
class RedMushroomBlock extends Solid{
|
||||
|
||||
|
@ -28,6 +28,7 @@ use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\TieredTool;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use function mt_rand;
|
||||
|
||||
class RedstoneOre extends Solid{
|
||||
|
||||
|
@ -28,6 +28,7 @@ use pocketmine\level\generator\object\Tree;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\utils\Random;
|
||||
use function mt_rand;
|
||||
|
||||
class Sapling extends Flowable{
|
||||
public const OAK = 0;
|
||||
|
@ -29,6 +29,7 @@ use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\tile\Sign as TileSign;
|
||||
use pocketmine\tile\Tile;
|
||||
use function floor;
|
||||
|
||||
class SignPost extends Transparent{
|
||||
|
||||
|
@ -30,6 +30,7 @@ use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\tile\Banner as TileBanner;
|
||||
use pocketmine\tile\Tile;
|
||||
use function floor;
|
||||
|
||||
class StandingBanner extends Transparent{
|
||||
|
||||
|
@ -30,6 +30,9 @@ use pocketmine\item\Item;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\utils\Random;
|
||||
use function cos;
|
||||
use function sin;
|
||||
use const M_PI;
|
||||
|
||||
class TNT extends Solid{
|
||||
|
||||
|
@ -27,6 +27,7 @@ use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use function mt_rand;
|
||||
|
||||
class TallGrass extends Flowable{
|
||||
|
||||
|
@ -45,8 +45,8 @@ class Torch extends Flowable{
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
$below = $this->getSide(Vector3::SIDE_DOWN);
|
||||
$side = $this->getDamage();
|
||||
$faces = [
|
||||
$meta = $this->getDamage();
|
||||
static $faces = [
|
||||
0 => Vector3::SIDE_DOWN,
|
||||
1 => Vector3::SIDE_WEST,
|
||||
2 => Vector3::SIDE_EAST,
|
||||
@ -54,8 +54,9 @@ class Torch extends Flowable{
|
||||
4 => Vector3::SIDE_SOUTH,
|
||||
5 => Vector3::SIDE_DOWN
|
||||
];
|
||||
$face = $faces[$meta] ?? Vector3::SIDE_DOWN;
|
||||
|
||||
if($this->getSide($faces[$side])->isTransparent() and !($faces[$side] === Vector3::SIDE_DOWN and ($below->getId() === self::FENCE or $below->getId() === self::COBBLESTONE_WALL))){
|
||||
if($this->getSide($face)->isTransparent() and !($face === Vector3::SIDE_DOWN and ($below->getId() === self::FENCE or $below->getId() === self::COBBLESTONE_WALL))){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,10 @@ class UnknownBlock extends Transparent{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function canBePlaced() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
return [];
|
||||
}
|
||||
|
@ -28,6 +28,8 @@ use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use function max;
|
||||
use function min;
|
||||
|
||||
class Vine extends Flowable{
|
||||
public const FLAG_SOUTH = 0x01;
|
||||
|
@ -67,7 +67,7 @@ class Water extends Liquid{
|
||||
|
||||
public function onEntityCollide(Entity $entity) : void{
|
||||
$entity->resetFallDistance();
|
||||
if($entity->fireTicks > 0){
|
||||
if($entity->isOnFire()){
|
||||
$entity->extinguish();
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use function mt_rand;
|
||||
|
||||
class Wheat extends Crops{
|
||||
|
||||
|
@ -32,6 +32,8 @@ use pocketmine\permission\PermissionManager;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\timings\TimingsHandler;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use function explode;
|
||||
use function str_replace;
|
||||
|
||||
abstract class Command{
|
||||
|
||||
|
@ -26,6 +26,22 @@ namespace pocketmine\command;
|
||||
use pocketmine\snooze\SleeperNotifier;
|
||||
use pocketmine\Thread;
|
||||
use pocketmine\utils\Utils;
|
||||
use function extension_loaded;
|
||||
use function fclose;
|
||||
use function fgets;
|
||||
use function fopen;
|
||||
use function fstat;
|
||||
use function getopt;
|
||||
use function is_resource;
|
||||
use function microtime;
|
||||
use function preg_replace;
|
||||
use function readline;
|
||||
use function readline_add_history;
|
||||
use function stream_isatty;
|
||||
use function stream_select;
|
||||
use function trim;
|
||||
use function usleep;
|
||||
use const STDIN;
|
||||
|
||||
class CommandReader extends Thread{
|
||||
|
||||
|
@ -31,6 +31,9 @@ use pocketmine\permission\PermissionAttachmentInfo;
|
||||
use pocketmine\plugin\Plugin;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\utils\MainLogger;
|
||||
use function explode;
|
||||
use function trim;
|
||||
use const PHP_INT_MAX;
|
||||
|
||||
class ConsoleCommandSender implements CommandSender{
|
||||
|
||||
|
@ -25,6 +25,11 @@ namespace pocketmine\command;
|
||||
|
||||
use pocketmine\Server;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use function count;
|
||||
use function ord;
|
||||
use function strlen;
|
||||
use function strpos;
|
||||
use function substr;
|
||||
|
||||
class FormattedCommandAlias extends Command{
|
||||
private $formatStrings = [];
|
||||
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\command;
|
||||
|
||||
use pocketmine\lang\TextContainer;
|
||||
use function trim;
|
||||
|
||||
class RemoteConsoleCommandSender extends ConsoleCommandSender{
|
||||
|
||||
|
@ -66,6 +66,16 @@ use pocketmine\command\defaults\VersionCommand;
|
||||
use pocketmine\command\defaults\WhitelistCommand;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\Server;
|
||||
use function array_map;
|
||||
use function array_shift;
|
||||
use function count;
|
||||
use function explode;
|
||||
use function implode;
|
||||
use function min;
|
||||
use function str_getcsv;
|
||||
use function strpos;
|
||||
use function strtolower;
|
||||
use function trim;
|
||||
|
||||
class SimpleCommandMap implements CommandMap{
|
||||
|
||||
@ -90,9 +100,11 @@ class SimpleCommandMap implements CommandMap{
|
||||
new DefaultGamemodeCommand("defaultgamemode"),
|
||||
new DeopCommand("deop"),
|
||||
new DifficultyCommand("difficulty"),
|
||||
new DumpMemoryCommand("dumpmemory"),
|
||||
new EffectCommand("effect"),
|
||||
new EnchantCommand("enchant"),
|
||||
new GamemodeCommand("gamemode"),
|
||||
new GarbageCollectorCommand("gc"),
|
||||
new GiveCommand("give"),
|
||||
new HelpCommand("help"),
|
||||
new KickCommand("kick"),
|
||||
@ -112,6 +124,7 @@ class SimpleCommandMap implements CommandMap{
|
||||
new SeedCommand("seed"),
|
||||
new SetWorldSpawnCommand("setworldspawn"),
|
||||
new SpawnpointCommand("spawnpoint"),
|
||||
new StatusCommand("status"),
|
||||
new StopCommand("stop"),
|
||||
new TeleportCommand("tp"),
|
||||
new TellCommand("tell"),
|
||||
@ -122,14 +135,6 @@ class SimpleCommandMap implements CommandMap{
|
||||
new VersionCommand("version"),
|
||||
new WhitelistCommand("whitelist")
|
||||
]);
|
||||
|
||||
if($this->server->getProperty("debug.commands", false)){
|
||||
$this->registerAll("pocketmine", [
|
||||
new StatusCommand("status"),
|
||||
new GarbageCollectorCommand("gc"),
|
||||
new DumpMemoryCommand("dumpmemory")
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -242,7 +247,7 @@ class SimpleCommandMap implements CommandMap{
|
||||
}
|
||||
|
||||
public function dispatch(CommandSender $sender, string $commandLine) : bool{
|
||||
$args = array_map("stripslashes", str_getcsv($commandLine, " "));
|
||||
$args = array_map("\stripslashes", str_getcsv($commandLine, " "));
|
||||
$sentCommandLabel = "";
|
||||
$target = $this->matchCommand($sentCommandLabel, $args);
|
||||
|
||||
|
@ -28,6 +28,9 @@ use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\Player;
|
||||
use function array_shift;
|
||||
use function count;
|
||||
use function implode;
|
||||
|
||||
class BanCommand extends VanillaCommand{
|
||||
|
||||
|
@ -28,6 +28,10 @@ use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\Player;
|
||||
use function array_shift;
|
||||
use function count;
|
||||
use function implode;
|
||||
use function preg_match;
|
||||
|
||||
class BanIpCommand extends VanillaCommand{
|
||||
|
||||
|
@ -27,6 +27,10 @@ use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\permission\BanEntry;
|
||||
use function array_map;
|
||||
use function count;
|
||||
use function implode;
|
||||
use function strtolower;
|
||||
|
||||
class BanListCommand extends VanillaCommand{
|
||||
|
||||
|
@ -27,6 +27,7 @@ use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\Server;
|
||||
use function count;
|
||||
|
||||
class DefaultGamemodeCommand extends VanillaCommand{
|
||||
|
||||
|
@ -29,6 +29,8 @@ use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use function array_shift;
|
||||
use function count;
|
||||
|
||||
class DeopCommand extends VanillaCommand{
|
||||
|
||||
|
@ -28,6 +28,7 @@ use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\level\Level;
|
||||
use function count;
|
||||
|
||||
class DifficultyCommand extends VanillaCommand{
|
||||
|
||||
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\command\defaults;
|
||||
|
||||
use pocketmine\command\CommandSender;
|
||||
use function date;
|
||||
|
||||
class DumpMemoryCommand extends VanillaCommand{
|
||||
|
||||
|
@ -29,6 +29,9 @@ use pocketmine\entity\Effect;
|
||||
use pocketmine\entity\EffectInstance;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use function count;
|
||||
use function strtolower;
|
||||
use const INT32_MAX;
|
||||
|
||||
class EffectCommand extends VanillaCommand{
|
||||
|
||||
|
@ -29,6 +29,8 @@ use pocketmine\item\enchantment\Enchantment;
|
||||
use pocketmine\item\enchantment\EnchantmentInstance;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use function count;
|
||||
use function is_numeric;
|
||||
|
||||
class EnchantCommand extends VanillaCommand{
|
||||
|
||||
@ -75,7 +77,15 @@ class EnchantCommand extends VanillaCommand{
|
||||
return true;
|
||||
}
|
||||
|
||||
$item->addEnchantment(new EnchantmentInstance($enchantment, (int) ($args[2] ?? 1)));
|
||||
$level = 1;
|
||||
if(isset($args[2])){
|
||||
$level = $this->getBoundedInt($sender, $args[2], 1, $enchantment->getMaxLevel());
|
||||
if($level === null){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$item->addEnchantment(new EnchantmentInstance($enchantment, $level));
|
||||
$player->getInventory()->setItemInHand($item);
|
||||
|
||||
|
||||
|
@ -30,6 +30,7 @@ use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use function count;
|
||||
|
||||
class GamemodeCommand extends VanillaCommand{
|
||||
|
||||
|
@ -25,6 +25,10 @@ namespace pocketmine\command\defaults;
|
||||
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use function count;
|
||||
use function memory_get_usage;
|
||||
use function number_format;
|
||||
use function round;
|
||||
|
||||
class GarbageCollectorCommand extends VanillaCommand{
|
||||
|
||||
@ -66,7 +70,7 @@ class GarbageCollectorCommand extends VanillaCommand{
|
||||
$sender->sendMessage(TextFormat::GOLD . "Tiles: " . TextFormat::RED . number_format($tilesCollected));
|
||||
|
||||
$sender->sendMessage(TextFormat::GOLD . "Cycles: " . TextFormat::RED . number_format($cyclesCollected));
|
||||
$sender->sendMessage(TextFormat::GOLD . "Memory freed: " . TextFormat::RED . number_format(round((($memory - memory_get_usage()) / 1024) / 1024, 2)) . " MB");
|
||||
$sender->sendMessage(TextFormat::GOLD . "Memory freed: " . TextFormat::RED . number_format(round((($memory - memory_get_usage()) / 1024) / 1024, 2), 2) . " MB");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,9 @@ use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\nbt\JsonNbtParser;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use function array_slice;
|
||||
use function count;
|
||||
use function implode;
|
||||
|
||||
class GiveCommand extends VanillaCommand{
|
||||
|
||||
|
@ -27,6 +27,17 @@ use pocketmine\command\Command;
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use function array_chunk;
|
||||
use function array_pop;
|
||||
use function count;
|
||||
use function explode;
|
||||
use function implode;
|
||||
use function is_numeric;
|
||||
use function ksort;
|
||||
use function min;
|
||||
use function strtolower;
|
||||
use const SORT_FLAG_CASE;
|
||||
use const SORT_NATURAL;
|
||||
|
||||
class HelpCommand extends VanillaCommand{
|
||||
|
||||
|
@ -29,6 +29,10 @@ use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use function array_shift;
|
||||
use function count;
|
||||
use function implode;
|
||||
use function trim;
|
||||
|
||||
class KickCommand extends VanillaCommand{
|
||||
|
||||
|
@ -30,6 +30,7 @@ use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use function count;
|
||||
|
||||
class KillCommand extends VanillaCommand{
|
||||
|
||||
|
@ -26,6 +26,10 @@ namespace pocketmine\command\defaults;
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\Player;
|
||||
use function array_filter;
|
||||
use function array_map;
|
||||
use function count;
|
||||
use function implode;
|
||||
|
||||
class ListCommand extends VanillaCommand{
|
||||
|
||||
|
@ -28,6 +28,8 @@ use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use function count;
|
||||
use function implode;
|
||||
|
||||
class MeCommand extends VanillaCommand{
|
||||
|
||||
|
@ -29,6 +29,8 @@ use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use function array_shift;
|
||||
use function count;
|
||||
|
||||
class OpCommand extends VanillaCommand{
|
||||
|
||||
|
@ -27,6 +27,7 @@ use pocketmine\command\Command;
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use function count;
|
||||
|
||||
class PardonCommand extends VanillaCommand{
|
||||
|
||||
|
@ -27,6 +27,8 @@ use pocketmine\command\Command;
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use function count;
|
||||
use function preg_match;
|
||||
|
||||
class PardonIpCommand extends VanillaCommand{
|
||||
|
||||
|
@ -62,6 +62,13 @@ use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\utils\Random;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use function count;
|
||||
use function explode;
|
||||
use function max;
|
||||
use function microtime;
|
||||
use function mt_rand;
|
||||
use function strpos;
|
||||
use function strtolower;
|
||||
|
||||
class ParticleCommand extends VanillaCommand{
|
||||
|
||||
@ -216,12 +223,12 @@ class ParticleCommand extends VanillaCommand{
|
||||
}elseif(strpos($name, "blockcrack_") === 0){
|
||||
$d = explode("_", $name);
|
||||
if(count($d) === 2){
|
||||
return new TerrainParticle($pos, BlockFactory::get($d[1] & 0xff, $d[1] >> 12));
|
||||
return new TerrainParticle($pos, BlockFactory::get(((int) $d[1]) & 0xff, ((int) $d[1]) >> 12));
|
||||
}
|
||||
}elseif(strpos($name, "blockdust_") === 0){
|
||||
$d = explode("_", $name);
|
||||
if(count($d) >= 4){
|
||||
return new DustParticle($pos, $d[1] & 0xff, $d[2] & 0xff, $d[3] & 0xff, isset($d[4]) ? $d[4] & 0xff : 255);
|
||||
return new DustParticle($pos, ((int) $d[1]) & 0xff, ((int) $d[2]) & 0xff, ((int) $d[3]) & 0xff, isset($d[4]) ? ((int) $d[4]) & 0xff : 255);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,9 @@ use pocketmine\command\CommandSender;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\plugin\Plugin;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use function array_map;
|
||||
use function count;
|
||||
use function implode;
|
||||
|
||||
class PluginsCommand extends VanillaCommand{
|
||||
|
||||
|
@ -29,6 +29,8 @@ use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use function count;
|
||||
use function implode;
|
||||
|
||||
class SayCommand extends VanillaCommand{
|
||||
|
||||
|
@ -30,6 +30,8 @@ use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use function count;
|
||||
use function round;
|
||||
|
||||
class SetWorldSpawnCommand extends VanillaCommand{
|
||||
|
||||
|
@ -31,6 +31,8 @@ use pocketmine\level\Level;
|
||||
use pocketmine\level\Position;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use function count;
|
||||
use function round;
|
||||
|
||||
class SpawnpointCommand extends VanillaCommand{
|
||||
|
||||
|
@ -26,6 +26,11 @@ namespace pocketmine\command\defaults;
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use pocketmine\utils\Utils;
|
||||
use function count;
|
||||
use function floor;
|
||||
use function microtime;
|
||||
use function number_format;
|
||||
use function round;
|
||||
|
||||
class StatusCommand extends VanillaCommand{
|
||||
|
||||
@ -91,14 +96,14 @@ class StatusCommand extends VanillaCommand{
|
||||
|
||||
$sender->sendMessage(TextFormat::GOLD . "Thread count: " . TextFormat::RED . Utils::getThreadCount());
|
||||
|
||||
$sender->sendMessage(TextFormat::GOLD . "Main thread memory: " . TextFormat::RED . number_format(round(($mUsage[0] / 1024) / 1024, 2)) . " MB.");
|
||||
$sender->sendMessage(TextFormat::GOLD . "Total memory: " . TextFormat::RED . number_format(round(($mUsage[1] / 1024) / 1024, 2)) . " MB.");
|
||||
$sender->sendMessage(TextFormat::GOLD . "Total virtual memory: " . TextFormat::RED . number_format(round(($mUsage[2] / 1024) / 1024, 2)) . " MB.");
|
||||
$sender->sendMessage(TextFormat::GOLD . "Heap memory: " . TextFormat::RED . number_format(round(($rUsage[0] / 1024) / 1024, 2)) . " MB.");
|
||||
$sender->sendMessage(TextFormat::GOLD . "Maximum memory (system): " . TextFormat::RED . number_format(round(($mUsage[2] / 1024) / 1024, 2)) . " MB.");
|
||||
$sender->sendMessage(TextFormat::GOLD . "Main thread memory: " . TextFormat::RED . number_format(round(($mUsage[0] / 1024) / 1024, 2), 2) . " MB.");
|
||||
$sender->sendMessage(TextFormat::GOLD . "Total memory: " . TextFormat::RED . number_format(round(($mUsage[1] / 1024) / 1024, 2), 2) . " MB.");
|
||||
$sender->sendMessage(TextFormat::GOLD . "Total virtual memory: " . TextFormat::RED . number_format(round(($mUsage[2] / 1024) / 1024, 2), 2) . " MB.");
|
||||
$sender->sendMessage(TextFormat::GOLD . "Heap memory: " . TextFormat::RED . number_format(round(($rUsage[0] / 1024) / 1024, 2), 2) . " MB.");
|
||||
$sender->sendMessage(TextFormat::GOLD . "Maximum memory (system): " . TextFormat::RED . number_format(round(($mUsage[2] / 1024) / 1024, 2), 2) . " MB.");
|
||||
|
||||
if($server->getProperty("memory.global-limit") > 0){
|
||||
$sender->sendMessage(TextFormat::GOLD . "Maximum memory (manager): " . TextFormat::RED . number_format(round($server->getProperty("memory.global-limit"), 2)) . " MB.");
|
||||
$sender->sendMessage(TextFormat::GOLD . "Maximum memory (manager): " . TextFormat::RED . number_format(round($server->getProperty("memory.global-limit"), 2), 2) . " MB.");
|
||||
}
|
||||
|
||||
foreach($server->getLevels() as $level){
|
||||
|
@ -30,6 +30,10 @@ use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use function array_filter;
|
||||
use function array_values;
|
||||
use function count;
|
||||
use function round;
|
||||
|
||||
class TeleportCommand extends VanillaCommand{
|
||||
|
||||
|
@ -28,6 +28,9 @@ use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use function array_shift;
|
||||
use function count;
|
||||
use function implode;
|
||||
|
||||
class TellCommand extends VanillaCommand{
|
||||
|
||||
|
@ -30,6 +30,7 @@ use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use function count;
|
||||
|
||||
class TimeCommand extends VanillaCommand{
|
||||
|
||||
@ -54,9 +55,7 @@ class TimeCommand extends VanillaCommand{
|
||||
return true;
|
||||
}
|
||||
foreach($sender->getServer()->getLevels() as $level){
|
||||
$level->checkTime();
|
||||
$level->startTime();
|
||||
$level->checkTime();
|
||||
}
|
||||
Command::broadcastCommandMessage($sender, "Restarted the time");
|
||||
return true;
|
||||
@ -67,9 +66,7 @@ class TimeCommand extends VanillaCommand{
|
||||
return true;
|
||||
}
|
||||
foreach($sender->getServer()->getLevels() as $level){
|
||||
$level->checkTime();
|
||||
$level->stopTime();
|
||||
$level->checkTime();
|
||||
}
|
||||
Command::broadcastCommandMessage($sender, "Stopped the time");
|
||||
return true;
|
||||
@ -109,9 +106,7 @@ class TimeCommand extends VanillaCommand{
|
||||
}
|
||||
|
||||
foreach($sender->getServer()->getLevels() as $level){
|
||||
$level->checkTime();
|
||||
$level->setTime($value);
|
||||
$level->checkTime();
|
||||
}
|
||||
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.time.set", [$value]));
|
||||
}elseif($args[0] === "add"){
|
||||
@ -123,9 +118,7 @@ class TimeCommand extends VanillaCommand{
|
||||
|
||||
$value = $this->getInteger($sender, $args[1], 0);
|
||||
foreach($sender->getServer()->getLevels() as $level){
|
||||
$level->checkTime();
|
||||
$level->setTime($level->getTime() + $value);
|
||||
$level->checkTime();
|
||||
}
|
||||
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.time.added", [$value]));
|
||||
}else{
|
||||
|
@ -31,6 +31,22 @@ use pocketmine\scheduler\BulkCurlTask;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\timings\TimingsHandler;
|
||||
use pocketmine\utils\InternetException;
|
||||
use function count;
|
||||
use function fclose;
|
||||
use function file_exists;
|
||||
use function fopen;
|
||||
use function fseek;
|
||||
use function http_build_query;
|
||||
use function is_array;
|
||||
use function json_decode;
|
||||
use function mkdir;
|
||||
use function stream_get_contents;
|
||||
use function strtolower;
|
||||
use const CURLOPT_AUTOREFERER;
|
||||
use const CURLOPT_FOLLOWLOCATION;
|
||||
use const CURLOPT_HTTPHEADER;
|
||||
use const CURLOPT_POST;
|
||||
use const CURLOPT_POSTFIELDS;
|
||||
|
||||
class TimingsCommand extends VanillaCommand{
|
||||
|
||||
|
@ -26,6 +26,9 @@ namespace pocketmine\command\defaults;
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use function array_slice;
|
||||
use function count;
|
||||
use function implode;
|
||||
|
||||
class TitleCommand extends VanillaCommand{
|
||||
|
||||
@ -82,7 +85,7 @@ class TitleCommand extends VanillaCommand{
|
||||
$player->addActionBarMessage(implode(" ", array_slice($args, 2)));
|
||||
break;
|
||||
case "times":
|
||||
if(count($args) < 4){
|
||||
if(count($args) < 5){
|
||||
throw new InvalidCommandSyntaxException();
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ namespace pocketmine\command\defaults;
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\Player;
|
||||
use function count;
|
||||
|
||||
class TransferServerCommand extends VanillaCommand{
|
||||
|
||||
|
@ -28,6 +28,8 @@ use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use function is_numeric;
|
||||
use function substr;
|
||||
|
||||
abstract class VanillaCommand extends Command{
|
||||
public const MAX_COORD = 30000000;
|
||||
|
@ -28,6 +28,10 @@ use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\network\mcpe\protocol\ProtocolInfo;
|
||||
use pocketmine\plugin\Plugin;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use function count;
|
||||
use function implode;
|
||||
use function stripos;
|
||||
use function strtolower;
|
||||
|
||||
class VersionCommand extends VanillaCommand{
|
||||
|
||||
|
@ -28,6 +28,9 @@ use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use function count;
|
||||
use function implode;
|
||||
use function strtolower;
|
||||
|
||||
class WhitelistCommand extends VanillaCommand{
|
||||
|
||||
|
@ -23,6 +23,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\entity;
|
||||
|
||||
use function max;
|
||||
use function min;
|
||||
|
||||
class Attribute{
|
||||
|
||||
public const ABSORPTION = 0;
|
||||
@ -127,8 +130,8 @@ class Attribute{
|
||||
}
|
||||
|
||||
public function setMinValue(float $minValue){
|
||||
if($minValue > $this->getMaxValue()){
|
||||
throw new \InvalidArgumentException("Value $minValue is bigger than the maxValue!");
|
||||
if($minValue > ($max = $this->getMaxValue())){
|
||||
throw new \InvalidArgumentException("Minimum $minValue is greater than the maximum $max");
|
||||
}
|
||||
|
||||
if($this->minValue != $minValue){
|
||||
@ -143,8 +146,8 @@ class Attribute{
|
||||
}
|
||||
|
||||
public function setMaxValue(float $maxValue){
|
||||
if($maxValue < $this->getMinValue()){
|
||||
throw new \InvalidArgumentException("Value $maxValue is bigger than the minValue!");
|
||||
if($maxValue < ($min = $this->getMinValue())){
|
||||
throw new \InvalidArgumentException("Maximum $maxValue is less than the minimum $min");
|
||||
}
|
||||
|
||||
if($this->maxValue != $maxValue){
|
||||
@ -160,7 +163,7 @@ class Attribute{
|
||||
|
||||
public function setDefaultValue(float $defaultValue){
|
||||
if($defaultValue > $this->getMaxValue() or $defaultValue < $this->getMinValue()){
|
||||
throw new \InvalidArgumentException("Value $defaultValue exceeds the range!");
|
||||
throw new \InvalidArgumentException("Default $defaultValue is outside the range " . $this->getMinValue() . " - " . $this->getMaxValue());
|
||||
}
|
||||
|
||||
if($this->defaultValue !== $defaultValue){
|
||||
@ -188,7 +191,7 @@ class Attribute{
|
||||
public function setValue(float $value, bool $fit = false, bool $forceSend = false){
|
||||
if($value > $this->getMaxValue() or $value < $this->getMinValue()){
|
||||
if(!$fit){
|
||||
throw new \InvalidArgumentException("Value $value exceeds the range!");
|
||||
throw new \InvalidArgumentException("Value $value is outside the range " . $this->getMinValue() . " - " . $this->getMaxValue());
|
||||
}
|
||||
$value = min(max($value, $this->getMinValue()), $this->getMaxValue());
|
||||
}
|
||||
|
@ -23,6 +23,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\entity;
|
||||
|
||||
use function array_filter;
|
||||
|
||||
class AttributeMap implements \ArrayAccess{
|
||||
/** @var Attribute[] */
|
||||
private $attributes = [];
|
||||
|
@ -25,6 +25,10 @@ namespace pocketmine\entity;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Vector3;
|
||||
use function assert;
|
||||
use function is_float;
|
||||
use function is_int;
|
||||
use function is_string;
|
||||
|
||||
class DataPropertyManager{
|
||||
|
||||
|
@ -29,6 +29,9 @@ use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\event\entity\EntityRegainHealthEvent;
|
||||
use pocketmine\event\player\PlayerExhaustEvent;
|
||||
use pocketmine\utils\Color;
|
||||
use function constant;
|
||||
use function defined;
|
||||
use function strtoupper;
|
||||
|
||||
class Effect{
|
||||
public const SPEED = 1;
|
||||
|
@ -24,6 +24,8 @@ declare(strict_types=1);
|
||||
namespace pocketmine\entity;
|
||||
|
||||
use pocketmine\utils\Color;
|
||||
use function max;
|
||||
use const INT32_MAX;
|
||||
|
||||
class EffectInstance{
|
||||
/** @var Effect */
|
||||
|
@ -73,6 +73,23 @@ use pocketmine\plugin\Plugin;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\timings\Timings;
|
||||
use pocketmine\timings\TimingsHandler;
|
||||
use function abs;
|
||||
use function assert;
|
||||
use function cos;
|
||||
use function count;
|
||||
use function current;
|
||||
use function deg2rad;
|
||||
use function floor;
|
||||
use function get_class;
|
||||
use function in_array;
|
||||
use function is_a;
|
||||
use function is_array;
|
||||
use function is_infinite;
|
||||
use function is_nan;
|
||||
use function lcg_value;
|
||||
use function reset;
|
||||
use function sin;
|
||||
use const M_PI_2;
|
||||
|
||||
abstract class Entity extends Location implements Metadatable, EntityIds{
|
||||
|
||||
@ -460,7 +477,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
||||
/** @var int */
|
||||
public $lastUpdate;
|
||||
/** @var int */
|
||||
public $fireTicks = 0;
|
||||
protected $fireTicks = 0;
|
||||
/** @var CompoundTag */
|
||||
public $namedtag;
|
||||
/** @var bool */
|
||||
@ -1076,8 +1093,8 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
||||
|
||||
public function setOnFire(int $seconds) : void{
|
||||
$ticks = $seconds * 20;
|
||||
if($ticks > $this->fireTicks){
|
||||
$this->fireTicks = $ticks;
|
||||
if($ticks > $this->getFireTicks()){
|
||||
$this->setFireTicks($ticks);
|
||||
}
|
||||
|
||||
$this->setGenericFlag(self::DATA_FLAG_ONFIRE, true);
|
||||
@ -1092,8 +1109,12 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
||||
|
||||
/**
|
||||
* @param int $fireTicks
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function setFireTicks(int $fireTicks) : void{
|
||||
if($fireTicks < 0 or $fireTicks > 0x7fff){
|
||||
throw new \InvalidArgumentException("Fire ticks must be in range 0 ... " . 0x7fff . ", got $fireTicks");
|
||||
}
|
||||
$this->fireTicks = $fireTicks;
|
||||
}
|
||||
|
||||
@ -1962,6 +1983,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
||||
$pk->position = $this->asVector3();
|
||||
$pk->motion = $this->getMotion();
|
||||
$pk->yaw = $this->yaw;
|
||||
$pk->headYaw = $this->yaw; //TODO
|
||||
$pk->pitch = $this->pitch;
|
||||
$pk->attributes = $this->attributeMap->getAll();
|
||||
$pk->metadata = $this->propertyManager->getAll();
|
||||
@ -2169,4 +2191,47 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
||||
public function __toString(){
|
||||
return (new \ReflectionClass($this))->getShortName() . "(" . $this->getId() . ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: remove this BC hack in 4.0
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return mixed
|
||||
* @throws \ErrorException
|
||||
*/
|
||||
public function __get($name){
|
||||
if($name === "fireTicks"){
|
||||
return $this->fireTicks;
|
||||
}
|
||||
throw new \ErrorException("Undefined property: " . get_class($this) . "::\$" . $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: remove this BC hack in 4.0
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*
|
||||
* @throws \ErrorException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __set($name, $value){
|
||||
if($name === "fireTicks"){
|
||||
$this->setFireTicks($value);
|
||||
}else{
|
||||
throw new \ErrorException("Undefined property: " . get_class($this) . "::\$" . $name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: remove this BC hack in 4.0
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function __isset($name){
|
||||
return $name === "fireTicks";
|
||||
}
|
||||
}
|
||||
|
@ -55,6 +55,18 @@ use pocketmine\network\mcpe\protocol\PlayerSkinPacket;
|
||||
use pocketmine\network\mcpe\protocol\types\PlayerListEntry;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\utils\UUID;
|
||||
use function array_filter;
|
||||
use function array_merge;
|
||||
use function array_rand;
|
||||
use function array_values;
|
||||
use function ceil;
|
||||
use function max;
|
||||
use function min;
|
||||
use function mt_rand;
|
||||
use function random_int;
|
||||
use function strlen;
|
||||
use const INT32_MAX;
|
||||
use const INT32_MIN;
|
||||
|
||||
class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||
|
||||
|
@ -51,6 +51,19 @@ use pocketmine\Player;
|
||||
use pocketmine\timings\Timings;
|
||||
use pocketmine\utils\Binary;
|
||||
use pocketmine\utils\Color;
|
||||
use function abs;
|
||||
use function array_shift;
|
||||
use function atan2;
|
||||
use function ceil;
|
||||
use function count;
|
||||
use function floor;
|
||||
use function lcg_value;
|
||||
use function max;
|
||||
use function min;
|
||||
use function mt_getrandmax;
|
||||
use function mt_rand;
|
||||
use function sqrt;
|
||||
use const M_PI;
|
||||
|
||||
abstract class Living extends Entity implements Damageable{
|
||||
|
||||
@ -652,7 +665,7 @@ abstract class Living extends Entity implements Damageable{
|
||||
}
|
||||
|
||||
protected function endDeathAnimation() : void{
|
||||
//TODO
|
||||
$this->despawnFromAll();
|
||||
}
|
||||
|
||||
public function entityBaseTick(int $tickDiff = 1) : bool{
|
||||
|
@ -23,6 +23,10 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\entity;
|
||||
|
||||
use function json_decode;
|
||||
use function json_encode;
|
||||
use function strlen;
|
||||
|
||||
class Skin{
|
||||
|
||||
/** @var string */
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user