/// <summary>
        /// Fired when packet received.
        /// </summary>
        private void PacketReceived(PacketBase packet)
        {
            try
            {
                //reject if wrong game or version
                if ((packet.GameTitle != _config.GameTitle) || (packet.GameVersion != _config.GameVersion))
                {
                    return;
                }

                //special logic for invite requests
                if ((packet is CommandRequestPacket p1) && (p1.CommandType == CommandType.ConnectToPlayer))
                {
                    _commandRequestsReceived++;
                    PacketParser  parser          = new PacketParser(p1.Data);
                    string        playerName      = parser.GetString();
                    NetworkPlayer pendingOpponent = new NetworkPlayer(p1.SourceIP, p1.GameTitle, p1.GameVersion, playerName, p1.Sequence);
                    OpponentInviteReceived?.InvokeFromTask(pendingOpponent);
                    return;
                }

                ////special logic for end-session requests
                //if ((packet is CommandRequestPacket p3) && (p3.CommandType == CommandType.))

                ////reject if wrong opponent
                //if ((!packet.SourceIP.Equals(_config.ServerIP)) && ((_opponent == null) || (!packet.SourceIP.Equals(_opponent.IP))))
                //    return;

                //queue packet for processing
                lock (_incomingPackets)
                {
                    _incomingPackets.Add(packet);
                }

                //signal
                _incomingPacketSignal.Set();
            }
            catch (Exception ex)
            {
                _tcpErrors++;
                Log.Write("PacketReceived: Error processing packet");
                ErrorHandler.LogError(ex);
            }
        }