From 602bdf27a5e5bd341b52eda5d88bfed9a65b1a79 Mon Sep 17 00:00:00 2001 From: Shoghi Cervantes Date: Thu, 2 Oct 2014 16:58:37 +0200 Subject: [PATCH] Compatibility with pthreads > 2.0.8 --- .travis.yml | 2 +- src/pocketmine/Player.php | 10 ++++--- src/pocketmine/Server.php | 4 ++- src/pocketmine/command/CommandReader.php | 7 +++-- src/pocketmine/entity/Entity.php | 9 +++--- src/pocketmine/event/TimingsHandler.php | 2 +- src/pocketmine/level/Level.php | 12 ++++---- .../level/format/generic/BaseFullChunk.php | 4 +++ .../generator/GenerationRequestManager.php | 7 ++++- .../level/generator/GenerationThread.php | 6 ++-- src/pocketmine/network/RakLibInterface.php | 30 +++++++++++-------- src/raklib | 2 +- 12 files changed, 58 insertions(+), 37 deletions(-) diff --git a/.travis.yml b/.travis.yml index e02a9e81e..40480328c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ branches: before_script: - mkdir plugins - wget -O plugins/DevTools.phar https://github.com/PocketMine/DevTools/releases/download/v1.9.0/DevTools_v1.9.0.phar - - pecl install channel://pecl.php.net/pthreads-2.0.9 + - pecl install channel://pecl.php.net/pthreads-2.0.10 - pecl install channel://pecl.php.net/weakref-0.2.4 - echo | pecl install channel://pecl.php.net/yaml-1.1.1 diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 3bb151290..555cda26f 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -661,13 +661,13 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $this->inventory->sendContents($this); $this->inventory->sendArmorContents($this); - $this->spawnToAll(); - $this->server->getPluginManager()->callEvent($ev = new PlayerJoinEvent($this, TextFormat::YELLOW . $this->getName() . " joined the game")); if(strlen(trim($ev->getJoinMessage())) > 0){ $this->server->broadcastMessage($ev->getJoinMessage()); } + $this->spawnToAll(); + if($this->server->getUpdater()->hasUpdate() and $this->hasPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE)){ $this->server->getUpdater()->showPlayerUpdate($this); } @@ -1171,8 +1171,8 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $this->processMovement(); - $hasUpdate = $this->entityBaseTick(); - foreach($this->getLevel()->getNearbyEntities($this->boundingBox->grow(1, 1, 1), $this) as $entity){ + $this->entityBaseTick(); + foreach($this->level->getNearbyEntities($this->boundingBox->grow(1, 1, 1), $this) as $entity){ if($entity instanceof Arrow and $entity->onGround and $this->motionX == 0 and $this->motionY == 0 and $this->motionZ == 0){ if($entity->dead !== true){ $item = Item::get(Item::ARROW, 0, 1); @@ -2418,6 +2418,8 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $this->server->broadcast($ev->getDeathMessage(), Server::BROADCAST_CHANNEL_USERS); } + $this->despawnFromAll(); + } public function setHealth($amount){ diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index fd902ac99..082256e66 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -141,6 +141,7 @@ class Server{ /** @var CommandReader */ private $console = null; + private $consoleThreaded; /** @var SimpleCommandMap */ private $commandMap = null; @@ -1449,7 +1450,8 @@ class Server{ $this->banByIP = new BanList($this->dataPath . "banned-ips.txt"); $this->banByIP->load(); - $this->console = new CommandReader(); + $this->consoleThreaded = new \Threaded(); + $this->console = new CommandReader($this->consoleThreaded); $version = new VersionString($this->getPocketMineVersion()); $this->logger->info("Starting Minecraft: PE server version " . TextFormat::AQUA . $this->getVersion()); diff --git a/src/pocketmine/command/CommandReader.php b/src/pocketmine/command/CommandReader.php index d908ecf77..fc5bddc89 100644 --- a/src/pocketmine/command/CommandReader.php +++ b/src/pocketmine/command/CommandReader.php @@ -31,13 +31,15 @@ class CommandReader extends Thread{ private $readline; /** @var \Threaded */ - private $buffer; + protected $buffer; /** + * @param \Threaded $threaded * @param string $stream */ - public function __construct($stream = "php://stdin"){ + public function __construct(\Threaded $threaded, $stream = "php://stdin"){ $this->stream = $stream; + $this->buffer = $threaded; $this->start(); } @@ -70,7 +72,6 @@ class CommandReader extends Thread{ } public function run(){ - $this->buffer = new \Threaded; $opts = getopt("", ["disable-readline"]); if(extension_loaded("readline") and $this->stream === "php://stdin" and !isset($opts["disable-readline"])){ $this->readline = true; diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index c7f19a533..fa70052ea 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -459,6 +459,8 @@ abstract class Entity extends Position implements Metadatable{ } public function entityBaseTick(){ + + Timings::$tickEntityTimer->startTiming(); //TODO: check vehicles $this->justCreated = false; @@ -466,7 +468,7 @@ abstract class Entity extends Position implements Metadatable{ if($this->dead === true and !$isPlayer){ $this->close(); - + Timings::$tickEntityTimer->stopTiming(); return false; }elseif($this->dead === true){ $this->despawnFromAll(); @@ -509,6 +511,8 @@ abstract class Entity extends Position implements Metadatable{ ++$this->age; ++$this->ticksLived; + + Timings::$tickEntityTimer->stopTiming(); } public function updateMovement(){ @@ -1163,9 +1167,6 @@ abstract class Entity extends Position implements Metadatable{ $this->server->getPluginManager()->callEvent(new EntityDespawnEvent($this)); $this->closed = true; unset($this->level->updateEntities[$this->id]); - if($this->chunk instanceof FullChunk){ - $this->chunk->removeEntity($this); - } if(($level = $this->getLevel()) instanceof Level){ $level->removeEntity($this); } diff --git a/src/pocketmine/event/TimingsHandler.php b/src/pocketmine/event/TimingsHandler.php index 6039e0cc2..808eac0c0 100644 --- a/src/pocketmine/event/TimingsHandler.php +++ b/src/pocketmine/event/TimingsHandler.php @@ -101,7 +101,7 @@ class TimingsHandler{ if(PluginManager::$useTimings){ foreach(self::$HANDLERS as $timings){ if($timings->curTickTotal > 0.05){ - $timings->violations += ceil($timings->curTickTotal / 0.05); + $timings->violations += round($timings->curTickTotal / 0.05); } $timings->curTickTotal = 0; $timings->timingDepth = 0; diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 488d3b886..f5f6a9a6d 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -519,13 +519,13 @@ class Level implements ChunkManager, Metadatable{ $this->timings->entityTick->startTiming(); //Update entities that need update //if(count($this->updateEntities) > 0){ - //Timings::$tickEntityTimer->startTiming(); + Timings::$tickEntityTimer->startTiming(); foreach($this->entities as $id => $entity){ - if($entity->onUpdate() !== true){ - unset($this->updateEntities[$id]); + if(!$entity->closed){ + $entity->onUpdate(); } } - //Timings::$tickEntityTimer->stopTiming(); + Timings::$tickEntityTimer->stopTiming(); //} $this->timings->entityTick->stopTiming(); @@ -1706,8 +1706,8 @@ class Level implements ChunkManager, Metadatable{ $entity->kill(); } - if($this->isChunkLoaded($entity->chunkX, $entity->chunkZ)){ - $this->getChunk($entity->chunkX, $entity->chunkZ, true)->removeEntity($entity); + if(($chunk = $this->getChunk($entity->chunkX, $entity->chunkZ)) instanceof FullChunk){ + $chunk->removeEntity($entity); } unset($this->entities[$entity->getID()]); diff --git a/src/pocketmine/level/format/generic/BaseFullChunk.php b/src/pocketmine/level/format/generic/BaseFullChunk.php index dafb66aad..646baf1ef 100644 --- a/src/pocketmine/level/format/generic/BaseFullChunk.php +++ b/src/pocketmine/level/format/generic/BaseFullChunk.php @@ -29,6 +29,7 @@ use pocketmine\level\format\FullChunk; use pocketmine\level\format\LevelProvider; use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\String; +use pocketmine\Player; use pocketmine\tile\Chest; use pocketmine\tile\Furnace; use pocketmine\tile\Sign; @@ -268,6 +269,9 @@ abstract class BaseFullChunk implements FullChunk{ } if($this->getProvider()->unloadChunk($this->getX(), $this->getZ(), $safe)){ foreach($this->getEntities() as $entity){ + if($entity instanceof Player){ + continue; + } $entity->close(); } foreach($this->getTiles() as $tile){ diff --git a/src/pocketmine/level/generator/GenerationRequestManager.php b/src/pocketmine/level/generator/GenerationRequestManager.php index 855a15323..b8f4b00bd 100644 --- a/src/pocketmine/level/generator/GenerationRequestManager.php +++ b/src/pocketmine/level/generator/GenerationRequestManager.php @@ -33,12 +33,17 @@ class GenerationRequestManager{ /** @var GenerationThread */ protected $generationThread; + private $internalThreaded; + private $externalThreaded; + /** * @param Server $server */ public function __construct(Server $server){ $this->server = $server; - $this->generationThread = new GenerationThread($server->getLogger(), $server->getLoader()); + $this->internalThreaded = new \Threaded(); + $this->externalThreaded = new \Threaded(); + $this->generationThread = new GenerationThread($this->internalThreaded, $this->externalThreaded, $server->getLogger(), $server->getLoader()); } /** diff --git a/src/pocketmine/level/generator/GenerationThread.php b/src/pocketmine/level/generator/GenerationThread.php index f54a2a681..dee18e5dd 100644 --- a/src/pocketmine/level/generator/GenerationThread.php +++ b/src/pocketmine/level/generator/GenerationThread.php @@ -77,15 +77,15 @@ class GenerationThread extends Thread{ return $this->logger; } - public function __construct(\ThreadedLogger $logger, \ClassLoader $loader){ + public function __construct(\Threaded $internalThreaded, \Threaded $externalThreaded, \ThreadedLogger $logger, \ClassLoader $loader){ $this->loader = $loader; $this->logger = $logger; $loadPaths = []; $this->addDependency($loadPaths, new \ReflectionClass($this->loader)); $this->loadPaths = array_reverse($loadPaths); - $this->externalQueue = new \Threaded(); - $this->internalQueue = new \Threaded(); + $this->externalQueue = $internalThreaded; + $this->internalQueue = $externalThreaded; $this->start(); } diff --git a/src/pocketmine/network/RakLibInterface.php b/src/pocketmine/network/RakLibInterface.php index 89f2a8372..ac42cc546 100644 --- a/src/pocketmine/network/RakLibInterface.php +++ b/src/pocketmine/network/RakLibInterface.php @@ -88,7 +88,7 @@ class RakLibInterface implements ServerInstance, SourceInterface{ private $players = []; /** @var \SplObjectStorage */ - private $identifers; + private $identifiers; /** @var int[] */ private $identifiersACK = []; @@ -98,12 +98,18 @@ class RakLibInterface implements ServerInstance, SourceInterface{ private $upload = 0; private $download = 0; + + private $internalThreaded; + private $externalThreaded; public function __construct(Server $server){ $this->server = $server; - $this->identifers = new \SplObjectStorage(); + $this->identifiers = new \SplObjectStorage(); + + $this->internalThreaded = new \Threaded(); + $this->externalThreaded = new \Threaded(); - $server = new RakLibServer($this->server->getLogger(), $this->server->getLoader(), $this->server->getPort(), $this->server->getIp() === "" ? "0.0.0.0" : $this->server->getIp()); + $server = new RakLibServer($this->internalThreaded, $this->externalThreaded, $this->server->getLogger(), $this->server->getLoader(), $this->server->getPort(), $this->server->getIp() === "" ? "0.0.0.0" : $this->server->getIp()); $this->interface = new ServerHandler($server, $this); $this->setName($this->server->getMotd()); } @@ -128,7 +134,7 @@ class RakLibInterface implements ServerInstance, SourceInterface{ public function closeSession($identifier, $reason){ if(isset($this->players[$identifier])){ $player = $this->players[$identifier]; - $this->identifers->detach($player); + $this->identifiers->detach($player); unset($this->players[$identifier]); unset($this->identifiersACK[$identifier]); $player->close(TextFormat::YELLOW . $player->getName() . " has left the game", $reason); @@ -136,11 +142,11 @@ class RakLibInterface implements ServerInstance, SourceInterface{ } public function close(Player $player, $reason = "unknown reason"){ - if(isset($this->identifers[$player])){ - unset($this->players[$this->identifers[$player]]); - unset($this->identifiersACK[$this->identifers[$player]]); - $this->interface->closeSession($this->identifers[$player], $reason); - $this->identifers->detach($player); + if(isset($this->identifiers[$player])){ + unset($this->players[$this->identifiers[$player]]); + unset($this->identifiersACK[$this->identifiers[$player]]); + $this->interface->closeSession($this->identifiers[$player], $reason); + $this->identifiers->detach($player); } } @@ -156,7 +162,7 @@ class RakLibInterface implements ServerInstance, SourceInterface{ $player = new Player($this, null, $address, $port); $this->players[$identifier] = $player; $this->identifiersACK[$identifier] = 0; - $this->identifers->attach($player, $identifier); + $this->identifiers->attach($player, $identifier); $this->server->addPlayer($identifier, $player); } @@ -207,8 +213,8 @@ class RakLibInterface implements ServerInstance, SourceInterface{ } public function putPacket(Player $player, DataPacket $packet, $needACK = false, $immediate = false){ - if(isset($this->identifers[$player])){ - $identifier = $this->identifers[$player]; + if(isset($this->identifiers[$player])){ + $identifier = $this->identifiers[$player]; $packet->encode(); $pk = new EncapsulatedPacket(); $pk->buffer = $packet->buffer; diff --git a/src/raklib b/src/raklib index 67a6499c4..64a96a7e8 160000 --- a/src/raklib +++ b/src/raklib @@ -1 +1 @@ -Subproject commit 67a6499c41b04ce66a78b46d1749de7b0d2b7190 +Subproject commit 64a96a7e807118bc24de76371dbc3b5325fab709