mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-06-06 11:57:10 +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
|
||||
- New blocks, items & mobs aren't implemented
|
||||
- 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"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "0.12.37",
|
||||
"phpstan/phpstan": "0.12.42",
|
||||
"phpstan/phpstan-phpunit": "^0.12.6",
|
||||
"phpstan/phpstan-strict-rules": "^0.12.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",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "3a8f754965da97b4e3237fd32168a6aa",
|
||||
"content-hash": "adc74d30203a9378694bc478baf7a142",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/json-comment",
|
||||
@ -1443,16 +1443,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan",
|
||||
"version": "0.12.37",
|
||||
"version": "0.12.42",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpstan.git",
|
||||
"reference": "5e16d83e6eb2dd784fbdaeaece5e2bca72e4f68a"
|
||||
"reference": "7c43b7c2d5ca6554f6231e82e342a710163ac5f4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/5e16d83e6eb2dd784fbdaeaece5e2bca72e4f68a",
|
||||
"reference": "5e16d83e6eb2dd784fbdaeaece5e2bca72e4f68a",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/7c43b7c2d5ca6554f6231e82e342a710163ac5f4",
|
||||
"reference": "7c43b7c2d5ca6554f6231e82e342a710163ac5f4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1495,7 +1495,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2020-08-09T14:32:41+00:00"
|
||||
"time": "2020-09-02T13:14:53+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan-phpunit",
|
||||
|
@ -24,6 +24,8 @@ parameters:
|
||||
checkExplicitMixed: true
|
||||
bootstrapFiles:
|
||||
- tests/phpstan/bootstrap.php
|
||||
scanDirectories:
|
||||
- tests/plugins/TesterPlugin
|
||||
scanFiles:
|
||||
- src/PocketMine.php
|
||||
- build/make-release.php
|
||||
@ -34,6 +36,7 @@ parameters:
|
||||
- build/make-release.php
|
||||
- build/server-phar.php
|
||||
- tests/phpunit
|
||||
- tests/plugins/TesterPlugin
|
||||
dynamicConstantNames:
|
||||
- pocketmine\VersionInfo::IS_DEVELOPMENT_BUILD
|
||||
- pocketmine\DEBUG
|
||||
|
@ -30,9 +30,13 @@ use function mt_rand;
|
||||
class Potato extends Crops{
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
VanillaItems::POTATO()->setCount($this->age >= 7 ? mt_rand(1, 4) : 1)
|
||||
$result = [
|
||||
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{
|
||||
|
@ -98,7 +98,12 @@ class Sugarcane extends Flowable{
|
||||
for($y = 1; $y < 3; ++$y){
|
||||
$b = $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + $y, $this->pos->z);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -75,6 +75,7 @@ use const M_PI_2;
|
||||
abstract class Entity{
|
||||
|
||||
public const MOTION_THRESHOLD = 0.00001;
|
||||
protected const STEP_CLIP_MULTIPLIER = 0.4;
|
||||
|
||||
/** @var int */
|
||||
private static $entityCount = 1;
|
||||
@ -137,6 +138,8 @@ abstract class Entity{
|
||||
/** @var int */
|
||||
private $maxHealth = 20;
|
||||
|
||||
/** @var float */
|
||||
protected $ySize = 0.0;
|
||||
/** @var float */
|
||||
protected $stepHeight = 0.0;
|
||||
/** @var bool */
|
||||
@ -329,10 +332,10 @@ abstract class Entity{
|
||||
|
||||
$this->boundingBox = new AxisAlignedBB(
|
||||
$this->location->x - $halfWidth,
|
||||
$this->location->y,
|
||||
$this->location->y + $this->ySize,
|
||||
$this->location->z - $halfWidth,
|
||||
$this->location->x + $halfWidth,
|
||||
$this->location->y + $this->height,
|
||||
$this->location->y + $this->height + $this->ySize,
|
||||
$this->location->z + $halfWidth
|
||||
);
|
||||
}
|
||||
@ -1081,6 +1084,7 @@ abstract class Entity{
|
||||
if($this->keepMovement){
|
||||
$this->boundingBox->offset($dx, $dy, $dz);
|
||||
}else{
|
||||
$this->ySize *= self::STEP_CLIP_MULTIPLIER;
|
||||
|
||||
/*
|
||||
if($this->isColliding){ //With cobweb?
|
||||
@ -1175,7 +1179,12 @@ abstract class Entity{
|
||||
|
||||
$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)){
|
||||
$dx = $cx;
|
||||
@ -1183,6 +1192,7 @@ abstract class Entity{
|
||||
$dz = $cz;
|
||||
}else{
|
||||
$moveBB = $stepBB;
|
||||
$this->ySize += $dy;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1190,7 +1200,7 @@ abstract class Entity{
|
||||
}
|
||||
|
||||
$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->checkChunks();
|
||||
@ -1420,6 +1430,7 @@ abstract class Entity{
|
||||
if($ev->isCancelled()){
|
||||
return false;
|
||||
}
|
||||
$this->ySize = 0;
|
||||
$pos = $ev->getTo();
|
||||
|
||||
$this->setMotion(new Vector3(0, 0, 0));
|
||||
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\entity\utils;
|
||||
|
||||
use pocketmine\math\Math;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
use function max;
|
||||
|
||||
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.
|
||||
*/
|
||||
public static function getLevelFromXp(int $xp) : float{
|
||||
if($xp < 0){
|
||||
throw new \InvalidArgumentException("XP must be at least 0");
|
||||
}
|
||||
if($xp <= self::getXpToReachLevel(16)){
|
||||
$a = 1;
|
||||
$b = 6;
|
||||
@ -74,6 +78,9 @@ abstract class ExperienceUtils{
|
||||
}
|
||||
|
||||
$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
|
||||
}
|
||||
|
@ -2207,6 +2207,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
|
||||
$this->networkSession->syncMovement($pos, $yaw, $pitch, $mode);
|
||||
|
||||
$this->forceMoveSync = $pos->asVector3();
|
||||
$this->ySize = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -115,11 +115,6 @@ parameters:
|
||||
count: 1
|
||||
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\\.$#"
|
||||
count: 1
|
||||
@ -417,11 +412,6 @@ parameters:
|
||||
|
||||
-
|
||||
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
|
||||
path: ../../../src/permission/BanEntry.php
|
||||
|
||||
@ -961,7 +951,7 @@ parameters:
|
||||
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
|
||||
path: ../../phpunit/network/mcpe/handler/StupidJsonDecodeTest.php
|
||||
path: ../../plugins/TesterPlugin/src/pmmp/TesterPlugin/CheckTestCompletionTask.php
|
||||
|
||||
|
@ -10,3 +10,8 @@ parameters:
|
||||
count: 1
|
||||
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;
|
||||
|
||||
class StupidJsonDecodeTest extends TestCase{
|
||||
/** @var \Closure */
|
||||
/**
|
||||
* @var \Closure
|
||||
* @phpstan-var \Closure(string $json, bool $assoc=) : mixed
|
||||
*/
|
||||
private $stupidJsonDecodeFunc;
|
||||
|
||||
public function setUp() : void{
|
||||
|
@ -38,14 +38,14 @@ class Main extends PluginBase implements Listener{
|
||||
/** @var int */
|
||||
protected $currentTestNumber = 0;
|
||||
|
||||
public function onEnable(){
|
||||
public function onEnable() : void{
|
||||
$this->getServer()->getPluginManager()->registerEvents($this, $this);
|
||||
$this->getScheduler()->scheduleRepeatingTask(new CheckTestCompletionTask($this), 10);
|
||||
|
||||
$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
|
||||
//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
|
||||
@ -55,10 +55,7 @@ class Main extends PluginBase implements Listener{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Test|null
|
||||
*/
|
||||
public function getCurrentTest(){
|
||||
public function getCurrentTest() : ?Test{
|
||||
return $this->currentTest;
|
||||
}
|
||||
|
||||
@ -73,7 +70,7 @@ class Main extends PluginBase implements Listener{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onTestCompleted(Test $test){
|
||||
public function onTestCompleted(Test $test) : void{
|
||||
$message = "Finished test #" . $this->currentTestNumber . " (" . $test->getName() . "): ";
|
||||
switch($test->getResult()){
|
||||
case Test::RESULT_OK:
|
||||
@ -99,7 +96,7 @@ class Main extends PluginBase implements Listener{
|
||||
$this->currentTest = null;
|
||||
}
|
||||
|
||||
public function onAllTestsCompleted(){
|
||||
public function onAllTestsCompleted() : void{
|
||||
$this->getLogger()->notice("All tests finished, stopping the server");
|
||||
$this->getServer()->shutdown();
|
||||
}
|
||||
|
@ -29,9 +29,13 @@ abstract class Test{
|
||||
const RESULT_FAILED = 1;
|
||||
const RESULT_ERROR = 2;
|
||||
|
||||
/** @var Main */
|
||||
private $plugin;
|
||||
/** @var int */
|
||||
private $result = Test::RESULT_WAITING;
|
||||
/** @var int */
|
||||
private $startTime;
|
||||
/** @var int */
|
||||
private $timeout = 60; //seconds
|
||||
|
||||
public function __construct(Main $plugin){
|
||||
@ -42,7 +46,7 @@ abstract class Test{
|
||||
return $this->plugin;
|
||||
}
|
||||
|
||||
final public function start(){
|
||||
final public function start() : void{
|
||||
$this->startTime = time();
|
||||
try{
|
||||
$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{
|
||||
return $this->result !== Test::RESULT_WAITING;
|
||||
@ -69,7 +73,7 @@ abstract class Test{
|
||||
return !$this->isFinished() and time() - $this->timeout > $this->startTime;
|
||||
}
|
||||
|
||||
protected function setTimeout(int $timeout){
|
||||
protected function setTimeout(int $timeout) : void{
|
||||
$this->timeout = $timeout;
|
||||
}
|
||||
|
||||
@ -77,7 +81,7 @@ abstract class Test{
|
||||
return $this->result;
|
||||
}
|
||||
|
||||
public function setResult(int $result){
|
||||
public function setResult(int $result) : void{
|
||||
$this->result = $result;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user