mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-06-28 14:19:53 +00:00
Merge branch 'api3/network' into api3/network_mcpe-1.0.5
This commit is contained in:
commit
bb79684480
@ -112,7 +112,6 @@ use pocketmine\network\mcpe\protocol\AddPlayerPacket;
|
|||||||
use pocketmine\network\mcpe\protocol\AdventureSettingsPacket;
|
use pocketmine\network\mcpe\protocol\AdventureSettingsPacket;
|
||||||
use pocketmine\network\mcpe\protocol\AnimatePacket;
|
use pocketmine\network\mcpe\protocol\AnimatePacket;
|
||||||
use pocketmine\network\mcpe\protocol\AvailableCommandsPacket;
|
use pocketmine\network\mcpe\protocol\AvailableCommandsPacket;
|
||||||
use pocketmine\network\mcpe\protocol\BatchPacket;
|
|
||||||
use pocketmine\network\mcpe\protocol\BlockEntityDataPacket;
|
use pocketmine\network\mcpe\protocol\BlockEntityDataPacket;
|
||||||
use pocketmine\network\mcpe\protocol\BlockEventPacket;
|
use pocketmine\network\mcpe\protocol\BlockEventPacket;
|
||||||
use pocketmine\network\mcpe\protocol\BlockPickRequestPacket;
|
use pocketmine\network\mcpe\protocol\BlockPickRequestPacket;
|
||||||
@ -1955,11 +1954,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handleBatch(BatchPacket $packet) : bool{
|
|
||||||
$this->server->getNetwork()->processBatch($packet, $this);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function handleResourcePacksInfo(ResourcePacksInfoPacket $packet) : bool{
|
public function handleResourcePacksInfo(ResourcePacksInfoPacket $packet) : bool{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2237,6 +2231,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||||||
$item = $this->inventory->getItem($packet->inventorySlot);
|
$item = $this->inventory->getItem($packet->inventorySlot);
|
||||||
|
|
||||||
if(!$item->equals($packet->item)){
|
if(!$item->equals($packet->item)){
|
||||||
|
$this->server->getLogger()->debug("Tried to equip " . $packet->item . " but have " . $item . " in target slot");
|
||||||
$this->inventory->sendContents($this);
|
$this->inventory->sendContents($this);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -3317,6 +3312,9 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||||||
$timings = Timings::getReceiveDataPacketTimings($packet);
|
$timings = Timings::getReceiveDataPacketTimings($packet);
|
||||||
$timings->startTiming();
|
$timings->startTiming();
|
||||||
|
|
||||||
|
$packet->decode();
|
||||||
|
assert($packet->feof(), "Still " . strlen(substr($packet->buffer, $packet->offset)) . " bytes unread in " . get_class($packet));
|
||||||
|
|
||||||
$this->server->getPluginManager()->callEvent($ev = new DataPacketReceiveEvent($this, $packet));
|
$this->server->getPluginManager()->callEvent($ev = new DataPacketReceiveEvent($this, $packet));
|
||||||
if(!$ev->isCancelled() and !$packet->handle($this)){
|
if(!$ev->isCancelled() and !$packet->handle($this)){
|
||||||
$this->server->getLogger()->debug("Unhandled " . get_class($packet) . " received from " . $this->getName());
|
$this->server->getLogger()->debug("Unhandled " . get_class($packet) . " received from " . $this->getName());
|
||||||
@ -3580,6 +3578,13 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||||||
return $this->username;
|
return $this->username;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getLowerCaseName() : string{
|
||||||
|
return $this->iusername;
|
||||||
|
}
|
||||||
|
|
||||||
public function kill(){
|
public function kill(){
|
||||||
if(!$this->spawned){
|
if(!$this->spawned){
|
||||||
return;
|
return;
|
||||||
|
@ -158,6 +158,9 @@ class Server{
|
|||||||
private $currentTPS = 20;
|
private $currentTPS = 20;
|
||||||
private $currentUse = 0;
|
private $currentUse = 0;
|
||||||
|
|
||||||
|
/** @var bool */
|
||||||
|
private $doTitleTick = true;
|
||||||
|
|
||||||
private $sendUsageTicker = 0;
|
private $sendUsageTicker = 0;
|
||||||
|
|
||||||
private $dispatchSignals = false;
|
private $dispatchSignals = false;
|
||||||
@ -817,7 +820,7 @@ class Server{
|
|||||||
public function getPlayerExact($name){
|
public function getPlayerExact($name){
|
||||||
$name = strtolower($name);
|
$name = strtolower($name);
|
||||||
foreach($this->getOnlinePlayers() as $player){
|
foreach($this->getOnlinePlayers() as $player){
|
||||||
if(strtolower($player->getName()) === $name){
|
if($player->getLowerCaseName() === $name){
|
||||||
return $player;
|
return $player;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -834,7 +837,7 @@ class Server{
|
|||||||
$partialName = strtolower($partialName);
|
$partialName = strtolower($partialName);
|
||||||
$matchedPlayers = [];
|
$matchedPlayers = [];
|
||||||
foreach($this->getOnlinePlayers() as $player){
|
foreach($this->getOnlinePlayers() as $player){
|
||||||
if(strtolower($player->getName()) === $partialName){
|
if($player->getLowerCaseName() === $partialName){
|
||||||
$matchedPlayers = [$player];
|
$matchedPlayers = [$player];
|
||||||
break;
|
break;
|
||||||
}elseif(stripos($player->getName(), $partialName) !== false){
|
}elseif(stripos($player->getName(), $partialName) !== false){
|
||||||
@ -1466,6 +1469,8 @@ class Server{
|
|||||||
$this->alwaysTickPlayers = (int) $this->getProperty("level-settings.always-tick-players", false);
|
$this->alwaysTickPlayers = (int) $this->getProperty("level-settings.always-tick-players", false);
|
||||||
$this->baseTickRate = (int) $this->getProperty("level-settings.base-tick-rate", 1);
|
$this->baseTickRate = (int) $this->getProperty("level-settings.base-tick-rate", 1);
|
||||||
|
|
||||||
|
$this->doTitleTick = (bool) $this->getProperty("console.title-tick", true);
|
||||||
|
|
||||||
$this->scheduler = new ServerScheduler();
|
$this->scheduler = new ServerScheduler();
|
||||||
|
|
||||||
if($this->getConfigBoolean("enable-rcon", false) === true){
|
if($this->getConfigBoolean("enable-rcon", false) === true){
|
||||||
@ -1546,7 +1551,7 @@ class Server{
|
|||||||
Attribute::init();
|
Attribute::init();
|
||||||
$this->craftingManager = new CraftingManager();
|
$this->craftingManager = new CraftingManager();
|
||||||
|
|
||||||
$this->resourceManager = new ResourcePackManager($this, \pocketmine\PATH . "resource_packs" . DIRECTORY_SEPARATOR);
|
$this->resourceManager = new ResourcePackManager($this, $this->getDataPath() . "resource_packs" . DIRECTORY_SEPARATOR);
|
||||||
|
|
||||||
$this->pluginManager = new PluginManager($this, $this->commandMap);
|
$this->pluginManager = new PluginManager($this, $this->commandMap);
|
||||||
$this->pluginManager->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this->consoleSender);
|
$this->pluginManager->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this->consoleSender);
|
||||||
@ -2262,7 +2267,9 @@ class Server{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function sendUsage($type = SendUsageTask::TYPE_STATUS){
|
public function sendUsage($type = SendUsageTask::TYPE_STATUS){
|
||||||
$this->scheduler->scheduleAsyncTask(new SendUsageTask($this, $type, $this->uniquePlayers));
|
if($this->getProperty("anonymous-statistics.enabled", true)){
|
||||||
|
$this->scheduler->scheduleAsyncTask(new SendUsageTask($this, $type, $this->uniquePlayers));
|
||||||
|
}
|
||||||
$this->uniquePlayers = [];
|
$this->uniquePlayers = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2296,10 +2303,6 @@ class Server{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private function titleTick(){
|
private function titleTick(){
|
||||||
if(!Terminal::hasFormattingCodes()){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$d = Utils::getRealMemoryUsage();
|
$d = Utils::getRealMemoryUsage();
|
||||||
|
|
||||||
$u = Utils::getMemoryUsage(true);
|
$u = Utils::getMemoryUsage(true);
|
||||||
@ -2375,7 +2378,9 @@ class Server{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(($this->tickCounter & 0b1111) === 0){
|
if(($this->tickCounter & 0b1111) === 0){
|
||||||
$this->titleTick();
|
if($this->doTitleTick and Terminal::hasFormattingCodes()){
|
||||||
|
$this->titleTick();
|
||||||
|
}
|
||||||
$this->currentTPS = 20;
|
$this->currentTPS = 20;
|
||||||
$this->currentUse = 0;
|
$this->currentUse = 0;
|
||||||
|
|
||||||
@ -2440,4 +2445,13 @@ class Server{
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when something attempts to serialize the server instance.
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException because Server instances cannot be serialized
|
||||||
|
*/
|
||||||
|
public function __sleep(){
|
||||||
|
throw new \BadMethodCallException("Cannot serialize Server instance");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
|
|
||||||
class GlowingObsidian extends Transparent{
|
class GlowingObsidian extends Solid{
|
||||||
|
|
||||||
protected $id = self::GLOWING_OBSIDIAN;
|
protected $id = self::GLOWING_OBSIDIAN;
|
||||||
|
|
||||||
|
@ -32,4 +32,8 @@ class RedstoneTorch extends Torch{
|
|||||||
public function getName(){
|
public function getName(){
|
||||||
return "Redstone Torch";
|
return "Redstone Torch";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getLightLevel(){
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ class Torch extends Flowable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function getLightLevel(){
|
public function getLightLevel(){
|
||||||
return 15;
|
return 14;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getName(){
|
public function getName(){
|
||||||
|
@ -136,7 +136,7 @@ class SimpleCommandMap implements CommandMap{
|
|||||||
if($label === null){
|
if($label === null){
|
||||||
$label = $command->getName();
|
$label = $command->getName();
|
||||||
}
|
}
|
||||||
$label = strtolower(trim($label));
|
$label = trim($label);
|
||||||
$fallbackPrefix = strtolower(trim($fallbackPrefix));
|
$fallbackPrefix = strtolower(trim($fallbackPrefix));
|
||||||
|
|
||||||
$registered = $this->registerAlias($command, false, $fallbackPrefix, $label);
|
$registered = $this->registerAlias($command, false, $fallbackPrefix, $label);
|
||||||
@ -188,7 +188,7 @@ class SimpleCommandMap implements CommandMap{
|
|||||||
* @return Command|null
|
* @return Command|null
|
||||||
*/
|
*/
|
||||||
public function matchCommand(string &$commandName, array &$args){
|
public function matchCommand(string &$commandName, array &$args){
|
||||||
$count = max(count($args), 255);
|
$count = min(count($args), 255);
|
||||||
|
|
||||||
for($i = 0; $i < $count; ++$i){
|
for($i = 0; $i < $count; ++$i){
|
||||||
$commandName .= array_shift($args);
|
$commandName .= array_shift($args);
|
||||||
|
@ -443,7 +443,9 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
|||||||
$slotCount = $this->inventory->getSize() + $this->inventory->getHotbarSize();
|
$slotCount = $this->inventory->getSize() + $this->inventory->getHotbarSize();
|
||||||
for($slot = $this->inventory->getHotbarSize(); $slot < $slotCount; ++$slot){
|
for($slot = $this->inventory->getHotbarSize(); $slot < $slotCount; ++$slot){
|
||||||
$item = $this->inventory->getItem($slot - 9);
|
$item = $this->inventory->getItem($slot - 9);
|
||||||
$this->namedtag->Inventory[$slot] = $item->nbtSerialize($slot);
|
if($item->getId() !== ItemItem::AIR){
|
||||||
|
$this->namedtag->Inventory[$slot] = $item->nbtSerialize($slot);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Armor
|
//Armor
|
||||||
|
@ -25,6 +25,13 @@ use pocketmine\level\Level;
|
|||||||
|
|
||||||
class LevelTimings{
|
class LevelTimings{
|
||||||
|
|
||||||
|
/** @var TimingsHandler */
|
||||||
|
public $setBlock;
|
||||||
|
/** @var TimingsHandler */
|
||||||
|
public $doBlockLightUpdates;
|
||||||
|
/** @var TimingsHandler */
|
||||||
|
public $doBlockSkyLightUpdates;
|
||||||
|
|
||||||
/** @var TimingsHandler */
|
/** @var TimingsHandler */
|
||||||
public $mobSpawn;
|
public $mobSpawn;
|
||||||
/** @var TimingsHandler */
|
/** @var TimingsHandler */
|
||||||
@ -79,6 +86,10 @@ class LevelTimings{
|
|||||||
public function __construct(Level $level){
|
public function __construct(Level $level){
|
||||||
$name = $level->getFolderName() . " - ";
|
$name = $level->getFolderName() . " - ";
|
||||||
|
|
||||||
|
$this->setBlock = new TimingsHandler("** " . $name . "setBlock");
|
||||||
|
$this->doBlockLightUpdates = new TimingsHandler("** " . $name . "doBlockLightUpdates");
|
||||||
|
$this->doBlockSkyLightUpdates = new TimingsHandler("** " . $name . "doBlockSkyLightUpdates");
|
||||||
|
|
||||||
$this->mobSpawn = new TimingsHandler("** " . $name . "mobSpawn");
|
$this->mobSpawn = new TimingsHandler("** " . $name . "mobSpawn");
|
||||||
$this->doChunkUnload = new TimingsHandler("** " . $name . "doChunkUnload");
|
$this->doChunkUnload = new TimingsHandler("** " . $name . "doChunkUnload");
|
||||||
$this->doTickPending = new TimingsHandler("** " . $name . "doTickPending");
|
$this->doTickPending = new TimingsHandler("** " . $name . "doTickPending");
|
||||||
|
@ -65,13 +65,19 @@ class Item implements ItemIds, \JsonSerializable{
|
|||||||
|
|
||||||
/** @var \SplFixedArray */
|
/** @var \SplFixedArray */
|
||||||
public static $list = null;
|
public static $list = null;
|
||||||
|
/** @var Block|null */
|
||||||
protected $block;
|
protected $block;
|
||||||
|
/** @var int */
|
||||||
protected $id;
|
protected $id;
|
||||||
|
/** @var int */
|
||||||
protected $meta;
|
protected $meta;
|
||||||
|
/** @var string */
|
||||||
private $tags = "";
|
private $tags = "";
|
||||||
|
/** @var CompoundTag|null */
|
||||||
private $cachedNBT = null;
|
private $cachedNBT = null;
|
||||||
|
/** @var int */
|
||||||
public $count;
|
public $count;
|
||||||
protected $durability = 0;
|
/** @var string */
|
||||||
protected $name;
|
protected $name;
|
||||||
|
|
||||||
public function canBeActivated(){
|
public function canBeActivated(){
|
||||||
@ -1007,4 +1013,12 @@ class Item implements ItemIds, \JsonSerializable{
|
|||||||
return $item;
|
return $item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function __clone(){
|
||||||
|
if($this->block !== null){
|
||||||
|
$this->block = clone $this->block;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->cachedNBT = null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -37,10 +37,6 @@ class ItemBlock extends Item{
|
|||||||
$this->block->setDamage($this->meta !== -1 ? $this->meta : 0);
|
$this->block->setDamage($this->meta !== -1 ? $this->meta : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __clone(){
|
|
||||||
$this->block = clone $this->block;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getBlock() : Block{
|
public function getBlock() : Block{
|
||||||
return $this->block;
|
return $this->block;
|
||||||
}
|
}
|
||||||
|
@ -1254,17 +1254,42 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function updateBlockSkyLight(int $x, int $y, int $z){
|
public function updateBlockSkyLight(int $x, int $y, int $z){
|
||||||
|
$this->timings->doBlockSkyLightUpdates->startTiming();
|
||||||
//TODO
|
//TODO
|
||||||
|
$this->timings->doBlockSkyLightUpdates->stopTiming();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the highest light level available in the positions adjacent to the specified block coordinates.
|
||||||
|
*
|
||||||
|
* @param int $x
|
||||||
|
* @param int $y
|
||||||
|
* @param int $z
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getHighestAdjacentBlockLight(int $x, int $y, int $z) : int{
|
||||||
|
return max([
|
||||||
|
$this->getBlockLightAt($x + 1, $y, $z),
|
||||||
|
$this->getBlockLightAt($x - 1, $y, $z),
|
||||||
|
$this->getBlockLightAt($x, $y + 1, $z),
|
||||||
|
$this->getBlockLightAt($x, $y - 1, $z),
|
||||||
|
$this->getBlockLightAt($x, $y, $z + 1),
|
||||||
|
$this->getBlockLightAt($x, $y, $z - 1)
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateBlockLight(int $x, int $y, int $z){
|
public function updateBlockLight(int $x, int $y, int $z){
|
||||||
|
$this->timings->doBlockLightUpdates->startTiming();
|
||||||
|
|
||||||
$lightPropagationQueue = new \SplQueue();
|
$lightPropagationQueue = new \SplQueue();
|
||||||
$lightRemovalQueue = new \SplQueue();
|
$lightRemovalQueue = new \SplQueue();
|
||||||
$visited = [];
|
$visited = [];
|
||||||
$removalVisited = [];
|
$removalVisited = [];
|
||||||
|
|
||||||
|
$id = $this->getBlockIdAt($x, $y, $z);
|
||||||
$oldLevel = $this->getBlockLightAt($x, $y, $z);
|
$oldLevel = $this->getBlockLightAt($x, $y, $z);
|
||||||
$newLevel = (int) Block::$light[$this->getBlockIdAt($x, $y, $z)];
|
$newLevel = max(Block::$light[$id], $this->getHighestAdjacentBlockLight($x, $y, $z) - Block::$lightFilter[$id]);
|
||||||
|
|
||||||
if($oldLevel !== $newLevel){
|
if($oldLevel !== $newLevel){
|
||||||
$this->setBlockLightAt($x, $y, $z, $newLevel);
|
$this->setBlockLightAt($x, $y, $z, $newLevel);
|
||||||
@ -1296,7 +1321,7 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
/** @var Vector3 $node */
|
/** @var Vector3 $node */
|
||||||
$node = $lightPropagationQueue->dequeue();
|
$node = $lightPropagationQueue->dequeue();
|
||||||
|
|
||||||
$lightLevel = $this->getBlockLightAt($node->x, $node->y, $node->z) - (int) Block::$lightFilter[$this->getBlockIdAt($node->x, $node->y, $node->z)];
|
$lightLevel = $this->getBlockLightAt($node->x, $node->y, $node->z);
|
||||||
|
|
||||||
if($lightLevel >= 1){
|
if($lightLevel >= 1){
|
||||||
$this->computeSpreadBlockLight($node->x - 1, $node->y, $node->z, $lightLevel, $lightPropagationQueue, $visited);
|
$this->computeSpreadBlockLight($node->x - 1, $node->y, $node->z, $lightLevel, $lightPropagationQueue, $visited);
|
||||||
@ -1307,6 +1332,8 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
$this->computeSpreadBlockLight($node->x, $node->y, $node->z + 1, $lightLevel, $lightPropagationQueue, $visited);
|
$this->computeSpreadBlockLight($node->x, $node->y, $node->z + 1, $lightLevel, $lightPropagationQueue, $visited);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->timings->doBlockLightUpdates->stopTiming();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function computeRemoveBlockLight(int $x, int $y, int $z, int $currentLight, \SplQueue $queue, \SplQueue $spreadQueue, array &$visited, array &$spreadVisited){
|
private function computeRemoveBlockLight(int $x, int $y, int $z, int $currentLight, \SplQueue $queue, \SplQueue $spreadQueue, array &$visited, array &$spreadVisited){
|
||||||
@ -1333,6 +1360,7 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
private function computeSpreadBlockLight(int $x, int $y, int $z, int $currentLight, \SplQueue $queue, array &$visited){
|
private function computeSpreadBlockLight(int $x, int $y, int $z, int $currentLight, \SplQueue $queue, array &$visited){
|
||||||
if($y < 0) return;
|
if($y < 0) return;
|
||||||
$current = $this->getBlockLightAt($x, $y, $z);
|
$current = $this->getBlockLightAt($x, $y, $z);
|
||||||
|
$currentLight -= Block::$lightFilter[$this->getBlockIdAt($x, $y, $z)];
|
||||||
|
|
||||||
if($current < $currentLight){
|
if($current < $currentLight){
|
||||||
$this->setBlockLightAt($x, $y, $z, $currentLight);
|
$this->setBlockLightAt($x, $y, $z, $currentLight);
|
||||||
@ -1370,6 +1398,8 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->timings->setBlock->startTiming();
|
||||||
|
|
||||||
if($this->getChunk($pos->x >> 4, $pos->z >> 4, true)->setBlock($pos->x & 0x0f, $pos->y & Level::Y_MASK, $pos->z & 0x0f, $block->getId(), $block->getDamage())){
|
if($this->getChunk($pos->x >> 4, $pos->z >> 4, true)->setBlock($pos->x & 0x0f, $pos->y & Level::Y_MASK, $pos->z & 0x0f, $block->getId(), $block->getDamage())){
|
||||||
if(!($pos instanceof Position)){
|
if(!($pos instanceof Position)){
|
||||||
$pos = $this->temporalPosition->setComponents($pos->x, $pos->y, $pos->z);
|
$pos = $this->temporalPosition->setComponents($pos->x, $pos->y, $pos->z);
|
||||||
@ -1409,9 +1439,13 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
$this->updateAround($pos);
|
$this->updateAround($pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->timings->setBlock->stopTiming();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->timings->setBlock->stopTiming();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1476,7 +1510,7 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
|
|
||||||
if(($player->isSurvival() and $item instanceof Item and !$target->isBreakable($item)) or $player->isSpectator()){
|
if(($player->isSurvival() and $item instanceof Item and !$target->isBreakable($item)) or $player->isSpectator()){
|
||||||
$ev->setCancelled();
|
$ev->setCancelled();
|
||||||
}elseif(!$player->isOp() and ($distance = $this->server->getSpawnRadius()) > -1){
|
}elseif(!$player->hasPermission("pocketmine.spawnprotect.bypass") and ($distance = $this->server->getSpawnRadius()) > -1){
|
||||||
$t = new Vector2($target->x, $target->z);
|
$t = new Vector2($target->x, $target->z);
|
||||||
$s = new Vector2($this->getSpawnLocation()->x, $this->getSpawnLocation()->z);
|
$s = new Vector2($this->getSpawnLocation()->x, $this->getSpawnLocation()->z);
|
||||||
if(count($this->server->getOps()->getAll()) > 0 and $t->distance($s) <= $distance){ //set it to cancelled so plugins can bypass this
|
if(count($this->server->getOps()->getAll()) > 0 and $t->distance($s) <= $distance){ //set it to cancelled so plugins can bypass this
|
||||||
@ -1613,7 +1647,7 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
|
|
||||||
if($player !== null){
|
if($player !== null){
|
||||||
$ev = new PlayerInteractEvent($player, $item, $target, $face, $target->getId() === 0 ? PlayerInteractEvent::RIGHT_CLICK_AIR : PlayerInteractEvent::RIGHT_CLICK_BLOCK);
|
$ev = new PlayerInteractEvent($player, $item, $target, $face, $target->getId() === 0 ? PlayerInteractEvent::RIGHT_CLICK_AIR : PlayerInteractEvent::RIGHT_CLICK_BLOCK);
|
||||||
if(!$player->isOp() and ($distance = $this->server->getSpawnRadius()) > -1){
|
if(!$player->hasPermission("pocketmine.spawnprotect.bypass") and ($distance = $this->server->getSpawnRadius()) > -1){
|
||||||
$t = new Vector2($target->x, $target->z);
|
$t = new Vector2($target->x, $target->z);
|
||||||
$s = new Vector2($this->getSpawnLocation()->x, $this->getSpawnLocation()->z);
|
$s = new Vector2($this->getSpawnLocation()->x, $this->getSpawnLocation()->z);
|
||||||
if(count($this->server->getOps()->getAll()) > 0 and $t->distance($s) <= $distance){ //set it to cancelled so plugins can bypass this
|
if(count($this->server->getOps()->getAll()) > 0 and $t->distance($s) <= $distance){ //set it to cancelled so plugins can bypass this
|
||||||
@ -1703,7 +1737,7 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
|
|
||||||
if($player !== null){
|
if($player !== null){
|
||||||
$ev = new BlockPlaceEvent($player, $hand, $block, $target, $item);
|
$ev = new BlockPlaceEvent($player, $hand, $block, $target, $item);
|
||||||
if(!$player->isOp() and ($distance = $this->server->getSpawnRadius()) > -1){
|
if(!$player->hasPermission("pocketmine.spawnprotect.bypass") and ($distance = $this->server->getSpawnRadius()) > -1){
|
||||||
$t = new Vector2($target->x, $target->z);
|
$t = new Vector2($target->x, $target->z);
|
||||||
$s = new Vector2($this->getSpawnLocation()->x, $this->getSpawnLocation()->z);
|
$s = new Vector2($this->getSpawnLocation()->x, $this->getSpawnLocation()->z);
|
||||||
if(count($this->server->getOps()->getAll()) > 0 and $t->distance($s) <= $distance){ //set it to cancelled so plugins can bypass this
|
if(count($this->server->getOps()->getAll()) > 0 and $t->distance($s) <= $distance){ //set it to cancelled so plugins can bypass this
|
||||||
|
@ -250,7 +250,7 @@ class Vector3{
|
|||||||
if($f < 0 or $f > 1){
|
if($f < 0 or $f > 1){
|
||||||
return null;
|
return null;
|
||||||
}else{
|
}else{
|
||||||
return new Vector3($this->x + $xDiff * $f, $this->y + $yDiff * $f, $this->z + $zDiff * $f);
|
return new Vector3($x, $this->y + $yDiff * $f, $this->z + $zDiff * $f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,7 +277,7 @@ class Vector3{
|
|||||||
if($f < 0 or $f > 1){
|
if($f < 0 or $f > 1){
|
||||||
return null;
|
return null;
|
||||||
}else{
|
}else{
|
||||||
return new Vector3($this->x + $xDiff * $f, $this->y + $yDiff * $f, $this->z + $zDiff * $f);
|
return new Vector3($this->x + $xDiff * $f, $y, $this->z + $zDiff * $f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,7 +304,7 @@ class Vector3{
|
|||||||
if($f < 0 or $f > 1){
|
if($f < 0 or $f > 1){
|
||||||
return null;
|
return null;
|
||||||
}else{
|
}else{
|
||||||
return new Vector3($this->x + $xDiff * $f, $this->y + $yDiff * $f, $this->z + $zDiff * $f);
|
return new Vector3($this->x + $xDiff * $f, $this->y + $yDiff * $f, $z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,24 +57,24 @@ use pocketmine\network\mcpe\protocol\EntityEventPacket;
|
|||||||
use pocketmine\network\mcpe\protocol\ExplodePacket;
|
use pocketmine\network\mcpe\protocol\ExplodePacket;
|
||||||
use pocketmine\network\mcpe\protocol\FullChunkDataPacket;
|
use pocketmine\network\mcpe\protocol\FullChunkDataPacket;
|
||||||
use pocketmine\network\mcpe\protocol\HurtArmorPacket;
|
use pocketmine\network\mcpe\protocol\HurtArmorPacket;
|
||||||
use pocketmine\network\mcpe\protocol\MapInfoRequestPacket;
|
|
||||||
use pocketmine\network\mcpe\protocol\PlaySoundPacket;
|
|
||||||
use pocketmine\network\mcpe\protocol\ProtocolInfo;
|
|
||||||
use pocketmine\network\mcpe\protocol\InteractPacket;
|
use pocketmine\network\mcpe\protocol\InteractPacket;
|
||||||
use pocketmine\network\mcpe\protocol\InventoryActionPacket;
|
use pocketmine\network\mcpe\protocol\InventoryActionPacket;
|
||||||
use pocketmine\network\mcpe\protocol\ItemFrameDropItemPacket;
|
use pocketmine\network\mcpe\protocol\ItemFrameDropItemPacket;
|
||||||
use pocketmine\network\mcpe\protocol\LevelEventPacket;
|
use pocketmine\network\mcpe\protocol\LevelEventPacket;
|
||||||
use pocketmine\network\mcpe\protocol\LevelSoundEventPacket;
|
use pocketmine\network\mcpe\protocol\LevelSoundEventPacket;
|
||||||
use pocketmine\network\mcpe\protocol\LoginPacket;
|
use pocketmine\network\mcpe\protocol\LoginPacket;
|
||||||
use pocketmine\network\mcpe\protocol\MobEquipmentPacket;
|
use pocketmine\network\mcpe\protocol\MapInfoRequestPacket;
|
||||||
use pocketmine\network\mcpe\protocol\MobArmorEquipmentPacket;
|
use pocketmine\network\mcpe\protocol\MobArmorEquipmentPacket;
|
||||||
|
use pocketmine\network\mcpe\protocol\MobEquipmentPacket;
|
||||||
use pocketmine\network\mcpe\protocol\MoveEntityPacket;
|
use pocketmine\network\mcpe\protocol\MoveEntityPacket;
|
||||||
use pocketmine\network\mcpe\protocol\MovePlayerPacket;
|
use pocketmine\network\mcpe\protocol\MovePlayerPacket;
|
||||||
use pocketmine\network\mcpe\protocol\PlayerActionPacket;
|
use pocketmine\network\mcpe\protocol\PlayerActionPacket;
|
||||||
use pocketmine\network\mcpe\protocol\PlayerFallPacket;
|
use pocketmine\network\mcpe\protocol\PlayerFallPacket;
|
||||||
use pocketmine\network\mcpe\protocol\PlayerInputPacket;
|
use pocketmine\network\mcpe\protocol\PlayerInputPacket;
|
||||||
use pocketmine\network\mcpe\protocol\PlayerListPacket;
|
use pocketmine\network\mcpe\protocol\PlayerListPacket;
|
||||||
|
use pocketmine\network\mcpe\protocol\PlaySoundPacket;
|
||||||
use pocketmine\network\mcpe\protocol\PlayStatusPacket;
|
use pocketmine\network\mcpe\protocol\PlayStatusPacket;
|
||||||
|
use pocketmine\network\mcpe\protocol\ProtocolInfo;
|
||||||
use pocketmine\network\mcpe\protocol\RemoveBlockPacket;
|
use pocketmine\network\mcpe\protocol\RemoveBlockPacket;
|
||||||
use pocketmine\network\mcpe\protocol\RemoveEntityPacket;
|
use pocketmine\network\mcpe\protocol\RemoveEntityPacket;
|
||||||
use pocketmine\network\mcpe\protocol\ReplaceItemInSlotPacket;
|
use pocketmine\network\mcpe\protocol\ReplaceItemInSlotPacket;
|
||||||
@ -108,9 +108,7 @@ use pocketmine\network\mcpe\protocol\UnknownPacket;
|
|||||||
use pocketmine\network\mcpe\protocol\UpdateBlockPacket;
|
use pocketmine\network\mcpe\protocol\UpdateBlockPacket;
|
||||||
use pocketmine\network\mcpe\protocol\UpdateTradePacket;
|
use pocketmine\network\mcpe\protocol\UpdateTradePacket;
|
||||||
use pocketmine\network\mcpe\protocol\UseItemPacket;
|
use pocketmine\network\mcpe\protocol\UseItemPacket;
|
||||||
use pocketmine\Player;
|
|
||||||
use pocketmine\Server;
|
use pocketmine\Server;
|
||||||
use pocketmine\utils\BinaryStream;
|
|
||||||
|
|
||||||
class Network{
|
class Network{
|
||||||
|
|
||||||
@ -237,50 +235,6 @@ class Network{
|
|||||||
return $this->server;
|
return $this->server;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Decodes a batch packet and does handling for it.
|
|
||||||
*
|
|
||||||
* TODO: Move this out of here
|
|
||||||
*
|
|
||||||
* @param BatchPacket $packet
|
|
||||||
* @param Player $player
|
|
||||||
*
|
|
||||||
* @throws \InvalidArgumentException|\InvalidStateException
|
|
||||||
*/
|
|
||||||
public function processBatch(BatchPacket $packet, Player $p){
|
|
||||||
$rawLen = strlen($packet->payload);
|
|
||||||
if($rawLen === 0){
|
|
||||||
throw new \InvalidArgumentException("BatchPacket payload is empty or packet decode error");
|
|
||||||
}elseif($rawLen < 3){
|
|
||||||
throw new \InvalidArgumentException("Not enough bytes, expected zlib header");
|
|
||||||
}
|
|
||||||
|
|
||||||
$str = zlib_decode($packet->payload, 1024 * 1024 * 64); //Max 64MB
|
|
||||||
$len = strlen($str);
|
|
||||||
|
|
||||||
if($len === 0){
|
|
||||||
throw new \InvalidStateException("Decoded BatchPacket payload is empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
$stream = new BinaryStream($str);
|
|
||||||
|
|
||||||
while($stream->offset < $len){
|
|
||||||
$buf = $stream->getString();
|
|
||||||
|
|
||||||
if(($pk = $this->getPacket(ord($buf{0}))) !== null){
|
|
||||||
if(!$pk->canBeBatched()){
|
|
||||||
throw new \InvalidStateException("Received invalid " . get_class($pk) . " inside BatchPacket");
|
|
||||||
}
|
|
||||||
|
|
||||||
$pk->setBuffer($buf, 1);
|
|
||||||
|
|
||||||
$pk->decode();
|
|
||||||
assert($pk->feof(), "Still " . strlen(substr($pk->buffer, $pk->offset)) . " bytes unread in " . get_class($pk));
|
|
||||||
$p->handleDataPacket($pk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $id
|
* @param $id
|
||||||
*
|
*
|
||||||
|
@ -32,7 +32,6 @@ use pocketmine\network\mcpe\protocol\AddPlayerPacket;
|
|||||||
use pocketmine\network\mcpe\protocol\AdventureSettingsPacket;
|
use pocketmine\network\mcpe\protocol\AdventureSettingsPacket;
|
||||||
use pocketmine\network\mcpe\protocol\AnimatePacket;
|
use pocketmine\network\mcpe\protocol\AnimatePacket;
|
||||||
use pocketmine\network\mcpe\protocol\AvailableCommandsPacket;
|
use pocketmine\network\mcpe\protocol\AvailableCommandsPacket;
|
||||||
use pocketmine\network\mcpe\protocol\BatchPacket;
|
|
||||||
use pocketmine\network\mcpe\protocol\BlockEntityDataPacket;
|
use pocketmine\network\mcpe\protocol\BlockEntityDataPacket;
|
||||||
use pocketmine\network\mcpe\protocol\BlockEventPacket;
|
use pocketmine\network\mcpe\protocol\BlockEventPacket;
|
||||||
use pocketmine\network\mcpe\protocol\BlockPickRequestPacket;
|
use pocketmine\network\mcpe\protocol\BlockPickRequestPacket;
|
||||||
@ -49,6 +48,7 @@ use pocketmine\network\mcpe\protocol\ContainerSetDataPacket;
|
|||||||
use pocketmine\network\mcpe\protocol\ContainerSetSlotPacket;
|
use pocketmine\network\mcpe\protocol\ContainerSetSlotPacket;
|
||||||
use pocketmine\network\mcpe\protocol\CraftingDataPacket;
|
use pocketmine\network\mcpe\protocol\CraftingDataPacket;
|
||||||
use pocketmine\network\mcpe\protocol\CraftingEventPacket;
|
use pocketmine\network\mcpe\protocol\CraftingEventPacket;
|
||||||
|
use pocketmine\network\mcpe\protocol\DataPacket;
|
||||||
use pocketmine\network\mcpe\protocol\DisconnectPacket;
|
use pocketmine\network\mcpe\protocol\DisconnectPacket;
|
||||||
use pocketmine\network\mcpe\protocol\DropItemPacket;
|
use pocketmine\network\mcpe\protocol\DropItemPacket;
|
||||||
use pocketmine\network\mcpe\protocol\EntityEventPacket;
|
use pocketmine\network\mcpe\protocol\EntityEventPacket;
|
||||||
@ -108,9 +108,17 @@ use pocketmine\network\mcpe\protocol\UpdateAttributesPacket;
|
|||||||
use pocketmine\network\mcpe\protocol\UpdateBlockPacket;
|
use pocketmine\network\mcpe\protocol\UpdateBlockPacket;
|
||||||
use pocketmine\network\mcpe\protocol\UpdateTradePacket;
|
use pocketmine\network\mcpe\protocol\UpdateTradePacket;
|
||||||
use pocketmine\network\mcpe\protocol\UseItemPacket;
|
use pocketmine\network\mcpe\protocol\UseItemPacket;
|
||||||
|
use pocketmine\Server;
|
||||||
|
|
||||||
interface NetworkSession{
|
interface NetworkSession{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Server
|
||||||
|
*/
|
||||||
|
public function getServer();
|
||||||
|
|
||||||
|
public function handleDataPacket(DataPacket $pk);
|
||||||
|
|
||||||
public function handleLogin(LoginPacket $packet) : bool;
|
public function handleLogin(LoginPacket $packet) : bool;
|
||||||
|
|
||||||
public function handlePlayStatus(PlayStatusPacket $packet) : bool;
|
public function handlePlayStatus(PlayStatusPacket $packet) : bool;
|
||||||
@ -121,8 +129,6 @@ interface NetworkSession{
|
|||||||
|
|
||||||
public function handleDisconnect(DisconnectPacket $packet) : bool;
|
public function handleDisconnect(DisconnectPacket $packet) : bool;
|
||||||
|
|
||||||
public function handleBatch(BatchPacket $packet) : bool;
|
|
||||||
|
|
||||||
public function handleResourcePacksInfo(ResourcePacksInfoPacket $packet) : bool;
|
public function handleResourcePacksInfo(ResourcePacksInfoPacket $packet) : bool;
|
||||||
|
|
||||||
public function handleResourcePackStack(ResourcePackStackPacket $packet) : bool;
|
public function handleResourcePackStack(ResourcePackStackPacket $packet) : bool;
|
||||||
|
@ -132,11 +132,7 @@ class RakLibInterface implements ServerInstance, AdvancedSourceInterface{
|
|||||||
try{
|
try{
|
||||||
if($packet->buffer !== ""){
|
if($packet->buffer !== ""){
|
||||||
$pk = $this->getPacket($packet->buffer);
|
$pk = $this->getPacket($packet->buffer);
|
||||||
if($pk !== null){
|
$this->players[$identifier]->handleDataPacket($pk);
|
||||||
$pk->decode();
|
|
||||||
assert($pk->feof(), "Still " . strlen(substr($pk->buffer, $pk->offset)) . " bytes unread!");
|
|
||||||
$this->players[$identifier]->handleDataPacket($pk);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}catch(\Throwable $e){
|
}catch(\Throwable $e){
|
||||||
if(\pocketmine\DEBUG > 1 and isset($pk)){
|
if(\pocketmine\DEBUG > 1 and isset($pk)){
|
||||||
|
@ -45,7 +45,32 @@ class BatchPacket extends DataPacket{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function handle(NetworkSession $session) : bool{
|
public function handle(NetworkSession $session) : bool{
|
||||||
return $session->handleBatch($this);
|
if(strlen($this->payload) < 2){
|
||||||
|
throw new \InvalidStateException("Not enough bytes in payload, expected zlib header");
|
||||||
|
}
|
||||||
|
|
||||||
|
$str = zlib_decode($this->payload, 1024 * 1024 * 64); //Max 64MB
|
||||||
|
$len = strlen($str);
|
||||||
|
|
||||||
|
if($len === 0){
|
||||||
|
throw new \InvalidStateException("Decoded BatchPacket payload is empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->setBuffer($str, 0);
|
||||||
|
|
||||||
|
$network = $session->getServer()->getNetwork();
|
||||||
|
while(!$this->feof()){
|
||||||
|
$buf = $this->getString();
|
||||||
|
$pk = $network->getPacket(ord($buf{0}));
|
||||||
|
if(!$pk->canBeBatched()){
|
||||||
|
throw new \InvalidArgumentException("Received invalid " . get_class($pk) . " inside BatchPacket");
|
||||||
|
}
|
||||||
|
|
||||||
|
$pk->setBuffer($buf, 1);
|
||||||
|
$session->handleDataPacket($pk);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -47,12 +47,13 @@ abstract class DefaultPermissions{
|
|||||||
$parent = self::registerPermission(new Permission(self::ROOT, "Allows using all PocketMine commands and utilities"));
|
$parent = self::registerPermission(new Permission(self::ROOT, "Allows using all PocketMine commands and utilities"));
|
||||||
|
|
||||||
$broadcasts = self::registerPermission(new Permission(self::ROOT . ".broadcast", "Allows the user to receive all broadcast messages"), $parent);
|
$broadcasts = self::registerPermission(new Permission(self::ROOT . ".broadcast", "Allows the user to receive all broadcast messages"), $parent);
|
||||||
|
|
||||||
self::registerPermission(new Permission(self::ROOT . ".broadcast.admin", "Allows the user to receive administrative broadcasts", Permission::DEFAULT_OP), $broadcasts);
|
self::registerPermission(new Permission(self::ROOT . ".broadcast.admin", "Allows the user to receive administrative broadcasts", Permission::DEFAULT_OP), $broadcasts);
|
||||||
self::registerPermission(new Permission(self::ROOT . ".broadcast.user", "Allows the user to receive user broadcasts", Permission::DEFAULT_TRUE), $broadcasts);
|
self::registerPermission(new Permission(self::ROOT . ".broadcast.user", "Allows the user to receive user broadcasts", Permission::DEFAULT_TRUE), $broadcasts);
|
||||||
|
|
||||||
$broadcasts->recalculatePermissibles();
|
$broadcasts->recalculatePermissibles();
|
||||||
|
|
||||||
|
$spawnprotect = self::registerPermission(new Permission(self::ROOT . ".spawnprotect.bypass", "Allows the user to edit blocks within the protected spawn radius", Permission::DEFAULT_OP), $parent);
|
||||||
|
$spawnprotect->recalculatePermissibles();
|
||||||
|
|
||||||
$commands = self::registerPermission(new Permission(self::ROOT . ".command", "Allows using all PocketMine commands"), $parent);
|
$commands = self::registerPermission(new Permission(self::ROOT . ".command", "Allows using all PocketMine commands"), $parent);
|
||||||
|
|
||||||
$whitelist = self::registerPermission(new Permission(self::ROOT . ".command.whitelist", "Allows the user to modify the server whitelist", Permission::DEFAULT_OP), $commands);
|
$whitelist = self::registerPermission(new Permission(self::ROOT . ".command.whitelist", "Allows the user to modify the server whitelist", Permission::DEFAULT_OP), $commands);
|
||||||
|
@ -185,6 +185,11 @@ timings:
|
|||||||
#Choose the host to use for viewing your timings results.
|
#Choose the host to use for viewing your timings results.
|
||||||
host: mcpetimings.com
|
host: mcpetimings.com
|
||||||
|
|
||||||
|
console:
|
||||||
|
#Choose whether to enable server stats reporting on the console title.
|
||||||
|
#NOTE: The title ticker will be disabled regardless if console colours are not enabled.
|
||||||
|
title-tick: true
|
||||||
|
|
||||||
aliases:
|
aliases:
|
||||||
#Examples:
|
#Examples:
|
||||||
#showtheversion: version
|
#showtheversion: version
|
||||||
|
Loading…
x
Reference in New Issue
Block a user