+ writeMessage(block);
+}
+
+
+/*** Handshake messages ***/
+
+/* These messages are transmitted during handshake phase, which in case of the legacy protocol means they have
+ * a structure different from those being used after the handshake.
+ * Also, the legacy handshake does not fully match the redesigned one, so we'll have to do various mappings here.
+ */
+
+void LegacyPeer::handleHandshakeMessage(const QVariant &msg)
+{
+ QVariantMap m = msg.toMap();
+
+ QString msgType = m["MsgType"].toString();
+ if (msgType.isEmpty()) {
+ emit protocolError(tr("Invalid handshake message!"));
+ return;
+ }
+
+ if (msgType == "ClientInit") {
+ // FIXME only in compat mode
+ uint ver = m["ProtocolVersion"].toUInt();
+ if (ver < coreNeedsProtocol) {
+ emit protocolVersionMismatch((int)ver, (int)coreNeedsProtocol);
+ return;
+ }
+
+#ifndef QT_NO_COMPRESS
+ // FIXME only in compat mode
+ if (m["UseCompression"].toBool()) {
+ socket()->setProperty("UseCompression", true);
+ }
+#endif
+ handle(RegisterClient{Quassel::Features{m["FeatureList"].toStringList(), Quassel::LegacyFeatures(m["Features"].toUInt())},
+ m["ClientVersion"].toString(),
+ m["ClientDate"].toString(),
+ m["UseSsl"].toBool()});
+ }
+
+ else if (msgType == "ClientInitReject") {
+ handle(ClientDenied(m["Error"].toString()));
+ }
+
+ else if (msgType == "ClientInitAck") {
+ // FIXME only in compat mode
+ uint ver = m["ProtocolVersion"].toUInt(); // actually an UInt
+ if (ver < clientNeedsProtocol) {
+ emit protocolVersionMismatch((int)ver, (int)clientNeedsProtocol);
+ return;
+ }
+#ifndef QT_NO_COMPRESS
+ if (m["SupportsCompression"].toBool())
+ socket()->setProperty("UseCompression", true);
+#endif
+
+ handle(ClientRegistered{Quassel::Features{m["FeatureList"].toStringList(), Quassel::LegacyFeatures(m["CoreFeatures"].toUInt())},
+ m["Configured"].toBool(),
+ m["StorageBackends"].toList(),
+ m["Authenticators"].toList(),
+ m["SupportSsl"].toBool()});
+ }
+
+ else if (msgType == "CoreSetupData") {
+ QVariantMap map = m["SetupData"].toMap();
+ handle(SetupData(map["AdminUser"].toString(), map["AdminPasswd"].toString(), map["Backend"].toString(), map["ConnectionProperties"].toMap(), map["Authenticator"].toString(), map["AuthProperties"].toMap()));
+ }
+
+ else if (msgType == "CoreSetupReject") {
+ handle(SetupFailed(m["Error"].toString()));
+ }
+
+ else if (msgType == "CoreSetupAck") {
+ handle(SetupDone());
+ }
+
+ else if (msgType == "ClientLogin") {
+ handle(Login(m["User"].toString(), m["Password"].toString()));
+ }
+
+ else if (msgType == "ClientLoginReject") {
+ handle(LoginFailed(m["Error"].toString()));
+ }
+
+ else if (msgType == "ClientLoginAck") {
+ handle(LoginSuccess());
+ }
+
+ else if (msgType == "SessionInit") {
+ QVariantMap map = m["SessionState"].toMap();
+ handle(SessionState(map["Identities"].toList(), map["BufferInfos"].toList(), map["NetworkIds"].toList()));
+ }
+
+ else {
+ emit protocolError(tr("Unknown protocol message of type %1").arg(msgType));
+ }
+}
+
+
+void LegacyPeer::dispatch(const RegisterClient &msg) {
+ QVariantMap m;
+ m["MsgType"] = "ClientInit";
+ m["Features"] = static_cast<quint32>(msg.features.toLegacyFeatures());
+ m["FeatureList"] = msg.features.toStringList();
+ m["ClientVersion"] = msg.clientVersion;
+ m["ClientDate"] = msg.buildDate;
+
+ // FIXME only in compat mode
+ m["ProtocolVersion"] = protocolVersion;
+ m["UseSsl"] = msg.sslSupported;
+#ifndef QT_NO_COMPRESS
+ m["UseCompression"] = true;
+#else
+ m["UseCompression"] = false;
+#endif
+
+ writeMessage(m);
+}
+
+
+void LegacyPeer::dispatch(const ClientDenied &msg) {
+ QVariantMap m;
+ m["MsgType"] = "ClientInitReject";
+ m["Error"] = msg.errorString;
+
+ writeMessage(m);
+}
+
+
+void LegacyPeer::dispatch(const ClientRegistered &msg) {
+ QVariantMap m;
+ m["MsgType"] = "ClientInitAck";
+ if (hasFeature(Quassel::Feature::ExtendedFeatures)) {
+ m["FeatureList"] = msg.features.toStringList();
+ }
+ else {
+ m["CoreFeatures"] = static_cast<quint32>(msg.features.toLegacyFeatures());
+ }
+ m["StorageBackends"] = msg.backendInfo;
+ if (hasFeature(Quassel::Feature::Authenticators)) {
+ m["Authenticators"] = msg.authenticatorInfo;
+ }
+
+ // FIXME only in compat mode
+ m["ProtocolVersion"] = protocolVersion;
+ m["SupportSsl"] = msg.sslSupported;
+ m["SupportsCompression"] = socket()->property("UseCompression").toBool(); // this property gets already set in the ClientInit handler
+
+ // This is only used for display by really old v10 clients (pre-0.5), and we no longer set this
+ m["CoreInfo"] = QString();
+
+ m["LoginEnabled"] = m["Configured"] = msg.coreConfigured;
+
+ writeMessage(m);
+}
+
+
+void LegacyPeer::dispatch(const SetupData &msg)
+{
+ QVariantMap map;
+ map["AdminUser"] = msg.adminUser;
+ map["AdminPasswd"] = msg.adminPassword;
+ map["Backend"] = msg.backend;
+ map["ConnectionProperties"] = msg.setupData;
+
+ // Auth backend properties.
+ map["Authenticator"] = msg.authenticator;
+ map["AuthProperties"] = msg.authSetupData;
+
+ QVariantMap m;
+ m["MsgType"] = "CoreSetupData";
+ m["SetupData"] = map;
+ writeMessage(m);
+}
+
+
+void LegacyPeer::dispatch(const SetupFailed &msg)
+{
+ QVariantMap m;
+ m["MsgType"] = "CoreSetupReject";
+ m["Error"] = msg.errorString;
+
+ writeMessage(m);
+}
+
+
+void LegacyPeer::dispatch(const SetupDone &msg)
+{
+ Q_UNUSED(msg)
+
+ QVariantMap m;
+ m["MsgType"] = "CoreSetupAck";
+
+ writeMessage(m);
+}
+
+
+void LegacyPeer::dispatch(const Login &msg)
+{
+ QVariantMap m;
+ m["MsgType"] = "ClientLogin";
+ m["User"] = msg.user;
+ m["Password"] = msg.password;
+
+ writeMessage(m);
+}
+
+
+void LegacyPeer::dispatch(const LoginFailed &msg)
+{
+ QVariantMap m;
+ m["MsgType"] = "ClientLoginReject";
+ m["Error"] = msg.errorString;
+
+ writeMessage(m);
+}
+
+
+void LegacyPeer::dispatch(const LoginSuccess &msg)
+{
+ Q_UNUSED(msg)
+
+ QVariantMap m;
+ m["MsgType"] = "ClientLoginAck";
+
+ writeMessage(m);
+}
+
+
+void LegacyPeer::dispatch(const SessionState &msg)
+{
+ QVariantMap m;
+ m["MsgType"] = "SessionInit";
+
+ QVariantMap map;
+ map["BufferInfos"] = msg.bufferInfos;
+ map["NetworkIds"] = msg.networkIds;
+ map["Identities"] = msg.identities;
+ m["SessionState"] = map;
+
+ writeMessage(m);