+ magic |= Protocol::Compression;
+
+ stream << magic;
+
+ // here goes the list of protocols we support, in order of preference
+ PeerFactory::ProtoList protos = PeerFactory::supportedProtocols();
+ for (int i = 0; i < protos.count(); ++i) {
+ quint32 reply = protos[i].first;
+ reply |= protos[i].second<<8;
+ if (i == protos.count() - 1)
+ reply |= 0x80000000; // end list
+ stream << reply;
+ }
+
+ socket()->flush(); // make sure the probing data is sent immediately
+ return;
+ }
+
+ // If we arrive here, it's the second connection attempt, meaning probing was not successful -> enable legacy support
+
+ qDebug() << "Legacy core detected, switching to compatibility mode";
+
+ RemotePeer *peer = PeerFactory::createPeer(PeerFactory::ProtoDescriptor(Protocol::LegacyProtocol, 0), this, socket(), Compressor::NoCompression, this);
+ // Only needed for the legacy peer, as all others check the protocol version before instantiation
+ connect(peer, SIGNAL(protocolVersionMismatch(int,int)), SLOT(onProtocolVersionMismatch(int,int)));
+
+ setPeer(peer);
+}
+
+
+void ClientAuthHandler::onReadyRead()
+{
+ if (socket()->bytesAvailable() < 4)
+ return;
+
+ if (!_probing)
+ return; // make sure to not read more data than needed
+
+ _probing = false;
+ disconnect(socket(), SIGNAL(readyRead()), this, SLOT(onReadyRead()));
+
+ quint32 reply;
+ socket()->read((char *)&reply, 4);
+ reply = qFromBigEndian<quint32>(reply);
+
+ Protocol::Type type = static_cast<Protocol::Type>(reply & 0xff);
+ quint16 protoFeatures = static_cast<quint16>(reply>>8 & 0xffff);
+ _connectionFeatures = static_cast<quint8>(reply>>24);
+
+ Compressor::CompressionLevel level;
+ if (_connectionFeatures & Protocol::Compression)
+ level = Compressor::BestCompression;
+ else
+ level = Compressor::NoCompression;
+
+ RemotePeer *peer = PeerFactory::createPeer(PeerFactory::ProtoDescriptor(type, protoFeatures), this, socket(), level, this);
+ if (!peer) {
+ qWarning() << "No valid protocol supported for this core!";
+ emit errorPopup(tr("<b>Incompatible Quassel Core!</b><br>"
+ "None of the protocols this client speaks are supported by the core you are trying to connect to."));
+
+ requestDisconnect(tr("Core speaks none of the protocols we support"));
+ return;
+ }
+
+ if (peer->protocol() == Protocol::LegacyProtocol) {
+ connect(peer, SIGNAL(protocolVersionMismatch(int,int)), SLOT(onProtocolVersionMismatch(int,int)));
+ _legacy = true;
+ }