~ubuntu-branches/ubuntu/trusty/quassel/trusty-updates

« back to all changes in this revision

Viewing changes to src/client/coreconnection.cpp

  • Committer: Package Import Robot
  • Author(s): Scott Kitterman
  • Date: 2014-02-18 23:18:25 UTC
  • mfrom: (1.1.54)
  • Revision ID: package-import@ubuntu.com-20140218231825-6vvoh451otn95pkn
Tags: 0.10~beta1-0ubuntu1
* New upstream beta relase
  - Drop debian/patches/upstream_fix_fullscreen_mode.diff which had been
    cherrypicked from upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/***************************************************************************
2
 
 *   Copyright (C) 2005-2013 by the Quassel Project                        *
 
2
 *   Copyright (C) 2005-2014 by the Quassel Project                        *
3
3
 *   devel@quassel-irc.org                                                 *
4
4
 *                                                                         *
5
5
 *   This program is free software; you can redistribute it and/or modify  *
20
20
 
21
21
#include "coreconnection.h"
22
22
 
23
 
#ifndef QT_NO_NETWORKPROXY
24
 
#  include <QNetworkProxy>
25
 
#endif
26
 
 
27
23
#include "client.h"
 
24
#include "clientauthhandler.h"
28
25
#include "clientsettings.h"
29
26
#include "coreaccountmodel.h"
30
27
#include "identity.h"
37
34
 
38
35
#include "protocols/legacy/legacypeer.h"
39
36
 
40
 
CoreConnection::CoreConnection(CoreAccountModel *model, QObject *parent)
 
37
CoreConnection::CoreConnection(QObject *parent)
41
38
    : QObject(parent),
42
 
    _model(model),
 
39
    _authHandler(0),
43
40
    _state(Disconnected),
44
41
    _wantReconnect(false),
45
42
    _wasReconnect(false),
73
70
}
74
71
 
75
72
 
 
73
CoreAccountModel *CoreConnection::accountModel() const
 
74
{
 
75
    return Client::coreAccountModel();
 
76
}
 
77
 
 
78
 
76
79
void CoreConnection::setProgressText(const QString &text)
77
80
{
78
81
    if (_progressText != text) {
194
197
    }
195
198
}
196
199
 
197
 
 
198
200
#endif
199
201
 
200
202
bool CoreConnection::isEncrypted() const
216
218
}
217
219
 
218
220
 
219
 
void CoreConnection::socketStateChanged(QAbstractSocket::SocketState socketState)
220
 
{
221
 
    QString text;
222
 
 
223
 
    switch (socketState) {
224
 
    case QAbstractSocket::UnconnectedState:
225
 
        text = tr("Disconnected");
226
 
        break;
227
 
    case QAbstractSocket::HostLookupState:
228
 
        text = tr("Looking up %1...").arg(currentAccount().hostName());
229
 
        break;
230
 
    case QAbstractSocket::ConnectingState:
231
 
        text = tr("Connecting to %1...").arg(currentAccount().hostName());
232
 
        break;
233
 
    case QAbstractSocket::ConnectedState:
234
 
        text = tr("Connected to %1").arg(currentAccount().hostName());
235
 
        break;
236
 
    case QAbstractSocket::ClosingState:
237
 
        text = tr("Disconnecting from %1...").arg(currentAccount().hostName());
238
 
        break;
239
 
    default:
240
 
        break;
241
 
    }
242
 
 
243
 
    if (!text.isEmpty())
244
 
        emit progressTextChanged(text);
245
 
 
246
 
    setState(socketState);
247
 
}
248
 
 
249
 
 
250
 
void CoreConnection::setState(QAbstractSocket::SocketState socketState)
251
 
{
252
 
    ConnectionState state;
253
 
 
254
 
    switch (socketState) {
255
 
    case QAbstractSocket::UnconnectedState:
256
 
        state = Disconnected;
257
 
        break;
258
 
    case QAbstractSocket::HostLookupState:
259
 
    case QAbstractSocket::ConnectingState:
260
 
    case QAbstractSocket::ConnectedState: // we'll set it to Connected in connectionReady()
261
 
        state = Connecting;
262
 
        break;
263
 
    default:
264
 
        state = Disconnected;
265
 
    }
266
 
 
267
 
    setState(state);
 
221
void CoreConnection::onConnectionReady()
 
222
{
 
223
    setState(Connected);
268
224
}
269
225
 
270
226
 
279
235
}
280
236
 
281
237
 
282
 
void CoreConnection::coreSocketError(QAbstractSocket::SocketError)
 
238
void CoreConnection::coreSocketError(QAbstractSocket::SocketError error, const QString &errorString)
283
239
{
284
 
    disconnectFromCore(_socket->errorString(), true);
 
240
    Q_UNUSED(error)
 
241
 
 
242
    disconnectFromCore(errorString, true);
285
243
}
286
244
 
287
245
 
288
246
void CoreConnection::coreSocketDisconnected()
289
247
{
 
248
    setState(Disconnected);
290
249
    _wasReconnect = false;
291
250
    resetConnection(_wantReconnect);
292
 
    // FIXME handle disconnects gracefully
293
 
}
294
 
 
295
 
 
296
 
// note: this still expects the legacy protocol
297
 
// note²: after cleaning this up, we can probably get rid of _socket altogether
298
 
void CoreConnection::coreHasData(const QVariant &item)
299
 
{
300
 
    QVariantMap msg = item.toMap();
301
 
    if (!msg.contains("MsgType")) {
302
 
        // This core is way too old and does not even speak our init protocol...
303
 
        emit connectionErrorPopup(tr("The Quassel Core you try to connect to is too old! Please consider upgrading."));
304
 
        disconnectFromCore(QString(), false);
305
 
        return;
306
 
    }
307
 
    if (msg["MsgType"] == "ClientInitAck") {
308
 
        clientInitAck(msg);
309
 
    }
310
 
    else if (msg["MsgType"] == "ClientInitReject") {
311
 
        emit connectionErrorPopup(msg["Error"].toString());
312
 
        disconnectFromCore(QString(), false);
313
 
        return;
314
 
    }
315
 
    else if (msg["MsgType"] == "CoreSetupAck") {
316
 
        emit coreSetupSuccess();
317
 
    }
318
 
    else if (msg["MsgType"] == "CoreSetupReject") {
319
 
        emit coreSetupFailed(msg["Error"].toString());
320
 
    }
321
 
    else if (msg["MsgType"] == "ClientLoginReject") {
322
 
        loginFailed(msg["Error"].toString());
323
 
    }
324
 
    else if (msg["MsgType"] == "ClientLoginAck") {
325
 
        loginSuccess();
326
 
    }
327
 
    else if (msg["MsgType"] == "SessionInit") {
328
 
        // that's it, let's hand over to the signal proxy
329
 
        // if the connection is an orphan, the signalProxy adopts it.
330
 
        // -> we don't need to care about it anymore
331
 
 
332
 
        disconnect(_peer, 0, this, 0);
333
 
 
334
 
        _peer->setParent(0);
335
 
        Client::signalProxy()->addPeer(_peer);
336
 
 
337
 
        sessionStateReceived(msg["SessionState"].toMap());
338
 
    }
339
 
    else {
340
 
        disconnectFromCore(tr("Invalid data received from core"), false);
341
 
        return;
342
 
    }
343
251
}
344
252
 
345
253
 
346
254
void CoreConnection::disconnectFromCore()
347
255
{
348
 
    if (_socket)
349
 
        disconnectFromCore(QString(), false); // requested disconnect, so don't try to reconnect
 
256
    disconnectFromCore(QString(), false); // requested disconnect, so don't try to reconnect
350
257
}
351
258
 
352
259
 
360
267
    _wantReconnect = wantReconnect; // store if disconnect was requested
361
268
    _wasReconnect = false;
362
269
 
363
 
    if (_socket)
364
 
        _socket->close();
 
270
    if (_authHandler)
 
271
        _authHandler->close();
 
272
    else if(_peer)
 
273
        _peer->close();
365
274
 
366
275
    if (errorString.isEmpty())
367
276
        emit connectionError(tr("Disconnected"));
378
287
 
379
288
    _wantReconnect = wantReconnect;
380
289
 
 
290
    if (_authHandler) {
 
291
        disconnect(_authHandler, 0, this, 0);
 
292
        _authHandler->close();
 
293
        _authHandler->deleteLater();
 
294
        _authHandler = 0;
 
295
    }
 
296
 
381
297
    if (_peer) {
382
 
        disconnect(_socket, 0, this, 0);
383
298
        disconnect(_peer, 0, this, 0);
 
299
        // peer belongs to the sigproxy and thus gets deleted by it
384
300
        _peer->close();
385
 
 
386
 
        if (_peer->parent() == this)
387
 
            _peer->deleteLater(); // if it's not us, it belongs to the sigproxy which will delete it
388
 
        _socket = 0;      // socket is owned and will be deleted by RemoteConnection
389
301
        _peer = 0;
390
302
    }
391
 
    else if (_socket) {
392
 
        disconnect(_socket, 0, this, 0);
393
 
        _socket->deleteLater();
394
 
        _socket = 0;
395
 
    }
396
303
 
397
 
    _coreMsgBuffer.clear();
398
304
    _netsToSync.clear();
399
305
    _numNetsToSync = 0;
400
306
 
404
310
 
405
311
    emit connectionMsg(tr("Disconnected from core."));
406
312
    emit encrypted(false);
 
313
    setState(Disconnected);
407
314
 
408
315
    // initiate if a reconnect if appropriate
409
316
    CoreConnectionSettings s;
466
373
 
467
374
void CoreConnection::connectToCurrentAccount()
468
375
{
 
376
    if (_authHandler) {
 
377
        qWarning() << Q_FUNC_INFO << "Already connected!";
 
378
        return;
 
379
    }
 
380
 
469
381
    resetConnection(false);
470
382
 
471
383
    if (currentAccount().isInternal()) {
476
388
        emit startInternalCore();
477
389
 
478
390
        InternalPeer *peer = new InternalPeer();
 
391
        _peer = peer;
479
392
        Client::instance()->signalProxy()->addPeer(peer); // sigproxy will take ownership
480
393
        emit connectToInternalCore(peer);
481
 
 
482
 
        return;
483
 
    }
484
 
 
485
 
    CoreAccountSettings s;
486
 
 
487
 
    Q_ASSERT(!_socket);
488
 
#ifdef HAVE_SSL
489
 
    QSslSocket *sock = new QSslSocket(this);
490
 
    // make sure the warning is shown if we happen to connect without SSL support later
491
 
    s.setAccountValue("ShowNoClientSslWarning", true);
492
 
#else
493
 
    if (_account.useSsl()) {
494
 
        if (s.accountValue("ShowNoClientSslWarning", true).toBool()) {
495
 
            bool accepted = false;
496
 
            emit handleNoSslInClient(&accepted);
497
 
            if (!accepted) {
498
 
                emit connectionError(tr("Unencrypted connection canceled"));
499
 
                return;
500
 
            }
501
 
            s.setAccountValue("ShowNoClientSslWarning", false);
502
 
        }
503
 
    }
504
 
    QTcpSocket *sock = new QTcpSocket(this);
505
 
#endif
506
 
 
507
 
#ifndef QT_NO_NETWORKPROXY
508
 
    if (_account.useProxy()) {
509
 
        QNetworkProxy proxy(_account.proxyType(), _account.proxyHostName(), _account.proxyPort(), _account.proxyUser(), _account.proxyPassword());
510
 
        sock->setProxy(proxy);
511
 
    }
512
 
#endif
513
 
 
514
 
    _socket = sock;
515
 
    connect(sock, SIGNAL(connected()), SLOT(coreSocketConnected()));
516
 
    connect(sock, SIGNAL(disconnected()), SLOT(coreSocketDisconnected()));
517
 
    connect(sock, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(coreSocketError(QAbstractSocket::SocketError)));
518
 
    connect(sock, SIGNAL(stateChanged(QAbstractSocket::SocketState)), SLOT(socketStateChanged(QAbstractSocket::SocketState)));
519
 
 
520
 
    emit connectionMsg(tr("Connecting to %1...").arg(currentAccount().accountName()));
521
 
    sock->connectToHost(_account.hostName(), _account.port());
522
 
}
523
 
 
524
 
 
525
 
void CoreConnection::coreSocketConnected()
526
 
{
527
 
    // Create the connection which will handle the incoming data
528
 
    Q_ASSERT(!_peer);
529
 
    _peer = new LegacyPeer(_socket, this);
530
 
    connect(_peer, SIGNAL(dataReceived(QVariant)), SLOT(coreHasData(QVariant)));
531
 
    connect(_peer, SIGNAL(transferProgress(int,int)), SLOT(updateProgress(int,int)));
532
 
 
533
 
    // Phase One: Send client info and wait for core info
534
 
 
535
 
    emit connectionMsg(tr("Synchronizing to core..."));
536
 
 
537
 
    QVariantMap clientInit;
538
 
    clientInit["MsgType"] = "ClientInit";
539
 
    clientInit["ClientVersion"] = Quassel::buildInfo().fancyVersionString;
540
 
    clientInit["ClientDate"] = Quassel::buildInfo().buildDate;
541
 
    clientInit["ProtocolVersion"] = Quassel::buildInfo().protocolVersion;
542
 
#ifdef HAVE_SSL
543
 
    clientInit["UseSsl"] = _account.useSsl();
544
 
#else
545
 
    clientInit["UseSsl"] = false;
546
 
#endif
547
 
#ifndef QT_NO_COMPRESS
548
 
    clientInit["UseCompression"] = true;
549
 
#else
550
 
    clientInit["UseCompression"] = false;
551
 
#endif
552
 
 
553
 
    qobject_cast<RemotePeer *>(_peer)->writeSocketData(clientInit);
554
 
}
555
 
 
556
 
 
557
 
void CoreConnection::clientInitAck(const QVariantMap &msg)
558
 
{
559
 
    // Core has accepted our version info and sent its own. Let's see if we accept it as well...
560
 
    uint ver = msg["ProtocolVersion"].toUInt();
561
 
    if (ver < Quassel::buildInfo().clientNeedsProtocol) {
562
 
        emit connectionErrorPopup(tr("<b>The Quassel Core you are trying to connect to is too old!</b><br>"
563
 
                                     "Need at least core/client protocol v%1 to connect.").arg(Quassel::buildInfo().clientNeedsProtocol));
564
 
        disconnectFromCore(QString(), false);
565
 
        return;
566
 
    }
567
 
 
568
 
    Client::setCoreFeatures((Quassel::Features)msg["CoreFeatures"].toUInt());
569
 
 
570
 
#ifndef QT_NO_COMPRESS
571
 
    if (msg["SupportsCompression"].toBool()) {
572
 
        _socket->setProperty("UseCompression", true);
573
 
    }
574
 
#endif
575
 
 
576
 
    _coreMsgBuffer = msg;
577
 
 
578
 
#ifdef HAVE_SSL
579
 
    CoreAccountSettings s;
580
 
    if (currentAccount().useSsl()) {
581
 
        if (msg["SupportSsl"].toBool()) {
582
 
            // Make sure the warning is shown next time we don't have SSL in the core
583
 
            s.setAccountValue("ShowNoCoreSslWarning", true);
584
 
 
585
 
            QSslSocket *sslSocket = qobject_cast<QSslSocket *>(_socket);
586
 
            Q_ASSERT(sslSocket);
587
 
            connect(sslSocket, SIGNAL(encrypted()), SLOT(sslSocketEncrypted()));
588
 
            connect(sslSocket, SIGNAL(sslErrors(const QList<QSslError> &)), SLOT(sslErrors()));
589
 
            sslSocket->startClientEncryption();
590
 
        }
591
 
        else {
592
 
            if (s.accountValue("ShowNoCoreSslWarning", true).toBool()) {
593
 
                bool accepted = false;
594
 
                emit handleNoSslInCore(&accepted);
595
 
                if (!accepted) {
596
 
                    disconnectFromCore(tr("Unencrypted connection canceled"), false);
597
 
                    return;
598
 
                }
599
 
                s.setAccountValue("ShowNoCoreSslWarning", false);
600
 
                s.setAccountValue("SslCert", QString());
601
 
            }
602
 
            connectionReady();
603
 
        }
604
 
        return;
605
 
    }
606
 
#endif
607
 
    // if we use SSL we wait for the next step until every SSL warning has been cleared
608
 
    connectionReady();
609
 
}
610
 
 
611
 
 
612
 
#ifdef HAVE_SSL
613
 
 
614
 
void CoreConnection::sslSocketEncrypted()
615
 
{
616
 
    QSslSocket *socket = qobject_cast<QSslSocket *>(sender());
617
 
    Q_ASSERT(socket);
618
 
 
619
 
    if (!socket->sslErrors().count()) {
620
 
        // Cert is valid, so we don't want to store it as known
621
 
        // That way, a warning will appear in case it becomes invalid at some point
622
 
        CoreAccountSettings s;
623
 
        s.setAccountValue("SSLCert", QString());
624
 
    }
625
 
 
626
 
    emit encrypted(true);
627
 
    connectionReady();
628
 
}
629
 
 
630
 
 
631
 
void CoreConnection::sslErrors()
632
 
{
633
 
    QSslSocket *socket = qobject_cast<QSslSocket *>(sender());
634
 
    Q_ASSERT(socket);
635
 
 
636
 
    CoreAccountSettings s;
637
 
    QByteArray knownDigest = s.accountValue("SslCert").toByteArray();
638
 
 
639
 
    if (knownDigest != socket->peerCertificate().digest()) {
640
 
        bool accepted = false;
641
 
        bool permanently = false;
642
 
        emit handleSslErrors(socket, &accepted, &permanently);
643
 
 
644
 
        if (!accepted) {
645
 
            disconnectFromCore(tr("Unencrypted connection canceled"), false);
646
 
            return;
647
 
        }
648
 
 
649
 
        if (permanently)
650
 
            s.setAccountValue("SslCert", socket->peerCertificate().digest());
651
 
        else
652
 
            s.setAccountValue("SslCert", QString());
653
 
    }
654
 
 
655
 
    socket->ignoreSslErrors();
656
 
}
657
 
 
658
 
 
659
 
#endif /* HAVE_SSL */
660
 
 
661
 
void CoreConnection::connectionReady()
662
 
{
663
 
    setState(Connected);
664
 
    emit connectionMsg(tr("Connected to %1").arg(currentAccount().accountName()));
665
 
 
666
 
    if (!_coreMsgBuffer["Configured"].toBool()) {
667
 
        // start wizard
668
 
        emit startCoreSetup(_coreMsgBuffer["StorageBackends"].toList());
669
 
    }
670
 
    else if (_coreMsgBuffer["LoginEnabled"].toBool()) {
671
 
        loginToCore();
672
 
    }
673
 
    _coreMsgBuffer.clear();
 
394
        setState(Connected);
 
395
 
 
396
        return;
 
397
    }
 
398
 
 
399
    _authHandler = new ClientAuthHandler(currentAccount(), this);
 
400
 
 
401
    connect(_authHandler, SIGNAL(disconnected()), SLOT(coreSocketDisconnected()));
 
402
    connect(_authHandler, SIGNAL(connectionReady()), SLOT(onConnectionReady()));
 
403
    connect(_authHandler, SIGNAL(socketError(QAbstractSocket::SocketError,QString)), SLOT(coreSocketError(QAbstractSocket::SocketError,QString)));
 
404
    connect(_authHandler, SIGNAL(transferProgress(int,int)), SLOT(updateProgress(int,int)));
 
405
    connect(_authHandler, SIGNAL(requestDisconnect(QString,bool)), SLOT(disconnectFromCore(QString,bool)));
 
406
 
 
407
    connect(_authHandler, SIGNAL(errorMessage(QString)), SIGNAL(connectionError(QString)));
 
408
    connect(_authHandler, SIGNAL(errorPopup(QString)), SIGNAL(connectionErrorPopup(QString)), Qt::QueuedConnection);
 
409
    connect(_authHandler, SIGNAL(statusMessage(QString)), SIGNAL(connectionMsg(QString)));
 
410
    connect(_authHandler, SIGNAL(encrypted(bool)), SIGNAL(encrypted(bool)));
 
411
    connect(_authHandler, SIGNAL(startCoreSetup(QVariantList)), SIGNAL(startCoreSetup(QVariantList)));
 
412
    connect(_authHandler, SIGNAL(coreSetupFailed(QString)), SIGNAL(coreSetupFailed(QString)));
 
413
    connect(_authHandler, SIGNAL(coreSetupSuccessful()), SIGNAL(coreSetupSuccess()));
 
414
    connect(_authHandler, SIGNAL(userAuthenticationRequired(CoreAccount*,bool*,QString)), SIGNAL(userAuthenticationRequired(CoreAccount*,bool*,QString)));
 
415
    connect(_authHandler, SIGNAL(handleNoSslInClient(bool*)), SIGNAL(handleNoSslInClient(bool*)));
 
416
    connect(_authHandler, SIGNAL(handleNoSslInCore(bool*)), SIGNAL(handleNoSslInCore(bool*)));
 
417
#ifdef HAVE_SSL
 
418
    connect(_authHandler, SIGNAL(handleSslErrors(const QSslSocket*,bool*,bool*)), SIGNAL(handleSslErrors(const QSslSocket*,bool*,bool*)));
 
419
#endif
 
420
 
 
421
    connect(_authHandler, SIGNAL(loginSuccessful(CoreAccount)), SLOT(onLoginSuccessful(CoreAccount)));
 
422
    connect(_authHandler, SIGNAL(handshakeComplete(RemotePeer*,Protocol::SessionState)), SLOT(onHandshakeComplete(RemotePeer*,Protocol::SessionState)));
 
423
 
 
424
    setState(Connecting);
 
425
    _authHandler->connectToCore();
 
426
}
 
427
 
 
428
 
 
429
void CoreConnection::setupCore(const Protocol::SetupData &setupData)
 
430
{
 
431
    _authHandler->setupCore(setupData);
674
432
}
675
433
 
676
434
 
677
435
void CoreConnection::loginToCore(const QString &user, const QString &password, bool remember)
678
436
{
679
 
    _account.setUser(user);
680
 
    _account.setPassword(password);
681
 
    _account.setStorePassword(remember);
682
 
    loginToCore();
683
 
}
684
 
 
685
 
 
686
 
void CoreConnection::loginToCore(const QString &prevError)
687
 
{
688
 
    emit connectionMsg(tr("Logging in..."));
689
 
    if (currentAccount().user().isEmpty() || currentAccount().password().isEmpty() || !prevError.isEmpty()) {
690
 
        bool valid = false;
691
 
        emit userAuthenticationRequired(&_account, &valid, prevError); // *must* be a synchronous call
692
 
        if (!valid || currentAccount().user().isEmpty() || currentAccount().password().isEmpty()) {
693
 
            disconnectFromCore(tr("Login canceled"), false);
694
 
            return;
695
 
        }
696
 
    }
697
 
 
698
 
    QVariantMap clientLogin;
699
 
    clientLogin["MsgType"] = "ClientLogin";
700
 
    clientLogin["User"] = currentAccount().user();
701
 
    clientLogin["Password"] = currentAccount().password();
702
 
    qobject_cast<RemotePeer*>(_peer)->writeSocketData(clientLogin);
703
 
}
704
 
 
705
 
 
706
 
void CoreConnection::loginFailed(const QString &error)
707
 
{
708
 
    loginToCore(error);
709
 
}
710
 
 
711
 
 
712
 
void CoreConnection::loginSuccess()
 
437
    _authHandler->login(user, password, remember);
 
438
}
 
439
 
 
440
 
 
441
void CoreConnection::onLoginSuccessful(const CoreAccount &account)
713
442
{
714
443
    updateProgress(0, 0);
715
444
 
716
445
    // save current account data
717
 
    _model->createOrUpdateAccount(currentAccount());
718
 
    _model->save();
 
446
    accountModel()->createOrUpdateAccount(account);
 
447
    accountModel()->save();
719
448
 
720
449
    _reconnectTimer.stop();
721
450
 
722
451
    setProgressText(tr("Receiving session state"));
723
452
    setState(Synchronizing);
724
 
    emit connectionMsg(tr("Synchronizing to %1...").arg(currentAccount().accountName()));
725
 
}
726
 
 
727
 
 
728
 
void CoreConnection::sessionStateReceived(const QVariantMap &state)
729
 
{
730
 
    updateProgress(100, 100);
731
 
 
732
 
    syncToCore(state);
733
 
}
734
 
 
735
 
 
736
 
void CoreConnection::internalSessionStateReceived(const QVariant &packedState)
737
 
{
738
 
    updateProgress(100, 100);
 
453
    emit connectionMsg(tr("Synchronizing to %1...").arg(account.accountName()));
 
454
}
 
455
 
 
456
 
 
457
void CoreConnection::onHandshakeComplete(RemotePeer *peer, const Protocol::SessionState &sessionState)
 
458
{
 
459
    updateProgress(100, 100);
 
460
 
 
461
    disconnect(_authHandler, 0, this, 0);
 
462
    _authHandler->deleteLater();
 
463
    _authHandler = 0;
 
464
 
 
465
    _peer = peer;
 
466
    connect(peer, SIGNAL(disconnected()), SLOT(coreSocketDisconnected()));
 
467
    connect(peer, SIGNAL(statusMessage(QString)), SIGNAL(connectionMsg(QString)));
 
468
    connect(peer, SIGNAL(socketError(QAbstractSocket::SocketError,QString)), SLOT(coreSocketError(QAbstractSocket::SocketError,QString)));
 
469
 
 
470
    Client::signalProxy()->addPeer(_peer);  // sigproxy takes ownership of the peer!
 
471
 
 
472
    syncToCore(sessionState);
 
473
}
 
474
 
 
475
 
 
476
void CoreConnection::internalSessionStateReceived(const Protocol::SessionState &sessionState)
 
477
{
 
478
    updateProgress(100, 100);
 
479
 
 
480
    Client::setCoreFeatures(Quassel::features()); // mono connection...
739
481
 
740
482
    setState(Synchronizing);
741
 
    syncToCore(packedState.toMap());
 
483
    syncToCore(sessionState);
742
484
}
743
485
 
744
486
 
745
 
void CoreConnection::syncToCore(const QVariantMap &sessionState)
 
487
void CoreConnection::syncToCore(const Protocol::SessionState &sessionState)
746
488
{
747
 
    if (sessionState.contains("CoreFeatures"))
748
 
        Client::setCoreFeatures((Quassel::Features)sessionState["CoreFeatures"].toUInt());
749
 
 
750
489
    setProgressText(tr("Receiving network states"));
751
490
    updateProgress(0, 100);
752
491
 
753
492
    // create identities
754
 
    foreach(QVariant vid, sessionState["Identities"].toList()) {
 
493
    foreach(const QVariant &vid, sessionState.identities) {
755
494
        Client::instance()->coreIdentityCreated(vid.value<Identity>());
756
495
    }
757
496
 
758
497
    // create buffers
759
498
    // FIXME: get rid of this crap -- why?
760
 
    QVariantList bufferinfos = sessionState["BufferInfos"].toList();
761
499
    NetworkModel *networkModel = Client::networkModel();
762
500
    Q_ASSERT(networkModel);
763
 
    foreach(QVariant vinfo, bufferinfos)
764
 
    networkModel->bufferUpdated(vinfo.value<BufferInfo>());  // create BufferItems
765
 
 
766
 
    QVariantList networkids = sessionState["NetworkIds"].toList();
 
501
    foreach(const QVariant &vinfo, sessionState.bufferInfos)
 
502
        networkModel->bufferUpdated(vinfo.value<BufferInfo>());  // create BufferItems
767
503
 
768
504
    // prepare sync progress thingys...
769
505
    // FIXME: Care about removal of networks
770
 
    _numNetsToSync = networkids.count();
 
506
    _numNetsToSync = sessionState.networkIds.count();
771
507
    updateProgress(0, _numNetsToSync);
772
508
 
773
509
    // create network objects
774
 
    foreach(QVariant networkid, networkids) {
 
510
    foreach(const QVariant &networkid, sessionState.networkIds) {
775
511
        NetworkId netid = networkid.value<NetworkId>();
776
512
        if (Client::network(netid))
777
513
            continue;
806
542
        emit synchronized();
807
543
    }
808
544
}
809
 
 
810
 
 
811
 
void CoreConnection::doCoreSetup(const QVariant &setupData)
812
 
{
813
 
    QVariantMap setup;
814
 
    setup["MsgType"] = "CoreSetupData";
815
 
    setup["SetupData"] = setupData;
816
 
    qobject_cast<RemotePeer *>(_peer)->writeSocketData(setup);
817
 
}