From d932581f4abde1b3f28d90a073fddec77941f23b Mon Sep 17 00:00:00 2001 From: Rob Blanckaert Date: Thu, 7 Feb 2019 11:08:44 -0800 Subject: [PATCH] Move to bottom of library in random order. (#3549) * - Allow shuffling a subset of a zone - When moving cards to the bottom of library, shuffle them after - Process events in the correct order serverside * Zach fixes Signed-off-by: Zach Halpern * Comments + additional guard --- cockatrice/src/messagelogwidget.cpp | 71 +++++++++++----- cockatrice/src/messagelogwidget.h | 2 +- cockatrice/src/player.cpp | 14 +++- cockatrice/src/player.h | 2 +- common/pb/command_shuffle.proto | 3 + common/pb/event_shuffle.proto | 2 + common/server_cardzone.cpp | 38 ++++++--- common/server_cardzone.h | 4 +- common/server_player.cpp | 122 ++++++++++++++-------------- common/server_player.h | 11 +-- 10 files changed, 160 insertions(+), 109 deletions(-) diff --git a/cockatrice/src/messagelogwidget.cpp b/cockatrice/src/messagelogwidget.cpp index 533a5911..15542509 100644 --- a/cockatrice/src/messagelogwidget.cpp +++ b/cockatrice/src/messagelogwidget.cpp @@ -1,6 +1,8 @@ -#include "messagelogwidget.h" +#include + #include "carditem.h" #include "cardzone.h" +#include "messagelogwidget.h" #include "pb/context_move_card.pb.h" #include "pb/context_mulligan.pb.h" #include "pb/serverinfo_user.pb.h" @@ -120,14 +122,14 @@ MessageLogWidget::getFromStr(CardZone *zone, QString cardName, int position, boo void MessageLogWidget::containerProcessingDone() { if (currentContext == MessageContext_MoveCard) { - for (int i = 0; i < moveCardQueue.size(); ++i) - logDoMoveCard(moveCardQueue[i]); + for (auto &i : moveCardQueue) + logDoMoveCard(i); moveCardQueue.clear(); moveCardPT.clear(); moveCardTapped.clear(); } else if (currentContext == MessageContext_Mulligan) { logMulligan(mulliganPlayer, mulliganNumber); - mulliganPlayer = 0; + mulliganPlayer = nullptr; mulliganNumber = 0; } @@ -141,7 +143,7 @@ void MessageLogWidget::containerProcessingStarted(const GameEventContext &contex else if (context.HasExtension(Context_Mulligan::ext)) { const Context_Mulligan &contextMulligan = context.GetExtension(Context_Mulligan::ext); currentContext = MessageContext_Mulligan; - mulliganPlayer = 0; + mulliganPlayer = nullptr; mulliganNumber = contextMulligan.number(); } } @@ -158,9 +160,9 @@ void MessageLogWidget::logAttachCard(Player *player, QString cardName, Player *t { appendHtmlServerMessage(tr("%1 attaches %2 to %3's %4.") .arg(sanitizeHtml(player->getName())) - .arg(cardLink(cardName)) + .arg(cardLink(std::move(cardName))) .arg(sanitizeHtml(targetPlayer->getName())) - .arg(cardLink(targetCardName))); + .arg(cardLink(std::move(targetCardName)))); } void MessageLogWidget::logConcede(Player *player) @@ -247,7 +249,7 @@ void MessageLogWidget::logCreateToken(Player *player, QString cardName, QString { appendHtmlServerMessage(tr("%1 creates token: %2%3.") .arg(sanitizeHtml(player->getName())) - .arg(cardLink(cardName)) + .arg(cardLink(std::move(cardName))) .arg(pt.isEmpty() ? QString() : QString(" (%1)").arg(sanitizeHtml(pt)))); } @@ -264,7 +266,8 @@ void MessageLogWidget::logDeckSelect(Player *player, QString deckHash, int sideb void MessageLogWidget::logDestroyCard(Player *player, QString cardName) { - appendHtmlServerMessage(tr("%1 destroys %2.").arg(sanitizeHtml(player->getName())).arg(cardLink(cardName))); + appendHtmlServerMessage( + tr("%1 destroys %2.").arg(sanitizeHtml(player->getName())).arg(cardLink(std::move(cardName)))); } void MessageLogWidget::logDoMoveCard(LogMoveCard &lmc) @@ -395,7 +398,7 @@ void MessageLogWidget::logJoin(Player *player) void MessageLogWidget::logJoinSpectator(QString name) { soundEngine->playSound("spectator_join"); - appendHtmlServerMessage(tr("%1 is now watching the game.").arg(sanitizeHtml(name))); + appendHtmlServerMessage(tr("%1 is now watching the game.").arg(sanitizeHtml(std::move(name)))); } void MessageLogWidget::logKicked() @@ -406,15 +409,15 @@ void MessageLogWidget::logKicked() void MessageLogWidget::logLeave(Player *player, QString reason) { soundEngine->playSound("player_leave"); - appendHtmlServerMessage(tr("%1 has left the game (%2).").arg(sanitizeHtml(player->getName()), sanitizeHtml(reason)), - true); + appendHtmlServerMessage( + tr("%1 has left the game (%2).").arg(sanitizeHtml(player->getName()), sanitizeHtml(std::move(reason))), true); } void MessageLogWidget::logLeaveSpectator(QString name, QString reason) { soundEngine->playSound("spectator_leave"); - appendHtmlServerMessage( - tr("%1 is not watching the game any more (%2).").arg(sanitizeHtml(name), sanitizeHtml(reason))); + appendHtmlServerMessage(tr("%1 is not watching the game any more (%2).") + .arg(sanitizeHtml(std::move(name)), sanitizeHtml(std::move(reason)))); } void MessageLogWidget::logNotReadyStart(Player *player) @@ -551,7 +554,7 @@ void MessageLogWidget::logRollDie(Player *player, int sides, int roll) void MessageLogWidget::logSay(Player *player, QString message) { - appendMessage(message, 0, player->getName(), UserLevelFlags(player->getUserInfo()->user_level()), + appendMessage(std::move(message), nullptr, player->getName(), UserLevelFlags(player->getUserInfo()->user_level()), QString::fromStdString(player->getUserInfo()->privlevel()), true); } @@ -636,7 +639,7 @@ void MessageLogWidget::logSetAnnotation(Player *player, CardItem *card, QString QString(tr("%1 sets annotation of %2 to %3.")) .arg(sanitizeHtml(player->getName())) .arg(cardLink(card->getName())) - .arg(QString(""%1"").arg(sanitizeHtml(newAnnotation)))); + .arg(QString(""%1"").arg(sanitizeHtml(std::move(newAnnotation))))); } void MessageLogWidget::logSetCardCounter(Player *player, QString cardName, int counterId, int value, int oldValue) @@ -665,7 +668,7 @@ void MessageLogWidget::logSetCardCounter(Player *player, QString cardName, int c appendHtmlServerMessage(finalStr.arg(sanitizeHtml(player->getName())) .arg("" + QString::number(delta) + "") .arg(colorStr) - .arg(cardLink(cardName)) + .arg(cardLink(std::move(cardName))) .arg(value)); } @@ -741,13 +744,36 @@ void MessageLogWidget::logSetTapped(Player *player, CardItem *card, bool tapped) } } -void MessageLogWidget::logShuffle(Player *player, CardZone *zone) +void MessageLogWidget::logShuffle(Player *player, CardZone *zone, int start, int end) { soundEngine->playSound("shuffle"); - if (currentContext != MessageContext_Mulligan) + if (currentContext == MessageContext_Mulligan) { + return; + } + + // start and end are indexes into the portion of the deck that was shuffled + // with negitive numbers counging from the bottom up. + if (start == 0 && end == -1) { appendHtmlServerMessage(tr("%1 shuffles %2.") .arg(sanitizeHtml(player->getName())) .arg(zone->getTranslatedName(true, CaseShuffleZone))); + } else if (start < 0 && end == -1) { + appendHtmlServerMessage(tr("%1 shuffles the bottom %3 cards of %2.") + .arg(sanitizeHtml(player->getName())) + .arg(zone->getTranslatedName(true, CaseShuffleZone)) + .arg(-start)); + } else if (start < 0 && end > 0) { + appendHtmlServerMessage(tr("%1 shuffles the top %3 cards of %2.") + .arg(sanitizeHtml(player->getName())) + .arg(zone->getTranslatedName(true, CaseShuffleZone)) + .arg(end + 1)); + } else { + appendHtmlServerMessage(tr("%1 shuffles cards %3 - %4 of %2.") + .arg(sanitizeHtml(player->getName())) + .arg(zone->getTranslatedName(true, CaseShuffleZone)) + .arg(start) + .arg(end)); + } } void MessageLogWidget::logSpectatorSay(QString spectatorName, @@ -755,7 +781,7 @@ void MessageLogWidget::logSpectatorSay(QString spectatorName, QString userPrivLevel, QString message) { - appendMessage(message, 0, spectatorName, spectatorUserLevel, userPrivLevel, false); + appendMessage(std::move(message), nullptr, spectatorName, spectatorUserLevel, userPrivLevel, false); } void MessageLogWidget::logStopDumpZone(Player *player, CardZone *zone) @@ -767,7 +793,8 @@ void MessageLogWidget::logStopDumpZone(Player *player, CardZone *zone) void MessageLogWidget::logUnattachCard(Player *player, QString cardName) { - appendHtmlServerMessage(tr("%1 unattaches %2.").arg(sanitizeHtml(player->getName())).arg(cardLink(cardName))); + appendHtmlServerMessage( + tr("%1 unattaches %2.").arg(sanitizeHtml(player->getName())).arg(cardLink(std::move(cardName)))); } void MessageLogWidget::logUndoDraw(Player *player, QString cardName) @@ -784,7 +811,7 @@ void MessageLogWidget::logUndoDraw(Player *player, QString cardName) void MessageLogWidget::connectToPlayer(Player *player) { connect(player, SIGNAL(logSay(Player *, QString)), this, SLOT(logSay(Player *, QString))); - connect(player, SIGNAL(logShuffle(Player *, CardZone *)), this, SLOT(logShuffle(Player *, CardZone *))); + connect(player, &Player::logShuffle, this, &MessageLogWidget::logShuffle); connect(player, SIGNAL(logRollDie(Player *, int, int)), this, SLOT(logRollDie(Player *, int, int))); connect(player, SIGNAL(logCreateArrow(Player *, Player *, QString, Player *, QString, bool)), this, SLOT(logCreateArrow(Player *, Player *, QString, Player *, QString, bool))); diff --git a/cockatrice/src/messagelogwidget.h b/cockatrice/src/messagelogwidget.h index 449df4aa..8f9217a9 100644 --- a/cockatrice/src/messagelogwidget.h +++ b/cockatrice/src/messagelogwidget.h @@ -102,7 +102,7 @@ public slots: void logSetPT(Player *player, CardItem *card, QString newPT); void logSetSideboardLock(Player *player, bool locked); void logSetTapped(Player *player, CardItem *card, bool tapped); - void logShuffle(Player *player, CardZone *zone); + void logShuffle(Player *player, CardZone *zone, int start, int end); void logSpectatorSay(QString spectatorName, UserLevelFlags spectatorUserLevel, QString userPrivLevel, QString message); void logStopDumpZone(Player *player, CardZone *zone); diff --git a/cockatrice/src/player.cpp b/cockatrice/src/player.cpp index 1bc0923b..569c7191 100644 --- a/cockatrice/src/player.cpp +++ b/cockatrice/src/player.cpp @@ -738,7 +738,7 @@ void Player::retranslateUi() aMoveToTopLibrary->setText(tr("&Top of library")); aMoveToXfromTopOfLibrary->setText(tr("X cards from the top of library...")); - aMoveToBottomLibrary->setText(tr("&Bottom of library")); + aMoveToBottomLibrary->setText(tr("&Bottom of library in random order")); aMoveToHand->setText(tr("&Hand")); aMoveToGraveyard->setText(tr("&Graveyard")); aMoveToExile->setText(tr("&Exile")); @@ -1453,7 +1453,7 @@ void Player::eventShuffle(const Event_Shuffle &event) if (zone->getView() && zone->getView()->getRevealZone()) { zone->getView()->setWriteableRevealZone(false); } - emit logShuffle(this, zone); + emit logShuffle(this, zone, event.start(), event.end()); } void Player::eventRollDie(const Event_RollDie &event) @@ -2440,6 +2440,16 @@ void Player::cardMenuAction() cmd->set_target_zone("deck"); cmd->set_x(-1); cmd->set_y(0); + + if (idList.card_size() > 1) { + auto *scmd = new Command_Shuffle; + scmd->set_zone_name("deck"); + scmd->set_start(-idList.card_size()); + scmd->set_end(-1); + // Server process events backwards, so... + commandList.append(scmd); + } + commandList.append(cmd); break; } diff --git a/cockatrice/src/player.h b/cockatrice/src/player.h index 58ee8c2f..b88338b1 100644 --- a/cockatrice/src/player.h +++ b/cockatrice/src/player.h @@ -103,7 +103,7 @@ signals: void newCardAdded(AbstractCardItem *card); // Log events void logSay(Player *player, QString message); - void logShuffle(Player *player, CardZone *zone); + void logShuffle(Player *player, CardZone *zone, int start, int end); void logRollDie(Player *player, int sides, int roll); void logCreateArrow(Player *player, Player *startPlayer, diff --git a/common/pb/command_shuffle.proto b/common/pb/command_shuffle.proto index e2e1d5ec..507195a4 100644 --- a/common/pb/command_shuffle.proto +++ b/common/pb/command_shuffle.proto @@ -4,5 +4,8 @@ message Command_Shuffle { extend GameCommand { optional Command_Shuffle ext = 1003; } + optional string zone_name = 1; + optional sint32 start = 2 [default = 0]; + optional sint32 end = 3 [default = -1]; } diff --git a/common/pb/event_shuffle.proto b/common/pb/event_shuffle.proto index c1fc1afb..8285a1d8 100644 --- a/common/pb/event_shuffle.proto +++ b/common/pb/event_shuffle.proto @@ -6,4 +6,6 @@ message Event_Shuffle { optional Event_Shuffle ext = 2007; } optional string zone_name = 1; + optional sint32 start = 2 [default = 0]; + optional sint32 end = 3 [default = -1]; } diff --git a/common/server_cardzone.cpp b/common/server_cardzone.cpp index fbf0cf2f..4048fbef 100644 --- a/common/server_cardzone.cpp +++ b/common/server_cardzone.cpp @@ -40,13 +40,25 @@ Server_CardZone::~Server_CardZone() clear(); } -void Server_CardZone::shuffle() +void Server_CardZone::shuffle(int start, int end) { // Size 0 or 1 decks are sorted if (cards.size() < 2) return; - for (int i = cards.size() - 1; i > 0; i--) { - int j = rng->rand(0, i); + + // Negative numbers signify positions starting at the end of the + // zone convert these to actual indexes. + if (end < 0) + end += cards.size(); + + if (start < 0) + start += cards.size(); + + if (start < 0 || end < 0 || start >= cards.size() || end >= cards.size()) + return; + + for (int i = end; i > start; i--) { + int j = rng->rand(start, i); cards.swap(j, i); } playersWithWritePermission.clear(); @@ -108,7 +120,7 @@ int Server_CardZone::removeCard(Server_Card *card) cards.removeAt(index); if (has_coords) removeCardFromCoordMap(card, card->getX(), card->getY()); - card->setZone(0); + card->setZone(nullptr); return index; } @@ -123,21 +135,21 @@ Server_Card *Server_CardZone::getCard(int id, int *position, bool remove) *position = i; if (remove) { cards.removeAt(i); - tmp->setZone(0); + tmp->setZone(nullptr); } return tmp; } } - return NULL; + return nullptr; } else { if ((id >= cards.size()) || (id < 0)) - return NULL; + return nullptr; Server_Card *tmp = cards[id]; if (position) *position = id; if (remove) { cards.removeAt(id); - tmp->setZone(0); + tmp->setZone(nullptr); } return tmp; } @@ -203,7 +215,7 @@ bool Server_CardZone::isColumnEmpty(int x, int y) const void Server_CardZone::moveCardInRow(GameEventStorage &ges, Server_Card *card, int x, int y) { - CardToMove *cardToMove = new CardToMove; + auto *cardToMove = new CardToMove; cardToMove->set_card_id(card->getId()); player->moveCard(ges, this, QList() << cardToMove, this, x, y, false, false); delete cardToMove; @@ -215,8 +227,8 @@ void Server_CardZone::fixFreeSpaces(GameEventStorage &ges) return; QSet> placesToLook; - for (int i = 0; i < cards.size(); ++i) - placesToLook.insert(QPair((cards[i]->getX() / 3) * 3, cards[i]->getY())); + for (auto &card : cards) + placesToLook.insert(QPair((card->getX() / 3) * 3, card->getY())); QSetIterator> placeIterator(placesToLook); while (placeIterator.hasNext()) { @@ -266,8 +278,8 @@ void Server_CardZone::insertCard(Server_Card *card, int x, int y) void Server_CardZone::clear() { - for (int i = 0; i < cards.size(); i++) - delete cards.at(i); + for (auto card : cards) + delete card; cards.clear(); coordinateMap.clear(); freePilesMap.clear(); diff --git a/common/server_cardzone.h b/common/server_cardzone.h index a2061540..4fc8f066 100644 --- a/common/server_cardzone.h +++ b/common/server_cardzone.h @@ -57,7 +57,7 @@ public: return cards; } int removeCard(Server_Card *card); - Server_Card *getCard(int id, int *position = NULL, bool remove = false); + Server_Card *getCard(int id, int *position = nullptr, bool remove = false); int getCardsBeingLookedAt() const { @@ -92,7 +92,7 @@ public: void moveCardInRow(GameEventStorage &ges, Server_Card *card, int x, int y); void insertCard(Server_Card *card, int x, int y); void updateCardCoordinates(Server_Card *card, int oldX, int oldY); - void shuffle(); + void shuffle(int start = 0, int end = -1); void clear(); void addWritePermission(int playerId); const QSet &getPlayersWithWritePermission() const diff --git a/common/server_player.cpp b/common/server_player.cpp index 6f1e332a..9fd8b291 100644 --- a/common/server_player.cpp +++ b/common/server_player.cpp @@ -88,15 +88,13 @@ Server_Player::Server_Player(Server_Game *_game, const ServerInfo_User &_userInfo, bool _spectator, Server_AbstractUserInterface *_userInterface) - : ServerInfo_User_Container(_userInfo), game(_game), userInterface(_userInterface), deck(0), pingTime(0), + : ServerInfo_User_Container(_userInfo), game(_game), userInterface(_userInterface), deck(nullptr), pingTime(0), playerId(_playerId), spectator(_spectator), initialCards(0), nextCardId(0), readyStart(false), conceded(false), sideboardLocked(true) { } -Server_Player::~Server_Player() -{ -} +Server_Player::~Server_Player() = default; void Server_Player::prepareDestroy() { @@ -170,11 +168,11 @@ void Server_Player::setupZones() // ------------------------------------------------------------------ - // Assign card ids and create deck from decklist + // Assign card ids and create deck from deck list InnerDecklistNode *listRoot = deck->getRoot(); nextCardId = 0; for (int i = 0; i < listRoot->size(); ++i) { - InnerDecklistNode *currentZone = dynamic_cast(listRoot->at(i)); + auto *currentZone = dynamic_cast(listRoot->at(i)); Server_CardZone *z; if (currentZone->getName() == DECK_ZONE_MAIN) z = deckZone; @@ -184,7 +182,7 @@ void Server_Player::setupZones() continue; for (int j = 0; j < currentZone->size(); ++j) { - DecklistCardNode *currentCard = dynamic_cast(currentZone->at(j)); + auto *currentCard = dynamic_cast(currentZone->at(j)); if (!currentCard) continue; for (int k = 0; k < currentCard->getNumber(); ++k) @@ -193,8 +191,7 @@ void Server_Player::setupZones() } const QList &sideboardPlan = deck->getCurrentSideboardPlan(); - for (int i = 0; i < sideboardPlan.size(); ++i) { - const MoveCard_ToZone &m = sideboardPlan[i]; + for (const auto &m : sideboardPlan) { const QString startZone = QString::fromStdString(m.start_zone()); const QString targetZone = QString::fromStdString(m.target_zone()); @@ -214,7 +211,7 @@ void Server_Player::setupZones() for (int j = 0; j < start->getCards().size(); ++j) if (start->getCards()[j]->getName() == QString::fromStdString(m.card_name())) { - Server_Card *card = start->getCard(j, NULL, true); + Server_Card *card = start->getCard(j, nullptr, true); target->insertCard(card, -1, 0); break; } @@ -296,7 +293,7 @@ Response::ResponseCode Server_Player::drawCards(GameEventStorage &ges, int numbe Event_DrawCards eventPrivate(eventOthers); for (int i = 0; i < number; ++i) { - Server_Card *card = deckZone->getCard(0, NULL, true); + Server_Card *card = deckZone->getCard(0, nullptr, true); handZone->insertCard(card, -1, 0); lastDrawList.append(card->getId()); @@ -365,15 +362,15 @@ Response::ResponseCode Server_Player::moveCard(GameEventStorage &ges, QList> cardsToMove; QMap cardProperties; QSet cardIdsToMove; - for (int i = 0; i < _cards.size(); ++i) { + for (auto _card : _cards) { // The same card being moved twice would lead to undefined behaviour. - if (cardIdsToMove.contains(_cards[i]->card_id())) + if (cardIdsToMove.contains(_card->card_id())) continue; - cardIdsToMove.insert(_cards[i]->card_id()); + cardIdsToMove.insert(_card->card_id()); // Consistency checks. In case the command contains illegal moves, try to resolve the legal ones still. int position; - Server_Card *card = startzone->getCard(_cards[i]->card_id(), &position); + Server_Card *card = startzone->getCard(_card->card_id(), &position); if (!card) return Response::RespNameNotFound; if (card->getParentCard()) @@ -381,7 +378,7 @@ Response::ResponseCode Server_Player::moveCard(GameEventStorage &ges, if (!card->getAttachedCards().isEmpty() && !targetzone->isColumnEmpty(x, y)) continue; cardsToMove.append(QPair(card, position)); - cardProperties.insert(card, _cards[i]); + cardProperties.insert(card, _card); } // In case all moves were filtered out, abort. if (cardsToMove.isEmpty()) @@ -427,34 +424,34 @@ Response::ResponseCode Server_Player::moveCard(GameEventStorage &ges, if (startzone->getName() != targetzone->getName()) { // Delete all attachment relationships if (card->getParentCard()) - card->setParentCard(0); + card->setParentCard(nullptr); // Make a copy of the list because the original one gets modified during the loop QList attachedCards = card->getAttachedCards(); - for (int i = 0; i < attachedCards.size(); ++i) - attachedCards[i]->getZone()->getPlayer()->unattachCard(ges, attachedCards[i]); + for (auto &attachedCard : attachedCards) + attachedCard->getZone()->getPlayer()->unattachCard(ges, attachedCard); } if (startzone != targetzone) { // Delete all arrows from and to the card const QList &players = game->getPlayers().values(); - for (int i = 0; i < players.size(); ++i) { + for (auto player : players) { QList arrowsToDelete; - QMapIterator arrowIterator(players[i]->getArrows()); + QMapIterator arrowIterator(player->getArrows()); while (arrowIterator.hasNext()) { Server_Arrow *arrow = arrowIterator.next().value(); if ((arrow->getStartCard() == card) || (arrow->getTargetItem() == card)) arrowsToDelete.append(arrow->getId()); } - for (int j = 0; j < arrowsToDelete.size(); ++j) - players[i]->deleteArrow(arrowsToDelete[j]); + for (int j : arrowsToDelete) + player->deleteArrow(j); } } if (card->getDestroyOnZoneChange() && (startzone->getName() != targetzone->getName())) { Event_DestroyCard event; event.set_zone_name(startzone->getName().toStdString()); - event.set_card_id(card->getId()); + event.set_card_id(static_cast(card->getId())); ges.enqueueGameEvent(event, playerId); card->deleteLater(); @@ -586,14 +583,14 @@ void Server_Player::unattachCard(GameEventStorage &ges, Server_Card *card) { Server_CardZone *zone = card->getZone(); Server_Card *parentCard = card->getParentCard(); - card->setParentCard(0); + card->setParentCard(nullptr); Event_AttachCard event; event.set_start_zone(zone->getName().toStdString()); event.set_card_id(card->getId()); ges.enqueueGameEvent(event, playerId); - CardToMove *cardToMove = new CardToMove; + auto *cardToMove = new CardToMove; cardToMove->set_card_id(card->getId()); moveCard(ges, zone, QList() << cardToMove, zone, -1, card->getY(), card->getFaceDown()); delete cardToMove; @@ -696,7 +693,7 @@ Server_Player::cmdDeckSelect(const Command_DeckSelect &cmd, ResponseContainer &r context.set_sideboard_size(deck->getSideboardSize()); ges.setGameEventContext(context); - Response_DeckDownload *re = new Response_DeckDownload; + auto *re = new Response_DeckDownload; re->set_deck(deck->writeToString_Native().toStdString()); rc.setResponseExtension(re); @@ -844,28 +841,37 @@ Server_Player::cmdGameSay(const Command_GameSay &cmd, ResponseContainer & /*rc*/ } Response::ResponseCode -Server_Player::cmdShuffle(const Command_Shuffle & /*cmd*/, ResponseContainer & /*rc*/, GameEventStorage &ges) +Server_Player::cmdShuffle(const Command_Shuffle &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { if (spectator) return Response::RespFunctionNotAllowed; if (!game->getGameStarted()) return Response::RespGameNotStarted; + if (conceded) return Response::RespContextError; - Server_CardZone *deckZone = zones.value("deck"); - deckZone->shuffle(); + if (cmd.zone_name() != "deck") + return Response::RespFunctionNotAllowed; + + Server_CardZone *zone = zones.value("deck"); + if (!zone) + return Response::RespNameNotFound; + + zone->shuffle(cmd.start(), cmd.end()); Event_Shuffle event; - event.set_zone_name("deck"); + event.set_zone_name(zone->getName().toStdString()); + event.set_start(cmd.start()); + event.set_end(cmd.end()); ges.enqueueGameEvent(event, playerId); - if (deckZone->getAlwaysRevealTopCard() && !deckZone->getCards().isEmpty()) { + if (zone->getAlwaysRevealTopCard() && !zone->getCards().isEmpty()) { Event_RevealCards revealEvent; - revealEvent.set_zone_name(deckZone->getName().toStdString()); + revealEvent.set_zone_name(zone->getName().toStdString()); revealEvent.set_card_id(0); - deckZone->getCards().first()->getInfo(revealEvent.add_cards()); + zone->getCards().first()->getInfo(revealEvent.add_cards()); ges.enqueueGameEvent(revealEvent, playerId); } @@ -889,7 +895,7 @@ Server_Player::cmdMulligan(const Command_Mulligan & /*cmd*/, ResponseContainer & Server_CardZone *deck = zones.value("deck"); while (!hand->getCards().isEmpty()) { - CardToMove *cardToMove = new CardToMove; + auto *cardToMove = new CardToMove; cardToMove->set_card_id(hand->getCards().first()->getId()); moveCard(ges, hand, QList() << cardToMove, deck, 0, 0, false); delete cardToMove; @@ -904,7 +910,7 @@ Server_Player::cmdMulligan(const Command_Mulligan & /*cmd*/, ResponseContainer & number = -1; Context_Mulligan context; - context.set_number(number); + context.set_number(static_cast(number)); ges.setGameEventContext(context); return Response::RespOk; @@ -955,7 +961,7 @@ Server_Player::cmdUndoDraw(const Command_UndoDraw & /*cmd*/, ResponseContainer & return Response::RespContextError; Response::ResponseCode retVal; - CardToMove *cardToMove = new CardToMove; + auto *cardToMove = new CardToMove; cardToMove->set_card_id(lastDrawList.takeLast()); retVal = moveCard(ges, zones.value("hand"), QList() << cardToMove, zones.value("deck"), 0, 0, false, true); @@ -1063,9 +1069,9 @@ Server_Player::cmdAttachCard(const Command_AttachCard &cmd, ResponseContainer & if (!card) return Response::RespNameNotFound; - Server_Player *targetPlayer = 0; - Server_CardZone *targetzone = 0; - Server_Card *targetCard = 0; + Server_Player *targetPlayer = nullptr; + Server_CardZone *targetzone = nullptr; + Server_Card *targetCard = nullptr; if (cmd.has_target_player_id()) { targetPlayer = game->getPlayers().value(cmd.target_player_id()); @@ -1097,17 +1103,16 @@ Server_Player::cmdAttachCard(const Command_AttachCard &cmd, ResponseContainer & Server_Player *p = playerIterator.next().value(); QList arrows = p->getArrows().values(); QList toDelete; - for (int i = 0; i < arrows.size(); ++i) { - Server_Arrow *a = arrows[i]; - Server_Card *tCard = qobject_cast(a->getTargetItem()); + for (auto a : arrows) { + auto *tCard = qobject_cast(a->getTargetItem()); if ((tCard == card) || (a->getStartCard() == card)) toDelete.append(a); } - for (int i = 0; i < toDelete.size(); ++i) { + for (auto &i : toDelete) { Event_DeleteArrow event; - event.set_arrow_id(toDelete[i]->getId()); + event.set_arrow_id(i->getId()); ges.enqueueGameEvent(event, p->getPlayerId()); - p->deleteArrow(toDelete[i]->getId()); + p->deleteArrow(i->getId()); } } @@ -1115,8 +1120,8 @@ Server_Player::cmdAttachCard(const Command_AttachCard &cmd, ResponseContainer & // Unattach all cards attached to the card being attached. // Make a copy of the list because its contents change during the loop otherwise. QList attachedList = card->getAttachedCards(); - for (int i = 0; i < attachedList.size(); ++i) - attachedList[i]->getZone()->getPlayer()->unattachCard(ges, attachedList[i]); + for (auto &i : attachedList) + i->getZone()->getPlayer()->unattachCard(ges, i); card->setParentCard(targetCard); const int oldX = card->getX(); @@ -1124,7 +1129,7 @@ Server_Player::cmdAttachCard(const Command_AttachCard &cmd, ResponseContainer & startzone->updateCardCoordinates(card, oldX, card->getY()); if (targetzone->isColumnStacked(targetCard->getX(), targetCard->getY())) { - CardToMove *cardToMove = new CardToMove; + auto *cardToMove = new CardToMove; cardToMove->set_card_id(targetCard->getId()); targetPlayer->moveCard(ges, targetzone, QList() << cardToMove, targetzone, targetzone->getFreeGridColumn(-2, targetCard->getY(), targetCard->getName(), false), @@ -1193,7 +1198,7 @@ Server_Player::cmdCreateToken(const Command_CreateToken &cmd, ResponseContainer event.set_y(y); ges.enqueueGameEvent(event, playerId); - // chck if the token is a replacement for an existing card + // check if the token is a replacement for an existing card if (cmd.target_card_id() < 0) return Response::RespOk; @@ -1226,7 +1231,7 @@ Server_Player::cmdCreateArrow(const Command_CreateArrow &cmd, ResponseContainer QString startZoneName = QString::fromStdString(cmd.start_zone()); Server_CardZone *startZone = startPlayer->getZones().value(startZoneName); bool playerTarget = !cmd.has_target_zone(); - Server_CardZone *targetZone = 0; + Server_CardZone *targetZone = nullptr; if (!playerTarget) targetZone = targetPlayer->getZones().value(QString::fromStdString(cmd.target_zone())); if (!startZone || (!targetZone && !playerTarget)) @@ -1236,7 +1241,7 @@ Server_Player::cmdCreateArrow(const Command_CreateArrow &cmd, ResponseContainer Server_Card *startCard = startZone->getCard(cmd.start_card_id()); if (!startCard) return Response::RespNameNotFound; - Server_Card *targetCard = 0; + Server_Card *targetCard = nullptr; if (!playerTarget) { if (targetZone->getType() != ServerInfo_Zone::PublicZone) return Response::RespContextError; @@ -1258,7 +1263,7 @@ Server_Player::cmdCreateArrow(const Command_CreateArrow &cmd, ResponseContainer return Response::RespContextError; } - Server_Arrow *arrow = new Server_Arrow(newArrowId(), startCard, targetItem, cmd.arrow_color()); + auto arrow = new Server_Arrow(newArrowId(), startCard, targetItem, cmd.arrow_color()); addArrow(arrow); Event_CreateArrow event; @@ -1535,7 +1540,7 @@ Server_Player::cmdDumpZone(const Command_DumpZone &cmd, ResponseContainer &rc, G int numberCards = cmd.number_cards(); const QList &cards = zone->getCards(); - Response_DumpZone *re = new Response_DumpZone; + auto *re = new Response_DumpZone; ServerInfo_Zone *zoneInfo = re->mutable_zone_info(); zoneInfo->set_name(zone->getName().toStdString()); zoneInfo->set_type(zone->getType()); @@ -1668,8 +1673,7 @@ Server_Player::cmdRevealCards(const Command_RevealCards &cmd, ResponseContainer Event_RevealCards eventPrivate(eventOthers); - for (int i = 0; i < cardsToReveal.size(); ++i) { - Server_Card *card = cardsToReveal[i]; + for (auto card : cardsToReveal) { ServerInfo_Card *cardInfo = eventPrivate.add_cards(); cardInfo->set_id(card->getId()); @@ -1709,8 +1713,8 @@ Server_Player::cmdRevealCards(const Command_RevealCards &cmd, ResponseContainer } else { if (cmd.grant_write_access()) { const QList &playerIds = game->getPlayers().keys(); - for (int i = 0; i < playerIds.size(); ++i) - zone->addWritePermission(playerIds[i]); + for (int playerId : playerIds) + zone->addWritePermission(playerId); } ges.enqueueGameEvent(eventPrivate, playerId); @@ -1890,7 +1894,7 @@ void Server_Player::disconnectClient() if (!(userInfo->user_level() & ServerInfo_User::IsRegistered) || spectator) game->removePlayer(this, Event_Leave::USER_DISCONNECTED); else - setUserInterface(0); + setUserInterface(nullptr); } void Server_Player::getInfo(ServerInfo_Player *info, diff --git a/common/server_player.h b/common/server_player.h index e8caa26f..9ff4ebde 100644 --- a/common/server_player.h +++ b/common/server_player.h @@ -90,7 +90,7 @@ public: const ServerInfo_User &_userInfo, bool _spectator, Server_AbstractUserInterface *_handler); - ~Server_Player(); + ~Server_Player() override; void prepareDestroy(); Server_AbstractUserInterface *getUserInterface() const { @@ -99,10 +99,6 @@ public: void setUserInterface(Server_AbstractUserInterface *_userInterface); void disconnectClient(); - void setPlayerId(int _id) - { - playerId = _id; - } bool getReadyStart() const { return readyStart; @@ -127,10 +123,7 @@ public: { conceded = _conceded; } - DeckList *getDeck() const - { - return deck; - } + Server_Game *getGame() const { return game;