From d174a2941f0de476bf5900b8e25ad4d8b67e7cd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Br=C3=BCbach?= Date: Tue, 14 Apr 2026 07:27:00 +0200 Subject: [PATCH] Connect/disconnect and join game/room intents. Took 3 hours 14 minutes --- cockatrice/CMakeLists.txt | 11 +++ .../contexts/context_connect_to_server.h | 14 ++++ .../intents/contexts/context_join_game.h | 11 +++ .../intents/contexts/context_join_room.h | 14 ++++ .../intents/intent_connect_to_server.cpp | 1 + .../intents/intent_connect_to_server.h | 54 +++++++++++++++ .../intents/intent_disconnect_from_server.cpp | 1 + .../intents/intent_disconnect_from_server.h | 47 +++++++++++++ .../intents/intent_join_server_game.cpp | 1 + .../intents/intent_join_server_game.h | 63 +++++++++++++++++ .../intents/intent_join_server_room.cpp | 1 + .../intents/intent_join_server_room.h | 58 ++++++++++++++++ .../src/interface/intents/intent_login.cpp | 1 + .../src/interface/intents/intent_login.h | 52 ++++++++++++++ .../src/interface/intents/url_parser.cpp | 67 +++++++++++++++++++ cockatrice/src/interface/intents/url_parser.h | 22 ++++++ .../widgets/server/game_selector.cpp | 19 ++++++ .../interface/widgets/server/game_selector.h | 1 + .../src/interface/widgets/tabs/tab_room.h | 4 ++ .../src/interface/widgets/tabs/tab_server.h | 2 +- .../interface/widgets/tabs/tab_supervisor.h | 4 ++ cockatrice/src/interface/window_main.h | 5 ++ cockatrice/src/main.cpp | 7 +- .../network/client/remote/remote_client.h | 8 +++ .../settings/servers_settings.cpp | 43 ++++++++++++ .../libcockatrice/settings/servers_settings.h | 4 ++ 26 files changed, 512 insertions(+), 3 deletions(-) create mode 100644 cockatrice/src/interface/intents/contexts/context_connect_to_server.h create mode 100644 cockatrice/src/interface/intents/contexts/context_join_game.h create mode 100644 cockatrice/src/interface/intents/contexts/context_join_room.h create mode 100644 cockatrice/src/interface/intents/intent_connect_to_server.cpp create mode 100644 cockatrice/src/interface/intents/intent_connect_to_server.h create mode 100644 cockatrice/src/interface/intents/intent_disconnect_from_server.cpp create mode 100644 cockatrice/src/interface/intents/intent_disconnect_from_server.h create mode 100644 cockatrice/src/interface/intents/intent_join_server_game.cpp create mode 100644 cockatrice/src/interface/intents/intent_join_server_game.h create mode 100644 cockatrice/src/interface/intents/intent_join_server_room.cpp create mode 100644 cockatrice/src/interface/intents/intent_join_server_room.h create mode 100644 cockatrice/src/interface/intents/intent_login.cpp create mode 100644 cockatrice/src/interface/intents/intent_login.h create mode 100644 cockatrice/src/interface/intents/url_parser.cpp create mode 100644 cockatrice/src/interface/intents/url_parser.h diff --git a/cockatrice/CMakeLists.txt b/cockatrice/CMakeLists.txt index 93f1fe1c5..fbe1dc2dd 100644 --- a/cockatrice/CMakeLists.txt +++ b/cockatrice/CMakeLists.txt @@ -330,6 +330,17 @@ set(cockatrice_SOURCES src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_budget_navigation_widget.h src/single_instance_manager.cpp src/single_instance_manager.h + src/interface/intents/intent_connect_to_server.cpp + src/interface/intents/intent_connect_to_server.h + src/interface/intents/intent_disconnect_from_server.cpp + src/interface/intents/intent_disconnect_from_server.h + src/interface/intents/intent_join_server_game.cpp + src/interface/intents/intent_join_server_room.cpp + src/interface/intents/intent_join_server_room.h + src/interface/intents/url_parser.cpp + src/interface/intents/url_parser.h + src/interface/intents/intent_login.cpp + src/interface/intents/intent_login.h ) add_subdirectory(sounds) diff --git a/cockatrice/src/interface/intents/contexts/context_connect_to_server.h b/cockatrice/src/interface/intents/contexts/context_connect_to_server.h new file mode 100644 index 000000000..c7c40b261 --- /dev/null +++ b/cockatrice/src/interface/intents/contexts/context_connect_to_server.h @@ -0,0 +1,14 @@ +#ifndef COCKATRICE_CONTEXT_CONNECT_TO_SERVER_H +#define COCKATRICE_CONTEXT_CONNECT_TO_SERVER_H + +#include + +struct ContextConnectToServer +{ + QString hostname; + QString port; + QString username; + QString password; +}; + +#endif // COCKATRICE_CONTEXT_CONNECT_TO_SERVER_H diff --git a/cockatrice/src/interface/intents/contexts/context_join_game.h b/cockatrice/src/interface/intents/contexts/context_join_game.h new file mode 100644 index 000000000..102e2a520 --- /dev/null +++ b/cockatrice/src/interface/intents/contexts/context_join_game.h @@ -0,0 +1,11 @@ +#ifndef COCKATRICE_CONTEXT_JOIN_GAME_H +#define COCKATRICE_CONTEXT_JOIN_GAME_H +#include "context_join_room.h" + +struct ContextJoinGame +{ + ContextJoinRoom roomContext; + int gameId; +}; + +#endif // COCKATRICE_CONTEXT_JOIN_GAME_H diff --git a/cockatrice/src/interface/intents/contexts/context_join_room.h b/cockatrice/src/interface/intents/contexts/context_join_room.h new file mode 100644 index 000000000..23ae05e81 --- /dev/null +++ b/cockatrice/src/interface/intents/contexts/context_join_room.h @@ -0,0 +1,14 @@ +#ifndef COCKATRICE_CONTEXT_JOIN_ROOM_H +#define COCKATRICE_CONTEXT_JOIN_ROOM_H + +#include "context_connect_to_server.h" + +#include + +struct ContextJoinRoom +{ + ContextConnectToServer serverContext; + int roomId; +}; + +#endif // COCKATRICE_CONTEXT_JOIN_ROOM_H diff --git a/cockatrice/src/interface/intents/intent_connect_to_server.cpp b/cockatrice/src/interface/intents/intent_connect_to_server.cpp new file mode 100644 index 000000000..912afa09c --- /dev/null +++ b/cockatrice/src/interface/intents/intent_connect_to_server.cpp @@ -0,0 +1 @@ +#include "intent_connect_to_server.h" diff --git a/cockatrice/src/interface/intents/intent_connect_to_server.h b/cockatrice/src/interface/intents/intent_connect_to_server.h new file mode 100644 index 000000000..291f68849 --- /dev/null +++ b/cockatrice/src/interface/intents/intent_connect_to_server.h @@ -0,0 +1,54 @@ +#ifndef COCKATRICE_INTENT_CONNECT_TO_SERVER_H +#define COCKATRICE_INTENT_CONNECT_TO_SERVER_H + +#include "contexts/context_connect_to_server.h" +#include "intent.h" +#include "intent_disconnect_from_server.h" +#include "remote_client.h" + +#include + +class IntentConnectToServer : public Intent +{ + Q_OBJECT + +public: + IntentConnectToServer(RemoteClient *_remoteClient, ContextConnectToServer *_context) + : Intent(), remoteClient(_remoteClient), context(_context) + { + } + +protected: + bool checkPrecondition() const override + { + return remoteClient->getStatus() == ClientStatus::StatusDisconnected; + } + + void onPreconditionSatisfied() override + { + remoteClient->connectToServer(context->hostname, context->port.toUInt(), context->username, context->password); + connect(remoteClient, &RemoteClient::statusChanged, this, &IntentConnectToServer::onStatusChanged); + } + + void onPreconditionNotSatisfied() override + { + runDependency(new IntentDisconnectFromServer(remoteClient)); + } + +private: + RemoteClient *remoteClient; + ContextConnectToServer *context; +private slots: + void onStatusChanged(ClientStatus status) + { + if (status == ClientStatus::StatusLoggedIn) { + auto timer = new QTimer(this); + timer->setSingleShot(true); + timer->setInterval(2000); + connect(timer, &QTimer::timeout, this, &IntentConnectToServer::finished); + timer->start(); + } + } +}; + +#endif // COCKATRICE_INTENT_CONNECT_TO_SERVER_H diff --git a/cockatrice/src/interface/intents/intent_disconnect_from_server.cpp b/cockatrice/src/interface/intents/intent_disconnect_from_server.cpp new file mode 100644 index 000000000..36f78cede --- /dev/null +++ b/cockatrice/src/interface/intents/intent_disconnect_from_server.cpp @@ -0,0 +1 @@ +#include "intent_disconnect_from_server.h" diff --git a/cockatrice/src/interface/intents/intent_disconnect_from_server.h b/cockatrice/src/interface/intents/intent_disconnect_from_server.h new file mode 100644 index 000000000..b11452639 --- /dev/null +++ b/cockatrice/src/interface/intents/intent_disconnect_from_server.h @@ -0,0 +1,47 @@ +#ifndef COCKATRICE_INTENT_DISCONNECT_FROM_SERVER_H +#define COCKATRICE_INTENT_DISCONNECT_FROM_SERVER_H +#include "intent.h" +#include "remote_client.h" + +class IntentDisconnectFromServer : public Intent +{ + Q_OBJECT + +public: + IntentDisconnectFromServer(RemoteClient *_remoteClient) : Intent(), remoteClient(_remoteClient) + { + } + +protected: + bool checkPrecondition() const override + { + return remoteClient->getStatus() == ClientStatus::StatusDisconnected; + } + + void onPreconditionSatisfied() override + { + qWarning() << "Client disconnected, disconnect is finished"; + emit finished(); + } + + void onPreconditionNotSatisfied() override + { + qWarning() << "Client not disconnected, hooking up signal and disconnecting." << remoteClient->getStatus(); + connect(remoteClient, &RemoteClient::statusChanged, this, &IntentDisconnectFromServer::onStatusChanged); + remoteClient->disconnectFromServer(); + } + +private: + RemoteClient *remoteClient; +private slots: + void onStatusChanged(ClientStatus status) + { + qWarning() << "Client Status changed: " << status; + if (status == ClientStatus::StatusDisconnected) { + qWarning() << "Client disconnected, finished"; + emit finished(); + } + } +}; + +#endif // COCKATRICE_INTENT_DISCONNECT_FROM_SERVER_H diff --git a/cockatrice/src/interface/intents/intent_join_server_game.cpp b/cockatrice/src/interface/intents/intent_join_server_game.cpp new file mode 100644 index 000000000..853307eb5 --- /dev/null +++ b/cockatrice/src/interface/intents/intent_join_server_game.cpp @@ -0,0 +1 @@ +#include "intent_join_server_game.h" diff --git a/cockatrice/src/interface/intents/intent_join_server_game.h b/cockatrice/src/interface/intents/intent_join_server_game.h new file mode 100644 index 000000000..79bbfe7f9 --- /dev/null +++ b/cockatrice/src/interface/intents/intent_join_server_game.h @@ -0,0 +1,63 @@ +#ifndef COCKATRICE_INTENT_JOIN_SERVER_GAME_H +#define COCKATRICE_INTENT_JOIN_SERVER_GAME_H + +#include "../widgets/server/game_selector.h" +#include "../widgets/tabs/tab_room.h" +#include "../widgets/tabs/tab_server.h" +#include "../widgets/tabs/tab_supervisor.h" +#include "contexts/context_join_game.h" +#include "contexts/context_join_room.h" +#include "intent.h" +#include "intent_join_server_room.h" +#include "remote_client.h" + +class IntentJoinServerGame : public Intent +{ + Q_OBJECT + +public: + IntentJoinServerGame(TabSupervisor *_tabSupervisor, RemoteClient *_remoteClient, ContextJoinGame *_context) + : Intent(), tabSupervisor(_tabSupervisor), remoteClient(_remoteClient), context(_context) + { + } + +protected: + bool checkPrecondition() const override + { + if (remoteClient->getStatus() != ClientStatus::StatusLoggedIn) { + return false; + } + if (remoteClient->peerName() != context->roomContext.serverContext.hostname) { + return false; + } + if (QString::number(remoteClient->peerPort()) != context->roomContext.serverContext.port) { + return false; + } + + if (!tabSupervisor->getRoomTabs()[context->roomContext.roomId]) { + qWarning() << "No room tab"; + return false; + }; + + return true; + } + + void onPreconditionSatisfied() override + { + qWarning() << "All lights green, joining game"; + TabRoom *room = tabSupervisor->getRoomTabs()[context->roomContext.roomId]; + room->getGameSelector()->joinGameById(context->gameId); + } + + void onPreconditionNotSatisfied() override + { + runDependency(new IntentJoinServerRoom(tabSupervisor, remoteClient, &context->roomContext)); + } + +private: + TabSupervisor *tabSupervisor; + RemoteClient *remoteClient; + ContextJoinGame *context; +}; + +#endif // COCKATRICE_INTENT_JOIN_SERVER_GAME_H diff --git a/cockatrice/src/interface/intents/intent_join_server_room.cpp b/cockatrice/src/interface/intents/intent_join_server_room.cpp new file mode 100644 index 000000000..89dffc0b3 --- /dev/null +++ b/cockatrice/src/interface/intents/intent_join_server_room.cpp @@ -0,0 +1 @@ +#include "intent_join_server_room.h" diff --git a/cockatrice/src/interface/intents/intent_join_server_room.h b/cockatrice/src/interface/intents/intent_join_server_room.h new file mode 100644 index 000000000..cd48c1df9 --- /dev/null +++ b/cockatrice/src/interface/intents/intent_join_server_room.h @@ -0,0 +1,58 @@ +#ifndef COCKATRICE_INTENT_JOIN_SERVER_ROOM_H +#define COCKATRICE_INTENT_JOIN_SERVER_ROOM_H + +#include "../widgets/tabs/tab_server.h" +#include "../widgets/tabs/tab_supervisor.h" +#include "contexts/context_connect_to_server.h" +#include "contexts/context_join_room.h" +#include "intent.h" +#include "intent_connect_to_server.h" +#include "intent_disconnect_from_server.h" +#include "remote_client.h" + +class IntentJoinServerRoom : public Intent +{ + Q_OBJECT + +public: + IntentJoinServerRoom(TabSupervisor *_tabSupervisor, RemoteClient *_remoteClient, ContextJoinRoom *_context) + : Intent(), tabSupervisor(_tabSupervisor), remoteClient(_remoteClient), context(_context) + { + } + +protected: + bool checkPrecondition() const override + { + if (remoteClient->getStatus() != ClientStatus::StatusLoggedIn) { + return false; + } + if (remoteClient->peerName() != context->serverContext.hostname) { + return false; + } + if (QString::number(remoteClient->peerPort()) != context->serverContext.port) { + return false; + } + + return true; + } + + void onPreconditionSatisfied() override + { + auto tabServer = tabSupervisor->getTabServer(); + tabServer->joinRoom(context->roomId, true); + + connect(tabServer, &TabServer::roomJoined, this, &IntentJoinServerRoom::finished); + } + + void onPreconditionNotSatisfied() override + { + runDependency(new IntentConnectToServer(remoteClient, &context->serverContext)); + } + +private: + TabSupervisor *tabSupervisor; + RemoteClient *remoteClient; + ContextJoinRoom *context; +}; + +#endif // COCKATRICE_INTENT_JOIN_SERVER_ROOM_H diff --git a/cockatrice/src/interface/intents/intent_login.cpp b/cockatrice/src/interface/intents/intent_login.cpp new file mode 100644 index 000000000..b788872c3 --- /dev/null +++ b/cockatrice/src/interface/intents/intent_login.cpp @@ -0,0 +1 @@ +#include "intent_login.h" diff --git a/cockatrice/src/interface/intents/intent_login.h b/cockatrice/src/interface/intents/intent_login.h new file mode 100644 index 000000000..d7df3df7a --- /dev/null +++ b/cockatrice/src/interface/intents/intent_login.h @@ -0,0 +1,52 @@ +#ifndef COCKATRICE_INTENT_LOGIN_H +#define COCKATRICE_INTENT_LOGIN_H + +#include "../../client/settings/cache_settings.h" +#include "contexts/context_connect_to_server.h" +#include "intent.h" +#include "remote_client.h" + +class IntentGetLoginCredentials : public Intent +{ + Q_OBJECT + +public: + IntentGetLoginCredentials(RemoteClient *_remoteClient, ContextConnectToServer *_context) + : Intent(), remoteClient(_remoteClient), context(_context) + { + } + +protected: + bool checkPrecondition() const override + { + ServersSettings &servers = SettingsCache::instance().servers(); + return servers.hasLoginData(context->hostname, context->port); + } + + void onPreconditionSatisfied() override + { + ServersSettings &servers = SettingsCache::instance().servers(); + auto index = servers.findServerIndex(context->hostname, context->port); + + if (index >= 0) { + context->username = + servers.getValue(QString("username%1").arg(index), "server", "server_details").toString(); + context->password = + servers.getValue(QString("password%1").arg(index), "server", "server_details").toString(); + emit finished(); + qWarning() << "Using saved credentials"; + } else { + qWarning() << "No saved server entry"; + } + } + + void onPreconditionNotSatisfied() override + { + } + +private: + RemoteClient *remoteClient; + ContextConnectToServer *context; +}; + +#endif // COCKATRICE_INTENT_LOGIN_H diff --git a/cockatrice/src/interface/intents/url_parser.cpp b/cockatrice/src/interface/intents/url_parser.cpp new file mode 100644 index 000000000..0987ea842 --- /dev/null +++ b/cockatrice/src/interface/intents/url_parser.cpp @@ -0,0 +1,67 @@ +#include "url_parser.h" + +#include "../window_main.h" +#include "contexts/context_join_room.h" +#include "intent_join_server_game.h" +#include "intent_join_server_room.h" +#include "intent_login.h" + +#include +#include +#include + +IntentUrlParser::IntentUrlParser(QObject *parent, MainWindow *_mainWindow) : QObject(parent), mainWindow(_mainWindow) +{ +} + +void IntentUrlParser::handle(const QString &urlStr) +{ + QUrl url(urlStr); + + if (url.scheme() != "cockatrice") + return; + + const QString action = url.host(); + QUrlQuery query(url); + + if (action == "joingame") { + handleJoinGame(query); + } else if (action == "opendeck") { + // handleOpenDeck(query); + } else { + qWarning() << "Unknown intent:" << action; + } +} + +void IntentUrlParser::handleJoinGame(const QUrlQuery &query) +{ + auto ctx = new ContextJoinGame(); + + ctx->roomContext.serverContext.hostname = query.queryItemValue("hostname"); + ctx->roomContext.serverContext.port = query.queryItemValue("port"); + + bool ok = false; + ctx->roomContext.roomId = query.queryItemValue("roomid").toInt(&ok); + + if (!ok) { + qWarning() << "Invalid or missing roomId"; + return; + } + + ok = false; + ctx->gameId = query.queryItemValue("gameid").toInt(&ok); + + if (!ok) { + qWarning() << "Invalid or missing gameId"; + return; + } + + auto getLoginCredentialsIntent = + new IntentGetLoginCredentials(mainWindow->getRemoteClient(), &ctx->roomContext.serverContext); + + auto joinGameIntent = new IntentJoinServerGame(mainWindow->getTabSupervisor(), mainWindow->getRemoteClient(), ctx); + + connect(getLoginCredentialsIntent, &Intent::finished, joinGameIntent, &Intent::execute); + + getLoginCredentialsIntent->execute(); +} diff --git a/cockatrice/src/interface/intents/url_parser.h b/cockatrice/src/interface/intents/url_parser.h new file mode 100644 index 000000000..fb3e8181c --- /dev/null +++ b/cockatrice/src/interface/intents/url_parser.h @@ -0,0 +1,22 @@ +#ifndef COCKATRICE_URL_PARSER_H +#define COCKATRICE_URL_PARSER_H +#include +#include + +class MainWindow; +class IntentUrlParser : public QObject +{ + Q_OBJECT + +public: + IntentUrlParser(QObject *parent, MainWindow *mainWindow); + void handle(const QString &urlStr); + void handleJoinGame(const QUrlQuery &query); + + void parse(QString url); + +private: + MainWindow *mainWindow; +}; + +#endif // COCKATRICE_URL_PARSER_H diff --git a/cockatrice/src/interface/widgets/server/game_selector.cpp b/cockatrice/src/interface/widgets/server/game_selector.cpp index f14cc6d82..16119e538 100644 --- a/cockatrice/src/interface/widgets/server/game_selector.cpp +++ b/cockatrice/src/interface/widgets/server/game_selector.cpp @@ -305,6 +305,7 @@ void GameSelector::customContextMenu(const QPoint &point) connect(&getGameInfo, &QAction::triggered, this, [=, this]() { const ServerInfo_Game &gameInfo = gameListModel->getGame(index.data(Qt::UserRole).toInt()); const QMap &gameTypes = gameListModel->getGameTypes().value(gameInfo.room_id()); + qWarning() << "Game Id: " << gameInfo.game_id(); DlgCreateGame dlg(gameInfo, gameTypes, this); dlg.exec(); @@ -374,6 +375,24 @@ void GameSelector::joinGame(const bool asSpectator, const bool asJudge) disableButtons(); } +bool GameSelector::joinGameById(int gameId) +{ + auto *model = gameListView->model(); + + for (int row = 0; row < model->rowCount(); ++row) { + QModelIndex idx = model->index(row, 0); + const ServerInfo_Game &game = gameListModel->getGame(idx.data(Qt::UserRole).toInt()); + if (game.game_id() == gameId) { + gameListView->setCurrentIndex(idx); + joinGame(); + return true; + } + } + + qWarning() << "Game" << gameId << "not found"; + return false; +} + void GameSelector::disableButtons() { if (createButton) diff --git a/cockatrice/src/interface/widgets/server/game_selector.h b/cockatrice/src/interface/widgets/server/game_selector.h index ea0a4feb0..c502fd04d 100644 --- a/cockatrice/src/interface/widgets/server/game_selector.h +++ b/cockatrice/src/interface/widgets/server/game_selector.h @@ -201,6 +201,7 @@ public: * @param info The ServerInfo_Game object containing information about the game to update. */ void processGameInfo(const ServerInfo_Game &info); + bool joinGameById(int gameId); }; #endif diff --git a/cockatrice/src/interface/widgets/tabs/tab_room.h b/cockatrice/src/interface/widgets/tabs/tab_room.h index 67d9afc86..d5a45533a 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_room.h +++ b/cockatrice/src/interface/widgets/tabs/tab_room.h @@ -125,6 +125,10 @@ public: { return ownUser; } + [[nodiscard]] GameSelector *getGameSelector() const + { + return gameSelector; + } PendingCommand *prepareRoomCommand(const ::google::protobuf::Message &cmd); void sendRoomCommand(PendingCommand *pend); diff --git a/cockatrice/src/interface/widgets/tabs/tab_server.h b/cockatrice/src/interface/widgets/tabs/tab_server.h index f2dd8f0a2..218ddb230 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_server.h +++ b/cockatrice/src/interface/widgets/tabs/tab_server.h @@ -51,7 +51,6 @@ signals: void roomJoined(const ServerInfo_Room &info, bool setCurrent); private slots: void processServerMessageEvent(const Event_ServerMessage &event); - void joinRoom(int id, bool setCurrent); void joinRoomFinished(const Response &resp, const CommandContainer &commandContainer, const QVariant &extraData); private: @@ -62,6 +61,7 @@ private: public: TabServer(TabSupervisor *_tabSupervisor, AbstractClient *_client); + void joinRoom(int id, bool setCurrent); void retranslateUi() override; [[nodiscard]] QString getTabText() const override { diff --git a/cockatrice/src/interface/widgets/tabs/tab_supervisor.h b/cockatrice/src/interface/widgets/tabs/tab_supervisor.h index 0c4428f83..8f5436519 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_supervisor.h +++ b/cockatrice/src/interface/widgets/tabs/tab_supervisor.h @@ -149,6 +149,10 @@ public: { return userListManager; } + [[nodiscard]] TabServer *getTabServer() const + { + return tabServer; + } [[nodiscard]] const QMap &getRoomTabs() const { return roomTabs; diff --git a/cockatrice/src/interface/window_main.h b/cockatrice/src/interface/window_main.h index ed6de5b0d..515527ef2 100644 --- a/cockatrice/src/interface/window_main.h +++ b/cockatrice/src/interface/window_main.h @@ -172,6 +172,11 @@ public: } ~MainWindow() override; + RemoteClient *getRemoteClient() const + { + return client; + }; + TabSupervisor *getTabSupervisor() const { return tabSupervisor; diff --git a/cockatrice/src/main.cpp b/cockatrice/src/main.cpp index c385828fc..9200b2f29 100644 --- a/cockatrice/src/main.cpp +++ b/cockatrice/src/main.cpp @@ -25,6 +25,7 @@ #include "client/sound_engine.h" #include "database/interface/settings_card_preference_provider.h" #include "interface/intents/intent_open_local_deck.h" +#include "interface/intents/url_parser.h" #include "interface/logger.h" #include "interface/pixel_map_generator.h" #include "interface/theme_manager.h" @@ -317,7 +318,8 @@ int main(int argc, char *argv[]) for (const QString &file : startupFiles) { if (file.startsWith("cockatrice://")) { - // ui.openUrl(QUrl(file)); + auto urlParser = new IntentUrlParser(&ui, &ui); + urlParser->handle(file); } else if (QFileInfo(file).exists()) { auto openDeckIntent = new IntentOpenLocalDeck(ui.getTabSupervisor(), file); openDeckIntent->execute(); @@ -328,7 +330,8 @@ int main(int argc, char *argv[]) QObject::connect(&instance, &SingleInstanceManager::filesReceived, [&ui](const QStringList &files) { for (const QString &file : files) { if (file.startsWith("cockatrice://")) { - // ui.openUrl(QUrl(file)); + auto urlParser = new IntentUrlParser(&ui, &ui); + urlParser->handle(file); } else if (QFileInfo(file).exists()) { auto openDeckIntent = new IntentOpenLocalDeck(ui.getTabSupervisor(), file); openDeckIntent->execute(); diff --git a/libcockatrice_network/libcockatrice/network/client/remote/remote_client.h b/libcockatrice_network/libcockatrice/network/client/remote/remote_client.h index 15e3e8ef5..b5e80eee1 100644 --- a/libcockatrice_network/libcockatrice/network/client/remote/remote_client.h +++ b/libcockatrice_network/libcockatrice/network/client/remote/remote_client.h @@ -131,6 +131,14 @@ public: return socket->peerName(); } } + quint16 peerPort() const + { + if (usingWebSocket) { + return websocket->peerPort(); + } else { + return socket->peerPort(); + } + } void connectToServer(const QString &hostname, unsigned int port, const QString &_userName, const QString &_password); void registerToServer(const QString &hostname, diff --git a/libcockatrice_settings/libcockatrice/settings/servers_settings.cpp b/libcockatrice_settings/libcockatrice/settings/servers_settings.cpp index 0140182be..835b97aca 100644 --- a/libcockatrice_settings/libcockatrice/settings/servers_settings.cpp +++ b/libcockatrice_settings/libcockatrice/settings/servers_settings.cpp @@ -289,3 +289,46 @@ bool ServersSettings::updateExistingServer(QString saveName, } return false; } + +int ServersSettings::findServerIndex(const QString &host, const QString &port) const +{ + int size = getValue("totalServers", "server", "server_details").toInt(); + + for (int i = 0; i <= size; ++i) { + QString storedHost = getValue(QString("server%1").arg(i), "server", "server_details").toString(); + QString storedPort = getValue(QString("port%1").arg(i), "server", "server_details").toString(); + + if (storedHost == host && storedPort == port) { + return i; + } + } + + return -1; +} + +bool ServersSettings::hasUsername(const QString &host, const QString &port) const +{ + int index = findServerIndex(host, port); + if (index < 0) + return false; + + QString user = getValue(QString("username%1").arg(index), "server", "server_details").toString(); + return !user.isEmpty(); +} + +bool ServersSettings::hasCredentials(const QString &host, const QString &port) const +{ + int index = findServerIndex(host, port); + if (index < 0) + return false; + + bool save = getValue(QString("savePassword%1").arg(index), "server", "server_details").toBool(); + QString password = getValue(QString("password%1").arg(index), "server", "server_details").toString(); + + return save && !password.isEmpty(); +} + +bool ServersSettings::hasLoginData(const QString &host, const QString &port) const +{ + return hasUsername(host, port) && hasCredentials(host, port); +} \ No newline at end of file diff --git a/libcockatrice_settings/libcockatrice/settings/servers_settings.h b/libcockatrice_settings/libcockatrice/settings/servers_settings.h index 22603a356..e18857931 100644 --- a/libcockatrice_settings/libcockatrice/settings/servers_settings.h +++ b/libcockatrice_settings/libcockatrice/settings/servers_settings.h @@ -61,6 +61,10 @@ public: QString password, bool savePassword, QString site = QString()); + int findServerIndex(const QString &host, const QString &port) const; + bool hasUsername(const QString &host, const QString &port) const; + bool hasCredentials(const QString &host, const QString &port) const; + bool hasLoginData(const QString &host, const QString &port) const; bool updateExistingServerWithoutLoss(QString saveName, QString serv = QString(),