Separate packet-sender functionality from NetworkInterface, break cyclic dependency between NetworkInterface and NetworkSession

This commit is contained in:
Dylan K. Taylor 2019-06-26 18:19:29 +01:00
parent 9cedfeb2b2
commit 7eaca6bbaa
5 changed files with 110 additions and 39 deletions

View File

@ -26,8 +26,6 @@ declare(strict_types=1);
*/
namespace pocketmine\network;
use pocketmine\network\mcpe\NetworkSession;
/**
* Network interfaces are transport layers which can be used to transmit packets between the server and clients.
*/
@ -38,23 +36,6 @@ interface NetworkInterface{
*/
public function start() : void;
/**
* Sends a packet to the interface, returns an unique identifier for the packet if $needACK is true
*
* @param NetworkSession $session
* @param string $payload
* @param bool $immediate
*/
public function putPacket(NetworkSession $session, string $payload, bool $immediate = true) : void;
/**
* Terminates the connection
*
* @param NetworkSession $session
* @param string $reason
*/
public function close(NetworkSession $session, string $reason = "unknown reason") : void;
/**
* @param string $name
*/

View File

@ -137,10 +137,14 @@ class NetworkSession{
/** @var InventoryManager|null */
private $invManager = null;
public function __construct(Server $server, NetworkSessionManager $manager, NetworkInterface $interface, string $ip, int $port){
/** @var PacketSender */
private $sender;
public function __construct(Server $server, NetworkSessionManager $manager, NetworkInterface $interface, PacketSender $sender, string $ip, int $port){
$this->server = $server;
$this->manager = $manager;
$this->interface = $interface;
$this->sender = $sender;
$this->ip = $ip;
$this->port = $port;
@ -431,7 +435,7 @@ class NetworkSession{
$payload = $this->cipher->encrypt($payload);
Timings::$playerNetworkSendEncryptTimer->stopTiming();
}
$this->interface->putPacket($this, $payload, $immediate);
$this->sender->send($payload, $immediate);
}
private function tryDisconnect(\Closure $func, string $reason) : void{
@ -506,7 +510,7 @@ class NetworkSession{
$this->sendDataPacket($reason === "" ? DisconnectPacket::silent() : DisconnectPacket::message($reason), true);
}
$this->interface->close($this, $notify ? $reason : "");
$this->sender->close($notify ? $reason : "");
}
/**

View File

@ -0,0 +1,42 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe;
interface PacketSender{
/**
* Pushes a packet into the channel to be processed.
*
* @param string $payload
* @param bool $immediate
*/
public function send(string $payload, bool $immediate) : void;
/**
* Closes the channel, terminating the connection.
*
* @param string $reason
*/
public function close(string $reason = "unknown reason") : void;
}

View File

@ -42,7 +42,6 @@ use function bin2hex;
use function implode;
use function random_bytes;
use function rtrim;
use function spl_object_id;
use function substr;
use function unserialize;
use const PTHREADS_INHERIT_CONSTANTS;
@ -68,9 +67,6 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{
/** @var NetworkSession[] */
private $sessions = [];
/** @var int[] */
private $identifiers = [];
/** @var ServerHandler */
private $interface;
@ -119,17 +115,15 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{
public function closeSession(int $sessionId, string $reason) : void{
if(isset($this->sessions[$sessionId])){
$session = $this->sessions[$sessionId];
unset($this->identifiers[spl_object_id($session)]);
unset($this->sessions[$sessionId]);
$session->onClientDisconnect($reason);
}
}
public function close(NetworkSession $session, string $reason = "unknown reason") : void{
if(isset($this->identifiers[$h = spl_object_id($session)])){
unset($this->sessions[$this->identifiers[$h]]);
$this->interface->closeSession($this->identifiers[$h], $reason);
unset($this->identifiers[$h]);
public function close(int $sessionId, string $reason = "unknown reason") : void{
if(isset($this->sessions[$sessionId])){
unset($this->sessions[$sessionId]);
$this->interface->closeSession($sessionId, $reason);
}
}
@ -139,9 +133,8 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{
}
public function openSession(int $sessionId, string $address, int $port, int $clientID) : void{
$session = new NetworkSession($this->server, $this->network->getSessionManager(), $this, $address, $port);
$session = new NetworkSession($this->server, $this->network->getSessionManager(), $this, new RakLibPacketSender($sessionId, $this), $address, $port);
$this->sessions[$sessionId] = $session;
$this->identifiers[spl_object_id($session)] = $sessionId;
}
public function handleEncapsulated(int $sessionId, EncapsulatedPacket $packet, int $flags) : void{
@ -225,16 +218,14 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{
}
}
public function putPacket(NetworkSession $session, string $payload, bool $immediate = true) : void{
if(isset($this->identifiers[$h = spl_object_id($session)])){
$identifier = $this->identifiers[$h];
public function putPacket(int $sessionId, string $payload, bool $immediate = true) : void{
if(isset($this->sessions[$sessionId])){
$pk = new EncapsulatedPacket();
$pk->buffer = self::MCPE_RAKNET_PACKET_ID . $payload;
$pk->reliability = PacketReliability::RELIABLE_ORDERED;
$pk->orderChannel = 0;
$this->interface->sendEncapsulated($identifier, $pk, ($immediate ? RakLib::PRIORITY_IMMEDIATE : RakLib::PRIORITY_NORMAL));
$this->interface->sendEncapsulated($sessionId, $pk, ($immediate ? RakLib::PRIORITY_IMMEDIATE : RakLib::PRIORITY_NORMAL));
}
}

View File

@ -0,0 +1,53 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe;
class RakLibPacketSender implements PacketSender{
/** @var int */
private $sessionId;
/** @var RakLibInterface */
private $handler;
/** @var bool */
private $closed = false;
public function __construct(int $sessionId, RakLibInterface $handler){
$this->sessionId = $sessionId;
$this->handler = $handler;
}
public function send(string $payload, bool $immediate) : void{
if(!$this->closed){
$this->handler->putPacket($this->sessionId, $payload, $immediate);
}
}
public function close(string $reason = "unknown reason") : void{
if(!$this->closed){
$this->closed = true;
$this->handler->closeSession($this->sessionId, $reason);
}
}
}