示例#1
0
serversDialog::serversDialog(QWidget *parent) : QDialog(parent) {

	setupUi(this) ;

	connect(buttonBox,SIGNAL(rejected()),this,SLOT(deleteLater())) ;
	connect(buttonBox,SIGNAL(accepted()),this,SLOT(acceptList())) ;
	connect(addButton,SIGNAL(clicked()),this,SLOT(addServer())) ;
	connect(editButton,SIGNAL(clicked()),this,SLOT(editServer())) ;
	connect(removeButton,SIGNAL(clicked()),this,SLOT(removeServer())) ;
	connect(serverList,SIGNAL(itemSelectionChanged()),this,SLOT(rowChanged())) ;

	updateServerList() ;

}
示例#2
0
void MainWindow::logged(CatchChallenger::Api_client_real *senderObject,const QList<CatchChallenger::ServerFromPoolForDisplay *> &serverOrdenedList,const QList<QList<CatchChallenger::CharacterEntry> > &characterEntryList,bool haveTheDatapack)
{
    Q_UNUSED(haveTheDatapack);
    if(senderObject==NULL)
    {
        qDebug() << "MainWindow::logged(): qobject_cast<CatchChallenger::Api_client_real *>(sender())==NULL";
        return;
    }

    ui->characterList->clear();
    this->serverOrdenedList=serverOrdenedList;
    this->characterEntryList=characterEntryList;

    ui->characterList->setEnabled(ui->characterList->count()>0 && !ui->multipleConnexion->isChecked());

    ui->serverList->header()->setSectionResizeMode(QHeaderView::Fixed);
    ui->serverList->header()->resizeSection(0,400);
    updateServerList(senderObject);
}
示例#3
0
bool Servatrice::initServer()
{
    serverName = settings->value("server/name").toString();
    serverId = settings->value("server/id", 0).toInt();
    bool regServerOnly = settings->value("server/regonly", 0).toBool();
        
    const QString authenticationMethodStr = settings->value("authentication/method").toString();
    if (authenticationMethodStr == "sql") {
        authenticationMethod = AuthenticationSql;
    } else {
        if (regServerOnly) {
            qDebug() << "Registration only server enabled but no DB Connection : Error.";
            return false;   
        }
        authenticationMethod = AuthenticationNone;
    }
    
    QString dbTypeStr = settings->value("database/type").toString();
    if (dbTypeStr == "mysql")
        databaseType = DatabaseMySql;
    else
        databaseType = DatabaseNone;
    
    servatriceDatabaseInterface = new Servatrice_DatabaseInterface(-1, this);
    setDatabaseInterface(servatriceDatabaseInterface);
    
    if (databaseType != DatabaseNone) {
        settings->beginGroup("database");
        dbPrefix = settings->value("prefix").toString();
        servatriceDatabaseInterface->initDatabase("QMYSQL",
                              settings->value("hostname").toString(),
                              settings->value("database").toString(),
                              settings->value("user").toString(),
                              settings->value("password").toString());
        settings->endGroup();
        
        updateServerList();
        
        qDebug() << "Clearing previous sessions...";
        servatriceDatabaseInterface->clearSessionTables();
    }
    
    const QString roomMethod = settings->value("rooms/method").toString();
    if (roomMethod == "sql") {
        QSqlQuery query(servatriceDatabaseInterface->getDatabase());
        query.prepare("select id, name, descr, auto_join, join_message from " + dbPrefix + "_rooms order by id asc");
        servatriceDatabaseInterface->execSqlQuery(query);
        while (query.next()) {
            QSqlQuery query2(servatriceDatabaseInterface->getDatabase());
            query2.prepare("select name from " + dbPrefix + "_rooms_gametypes where id_room = :id_room");
            query2.bindValue(":id_room", query.value(0).toInt());
            servatriceDatabaseInterface->execSqlQuery(query2);
            QStringList gameTypes;
            while (query2.next())
                gameTypes.append(query2.value(0).toString());
            
            addRoom(new Server_Room(query.value(0).toInt(),
                                    query.value(1).toString(),
                                    query.value(2).toString(),
                                    query.value(3).toInt(),
                                    query.value(4).toString(),
                                    gameTypes,
                                    this
            ));
        }
    } else {
        int size = settings->beginReadArray("rooms/roomlist");
        for (int i = 0; i < size; ++i) {
            settings->setArrayIndex(i);
            
            QStringList gameTypes;
            int size2 = settings->beginReadArray("game_types");
                for (int j = 0; j < size2; ++j) {
                settings->setArrayIndex(j);
                gameTypes.append(settings->value("name").toString());
            }
            settings->endArray();
                
            Server_Room *newRoom = new Server_Room(
                i,
                settings->value("name").toString(),
                settings->value("description").toString(),
                settings->value("autojoin").toBool(),
                settings->value("joinmessage").toString(),
                gameTypes,
                this
            );
            addRoom(newRoom);
        }
        settings->endArray();
    }
    
    updateLoginMessage();
    
    maxGameInactivityTime = settings->value("game/max_game_inactivity_time").toInt();
    maxPlayerInactivityTime = settings->value("game/max_player_inactivity_time").toInt();
    
    maxUsersPerAddress = settings->value("security/max_users_per_address").toInt();
    messageCountingInterval = settings->value("security/message_counting_interval").toInt();
    maxMessageCountPerInterval = settings->value("security/max_message_count_per_interval").toInt();
    maxMessageSizePerInterval = settings->value("security/max_message_size_per_interval").toInt();
    maxGamesPerUser = settings->value("security/max_games_per_user").toInt();

	try { if (settings->value("servernetwork/active", 0).toInt()) {
		qDebug() << "Connecting to ISL network.";
		const QString certFileName = settings->value("servernetwork/ssl_cert").toString();
		const QString keyFileName = settings->value("servernetwork/ssl_key").toString();
		qDebug() << "Loading certificate...";
		QFile certFile(certFileName);
		if (!certFile.open(QIODevice::ReadOnly))
			throw QString("Error opening certificate file: %1").arg(certFileName);
		QSslCertificate cert(&certFile);
#if QT_VERSION < 0x050000
		if (!cert.isValid())
			throw(QString("Invalid certificate."));
#else
		const QDateTime currentTime = QDateTime::currentDateTime();
		if(currentTime < cert.effectiveDate() ||
			currentTime > cert.expiryDate() ||
			cert.isBlacklisted())
			throw(QString("Invalid certificate."));
#endif
		qDebug() << "Loading private key...";
		QFile keyFile(keyFileName);
		if (!keyFile.open(QIODevice::ReadOnly))
			throw QString("Error opening private key file: %1").arg(keyFileName);
		QSslKey key(&keyFile, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
		if (key.isNull())
			throw QString("Invalid private key.");
		
		QMutableListIterator<ServerProperties> serverIterator(serverList);
		while (serverIterator.hasNext()) {
			const ServerProperties &prop = serverIterator.next();
			if (prop.cert == cert) {
				serverIterator.remove();
				continue;
			}
			
			QThread *thread = new QThread;
			thread->setObjectName("isl_" + QString::number(prop.id));
			connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
			
			IslInterface *interface = new IslInterface(prop.id, prop.hostname, prop.address.toString(), prop.controlPort, prop.cert, cert, key, this);
			interface->moveToThread(thread);
			connect(interface, SIGNAL(destroyed()), thread, SLOT(quit()));
			
			thread->start();
			QMetaObject::invokeMethod(interface, "initClient", Qt::BlockingQueuedConnection);
		}
			
		const int networkPort = settings->value("servernetwork/port", 14747).toInt();
		qDebug() << "Starting ISL server on port" << networkPort;
		
		islServer = new Servatrice_IslServer(this, cert, key, this);
		if (islServer->listen(QHostAddress::Any, networkPort))
			qDebug() << "ISL server listening.";
		else
			throw QString("islServer->listen()");
	} } catch (QString error) {
		qDebug() << "ERROR --" << error;
		return false;
	}
	
	pingClock = new QTimer(this);
	connect(pingClock, SIGNAL(timeout()), this, SIGNAL(pingClockTimeout()));
	pingClock->start(1000);
	
	int statusUpdateTime = settings->value("server/statusupdate").toInt();
	statusUpdateClock = new QTimer(this);
	connect(statusUpdateClock, SIGNAL(timeout()), this, SLOT(statusUpdate()));
	if (statusUpdateTime != 0) {
		qDebug() << "Starting status update clock, interval " << statusUpdateTime << " ms";
		statusUpdateClock->start(statusUpdateTime);
	}
	
	const int numberPools = settings->value("server/number_pools", 1).toInt();
	gameServer = new Servatrice_GameServer(this, numberPools, servatriceDatabaseInterface->getDatabase(), this);
	gameServer->setMaxPendingConnections(1000);
	const int gamePort = settings->value("server/port", 4747).toInt();
	qDebug() << "Starting server on port" << gamePort;
	if (gameServer->listen(QHostAddress::Any, gamePort))
		qDebug() << "Server listening.";
	else {
		qDebug() << "gameServer->listen(): Error.";
		return false;
	}
	return true;
}
示例#4
0
    ServerListDialog::ServerListDialog(QWidget *parent, const char *name)
        : KDialogBase(Plain, i18n("Server List"), Ok|Close, Ok, parent, name, false)
    {
        setButtonOK(KGuiItem(i18n("C&onnect"), "connect_creating", i18n("Connect to the server"), i18n("Click here to connect to the selected IRC network and channel.")));

        QFrame* mainWidget = plainPage();

        m_serverList = new ServerListView(mainWidget);
        QWhatsThis::add(m_serverList, i18n("This shows the listof configured IRC networks. An IRC network is a collection of cooperating servers. You need only connect to one of the servers in the network to be connected to the entire IRC network. Once connected, Konversation will automatically join the channels shown. When Konversation is started for the first time, the Freenode network and the <i>#kde</i> channel are already entered for you."));
        m_serverList->setAllColumnsShowFocus(true);
        m_serverList->setRootIsDecorated(true);
        m_serverList->setResizeMode(QListView::AllColumns);
        m_serverList->addColumn(i18n("Network"));
        m_serverList->addColumn(i18n("Identity"));
        m_serverList->addColumn(i18n("Channels"));
        m_serverList->setSelectionModeExt(KListView::Extended);
        m_serverList->setShowSortIndicator(true);
        m_serverList->setSortColumn(0);
        m_serverList->setDragEnabled(true);
        m_serverList->setAcceptDrops(true);
        m_serverList->setDropVisualizer(true);
        m_serverList->header()->setMovingEnabled(false);

        m_addButton = new QPushButton(i18n("&New..."), mainWidget);
        QWhatsThis::add(m_addButton, i18n("Click here to define a new Network, including the server to connect to, and the Channels to automatically join once connected."));
        m_editButton = new QPushButton(i18n("&Edit..."), mainWidget);
        m_delButton = new QPushButton(i18n("&Delete"), mainWidget);

        QCheckBox* showAtStartup = new QCheckBox(i18n("Show at application startup"), mainWidget);
        showAtStartup->setChecked(Preferences::showServerList());
        connect(showAtStartup, SIGNAL(toggled(bool)), this, SLOT(setShowAtStartup(bool)));

        QGridLayout* layout = new QGridLayout(mainWidget, 5, 2, 0, spacingHint());

        layout->addMultiCellWidget(m_serverList, 0, 3, 0, 0);
        layout->addWidget(m_addButton, 0, 1);
        layout->addWidget(m_editButton, 1, 1);
        layout->addWidget(m_delButton, 2, 1);
        layout->addMultiCellWidget(showAtStartup, 4, 4, 0, 1);
        layout->setRowStretch(3, 10);

        m_serverList->setFocus();

        m_selectedItem = false;
        m_selectedServer = ServerSettings("");

        // Load server list
        updateServerList();

        connect(m_serverList, SIGNAL(aboutToMove()), this, SLOT(slotAboutToMove()));
        connect(m_serverList, SIGNAL(moved()), this, SLOT(slotMoved()));
        connect(m_serverList, SIGNAL(doubleClicked(QListViewItem *, const QPoint&, int)), this, SLOT(slotOk()));
        connect(m_serverList, SIGNAL(selectionChanged()), this, SLOT(updateButtons()));
        connect(m_serverList, SIGNAL(expanded(QListViewItem*)), this, SLOT(slotSetGroupExpanded(QListViewItem*)));
        connect(m_serverList, SIGNAL(collapsed(QListViewItem*)), this, SLOT(slotSetGroupCollapsed(QListViewItem*)));
        connect(m_addButton, SIGNAL(clicked()), this, SLOT(slotAdd()));
        connect(m_editButton, SIGNAL(clicked()), this, SLOT(slotEdit()));
        connect(m_delButton, SIGNAL(clicked()), this, SLOT(slotDelete()));

        updateButtons();

        KConfig* config = kapp->config();
        config->setGroup("ServerListDialog");
        QSize newSize = size();
        newSize = config->readSizeEntry("Size", &newSize);
        resize(newSize);

        m_serverList->setSelected(m_serverList->firstChild(), true);
    }
示例#5
0
bool Servatrice::initServer()
{
    serverName = settingsCache->value("server/name", "My Cockatrice server").toString();
    serverId = settingsCache->value("server/id", 0).toInt();
    clientIdRequired = settingsCache->value("server/requireclientid",0).toBool();
    regServerOnly = settingsCache->value("authentication/regonly", 0).toBool();

    const QString authenticationMethodStr = settingsCache->value("authentication/method").toString();
    if (authenticationMethodStr == "sql") {
        qDebug() << "Authenticating method: sql";
        authenticationMethod = AuthenticationSql;
    } else if(authenticationMethodStr == "password") {
        qDebug() << "Authenticating method: password";
        authenticationMethod = AuthenticationPassword;
    } else {
        if (regServerOnly) {
            qDebug() << "Registration only server enabled but no authentication method defined: Error.";
            return false;
        }

        qDebug() << "Authenticating method: none";
        authenticationMethod = AuthenticationNone;
    }

    qDebug() << "Store Replays: " << settingsCache->value("game/store_replays", true).toBool();
    qDebug() << "Client ID Required: " << clientIdRequired;
    bool maxUserLimitEnabled = settingsCache->value("security/enable_max_user_limit", false).toBool();
    qDebug() << "Maximum user limit enabled: " << maxUserLimitEnabled;

    if (maxUserLimitEnabled){
        int maxUserLimit = settingsCache->value("security/max_users_total", 500).toInt();
        qDebug() << "Maximum total user limit: " << maxUserLimit;
        int maxTcpUserLimit = settingsCache->value("security/max_users_tcp", 500).toInt();
        qDebug() << "Maximum tcp user limit: " << maxTcpUserLimit;
        int maxWebsocketUserLimit = settingsCache->value("security/max_users_websocket", 500).toInt();
        qDebug() << "Maximum websocket user limit: " << maxWebsocketUserLimit;
    }

    bool registrationEnabled = settingsCache->value("registration/enabled", false).toBool();
    bool requireEmailForRegistration = settingsCache->value("registration/requireemail", true).toBool();
    bool requireEmailActivation = settingsCache->value("registration/requireemailactivation", true).toBool();

    qDebug() << "Accept registered users only: " << regServerOnly;
    qDebug() << "Registration enabled: " << registrationEnabled;
    if (registrationEnabled)
    {
        qDebug() << "Require email address to register: " << requireEmailForRegistration;
        qDebug() << "Require email activation via token: " << requireEmailActivation;
    }

    FeatureSet features;
    features.initalizeFeatureList(serverRequiredFeatureList);
    requiredFeatures = settingsCache->value("server/requiredfeatures","").toString();
    QStringList listReqFeatures = requiredFeatures.split(",", QString::SkipEmptyParts);
    if (!listReqFeatures.isEmpty())
        foreach(QString reqFeature, listReqFeatures)
            features.enableRequiredFeature(serverRequiredFeatureList,reqFeature);

    qDebug() << "Required client features: " << serverRequiredFeatureList;

    QString dbTypeStr = settingsCache->value("database/type").toString();
    if (dbTypeStr == "mysql")
        databaseType = DatabaseMySql;
    else
        databaseType = DatabaseNone;

    servatriceDatabaseInterface = new Servatrice_DatabaseInterface(-1, this);
    setDatabaseInterface(servatriceDatabaseInterface);

    if (databaseType != DatabaseNone) {
        settingsCache->beginGroup("database");
        dbPrefix = settingsCache->value("prefix").toString();
        bool dbOpened =
            servatriceDatabaseInterface->initDatabase("QMYSQL",
                 settingsCache->value("hostname").toString(),
                 settingsCache->value("database").toString(),
                 settingsCache->value("user").toString(),
                 settingsCache->value("password").toString());
        settingsCache->endGroup();
        if (!dbOpened) {
            qDebug() << "Failed to open database";
            return false;
        }

        updateServerList();

        qDebug() << "Clearing previous sessions...";
        servatriceDatabaseInterface->clearSessionTables();
    }

    const QString roomMethod = settingsCache->value("rooms/method").toString();
    if (roomMethod == "sql") {
        QSqlQuery *query = servatriceDatabaseInterface->prepareQuery("select id, name, descr, permissionlevel, auto_join, join_message, chat_history_size from {prefix}_rooms where id_server = :id_server order by id asc");
        query->bindValue(":id_server", serverId);
        servatriceDatabaseInterface->execSqlQuery(query);
        while (query->next()) {
            QSqlQuery *query2 = servatriceDatabaseInterface->prepareQuery("select name from {prefix}_rooms_gametypes where id_room = :id_room AND id_server = :id_server");
            query2->bindValue(":id_server", serverId);
            query2->bindValue(":id_room", query->value(0).toInt());
            servatriceDatabaseInterface->execSqlQuery(query2);
            QStringList gameTypes;
            while (query2->next())
                gameTypes.append(query2->value(0).toString());

            addRoom(new Server_Room(query->value(0).toInt(),
                                    query->value(6).toInt(),
                                    query->value(1).toString(),
                                    query->value(2).toString(),
                                    query->value(3).toString().toLower(),
                                    query->value(4).toInt(),
                                    query->value(5).toString(),
                                    gameTypes,
                                    this
            ));
        }
    } else {
        int size = settingsCache->beginReadArray("rooms/roomlist");
        for (int i = 0; i < size; ++i) {
            settingsCache->setArrayIndex(i);

            QStringList gameTypes;
            int size2 = settingsCache->beginReadArray("game_types");
                for (int j = 0; j < size2; ++j) {
                settingsCache->setArrayIndex(j);
                gameTypes.append(settingsCache->value("name").toString());
            }
            settingsCache->endArray();

            Server_Room *newRoom = new Server_Room(
                i,
                settingsCache->value("chathistorysize").toInt(),
                settingsCache->value("name").toString(),
                settingsCache->value("description").toString(),
                settingsCache->value("permissionlevel").toString().toLower(),
                settingsCache->value("autojoin").toBool(),
                settingsCache->value("joinmessage").toString(),
                gameTypes,
                this
            );
            addRoom(newRoom);
        }

        if(size==0)
        {
            // no room defined in config, add a dummy one
            Server_Room *newRoom = new Server_Room(
                0,
                100,
                "General room",
                "Play anything here.",
                "none",
                true,
                "",
                QStringList("Standard"),
                this
            );
            addRoom(newRoom);
        }

        settingsCache->endArray();
    }

    updateLoginMessage();

    maxGameInactivityTime = settingsCache->value("game/max_game_inactivity_time", 120).toInt();
    maxPlayerInactivityTime = settingsCache->value("server/max_player_inactivity_time", 15).toInt();
    pingClockInterval = settingsCache->value("server/clientkeepalive", 1).toInt();
    maxUsersPerAddress = settingsCache->value("security/max_users_per_address", 4).toInt();
    messageCountingInterval = settingsCache->value("security/message_counting_interval", 10).toInt();
    maxMessageCountPerInterval = settingsCache->value("security/max_message_count_per_interval", 15).toInt();
    maxMessageSizePerInterval = settingsCache->value("security/max_message_size_per_interval", 1000).toInt();
    maxGamesPerUser = settingsCache->value("security/max_games_per_user", 5).toInt();
    commandCountingInterval = settingsCache->value("game/command_counting_interval", 10).toInt();
    maxCommandCountPerInterval = settingsCache->value("game/max_command_count_per_interval", 20).toInt();

    try { if (settingsCache->value("servernetwork/active", 0).toInt()) {
        qDebug() << "Connecting to ISL network.";
        const QString certFileName = settingsCache->value("servernetwork/ssl_cert").toString();
        const QString keyFileName = settingsCache->value("servernetwork/ssl_key").toString();
        qDebug() << "Loading certificate...";
        QFile certFile(certFileName);
        if (!certFile.open(QIODevice::ReadOnly))
            throw QString("Error opening certificate file: %1").arg(certFileName);
        QSslCertificate cert(&certFile);

        const QDateTime currentTime = QDateTime::currentDateTime();
        if(currentTime < cert.effectiveDate() ||
            currentTime > cert.expiryDate() ||
            cert.isBlacklisted())
            throw(QString("Invalid certificate."));

        qDebug() << "Loading private key...";
        QFile keyFile(keyFileName);
        if (!keyFile.open(QIODevice::ReadOnly))
            throw QString("Error opening private key file: %1").arg(keyFileName);
        QSslKey key(&keyFile, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
        if (key.isNull())
            throw QString("Invalid private key.");

        QMutableListIterator<ServerProperties> serverIterator(serverList);
        while (serverIterator.hasNext()) {
            const ServerProperties &prop = serverIterator.next();
            if (prop.cert == cert) {
                serverIterator.remove();
                continue;
            }

            QThread *thread = new QThread;
            thread->setObjectName("isl_" + QString::number(prop.id));
            connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));

            IslInterface *interface = new IslInterface(prop.id, prop.hostname, prop.address.toString(), prop.controlPort, prop.cert, cert, key, this);
            interface->moveToThread(thread);
            connect(interface, SIGNAL(destroyed()), thread, SLOT(quit()));

            thread->start();
            QMetaObject::invokeMethod(interface, "initClient", Qt::BlockingQueuedConnection);
        }

        const int networkPort = settingsCache->value("servernetwork/port", 14747).toInt();
        qDebug() << "Starting ISL server on port" << networkPort;

        islServer = new Servatrice_IslServer(this, cert, key, this);
        if (islServer->listen(QHostAddress::Any, networkPort))
            qDebug() << "ISL server listening.";
        else
            throw QString("islServer->listen()");
    } } catch (QString error) {
        qDebug() << "ERROR --" << error;
        return false;
    }

    pingClock = new QTimer(this);
    connect(pingClock, SIGNAL(timeout()), this, SIGNAL(pingClockTimeout()));
    pingClock->start(pingClockInterval * 1000);

    int statusUpdateTime = settingsCache->value("server/statusupdate", 15000).toInt();
    statusUpdateClock = new QTimer(this);
    connect(statusUpdateClock, SIGNAL(timeout()), this, SLOT(statusUpdate()));
    if (statusUpdateTime != 0) {
        qDebug() << "Starting status update clock, interval " << statusUpdateTime << " ms";
        statusUpdateClock->start(statusUpdateTime);
    }

    // SOCKET SERVER
    const int numberPools = settingsCache->value("server/number_pools", 1).toInt();
    if(numberPools > 0)
    {
        gameServer = new Servatrice_GameServer(this, numberPools, servatriceDatabaseInterface->getDatabase(), this);
        gameServer->setMaxPendingConnections(1000);
        const int gamePort = settingsCache->value("server/port", 4747).toInt();
        qDebug() << "Starting server on port" << gamePort;
        if (gameServer->listen(QHostAddress::Any, gamePort))
            qDebug() << "Server listening.";
        else {
            qDebug() << "gameServer->listen(): Error:" << gameServer->errorString();
            return false;
        }
    }

#if QT_VERSION > 0x050300
    // WEBSOCKET SERVER
    const int wesocketNumberPools = settingsCache->value("server/websocket_number_pools", 1).toInt();
    if(wesocketNumberPools > 0)
    {
        websocketGameServer = new Servatrice_WebsocketGameServer(this, wesocketNumberPools, servatriceDatabaseInterface->getDatabase(), this);
        websocketGameServer->setMaxPendingConnections(1000);
        const int websocketGamePort = settingsCache->value("server/websocket_port", 4748).toInt();
        qDebug() << "Starting websocket server on port" << websocketGamePort;
        if (websocketGameServer->listen(QHostAddress::Any, websocketGamePort))
            qDebug() << "Websocket server listening.";
        else {
            qDebug() << "websocketGameServer->listen(): Error:" << websocketGameServer->errorString();
            return false;
        }
    }
#endif
    return true;
}
示例#6
0
OpenRcon::OpenRcon(QWidget *parent) : QMainWindow(parent)
{
    // Initialize the QSettings object.
    settings = new QSettings(APP_NAME, APP_NAME, this);

    // Create ServerManager instances.
    serverManager = new ServerManager(this);
    sessionManager = new SessionManager(this);

    // Create dialogs.
    serverListDialog = new ServerListDialog(this);
    optionsDialog = new OptionsDialog(this);
    aboutDialog = new AboutDialog(this);

    // Sets window title
    setWindowTitle(QString("%1 %2").arg(APP_NAME).arg(APP_VERSION));
    setWindowIcon(QIcon(":/icons/openrcon.png"));

    // Actions
    actionServerManager = new QAction(QIcon(":/icons/servermanager.png"), tr("&Servers"), this);
    actionServerManager->setShortcut(tr("Ctrl+S"));
    actionServerManager->setToolTip(tr("View and edit servers."));
    actionQuit = new QAction(QIcon(":/icons/quit.png"), tr("&Quit"), this);
    actionQuit->setShortcut(tr("Ctrl+Q"));
    actionQuickConnect = new QAction(tr("Quickconnect"), this);
    actionQuickConnect->setCheckable(true);
    actionOptions = new QAction(QIcon(":/icons/options.png"), tr("&Options"), this);
    actionOptions->setShortcut(tr("Ctrl+O"));
    actionDocumentation = new QAction(QIcon(":/icons/documentation.png"), tr("Documentation"), this);
    actionVisitWebsite = new QAction(QIcon(":/icons/internet.png"), tr("Visit website"), this);
    actionReportBug = new QAction(QIcon(":/icons/report-bug.png"), tr("Report bug"), this);
    actionAbout = new QAction(QIcon(APP_ICON), tr("&About %1").arg(APP_NAME), this);
    actionAbout->setShortcut(tr("Ctrl+A"));
    actionAboutQt = new QAction(QIcon(":/qt-project.org/qmessagebox/images/qtlogo-64.png"), tr("About Qt"), this);
    actionAboutQt->setMenuRole(QAction::AboutQtRole);

    // Menubar
    menuBar = new QMenuBar(this);

    menuApplication = menuBar->addMenu(tr("Application"));
    menuApplication->addAction(actionServerManager);
    menuApplication->addSeparator();
    menuApplication->addAction(actionQuit);

    menuView = menuBar->addMenu(tr("View"));
    menuToolbars = menuView->addMenu(tr("Toolbars"));
    menuToolbars->addAction(actionQuickConnect);

    menuTools = menuBar->addMenu(tr("Tools"));
    menuTools->addAction(actionOptions);

    menuHelp = menuBar->addMenu(tr("Help"));
    menuHelp->addAction(actionDocumentation);
    menuHelp->addAction(actionVisitWebsite);
    menuHelp->addAction(actionReportBug);
    menuHelp->addSeparator();
    menuHelp->addAction(actionAbout);
    menuHelp->addAction(actionAboutQt);
    setMenuBar(menuBar);

    // Toolbar
    toolBar_quickConnect = new QToolBar(tr("Quick Connect"), this);
    toolBar_quickConnect->setFloatable(false);

    comboBox_quickConnect_server = new QComboBox(toolBar_quickConnect);
    comboBox_quickConnect_server->setToolTip(tr("Let's you select a prevously stored server."));

    pushButton_quickConnect_connect = new QPushButton(tr("Connect"), toolBar_quickConnect);
    pushButton_quickConnect_connect->setToolTip(tr("Connect's to the server selected in the combobox."));

    toolBar_quickConnect->addAction(actionServerManager);
    toolBar_quickConnect->addWidget(comboBox_quickConnect_server);
    toolBar_quickConnect->addWidget(pushButton_quickConnect_connect);
    addToolBar(toolBar_quickConnect);

    // TabWidget
    tabWidget = new QTabWidget(this);
    tabWidget->setDocumentMode(true);
    tabWidget->setMovable(true);
    tabWidget->setTabsClosable(true);
    setCentralWidget(tabWidget);

    // Statusbar
    statusBar = new QStatusBar(this);
    setStatusBar(statusBar);

    // Create and read settings
    readSettings();

    // Autoconnect serverentries which has the autoconnect option set to true.
    autoConnect();

    // Loads the server list from ServerManager.
    updateServerList();

    // Actions
    connect(actionServerManager, &QAction::triggered, this, &OpenRcon::actionServerManager_triggered);
    connect(actionQuit,          &QAction::triggered, this, &OpenRcon::close);
    connect(actionQuickConnect,  &QAction::triggered, this, &OpenRcon::actionQuickConnect_triggered);
    connect(actionOptions,       &QAction::triggered, this, &OpenRcon::actionOptions_triggered);
    connect(actionDocumentation, &QAction::triggered, this, &OpenRcon::actionDocumentation_triggered);
    connect(actionVisitWebsite,  &QAction::triggered, this, &OpenRcon::actionVisitWebsite_triggered);
    connect(actionReportBug,     &QAction::triggered, this, &OpenRcon::actionReportBug_triggered);
    connect(actionAbout,         &QAction::triggered, this, &OpenRcon::actionAbout_triggered);
    connect(actionAboutQt,       &QAction::triggered, this, &OpenRcon::actionAboutQt_triggered);

    // Toolbars
    connect(pushButton_quickConnect_connect, &QPushButton::clicked,              this, &OpenRcon::pushButton_quickConnect_connect_clicked);
    connect(serverManager,                   &ServerManager::onServerUpdated,    this, &OpenRcon::updateServerList);
    connect(sessionManager,                  &SessionManager::onServerConnected, this, &OpenRcon::updateServerList);

    // TabWidget
    connect(tabWidget, &QTabWidget::tabCloseRequested, this, &OpenRcon::closeTab);
}