mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-15 13:55:12 +00:00
Compare commits
45 Commits
Author | SHA1 | Date | |
---|---|---|---|
e8b6b56330 | |||
c368ebb5e7 | |||
fa920aa868 | |||
a421d32273 | |||
6c21c23444 | |||
55e0d9c520 | |||
37ee3f2775 | |||
bfdcc12e81 | |||
b2299e08e0 | |||
d7741050c5 | |||
6cff08cd65 | |||
fec42f16ba | |||
deb0cee8a0 | |||
c0dafe7872 | |||
340881d590 | |||
e2e960e43d | |||
500fd2d842 | |||
0b550b346b | |||
1424114cf2 | |||
a8980a0f67 | |||
69aa7c5ac1 | |||
11b74868ee | |||
9a53de0903 | |||
0f8101d4a6 | |||
55ecac4c80 | |||
2a1d1e90a2 | |||
4444a79468 | |||
4cbeee3ab8 | |||
a251960c1c | |||
52f734799e | |||
42171f6e06 | |||
1fe4fdc67c | |||
af4f30d1c8 | |||
3e2926441d | |||
0b33762be0 | |||
e6f89213dc | |||
f8d249b240 | |||
b39afa20d1 | |||
7027a9b972 | |||
b02f3f4090 | |||
8564912149 | |||
873535f719 | |||
78f4fcf6ab | |||
90b749c260 | |||
d5398b2781 |
@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\build\make_release;
|
||||
|
||||
use pocketmine\utils\VersionString;
|
||||
use function defined;
|
||||
use function dirname;
|
||||
use function fgets;
|
||||
use function file_get_contents;
|
||||
@ -37,7 +38,6 @@ use const STDIN;
|
||||
|
||||
require_once dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
|
||||
function replaceVersion(string $versionInfoPath, string $newVersion, bool $isDev) : void{
|
||||
$versionInfo = file_get_contents($versionInfoPath);
|
||||
$versionInfo = preg_replace(
|
||||
|
@ -32,3 +32,23 @@ Plugin developers should **only** update their required API to this version if y
|
||||
- Fixed issues with preloading `SubChunk`.
|
||||
- `/gc` and automatic garbage collection will now release unused heap blocks back to the OS. Previously, the PHP process might hold onto these blocks indefinitely even when not used, causing elevated real memory usage.
|
||||
- Added some documentation to `FurnaceBurnEvent`.
|
||||
|
||||
# 3.15.3
|
||||
- Fixed fall damage accumulation over continuous knockbacks (e.g. combo attacks in PvP).
|
||||
- Fixed a bug in `Human->addXp()` that would cause a crash when saving player data.
|
||||
- `Human->addXp()` will no longer modify the target's total XP if `PlayerExperienceChangeEvent` was cancelled.
|
||||
- `AsyncPool->getTaskQueueSizes()` has been added to allow external detection of async pool overload. This is planned to be implemented as a core feature in the future, but it hasn't been done yet.
|
||||
- `BaseInventory->canAddItem()` behaviour now matches `addItem()` by considering the max stack size of the given item.
|
||||
- Fixed a bug in generator options handling for worlds loaded via `pocketmine.yml`. This fix has the following side effects:
|
||||
- It's now possible to provide generator options as an `options` key when loading a world via `pocketmine.yml`.
|
||||
- If generator options are not provided, the options from `server.properties` will be used, instead of using an empty preset. (It's not clear whether this is desired behaviour, but it was clearly intended, since there is code to do this which was broken until this release. As such, this behaviour is subject to change in the future.)
|
||||
- Fixed a bug in region-based world loading where some files without filename extensions and names containing a region filename extension (e.g a file named `amca` in a McRegion world) would cause the world not to load. These files are now ignored.
|
||||
- Default network compression level has been lowered to 6, due to level 7 being 25% more expensive for only a marginal improvement in bandwidth.
|
||||
- Fixed a performance issue with chunk requesting when players trigger chunk generation on first join.
|
||||
- Setup wizard will now always show IP information, even if the user chose to skip the setup wizard when prompted. (This doesn't affect `--no-wizard` in any way.)
|
||||
- `Maximum memory (system)` is no longer reported in `/status` due to having a misleading output (it was the same as the current memory usage).
|
||||
- The `Player Chunk Send` timer on timings reports now actually reports measurements of chunk sending, not chunk loading.
|
||||
- A new parent timer `World Load` has been added to timings reports, which aggregates timings from `syncChunkLoad` and subtimings from all worlds.
|
||||
|
||||
# 3.15.4
|
||||
- Fixed a bug in the inventory transaction system that caused the server to freeze under some circumstances.
|
||||
|
@ -35,10 +35,10 @@
|
||||
"pocketmine/log-pthreads": "^0.1.0",
|
||||
"pocketmine/callback-validator": "^1.0.2",
|
||||
"adhocore/json-comment": "^0.1.0",
|
||||
"ocramius/package-versions": "^1.5"
|
||||
"composer-runtime-api": "^2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "0.12.48",
|
||||
"phpstan/phpstan": "0.12.54",
|
||||
"phpstan/phpstan-phpunit": "^0.12.6",
|
||||
"phpstan/phpstan-strict-rules": "^0.12.2",
|
||||
"phpunit/phpunit": "^9.2"
|
||||
|
443
composer.lock
generated
443
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,6 @@ includes:
|
||||
- tests/phpstan/configs/actual-problems.neon
|
||||
- tests/phpstan/configs/check-explicit-mixed-baseline.neon
|
||||
- tests/phpstan/configs/com-dotnet-magic.neon
|
||||
- tests/phpstan/configs/custom-leveldb.neon
|
||||
- tests/phpstan/configs/gc-hacks.neon
|
||||
- tests/phpstan/configs/l7-baseline.neon
|
||||
- tests/phpstan/configs/l8-baseline.neon
|
||||
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
use PackageVersions\Versions;
|
||||
use Composer\InstalledVersions;
|
||||
use pocketmine\network\mcpe\protocol\ProtocolInfo;
|
||||
use pocketmine\plugin\PluginBase;
|
||||
use pocketmine\plugin\PluginLoadOrder;
|
||||
@ -54,6 +54,7 @@ use function php_uname;
|
||||
use function phpinfo;
|
||||
use function phpversion;
|
||||
use function preg_replace;
|
||||
use function sprintf;
|
||||
use function str_split;
|
||||
use function strpos;
|
||||
use function substr;
|
||||
@ -338,6 +339,15 @@ class CrashDump{
|
||||
|
||||
private function generalData() : void{
|
||||
$version = new VersionString(\pocketmine\BASE_VERSION, \pocketmine\IS_DEVELOPMENT_BUILD, \pocketmine\BUILD_NUMBER);
|
||||
$composerLibraries = [];
|
||||
foreach(InstalledVersions::getInstalledPackages() as $package){
|
||||
$composerLibraries[$package] = sprintf(
|
||||
"%s@%s",
|
||||
InstalledVersions::getPrettyVersion($package) ?? "unknown",
|
||||
InstalledVersions::getReference($package) ?? "unknown"
|
||||
);
|
||||
}
|
||||
|
||||
$this->data["general"] = [];
|
||||
$this->data["general"]["name"] = $this->server->getName();
|
||||
$this->data["general"]["base_version"] = \pocketmine\BASE_VERSION;
|
||||
@ -350,7 +360,7 @@ class CrashDump{
|
||||
$this->data["general"]["zend"] = zend_version();
|
||||
$this->data["general"]["php_os"] = PHP_OS;
|
||||
$this->data["general"]["os"] = Utils::getOS();
|
||||
$this->data["general"]["composer_libraries"] = Versions::VERSIONS;
|
||||
$this->data["general"]["composer_libraries"] = $composerLibraries;
|
||||
$this->addLine($this->server->getName() . " version: " . $version->getFullVersion(true) . " [Protocol " . ProtocolInfo::CURRENT_PROTOCOL . "]");
|
||||
$this->addLine("Git commit: " . \pocketmine\GIT_COMMIT);
|
||||
$this->addLine("uname -a: " . php_uname("a"));
|
||||
@ -358,7 +368,7 @@ class CrashDump{
|
||||
$this->addLine("Zend version: " . zend_version());
|
||||
$this->addLine("OS : " . PHP_OS . ", " . Utils::getOS());
|
||||
$this->addLine("Composer libraries: ");
|
||||
foreach(Versions::VERSIONS as $library => $libraryVersion){
|
||||
foreach($composerLibraries as $library => $libraryVersion){
|
||||
$this->addLine("- $library $libraryVersion");
|
||||
}
|
||||
}
|
||||
|
@ -4122,7 +4122,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
}
|
||||
|
||||
public function onChunkChanged(Chunk $chunk){
|
||||
if(isset($this->usedChunks[$hash = Level::chunkHash($chunk->getX(), $chunk->getZ())])){
|
||||
$hasSent = $this->usedChunks[$hash = Level::chunkHash($chunk->getX(), $chunk->getZ())] ?? false;
|
||||
if($hasSent){
|
||||
$this->usedChunks[$hash] = false;
|
||||
$this->nextChunkOrderRun = 0;
|
||||
}
|
||||
|
@ -1400,10 +1400,10 @@ class Server{
|
||||
Network::$BATCH_THRESHOLD = -1;
|
||||
}
|
||||
|
||||
$this->networkCompressionLevel = (int) $this->getProperty("network.compression-level", 7);
|
||||
$this->networkCompressionLevel = (int) $this->getProperty("network.compression-level", 6);
|
||||
if($this->networkCompressionLevel < 1 or $this->networkCompressionLevel > 9){
|
||||
$this->logger->warning("Invalid network compression level $this->networkCompressionLevel set, setting to default 7");
|
||||
$this->networkCompressionLevel = 7;
|
||||
$this->logger->warning("Invalid network compression level $this->networkCompressionLevel set, setting to default 6");
|
||||
$this->networkCompressionLevel = 6;
|
||||
}
|
||||
$this->networkCompressionAsync = (bool) $this->getProperty("network.async-compression", true);
|
||||
|
||||
@ -1543,7 +1543,7 @@ class Server{
|
||||
if(isset($options["generator"])){
|
||||
$generatorOptions = explode(":", $options["generator"]);
|
||||
$generator = GeneratorManager::getGenerator(array_shift($generatorOptions));
|
||||
if(count($options) > 0){
|
||||
if(count($generatorOptions) > 0){
|
||||
$options["preset"] = implode(":", $generatorOptions);
|
||||
}
|
||||
}else{
|
||||
|
@ -33,6 +33,6 @@ if(defined('pocketmine\_VERSION_INFO_INCLUDED')){
|
||||
const _VERSION_INFO_INCLUDED = true;
|
||||
|
||||
const NAME = "PocketMine-MP";
|
||||
const BASE_VERSION = "3.15.2";
|
||||
const BASE_VERSION = "3.15.4";
|
||||
const IS_DEVELOPMENT_BUILD = false;
|
||||
const BUILD_NUMBER = 0;
|
||||
|
@ -100,7 +100,6 @@ class StatusCommand extends VanillaCommand{
|
||||
$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), 2) . " MB.");
|
||||
|
@ -1451,8 +1451,14 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
||||
$this->fall($this->fallDistance);
|
||||
$this->resetFallDistance();
|
||||
}
|
||||
}elseif($distanceThisTick < 0){
|
||||
}elseif($distanceThisTick < $this->fallDistance){
|
||||
//we've fallen some distance (distanceThisTick is negative)
|
||||
//or we ascended back towards where fall distance was measured from initially (distanceThisTick is positive but less than existing fallDistance)
|
||||
$this->fallDistance -= $distanceThisTick;
|
||||
}else{
|
||||
//we ascended past the apex where fall distance was originally being measured from
|
||||
//reset it so it will be measured starting from the new, higher position
|
||||
$this->fallDistance = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -400,12 +400,14 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||
* @param bool $playSound Whether to play level-up and XP gained sounds.
|
||||
*/
|
||||
public function addXp(int $amount, bool $playSound = true) : bool{
|
||||
$this->totalXp += $amount;
|
||||
|
||||
$oldLevel = $this->getXpLevel();
|
||||
$oldTotal = $this->getCurrentTotalXp();
|
||||
|
||||
if($this->setCurrentTotalXp($oldTotal + $amount)){
|
||||
if($amount > 0){
|
||||
$this->totalXp += $amount;
|
||||
}
|
||||
|
||||
if($playSound){
|
||||
$newLevel = $this->getXpLevel();
|
||||
if((int) ($newLevel / 5) > (int) ($oldLevel / 5)){
|
||||
|
@ -25,6 +25,7 @@ namespace pocketmine\entity\utils;
|
||||
|
||||
use pocketmine\math\Math;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
use function count;
|
||||
use function max;
|
||||
|
||||
abstract class ExperienceUtils{
|
||||
|
@ -252,11 +252,11 @@ abstract class BaseInventory implements Inventory{
|
||||
for($i = 0, $size = $this->getSize(); $i < $size; ++$i){
|
||||
$slot = $this->getItem($i);
|
||||
if($item->equals($slot)){
|
||||
if(($diff = $slot->getMaxStackSize() - $slot->getCount()) > 0){
|
||||
if(($diff = min($slot->getMaxStackSize(), $item->getMaxStackSize()) - $slot->getCount()) > 0){
|
||||
$count -= $diff;
|
||||
}
|
||||
}elseif($slot->isNull()){
|
||||
$count -= $this->getMaxStackSize();
|
||||
$count -= min($this->getMaxStackSize(), $item->getMaxStackSize());
|
||||
}
|
||||
|
||||
if($count <= 0){
|
||||
|
@ -108,9 +108,6 @@ class CraftingTransaction extends InventoryTransaction{
|
||||
}
|
||||
}
|
||||
|
||||
if($iterations < 1){
|
||||
throw new TransactionValidationException("Tried to craft zero times");
|
||||
}
|
||||
if(count($txItems) > 0){
|
||||
//all items should be destroyed in this process
|
||||
throw new TransactionValidationException("Expected 0 ingredients left over, have " . count($txItems));
|
||||
|
@ -230,21 +230,34 @@ class InventoryTransaction{
|
||||
protected function findResultItem(Item $needOrigin, array $possibleActions) : ?Item{
|
||||
assert(count($possibleActions) > 0);
|
||||
|
||||
$candidate = null;
|
||||
$newList = $possibleActions;
|
||||
foreach($possibleActions as $i => $action){
|
||||
if($action->getSourceItem()->equalsExact($needOrigin)){
|
||||
$newList = $possibleActions;
|
||||
if($candidate !== null){
|
||||
/*
|
||||
* we found multiple possible actions that match the origin action
|
||||
* this means that there are multiple ways that this chain could play out
|
||||
* if we cared so much about this, we could build all the possible chains in parallel and see which
|
||||
* variation managed to complete the chain, but this has an extremely high complexity which is not
|
||||
* worth the trouble for this scenario (we don't usually expect to see chains longer than a couple
|
||||
* of actions in here anyway), and might still result in multiple possible results.
|
||||
*/
|
||||
return null;
|
||||
}
|
||||
$candidate = $action;
|
||||
unset($newList[$i]);
|
||||
if(count($newList) === 0){
|
||||
return $action->getTargetItem();
|
||||
}
|
||||
$result = $this->findResultItem($action->getTargetItem(), $newList);
|
||||
if($result !== null){
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
if($candidate === null){
|
||||
//chaining is not possible with this origin, none of the actions are valid
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
if(count($newList) === 0){
|
||||
return $candidate->getTargetItem();
|
||||
}
|
||||
return $this->findResultItem($candidate->getTargetItem(), $newList);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -154,7 +154,6 @@ class Explosion{
|
||||
* and creating sounds and particles.
|
||||
*/
|
||||
public function explodeB() : bool{
|
||||
$send = [];
|
||||
$updateBlocks = [];
|
||||
|
||||
$source = (new Vector3($this->source->x, $this->source->y, $this->source->z))->floor();
|
||||
@ -254,7 +253,6 @@ class Explosion{
|
||||
$updateBlocks[$index] = true;
|
||||
}
|
||||
}
|
||||
$send[] = new Vector3($block->x - $source->x, $block->y - $source->y, $block->z - $source->z);
|
||||
}
|
||||
|
||||
$this->level->addParticle(new HugeExplodeSeedParticle($source));
|
||||
|
@ -53,7 +53,6 @@ use pocketmine\level\format\io\ChunkRequestTask;
|
||||
use pocketmine\level\format\io\exception\CorruptedChunkException;
|
||||
use pocketmine\level\format\io\exception\UnsupportedChunkFormatException;
|
||||
use pocketmine\level\format\io\LevelProvider;
|
||||
use pocketmine\level\generator\Generator;
|
||||
use pocketmine\level\generator\GeneratorManager;
|
||||
use pocketmine\level\generator\GeneratorRegisterTask;
|
||||
use pocketmine\level\generator\GeneratorUnregisterTask;
|
||||
@ -289,7 +288,10 @@ class Level implements ChunkManager, Metadatable{
|
||||
/** @var bool */
|
||||
private $doingTick = false;
|
||||
|
||||
/** @var string|Generator */
|
||||
/**
|
||||
* @var string
|
||||
* @phpstan-var class-string<\pocketmine\level\generator\Generator>
|
||||
*/
|
||||
private $generator;
|
||||
|
||||
/** @var bool */
|
||||
|
@ -80,15 +80,14 @@ class LevelTimings{
|
||||
$this->entityTick = new TimingsHandler("** " . $name . "entityTick");
|
||||
$this->tileEntityTick = new TimingsHandler("** " . $name . "tileEntityTick");
|
||||
|
||||
$this->syncChunkSendTimer = new TimingsHandler("** " . $name . "syncChunkSend");
|
||||
$this->syncChunkSendPrepareTimer = new TimingsHandler("** " . $name . "syncChunkSendPrepare");
|
||||
Timings::init(); //make sure the timers we want are available
|
||||
$this->syncChunkSendTimer = new TimingsHandler("** " . $name . "syncChunkSend", Timings::$playerChunkSendTimer);
|
||||
$this->syncChunkSendPrepareTimer = new TimingsHandler("** " . $name . "syncChunkSendPrepare", Timings::$playerChunkSendTimer);
|
||||
|
||||
$this->syncChunkLoadTimer = new TimingsHandler("** " . $name . "syncChunkLoad");
|
||||
$this->syncChunkLoadTimer = new TimingsHandler("** " . $name . "syncChunkLoad", Timings::$worldLoadTimer);
|
||||
$this->syncChunkLoadDataTimer = new TimingsHandler("** " . $name . "syncChunkLoad - Data");
|
||||
$this->syncChunkLoadEntitiesTimer = new TimingsHandler("** " . $name . "syncChunkLoad - Entities");
|
||||
$this->syncChunkLoadTileEntitiesTimer = new TimingsHandler("** " . $name . "syncChunkLoad - TileEntities");
|
||||
|
||||
Timings::init(); //make sure the timer we want is available
|
||||
$this->syncChunkSaveTimer = new TimingsHandler("** " . $name . "syncChunkSave", Timings::$worldSaveTimer);
|
||||
|
||||
$this->doTick = new TimingsHandler($name . "doTick");
|
||||
|
@ -929,6 +929,7 @@ class Chunk{
|
||||
$chunk->setGenerated($terrainGenerated);
|
||||
$chunk->setPopulated($terrainPopulated);
|
||||
$chunk->setLightPopulated($lightPopulated);
|
||||
$chunk->setChanged(false);
|
||||
|
||||
return $chunk;
|
||||
}
|
||||
|
@ -245,11 +245,13 @@ class McRegion extends BaseLevelProvider{
|
||||
|
||||
if($isValid){
|
||||
$files = array_filter(scandir($path . "/region/", SCANDIR_SORT_NONE), function(string $file) : bool{
|
||||
return substr($file, strrpos($file, ".") + 1, 2) === "mc"; //region file
|
||||
$extPos = strrpos($file, ".");
|
||||
return $extPos !== false && substr($file, $extPos + 1, 2) === "mc"; //region file
|
||||
});
|
||||
|
||||
foreach($files as $f){
|
||||
if(substr($f, strrpos($f, ".") + 1) !== static::REGION_FILE_EXTENSION){
|
||||
$extPos = strrpos($f, ".");
|
||||
if($extPos !== false && substr($f, $extPos + 1) !== static::REGION_FILE_EXTENSION){
|
||||
$isValid = false;
|
||||
break;
|
||||
}
|
||||
|
@ -35,7 +35,10 @@ use function unserialize;
|
||||
|
||||
class GeneratorRegisterTask extends AsyncTask{
|
||||
|
||||
/** @var string */
|
||||
/**
|
||||
* @var string
|
||||
* @phpstan-var class-string<Generator>
|
||||
*/
|
||||
public $generatorClass;
|
||||
/** @var string */
|
||||
public $settings;
|
||||
@ -48,6 +51,7 @@ class GeneratorRegisterTask extends AsyncTask{
|
||||
|
||||
/**
|
||||
* @param mixed[] $generatorSettings
|
||||
* @phpstan-param class-string<Generator> $generatorClass
|
||||
* @phpstan-param array<string, mixed> $generatorSettings
|
||||
*/
|
||||
public function __construct(Level $level, string $generatorClass, array $generatorSettings = []){
|
||||
|
@ -58,7 +58,7 @@ class PluginDescription{
|
||||
private $compatibleOperatingSystems = [];
|
||||
/**
|
||||
* @var string[][]
|
||||
* @phpstan-var array<string, list<mixed>>
|
||||
* @phpstan-var array<string, list<string>>
|
||||
*/
|
||||
private $extensions = [];
|
||||
/** @var string[] */
|
||||
@ -104,13 +104,13 @@ class PluginDescription{
|
||||
|
||||
$this->name = $plugin["name"];
|
||||
if(preg_match('/^[A-Za-z0-9 _.-]+$/', $this->name) === 0){
|
||||
throw new PluginException("Invalid PluginDescription name");
|
||||
throw new PluginException("Invalid Plugin name");
|
||||
}
|
||||
$this->name = str_replace(" ", "_", $this->name);
|
||||
$this->version = (string) $plugin["version"];
|
||||
$this->main = $plugin["main"];
|
||||
if(stripos($this->main, "pocketmine\\") === 0){
|
||||
throw new PluginException("Invalid PluginDescription main, cannot start within the PocketMine namespace");
|
||||
throw new PluginException("Invalid Plugin main, cannot start within the PocketMine namespace");
|
||||
}
|
||||
|
||||
$this->api = array_map("\strval", (array) ($plugin["api"] ?? []));
|
||||
@ -132,7 +132,7 @@ class PluginDescription{
|
||||
$k = $v;
|
||||
$v = "*";
|
||||
}
|
||||
$this->extensions[$k] = is_array($v) ? $v : [$v];
|
||||
$this->extensions[$k] = array_map('strval', is_array($v) ? $v : [$v]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,7 +149,7 @@ class PluginDescription{
|
||||
if(isset($plugin["load"])){
|
||||
$order = mb_strtoupper($plugin["load"]);
|
||||
if(!defined(PluginLoadOrder::class . "::" . $order)){
|
||||
throw new PluginException("Invalid PluginDescription load");
|
||||
throw new PluginException("Invalid Plugin load");
|
||||
}else{
|
||||
$this->order = constant(PluginLoadOrder::class . "::" . $order);
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ network:
|
||||
#Set to 0 to compress everything, -1 to disable.
|
||||
batch-threshold: 256
|
||||
#Compression level used when sending batched packets. Higher = more CPU, less bandwidth usage
|
||||
compression-level: 7
|
||||
compression-level: 6
|
||||
#Use AsyncTasks for compression. Adds half/one tick delay, less CPU load on main thread
|
||||
async-compression: false
|
||||
#Experimental, only for Windows. Tries to use UPnP to automatically port forward
|
||||
|
@ -329,6 +329,16 @@ class AsyncPool{
|
||||
$this->collectWorkers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of worker ID => task queue size
|
||||
*
|
||||
* @return int[]
|
||||
* @phpstan-return array<int, int>
|
||||
*/
|
||||
public function getTaskQueueSizes() : array{
|
||||
return $this->workerUsage;
|
||||
}
|
||||
|
||||
public function shutdownUnusedWorkers() : int{
|
||||
$ret = 0;
|
||||
$time = time();
|
||||
|
@ -59,6 +59,8 @@ abstract class Timings{
|
||||
/** @var TimingsHandler */
|
||||
public static $serverCommandTimer;
|
||||
/** @var TimingsHandler */
|
||||
public static $worldLoadTimer;
|
||||
/** @var TimingsHandler */
|
||||
public static $worldSaveTimer;
|
||||
/** @var TimingsHandler */
|
||||
public static $populationTimer;
|
||||
@ -126,6 +128,7 @@ abstract class Timings{
|
||||
self::$connectionTimer = new TimingsHandler("Connection Handler");
|
||||
self::$schedulerTimer = new TimingsHandler("Scheduler");
|
||||
self::$serverCommandTimer = new TimingsHandler("Server Command");
|
||||
self::$worldLoadTimer = new TimingsHandler("World Load");
|
||||
self::$worldSaveTimer = new TimingsHandler("World Save");
|
||||
self::$populationTimer = new TimingsHandler("World Population");
|
||||
self::$generationCallbackTimer = new TimingsHandler("World Generation Callback");
|
||||
|
@ -88,7 +88,7 @@ abstract class Timezone{
|
||||
break;
|
||||
}
|
||||
|
||||
if($response = Internet::getURL("http://ip-api.com/json") //If system timezone detection fails or timezone is an invalid value.
|
||||
if(($response = Internet::getURL("http://ip-api.com/json")) !== false //If system timezone detection fails or timezone is an invalid value.
|
||||
and $ip_geolocation_data = json_decode($response, true)
|
||||
and $ip_geolocation_data['status'] !== 'fail'
|
||||
and date_default_timezone_set($ip_geolocation_data['timezone'])
|
||||
|
@ -527,7 +527,7 @@ class Utils{
|
||||
$ret = explode("\n", $contents);
|
||||
ob_end_clean();
|
||||
|
||||
if(count($ret) >= 1 and preg_match('/^.* refcount\\(([0-9]+)\\)\\{$/', trim($ret[0]), $m) > 0){
|
||||
if(preg_match('/^.* refcount\\(([0-9]+)\\)\\{$/', trim($ret[0]), $m) > 0){
|
||||
return ((int) $m[1]) - ($includeCurrent ? 3 : 4); //$value + zval call + extra call
|
||||
}
|
||||
return -1;
|
||||
|
@ -92,6 +92,7 @@ class SetupWizard{
|
||||
$config->save();
|
||||
|
||||
if(strtolower($this->getInput($this->lang->get("skip_installer"), "n", "y/N")) === "y"){
|
||||
$this->printIpDetails();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -101,6 +102,7 @@ class SetupWizard{
|
||||
$this->generateUserFiles();
|
||||
|
||||
$this->networkFunctions();
|
||||
$this->printIpDetails();
|
||||
|
||||
$this->endWizard();
|
||||
|
||||
@ -218,7 +220,9 @@ LICENSE;
|
||||
}
|
||||
|
||||
$config->save();
|
||||
|
||||
}
|
||||
|
||||
private function printIpDetails() : void{
|
||||
$this->message($this->lang->get("ip_get"));
|
||||
|
||||
$externalIP = Internet::getIP();
|
||||
|
@ -23,6 +23,11 @@ declare(strict_types=1);
|
||||
|
||||
define('pocketmine\_PHPSTAN_ANALYSIS', true);
|
||||
|
||||
if(!defined('LEVELDB_ZLIB_RAW_COMPRESSION')){
|
||||
//leveldb might not be loaded
|
||||
define('LEVELDB_ZLIB_RAW_COMPRESSION', 4);
|
||||
}
|
||||
|
||||
//TODO: these need to be defined properly or removed
|
||||
define('pocketmine\COMPOSER_AUTOLOADER_PATH', dirname(__DIR__, 2) . '/vendor/autoload.php');
|
||||
define('pocketmine\DATA', '');
|
||||
|
@ -530,21 +530,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../src/pocketmine/plugin/PluginDescription.php
|
||||
|
||||
-
|
||||
message: "#^Method pocketmine\\\\plugin\\\\PluginDescription\\:\\:getRequiredExtensions\\(\\) should return array\\<string, array\\<int, string\\>\\> but returns array\\<string, array\\<int, mixed\\>\\>\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/pocketmine/plugin/PluginDescription.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$str of function substr expects string, mixed given\\.$#"
|
||||
count: 2
|
||||
path: ../../../src/pocketmine/plugin/PluginDescription.php
|
||||
|
||||
-
|
||||
message: "#^Part \\$constr \\(mixed\\) of encapsed string cannot be cast to string\\.$#"
|
||||
count: 2
|
||||
path: ../../../src/pocketmine/plugin/PluginDescription.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$description of method pocketmine\\\\command\\\\Command\\:\\:setDescription\\(\\) expects string, mixed given\\.$#"
|
||||
count: 1
|
||||
|
@ -1,12 +0,0 @@
|
||||
parameters:
|
||||
ignoreErrors:
|
||||
#TODO: use custom stubs
|
||||
-
|
||||
message: "#^Used constant LEVELDB_ZLIB_RAW_COMPRESSION not found\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/pocketmine/level/format/io/leveldb/LevelDB.php
|
||||
|
||||
-
|
||||
message: "#^Constant LEVELDB_ZLIB_RAW_COMPRESSION not found\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/pocketmine/level/format/io/leveldb/LevelDB.php
|
@ -355,21 +355,11 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../src/pocketmine/command/CommandReader.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$params of class pocketmine\\\\lang\\\\TranslationContainer constructor expects array\\<float\\|int\\|string\\>, array\\<int, string\\|null\\> given\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/pocketmine/command/defaults/BanCommand.php
|
||||
|
||||
-
|
||||
message: "#^Only booleans are allowed in an if condition, int\\|false given\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/pocketmine/command/defaults/BanIpCommand.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$params of class pocketmine\\\\lang\\\\TranslationContainer constructor expects array\\<float\\|int\\|string\\>, array\\<int, string\\|null\\> given\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/pocketmine/command/defaults/BanIpCommand.php
|
||||
|
||||
-
|
||||
message: "#^Only booleans are allowed in an if condition, int\\|false given\\.$#"
|
||||
count: 1
|
||||
@ -575,11 +565,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../src/pocketmine/level/Explosion.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$generatorClass of class pocketmine\\\\level\\\\generator\\\\GeneratorRegisterTask constructor expects string, pocketmine\\\\level\\\\generator\\\\Generator\\|string given\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/pocketmine/level/Level.php
|
||||
|
||||
-
|
||||
message: "#^Cannot access offset 'priority' on array\\('priority' \\=\\> int, 'data' \\=\\> pocketmine\\\\math\\\\Vector3\\)\\|int\\|pocketmine\\\\math\\\\Vector3\\.$#"
|
||||
count: 1
|
||||
@ -750,11 +735,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../src/pocketmine/level/format/io/region/McRegion.php
|
||||
|
||||
-
|
||||
message: "#^Only numeric types are allowed in \\+, int\\|false given on the left side\\.$#"
|
||||
count: 2
|
||||
path: ../../../src/pocketmine/level/format/io/region/McRegion.php
|
||||
|
||||
-
|
||||
message: "#^Only numeric types are allowed in %%, int\\|false given on the left side\\.$#"
|
||||
count: 1
|
||||
|
@ -240,11 +240,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../src/pocketmine/Server.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$name of static method pocketmine\\\\level\\\\generator\\\\GeneratorManager\\:\\:getGenerator\\(\\) expects string, string\\|null given\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/pocketmine/Server.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$uuid of method pocketmine\\\\Server\\:\\:updatePlayerListData\\(\\) expects pocketmine\\\\utils\\\\UUID, pocketmine\\\\utils\\\\UUID\\|null given\\.$#"
|
||||
count: 1
|
||||
@ -535,46 +530,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../src/pocketmine/command/SimpleCommandMap.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$target of method pocketmine\\\\permission\\\\BanList\\:\\:addBan\\(\\) expects string, string\\|null given\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/pocketmine/command/defaults/BanCommand.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$name of method pocketmine\\\\Server\\:\\:getPlayerExact\\(\\) expects string, string\\|null given\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/pocketmine/command/defaults/BanCommand.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$subject of function preg_match expects string, string\\|null given\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/pocketmine/command/defaults/BanIpCommand.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$ip of method pocketmine\\\\command\\\\defaults\\\\BanIpCommand\\:\\:processIPBan\\(\\) expects string, string\\|null given\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/pocketmine/command/defaults/BanIpCommand.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$name of method pocketmine\\\\Server\\:\\:getPlayer\\(\\) expects string, string\\|null given\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/pocketmine/command/defaults/BanIpCommand.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$name of method pocketmine\\\\Server\\:\\:getOfflinePlayer\\(\\) expects string, string\\|null given\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/pocketmine/command/defaults/DeopCommand.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$name of method pocketmine\\\\Server\\:\\:getPlayer\\(\\) expects string, string\\|null given\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/pocketmine/command/defaults/KickCommand.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$name of method pocketmine\\\\Server\\:\\:getOfflinePlayer\\(\\) expects string, string\\|null given\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/pocketmine/command/defaults/OpCommand.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method addParticle\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#"
|
||||
count: 1
|
||||
@ -1535,11 +1490,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../src/pocketmine/network/rcon/RCONInstance.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$str of function trim expects string, string\\|null given\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/pocketmine/permission/BanEntry.php
|
||||
|
||||
-
|
||||
message: "#^Method pocketmine\\\\permission\\\\DefaultPermissions\\:\\:registerPermission\\(\\) should return pocketmine\\\\permission\\\\Permission but returns pocketmine\\\\permission\\\\Permission\\|null\\.$#"
|
||||
count: 1
|
||||
@ -1670,11 +1620,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../src/pocketmine/utils/Config.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$str of function trim expects string, string\\|null given\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/pocketmine/utils/Config.php
|
||||
|
||||
-
|
||||
message: "#^Method pocketmine\\\\utils\\\\MainLogger\\:\\:getLogger\\(\\) should return pocketmine\\\\utils\\\\MainLogger but returns pocketmine\\\\utils\\\\MainLogger\\|null\\.$#"
|
||||
count: 1
|
||||
|
@ -60,11 +60,6 @@ parameters:
|
||||
count: 2
|
||||
path: ../../../src/pocketmine/level/Level.php
|
||||
|
||||
-
|
||||
message: "#^Call to function assert\\(\\) with bool will always evaluate to true\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/pocketmine/level/Level.php
|
||||
|
||||
-
|
||||
message: "#^Call to function is_subclass_of\\(\\) with class\\-string\\<pocketmine\\\\level\\\\generator\\\\Generator\\> and 'pocketmine\\\\\\\\level\\\\\\\\generator\\\\\\\\Generator' will always evaluate to true\\.$#"
|
||||
count: 1
|
||||
|
@ -110,8 +110,6 @@ class BlockTest extends TestCase{
|
||||
|
||||
/**
|
||||
* @dataProvider blockGetProvider
|
||||
* @param int $id
|
||||
* @param int $meta
|
||||
*/
|
||||
public function testBlockGet(int $id, int $meta) : void{
|
||||
$block = BlockFactory::get($id, $meta);
|
||||
|
@ -79,9 +79,6 @@ class ItemTest extends TestCase{
|
||||
|
||||
/**
|
||||
* @dataProvider itemFromStringProvider
|
||||
* @param string $string
|
||||
* @param int $id
|
||||
* @param int $meta
|
||||
*/
|
||||
public function testFromStringSingle(string $string, int $id, int $meta) : void{
|
||||
$item = ItemFactory::fromStringSingle($string);
|
||||
|
@ -82,8 +82,6 @@ class RegionLoaderTest extends TestCase{
|
||||
|
||||
/**
|
||||
* @dataProvider outOfBoundsCoordsProvider
|
||||
* @param int $x
|
||||
* @param int $z
|
||||
*
|
||||
* @throws ChunkException
|
||||
* @throws \InvalidArgumentException
|
||||
@ -109,8 +107,6 @@ class RegionLoaderTest extends TestCase{
|
||||
|
||||
/**
|
||||
* @dataProvider outOfBoundsCoordsProvider
|
||||
* @param int $x
|
||||
* @param int $z
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws \pocketmine\level\format\io\exception\CorruptedChunkException
|
||||
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\level\format\io\region;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use function sprintf;
|
||||
|
||||
class RegionLocationTableEntryTest extends TestCase{
|
||||
|
||||
|
@ -57,7 +57,6 @@ class StupidJsonDecodeTest extends TestCase{
|
||||
/**
|
||||
* @dataProvider stupidJsonDecodeProvider
|
||||
*
|
||||
* @param string $brokenJson
|
||||
* @param mixed $expect
|
||||
*
|
||||
* @throws \ReflectionException
|
||||
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\utils;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use function yaml_parse;
|
||||
|
||||
class ConfigTest extends TestCase{
|
||||
|
||||
@ -61,7 +62,6 @@ class ConfigTest extends TestCase{
|
||||
/**
|
||||
* @dataProvider fixYamlIndexesProvider
|
||||
*
|
||||
* @param string $test
|
||||
* @param mixed[] $expected
|
||||
*/
|
||||
public function testFixYamlIndexes(string $test, array $expected) : void{
|
||||
|
@ -51,7 +51,6 @@ class UtilsTest extends TestCase{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $docComment
|
||||
* @dataProvider parseDocCommentNewlineProvider
|
||||
*/
|
||||
public function testParseDocCommentNewlines(string $docComment) : void{
|
||||
|
@ -26,6 +26,7 @@ namespace pmmp\TesterPlugin;
|
||||
use pocketmine\event\Listener;
|
||||
use pocketmine\event\server\CommandEvent;
|
||||
use pocketmine\plugin\PluginBase;
|
||||
use function array_shift;
|
||||
|
||||
class Main extends PluginBase implements Listener{
|
||||
|
||||
|
@ -23,6 +23,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace pmmp\TesterPlugin;
|
||||
|
||||
use function time;
|
||||
|
||||
abstract class Test{
|
||||
const RESULT_WAITING = -1;
|
||||
const RESULT_OK = 0;
|
||||
|
@ -28,7 +28,10 @@ use pocketmine\scheduler\AsyncTask;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
use pocketmine\utils\MainLogger;
|
||||
use function ob_end_flush;
|
||||
use function ob_get_contents;
|
||||
use function ob_start;
|
||||
use function strpos;
|
||||
|
||||
class AsyncTaskMainLoggerTest extends Test{
|
||||
|
||||
@ -69,5 +72,4 @@ class AsyncTaskMainLoggerTest extends Test{
|
||||
return "Verifies that the MainLogger is accessible by MainLogger::getLogger() in an AsyncTask";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ namespace pmmp\TesterPlugin\tests;
|
||||
|
||||
use pmmp\TesterPlugin\Test;
|
||||
use pocketmine\scheduler\AsyncTask;
|
||||
use function usleep;
|
||||
|
||||
class AsyncTaskMemoryLeakTest extends Test{
|
||||
|
||||
|
@ -15,3 +15,4 @@ before_script:
|
||||
- make install
|
||||
- cd ..
|
||||
- echo "extension=pthreads.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
|
||||
- composer self-update --2
|
||||
|
Reference in New Issue
Block a user