Move more session logic out of Player

This commit is contained in:
Dylan K. Taylor 2018-07-18 12:48:58 +01:00
parent 4d1e2d1b3a
commit 36e197e2a9
2 changed files with 37 additions and 70 deletions

View File

@ -67,7 +67,6 @@ use pocketmine\event\player\PlayerToggleFlightEvent;
use pocketmine\event\player\PlayerToggleSneakEvent; use pocketmine\event\player\PlayerToggleSneakEvent;
use pocketmine\event\player\PlayerToggleSprintEvent; use pocketmine\event\player\PlayerToggleSprintEvent;
use pocketmine\event\player\PlayerTransferEvent; use pocketmine\event\player\PlayerTransferEvent;
use pocketmine\event\server\DataPacketSendEvent;
use pocketmine\inventory\CraftingGrid; use pocketmine\inventory\CraftingGrid;
use pocketmine\inventory\Inventory; use pocketmine\inventory\Inventory;
use pocketmine\inventory\PlayerCursorInventory; use pocketmine\inventory\PlayerCursorInventory;
@ -108,7 +107,6 @@ use pocketmine\network\mcpe\protocol\BookEditPacket;
use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket;
use pocketmine\network\mcpe\protocol\ContainerClosePacket; use pocketmine\network\mcpe\protocol\ContainerClosePacket;
use pocketmine\network\mcpe\protocol\DataPacket; use pocketmine\network\mcpe\protocol\DataPacket;
use pocketmine\network\mcpe\protocol\DisconnectPacket;
use pocketmine\network\mcpe\protocol\EntityEventPacket; use pocketmine\network\mcpe\protocol\EntityEventPacket;
use pocketmine\network\mcpe\protocol\InteractPacket; use pocketmine\network\mcpe\protocol\InteractPacket;
use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket;
@ -185,10 +183,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return $lname !== "rcon" and $lname !== "console" and $len >= 1 and $len <= 16 and preg_match("/[^A-Za-z0-9_ ]/", $name) === 0; return $lname !== "rcon" and $lname !== "console" and $len >= 1 and $len <= 16 and preg_match("/[^A-Za-z0-9_ ]/", $name) === 0;
} }
/** @var NetworkInterface */
protected $interface;
/** /**
* @var PlayerNetworkSessionAdapter * @var PlayerNetworkSessionAdapter
* TODO: remove this once player and network are divorced properly * TODO: remove this once player and network are divorced properly
@ -203,12 +197,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
/** @var int */ /** @var int */
protected $port; protected $port;
/** @var bool[] */
private $needACK = [];
/** @var DataPacket[] */
private $batchedPackets = [];
/** /**
* @var int * @var int
* Last measurement of player's latency in milliseconds. * Last measurement of player's latency in milliseconds.
@ -710,7 +698,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
* @param int $port * @param int $port
*/ */
public function __construct(NetworkInterface $interface, string $ip, int $port){ public function __construct(NetworkInterface $interface, string $ip, int $port){
$this->interface = $interface;
$this->perm = new PermissibleBase($this); $this->perm = new PermissibleBase($this);
$this->namedtag = new CompoundTag(); $this->namedtag = new CompoundTag();
$this->server = Server::getInstance(); $this->server = Server::getInstance();
@ -727,7 +714,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$this->allowMovementCheats = (bool) $this->server->getProperty("player.anti-cheat.allow-movement-cheats", false); $this->allowMovementCheats = (bool) $this->server->getProperty("player.anti-cheat.allow-movement-cheats", false);
$this->sessionAdapter = new PlayerNetworkSessionAdapter($this->server, $this); $this->sessionAdapter = new PlayerNetworkSessionAdapter($this->server, $this, $interface);
} }
/** /**
@ -1802,11 +1789,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
if(count($this->loadQueue) > 0){ if(count($this->loadQueue) > 0){
$this->sendNextChunk(); $this->sendNextChunk();
} }
if(count($this->batchedPackets) > 0){
$this->server->batchPackets([$this], $this->batchedPackets, false);
$this->batchedPackets = [];
}
} }
/** /**
@ -3058,31 +3040,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
} }
/**
* Batch a Data packet into the channel list to send at the end of the tick
*
* @param DataPacket $packet
*
* @return bool
*/
public function batchDataPacket(DataPacket $packet) : bool{
if(!$this->isConnected()){
return false;
}
$timings = Timings::getSendDataPacketTimings($packet);
$timings->startTiming();
$this->server->getPluginManager()->callEvent($ev = new DataPacketSendEvent($this, $packet));
if($ev->isCancelled()){
$timings->stopTiming();
return false;
}
$this->batchedPackets[] = clone $packet;
$timings->stopTiming();
return true;
}
/** /**
* @param DataPacket $packet * @param DataPacket $packet
* @param bool $needACK * @param bool $needACK
@ -3100,25 +3057,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
throw new \InvalidArgumentException("Attempted to send " . get_class($packet) . " to " . $this->getName() . " too early"); throw new \InvalidArgumentException("Attempted to send " . get_class($packet) . " to " . $this->getName() . " too early");
} }
$timings = Timings::getSendDataPacketTimings($packet); return $this->sessionAdapter->sendDataPacket($packet, $immediate);
$timings->startTiming();
try{
$this->server->getPluginManager()->callEvent($ev = new DataPacketSendEvent($this, $packet));
if($ev->isCancelled()){
return false;
}
$identifier = $this->interface->putPacket($this, $packet, $needACK, $immediate);
if($needACK and $identifier !== null){
$this->needACK[$identifier] = false;
return $identifier;
}
return true;
}finally{
$timings->stopTiming();
}
} }
/** /**
@ -3368,12 +3307,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
if($this->isConnected() and !$this->closed){ if($this->isConnected() and !$this->closed){
try{ try{
if($notify and strlen($reason) > 0){ $this->sessionAdapter->serverDisconnect($reason, $notify);
$pk = new DisconnectPacket();
$pk->message = $reason;
$this->directDataPacket($pk);
}
$this->interface->close($this, $notify ? $reason : "");
$this->sessionAdapter = null; $this->sessionAdapter = null;
$this->server->getPluginManager()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_USERS, $this); $this->server->getPluginManager()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_USERS, $this);

View File

@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe;
use pocketmine\event\server\DataPacketReceiveEvent; use pocketmine\event\server\DataPacketReceiveEvent;
use pocketmine\event\server\DataPacketSendEvent;
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\BlockEntityDataPacket; use pocketmine\network\mcpe\protocol\BlockEntityDataPacket;
@ -37,6 +38,7 @@ use pocketmine\network\mcpe\protocol\CommandRequestPacket;
use pocketmine\network\mcpe\protocol\ContainerClosePacket; use pocketmine\network\mcpe\protocol\ContainerClosePacket;
use pocketmine\network\mcpe\protocol\CraftingEventPacket; use pocketmine\network\mcpe\protocol\CraftingEventPacket;
use pocketmine\network\mcpe\protocol\DataPacket; use pocketmine\network\mcpe\protocol\DataPacket;
use pocketmine\network\mcpe\protocol\DisconnectPacket;
use pocketmine\network\mcpe\protocol\EntityEventPacket; use pocketmine\network\mcpe\protocol\EntityEventPacket;
use pocketmine\network\mcpe\protocol\EntityFallPacket; use pocketmine\network\mcpe\protocol\EntityFallPacket;
use pocketmine\network\mcpe\protocol\EntityPickRequestPacket; use pocketmine\network\mcpe\protocol\EntityPickRequestPacket;
@ -62,6 +64,7 @@ use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket;
use pocketmine\network\mcpe\protocol\ShowCreditsPacket; use pocketmine\network\mcpe\protocol\ShowCreditsPacket;
use pocketmine\network\mcpe\protocol\SpawnExperienceOrbPacket; use pocketmine\network\mcpe\protocol\SpawnExperienceOrbPacket;
use pocketmine\network\mcpe\protocol\TextPacket; use pocketmine\network\mcpe\protocol\TextPacket;
use pocketmine\network\NetworkInterface;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\Server; use pocketmine\Server;
use pocketmine\timings\Timings; use pocketmine\timings\Timings;
@ -72,10 +75,13 @@ class PlayerNetworkSessionAdapter extends NetworkSession{
private $server; private $server;
/** @var Player */ /** @var Player */
private $player; private $player;
/** @var NetworkInterface */
private $interface;
public function __construct(Server $server, Player $player){ public function __construct(Server $server, Player $player, NetworkInterface $interface){
$this->server = $server; $this->server = $server;
$this->player = $player; $this->player = $player;
$this->interface = $interface;
} }
public function handleDataPacket(DataPacket $packet) : void{ public function handleDataPacket(DataPacket $packet) : void{
@ -96,6 +102,33 @@ class PlayerNetworkSessionAdapter extends NetworkSession{
$timings->stopTiming(); $timings->stopTiming();
} }
public function sendDataPacket(DataPacket $packet, bool $immediate = false) : bool{
$timings = Timings::getSendDataPacketTimings($packet);
$timings->startTiming();
try{
$this->server->getPluginManager()->callEvent($ev = new DataPacketSendEvent($this->player, $packet));
if($ev->isCancelled()){
return false;
}
$this->interface->putPacket($this->player, $packet, false, $immediate);
return true;
}finally{
$timings->stopTiming();
}
}
public function serverDisconnect(string $reason, bool $notify = true) : void{
if($notify){
$pk = new DisconnectPacket();
$pk->message = $reason;
$pk->hideDisconnectionScreen = $reason === "";
$this->sendDataPacket($pk, true);
}
$this->interface->close($this->player, $notify ? $reason : "");
}
public function handleLogin(LoginPacket $packet) : bool{ public function handleLogin(LoginPacket $packet) : bool{
return $this->player->handleLogin($packet); return $this->player->handleLogin($packet);
} }