mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-06-07 12:18:46 +00:00
Merge branch 'stable' into master
# Conflicts: # composer.lock # resources/vanilla # src/entity/Living.php # src/pocketmine/Player.php # src/pocketmine/VersionInfo.php # src/pocketmine/block/Potato.php # src/pocketmine/block/Sugarcane.php # src/pocketmine/entity/Entity.php # src/pocketmine/item/Item.php # src/pocketmine/level/format/Chunk.php # src/pocketmine/level/format/io/leveldb/LevelDB.php # src/world/generator/GeneratorRegisterTask.php # tests/phpstan/configs/check-explicit-mixed-baseline.neon # tests/phpstan/configs/l7-baseline.neon # tests/phpstan/configs/l8-baseline.neon # tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskMainLoggerTest.php # tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskMemoryLeakTest.php # tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskPublishProgressRaceTest.php
This commit is contained in:
commit
0aee39027e
11
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
11
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
blank_issues_enabled: false
|
||||||
|
contact_links:
|
||||||
|
- name: Help & support on Discord
|
||||||
|
url: https://discord.gg/bmSAZBG
|
||||||
|
about: We don't accept support requests on the issue tracker. Please try asking on Discord instead.
|
||||||
|
- name: Help & support on forums
|
||||||
|
url: https://forums.pmmp.io
|
||||||
|
about: We don't accept support requests on the issue tracker. Please try asking on forums instead.
|
||||||
|
- name: Documentation
|
||||||
|
url: https://pmmp.rtfd.io
|
||||||
|
about: PocketMine-MP documentation
|
14
.github/ISSUE_TEMPLATE/help---support.md
vendored
14
.github/ISSUE_TEMPLATE/help---support.md
vendored
@ -1,14 +0,0 @@
|
|||||||
---
|
|
||||||
name: Help & support
|
|
||||||
about: We don't accept support requests here. Try the links on the README.
|
|
||||||
title: ''
|
|
||||||
labels: Support request
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
We don't accept support requests on the issue tracker. Please try the following links instead:
|
|
||||||
|
|
||||||
Documentation: http://pmmp.rtfd.io
|
|
||||||
Forums: https://forums.pmmp.io
|
|
||||||
Discord: https://discord.gg/bmSAZBG
|
|
@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
name: Security/DoS vulnerability
|
|
||||||
about: 'Bug or exploit that can be used to attack servers (hint: don''t report it
|
|
||||||
on a public issue tracker)'
|
|
||||||
title: ''
|
|
||||||
labels: 'Auto: Spam'
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Please DO NOT report security vulnerabilities here.
|
|
||||||
Instead, send an email to team@pmmp.io or contact a developer directly, IN PRIVATE.
|
|
33
SECURITY.md
Normal file
33
SECURITY.md
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# Security Policy
|
||||||
|
|
||||||
|
## Supported Versions
|
||||||
|
The following release lines are currently receiving active security updates and bug fixes:
|
||||||
|
|
||||||
|
| Version | Supported |
|
||||||
|
| -------- | ------------------ |
|
||||||
|
| 3.15.x | :white_check_mark: |
|
||||||
|
| < 3.15.0 | :x: |
|
||||||
|
|
||||||
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
|
**DO NOT report vulnerabilities on the GitHub issue tracker.**
|
||||||
|
GitHub is public and anyone can see the issues you post on the issue tracker, including people who would exploit vulnerabilities for their own gain.
|
||||||
|
|
||||||
|
**WARNING: You may put live servers at risk by reporting a vulnerability on the GitHub issue tracker.**
|
||||||
|
|
||||||
|
**Contact us** by sending an email to [**team@pmmp.io**](mailto:team@pmmp.io?subject=Security%20Vulnerability%20in%20PocketMine-MP). Include the following information:
|
||||||
|
|
||||||
|
- Version of PocketMine-MP
|
||||||
|
- Detailed description of the vulnerability (e.g. how to exploit it, what the effects are)
|
||||||
|
|
||||||
|
Please note that we can't guarantee a reply to every email.
|
||||||
|
|
||||||
|
## FAQ
|
||||||
|
### Do you offer a bug bounty?
|
||||||
|
No.
|
||||||
|
|
||||||
|
### How soon can I expect a fix for a vulnerability I've reported?
|
||||||
|
This depends on the nature of the problem. We can't provide any general ETA (nor would it be wise to provide one).
|
||||||
|
In general, it depends on when developers have time to look into the problem, how complex the problem is to fix, and how many users it impacts.
|
||||||
|
|
||||||
|
When a fix for a severe vulnerability is pushed, a patch release for the target version will usually be released within 24 hours so that users can update.
|
@ -15,3 +15,15 @@ Plugin developers should **only** update their required API to this version if y
|
|||||||
- Pumpkin and melon stems may not connect to their corresponding pumpkin/melon
|
- Pumpkin and melon stems may not connect to their corresponding pumpkin/melon
|
||||||
- New blocks, items & mobs aren't implemented
|
- New blocks, items & mobs aren't implemented
|
||||||
- Nether doesn't exist
|
- Nether doesn't exist
|
||||||
|
|
||||||
|
# 3.15.1
|
||||||
|
- Fixed various PHP 7.4 compatibility issues in Composer dependencies (primarily callback-validator).
|
||||||
|
- Fixed LevelDB worlds with corrupted `level.dat` crashing the server instead of failing gracefully.
|
||||||
|
- Fixed error spam when using strings for layers in flatworld presets (`e.g. bedrock,3xdirt,grass`).
|
||||||
|
- Fixed blocks not getting updated properly on explosions.
|
||||||
|
- Fixed `BlockGrowEvent` not being called when sugarcane grows.
|
||||||
|
- Potato crops now drop poisonous potatoes when harvested.
|
||||||
|
- Fixed the wrong number of potatoes being dropped when harvesting potato crops.
|
||||||
|
- Players no longer get pullbacks when sprinting on slabs, stairs and various other blocks when `player.anti-cheat.allow-movement-cheats` is set to `false`. (This bug has been around for over 5 years, so many of you will be used to its existence.)
|
||||||
|
- Fixed entity collision box calculation not taking clip distance into account.
|
||||||
|
- Entities now step up the correct height of the target block, instead of jumping into the air 0.6 blocks and falling back down.
|
||||||
|
@ -50,7 +50,7 @@
|
|||||||
"respect/validation": "^2.0"
|
"respect/validation": "^2.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpstan/phpstan": "0.12.37",
|
"phpstan/phpstan": "0.12.42",
|
||||||
"phpstan/phpstan-phpunit": "^0.12.6",
|
"phpstan/phpstan-phpunit": "^0.12.6",
|
||||||
"phpstan/phpstan-strict-rules": "^0.12.2",
|
"phpstan/phpstan-strict-rules": "^0.12.2",
|
||||||
"phpunit/phpunit": "^9.2"
|
"phpunit/phpunit": "^9.2"
|
||||||
|
12
composer.lock
generated
12
composer.lock
generated
@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "3a8f754965da97b4e3237fd32168a6aa",
|
"content-hash": "adc74d30203a9378694bc478baf7a142",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "adhocore/json-comment",
|
"name": "adhocore/json-comment",
|
||||||
@ -1443,16 +1443,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpstan/phpstan",
|
"name": "phpstan/phpstan",
|
||||||
"version": "0.12.37",
|
"version": "0.12.42",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/phpstan/phpstan.git",
|
"url": "https://github.com/phpstan/phpstan.git",
|
||||||
"reference": "5e16d83e6eb2dd784fbdaeaece5e2bca72e4f68a"
|
"reference": "7c43b7c2d5ca6554f6231e82e342a710163ac5f4"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/5e16d83e6eb2dd784fbdaeaece5e2bca72e4f68a",
|
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/7c43b7c2d5ca6554f6231e82e342a710163ac5f4",
|
||||||
"reference": "5e16d83e6eb2dd784fbdaeaece5e2bca72e4f68a",
|
"reference": "7c43b7c2d5ca6554f6231e82e342a710163ac5f4",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -1495,7 +1495,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2020-08-09T14:32:41+00:00"
|
"time": "2020-09-02T13:14:53+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpstan/phpstan-phpunit",
|
"name": "phpstan/phpstan-phpunit",
|
||||||
|
@ -24,6 +24,8 @@ parameters:
|
|||||||
checkExplicitMixed: true
|
checkExplicitMixed: true
|
||||||
bootstrapFiles:
|
bootstrapFiles:
|
||||||
- tests/phpstan/bootstrap.php
|
- tests/phpstan/bootstrap.php
|
||||||
|
scanDirectories:
|
||||||
|
- tests/plugins/TesterPlugin
|
||||||
scanFiles:
|
scanFiles:
|
||||||
- src/PocketMine.php
|
- src/PocketMine.php
|
||||||
- build/make-release.php
|
- build/make-release.php
|
||||||
@ -34,6 +36,7 @@ parameters:
|
|||||||
- build/make-release.php
|
- build/make-release.php
|
||||||
- build/server-phar.php
|
- build/server-phar.php
|
||||||
- tests/phpunit
|
- tests/phpunit
|
||||||
|
- tests/plugins/TesterPlugin
|
||||||
dynamicConstantNames:
|
dynamicConstantNames:
|
||||||
- pocketmine\VersionInfo::IS_DEVELOPMENT_BUILD
|
- pocketmine\VersionInfo::IS_DEVELOPMENT_BUILD
|
||||||
- pocketmine\DEBUG
|
- pocketmine\DEBUG
|
||||||
|
@ -30,9 +30,13 @@ use function mt_rand;
|
|||||||
class Potato extends Crops{
|
class Potato extends Crops{
|
||||||
|
|
||||||
public function getDropsForCompatibleTool(Item $item) : array{
|
public function getDropsForCompatibleTool(Item $item) : array{
|
||||||
return [
|
$result = [
|
||||||
VanillaItems::POTATO()->setCount($this->age >= 7 ? mt_rand(1, 4) : 1)
|
VanillaItems::POTATO()->setCount($this->age >= 7 ? mt_rand(1, 5) : 1)
|
||||||
];
|
];
|
||||||
|
if($this->age >= 7 && mt_rand(0, 49) === 0){
|
||||||
|
$result[] = VanillaItems::POISONOUS_POTATO();
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPickedItem(bool $addUserData = false) : Item{
|
public function getPickedItem(bool $addUserData = false) : Item{
|
||||||
|
@ -98,7 +98,12 @@ class Sugarcane extends Flowable{
|
|||||||
for($y = 1; $y < 3; ++$y){
|
for($y = 1; $y < 3; ++$y){
|
||||||
$b = $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + $y, $this->pos->z);
|
$b = $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + $y, $this->pos->z);
|
||||||
if($b->getId() === BlockLegacyIds::AIR){
|
if($b->getId() === BlockLegacyIds::AIR){
|
||||||
$this->pos->getWorld()->setBlock($b->pos, VanillaBlocks::SUGARCANE());
|
$ev = new BlockGrowEvent($b, VanillaBlocks::SUGARCANE());
|
||||||
|
$ev->call();
|
||||||
|
if($ev->isCancelled()){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$this->pos->getWorld()->setBlock($b->pos, $ev->getNewState());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,6 +75,7 @@ use const M_PI_2;
|
|||||||
abstract class Entity{
|
abstract class Entity{
|
||||||
|
|
||||||
public const MOTION_THRESHOLD = 0.00001;
|
public const MOTION_THRESHOLD = 0.00001;
|
||||||
|
protected const STEP_CLIP_MULTIPLIER = 0.4;
|
||||||
|
|
||||||
/** @var int */
|
/** @var int */
|
||||||
private static $entityCount = 1;
|
private static $entityCount = 1;
|
||||||
@ -137,6 +138,8 @@ abstract class Entity{
|
|||||||
/** @var int */
|
/** @var int */
|
||||||
private $maxHealth = 20;
|
private $maxHealth = 20;
|
||||||
|
|
||||||
|
/** @var float */
|
||||||
|
protected $ySize = 0.0;
|
||||||
/** @var float */
|
/** @var float */
|
||||||
protected $stepHeight = 0.0;
|
protected $stepHeight = 0.0;
|
||||||
/** @var bool */
|
/** @var bool */
|
||||||
@ -329,10 +332,10 @@ abstract class Entity{
|
|||||||
|
|
||||||
$this->boundingBox = new AxisAlignedBB(
|
$this->boundingBox = new AxisAlignedBB(
|
||||||
$this->location->x - $halfWidth,
|
$this->location->x - $halfWidth,
|
||||||
$this->location->y,
|
$this->location->y + $this->ySize,
|
||||||
$this->location->z - $halfWidth,
|
$this->location->z - $halfWidth,
|
||||||
$this->location->x + $halfWidth,
|
$this->location->x + $halfWidth,
|
||||||
$this->location->y + $this->height,
|
$this->location->y + $this->height + $this->ySize,
|
||||||
$this->location->z + $halfWidth
|
$this->location->z + $halfWidth
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1081,6 +1084,7 @@ abstract class Entity{
|
|||||||
if($this->keepMovement){
|
if($this->keepMovement){
|
||||||
$this->boundingBox->offset($dx, $dy, $dz);
|
$this->boundingBox->offset($dx, $dy, $dz);
|
||||||
}else{
|
}else{
|
||||||
|
$this->ySize *= self::STEP_CLIP_MULTIPLIER;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if($this->isColliding){ //With cobweb?
|
if($this->isColliding){ //With cobweb?
|
||||||
@ -1175,7 +1179,12 @@ abstract class Entity{
|
|||||||
|
|
||||||
$stepBB->offset(0, 0, $dz);
|
$stepBB->offset(0, 0, $dz);
|
||||||
|
|
||||||
//TODO: here we need to shift back down on the Y-axis to the top of the target block (we don't want to jump into the air when walking onto carpet)
|
$reverseDY = -$dy;
|
||||||
|
foreach($list as $bb){
|
||||||
|
$reverseDY = $bb->calculateYOffset($stepBB, $reverseDY);
|
||||||
|
}
|
||||||
|
$dy += $reverseDY;
|
||||||
|
$stepBB->offset(0, $reverseDY, 0);
|
||||||
|
|
||||||
if(($cx ** 2 + $cz ** 2) >= ($dx ** 2 + $dz ** 2)){
|
if(($cx ** 2 + $cz ** 2) >= ($dx ** 2 + $dz ** 2)){
|
||||||
$dx = $cx;
|
$dx = $cx;
|
||||||
@ -1183,6 +1192,7 @@ abstract class Entity{
|
|||||||
$dz = $cz;
|
$dz = $cz;
|
||||||
}else{
|
}else{
|
||||||
$moveBB = $stepBB;
|
$moveBB = $stepBB;
|
||||||
|
$this->ySize += $dy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1190,7 +1200,7 @@ abstract class Entity{
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->location->x = ($this->boundingBox->minX + $this->boundingBox->maxX) / 2;
|
$this->location->x = ($this->boundingBox->minX + $this->boundingBox->maxX) / 2;
|
||||||
$this->location->y = $this->boundingBox->minY;
|
$this->location->y = $this->boundingBox->minY - $this->ySize;
|
||||||
$this->location->z = ($this->boundingBox->minZ + $this->boundingBox->maxZ) / 2;
|
$this->location->z = ($this->boundingBox->minZ + $this->boundingBox->maxZ) / 2;
|
||||||
|
|
||||||
$this->checkChunks();
|
$this->checkChunks();
|
||||||
@ -1420,6 +1430,7 @@ abstract class Entity{
|
|||||||
if($ev->isCancelled()){
|
if($ev->isCancelled()){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
$this->ySize = 0;
|
||||||
$pos = $ev->getTo();
|
$pos = $ev->getTo();
|
||||||
|
|
||||||
$this->setMotion(new Vector3(0, 0, 0));
|
$this->setMotion(new Vector3(0, 0, 0));
|
||||||
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
|||||||
namespace pocketmine\entity\utils;
|
namespace pocketmine\entity\utils;
|
||||||
|
|
||||||
use pocketmine\math\Math;
|
use pocketmine\math\Math;
|
||||||
|
use pocketmine\utils\AssumptionFailedError;
|
||||||
use function max;
|
use function max;
|
||||||
|
|
||||||
abstract class ExperienceUtils{
|
abstract class ExperienceUtils{
|
||||||
@ -59,6 +60,9 @@ abstract class ExperienceUtils{
|
|||||||
* This returns a floating-point number, the decimal part being the progress through the resulting level.
|
* This returns a floating-point number, the decimal part being the progress through the resulting level.
|
||||||
*/
|
*/
|
||||||
public static function getLevelFromXp(int $xp) : float{
|
public static function getLevelFromXp(int $xp) : float{
|
||||||
|
if($xp < 0){
|
||||||
|
throw new \InvalidArgumentException("XP must be at least 0");
|
||||||
|
}
|
||||||
if($xp <= self::getXpToReachLevel(16)){
|
if($xp <= self::getXpToReachLevel(16)){
|
||||||
$a = 1;
|
$a = 1;
|
||||||
$b = 6;
|
$b = 6;
|
||||||
@ -74,6 +78,9 @@ abstract class ExperienceUtils{
|
|||||||
}
|
}
|
||||||
|
|
||||||
$x = Math::solveQuadratic($a, $b, $c - $xp);
|
$x = Math::solveQuadratic($a, $b, $c - $xp);
|
||||||
|
if(count($x) === 0){
|
||||||
|
throw new AssumptionFailedError("Expected at least 1 solution");
|
||||||
|
}
|
||||||
|
|
||||||
return max($x); //we're only interested in the positive solution
|
return max($x); //we're only interested in the positive solution
|
||||||
}
|
}
|
||||||
|
@ -2207,6 +2207,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
|
|||||||
$this->networkSession->syncMovement($pos, $yaw, $pitch, $mode);
|
$this->networkSession->syncMovement($pos, $yaw, $pitch, $mode);
|
||||||
|
|
||||||
$this->forceMoveSync = $pos->asVector3();
|
$this->forceMoveSync = $pos->asVector3();
|
||||||
|
$this->ySize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -115,11 +115,6 @@ parameters:
|
|||||||
count: 1
|
count: 1
|
||||||
path: ../../../src/command/defaults/SetWorldSpawnCommand.php
|
path: ../../../src/command/defaults/SetWorldSpawnCommand.php
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Parameter \\#1 \\$name of method pocketmine\\\\Server\\:\\:getPlayer\\(\\) expects string, string\\|null given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../../../src/command/defaults/TellCommand.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Cannot call method getTime\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#"
|
message: "#^Cannot call method getTime\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#"
|
||||||
count: 1
|
count: 1
|
||||||
@ -417,11 +412,6 @@ parameters:
|
|||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Parameter \\#1 \\$str of function trim expects string, string\\|null given\\.$#"
|
message: "#^Parameter \\#1 \\$str of function trim expects string, string\\|null given\\.$#"
|
||||||
count: 4
|
|
||||||
path: ../../../src/permission/BanEntry.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Parameter \\#1 \\$date of static method pocketmine\\\\permission\\\\BanEntry\\:\\:parseDate\\(\\) expects string, string\\|null given\\.$#"
|
|
||||||
count: 1
|
count: 1
|
||||||
path: ../../../src/permission/BanEntry.php
|
path: ../../../src/permission/BanEntry.php
|
||||||
|
|
||||||
@ -961,7 +951,7 @@ parameters:
|
|||||||
path: ../../phpunit/event/HandlerListManagerTest.php
|
path: ../../phpunit/event/HandlerListManagerTest.php
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Property pocketmine\\\\network\\\\mcpe\\\\handler\\\\StupidJsonDecodeTest\\:\\:\\$stupidJsonDecodeFunc \\(Closure\\) does not accept Closure\\|null\\.$#"
|
message: "#^Cannot call method cancel\\(\\) on pocketmine\\\\scheduler\\\\TaskHandler\\|null\\.$#"
|
||||||
count: 1
|
count: 1
|
||||||
path: ../../phpunit/network/mcpe/handler/StupidJsonDecodeTest.php
|
path: ../../plugins/TesterPlugin/src/pmmp/TesterPlugin/CheckTestCompletionTask.php
|
||||||
|
|
||||||
|
@ -10,3 +10,8 @@ parameters:
|
|||||||
count: 1
|
count: 1
|
||||||
path: ../../phpunit/network/mcpe/handler/StupidJsonDecodeTest.php
|
path: ../../phpunit/network/mcpe/handler/StupidJsonDecodeTest.php
|
||||||
|
|
||||||
|
-
|
||||||
|
message: "#^Property pocketmine\\\\network\\\\mcpe\\\\handler\\\\StupidJsonDecodeTest\\:\\:\\$stupidJsonDecodeFunc \\(Closure\\(string, bool\\)\\: mixed\\) does not accept Closure\\|null\\.$#"
|
||||||
|
count: 1
|
||||||
|
path: ../../phpunit/network/mcpe/handler/StupidJsonDecodeTest.php
|
||||||
|
|
||||||
|
@ -26,7 +26,10 @@ namespace pocketmine\network\mcpe\handler;
|
|||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
class StupidJsonDecodeTest extends TestCase{
|
class StupidJsonDecodeTest extends TestCase{
|
||||||
/** @var \Closure */
|
/**
|
||||||
|
* @var \Closure
|
||||||
|
* @phpstan-var \Closure(string $json, bool $assoc=) : mixed
|
||||||
|
*/
|
||||||
private $stupidJsonDecodeFunc;
|
private $stupidJsonDecodeFunc;
|
||||||
|
|
||||||
public function setUp() : void{
|
public function setUp() : void{
|
||||||
|
@ -38,14 +38,14 @@ class Main extends PluginBase implements Listener{
|
|||||||
/** @var int */
|
/** @var int */
|
||||||
protected $currentTestNumber = 0;
|
protected $currentTestNumber = 0;
|
||||||
|
|
||||||
public function onEnable(){
|
public function onEnable() : void{
|
||||||
$this->getServer()->getPluginManager()->registerEvents($this, $this);
|
$this->getServer()->getPluginManager()->registerEvents($this, $this);
|
||||||
$this->getScheduler()->scheduleRepeatingTask(new CheckTestCompletionTask($this), 10);
|
$this->getScheduler()->scheduleRepeatingTask(new CheckTestCompletionTask($this), 10);
|
||||||
|
|
||||||
$this->waitingTests = [];
|
$this->waitingTests = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onServerCommand(CommandEvent $event){
|
public function onServerCommand(CommandEvent $event) : void{
|
||||||
//The CI will send this command as a failsafe to prevent the build from hanging if the tester plugin failed to
|
//The CI will send this command as a failsafe to prevent the build from hanging if the tester plugin failed to
|
||||||
//run. However, if the plugin loaded successfully we don't want to allow this to stop the server as there may
|
//run. However, if the plugin loaded successfully we don't want to allow this to stop the server as there may
|
||||||
//be asynchronous tests running. Instead we cancel this and stop the server of our own accord once all tests
|
//be asynchronous tests running. Instead we cancel this and stop the server of our own accord once all tests
|
||||||
@ -55,10 +55,7 @@ class Main extends PluginBase implements Listener{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getCurrentTest() : ?Test{
|
||||||
* @return Test|null
|
|
||||||
*/
|
|
||||||
public function getCurrentTest(){
|
|
||||||
return $this->currentTest;
|
return $this->currentTest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +70,7 @@ class Main extends PluginBase implements Listener{
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onTestCompleted(Test $test){
|
public function onTestCompleted(Test $test) : void{
|
||||||
$message = "Finished test #" . $this->currentTestNumber . " (" . $test->getName() . "): ";
|
$message = "Finished test #" . $this->currentTestNumber . " (" . $test->getName() . "): ";
|
||||||
switch($test->getResult()){
|
switch($test->getResult()){
|
||||||
case Test::RESULT_OK:
|
case Test::RESULT_OK:
|
||||||
@ -99,7 +96,7 @@ class Main extends PluginBase implements Listener{
|
|||||||
$this->currentTest = null;
|
$this->currentTest = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onAllTestsCompleted(){
|
public function onAllTestsCompleted() : void{
|
||||||
$this->getLogger()->notice("All tests finished, stopping the server");
|
$this->getLogger()->notice("All tests finished, stopping the server");
|
||||||
$this->getServer()->shutdown();
|
$this->getServer()->shutdown();
|
||||||
}
|
}
|
||||||
|
@ -29,9 +29,13 @@ abstract class Test{
|
|||||||
const RESULT_FAILED = 1;
|
const RESULT_FAILED = 1;
|
||||||
const RESULT_ERROR = 2;
|
const RESULT_ERROR = 2;
|
||||||
|
|
||||||
|
/** @var Main */
|
||||||
private $plugin;
|
private $plugin;
|
||||||
|
/** @var int */
|
||||||
private $result = Test::RESULT_WAITING;
|
private $result = Test::RESULT_WAITING;
|
||||||
|
/** @var int */
|
||||||
private $startTime;
|
private $startTime;
|
||||||
|
/** @var int */
|
||||||
private $timeout = 60; //seconds
|
private $timeout = 60; //seconds
|
||||||
|
|
||||||
public function __construct(Main $plugin){
|
public function __construct(Main $plugin){
|
||||||
@ -42,7 +46,7 @@ abstract class Test{
|
|||||||
return $this->plugin;
|
return $this->plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
final public function start(){
|
final public function start() : void{
|
||||||
$this->startTime = time();
|
$this->startTime = time();
|
||||||
try{
|
try{
|
||||||
$this->run();
|
$this->run();
|
||||||
@ -55,11 +59,11 @@ abstract class Test{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function tick(){
|
public function tick() : void{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract public function run();
|
abstract public function run() : void;
|
||||||
|
|
||||||
public function isFinished() : bool{
|
public function isFinished() : bool{
|
||||||
return $this->result !== Test::RESULT_WAITING;
|
return $this->result !== Test::RESULT_WAITING;
|
||||||
@ -69,7 +73,7 @@ abstract class Test{
|
|||||||
return !$this->isFinished() and time() - $this->timeout > $this->startTime;
|
return !$this->isFinished() and time() - $this->timeout > $this->startTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function setTimeout(int $timeout){
|
protected function setTimeout(int $timeout) : void{
|
||||||
$this->timeout = $timeout;
|
$this->timeout = $timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +81,7 @@ abstract class Test{
|
|||||||
return $this->result;
|
return $this->result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setResult(int $result){
|
public function setResult(int $result) : void{
|
||||||
$this->result = $result;
|
$this->result = $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user