public function __construct($stream, LoopInterface $loop)
 {
     parent::__construct($stream, $loop);
     $this->lastPacket = $this->currentTime();
     $this->connectionTimer = $loop->addPeriodicTimer(1, function () {
         $currentTime = $this->currentTime();
         if ($currentTime - $this->lastPacket > 10000) {
             $this->disconnectClient((new DisconnectPacket())->setReason('Connection timed out'));
         }
     });
     //default stage is handshake
     $this->stage = Stage::HANDSHAKE();
     //setup the default stage=>packetID=>class map TODO allow passing values in in constructor
     $this->packetClassMap = [STAGE::HANDSHAKE()->getValue() => [0x0 => 'PublicUHC\\MinecraftAuth\\Protocol\\Packets\\HandshakePacket'], STAGE::STATUS()->getValue() => [0x0 => 'PublicUHC\\MinecraftAuth\\Protocol\\Packets\\StatusRequestPacket', 0x1 => 'PublicUHC\\MinecraftAuth\\Protocol\\Packets\\PingRequestPacket'], STAGE::LOGIN()->getValue() => [0x0 => 'PublicUHC\\MinecraftAuth\\Protocol\\Packets\\LoginStartPacket', 0x1 => 'PublicUHC\\MinecraftAuth\\Protocol\\Packets\\EncryptionResponsePacket']];
     //call $this->onData whenever there is data available
     $this->on('data', [$this, 'onData']);
 }
 /**
  * Get the stage this packet is for
  * @return Stage
  */
 function getStage()
 {
     return Stage::HANDSHAKE();
 }