mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-09 03:06:55 +00:00
Compare commits
25 Commits
Author | SHA1 | Date | |
---|---|---|---|
9b078854c4 | |||
1455c38dbe | |||
75df6973df | |||
4763360e9e | |||
0299191e64 | |||
4249c00c3e | |||
69c343bb9b | |||
34a899e28b | |||
b80868040e | |||
bf8a8b386e | |||
60b1f0a6e9 | |||
d4fe1b8ece | |||
9b2653fb6f | |||
ed88684e71 | |||
cbb9c4f298 | |||
660d42e8d1 | |||
1d71f5edb3 | |||
4975da2aae | |||
f704061618 | |||
23dc6e09d8 | |||
15b7fc978e | |||
bb396174ba | |||
dcef3cba21 | |||
5f8a9f8747 | |||
84e41e6967 |
12
composer.lock
generated
12
composer.lock
generated
@ -48,16 +48,16 @@
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/binaryutils",
|
||||
"version": "0.1.1",
|
||||
"version": "0.1.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/BinaryUtils.git",
|
||||
"reference": "54efeb978be0ff9335022729fe63c1e2077bf1be"
|
||||
"reference": "2c1628f08a9cdeca4d3c682e13f24420944ca845"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/54efeb978be0ff9335022729fe63c1e2077bf1be",
|
||||
"reference": "54efeb978be0ff9335022729fe63c1e2077bf1be",
|
||||
"url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/2c1628f08a9cdeca4d3c682e13f24420944ca845",
|
||||
"reference": "2c1628f08a9cdeca4d3c682e13f24420944ca845",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -75,10 +75,10 @@
|
||||
],
|
||||
"description": "Classes and methods for conveniently handling binary data",
|
||||
"support": {
|
||||
"source": "https://github.com/pmmp/BinaryUtils/tree/master",
|
||||
"source": "https://github.com/pmmp/BinaryUtils/tree/0.1.2",
|
||||
"issues": "https://github.com/pmmp/BinaryUtils/issues"
|
||||
},
|
||||
"time": "2018-08-26T18:11:05+00:00"
|
||||
"time": "2018-12-22T12:29:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/math",
|
||||
|
@ -33,6 +33,14 @@ use raklib\RakLib;
|
||||
|
||||
class CrashDump{
|
||||
|
||||
/**
|
||||
* Crashdump data format version, used by the crash archive to decide how to decode the crashdump
|
||||
* This should be incremented when backwards incompatible changes are introduced, such as fields being removed or
|
||||
* having their content changed, version format changing, etc.
|
||||
* It is not necessary to increase this when adding new fields.
|
||||
*/
|
||||
private const FORMAT_VERSION = 1;
|
||||
|
||||
/** @var Server */
|
||||
private $server;
|
||||
private $fp;
|
||||
@ -54,6 +62,7 @@ class CrashDump{
|
||||
if(!is_resource($this->fp)){
|
||||
throw new \RuntimeException("Could not create Crash Dump");
|
||||
}
|
||||
$this->data["format_version"] = self::FORMAT_VERSION;
|
||||
$this->data["time"] = $this->time;
|
||||
$this->addLine($this->server->getName() . " Crash Dump " . date("D M j H:i:s T Y", $this->time));
|
||||
$this->addLine();
|
||||
@ -150,7 +159,7 @@ class CrashDump{
|
||||
$error = $lastExceptionError;
|
||||
}else{
|
||||
$error = (array) error_get_last();
|
||||
$error["trace"] = Utils::getTrace(4); //Skipping CrashDump->baseCrash, CrashDump->construct, Server->crashDump
|
||||
$error["trace"] = Utils::printableCurrentTrace(3); //Skipping CrashDump->baseCrash, CrashDump->construct, Server->crashDump
|
||||
$errorConversion = [
|
||||
E_ERROR => "E_ERROR",
|
||||
E_WARNING => "E_WARNING",
|
||||
@ -232,10 +241,10 @@ class CrashDump{
|
||||
$version = new VersionString(\pocketmine\BASE_VERSION, \pocketmine\IS_DEVELOPMENT_BUILD, \pocketmine\BUILD_NUMBER);
|
||||
$this->data["general"] = [];
|
||||
$this->data["general"]["name"] = $this->server->getName();
|
||||
$this->data["general"]["version"] = $version->getFullVersion(false);
|
||||
$this->data["general"]["build"] = $version->getBuild();
|
||||
$this->data["general"]["base_version"] = \pocketmine\BASE_VERSION;
|
||||
$this->data["general"]["build"] = \pocketmine\BUILD_NUMBER;
|
||||
$this->data["general"]["is_dev"] = \pocketmine\IS_DEVELOPMENT_BUILD;
|
||||
$this->data["general"]["protocol"] = ProtocolInfo::CURRENT_PROTOCOL;
|
||||
$this->data["general"]["api"] = \pocketmine\BASE_VERSION;
|
||||
$this->data["general"]["git"] = \pocketmine\GIT_COMMIT;
|
||||
$this->data["general"]["raklib"] = RakLib::VERSION;
|
||||
$this->data["general"]["uname"] = php_uname("a");
|
||||
|
@ -276,7 +276,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
/** @var int */
|
||||
protected $spawnThreshold;
|
||||
/** @var int */
|
||||
protected $chunkLoadCount = 0;
|
||||
protected $spawnChunkLoadCount = 0;
|
||||
/** @var int */
|
||||
protected $chunksPerTick;
|
||||
|
||||
@ -962,8 +962,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
}
|
||||
|
||||
$this->usedChunks[Level::chunkHash($x, $z)] = true;
|
||||
$this->chunkLoadCount++;
|
||||
|
||||
$this->dataPacket($payload);
|
||||
|
||||
if($this->spawned){
|
||||
@ -974,8 +972,9 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
}
|
||||
}
|
||||
|
||||
if($this->chunkLoadCount >= $this->spawnThreshold and !$this->spawned){
|
||||
$this->doFirstSpawn();
|
||||
if($this->spawnChunkLoadCount !== -1 and ++$this->spawnChunkLoadCount >= $this->spawnThreshold){
|
||||
$this->sendPlayStatus(PlayStatusPacket::PLAYER_SPAWN);
|
||||
$this->spawnChunkLoadCount = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1013,11 +1012,12 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
Timings::$playerChunkSendTimer->stopTiming();
|
||||
}
|
||||
|
||||
protected function doFirstSpawn(){
|
||||
public function doFirstSpawn(){
|
||||
if($this->spawned){
|
||||
return; //avoid player spawning twice (this can only happen on 3.x with a custom malicious client)
|
||||
}
|
||||
$this->spawned = true;
|
||||
|
||||
$this->sendPlayStatus(PlayStatusPacket::PLAYER_SPAWN);
|
||||
|
||||
if($this->hasPermission(Server::BROADCAST_CHANNEL_USERS)){
|
||||
PermissionManager::getInstance()->subscribeToPermission(Server::BROADCAST_CHANNEL_USERS, $this);
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ namespace pocketmine {
|
||||
use pocketmine\wizard\SetupWizard;
|
||||
|
||||
const NAME = "PocketMine-MP";
|
||||
const BASE_VERSION = "3.4.0";
|
||||
const BASE_VERSION = "3.4.3";
|
||||
const IS_DEVELOPMENT_BUILD = false;
|
||||
const BUILD_NUMBER = 0;
|
||||
|
||||
|
@ -2173,7 +2173,7 @@ class Server{
|
||||
"fullFile" => $e->getFile(),
|
||||
"file" => $errfile,
|
||||
"line" => $errline,
|
||||
"trace" => Utils::getTrace(0, $trace)
|
||||
"trace" => Utils::printableTrace($trace)
|
||||
];
|
||||
|
||||
global $lastExceptionError, $lastError;
|
||||
|
@ -29,6 +29,7 @@ use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\level\particle\AngryVillagerParticle;
|
||||
use pocketmine\level\particle\BlockForceFieldParticle;
|
||||
use pocketmine\level\particle\BubbleParticle;
|
||||
@ -84,14 +85,18 @@ class ParticleCommand extends VanillaCommand{
|
||||
|
||||
if($sender instanceof Player){
|
||||
$level = $sender->getLevel();
|
||||
$pos = new Vector3(
|
||||
$this->getRelativeDouble($sender->getX(), $sender, $args[1]),
|
||||
$this->getRelativeDouble($sender->getY(), $sender, $args[2], 0, Level::Y_MAX),
|
||||
$this->getRelativeDouble($sender->getZ(), $sender, $args[3])
|
||||
);
|
||||
}else{
|
||||
$level = $sender->getServer()->getDefaultLevel();
|
||||
$pos = new Vector3((float) $args[1], (float) $args[2], (float) $args[3]);
|
||||
}
|
||||
|
||||
$name = strtolower($args[0]);
|
||||
|
||||
$pos = new Vector3((float) $args[1], (float) $args[2], (float) $args[3]);
|
||||
|
||||
$xd = (float) $args[4];
|
||||
$yd = (float) $args[5];
|
||||
$zd = (float) $args[6];
|
||||
|
@ -171,7 +171,7 @@ class Attribute{
|
||||
}
|
||||
|
||||
public function resetToDefault() : void{
|
||||
$this->setValue($this->getDefaultValue());
|
||||
$this->setValue($this->getDefaultValue(), true);
|
||||
}
|
||||
|
||||
public function getValue() : float{
|
||||
|
@ -637,6 +637,9 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
||||
* @param float $value
|
||||
*/
|
||||
public function setScale(float $value) : void{
|
||||
if($value <= 0){
|
||||
throw new \InvalidArgumentException("Scale must be greater than 0");
|
||||
}
|
||||
$multiplier = $value / $this->getScale();
|
||||
|
||||
$this->width *= $multiplier;
|
||||
|
@ -571,7 +571,10 @@ abstract class Living extends Entity implements Damageable{
|
||||
}
|
||||
|
||||
if($e !== null){
|
||||
if($e->isOnFire()){
|
||||
if((
|
||||
$source->getCause() === EntityDamageEvent::CAUSE_PROJECTILE or
|
||||
$source->getCause() === EntityDamageEvent::CAUSE_ENTITY_ATTACK
|
||||
) and $e->isOnFire()){
|
||||
$this->setOnFire(2 * $this->level->getDifficulty());
|
||||
}
|
||||
|
||||
|
@ -450,13 +450,14 @@ class Level implements ChunkManager, Metadatable{
|
||||
if(!is_array($pk)){
|
||||
$pk = [$pk];
|
||||
}
|
||||
|
||||
if($players === null){
|
||||
foreach($pk as $e){
|
||||
$this->broadcastPacketToViewers($sound, $e);
|
||||
if(!empty($pk)){
|
||||
if($players === null){
|
||||
foreach($pk as $e){
|
||||
$this->broadcastPacketToViewers($sound, $e);
|
||||
}
|
||||
}else{
|
||||
$this->server->batchPackets($players, $pk, false);
|
||||
}
|
||||
}else{
|
||||
$this->server->batchPackets($players, $pk, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -465,13 +466,14 @@ class Level implements ChunkManager, Metadatable{
|
||||
if(!is_array($pk)){
|
||||
$pk = [$pk];
|
||||
}
|
||||
|
||||
if($players === null){
|
||||
foreach($pk as $e){
|
||||
$this->broadcastPacketToViewers($particle, $e);
|
||||
if(!empty($pk)){
|
||||
if($players === null){
|
||||
foreach($pk as $e){
|
||||
$this->broadcastPacketToViewers($particle, $e);
|
||||
}
|
||||
}else{
|
||||
$this->server->batchPackets($players, $pk, false);
|
||||
}
|
||||
}else{
|
||||
$this->server->batchPackets($players, $pk, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2438,7 +2440,7 @@ class Level implements ChunkManager, Metadatable{
|
||||
|
||||
$chunkHash = Level::chunkHash($chunkX, $chunkZ);
|
||||
$oldChunk = $this->getChunk($chunkX, $chunkZ, false);
|
||||
if($oldChunk !== null){
|
||||
if($oldChunk !== null and $oldChunk !== $chunk){
|
||||
if($unload){
|
||||
$this->unloadChunk($chunkX, $chunkZ, false, false);
|
||||
}else{
|
||||
@ -2460,6 +2462,10 @@ class Level implements ChunkManager, Metadatable{
|
||||
unset($this->blockCache[$chunkHash]);
|
||||
unset($this->chunkCache[$chunkHash]);
|
||||
unset($this->changedBlocks[$chunkHash]);
|
||||
if(isset($this->chunkSendTasks[$chunkHash])){ //invalidate pending caches
|
||||
$this->chunkSendTasks[$chunkHash]->cancelRun();
|
||||
unset($this->chunkSendTasks[$chunkHash]);
|
||||
}
|
||||
$chunk->setChanged();
|
||||
|
||||
if(!$this->isChunkInUse($chunkX, $chunkZ)){
|
||||
|
@ -283,6 +283,11 @@ class LevelDB extends BaseLevelProvider{
|
||||
/** @var SubChunk[] $subChunks */
|
||||
$subChunks = [];
|
||||
|
||||
/** @var int[] $heightMap */
|
||||
$heightMap = [];
|
||||
/** @var string $biomeIds */
|
||||
$biomeIds = "";
|
||||
|
||||
/** @var bool $lightPopulated */
|
||||
$lightPopulated = true;
|
||||
|
||||
@ -325,10 +330,12 @@ class LevelDB extends BaseLevelProvider{
|
||||
}
|
||||
}
|
||||
|
||||
$binaryStream->setBuffer($this->db->get($index . self::TAG_DATA_2D), 0);
|
||||
if(($maps2d = $this->db->get($index . self::TAG_DATA_2D)) !== false){
|
||||
$binaryStream->setBuffer($maps2d, 0);
|
||||
|
||||
$heightMap = array_values(unpack("v*", $binaryStream->get(512)));
|
||||
$biomeIds = $binaryStream->get(256);
|
||||
$heightMap = array_values(unpack("v*", $binaryStream->get(512)));
|
||||
$biomeIds = $binaryStream->get(256);
|
||||
}
|
||||
break;
|
||||
case 2: // < MCPE 1.0
|
||||
$binaryStream->setBuffer($this->db->get($index . self::TAG_LEGACY_TERRAIN));
|
||||
|
@ -33,10 +33,8 @@ abstract class Tree{
|
||||
public $overridable = [
|
||||
Block::AIR => true,
|
||||
Block::SAPLING => true,
|
||||
Block::LOG => true,
|
||||
Block::LEAVES => true,
|
||||
Block::SNOW_LAYER => true,
|
||||
Block::LOG2 => true,
|
||||
Block::LEAVES2 => true
|
||||
];
|
||||
|
||||
|
@ -58,6 +58,7 @@ use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket;
|
||||
use pocketmine\network\mcpe\protocol\ResourcePackChunkRequestPacket;
|
||||
use pocketmine\network\mcpe\protocol\ResourcePackClientResponsePacket;
|
||||
use pocketmine\network\mcpe\protocol\ServerSettingsRequestPacket;
|
||||
use pocketmine\network\mcpe\protocol\SetLocalPlayerAsInitializedPacket;
|
||||
use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket;
|
||||
use pocketmine\network\mcpe\protocol\ShowCreditsPacket;
|
||||
use pocketmine\network\mcpe\protocol\SpawnExperienceOrbPacket;
|
||||
@ -280,4 +281,9 @@ class PlayerNetworkSessionAdapter extends NetworkSession{
|
||||
public function handleServerSettingsRequest(ServerSettingsRequestPacket $packet) : bool{
|
||||
return false; //TODO: GUI stuff
|
||||
}
|
||||
|
||||
public function handleSetLocalPlayerAsInitialized(SetLocalPlayerAsInitializedPacket $packet) : bool{
|
||||
$this->player->doFirstSpawn();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -139,10 +139,10 @@ abstract class DataPacket extends NetworkBinaryStream{
|
||||
}
|
||||
|
||||
public function __get($name){
|
||||
throw new \Error("Cannot read non-existing field \"$name\"");
|
||||
throw new \Error("Undefined property: " . get_class($this) . "::\$" . $name);
|
||||
}
|
||||
|
||||
public function __set($name, $value){
|
||||
throw new \Error("Cannot write non-existing field \"$name\"");
|
||||
throw new \Error("Undefined property: " . get_class($this) . "::\$" . $name);
|
||||
}
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ class LoginPacket extends DataPacket{
|
||||
|
||||
$logger = MainLogger::getLogger();
|
||||
$logger->debug(get_class($e) . " was thrown while decoding connection request in login (protocol version " . ($this->protocol ?? "unknown") . "): " . $e->getMessage());
|
||||
foreach(Utils::getTrace(0, $e->getTrace()) as $line){
|
||||
foreach(Utils::printableTrace($e->getTrace()) as $line){
|
||||
$logger->debug($line);
|
||||
}
|
||||
}
|
||||
|
@ -118,6 +118,8 @@ class NetworkInventoryAction{
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new \UnexpectedValueException("Unknown inventory action source type $this->sourceType");
|
||||
}
|
||||
|
||||
$this->inventorySlot = $packet->getUnsignedVarInt();
|
||||
@ -145,6 +147,8 @@ class NetworkInventoryAction{
|
||||
case self::SOURCE_TODO:
|
||||
$packet->putVarInt($this->windowId);
|
||||
break;
|
||||
default:
|
||||
throw new \UnexpectedValueException("Unknown inventory action source type $this->sourceType");
|
||||
}
|
||||
|
||||
$packet->putUnsignedVarInt($this->inventorySlot);
|
||||
|
@ -210,7 +210,7 @@ class MainLogger extends \AttachableThreadedLogger{
|
||||
$errfile = Utils::cleanPath($errfile);
|
||||
|
||||
$message = get_class($e) . ": \"$errstr\" ($errno) in \"$errfile\" at line $errline";
|
||||
$stack = Utils::getTrace(0, $trace);
|
||||
$stack = Utils::printableTrace($trace);
|
||||
|
||||
$this->synchronized(function() use ($type, $message, $stack) : void{
|
||||
$this->log($type, $message);
|
||||
|
@ -313,8 +313,8 @@ class Utils{
|
||||
++$processors;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if(preg_match("/^([0-9]+)\\-([0-9]+)$/", trim(@file_get_contents("/sys/devices/system/cpu/present")), $matches) > 0){
|
||||
}elseif(is_readable("/sys/devices/system/cpu/present")){
|
||||
if(preg_match("/^([0-9]+)\\-([0-9]+)$/", trim(file_get_contents("/sys/devices/system/cpu/present")), $matches) > 0){
|
||||
$processors = (int) ($matches[2] - $matches[1]);
|
||||
}
|
||||
}
|
||||
@ -525,24 +525,13 @@ class Utils{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $start
|
||||
* @param array|null $trace
|
||||
* @param array $trace
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getTrace($start = 0, $trace = null){
|
||||
if($trace === null){
|
||||
if(function_exists("xdebug_get_function_stack")){
|
||||
$trace = array_reverse(xdebug_get_function_stack());
|
||||
}else{
|
||||
$e = new \Exception();
|
||||
$trace = $e->getTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static function printableTrace(array $trace) : array{
|
||||
$messages = [];
|
||||
$j = 0;
|
||||
for($i = (int) $start; isset($trace[$i]); ++$i, ++$j){
|
||||
for($i = 0; isset($trace[$i]); ++$i){
|
||||
$params = "";
|
||||
if(isset($trace[$i]["args"]) or isset($trace[$i]["params"])){
|
||||
if(isset($trace[$i]["args"])){
|
||||
@ -555,12 +544,39 @@ class Utils{
|
||||
return (is_object($value) ? get_class($value) . " object" : gettype($value) . " " . (is_array($value) ? "Array()" : Utils::printable(@strval($value))));
|
||||
}, $args));
|
||||
}
|
||||
$messages[] = "#$j " . (isset($trace[$i]["file"]) ? self::cleanPath($trace[$i]["file"]) : "") . "(" . (isset($trace[$i]["line"]) ? $trace[$i]["line"] : "") . "): " . (isset($trace[$i]["class"]) ? $trace[$i]["class"] . (($trace[$i]["type"] === "dynamic" or $trace[$i]["type"] === "->") ? "->" : "::") : "") . $trace[$i]["function"] . "(" . Utils::printable($params) . ")";
|
||||
$messages[] = "#$i " . (isset($trace[$i]["file"]) ? self::cleanPath($trace[$i]["file"]) : "") . "(" . (isset($trace[$i]["line"]) ? $trace[$i]["line"] : "") . "): " . (isset($trace[$i]["class"]) ? $trace[$i]["class"] . (($trace[$i]["type"] === "dynamic" or $trace[$i]["type"] === "->") ? "->" : "::") : "") . $trace[$i]["function"] . "(" . Utils::printable($params) . ")";
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $skipFrames
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function currentTrace(int $skipFrames = 0) : array{
|
||||
++$skipFrames; //omit this frame from trace, in addition to other skipped frames
|
||||
if(function_exists("xdebug_get_function_stack")){
|
||||
$trace = array_reverse(xdebug_get_function_stack());
|
||||
}else{
|
||||
$e = new \Exception();
|
||||
$trace = $e->getTrace();
|
||||
}
|
||||
for($i = 0; $i < $skipFrames; ++$i){
|
||||
unset($trace[$i]);
|
||||
}
|
||||
return array_values($trace);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $skipFrames
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function printableCurrentTrace(int $skipFrames = 0) : array{
|
||||
return self::printableTrace(self::currentTrace(++$skipFrames));
|
||||
}
|
||||
|
||||
public static function cleanPath($path){
|
||||
return str_replace(["\\", ".php", "phar://", str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PATH), str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PLUGIN_PATH)], ["/", "", "", "", ""], $path);
|
||||
}
|
||||
|
Submodule tests/plugins/PocketMine-DevTools updated: 638e44519a...3f14ab5bb7
Reference in New Issue
Block a user