mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-11 08:19:45 +00:00
Merged in 1.0.6 changes, added autogenerated data for 1.1.0.3 (doesn't work yet) and deliberately made the same merge error as Mojang
This commit is contained in:
parent
cdf6d200ef
commit
f3ab45e7d5
@ -345,7 +345,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
}
|
||||
|
||||
public function isBanned(){
|
||||
return $this->server->getNameBans()->isBanned(strtolower($this->getName()));
|
||||
return $this->server->getNameBans()->isBanned($this->iusername);
|
||||
}
|
||||
|
||||
public function setBanned($value){
|
||||
@ -358,14 +358,14 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
}
|
||||
|
||||
public function isWhitelisted(){
|
||||
return $this->server->isWhitelisted(strtolower($this->getName()));
|
||||
return $this->server->isWhitelisted($this->iusername);
|
||||
}
|
||||
|
||||
public function setWhitelisted($value){
|
||||
if($value === true){
|
||||
$this->server->addWhitelist(strtolower($this->getName()));
|
||||
$this->server->addWhitelist($this->iusername);
|
||||
}else{
|
||||
$this->server->removeWhitelist(strtolower($this->getName()));
|
||||
$this->server->removeWhitelist($this->iusername);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1562,10 +1562,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
}
|
||||
}
|
||||
|
||||
if(!$this->isSpectator()){
|
||||
$this->checkNearEntities($tickDiff);
|
||||
}
|
||||
|
||||
$this->speed = ($to->subtract($from))->divide($tickDiff);
|
||||
}elseif($distanceSquared == 0){
|
||||
$this->speed = new Vector3(0, 0, 0);
|
||||
@ -1655,28 +1651,33 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
$this->processMovement($tickDiff);
|
||||
$this->entityBaseTick($tickDiff);
|
||||
|
||||
if(!$this->isSpectator() and $this->speed !== null){
|
||||
if($this->onGround){
|
||||
if($this->inAirTicks !== 0){
|
||||
$this->startAirTicks = 5;
|
||||
}
|
||||
$this->inAirTicks = 0;
|
||||
}else{
|
||||
if(!$this->allowFlight and $this->inAirTicks > 10 and !$this->isSleeping() and !$this->isImmobile()){
|
||||
$expectedVelocity = (-$this->gravity) / $this->drag - ((-$this->gravity) / $this->drag) * exp(-$this->drag * ($this->inAirTicks - $this->startAirTicks));
|
||||
$diff = ($this->speed->y - $expectedVelocity) ** 2;
|
||||
if(!$this->isSpectator()){
|
||||
$this->checkNearEntities($tickDiff);
|
||||
|
||||
if(!$this->hasEffect(Effect::JUMP) and $diff > 0.6 and $expectedVelocity < $this->speed->y and !$this->server->getAllowFlight()){
|
||||
if($this->inAirTicks < 100){
|
||||
$this->setMotion(new Vector3(0, $expectedVelocity, 0));
|
||||
}elseif($this->kick("Flying is not enabled on this server")){
|
||||
$this->timings->stopTiming();
|
||||
return false;
|
||||
if($this->speed !== null){
|
||||
if($this->onGround){
|
||||
if($this->inAirTicks !== 0){
|
||||
$this->startAirTicks = 5;
|
||||
}
|
||||
$this->inAirTicks = 0;
|
||||
}else{
|
||||
if(!$this->allowFlight and $this->inAirTicks > 10 and !$this->isSleeping() and !$this->isImmobile()){
|
||||
$expectedVelocity = (-$this->gravity) / $this->drag - ((-$this->gravity) / $this->drag) * exp(-$this->drag * ($this->inAirTicks - $this->startAirTicks));
|
||||
$diff = ($this->speed->y - $expectedVelocity) ** 2;
|
||||
|
||||
if(!$this->hasEffect(Effect::JUMP) and $diff > 0.6 and $expectedVelocity < $this->speed->y and !$this->server->getAllowFlight()){
|
||||
if($this->inAirTicks < 100){
|
||||
$this->setMotion(new Vector3(0, $expectedVelocity, 0));
|
||||
}elseif($this->kick("Flying is not enabled on this server")){
|
||||
$this->timings->stopTiming();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++$this->inAirTicks;
|
||||
++$this->inAirTicks;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1722,18 +1723,18 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
|
||||
|
||||
protected function processLogin(){
|
||||
if(!$this->server->isWhitelisted(strtolower($this->getName()))){
|
||||
if(!$this->server->isWhitelisted($this->iusername)){
|
||||
$this->close($this->getLeaveMessage(), "Server is white-listed");
|
||||
|
||||
return;
|
||||
}elseif($this->server->getNameBans()->isBanned(strtolower($this->getName())) or $this->server->getIPBans()->isBanned($this->getAddress())){
|
||||
}elseif($this->server->getNameBans()->isBanned($this->iusername) or $this->server->getIPBans()->isBanned($this->getAddress())){
|
||||
$this->close($this->getLeaveMessage(), "You are banned");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
foreach($this->server->getOnlinePlayers() as $p){
|
||||
if($p !== $this and strtolower($p->getName()) === strtolower($this->getName())){
|
||||
if($p !== $this and $p->iusername === $this->iusername){
|
||||
if($p->kick("logged in from another location") === false){
|
||||
$this->close($this->getLeaveMessage(), "Logged in from another location");
|
||||
|
||||
@ -1975,7 +1976,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
//Client requested a resource pack but we don't have it available on the server
|
||||
$this->close("", "disconnectionScreen.resourcePack", true);
|
||||
$this->server->getLogger()->debug("Got a resource pack request for unknown pack with UUID " . $uuid . ", available packs: " . implode(", ", $manager->getPackIdList()));
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
|
||||
$pk = new ResourcePackDataInfoPacket();
|
||||
@ -2382,7 +2383,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
break; //TODO: handle these
|
||||
default:
|
||||
$this->server->getLogger()->debug("Unhandled/unknown interaction type " . $packet->action . "received from ". $this->getName());
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -2721,7 +2722,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
break; //TODO
|
||||
default:
|
||||
$this->server->getLogger()->debug("Unhandled/unknown player action type " . $packet->action . " from " . $this->getName());
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->startAction = -1;
|
||||
@ -3284,7 +3285,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
$this->close("", "disconnectionScreen.resourcePack", true);
|
||||
$this->server->getLogger()->debug("Got a resource pack chunk request for unknown pack with UUID " . $packet->packId . ", available packs: " . implode(", ", $manager->getPackIdList()));
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
$pk = new ResourcePackChunkDataPacket();
|
||||
@ -3336,7 +3337,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
}
|
||||
$this->server->getPluginManager()->callEvent($ev = new DataPacketReceiveEvent($this, $packet));
|
||||
if(!$ev->isCancelled() and !$packet->handle($this)){
|
||||
$this->server->getLogger()->debug("Unhandled " . get_class($packet) . " received from " . $this->getName() . ": " . bin2hex($packet->buffer));
|
||||
$this->server->getLogger()->debug("Unhandled " . get_class($packet) . " received from " . $this->getName() . ": 0x" . bin2hex($packet->buffer));
|
||||
}
|
||||
|
||||
$timings->stopTiming();
|
||||
@ -3410,10 +3411,10 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
*/
|
||||
public function addTitle(string $title, string $subtitle = "", int $fadeIn = -1, int $stay = -1, int $fadeOut = -1){
|
||||
$this->setTitleDuration($fadeIn, $stay, $fadeOut);
|
||||
$this->sendTitleText($title, SetTitlePacket::TYPE_SET_TITLE);
|
||||
if($subtitle !== ""){
|
||||
$this->sendTitleText($subtitle, SetTitlePacket::TYPE_SET_SUBTITLE);
|
||||
}
|
||||
$this->sendTitleText($title, SetTitlePacket::TYPE_SET_TITLE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -128,7 +128,6 @@ namespace pocketmine {
|
||||
|
||||
set_time_limit(0); //Who set it to 30 seconds?!?!
|
||||
|
||||
gc_enable();
|
||||
error_reporting(-1);
|
||||
ini_set("allow_url_fopen", 1);
|
||||
ini_set("display_errors", 1);
|
||||
|
@ -64,7 +64,7 @@ class Lava extends Liquid{
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$ret = $this->getLevel()->setBlock($this, $this, true, false);
|
||||
$this->getLevel()->scheduleUpdate($this, $this->tickRate());
|
||||
$this->getLevel()->scheduleDelayedBlockUpdate($this, $this->tickRate());
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
@ -189,7 +189,7 @@ abstract class Liquid extends Transparent{
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
$this->checkForHarden();
|
||||
$this->getLevel()->scheduleUpdate($this, $this->tickRate());
|
||||
$this->getLevel()->scheduleDelayedBlockUpdate($this, $this->tickRate());
|
||||
}elseif($type === Level::BLOCK_UPDATE_SCHEDULED){
|
||||
if($this->temporalVector === null){
|
||||
$this->temporalVector = new Vector3(0, 0, 0);
|
||||
@ -242,7 +242,7 @@ abstract class Liquid extends Transparent{
|
||||
$this->getLevel()->setBlock($this, new Air(), true);
|
||||
}else{
|
||||
$this->getLevel()->setBlock($this, Block::get($this->id, $decay), true);
|
||||
$this->getLevel()->scheduleUpdate($this, $this->tickRate());
|
||||
$this->getLevel()->scheduleDelayedBlockUpdate($this, $this->tickRate());
|
||||
}
|
||||
}elseif($flag){
|
||||
//$this->getLevel()->scheduleUpdate($this, $this->tickRate());
|
||||
@ -262,10 +262,10 @@ abstract class Liquid extends Transparent{
|
||||
|
||||
if($decay >= 8){
|
||||
$this->getLevel()->setBlock($bottomBlock, Block::get($this->id, $decay), true);
|
||||
$this->getLevel()->scheduleUpdate($bottomBlock, $this->tickRate());
|
||||
$this->getLevel()->scheduleDelayedBlockUpdate($bottomBlock, $this->tickRate());
|
||||
}else{
|
||||
$this->getLevel()->setBlock($bottomBlock, Block::get($this->id, $decay + 8), true);
|
||||
$this->getLevel()->scheduleUpdate($bottomBlock, $this->tickRate());
|
||||
$this->getLevel()->scheduleDelayedBlockUpdate($bottomBlock, $this->tickRate());
|
||||
}
|
||||
}elseif($decay >= 0 and ($decay === 0 or !$bottomBlock->canBeFlowedInto())){
|
||||
$flags = $this->getOptimalFlowDirections();
|
||||
@ -310,7 +310,7 @@ abstract class Liquid extends Transparent{
|
||||
}
|
||||
|
||||
$this->getLevel()->setBlock($block, Block::get($this->getId(), $newFlowDecay), true);
|
||||
$this->getLevel()->scheduleUpdate($block, $this->tickRate());
|
||||
$this->getLevel()->scheduleDelayedBlockUpdate($block, $this->tickRate());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ class Water extends Liquid{
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$ret = $this->getLevel()->setBlock($this, $this, true, false);
|
||||
$this->getLevel()->scheduleUpdate($this, $this->tickRate());
|
||||
$this->getLevel()->scheduleDelayedBlockUpdate($this, $this->tickRate());
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
@ -440,14 +440,10 @@ class Effect{
|
||||
$attr->setMaxValue($max);
|
||||
break;
|
||||
case Effect::ABSORPTION:
|
||||
if($ev->willModify() and $oldEffect !== null){
|
||||
$value = $entity->getAbsorption() - (4 * ($oldEffect->getAmplifier() + 1));
|
||||
}else{
|
||||
$value = $entity->getAbsorption();
|
||||
$new = (4 * ($this->amplifier + 1));
|
||||
if($new > $entity->getAbsorption()){
|
||||
$entity->setAbsorption($new);
|
||||
}
|
||||
|
||||
$value += (4 * ($this->amplifier + 1));
|
||||
$entity->setAbsorption($value);
|
||||
break;
|
||||
|
||||
}
|
||||
@ -490,7 +486,7 @@ class Effect{
|
||||
$attr->setMaxValue($attr->getMaxValue() - (4 * ($this->amplifier + 1)));
|
||||
break;
|
||||
case Effect::ABSORPTION:
|
||||
$entity->setAbsorption($entity->getAbsorption() - (4 * ($this->amplifier + 1)));
|
||||
$entity->setAbsorption(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -394,21 +394,38 @@ abstract class Entity extends Location implements Metadatable{
|
||||
public function setNameTagAlwaysVisible($value = true){
|
||||
$this->setDataFlag(self::DATA_FLAGS, self::DATA_FLAG_ALWAYS_SHOW_NAMETAG, $value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getScale(): float{
|
||||
public function getScale() : float{
|
||||
return $this->getDataProperty(self::DATA_SCALE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param float $value
|
||||
*/
|
||||
public function setScale(float $value){
|
||||
$multiplier = $value / $this->getScale();
|
||||
|
||||
$this->width *= $multiplier;
|
||||
$this->height *= $multiplier;
|
||||
$halfWidth = $this->width / 2;
|
||||
|
||||
$this->boundingBox->setBounds(
|
||||
$this->x - $halfWidth,
|
||||
$this->y,
|
||||
$this->z - $halfWidth,
|
||||
$this->x + $halfWidth,
|
||||
$this->y + $this->height,
|
||||
$this->z + $halfWidth
|
||||
);
|
||||
|
||||
$this->setDataProperty(self::DATA_SCALE, self::DATA_TYPE_FLOAT, $value);
|
||||
$this->setDataProperty(self::DATA_BOUNDING_BOX_WIDTH, self::DATA_TYPE_FLOAT, $this->width);
|
||||
$this->setDataProperty(self::DATA_BOUNDING_BOX_HEIGHT, self::DATA_TYPE_FLOAT, $this->height);
|
||||
}
|
||||
|
||||
|
||||
public function isSneaking(){
|
||||
return $this->getDataFlag(self::DATA_FLAGS, self::DATA_FLAG_SNEAKING);
|
||||
}
|
||||
|
@ -30,8 +30,6 @@ abstract class Event{
|
||||
* Any callable event must declare the static variable
|
||||
*
|
||||
* public static $handlerList = null;
|
||||
* public static $eventPool = [];
|
||||
* public static $nextEvent = 0;
|
||||
*
|
||||
* Not doing so will deny the proper event initialization
|
||||
*/
|
||||
@ -85,4 +83,4 @@ abstract class Event{
|
||||
return static::$handlerList;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -46,12 +46,22 @@ class Item implements ItemIds, \JsonSerializable{
|
||||
private static $cachedParser = null;
|
||||
|
||||
private static function parseCompoundTag(string $tag) : CompoundTag{
|
||||
if(strlen($tag) === 0){
|
||||
throw new \InvalidArgumentException("No NBT data found in supplied string");
|
||||
}
|
||||
|
||||
if(self::$cachedParser === null){
|
||||
self::$cachedParser = new NBT(NBT::LITTLE_ENDIAN);
|
||||
}
|
||||
|
||||
self::$cachedParser->read($tag);
|
||||
return self::$cachedParser->getData();
|
||||
$data = self::$cachedParser->getData();
|
||||
|
||||
if(!($data instanceof CompoundTag)){
|
||||
throw new \InvalidArgumentException("Invalid item NBT string given, it could not be deserialized");
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
private static function writeCompoundTag(CompoundTag $tag) : string{
|
||||
|
@ -201,7 +201,7 @@ class Explosion{
|
||||
|
||||
$pos = new Vector3($block->x, $block->y, $block->z);
|
||||
|
||||
for($side = 0; $side < 5; $side++){
|
||||
for($side = 0; $side <= 5; $side++){
|
||||
$sideBlock = $pos->getSide($side);
|
||||
if(!isset($this->affectedBlocks[$index = Level::blockHash($sideBlock->x, $sideBlock->y, $sideBlock->z)]) and !isset($updateBlocks[$index])){
|
||||
$this->level->getServer()->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->level->getBlock($sideBlock)));
|
||||
|
@ -190,8 +190,11 @@ class Level implements ChunkManager, Metadatable{
|
||||
private $changedBlocks = [];
|
||||
|
||||
/** @var ReversePriorityQueue */
|
||||
private $updateQueue;
|
||||
private $updateQueueIndex = [];
|
||||
private $scheduledBlockUpdateQueue;
|
||||
private $scheduledBlockUpdateQueueIndex = [];
|
||||
|
||||
/** @var \SplQueue */
|
||||
private $neighbourBlockUpdateQueue = [];
|
||||
|
||||
/** @var Player[][] */
|
||||
private $chunkSendQueue = [];
|
||||
@ -333,8 +336,11 @@ class Level implements ChunkManager, Metadatable{
|
||||
$this->generator = Generator::getGenerator($this->provider->getGenerator());
|
||||
|
||||
$this->folderName = $name;
|
||||
$this->updateQueue = new ReversePriorityQueue();
|
||||
$this->updateQueue->setExtractFlags(\SplPriorityQueue::EXTR_BOTH);
|
||||
$this->scheduledBlockUpdateQueue = new ReversePriorityQueue();
|
||||
$this->scheduledBlockUpdateQueue->setExtractFlags(\SplPriorityQueue::EXTR_BOTH);
|
||||
|
||||
$this->neighbourBlockUpdateQueue = new \SplQueue();
|
||||
|
||||
$this->time = (int) $this->provider->getTime();
|
||||
|
||||
$this->chunkTickRadius = min($this->server->getViewDistance(), max(1, (int) $this->server->getProperty("chunk-ticking.tick-radius", 4)));
|
||||
@ -663,11 +669,24 @@ class Level implements ChunkManager, Metadatable{
|
||||
|
||||
//Do block updates
|
||||
$this->timings->doTickPending->startTiming();
|
||||
while($this->updateQueue->count() > 0 and $this->updateQueue->current()["priority"] <= $currentTick){
|
||||
$block = $this->getBlock($this->updateQueue->extract()["data"]);
|
||||
unset($this->updateQueueIndex[Level::blockHash($block->x, $block->y, $block->z)]);
|
||||
|
||||
//Delayed updates
|
||||
while($this->scheduledBlockUpdateQueue->count() > 0 and $this->scheduledBlockUpdateQueue->current()["priority"] <= $currentTick){
|
||||
$block = $this->getBlock($this->scheduledBlockUpdateQueue->extract()["data"]);
|
||||
unset($this->scheduledBlockUpdateQueueIndex[Level::blockHash($block->x, $block->y, $block->z)]);
|
||||
$block->onUpdate(self::BLOCK_UPDATE_SCHEDULED);
|
||||
}
|
||||
|
||||
//Normal updates
|
||||
while($this->neighbourBlockUpdateQueue->count() > 0){
|
||||
$index = $this->neighbourBlockUpdateQueue->dequeue();
|
||||
Level::getBlockXYZ($index, $x, $y, $z);
|
||||
$this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlock($this->temporalVector->setComponents($x, $y, $z))));
|
||||
if(!$ev->isCancelled()){
|
||||
$ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
$this->timings->doTickPending->stopTiming();
|
||||
|
||||
$this->timings->entityTick->startTiming();
|
||||
@ -1018,15 +1037,45 @@ class Level implements ChunkManager, Metadatable{
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated This method will be removed in the future due to misleading/ambiguous name. Use {@link Level#scheduleDelayedBlockUpdate} instead.
|
||||
*
|
||||
* @param Vector3 $pos
|
||||
* @param int $delay
|
||||
*/
|
||||
public function scheduleUpdate(Vector3 $pos, int $delay){
|
||||
if(isset($this->updateQueueIndex[$index = Level::blockHash($pos->x, $pos->y, $pos->z)]) and $this->updateQueueIndex[$index] <= $delay){
|
||||
$this->scheduleDelayedBlockUpdate($pos, $delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a block update to be executed after the specified number of ticks.
|
||||
* Blocks will be updated with the scheduled update type.
|
||||
*
|
||||
* @param Vector3 $pos
|
||||
* @param int $delay
|
||||
*/
|
||||
public function scheduleDelayedBlockUpdate(Vector3 $pos, int $delay){
|
||||
if(isset($this->scheduledBlockUpdateQueueIndex[$index = Level::blockHash($pos->x, $pos->y, $pos->z)]) and $this->scheduledBlockUpdateQueueIndex[$index] <= $delay){
|
||||
return;
|
||||
}
|
||||
$this->updateQueueIndex[$index] = $delay;
|
||||
$this->updateQueue->insert(new Vector3((int) $pos->x, (int) $pos->y, (int) $pos->z), (int) $delay + $this->server->getTick());
|
||||
$this->scheduledBlockUpdateQueueIndex[$index] = $delay;
|
||||
$this->scheduledBlockUpdateQueue->insert(new Vector3((int) $pos->x, (int) $pos->y, (int) $pos->z), (int) $delay + $this->server->getTick());
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules the blocks around the specified position to be updated at the end of this tick.
|
||||
* Blocks will be updated with the normal update type.
|
||||
*
|
||||
* @param Vector3 $pos
|
||||
*/
|
||||
public function scheduleNeighbourBlockUpdates(Vector3 $pos){
|
||||
$pos = $pos->floor();
|
||||
|
||||
$this->neighbourBlockUpdateQueue->enqueue(Level::blockHash($pos->x + 1, $pos->y, $pos->z));
|
||||
$this->neighbourBlockUpdateQueue->enqueue(Level::blockHash($pos->x - 1, $pos->y, $pos->z));
|
||||
$this->neighbourBlockUpdateQueue->enqueue(Level::blockHash($pos->x, $pos->y + 1, $pos->z));
|
||||
$this->neighbourBlockUpdateQueue->enqueue(Level::blockHash($pos->x, $pos->y - 1, $pos->z));
|
||||
$this->neighbourBlockUpdateQueue->enqueue(Level::blockHash($pos->x, $pos->y, $pos->z + 1));
|
||||
$this->neighbourBlockUpdateQueue->enqueue(Level::blockHash($pos->x, $pos->y, $pos->z - 1));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1440,9 +1489,8 @@ class Level implements ChunkManager, Metadatable{
|
||||
$entity->scheduleUpdate();
|
||||
}
|
||||
$ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL);
|
||||
$this->scheduleNeighbourBlockUpdates($pos);
|
||||
}
|
||||
|
||||
$this->updateAround($pos);
|
||||
}
|
||||
|
||||
$this->timings->setBlock->stopTiming();
|
||||
|
@ -307,7 +307,7 @@ class Chunk{
|
||||
* @param int $level 0-15
|
||||
*/
|
||||
public function setBlockSkyLight(int $x, int $y, int $z, int $level){
|
||||
if($this->getSubChunk($y >> 4)->setBlockSkyLight($x, $y & 0x0f, $z, $level)){
|
||||
if($this->getSubChunk($y >> 4, true)->setBlockSkyLight($x, $y & 0x0f, $z, $level)){
|
||||
$this->hasChanged = true;
|
||||
}
|
||||
}
|
||||
@ -334,7 +334,7 @@ class Chunk{
|
||||
* @param int $level 0-15
|
||||
*/
|
||||
public function setBlockLight(int $x, int $y, int $z, int $level){
|
||||
if($this->getSubChunk($y >> 4)->setBlockLight($x, $y & 0x0f, $z, $level)){
|
||||
if($this->getSubChunk($y >> 4, true)->setBlockLight($x, $y & 0x0f, $z, $level)){
|
||||
$this->hasChanged = true;
|
||||
}
|
||||
}
|
||||
|
@ -47,8 +47,11 @@ class SubChunk{
|
||||
}
|
||||
|
||||
public function isEmpty() : bool{
|
||||
assert(strlen($this->ids) === 4096, "Wrong length of ID array, expecting 4096 bytes, got " . strlen($this->ids));
|
||||
return substr_count($this->ids, "\x00") === 4096;
|
||||
return (
|
||||
substr_count($this->ids, "\x00") === 4096 and
|
||||
substr_count($this->skyLight, "\xff") === 2048 and
|
||||
substr_count($this->blockLight, "\x00") === 2048
|
||||
);
|
||||
}
|
||||
|
||||
public function getBlockId(int $x, int $y, int $z) : int{
|
||||
|
@ -111,4 +111,12 @@ class CompoundTag extends NamedTag implements \ArrayAccess{
|
||||
}
|
||||
return $str . "}";
|
||||
}
|
||||
|
||||
public function __clone(){
|
||||
foreach($this as $key => $tag){
|
||||
if($tag instanceof Tag){
|
||||
$this->{$key} = clone $tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -220,4 +220,12 @@ class ListTag extends NamedTag implements \ArrayAccess, \Countable{
|
||||
}
|
||||
return $str . "}";
|
||||
}
|
||||
|
||||
public function __clone(){
|
||||
foreach($this as $key => $tag){
|
||||
if($tag instanceof Tag){
|
||||
$this->{$key} = clone $tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,8 +32,8 @@ interface ProtocolInfo{
|
||||
* Actual Minecraft: PE protocol version
|
||||
*/
|
||||
const CURRENT_PROTOCOL = 110;
|
||||
const MINECRAFT_VERSION = "v1.1.0.0 beta";
|
||||
const MINECRAFT_VERSION_NETWORK = "1.1.0.0";
|
||||
const MINECRAFT_VERSION = 'v1.1.0.3 beta';
|
||||
const MINECRAFT_VERSION_NETWORK = '1.1.0.3';
|
||||
|
||||
const LOGIN_PACKET = 0x01;
|
||||
const PLAY_STATUS_PACKET = 0x02;
|
||||
@ -41,7 +41,7 @@ interface ProtocolInfo{
|
||||
const CLIENT_TO_SERVER_HANDSHAKE_PACKET = 0x04;
|
||||
const DISCONNECT_PACKET = 0x05;
|
||||
const RESOURCE_PACKS_INFO_PACKET = 0x06;
|
||||
const RESOURCE_PACK_STACK_PACKET = 0x07; //ResourcePacksStackPacket
|
||||
const RESOURCE_PACK_STACK_PACKET = 0x07;
|
||||
const RESOURCE_PACK_CLIENT_RESPONSE_PACKET = 0x08;
|
||||
const TEXT_PACKET = 0x09;
|
||||
const SET_TIME_PACKET = 0x0a;
|
||||
@ -71,7 +71,7 @@ interface ProtocolInfo{
|
||||
const BLOCK_PICK_REQUEST_PACKET = 0x22;
|
||||
const USE_ITEM_PACKET = 0x23;
|
||||
const PLAYER_ACTION_PACKET = 0x24;
|
||||
const ENTITY_FALL_PACKET = 0x25; //PlayerFallPacket
|
||||
const ENTITY_FALL_PACKET = 0x25;
|
||||
const HURT_ARMOR_PACKET = 0x26;
|
||||
const SET_ENTITY_DATA_PACKET = 0x27;
|
||||
const SET_ENTITY_MOTION_PACKET = 0x28;
|
||||
@ -99,14 +99,14 @@ interface ProtocolInfo{
|
||||
const SET_PLAYER_GAME_TYPE_PACKET = 0x3e;
|
||||
const PLAYER_LIST_PACKET = 0x3f;
|
||||
const SIMPLE_EVENT_PACKET = 0x40;
|
||||
const EVENT_PACKET = 0x41; //TelemetryEventPacket
|
||||
const EVENT_PACKET = 0x41;
|
||||
const SPAWN_EXPERIENCE_ORB_PACKET = 0x42;
|
||||
const CLIENTBOUND_MAP_ITEM_DATA_PACKET = 0x43; //MapItemDataPacket
|
||||
const CLIENTBOUND_MAP_ITEM_DATA_PACKET = 0x43;
|
||||
const MAP_INFO_REQUEST_PACKET = 0x44;
|
||||
const REQUEST_CHUNK_RADIUS_PACKET = 0x45;
|
||||
const CHUNK_RADIUS_UPDATED_PACKET = 0x46;
|
||||
const ITEM_FRAME_DROP_ITEM_PACKET = 0x47;
|
||||
const REPLACE_ITEM_IN_SLOT_PACKET = 0x48; //ReplaceSelectedItemPacket
|
||||
const REPLACE_ITEM_IN_SLOT_PACKET = 0x48;
|
||||
const GAME_RULES_CHANGED_PACKET = 0x49;
|
||||
const CAMERA_PACKET = 0x4a;
|
||||
const ADD_ITEM_PACKET = 0x4b;
|
||||
@ -126,5 +126,7 @@ interface ProtocolInfo{
|
||||
const SET_TITLE_PACKET = 0x59;
|
||||
const ADD_BEHAVIOR_TREE_PACKET = 0x5a;
|
||||
const STRUCTURE_BLOCK_UPDATE_PACKET = 0x5b;
|
||||
const SHOW_STORE_OFFER_PACKET = 0x5c;
|
||||
const PURCHASE_RECEIPT_PACKET = 0x5d;
|
||||
|
||||
}
|
||||
|
@ -39,20 +39,22 @@ class ResourcePacksInfoPacket extends DataPacket{
|
||||
|
||||
public function decode(){
|
||||
/*$this->mustAccept = $this->getBool();
|
||||
$behaviorPackCount = $this->getUnsignedVarInt();
|
||||
$behaviorPackCount = $this->getLShort();
|
||||
while($behaviorPackCount-- > 0){
|
||||
$id = $this->getString();
|
||||
$version = $this->getString();
|
||||
$size = $this->getUnsignedVarLong();
|
||||
$size = $this->getLLong();
|
||||
$this->behaviorPackEntries[] = new ResourcePackInfoEntry($id, $version, $size);
|
||||
$this->getString();
|
||||
}
|
||||
|
||||
$resourcePackCount = $this->getUnsignedVarInt();
|
||||
$resourcePackCount = $this->getLShort();
|
||||
while($resourcePackCount-- > 0){
|
||||
$id = $this->getString();
|
||||
$version = $this->getString();
|
||||
$size = $this->getUnsignedVarLong();
|
||||
$size = $this->getLLong();
|
||||
$this->resourcePackEntries[] = new ResourcePackInfoEntry($id, $version, $size);
|
||||
$this->getString();
|
||||
}*/
|
||||
}
|
||||
|
||||
@ -60,17 +62,19 @@ class ResourcePacksInfoPacket extends DataPacket{
|
||||
$this->reset();
|
||||
|
||||
$this->putBool($this->mustAccept);
|
||||
$this->putUnsignedVarInt(count($this->behaviorPackEntries));
|
||||
$this->putLShort(count($this->behaviorPackEntries));
|
||||
foreach($this->behaviorPackEntries as $entry){
|
||||
$this->putString($entry->getPackId());
|
||||
$this->putString($entry->getPackVersion());
|
||||
$this->putUnsignedVarLong($entry->getPackSize());
|
||||
$this->putLLong($entry->getPackSize());
|
||||
$this->putString(""); //TODO
|
||||
}
|
||||
$this->putUnsignedVarInt(count($this->resourcePackEntries));
|
||||
$this->putLShort(count($this->resourcePackEntries));
|
||||
foreach($this->resourcePackEntries as $entry){
|
||||
$this->putString($entry->getPackId());
|
||||
$this->putString($entry->getPackVersion());
|
||||
$this->putUnsignedVarLong($entry->getPackSize());
|
||||
$this->putLLong($entry->getPackSize());
|
||||
$this->putString(""); //TODO
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,7 +183,7 @@ auto-updater:
|
||||
|
||||
timings:
|
||||
#Choose the host to use for viewing your timings results.
|
||||
host: mcpetimings.com
|
||||
host: timings.pmmp.io
|
||||
|
||||
console:
|
||||
#Choose whether to enable server stats reporting on the console title.
|
||||
|
@ -50,6 +50,8 @@ class Config{
|
||||
private $correct = false;
|
||||
/** @var int */
|
||||
private $type = Config::DETECT;
|
||||
/** @var int */
|
||||
private $jsonOptions = JSON_PRETTY_PRINT | JSON_BIGINT_AS_STRING;
|
||||
|
||||
public static $formats = [
|
||||
"properties" => Config::PROPERTIES,
|
||||
@ -187,7 +189,7 @@ class Config{
|
||||
$content = $this->writeProperties();
|
||||
break;
|
||||
case Config::JSON:
|
||||
$content = json_encode($this->config, JSON_PRETTY_PRINT | JSON_BIGINT_AS_STRING);
|
||||
$content = json_encode($this->config, $this->jsonOptions);
|
||||
break;
|
||||
case Config::YAML:
|
||||
$content = yaml_emit($this->config, YAML_UTF8_ENCODING);
|
||||
@ -219,6 +221,68 @@ class Config{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the options for the JSON encoding when saving
|
||||
*
|
||||
* @param int $options
|
||||
* @return Config $this
|
||||
* @throws \RuntimeException if the Config is not in JSON
|
||||
* @see json_encode
|
||||
*/
|
||||
public function setJsonOptions(int $options) : Config{
|
||||
if($this->type !== Config::JSON){
|
||||
throw new \RuntimeException("Attempt to set JSON options for non-JSON config");
|
||||
}
|
||||
$this->jsonOptions = $options;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the given option in addition to the currently set JSON options
|
||||
*
|
||||
* @param int $option
|
||||
* @return Config $this
|
||||
* @throws \RuntimeException if the Config is not in JSON
|
||||
* @see json_encode
|
||||
*/
|
||||
public function enableJsonOption(int $option) : Config{
|
||||
if($this->type !== Config::JSON){
|
||||
throw new \RuntimeException("Attempt to enable JSON option for non-JSON config");
|
||||
}
|
||||
$this->jsonOptions |= $option;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the given option for the JSON encoding when saving
|
||||
*
|
||||
* @param int $option
|
||||
* @return Config $this
|
||||
* @throws \RuntimeException if the Config is not in JSON
|
||||
* @see json_encode
|
||||
*/
|
||||
public function disableJsonOption(int $option) : Config{
|
||||
if($this->type !== Config::JSON){
|
||||
throw new \RuntimeException("Attempt to disable JSON option for non-JSON config");
|
||||
}
|
||||
$this->jsonOptions &= ~$option;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the options for the JSON encoding when saving
|
||||
*
|
||||
* @return int
|
||||
* @throws \RuntimeException if the Config is not in JSON
|
||||
* @see json_encode
|
||||
*/
|
||||
public function getJsonOptions() : int{
|
||||
if($this->type !== Config::JSON){
|
||||
throw new \RuntimeException("Attempt to get JSON options for non-JSON config");
|
||||
}
|
||||
return $this->jsonOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $k
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user