diff --git a/cockatrice/CMakeLists.txt b/cockatrice/CMakeLists.txt index 9ea463eef..6fd683461 100644 --- a/cockatrice/CMakeLists.txt +++ b/cockatrice/CMakeLists.txt @@ -246,7 +246,6 @@ set(cockatrice_SOURCES src/interface/widgets/replay/replay_widget.cpp src/interface/widgets/server/chat_view/chat_view.cpp src/interface/widgets/server/game_filter_configs.cpp - src/interface/widgets/server/game_link.cpp src/interface/widgets/server/game_selector.cpp src/interface/widgets/server/game_selector_quick_filter_toolbar.cpp src/interface/widgets/server/games_model.cpp diff --git a/cockatrice/src/interface/widgets/server/game_link.cpp b/cockatrice/src/interface/widgets/server/game_link.cpp deleted file mode 100644 index c866f6571..000000000 --- a/cockatrice/src/interface/widgets/server/game_link.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "game_link.h" - -#include -#include - -QString makeGameJoinLink(const QString &hostname, int port, int roomId, int gameId, const QString &description) -{ - QUrl url; - url.setScheme("cockatrice"); - url.setHost("joingame"); - QUrlQuery query; - query.addQueryItem("hostname", hostname); - query.addQueryItem("port", QString::number(port)); - query.addQueryItem("roomid", QString::number(roomId)); - query.addQueryItem("gameid", QString::number(gameId)); - if (!description.isEmpty()) { - // addQueryItem percent-encodes, so arbitrary descriptions (quotes, - // ampersands, non-ASCII…) survive the trip through chat. - query.addQueryItem("game", description); - } - url.setQuery(query); - return url.toString(QUrl::FullyEncoded); -} diff --git a/cockatrice/src/interface/widgets/server/game_link.h b/cockatrice/src/interface/widgets/server/game_link.h deleted file mode 100644 index d57bbd6d2..000000000 --- a/cockatrice/src/interface/widgets/server/game_link.h +++ /dev/null @@ -1,41 +0,0 @@ -/** - * @file game_link.h - * @ingroup UI - * @brief Builds cockatrice://joingame links that let another user join a server game. - */ - -#ifndef GAME_LINK_H -#define GAME_LINK_H - -#include - -/** - * Builds a cockatrice://joingame link for the given server game. The receiver's - * client opens it through the intent chain (connect -> join room -> join game). - * @p description, when non-empty, is embedded in the link as the URL-encoded - * "game" query item so the receiving client can name the game in its confirm - * prompt and chat anchor instead of only its numeric id. Links built without it - * stay valid: the parser and chat renderer fall back to the id alone. - */ -QString -makeGameJoinLink(const QString &hostname, int port, int roomId, int gameId, const QString &description = QString()); - -/** - * One game the inviter is currently in and can invite another user to. - * @p label is meant for display in menus, @p url is the ready-made invite link. - * @p description is the raw game description for building tr()-wrapped invite - * messages (the label already embeds it, but the send sites need the raw value). - * @p onlyBuddies and @p creatorName mirror the server game's room settings so - * callers can gate the invite to the creator's buddies. - */ -struct GameInviteOption -{ - int gameId = 0; - QString label; - QString url; - QString description; - bool onlyBuddies = false; - QString creatorName; -}; - -#endif // GAME_LINK_H diff --git a/cockatrice/src/interface/widgets/server/game_selector.cpp b/cockatrice/src/interface/widgets/server/game_selector.cpp index 28e2ae607..6580f0262 100644 --- a/cockatrice/src/interface/widgets/server/game_selector.cpp +++ b/cockatrice/src/interface/widgets/server/game_selector.cpp @@ -7,7 +7,6 @@ #include "../interface/widgets/tabs/tab_room.h" #include "../interface/widgets/tabs/tab_supervisor.h" #include "../interface/widgets/utility/get_text_with_max.h" -#include "game_link.h" #include "games_model.h" #include "user/user_list_manager.h" @@ -19,6 +18,8 @@ #include #include #include +#include +#include #include #include #include @@ -319,12 +320,19 @@ void GameSelector::customContextMenu(const QPoint &point) dlg.exec(); }); - QAction copyLink(tr("Cop&y game link")); + QAction copyLink(tr("Copy Game Link")); connect(©Link, &QAction::triggered, this, [=, this]() { const ServerInfo_Game &gameInfo = gameListModel->getGame(index.data(Qt::UserRole).toInt()); - QGuiApplication::clipboard()->setText(makeGameJoinLink(client->serverName(), client->serverPort(), - gameInfo.room_id(), gameInfo.game_id(), - QString::fromStdString(gameInfo.description()))); + QUrl url; + url.setScheme("cockatrice"); + url.setHost("joingame"); + QUrlQuery query; + query.addQueryItem("hostname", client->serverName()); + query.addQueryItem("port", QString::number(client->serverPort())); + query.addQueryItem("roomid", QString::number(gameInfo.room_id())); + query.addQueryItem("gameid", QString::number(gameInfo.game_id())); + url.setQuery(query); + QGuiApplication::clipboard()->setText(url.toString(QUrl::FullyEncoded)); }); QMenu menu; @@ -364,31 +372,13 @@ void GameSelector::joinGame(const bool asSpectator, const bool asJudge) return; } + bool spectator = asSpectator || game.player_count() == game.max_players(); + bool overrideRestrictions = !tabSupervisor->getAdminLocked(); - - // Joining a full game without override privileges silently becomes a - // spectator join, so ask first instead of surprising the player. - const bool gameFull = game.player_count() == game.max_players(); - if (gameFull && !asSpectator && !asJudge && !overrideRestrictions) { - const QMessageBox::StandardButton answer = - QMessageBox::question(this, tr("Join game"), tr("The game is full. Join as a spectator instead?"), - QMessageBox::Yes | QMessageBox::No, QMessageBox::No); - if (answer != QMessageBox::Yes) { - return; - } - } - - bool spectator = asSpectator || gameFull; - QString password; if (game.with_password() && !(spectator && !game.spectators_need_password()) && !overrideRestrictions) { bool ok; - // Games without a description have no sensible label — fall back to the - // game id so the prompt still tells the user which game they're entering. - const QString gameLabel = QString::fromStdString(game.description()); - const QString prompt = gameLabel.isEmpty() ? tr("Password for game #%1:").arg(game.game_id()) - : tr("Password for \"%1\":").arg(gameLabel); - password = getTextWithMax(this, tr("Join game"), prompt, QLineEdit::Password, QString(), &ok); + password = getTextWithMax(this, tr("Join game"), tr("Password:"), QLineEdit::Password, QString(), &ok); if (!ok) { return; } diff --git a/cockatrice/src/interface/widgets/tabs/tab_game.cpp b/cockatrice/src/interface/widgets/tabs/tab_game.cpp index 3f165c1d5..82d99b605 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_game.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_game.cpp @@ -20,7 +20,6 @@ #include "../interface/card_picture_loader/card_picture_loader.h" #include "../interface/widgets/cards/card_info_frame_widget.h" #include "../interface/widgets/dialogs/dlg_create_game.h" -#include "../interface/widgets/server/game_link.h" #include "../interface/widgets/server/user/user_list_manager.h" #include "../interface/widgets/utility/completer_utils.h" #include "../interface/widgets/utility/line_edit_completer.h" @@ -34,8 +33,6 @@ #include "tab_supervisor.h" #include -#include -#include #include #include #include @@ -334,9 +331,6 @@ void TabGame::retranslateUi() if (aGameInfo) { aGameInfo->setText(tr("Game &information")); } - if (aCopyGameLink) { - aCopyGameLink->setText(tr("Cop&y game link")); - } if (aConcede) { if (game->getPlayerManager()->isMainPlayerConceded()) { aConcede->setText(tr("Un&concede")); @@ -504,15 +498,6 @@ void TabGame::actGameInfo() dlg.exec(); } -void TabGame::actCopyGameLink() -{ - const QString link = - makeGameJoinLink(tabSupervisor->getClient()->serverName(), tabSupervisor->getClient()->serverPort(), - game->getGameMetaInfo()->proto().room_id(), game->getGameMetaInfo()->gameId(), - QString::fromStdString(game->getGameMetaInfo()->proto().description())); - QApplication::clipboard()->setText(link); -} - void TabGame::actConcede() { PlayerLogic *player = game->getPlayerManager()->getActiveLocalPlayer(game->getGameState()->getActivePlayer()); @@ -1001,9 +986,6 @@ void TabGame::createMenuItems() connect(aRotateViewCCW, &QAction::triggered, this, &TabGame::actRotateViewCCW); aGameInfo = new QAction(this); connect(aGameInfo, &QAction::triggered, this, &TabGame::actGameInfo); - aCopyGameLink = new QAction(this); - aCopyGameLink->setEnabled(!tabSupervisor->getIsLocalGame() && !tabSupervisor->getClient()->serverName().isEmpty()); - connect(aCopyGameLink, &QAction::triggered, this, &TabGame::actCopyGameLink); aConcede = new QAction(this); connect(aConcede, &QAction::triggered, this, &TabGame::actConcede); if (!game->getGameMetaInfo()->started()) { @@ -1042,7 +1024,6 @@ void TabGame::createMenuItems() gameMenu->addAction(aRotateViewCCW); gameMenu->addSeparator(); gameMenu->addAction(aGameInfo); - gameMenu->addAction(aCopyGameLink); gameMenu->addAction(aConcede); gameMenu->addAction(aFocusChat); gameMenu->addAction(aLeaveGame); @@ -1065,7 +1046,6 @@ void TabGame::createReplayMenuItems() aRotateViewCCW = nullptr; aResetLayout = nullptr; aGameInfo = nullptr; - aCopyGameLink = nullptr; aConcede = nullptr; aFocusChat = nullptr; aLeaveGame = new QAction(this); diff --git a/cockatrice/src/interface/widgets/tabs/tab_game.h b/cockatrice/src/interface/widgets/tabs/tab_game.h index b6555deef..fc51817c6 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_game.h +++ b/cockatrice/src/interface/widgets/tabs/tab_game.h @@ -83,8 +83,8 @@ private: QAction *playersSeparator; QMenu *gameMenu, *viewMenu; TearOffMenu *phasesMenu; - QAction *aGameInfo, *aConcede, *aCopyGameLink, *aLeaveGame, *aNextPhase, *aNextPhaseAction, *aNextTurn, - *aReverseTurn, *aRemoveLocalArrows, *aRotateViewCW, *aRotateViewCCW, *aResetLayout, *aResetReplayLayout; + QAction *aGameInfo, *aConcede, *aLeaveGame, *aNextPhase, *aNextPhaseAction, *aNextTurn, *aReverseTurn, + *aRemoveLocalArrows, *aRotateViewCW, *aRotateViewCCW, *aResetLayout, *aResetReplayLayout; QAction *aFocusChat; QList phaseActions; QAction *aCardMenu; @@ -148,7 +148,6 @@ private slots: void actGameInfo(); void actConcede(); - void actCopyGameLink(); void actRemoveLocalArrows(); void actRotateViewCW(); void actRotateViewCCW(); diff --git a/libcockatrice_network/libcockatrice/network/server/remote/CMakeLists.txt b/libcockatrice_network/libcockatrice/network/server/remote/CMakeLists.txt index 80a80e1ae..9fb63c221 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/CMakeLists.txt +++ b/libcockatrice_network/libcockatrice/network/server/remote/CMakeLists.txt @@ -10,7 +10,6 @@ set(HEADERS game/server_card.h game/server_cardzone.h game/server_counter.h - game/game_config.h game/server_game.h game/server_player.h game/server_spectator.h diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/game_config.h b/libcockatrice_network/libcockatrice/network/server/remote/game/game_config.h deleted file mode 100644 index baf946632..000000000 --- a/libcockatrice_network/libcockatrice/network/server/remote/game/game_config.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef GAME_CONFIG_H -#define GAME_CONFIG_H - -#include -#include -#include - -struct GameConfig -{ - ServerInfo_User creatorInfo; - int gameId = -1; - QString description; - QString password; - int maxPlayers = 2; - QList gameTypes; - bool onlyBuddies = false; - bool onlyRegistered = false; - bool spectatorsAllowed = false; - bool spectatorsNeedPassword = false; - bool spectatorsCanTalk = true; - bool spectatorsSeeEverything = true; - int startingLifeTotal = 20; - bool shareDecklistsOnLoad = true; -}; - -#endif diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/server_game.cpp b/libcockatrice_network/libcockatrice/network/server/remote/game/server_game.cpp index 60d11ead1..b9e548653 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/game/server_game.cpp +++ b/libcockatrice_network/libcockatrice/network/server/remote/game/server_game.cpp @@ -53,19 +53,34 @@ #include #include -Server_Game::Server_Game(const GameConfig &config, Server_Room *_room) - : QObject(), room(_room), nextPlayerId(0), hostId(0), creatorInfo(new ServerInfo_User(config.creatorInfo)), - gameStarted(false), gameClosed(false), gameId(config.gameId), description(config.description.simplified()), - password(config.password), maxPlayers(config.maxPlayers), gameTypes(config.gameTypes), activePlayer(-1), - activePhase(-1), onlyBuddies(config.onlyBuddies), onlyRegistered(config.onlyRegistered), - spectatorsAllowed(config.spectatorsAllowed), spectatorsNeedPassword(config.spectatorsNeedPassword), - spectatorsCanTalk(config.spectatorsCanTalk), spectatorsSeeEverything(config.spectatorsSeeEverything), - startingLifeTotal(config.startingLifeTotal), shareDecklistsOnLoad(config.shareDecklistsOnLoad), - inactivityCounter(0), startTimeOfThisGame(0), secondsElapsed(0), firstGameStarted(false), - turnOrderReversed(false), startTime(QDateTime::currentDateTime()), pingClock(nullptr), gameMutex() +Server_Game::Server_Game(const ServerInfo_User &_creatorInfo, + int _gameId, + const QString &_description, + const QString &_password, + int _maxPlayers, + const QList &_gameTypes, + bool _onlyBuddies, + bool _onlyRegistered, + bool _spectatorsAllowed, + bool _spectatorsNeedPassword, + bool _spectatorsCanTalk, + bool _spectatorsSeeEverything, + int _startingLifeTotal, + bool _shareDecklistsOnLoad, + Server_Room *_room) + : QObject(), room(_room), nextPlayerId(0), hostId(0), creatorInfo(new ServerInfo_User(_creatorInfo)), + gameStarted(false), gameClosed(false), gameId(_gameId), password(_password), maxPlayers(_maxPlayers), + gameTypes(_gameTypes), activePlayer(-1), activePhase(-1), onlyBuddies(_onlyBuddies), + onlyRegistered(_onlyRegistered), spectatorsAllowed(_spectatorsAllowed), + spectatorsNeedPassword(_spectatorsNeedPassword), spectatorsCanTalk(_spectatorsCanTalk), + spectatorsSeeEverything(_spectatorsSeeEverything), startingLifeTotal(_startingLifeTotal), + shareDecklistsOnLoad(_shareDecklistsOnLoad), inactivityCounter(0), startTimeOfThisGame(0), secondsElapsed(0), + firstGameStarted(false), turnOrderReversed(false), startTime(QDateTime::currentDateTime()), pingClock(nullptr), + gameMutex() { currentReplay = new GameReplay; currentReplay->set_replay_id(room->getServer()->getDatabaseInterface()->getNextReplayId()); + description = _description.simplified(); connect(this, &Server_Game::sigStartGameIfReady, this, &Server_Game::doStartGameIfReady, Qt::QueuedConnection); diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/server_game.h b/libcockatrice_network/libcockatrice/network/server/remote/game/server_game.h index 60b5398f2..e0e7896b7 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/game/server_game.h +++ b/libcockatrice_network/libcockatrice/network/server/remote/game/server_game.h @@ -21,7 +21,6 @@ #define SERVERGAME_H #include "../server_response_containers.h" -#include "game_config.h" #include #include @@ -93,7 +92,21 @@ private slots: public: mutable QRecursiveMutex gameMutex; - Server_Game(const GameConfig &config, Server_Room *parent); + Server_Game(const ServerInfo_User &_creatorInfo, + int _gameId, + const QString &_description, + const QString &_password, + int _maxPlayers, + const QList &_gameTypes, + bool _onlyBuddies, + bool _onlyRegistered, + bool _spectatorsAllowed, + bool _spectatorsNeedPassword, + bool _spectatorsCanTalk, + bool _spectatorsSeeEverything, + int _startingLifeTotal, + bool _shareDecklistsOnLoad, + Server_Room *parent); ~Server_Game() override; Server_Room *getRoom() const { diff --git a/libcockatrice_network/libcockatrice/network/server/remote/server_protocolhandler.cpp b/libcockatrice_network/libcockatrice/network/server/remote/server_protocolhandler.cpp index 561115084..ba6ac4691 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/server_protocolhandler.cpp +++ b/libcockatrice_network/libcockatrice/network/server/remote/server_protocolhandler.cpp @@ -1,6 +1,5 @@ #include "server_protocolhandler.h" -#include "game/game_config.h" #include "game/server_game.h" #include "game/server_player.h" #include "server_database_interface.h" @@ -921,22 +920,10 @@ Server_ProtocolHandler::cmdCreateGame(const Command_CreateGame &cmd, Server_Room // When server doesn't permit registered users to exist, do not honor only-reg setting bool onlyRegisteredUsers = cmd.only_registered() && (server->permitUnregisteredUsers()); - GameConfig config{.creatorInfo = copyUserInfo(false), - .gameId = gameId, - .description = description, - .password = QString::fromStdString(cmd.password()), - .maxPlayers = static_cast(cmd.max_players()), - .gameTypes = gameTypes, - .onlyBuddies = cmd.only_buddies(), - .onlyRegistered = onlyRegisteredUsers, - .spectatorsAllowed = cmd.spectators_allowed(), - .spectatorsNeedPassword = cmd.spectators_need_password(), - .spectatorsCanTalk = cmd.spectators_can_talk(), - .spectatorsSeeEverything = cmd.spectators_see_everything(), - .startingLifeTotal = startingLifeTotal, - .shareDecklistsOnLoad = shareDecklistsOnLoad}; - - auto *game = new Server_Game(config, room); + auto *game = new Server_Game(copyUserInfo(false), gameId, description, QString::fromStdString(cmd.password()), + cmd.max_players(), gameTypes, cmd.only_buddies(), onlyRegisteredUsers, + cmd.spectators_allowed(), cmd.spectators_need_password(), cmd.spectators_can_talk(), + cmd.spectators_see_everything(), startingLifeTotal, shareDecklistsOnLoad, room); game->addPlayer(this, rc, asSpectator, asJudge, false); room->addGame(game); diff --git a/tests/movecard_tests/reverse_card_move_test.cpp b/tests/movecard_tests/reverse_card_move_test.cpp index 64c93078c..2231a7e3b 100644 --- a/tests/movecard_tests/reverse_card_move_test.cpp +++ b/tests/movecard_tests/reverse_card_move_test.cpp @@ -1,4 +1,3 @@ -#include "game/game_config.h" #include "game/server_abstract_player.h" #include "game/server_card.h" #include "game/server_cardzone.h" @@ -23,21 +22,7 @@ TEST(ReverseCardMoveTest, MoveCardFromBottomTest) // instantiate a fake server instance FakeServer server; Server_Room room(0, 0, "", "", "", "", false, "", {}, &server); - GameConfig config{.creatorInfo = user, - .gameId = 1, - .description = QString(), - .password = QString(), - .maxPlayers = 2, - .gameTypes = QList(), - .onlyBuddies = false, - .onlyRegistered = false, - .spectatorsAllowed = false, - .spectatorsNeedPassword = false, - .spectatorsCanTalk = false, - .spectatorsSeeEverything = false, - .startingLifeTotal = 20, - .shareDecklistsOnLoad = false}; - Server_Game game(config, &room); + Server_Game game(user, 1, "", "", 2, QList(), false, false, false, false, false, false, 20, false, &room); Server_AbstractPlayer player(&game, 1, user, false, nullptr); Server_CardZone deckZone(&player, ZoneNames::DECK, true, ServerInfo_Zone::PublicZone); Server_CardZone exileZone(&player, ZoneNames::EXILE, true, ServerInfo_Zone::PublicZone);