mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-14 13:25:11 +00:00
Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
308cdb6863 | |||
ae50b952f1 | |||
efdd7a186d | |||
b574d49d36 | |||
47e9ecd257 | |||
799739fe86 | |||
168af31fd7 | |||
b56b35b10d | |||
71aad310c6 | |||
38828e2b42 |
Submodule build/php updated: fb297eb511...b2207cf70d
@ -12,3 +12,20 @@ Released 17th February 2023.
|
||||
## General
|
||||
- Added support for Minecraft: Bedrock Edition 1.19.62.
|
||||
- Removed support for older versions.
|
||||
|
||||
# 4.15.1
|
||||
Released 21st February 2023.
|
||||
|
||||
## Fixes
|
||||
- Fixed dropped items not despawning when in non-ticking chunks.
|
||||
- Fixed dropped items not despawning if an infinite pickup delay is set.
|
||||
- Fixed infinite despawn delay (never despawn) being ignored for dropped items.
|
||||
|
||||
# 4.15.2
|
||||
Released 24th February 2023.
|
||||
|
||||
## General
|
||||
- Accept Minecraft: Bedrock Edition 1.19.63 (identical protocol to 1.19.62, but different version due to Mojang mixup).
|
||||
|
||||
## Fixes
|
||||
- Fixed `World Population` timer sometimes not being stopped, causing strange results in timings reports.
|
@ -54,7 +54,7 @@
|
||||
"webmozart/path-util": "^2.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "1.9.17",
|
||||
"phpstan/phpstan": "1.9.18",
|
||||
"phpstan/phpstan-phpunit": "^1.1.0",
|
||||
"phpstan/phpstan-strict-rules": "^1.2.0",
|
||||
"phpunit/phpunit": "^9.2"
|
||||
|
14
composer.lock
generated
14
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "56a1e8facd8fd7d56d6c7d2eb390e842",
|
||||
"content-hash": "a6622fa16daeb7ba4d9a792579db468f",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/json-comment",
|
||||
@ -1832,16 +1832,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan",
|
||||
"version": "1.9.17",
|
||||
"version": "1.9.18",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpstan.git",
|
||||
"reference": "204e459e7822f2c586463029f5ecec31bb45a1f2"
|
||||
"reference": "f2d5cf71be91172a57c649770b73c20ebcffb0bf"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/204e459e7822f2c586463029f5ecec31bb45a1f2",
|
||||
"reference": "204e459e7822f2c586463029f5ecec31bb45a1f2",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/f2d5cf71be91172a57c649770b73c20ebcffb0bf",
|
||||
"reference": "f2d5cf71be91172a57c649770b73c20ebcffb0bf",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1871,7 +1871,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/phpstan/phpstan/issues",
|
||||
"source": "https://github.com/phpstan/phpstan/tree/1.9.17"
|
||||
"source": "https://github.com/phpstan/phpstan/tree/1.9.18"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -1887,7 +1887,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-02-08T12:25:00+00:00"
|
||||
"time": "2023-02-17T15:01:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan-phpunit",
|
||||
|
@ -31,7 +31,7 @@ use function str_repeat;
|
||||
|
||||
final class VersionInfo{
|
||||
public const NAME = "PocketMine-MP";
|
||||
public const BASE_VERSION = "4.15.0";
|
||||
public const BASE_VERSION = "4.15.2";
|
||||
public const IS_DEVELOPMENT_BUILD = false;
|
||||
public const BUILD_CHANNEL = "stable";
|
||||
|
||||
|
@ -113,33 +113,42 @@ class ItemEntity extends Entity{
|
||||
|
||||
$hasUpdate = parent::entityBaseTick($tickDiff);
|
||||
|
||||
if(!$this->isFlaggedForDespawn() && $this->pickupDelay !== self::NEVER_DESPAWN){ //Infinite delay
|
||||
if($this->isFlaggedForDespawn()){
|
||||
return $hasUpdate;
|
||||
}
|
||||
|
||||
if($this->pickupDelay !== self::NEVER_DESPAWN && $this->pickupDelay > 0){ //Infinite delay
|
||||
$hasUpdate = true;
|
||||
$this->pickupDelay -= $tickDiff;
|
||||
if($this->pickupDelay < 0){
|
||||
$this->pickupDelay = 0;
|
||||
}
|
||||
if($this->hasMovementUpdate() && $this->despawnDelay % self::MERGE_CHECK_PERIOD === 0){
|
||||
$mergeable = [$this]; //in case the merge target ends up not being this
|
||||
$mergeTarget = $this;
|
||||
foreach($this->getWorld()->getNearbyEntities($this->boundingBox->expandedCopy(0.5, 0.5, 0.5), $this) as $entity){
|
||||
if(!$entity instanceof ItemEntity || $entity->isFlaggedForDespawn()){
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if($entity->isMergeable($this)){
|
||||
$mergeable[] = $entity;
|
||||
if($entity->item->getCount() > $mergeTarget->item->getCount()){
|
||||
$mergeTarget = $entity;
|
||||
}
|
||||
}
|
||||
if($this->hasMovementUpdate() && $this->despawnDelay % self::MERGE_CHECK_PERIOD === 0){
|
||||
$mergeable = [$this]; //in case the merge target ends up not being this
|
||||
$mergeTarget = $this;
|
||||
foreach($this->getWorld()->getNearbyEntities($this->boundingBox->expandedCopy(0.5, 0.5, 0.5), $this) as $entity){
|
||||
if(!$entity instanceof ItemEntity || $entity->isFlaggedForDespawn()){
|
||||
continue;
|
||||
}
|
||||
foreach($mergeable as $itemEntity){
|
||||
if($itemEntity !== $mergeTarget){
|
||||
$itemEntity->tryMergeInto($mergeTarget);
|
||||
|
||||
if($entity->isMergeable($this)){
|
||||
$mergeable[] = $entity;
|
||||
if($entity->item->getCount() > $mergeTarget->item->getCount()){
|
||||
$mergeTarget = $entity;
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach($mergeable as $itemEntity){
|
||||
if($itemEntity !== $mergeTarget){
|
||||
$itemEntity->tryMergeInto($mergeTarget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!$this->isFlaggedForDespawn() && $this->despawnDelay !== self::NEVER_DESPAWN){
|
||||
$hasUpdate = true;
|
||||
$this->despawnDelay -= $tickDiff;
|
||||
if($this->despawnDelay <= 0){
|
||||
$ev = new ItemDespawnEvent($this);
|
||||
@ -148,7 +157,6 @@ class ItemEntity extends Entity{
|
||||
$this->despawnDelay = self::DEFAULT_DESPAWN_DELAY;
|
||||
}else{
|
||||
$this->flagForDespawn();
|
||||
$hasUpdate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ use pocketmine\player\XboxLivePlayerInfo;
|
||||
use pocketmine\Server;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use function is_array;
|
||||
use function preg_match;
|
||||
|
||||
/**
|
||||
* Handles the initial login phase of the session. This handler is used as the initial state.
|
||||
@ -63,18 +64,6 @@ class LoginPacketHandler extends PacketHandler{
|
||||
){}
|
||||
|
||||
public function handleLogin(LoginPacket $packet) : bool{
|
||||
if(!$this->isCompatibleProtocol($packet->protocol)){
|
||||
$this->session->sendDataPacket(PlayStatusPacket::create($packet->protocol < ProtocolInfo::CURRENT_PROTOCOL ? PlayStatusPacket::LOGIN_FAILED_CLIENT : PlayStatusPacket::LOGIN_FAILED_SERVER), true);
|
||||
|
||||
//This pocketmine disconnect message will only be seen by the console (PlayStatusPacket causes the messages to be shown for the client)
|
||||
$this->session->disconnect(
|
||||
$this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_disconnect_incompatibleProtocol((string) $packet->protocol)),
|
||||
false
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$extraData = $this->fetchAuthData($packet->chainDataJwt);
|
||||
|
||||
if(!Player::isValidUserName($extraData->displayName)){
|
||||
@ -236,8 +225,4 @@ class LoginPacketHandler extends PacketHandler{
|
||||
$this->server->getAsyncPool()->submitTask(new ProcessLoginTask($packet->chainDataJwt->chain, $packet->clientDataJwt, $authRequired, $this->authCallback));
|
||||
$this->session->setHandler(null); //drop packets received during login verification
|
||||
}
|
||||
|
||||
protected function isCompatibleProtocol(int $protocolVersion) : bool{
|
||||
return $protocolVersion === ProtocolInfo::CURRENT_PROTOCOL;
|
||||
}
|
||||
}
|
||||
|
@ -71,6 +71,9 @@ final class SessionStartPacketHandler extends PacketHandler{
|
||||
}
|
||||
|
||||
protected function isCompatibleProtocol(int $protocolVersion) : bool{
|
||||
return $protocolVersion === ProtocolInfo::CURRENT_PROTOCOL;
|
||||
//TODO: REMOVE THIS
|
||||
//1.19.63 released with an unchanged protocol, but a bumped protocol version, since they forgot to do it in the
|
||||
//previous release. Since they are functionally identical, we can accept both.
|
||||
return $protocolVersion === ProtocolInfo::CURRENT_PROTOCOL || $protocolVersion === 568;
|
||||
}
|
||||
}
|
||||
|
@ -3118,59 +3118,63 @@ class World implements ChunkManager{
|
||||
|
||||
Timings::$population->startTiming();
|
||||
|
||||
for($xx = -1; $xx <= 1; ++$xx){
|
||||
for($zz = -1; $zz <= 1; ++$zz){
|
||||
if($this->isChunkLocked($chunkX + $xx, $chunkZ + $zz)){
|
||||
//chunk is already in use by another generation request; queue the request for later
|
||||
return $resolver?->getPromise() ?? $this->enqueuePopulationRequest($chunkX, $chunkZ, $associatedChunkLoader);
|
||||
try{
|
||||
for($xx = -1; $xx <= 1; ++$xx){
|
||||
for($zz = -1; $zz <= 1; ++$zz){
|
||||
if($this->isChunkLocked($chunkX + $xx, $chunkZ + $zz)){
|
||||
//chunk is already in use by another generation request; queue the request for later
|
||||
return $resolver?->getPromise() ?? $this->enqueuePopulationRequest($chunkX, $chunkZ, $associatedChunkLoader);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->activeChunkPopulationTasks[$chunkHash] = true;
|
||||
if($resolver === null){
|
||||
$resolver = new PromiseResolver();
|
||||
$this->chunkPopulationRequestMap[$chunkHash] = $resolver;
|
||||
}
|
||||
|
||||
$chunkPopulationLockId = new ChunkLockId();
|
||||
|
||||
$temporaryChunkLoader = new class implements ChunkLoader{};
|
||||
for($xx = -1; $xx <= 1; ++$xx){
|
||||
for($zz = -1; $zz <= 1; ++$zz){
|
||||
$this->lockChunk($chunkX + $xx, $chunkZ + $zz, $chunkPopulationLockId);
|
||||
$this->registerChunkLoader($temporaryChunkLoader, $chunkX + $xx, $chunkZ + $zz);
|
||||
$this->activeChunkPopulationTasks[$chunkHash] = true;
|
||||
if($resolver === null){
|
||||
$resolver = new PromiseResolver();
|
||||
$this->chunkPopulationRequestMap[$chunkHash] = $resolver;
|
||||
}
|
||||
}
|
||||
|
||||
$centerChunk = $this->loadChunk($chunkX, $chunkZ);
|
||||
$adjacentChunks = $this->getAdjacentChunks($chunkX, $chunkZ);
|
||||
$task = new PopulationTask(
|
||||
$this->worldId,
|
||||
$chunkX,
|
||||
$chunkZ,
|
||||
$centerChunk,
|
||||
$adjacentChunks,
|
||||
function(Chunk $centerChunk, array $adjacentChunks) use ($chunkPopulationLockId, $chunkX, $chunkZ, $temporaryChunkLoader) : void{
|
||||
if(!$this->isLoaded()){
|
||||
return;
|
||||
$chunkPopulationLockId = new ChunkLockId();
|
||||
|
||||
$temporaryChunkLoader = new class implements ChunkLoader{
|
||||
};
|
||||
for($xx = -1; $xx <= 1; ++$xx){
|
||||
for($zz = -1; $zz <= 1; ++$zz){
|
||||
$this->lockChunk($chunkX + $xx, $chunkZ + $zz, $chunkPopulationLockId);
|
||||
$this->registerChunkLoader($temporaryChunkLoader, $chunkX + $xx, $chunkZ + $zz);
|
||||
}
|
||||
|
||||
$this->generateChunkCallback($chunkPopulationLockId, $chunkX, $chunkZ, $centerChunk, $adjacentChunks, $temporaryChunkLoader);
|
||||
}
|
||||
);
|
||||
$workerId = $this->workerPool->selectWorker();
|
||||
if(!isset($this->workerPool->getRunningWorkers()[$workerId]) && isset($this->generatorRegisteredWorkers[$workerId])){
|
||||
$this->logger->debug("Selected worker $workerId previously had generator registered, but is now offline");
|
||||
unset($this->generatorRegisteredWorkers[$workerId]);
|
||||
}
|
||||
if(!isset($this->generatorRegisteredWorkers[$workerId])){
|
||||
$this->registerGeneratorToWorker($workerId);
|
||||
}
|
||||
$this->workerPool->submitTaskToWorker($task, $workerId);
|
||||
|
||||
Timings::$population->stopTiming();
|
||||
return $resolver->getPromise();
|
||||
$centerChunk = $this->loadChunk($chunkX, $chunkZ);
|
||||
$adjacentChunks = $this->getAdjacentChunks($chunkX, $chunkZ);
|
||||
$task = new PopulationTask(
|
||||
$this->worldId,
|
||||
$chunkX,
|
||||
$chunkZ,
|
||||
$centerChunk,
|
||||
$adjacentChunks,
|
||||
function(Chunk $centerChunk, array $adjacentChunks) use ($chunkPopulationLockId, $chunkX, $chunkZ, $temporaryChunkLoader) : void{
|
||||
if(!$this->isLoaded()){
|
||||
return;
|
||||
}
|
||||
|
||||
$this->generateChunkCallback($chunkPopulationLockId, $chunkX, $chunkZ, $centerChunk, $adjacentChunks, $temporaryChunkLoader);
|
||||
}
|
||||
);
|
||||
$workerId = $this->workerPool->selectWorker();
|
||||
if(!isset($this->workerPool->getRunningWorkers()[$workerId]) && isset($this->generatorRegisteredWorkers[$workerId])){
|
||||
$this->logger->debug("Selected worker $workerId previously had generator registered, but is now offline");
|
||||
unset($this->generatorRegisteredWorkers[$workerId]);
|
||||
}
|
||||
if(!isset($this->generatorRegisteredWorkers[$workerId])){
|
||||
$this->registerGeneratorToWorker($workerId);
|
||||
}
|
||||
$this->workerPool->submitTaskToWorker($task, $workerId);
|
||||
|
||||
return $resolver->getPromise();
|
||||
}finally{
|
||||
Timings::$population->stopTiming();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user