mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-08 19:02:59 +00:00
Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
f0539f4898 | |||
63d7e7b811 | |||
4da06078ed | |||
8a6381c3fa | |||
d0d61597c7 | |||
7a2a4e2aa3 | |||
e41a2c0792 | |||
11a6e04a28 | |||
70b1ac856d | |||
d724374d1a | |||
a19143cae7 |
@ -5,23 +5,24 @@
|
||||
|
||||
[](https://travis-ci.org/pmmp/PocketMine-MP)
|
||||
|
||||
### Getting started
|
||||
## Getting started
|
||||
- [Documentation](http://pmmp.readthedocs.org/)
|
||||
- [Installation instructions](https://pmmp.readthedocs.io/en/rtfd/installation.html)
|
||||
- [Docker image](https://hub.docker.com/r/pmmp/pocketmine-mp)
|
||||
- [Plugin repository](https://poggit.pmmp.io/plugins)
|
||||
|
||||
### Discussion
|
||||
## Discussion/Help
|
||||
- [Forums](https://forums.pmmp.io/)
|
||||
- [Community Discord](https://discord.gg/bmSAZBG)
|
||||
- [StackOverflow](https://stackoverflow.com/tags/pocketmine)
|
||||
|
||||
### For developers
|
||||
## For developers
|
||||
* [Latest API documentation](https://jenkins.pmmp.io/job/PocketMine-MP-doc/doxygen/) - Doxygen documentation generated from development
|
||||
* [DevTools](https://github.com/pmmp/PocketMine-DevTools/) - Development tools plugin for creating plugins
|
||||
* [ExamplePlugin](https://github.com/pmmp/ExamplePlugin/) - Example plugin demonstrating some basic API features
|
||||
* [Contributing Guidelines](CONTRIBUTING.md)
|
||||
|
||||
### Donate
|
||||
## Donate
|
||||
- Bitcoin Cash (BCH): `qq3r46hn6ljnhnqnfwxt5pg3g447eq9jhvw5ddfear`
|
||||
- Bitcoin (BTC): `171u8K9e4FtU6j3e5sqNoxKUgEw9qWQdRV`
|
||||
- [Patreon](https://www.patreon.com/pocketminemp)
|
||||
|
@ -69,3 +69,8 @@ Plugin developers should **only** update their required API to this version if y
|
||||
- `Entity->despawnFromAll()`
|
||||
- Fixed plugin `softdepend` not influencing load order when a soft-depended plugin had an unresolved soft dependency of its own.
|
||||
- Fixed endless falling of sand on top of fences.
|
||||
|
||||
# 3.9.5
|
||||
- Fixed some issues with multiple consecutive commas inside quotes in form responses.
|
||||
- Fixed server crash when the manifest json does not contain a json object in a resource pack.
|
||||
- Ender pearls no longer collide with blocks that do not have any collision boxes.
|
||||
|
@ -2200,6 +2200,7 @@ class Server{
|
||||
|
||||
$this->logger->info($this->getLanguage()->translateString("pocketmine.server.defaultGameMode", [self::getGamemodeString($this->getGamemode())]));
|
||||
|
||||
$this->logger->info($this->getLanguage()->translateString("pocketmine.server.donate", [TextFormat::AQUA . "https://patreon.com/pocketminemp" . TextFormat::RESET]));
|
||||
$this->logger->info($this->getLanguage()->translateString("pocketmine.server.startFinished", [round(microtime(true) - \pocketmine\START_TIME, 3)]));
|
||||
|
||||
$this->tickProcessor();
|
||||
|
@ -22,6 +22,6 @@
|
||||
namespace pocketmine;
|
||||
|
||||
const NAME = "PocketMine-MP";
|
||||
const BASE_VERSION = "3.9.4";
|
||||
const BASE_VERSION = "3.9.5";
|
||||
const IS_DEVELOPMENT_BUILD = false;
|
||||
const BUILD_NUMBER = 0;
|
||||
|
@ -23,36 +23,14 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\entity\projectile;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\event\entity\ProjectileHitEvent;
|
||||
use pocketmine\level\sound\EndermanTeleportSound;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\RayTraceResult;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\network\mcpe\protocol\LevelEventPacket;
|
||||
|
||||
class EnderPearl extends Throwable{
|
||||
public const NETWORK_ID = self::ENDER_PEARL;
|
||||
|
||||
protected function calculateInterceptWithBlock(Block $block, Vector3 $start, Vector3 $end) : ?RayTraceResult{
|
||||
if($block->getId() !== Block::AIR and empty($block->getCollisionBoxes())){
|
||||
//TODO: remove this once block collision boxes are fixed properly
|
||||
$bb = new AxisAlignedBB(
|
||||
$block->x,
|
||||
$block->y,
|
||||
$block->z,
|
||||
$block->x + 1,
|
||||
$block->y + 1,
|
||||
$block->z + 1
|
||||
);
|
||||
|
||||
return $bb->calculateIntercept($start, $end);
|
||||
}
|
||||
|
||||
return parent::calculateInterceptWithBlock($block, $start, $end);
|
||||
}
|
||||
|
||||
protected function onHit(ProjectileHitEvent $event) : void{
|
||||
$owner = $this->getOwningEntity();
|
||||
if($owner !== null){
|
||||
|
Submodule src/pocketmine/lang/locale updated: 73ed1ab3e1...85343cfb7f
@ -74,7 +74,6 @@ use function implode;
|
||||
use function json_decode;
|
||||
use function json_last_error_msg;
|
||||
use function preg_match;
|
||||
use function preg_split;
|
||||
use function strlen;
|
||||
use function substr;
|
||||
use function trim;
|
||||
@ -270,16 +269,31 @@ class PlayerNetworkSessionAdapter extends NetworkSession{
|
||||
*/
|
||||
private static function stupid_json_decode(string $json, bool $assoc = false){
|
||||
if(preg_match('/^\[(.+)\]$/s', $json, $matches) > 0){
|
||||
$parts = preg_split('/(?:"(?:\\"|[^"])*"|)\K(,)/', $matches[1]); //Splits on commas not inside quotes, ignoring escaped quotes
|
||||
foreach($parts as $k => $part){
|
||||
$part = trim($part);
|
||||
if($part === ""){
|
||||
$part = "\"\"";
|
||||
$raw = $matches[1];
|
||||
$lastComma = -1;
|
||||
$newParts = [];
|
||||
$quoteType = null;
|
||||
for($i = 0, $len = strlen($raw); $i <= $len; ++$i){
|
||||
if($i === $len or ($raw[$i] === "," and $quoteType === null)){
|
||||
$part = substr($raw, $lastComma + 1, $i - ($lastComma + 1));
|
||||
if(trim($part) === ""){ //regular parts will have quotes or something else that makes them non-empty
|
||||
$part = '""';
|
||||
}
|
||||
$newParts[] = $part;
|
||||
$lastComma = $i;
|
||||
}elseif($raw[$i] === '"'){
|
||||
if($quoteType === null){
|
||||
$quoteType = $raw[$i];
|
||||
}elseif($raw[$i] === $quoteType){
|
||||
for($backslashes = 0; $backslashes < $i && $raw[$i - $backslashes - 1] === "\\"; ++$backslashes){}
|
||||
if(($backslashes % 2) === 0){ //unescaped quote
|
||||
$quoteType = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
$parts[$k] = $part;
|
||||
}
|
||||
|
||||
$fixed = "[" . implode(",", $parts) . "]";
|
||||
$fixed = "[" . implode(",", $newParts) . "]";
|
||||
if(($ret = json_decode($fixed, $assoc)) === null){
|
||||
throw new \InvalidArgumentException("Failed to fix JSON: " . json_last_error_msg() . "(original: $json, modified: $fixed)");
|
||||
}
|
||||
|
@ -104,7 +104,9 @@ class ZippedResourcePack implements ResourcePack{
|
||||
}catch(\RuntimeException $e){
|
||||
throw new ResourcePackException("Failed to parse manifest.json: " . $e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
|
||||
if(!($manifest instanceof \stdClass)){
|
||||
throw new ResourcePackException("manifest.json should contain a JSON object, not " . gettype($manifest));
|
||||
}
|
||||
if(!self::verifyManifest($manifest)){
|
||||
throw new ResourcePackException("manifest.json is missing required fields");
|
||||
}
|
||||
|
@ -26,6 +26,12 @@ namespace pocketmine\network\mcpe;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class StupidJsonDecodeTest extends TestCase{
|
||||
/** @var \Closure */
|
||||
private $stupidJsonDecodeFunc;
|
||||
|
||||
public function setUp() : void{
|
||||
$this->stupidJsonDecodeFunc = (new \ReflectionMethod(PlayerNetworkSessionAdapter::class, 'stupid_json_decode'))->getClosure();
|
||||
}
|
||||
|
||||
public function stupidJsonDecodeProvider() : array{
|
||||
return [
|
||||
@ -34,7 +40,10 @@ class StupidJsonDecodeTest extends TestCase{
|
||||
["false", false],
|
||||
["NULL", null],
|
||||
['["\",,\"word","a\",,\"word2",]', ['",,"word', 'a",,"word2', '']],
|
||||
['["\",,\"word","a\",,\"word2",""]', ['",,"word', 'a",,"word2', '']]
|
||||
['["\",,\"word","a\",,\"word2",""]', ['",,"word', 'a",,"word2', '']],
|
||||
['["Hello,, PocketMine"]', ['Hello,, PocketMine']],
|
||||
['[,]', ['', '']],
|
||||
['[]', []]
|
||||
];
|
||||
}
|
||||
|
||||
@ -47,10 +56,7 @@ class StupidJsonDecodeTest extends TestCase{
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public function testStupidJsonDecode(string $brokenJson, $expect){
|
||||
$func = new \ReflectionMethod(PlayerNetworkSessionAdapter::class, 'stupid_json_decode');
|
||||
$func->setAccessible(true);
|
||||
|
||||
$decoded = $func->invoke(null, $brokenJson, true);
|
||||
$decoded = ($this->stupidJsonDecodeFunc)($brokenJson, true);
|
||||
self::assertEquals($expect, $decoded);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user