diff --git a/cockatrice/src/client/tabs/tab_deck_editor.cpp b/cockatrice/src/client/tabs/tab_deck_editor.cpp index 79f82ebc2..0c9edbb0b 100644 --- a/cockatrice/src/client/tabs/tab_deck_editor.cpp +++ b/cockatrice/src/client/tabs/tab_deck_editor.cpp @@ -724,8 +724,10 @@ void TabDeckEditor::updateCardInfoRight(const QModelIndex ¤t, const QModel { if (!current.isValid()) return; - if (!current.model()->hasChildren(current.sibling(current.row(), 0))) - cardInfo->setCard(current.sibling(current.row(), 1).data().toString()); + if (!current.model()->hasChildren(current.sibling(current.row(), 0))) { + cardInfo->setCard(current.sibling(current.row(), 1).data().toString(), + current.sibling(current.row(), 4).data().toString()); + } } void TabDeckEditor::updateSearch(const QString &search) @@ -1014,7 +1016,7 @@ void TabDeckEditor::addCardHelper(QString zoneName) if (info->getIsToken()) zoneName = DECK_ZONE_TOKENS; - QModelIndex newCardIndex = deckModel->addCard(info->getName(), zoneName); + QModelIndex newCardIndex = deckModel->addPreferredPrintingCard(info->getName(), zoneName, false); recursiveExpand(newCardIndex); deckView->setCurrentIndex(newCardIndex); setModified(true); @@ -1027,6 +1029,7 @@ void TabDeckEditor::actSwapCard() if (!currentIndex.isValid()) return; const QString cardName = currentIndex.sibling(currentIndex.row(), 1).data().toString(); + const QString cardProviderID = currentIndex.sibling(currentIndex.row(), 2).data().toString(); const QModelIndex gparent = currentIndex.parent().parent(); if (!gparent.isValid()) @@ -1036,8 +1039,10 @@ void TabDeckEditor::actSwapCard() actDecrement(); const QString otherZoneName = zoneName == DECK_ZONE_MAIN ? DECK_ZONE_SIDE : DECK_ZONE_MAIN; - // Third argument (true) says create the card no mater what, even if not in DB - QModelIndex newCardIndex = deckModel->addCard(cardName, otherZoneName, true); + // Third argument (true) says create the card no matter what, even if not in DB + QModelIndex newCardIndex = deckModel->addCard( + cardName, CardDatabaseManager::getInstance()->getSpecificSetForCard(cardName, cardProviderID), otherZoneName, + true); recursiveExpand(newCardIndex); setModified(true); diff --git a/cockatrice/src/client/tabs/tab_game.cpp b/cockatrice/src/client/tabs/tab_game.cpp index f27384274..68c60ff15 100644 --- a/cockatrice/src/client/tabs/tab_game.cpp +++ b/cockatrice/src/client/tabs/tab_game.cpp @@ -326,6 +326,7 @@ void DeckViewContainer::deckSelectFinished(const Response &r) { const Response_DeckDownload &resp = r.GetExtension(Response_DeckDownload::ext); DeckLoader newDeck(QString::fromStdString(resp.deck())); + // TODO CHANGE THIS TO BE SELECTED BY UUID PictureLoader::cacheCardPixmaps(CardDatabaseManager::getInstance()->getCards(newDeck.getCardList())); setDeck(newDeck); } diff --git a/cockatrice/src/client/ui/picture_loader.cpp b/cockatrice/src/client/ui/picture_loader.cpp index e30e5fc58..ad18a9071 100644 --- a/cockatrice/src/client/ui/picture_loader.cpp +++ b/cockatrice/src/client/ui/picture_loader.cpp @@ -45,10 +45,11 @@ PictureToLoad::PictureToLoad(CardInfoPtr _card) std::sort(sortedSets.begin(), sortedSets.end(), SetDownloadPriorityComparator()); // If the pixmapCacheKey corresponds to a specific set, we have to try to load it first. for (const auto &set : card->getSets()) { - if (QLatin1String("card_") + QString(set.getProperty("uuid")) == card->getPixmapCacheKey()) { + if (QLatin1String("card_") + card->getName() + QString("_") + QString(set.getProperty("uuid")) == + card->getPixmapCacheKey()) { long long setIndex = sortedSets.indexOf(set.getPtr()); - CardSetPtr setForCardUUID = sortedSets.takeAt(setIndex); - sortedSets.prepend(setForCardUUID); + CardSetPtr setForCardProviderID = sortedSets.takeAt(setIndex); + sortedSets.prepend(setForCardProviderID); } } // The first time called, nextSet will also populate the Urls for the first set. @@ -178,7 +179,7 @@ void PictureLoaderWorker::processLoadQueue() qDebug().nospace() << "PictureLoader: [card: " << cardName << " set: " << setName << "]: Trying to load picture"; - if (CardDatabaseManager::getInstance()->isUuidForPreferredPrinting( + if (CardDatabaseManager::getInstance()->isProviderIdForPreferredPrinting( cardName, cardBeingLoaded.getCard()->getPixmapCacheKey())) { if (cardImageExistsOnDisk(setName, correctedCardName)) { continue; diff --git a/cockatrice/src/client/ui/widgets/cards/card_info_frame_widget.cpp b/cockatrice/src/client/ui/widgets/cards/card_info_frame_widget.cpp index 620543db0..fd9c84750 100644 --- a/cockatrice/src/client/ui/widgets/cards/card_info_frame_widget.cpp +++ b/cockatrice/src/client/ui/widgets/cards/card_info_frame_widget.cpp @@ -111,6 +111,11 @@ void CardInfoFrameWidget::setCard(const QString &cardName) setCard(CardDatabaseManager::getInstance()->guessCard(cardName)); } +void CardInfoFrameWidget::setCard(const QString &cardName, const QString &providerId) +{ + setCard(CardDatabaseManager::getInstance()->getCardByNameAndProviderId(cardName, providerId)); +} + void CardInfoFrameWidget::setCard(AbstractCardItem *card) { if (card) { diff --git a/cockatrice/src/client/ui/widgets/cards/card_info_frame_widget.h b/cockatrice/src/client/ui/widgets/cards/card_info_frame_widget.h index 2c2c4a3c8..a9a4a0597 100644 --- a/cockatrice/src/client/ui/widgets/cards/card_info_frame_widget.h +++ b/cockatrice/src/client/ui/widgets/cards/card_info_frame_widget.h @@ -36,6 +36,7 @@ public: public slots: void setCard(CardInfoPtr card); void setCard(const QString &cardName); + void setCard(const QString &cardName, const QString &providerId); void setCard(AbstractCardItem *card); void clearCard(); void setViewMode(int mode); diff --git a/cockatrice/src/deck/deck_list_model.cpp b/cockatrice/src/deck/deck_list_model.cpp index f2ef81307..a33e72c7e 100644 --- a/cockatrice/src/deck/deck_list_model.cpp +++ b/cockatrice/src/deck/deck_list_model.cpp @@ -79,24 +79,24 @@ int DeckListModel::rowCount(const QModelIndex &parent) const int DeckListModel::columnCount(const QModelIndex & /*parent*/) const { - return 2; + return 5; } QVariant DeckListModel::data(const QModelIndex &index, int role) const { // debugIndexInfo("data", index); if (!index.isValid()) { - return QVariant(); + return {}; } if (index.column() >= columnCount()) { - return QVariant(); + return {}; } auto *temp = static_cast(index.internalPointer()); auto *card = dynamic_cast(temp); if (card == nullptr) { - auto *node = dynamic_cast(temp); + const auto *node = dynamic_cast(temp); switch (role) { case Qt::FontRole: { QFont f; @@ -108,13 +108,22 @@ QVariant DeckListModel::data(const QModelIndex &index, int role) const switch (index.column()) { case 0: return node->recursiveCount(true); - case 1: + case 1: { if (role == Qt::DisplayRole) return node->getVisibleName(); - else - return node->getName(); + return node->getName(); + } + case 2: { + return node->getCardSetShortName(); + } + case 3: { + return node->getCardCollectorNumber(); + } + case 4: { + return node->getCardProviderId(); + } default: - return QVariant(); + return {}; } } case Qt::BackgroundRole: { @@ -125,7 +134,7 @@ QVariant DeckListModel::data(const QModelIndex &index, int role) const return QBrush(QColor(0, 0, 0)); } default: - return QVariant(); + return {}; } } else { switch (role) { @@ -136,8 +145,14 @@ QVariant DeckListModel::data(const QModelIndex &index, int role) const return card->getNumber(); case 1: return card->getName(); + case 2: + return card->getCardSetShortName(); + case 3: + return card->getCardCollectorNumber(); + case 4: + return card->getCardProviderId(); default: - return QVariant(); + return {}; } } case Qt::BackgroundRole: { @@ -148,28 +163,34 @@ QVariant DeckListModel::data(const QModelIndex &index, int role) const return QBrush(QColor(0, 0, 0)); } default: - return QVariant(); + return {}; } } } -QVariant DeckListModel::headerData(int section, Qt::Orientation orientation, int role) const +QVariant DeckListModel::headerData(const int section, const Qt::Orientation orientation, const int role) const { if ((role != Qt::DisplayRole) || (orientation != Qt::Horizontal)) { - return QVariant(); + return {}; } if (section >= columnCount()) { - return QVariant(); + return {}; } switch (section) { case 0: - return tr("Number"); + return tr("Count"); case 1: return tr("Card"); + case 2: + return tr("Set"); + case 3: + return tr("Number"); + case 4: + return tr("Provider ID"); default: - return QVariant(); + return {}; } } @@ -215,7 +236,7 @@ void DeckListModel::emitRecursiveUpdates(const QModelIndex &index) emitRecursiveUpdates(index.parent()); } -bool DeckListModel::setData(const QModelIndex &index, const QVariant &value, int role) +bool DeckListModel::setData(const QModelIndex &index, const QVariant &value, const int role) { auto *node = getNode(index); if (!node || (role != Qt::EditRole)) { @@ -229,6 +250,15 @@ bool DeckListModel::setData(const QModelIndex &index, const QVariant &value, int case 1: node->setName(value.toString()); break; + case 2: + node->setCardSetShortName(value.toString()); + break; + case 3: + node->setCardCollectorNumber(value.toString()); + break; + case 4: + node->setCardProviderId(value.toString()); + break; default: return false; } @@ -279,7 +309,8 @@ InnerDecklistNode *DeckListModel::createNodeIfNeeded(const QString &name, InnerD return newNode; } -DecklistModelCardNode *DeckListModel::findCardNode(const QString &cardName, const QString &zoneName) const +DecklistModelCardNode * +DeckListModel::findCardNode(const QString &cardName, const QString &zoneName, const QString &providerId) const { InnerDecklistNode *zoneNode, *typeNode; CardInfoPtr info; @@ -301,14 +332,17 @@ DecklistModelCardNode *DeckListModel::findCardNode(const QString &cardName, cons return nullptr; } - return dynamic_cast(typeNode->findChild(cardName)); + if (providerId.isEmpty()) { + return dynamic_cast(typeNode->findChild(cardName)); + } + return dynamic_cast(typeNode->findCardChildByNameAndProviderId(cardName, providerId)); } -QModelIndex DeckListModel::findCard(const QString &cardName, const QString &zoneName) const +QModelIndex DeckListModel::findCard(const QString &cardName, const QString &zoneName, const QString &providerId) const { DecklistModelCardNode *cardNode; - cardNode = findCardNode(cardName, zoneName); + cardNode = findCardNode(cardName, zoneName, providerId); if (!cardNode) { return {}; } @@ -316,16 +350,27 @@ QModelIndex DeckListModel::findCard(const QString &cardName, const QString &zone return nodeToIndex(cardNode); } -QModelIndex DeckListModel::addCard(const QString &cardName, const QString &zoneName, bool abAddAnyway) +QModelIndex DeckListModel::addPreferredPrintingCard(const QString &cardName, const QString &zoneName, bool abAddAnyway) { - CardInfoPtr info = CardDatabaseManager::getInstance()->getCard(cardName); - if (info == nullptr) { + return addCard(cardName, CardDatabaseManager::getInstance()->getPreferredSetForCard(cardName), zoneName, + abAddAnyway); +} + +QModelIndex DeckListModel::addCard(const QString &cardName, + const CardInfoPerSet cardInfoSet, + const QString &zoneName, + bool abAddAnyway) +{ + CardInfoPtr cardInfo = + CardDatabaseManager::getInstance()->getCardByNameAndProviderId(cardName, cardInfoSet.getProperty("uuid")); + + if (cardInfo == nullptr) { if (abAddAnyway) { // We need to keep this card added no matter what // This is usually called from tab_deck_editor // So we'll create a new CardInfo with the name // and default values for all fields - info = CardInfo::newInstance(cardName); + cardInfo = CardInfo::newInstance(cardName); } else { return {}; } @@ -333,18 +378,24 @@ QModelIndex DeckListModel::addCard(const QString &cardName, const QString &zoneN InnerDecklistNode *zoneNode = createNodeIfNeeded(zoneName, root); - QString cardType = info->getMainCardType(); + const QString cardType = cardInfo->getMainCardType(); InnerDecklistNode *cardTypeNode = createNodeIfNeeded(cardType, zoneNode); - QModelIndex parentIndex = nodeToIndex(cardTypeNode); - auto *cardNode = dynamic_cast(cardTypeNode->findChild(cardName)); + const QModelIndex parentIndex = nodeToIndex(cardTypeNode); + auto *cardNode = dynamic_cast( + cardTypeNode->findCardChildByNameAndProviderId(cardName, cardInfoSet.getProperty("uuid"))); if (!cardNode) { - DecklistCardNode *decklistCard = deckList->addCard(cardName, zoneName); - beginInsertRows(parentIndex, cardTypeNode->size(), cardTypeNode->size()); + auto *decklistCard = + deckList->addCard(cardInfo->getName(), zoneName, cardInfoSet.getPtr()->getCorrectedShortName(), + cardInfoSet.getProperty("num"), cardInfoSet.getProperty("uuid")); + beginInsertRows(parentIndex, static_cast(cardTypeNode->size()), static_cast(cardTypeNode->size())); cardNode = new DecklistModelCardNode(decklistCard, cardTypeNode); endInsertRows(); } else { cardNode->setNumber(cardNode->getNumber() + 1); + cardNode->setCardSetShortName(cardInfoSet.getPtr()->getCorrectedShortName()); + cardNode->setCardCollectorNumber(cardInfoSet.getProperty("num")); + cardNode->setCardProviderId(cardInfoSet.getProperty("uuid")); deckList->updateDeckHash(); } sort(lastKnownColumn, lastKnownOrder); diff --git a/cockatrice/src/deck/deck_list_model.h b/cockatrice/src/deck/deck_list_model.h index 01cf61780..24eaea612 100644 --- a/cockatrice/src/deck/deck_list_model.h +++ b/cockatrice/src/deck/deck_list_model.h @@ -1,6 +1,7 @@ #ifndef DECKLISTMODEL_H #define DECKLISTMODEL_H +#include "../game/cards/card_database.h" #include "decklist.h" #include @@ -37,6 +38,30 @@ public: { dataNode->setName(_name); } + QString getCardProviderId() const override + { + return dataNode->getCardProviderId(); + } + void setCardProviderId(const QString &_cardProviderId) override + { + dataNode->setCardProviderId(_cardProviderId); + } + QString getCardSetShortName() const override + { + return dataNode->getCardSetShortName(); + } + void setCardSetShortName(const QString &_cardSetShortName) override + { + dataNode->setCardSetShortName(_cardSetShortName); + } + QString getCardCollectorNumber() const override + { + return dataNode->getCardCollectorNumber(); + } + void setCardCollectorNumber(const QString &_cardSetNumber) override + { + dataNode->setCardCollectorNumber(_cardSetNumber); + } DecklistCardNode *getDataNode() const { return dataNode; @@ -65,8 +90,10 @@ public: Qt::ItemFlags flags(const QModelIndex &index) const override; bool setData(const QModelIndex &index, const QVariant &value, int role) override; bool removeRows(int row, int count, const QModelIndex &parent) override; - QModelIndex findCard(const QString &cardName, const QString &zoneName) const; - QModelIndex addCard(const QString &cardName, const QString &zoneName, bool abAddAnyway = false); + QModelIndex findCard(const QString &cardName, const QString &zoneName, const QString &providerId = "") const; + QModelIndex addPreferredPrintingCard(const QString &cardName, const QString &zoneName, bool abAddAnyway); + QModelIndex + addCard(const ::QString &cardName, CardInfoPerSet cardInfoSet, const QString &zoneName, bool abAddAnyway = false); void sort(int column, Qt::SortOrder order) override; void cleanList(); DeckLoader *getDeckList() const @@ -82,7 +109,8 @@ private: Qt::SortOrder lastKnownOrder; InnerDecklistNode *createNodeIfNeeded(const QString &name, InnerDecklistNode *parent); QModelIndex nodeToIndex(AbstractDecklistNode *node) const; - DecklistModelCardNode *findCardNode(const QString &cardName, const QString &zoneName) const; + DecklistModelCardNode * + findCardNode(const QString &cardName, const QString &zoneName, const QString &providerId = "") const; void emitRecursiveUpdates(const QModelIndex &index); void sortHelper(InnerDecklistNode *node, Qt::SortOrder order); diff --git a/cockatrice/src/deck/deck_view.cpp b/cockatrice/src/deck/deck_view.cpp index ff58fc882..9b7d77c5c 100644 --- a/cockatrice/src/deck/deck_view.cpp +++ b/cockatrice/src/deck/deck_view.cpp @@ -68,8 +68,11 @@ void DeckViewCardDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) event->accept(); } -DeckViewCard::DeckViewCard(const QString &_name, const QString &_originZone, QGraphicsItem *parent) - : AbstractCardItem(_name, 0, -1, parent), originZone(_originZone), dragItem(0) +DeckViewCard::DeckViewCard(QGraphicsItem *parent, + const QString &_name, + const QString &_providerId, + const QString &_originZone) + : AbstractCardItem(parent, _name, _providerId, 0, -1), originZone(_originZone), dragItem(0) { setAcceptHoverEvents(true); } @@ -354,7 +357,8 @@ void DeckViewScene::rebuildTree() continue; for (int k = 0; k < currentCard->getNumber(); ++k) { - DeckViewCard *newCard = new DeckViewCard(currentCard->getName(), currentZone->getName(), container); + DeckViewCard *newCard = new DeckViewCard(container, currentCard->getName(), + currentCard->getCardProviderId(), currentZone->getName()); container->addCard(newCard); emit newCardAdded(newCard); } diff --git a/cockatrice/src/deck/deck_view.h b/cockatrice/src/deck/deck_view.h index 11068d97b..88bbfdf39 100644 --- a/cockatrice/src/deck/deck_view.h +++ b/cockatrice/src/deck/deck_view.h @@ -24,9 +24,10 @@ private: DeckViewCardDragItem *dragItem; public: - DeckViewCard(const QString &_name = QString(), - const QString &_originZone = QString(), - QGraphicsItem *parent = nullptr); + DeckViewCard(QGraphicsItem *parent = nullptr, + const QString &_name = QString(), + const QString &_providerId = QString(), + const QString &_originZone = QString()); ~DeckViewCard(); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); const QString &getOriginZone() const diff --git a/cockatrice/src/game/cards/abstract_card_item.cpp b/cockatrice/src/game/cards/abstract_card_item.cpp index 139ca6a08..80da703a7 100644 --- a/cockatrice/src/game/cards/abstract_card_item.cpp +++ b/cockatrice/src/game/cards/abstract_card_item.cpp @@ -1,7 +1,6 @@ #include "abstract_card_item.h" #include "../../client/ui/picture_loader.h" -#include "../../main.h" #include "../../settings/cache_settings.h" #include "../game_scene.h" #include "card_database.h" @@ -13,9 +12,13 @@ #include #include -AbstractCardItem::AbstractCardItem(const QString &_name, Player *_owner, int _id, QGraphicsItem *parent) - : ArrowTarget(_owner, parent), id(_id), name(_name), tapped(false), facedown(false), tapAngle(0), - bgColor(Qt::transparent), isHovered(false), realZValue(0) +AbstractCardItem::AbstractCardItem(QGraphicsItem *parent, + const QString &_name, + const QString &_providerId, + Player *_owner, + int _id) + : ArrowTarget(_owner, parent), id(_id), name(_name), providerId(_providerId), tapped(false), facedown(false), + tapAngle(0), bgColor(Qt::transparent), isHovered(false), realZValue(0) { setCursor(Qt::OpenHandCursor); setFlag(ItemIsSelectable); @@ -50,7 +53,7 @@ void AbstractCardItem::pixmapUpdated() void AbstractCardItem::cardInfoUpdated() { - info = CardDatabaseManager::getInstance()->getCard(name); + info = CardDatabaseManager::getInstance()->getCardByNameAndProviderId(name, providerId); if (!info && !name.isEmpty()) { QVariantHash properties = QVariantHash(); @@ -185,6 +188,21 @@ void AbstractCardItem::setName(const QString &_name) cardInfoUpdated(); } +void AbstractCardItem::setProviderId(const QString &_providerId) +{ + if (providerId == _providerId) { + return; + } + + emit deleteCardInfoPopup(name); + if (info) { + disconnect(info.data(), nullptr, this, nullptr); + } + providerId = _providerId; + + cardInfoUpdated(); +} + void AbstractCardItem::setHovered(bool _hovered) { if (isHovered == _hovered) diff --git a/cockatrice/src/game/cards/abstract_card_item.h b/cockatrice/src/game/cards/abstract_card_item.h index 864783bbc..c7ecd0615 100644 --- a/cockatrice/src/game/cards/abstract_card_item.h +++ b/cockatrice/src/game/cards/abstract_card_item.h @@ -16,6 +16,7 @@ protected: CardInfoPtr info; int id; QString name; + QString providerId; bool tapped; bool facedown; int tapAngle; @@ -48,10 +49,11 @@ public: { return Type; } - AbstractCardItem(const QString &_name = QString(), + AbstractCardItem(QGraphicsItem *parent = nullptr, + const QString &_name = QString(), + const QString &_providerId = QString(), Player *_owner = nullptr, - int _id = -1, - QGraphicsItem *parent = nullptr); + int _id = -1); ~AbstractCardItem(); QRectF boundingRect() const override; QPainterPath shape() const override; @@ -75,6 +77,11 @@ public: return name; } void setName(const QString &_name = QString()); + QString getProviderId() const + { + return providerId; + } + void setProviderId(const QString &_providerId = QString()); qreal getRealZValue() const { return realZValue; diff --git a/cockatrice/src/game/cards/card_database.cpp b/cockatrice/src/game/cards/card_database.cpp index 9cff3d199..cd101d37f 100644 --- a/cockatrice/src/game/cards/card_database.cpp +++ b/cockatrice/src/game/cards/card_database.cpp @@ -441,13 +441,18 @@ QList CardDatabase::getCards(const QStringList &cardNames) const return cardInfos; } -CardInfoPtr CardDatabase::getCardByNameAndUUID(const QString &cardName, const QString &uuid) const +CardInfoPtr CardDatabase::getCardByNameAndProviderId(const QString &cardName, const QString &providerId) const { auto info = getCard(cardName); + if (providerId.isNull() || providerId.isEmpty() || info.isNull()) { + return info; + } + for (const auto &set : info->getSets()) { - if (set.getProperty("uuid") == uuid) { + if (set.getProperty("uuid") == providerId) { CardInfoPtr cardFromSpecificSet = info->clone(); - cardFromSpecificSet->setPixmapCacheKey(QLatin1String("card_") + QString(set.getProperty("uuid"))); + cardFromSpecificSet->setPixmapCacheKey(QLatin1String("card_") + QString(info->getName()) + QString("_") + + QString(set.getProperty("uuid"))); return cardFromSpecificSet; } } @@ -596,7 +601,8 @@ LoadStatus CardDatabase::loadCardDatabases() void CardDatabase::refreshPreferredPrintings() { for (const CardInfoPtr &card : cards) { - card->setPixmapCacheKey(QLatin1String("card_") + QString(getPreferredPrintingUUIDForCard(card->getName()))); + card->setPixmapCacheKey(QLatin1String("card_") + QString(card->getName()) + QString("_") + + QString(getPreferredPrintingProviderIdForCard(card->getName()))); } } @@ -631,23 +637,48 @@ CardInfoPerSet CardDatabase::getPreferredSetForCard(const QString &cardName) return CardInfoPerSet(nullptr); } -QString CardDatabase::getPreferredPrintingUUIDForCard(const QString &cardName) +CardInfoPerSet CardDatabase::getSpecificSetForCard(const QString &cardName, const QString &providerId) const +{ + CardInfoPtr cardInfo = getCard(cardName); + if (!cardInfo) { + return CardInfoPerSet(nullptr); + } + + CardInfoPerSetMap setMap = cardInfo->getSets(); + if (setMap.empty()) { + return CardInfoPerSet(nullptr); + } + + for (auto &cardInfoForSet : setMap) { + if (cardInfoForSet.getProperty("uuid") == providerId) { + return cardInfoForSet; + } + } + + return CardInfoPerSet(nullptr); +} + +QString CardDatabase::getPreferredPrintingProviderIdForCard(const QString &cardName) { CardInfoPerSet preferredSetCardInfo = getPreferredSetForCard(cardName); - QString preferredPrintingUUID = preferredSetCardInfo.getProperty(QString("uuid")); - if (preferredPrintingUUID.isEmpty()) { + QString preferredPrintingProviderId = preferredSetCardInfo.getProperty(QString("uuid")); + if (preferredPrintingProviderId.isEmpty()) { CardInfoPtr defaultCardInfo = getCard(cardName); if (defaultCardInfo.isNull()) { return cardName; } return defaultCardInfo->getName(); } - return preferredPrintingUUID; + return preferredPrintingProviderId; } -bool CardDatabase::isUuidForPreferredPrinting(const QString &cardName, const QString &uuid) +bool CardDatabase::isProviderIdForPreferredPrinting(const QString &cardName, const QString &providerId) { - return uuid == getPreferredPrintingUUIDForCard(cardName); + if (providerId.startsWith("card_")) { + return providerId == + QLatin1String("card_") + cardName + QString("_") + getPreferredPrintingProviderIdForCard(cardName); + } + return providerId == getPreferredPrintingProviderIdForCard(cardName); } void CardDatabase::refreshCachedReverseRelatedCards() diff --git a/cockatrice/src/game/cards/card_database.h b/cockatrice/src/game/cards/card_database.h index 5d360d39d..3322a5bb6 100644 --- a/cockatrice/src/game/cards/card_database.h +++ b/cockatrice/src/game/cards/card_database.h @@ -414,8 +414,6 @@ protected: private: CardInfoPtr getCardFromMap(const CardNameMap &cardMap, const QString &cardName) const; void checkUnknownSets(); - CardInfoPerSet getPreferredSetForCard(const QString &cardName); - QString getPreferredPrintingUUIDForCard(const QString &cardName); void refreshCachedReverseRelatedCards(); QBasicMutex *reloadDatabaseMutex = new QBasicMutex(), *clearDatabaseMutex = new QBasicMutex(), @@ -431,7 +429,10 @@ public: void removeCard(CardInfoPtr card); CardInfoPtr getCard(const QString &cardName) const; QList getCards(const QStringList &cardNames) const; - CardInfoPtr getCardByNameAndUUID(const QString &cardName, const QString &uuid) const; + CardInfoPtr getCardByNameAndProviderId(const QString &cardName, const QString &providerId) const; + CardInfoPerSet getPreferredSetForCard(const QString &cardName); + CardInfoPerSet getSpecificSetForCard(const QString &cardName, const QString &providerId) const; + QString getPreferredPrintingProviderIdForCard(const QString &cardName); CardInfoPtr guessCard(const QString &cardName) const; /* @@ -441,7 +442,7 @@ public: CardInfoPtr getCardBySimpleName(const QString &cardName) const; CardSetPtr getSet(const QString &setName); - bool isUuidForPreferredPrinting(const QString &cardName, const QString &uuid); + bool isProviderIdForPreferredPrinting(const QString &cardName, const QString &providerId); QList getCardList() const { return cards.values(); diff --git a/cockatrice/src/game/cards/card_item.cpp b/cockatrice/src/game/cards/card_item.cpp index dd78aee04..0378c1909 100644 --- a/cockatrice/src/game/cards/card_item.cpp +++ b/cockatrice/src/game/cards/card_item.cpp @@ -1,7 +1,6 @@ #include "card_item.h" #include "../../client/tabs/tab_game.h" -#include "../../main.h" #include "../../settings/cache_settings.h" #include "../board/arrow_item.h" #include "../game_scene.h" @@ -19,13 +18,14 @@ #include CardItem::CardItem(Player *_owner, + QGraphicsItem *parent, const QString &_name, + const QString &_providerId, int _cardid, bool _revealedCard, - QGraphicsItem *parent, CardZone *_zone) - : AbstractCardItem(_name, _owner, _cardid, parent), zone(_zone), revealedCard(_revealedCard), attacking(false), - destroyOnZoneChange(false), doesntUntap(false), dragItem(nullptr), attachedTo(nullptr) + : AbstractCardItem(parent, _name, _providerId, _owner, _cardid), zone(_zone), revealedCard(_revealedCard), + attacking(false), destroyOnZoneChange(false), doesntUntap(false), dragItem(nullptr), attachedTo(nullptr) { owner->addCard(this); @@ -243,6 +243,7 @@ void CardItem::processCardInfo(const ServerInfo_Card &_info) } setId(_info.id()); + setProviderId(QString::fromStdString(_info.provider_id())); setName(QString::fromStdString(_info.name())); setAttacking(_info.attacking()); setFaceDown(_info.face_down()); diff --git a/cockatrice/src/game/cards/card_item.h b/cockatrice/src/game/cards/card_item.h index 21224878f..bb037ead9 100644 --- a/cockatrice/src/game/cards/card_item.h +++ b/cockatrice/src/game/cards/card_item.h @@ -50,10 +50,11 @@ public: return Type; } CardItem(Player *_owner, + QGraphicsItem *parent = nullptr, const QString &_name = QString(), + const QString &_providerId = QString(), int _cardid = -1, bool revealedCard = false, - QGraphicsItem *parent = nullptr, CardZone *_zone = nullptr); ~CardItem(); void retranslateUi(); diff --git a/cockatrice/src/game/player/player.cpp b/cockatrice/src/game/player/player.cpp index f51006d4f..dd98305ff 100644 --- a/cockatrice/src/game/player/player.cpp +++ b/cockatrice/src/game/player/player.cpp @@ -2031,7 +2031,7 @@ void Player::eventCreateToken(const Event_CreateToken &event) return; } - CardItem *card = new CardItem(this, QString::fromStdString(event.card_name()), event.card_id()); + CardItem *card = new CardItem(this, nullptr, QString::fromStdString(event.card_name()), QString(), event.card_id()); // use db PT if not provided in event if (!QString::fromStdString(event.pt()).isEmpty()) { card->setPT(QString::fromStdString(event.pt())); @@ -2168,6 +2168,9 @@ void Player::eventMoveCard(const Event_MoveCard &event, const GameEventContext & if (event.has_card_name()) { card->setName(QString::fromStdString(event.card_name())); } + if (event.has_new_card_provider_id()) { + card->setProviderId(QString::fromStdString(event.new_card_provider_id())); + } if (card->getAttachedTo() && (startZone != targetZone)) { CardItem *parentCard = card->getAttachedTo(); @@ -2326,6 +2329,7 @@ void Player::eventDrawCards(const Event_DrawCards &event) for (int i = 0; i < listSize; ++i) { const ServerInfo_Card &cardInfo = event.cards(i); CardItem *card = _deck->takeCard(0, cardInfo.id()); + card->setProviderId(QString::fromStdString(cardInfo.provider_id())); card->setName(QString::fromStdString(cardInfo.name())); _hand->addCard(card, false, -1); } diff --git a/cockatrice/src/game/zones/card_zone.cpp b/cockatrice/src/game/zones/card_zone.cpp index b0e06f323..13732f960 100644 --- a/cockatrice/src/game/zones/card_zone.cpp +++ b/cockatrice/src/game/zones/card_zone.cpp @@ -126,7 +126,8 @@ void CardZone::addCard(CardItem *card, bool reorganize, int x, int y) { for (auto *view : views) { if ((x <= view->getCards().size()) || (view->getNumberCards() == -1)) { - view->addCard(new CardItem(player, card->getName(), card->getId()), reorganize, x, y); + view->addCard(new CardItem(player, nullptr, card->getName(), card->getProviderId(), card->getId()), + reorganize, x, y); } } diff --git a/cockatrice/src/game/zones/view_zone.cpp b/cockatrice/src/game/zones/view_zone.cpp index 6cf6ad52e..6d4908179 100644 --- a/cockatrice/src/game/zones/view_zone.cpp +++ b/cockatrice/src/game/zones/view_zone.cpp @@ -56,9 +56,9 @@ void ZoneViewZone::initializeCards(const QList &cardLis { if (!cardList.isEmpty()) { for (int i = 0; i < cardList.size(); ++i) - addCard( - new CardItem(player, QString::fromStdString(cardList[i]->name()), cardList[i]->id(), revealZone, this), - false, i); + addCard(new CardItem(player, this, QString::fromStdString(cardList[i]->name()), + QString::fromStdString(cardList[i]->provider_id()), cardList[i]->id(), revealZone), + false, i); reorganizeCards(); } else if (!origZone->contentsKnown()) { Command_DumpZone cmd; @@ -75,7 +75,8 @@ void ZoneViewZone::initializeCards(const QList &cardLis int number = numberCards == -1 ? c.size() : (numberCards < c.size() ? numberCards : c.size()); for (int i = 0; i < number; i++) { CardItem *card = c.at(i); - addCard(new CardItem(player, card->getName(), card->getId(), revealZone, this), false, i); + addCard(new CardItem(player, this, card->getName(), card->getProviderId(), card->getId(), revealZone), + false, i); } reorganizeCards(); } @@ -88,7 +89,8 @@ void ZoneViewZone::zoneDumpReceived(const Response &r) for (int i = 0; i < respCardListSize; ++i) { const ServerInfo_Card &cardInfo = resp.zone_info().card_list(i); auto cardName = QString::fromStdString(cardInfo.name()); - auto *card = new CardItem(player, cardName, cardInfo.id(), revealZone, this, this); + auto cardProviderId = QString::fromStdString(cardInfo.provider_id()); + auto *card = new CardItem(player, this, cardName, cardProviderId, cardInfo.id(), revealZone, this); cards.insert(i, card); } reorganizeCards(); diff --git a/common/decklist.cpp b/common/decklist.cpp index 1e118d22c..011c9e0f3 100644 --- a/common/decklist.cpp +++ b/common/decklist.cpp @@ -88,7 +88,8 @@ int AbstractDecklistNode::depth() const } InnerDecklistNode::InnerDecklistNode(InnerDecklistNode *other, InnerDecklistNode *_parent) - : AbstractDecklistNode(_parent), name(other->getName()) + : AbstractDecklistNode(_parent), name(other->getName()), cardSetShortName(other->getCardSetShortName()), + cardCollectorNumber(other->getCardCollectorNumber()), cardProviderId(other->getCardProviderId()) { for (int i = 0; i < other->size(); ++i) { auto *inner = dynamic_cast(other->at(i)); @@ -139,7 +140,9 @@ void InnerDecklistNode::clearTree() } DecklistCardNode::DecklistCardNode(DecklistCardNode *other, InnerDecklistNode *_parent) - : AbstractDecklistCardNode(_parent), name(other->getName()), number(other->getNumber()) + : AbstractDecklistCardNode(_parent), name(other->getName()), number(other->getNumber()), + cardSetShortName(other->getCardSetShortName()), cardSetNumber(other->getCardCollectorNumber()), + cardProviderId(other->getCardProviderId()) { } @@ -153,6 +156,17 @@ AbstractDecklistNode *InnerDecklistNode::findChild(const QString &_name) return nullptr; } +AbstractDecklistNode *InnerDecklistNode::findCardChildByNameAndProviderId(const QString &_name, + const QString &_providerId) +{ + for (int i = 0; i < size(); i++) { + if (at(i) != nullptr && at(i)->getName() == _name && at(i)->getCardProviderId() == _providerId) { + return at(i); + } + } + return nullptr; +} + int InnerDecklistNode::height() const { return at(0)->height() + 1; @@ -268,9 +282,10 @@ bool InnerDecklistNode::readElement(QXmlStreamReader *xml) InnerDecklistNode *newZone = new InnerDecklistNode(xml->attributes().value("name").toString(), this); newZone->readElement(xml); } else if (childName == "card") { - DecklistCardNode *newCard = - new DecklistCardNode(xml->attributes().value("name").toString(), - xml->attributes().value("number").toString().toInt(), this); + DecklistCardNode *newCard = new DecklistCardNode( + xml->attributes().value("name").toString(), xml->attributes().value("number").toString().toInt(), + this, xml->attributes().value("setShortName").toString(), + xml->attributes().value("collectorNumber").toString(), xml->attributes().value("uuid").toString()); newCard->readElement(xml); } } else if (xml->isEndElement() && (childName == "zone")) @@ -303,6 +318,16 @@ void AbstractDecklistCardNode::writeElement(QXmlStreamWriter *xml) xml->writeEmptyElement("card"); xml->writeAttribute("number", QString::number(getNumber())); xml->writeAttribute("name", getName()); + + if (getCardSetShortName().isEmpty()) { + xml->writeAttribute("setShortName", getCardSetShortName()); + } + if (getCardCollectorNumber().isEmpty()) { + xml->writeAttribute("collectorNumber", getCardCollectorNumber()); + } + if (getCardProviderId().isEmpty()) { + xml->writeAttribute("uuid", getCardProviderId()); + } } QVector> InnerDecklistNode::sort(Qt::SortOrder order) @@ -740,14 +765,18 @@ int DeckList::getSideboardSize() const return size; } -DecklistCardNode *DeckList::addCard(const QString &cardName, const QString &zoneName) +DecklistCardNode *DeckList::addCard(const QString &cardName, + const QString &zoneName, + const QString &cardSetName, + const QString &cardSetCollectorNumber, + const QString &cardProviderId) { auto *zoneNode = dynamic_cast(root->findChild(zoneName)); if (zoneNode == nullptr) { zoneNode = new InnerDecklistNode(zoneName, root); } - auto *node = new DecklistCardNode(cardName, 1, zoneNode); + auto *node = new DecklistCardNode(cardName, 1, zoneNode, cardSetName, cardSetCollectorNumber, cardProviderId); updateDeckHash(); return node; diff --git a/common/decklist.h b/common/decklist.h index bacba0ce6..ad5f59b22 100644 --- a/common/decklist.h +++ b/common/decklist.h @@ -1,12 +1,7 @@ #ifndef DECKLIST_H #define DECKLIST_H -#include #include -#include -#include -#include -#include #include // Required on Mac. Forward declaration doesn't work. Don't ask why. @@ -68,6 +63,9 @@ public: sortMethod = method; } virtual QString getName() const = 0; + virtual QString getCardProviderId() const = 0; + virtual QString getCardSetShortName() const = 0; + virtual QString getCardCollectorNumber() const = 0; InnerDecklistNode *getParent() const { return parent; @@ -82,8 +80,10 @@ public: class InnerDecklistNode : public AbstractDecklistNode, public QList { -private: QString name; + QString cardSetShortName; + QString cardCollectorNumber; + QString cardProviderId; class compareFunctor; public: @@ -94,7 +94,7 @@ public: explicit InnerDecklistNode(InnerDecklistNode *other, InnerDecklistNode *_parent = nullptr); ~InnerDecklistNode() override; void setSortMethod(DeckSortMethod method) override; - QString getName() const override + [[nodiscard]] QString getName() const override { return name; } @@ -103,9 +103,35 @@ public: name = _name; } static QString visibleNameFromName(const QString &_name); - virtual QString getVisibleName() const; + [[nodiscard]] virtual QString getVisibleName() const; + [[nodiscard]] QString getCardProviderId() const override + { + return cardProviderId; + } + void setCardProviderId(const QString &_cardProviderId) + { + cardProviderId = _cardProviderId; + } + [[nodiscard]] QString getCardSetShortName() const override + { + return cardSetShortName; + } + void setCardSetShortName(const QString &_cardSetShortName) + { + cardSetShortName = _cardSetShortName; + } + [[nodiscard]] QString getCardCollectorNumber() const override + { + return cardCollectorNumber; + } + void setCardCollectorNumber(const QString &_cardCollectorNumber) + { + cardCollectorNumber = _cardCollectorNumber; + } + void clearTree(); AbstractDecklistNode *findChild(const QString &_name); + AbstractDecklistNode *findCardChildByNameAndProviderId(const QString &_name, const QString &_providerId); int height() const override; int recursiveCount(bool countTotalCards = false) const; bool compare(AbstractDecklistNode *other) const override; @@ -127,6 +153,12 @@ public: virtual void setNumber(int _number) = 0; QString getName() const override = 0; virtual void setName(const QString &_name) = 0; + virtual QString getCardProviderId() const override = 0; + virtual void setCardProviderId(const QString &_cardProviderId) = 0; + virtual QString getCardSetShortName() const override = 0; + virtual void setCardSetShortName(const QString &_cardSetShortName) = 0; + virtual QString getCardCollectorNumber() const override = 0; + virtual void setCardCollectorNumber(const QString &_cardSetNumber) = 0; int height() const override { return 0; @@ -141,13 +173,22 @@ public: class DecklistCardNode : public AbstractDecklistCardNode { -private: QString name; int number; + QString cardSetShortName; + QString cardSetNumber; + QString cardProviderId; public: - explicit DecklistCardNode(QString _name = QString(), int _number = 1, InnerDecklistNode *_parent = nullptr) - : AbstractDecklistCardNode(_parent), name(std::move(_name)), number(_number) + explicit DecklistCardNode(QString _name = QString(), + int _number = 1, + InnerDecklistNode *_parent = nullptr, + QString _cardSetShortName = QString(), + QString _cardSetNumber = QString(), + QString _cardProviderId = QString()) + : AbstractDecklistCardNode(_parent), name(std::move(_name)), number(_number), + cardSetShortName(std::move(_cardSetShortName)), cardSetNumber(std::move(_cardSetNumber)), + cardProviderId(std::move(_cardProviderId)) { } explicit DecklistCardNode(DecklistCardNode *other, InnerDecklistNode *_parent); @@ -167,6 +208,31 @@ public: { name = _name; } + QString getCardProviderId() const override + { + return cardProviderId; + } + void setCardProviderId(const QString &_providerId) override + { + cardProviderId = _providerId; + } + + QString getCardSetShortName() const override + { + return cardSetShortName; + } + void setCardSetShortName(const QString &_cardSetShortName) override + { + cardSetShortName = _cardSetShortName; + } + QString getCardCollectorNumber() const override + { + return cardSetNumber; + } + void setCardCollectorNumber(const QString &_cardSetNumber) override + { + cardSetNumber = _cardSetNumber; + } }; class DeckList : public QObject @@ -255,7 +321,11 @@ public: { return root; } - DecklistCardNode *addCard(const QString &cardName, const QString &zoneName); + DecklistCardNode *addCard(const QString &cardName, + const QString &zoneName, + const QString &cardSetName = QString(), + const QString &cardSetCollectorNumber = QString(), + const QString &cardProviderId = QString()); bool deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNode = nullptr); /** @@ -277,4 +347,4 @@ public: } }; -#endif +#endif \ No newline at end of file diff --git a/common/pb/event_move_card.proto b/common/pb/event_move_card.proto index f6d309f36..33363344e 100644 --- a/common/pb/event_move_card.proto +++ b/common/pb/event_move_card.proto @@ -16,4 +16,5 @@ message Event_MoveCard { optional sint32 y = 9 [default = -1]; optional sint32 new_card_id = 10 [default = -1]; optional bool face_down = 11; + optional string new_card_provider_id = 12; } diff --git a/common/pb/serverinfo_card.proto b/common/pb/serverinfo_card.proto index 4d9a585cd..5d1cd9db4 100644 --- a/common/pb/serverinfo_card.proto +++ b/common/pb/serverinfo_card.proto @@ -18,4 +18,5 @@ message ServerInfo_Card { optional sint32 attach_player_id = 14 [default = -1]; optional string attach_zone = 15; optional sint32 attach_card_id = 16 [default = -1]; + optional string provider_id = 17; } diff --git a/common/server_card.cpp b/common/server_card.cpp index 3bab40132..c195695e2 100644 --- a/common/server_card.cpp +++ b/common/server_card.cpp @@ -27,10 +27,15 @@ #include -Server_Card::Server_Card(QString _name, int _id, int _coord_x, int _coord_y, Server_CardZone *_zone) - : zone(_zone), id(_id), coord_x(_coord_x), coord_y(_coord_y), name(_name), tapped(false), attacking(false), - facedown(false), color(), ptString(), annotation(), destroyOnZoneChange(false), doesntUntap(false), parentCard(0), - stashedCard(nullptr) +Server_Card::Server_Card(QString _name, + QString _provider_id, + int _id, + int _coord_x, + int _coord_y, + Server_CardZone *_zone) + : zone(_zone), id(_id), coord_x(_coord_x), coord_y(_coord_y), name(_name), provider_id(_provider_id), tapped(false), + attacking(false), facedown(false), color(), ptString(), annotation(), destroyOnZoneChange(false), + doesntUntap(false), parentCard(0), stashedCard(nullptr) { } @@ -130,6 +135,7 @@ void Server_Card::getInfo(ServerInfo_Card *info) QString displayedName = facedown ? QString() : name; info->set_id(id); + info->set_provider_id(provider_id.toStdString()); info->set_name(displayedName.toStdString()); info->set_x(coord_x); info->set_y(coord_y); diff --git a/common/server_card.h b/common/server_card.h index 58ef20255..bdf82dab8 100644 --- a/common/server_card.h +++ b/common/server_card.h @@ -39,6 +39,7 @@ private: int id; int coord_x, coord_y; QString name; + QString provider_id; QMap counters; bool tapped; bool attacking; @@ -54,7 +55,12 @@ private: Server_Card *stashedCard; public: - Server_Card(QString _name, int _id, int _coord_x, int _coord_y, Server_CardZone *_zone = nullptr); + Server_Card(QString _name, + QString _provider_id, + int _id, + int _coord_x, + int _coord_y, + Server_CardZone *_zone = nullptr); ~Server_Card() override; Server_CardZone *getZone() const @@ -70,6 +76,10 @@ public: { return id; } + QString getProviderId() const + { + return provider_id; + } int getX() const { return coord_x; diff --git a/common/server_player.cpp b/common/server_player.cpp index 862705a7d..adf1a66e0 100644 --- a/common/server_player.cpp +++ b/common/server_player.cpp @@ -209,7 +209,9 @@ void Server_Player::setupZones() continue; } for (int k = 0; k < currentCard->getNumber(); ++k) { - z->insertCard(new Server_Card(currentCard->getName(), nextCardId++, 0, 0, z), -1, 0); + z->insertCard( + new Server_Card(currentCard->getName(), currentCard->getCardProviderId(), nextCardId++, 0, 0, z), + -1, 0); } } } @@ -338,6 +340,7 @@ Response::ResponseCode Server_Player::drawCards(GameEventStorage &ges, int numbe ServerInfo_Card *cardInfo = eventPrivate.add_cards(); cardInfo->set_id(card->getId()); cardInfo->set_name(card->getName().toStdString()); + cardInfo->set_provider_id(card->getProviderId().toStdString()); } ges.enqueueGameEvent(eventPrivate, playerId, GameEventStorageItem::SendToPrivate, playerId); @@ -585,6 +588,7 @@ Response::ResponseCode Server_Player::moveCard(GameEventStorage &ges, if (sourceKnownToPlayer || !(faceDown || targetzone->getType() == ServerInfo_Zone::HiddenZone)) { QString privateCardName = card->getName(); eventPrivate.set_card_name(privateCardName.toStdString()); + eventPrivate.set_new_card_provider_id(card->getProviderId().toStdString()); } if (startzone->getType() == ServerInfo_Zone::HiddenZone) { eventPrivate.set_position(position); @@ -617,6 +621,7 @@ Response::ResponseCode Server_Player::moveCard(GameEventStorage &ges, if (!(sourceHiddenToOthers && targetHiddenToOthers)) { QString publicCardName = card->getName(); eventOthers.set_card_name(publicCardName.toStdString()); + eventOthers.set_new_card_provider_id(card->getProviderId().toStdString()); } eventOthers.set_new_card_id(card->getId()); } @@ -1406,7 +1411,7 @@ Server_Player::cmdCreateToken(const Command_CreateToken &cmd, ResponseContainer yCoord = 0; } - auto *card = new Server_Card(cardName, newCardId(), xCoord, yCoord); + auto *card = new Server_Card(cardName, QString(), newCardId(), xCoord, yCoord); card->moveToThread(thread()); card->setPT(nameFromStdString(cmd.pt())); card->setColor(nameFromStdString(cmd.color())); @@ -1941,6 +1946,7 @@ Server_Player::cmdDumpZone(const Command_DumpZone &cmd, ResponseContainer &rc, G Server_Card *card = cards[i]; QString displayedName = card->getFaceDown() ? QString() : card->getName(); ServerInfo_Card *cardInfo = zoneInfo->add_card_list(); + cardInfo->set_provider_id(card->getProviderId().toStdString()); cardInfo->set_name(displayedName.toStdString()); if (zone->getType() == ServerInfo_Zone::HiddenZone) { cardInfo->set_id(i); @@ -2058,6 +2064,7 @@ Server_Player::cmdRevealCards(const Command_RevealCards &cmd, ResponseContainer ServerInfo_Card *cardInfo = eventPrivate.add_cards(); cardInfo->set_id(card->getId()); + cardInfo->set_provider_id(card->getProviderId().toStdString()); cardInfo->set_name(card->getName().toStdString()); cardInfo->set_x(card->getX()); cardInfo->set_y(card->getY()); diff --git a/webclient/src/i18n-default.json b/webclient/src/i18n-default.json index 3aabe58f6..36abca615 100644 --- a/webclient/src/i18n-default.json +++ b/webclient/src/i18n-default.json @@ -1,382 +1 @@ -{ - "Common": { - "language": "English", - "disconnect": "Disconnect", - "label": { - "confirmPassword": "Confirm Password", - "confirmSure": "Are you sure?", - "country": "Country", - "delete": "Delete", - "email": "Email", - "hostName": "Host Name", - "hostAddress": "Host Address", - "password": "Password", - "passwordAgain": "Password Again", - "port": "Port", - "realName": "Real Name", - "saveChanges": "Save Changes", - "token": "Token", - "username": "Username" - }, - "validation": { - "minChars": "Minimum of {count} {count, plural, one {character} other {characters}} required", - "passwordsMustMatch": "Passwords don't match", - "required": "Required" - }, - "countries": { - "AD": "Andorra", - "AE": "United Arab Emirates", - "AF": "Afghanistan", - "AG": "Antigua and Barbuda", - "AI": "Anguilla", - "AL": "Albania", - "AM": "Armenia", - "AO": "Angola", - "AQ": "Antarctica", - "AR": "Argentina", - "AS": "American Samoa", - "AT": "Austria", - "AU": "Australia", - "AW": "Aruba", - "AX": "Åland Islands", - "AZ": "Azerbaijan", - "BA": "Bosnia and Herzegovina", - "BB": "Barbados", - "BD": "Bangladesh", - "BE": "Belgium", - "BF": "Burkina Faso", - "BG": "Bulgaria", - "BH": "Bahrain", - "BI": "Burundi", - "BJ": "Benin", - "BL": "Saint Barthélemy", - "BM": "Bermuda", - "BN": "Brunei Darussalam", - "BO": "Bolivia", - "BQ": "Bonaire, Sint Eustatius and Saba", - "BR": "Brazil", - "BS": "Bahamas", - "BT": "Bhutan", - "BV": "Bouvet Island", - "BW": "Botswana", - "BY": "Belarus", - "BZ": "Belize", - "CA": "Canada", - "CC": "Cocos (Keeling) Islands", - "CD": "DR Congo", - "CF": "Central African Republic", - "CG": "Republic of the Congo", - "CH": "Switzerland", - "CI": "Ivory Coast", - "CK": "Cook Islands", - "CL": "Chile", - "CM": "Cameroon", - "CN": "China", - "CO": "Colombia", - "CR": "Costa Rica", - "CU": "Cuba", - "CV": "Cape Verde", - "CW": "Curaçao", - "CX": "Christmas Island", - "CY": "Cyprus", - "CZ": "Czechia", - "DE": "Germany", - "DJ": "Djibouti", - "DK": "Denmark", - "DM": "Dominica", - "DO": "Dominican Republic", - "DZ": "Algeria", - "EC": "Ecuador", - "EE": "Estonia", - "EG": "Egypt", - "EH": "Western Sahara", - "ER": "Eritrea", - "ES": "Spain", - "ET": "Ethiopia", - "FI": "Finland", - "FJ": "Fiji", - "FK": "Falkland Islands", - "FM": "Micronesia", - "FO": "Faroe Islands", - "FR": "France", - "GA": "Gabon", - "GB": "United Kingdom", - "GD": "Grenada", - "GE": "Georgia", - "GF": "French Guiana", - "GG": "Guernsey", - "GH": "Ghana", - "GI": "Gibraltar", - "GL": "Greenland", - "GM": "Gambia", - "GN": "Guinea", - "GP": "Guadeloupe", - "GQ": "Equatorial Guinea", - "GR": "Greece", - "GS": "South Georgia and the South Sandwich Islands", - "GT": "Guatemala", - "GU": "Guam", - "GW": "Guinea-Bissau", - "GY": "Guyana", - "HK": "Hong Kong", - "HM": "Heard Island and McDonald Islands", - "HN": "Honduras", - "HR": "Croatia", - "HT": "Haiti", - "HU": "Hungary", - "ID": "Indonesia", - "IE": "Ireland", - "IL": "Israel", - "IM": "Isle of Man", - "IN": "India", - "IO": "British Indian Ocean Territory", - "IQ": "Iraq", - "IR": "Iran", - "IS": "Iceland", - "IT": "Italy", - "JE": "Jersey", - "JM": "Jamaica", - "JO": "Jordan", - "JP": "Japan", - "KE": "Kenya", - "KG": "Kyrgyzstan", - "KH": "Cambodia", - "KI": "Kiribati", - "KM": "Comoros", - "KN": "Saint Kitts and Nevis", - "KP": "North Korea", - "KR": "South Korea", - "KW": "Kuwait", - "KY": "Cayman Islands", - "KZ": "Kazakhstan", - "LA": "Laos", - "LB": "Lebanon", - "LC": "Saint Lucia", - "LI": "Liechtenstein", - "LK": "Sri Lanka", - "LR": "Liberia", - "LS": "Lesotho", - "LT": "Lithuania", - "LU": "Luxembourg", - "LV": "Latvia", - "LY": "Libya", - "MA": "Morocco", - "MC": "Monaco", - "MD": "Moldova", - "ME": "Montenegro", - "MF": "Saint Martin (French part)", - "MG": "Madagascar", - "MH": "Marshall Islands", - "MK": "North Macedonia", - "ML": "Mali", - "MM": "Myanmar", - "MN": "Mongolia", - "MO": "Macao", - "MP": "Northern Mariana Islands", - "MQ": "Martinique", - "MR": "Mauritania", - "MS": "Montserrat", - "MT": "Malta", - "MU": "Mauritius", - "MV": "Maldives", - "MW": "Malawi", - "MX": "Mexico", - "MY": "Malaysia", - "MZ": "Mozambique", - "NA": "Namibia", - "NC": "New Caledonia", - "NE": "Niger", - "NF": "Norfolk Island", - "NG": "Nigeria", - "NI": "Nicaragua", - "NL": "Netherlands", - "NO": "Norway", - "NP": "Nepal", - "NR": "Nauru", - "NU": "Niue", - "NZ": "New Zealand", - "OM": "Oman", - "PA": "Panama", - "PE": "Peru", - "PF": "French Polynesia", - "PG": "Papua New Guinea", - "PH": "Philippines", - "PK": "Pakistan", - "PL": "Poland", - "PM": "Saint Pierre and Miquelon", - "PN": "Pitcairn", - "PR": "Puerto Rico", - "PS": "Palestine", - "PT": "Portugal", - "PW": "Palau", - "PY": "Paraguay", - "QA": "Qatar", - "RE": "Réunion", - "RO": "Romania", - "RS": "Serbia", - "RU": "Russia", - "RW": "Rwanda", - "SA": "Saudi Arabia", - "SB": "Solomon Islands", - "SC": "Seychelles", - "SD": "Sudan", - "SE": "Sweden", - "SG": "Singapore", - "SH": "Saint Helena, Ascension and Tristan da Cunha", - "SI": "Slovenia", - "SJ": "Svalbard and Jan Mayen", - "SK": "Slovakia", - "SL": "Sierra Leone", - "SM": "San Marino", - "SN": "Senegal", - "SO": "Somalia", - "SR": "Suriname", - "SS": "South Sudan", - "ST": "Sao Tome and Principe", - "SV": "El Salvador", - "SX": "Sint Maarten (Dutch part)", - "SY": "Syria", - "SZ": "Eswatini", - "TC": "Turks and Caicos Islands", - "TD": "Chad", - "TF": "TAAF", - "TG": "Togo", - "TH": "Thailand", - "TJ": "Tajikistan", - "TK": "Tokelau", - "TL": "Timor-Leste", - "TM": "Turkmenistan", - "TN": "Tunisia", - "TO": "Tonga", - "TR": "Turkey", - "TT": "Trinidad and Tobago", - "TV": "Tuvalu", - "TW": "Taiwan", - "TZ": "Tanzania", - "UA": "Ukraine", - "UG": "Uganda", - "UM": "United States Minor Outlying Islands", - "US": "United States", - "UY": "Uruguay", - "UZ": "Uzbekistan", - "VA": "Holy See", - "VC": "Saint Vincent and the Grenadines", - "VE": "Venezuela", - "VG": "British Virgin Islands", - "VI": "U.S. Virgin Islands", - "VN": "Viet Nam", - "VU": "Vanuatu", - "WF": "Wallis and Futuna", - "WS": "Samoa", - "YE": "Yemen", - "YT": "Mayotte", - "XK": "Kosovo", - "ZA": "South Africa", - "ZM": "Zambia", - "ZW": "Zimbabwe", - "EU": "European Union" - }, - "languages": { - "en-US": "English - US", - "fr": "French", - "nl": "Dutch", - "pt_BR": "Portuguese - Brazil" - } - }, - "KnownHosts": { - "label": "Host", - "add": "Add new host", - "toast": "Host successfully {mode, select, created {created} deleted {deleted} other {edited}}." - }, - "InitializeContainer": { - "title": "DID YOU KNOW", - "subtitle": "<1>Cockatrice is run by volunteers<1>that love card games!" - }, - "LoginContainer": { - "header": { - "title": "Login", - "subtitle": "A cross-platform virtual tabletop for multiplayer card games." - }, - "footer": { - "registerPrompt": "Not registered yet?", - "registerAction": "Create an account", - "credit": "Cockatrice is an open source project", - "version": "Version" - }, - "content": { - "subtitle1": "Play multiplayer card games online.", - "subtitle2": "Cross-platform virtual tabletop for multiplayer card games. Forever free." - }, - "toasts": { - "passwordResetSuccessToast": "Password Reset Successfully", - "accountActivationSuccess": "Account Activated Successfully" - } - }, - "UnsupportedContainer": { - "title": "Unsupported Browser", - "subtitle1": "Please update your browser and/or check your permissions.", - "subtitle2": "Note: Private browsing causes some browsers to disable certain permissions or features." - }, - "AccountActivationDialog": { - "title": "Account Activation", - "subtitle1": "Your account has not been activated yet.", - "subtitle2": "You need to provide the activation token received in the activation email." - }, - "KnownHostDialog": { - "title": "{mode, select, edit {Edit} other {Add}} Known Host", - "subtitle": "Adding a new host allows you to connect to different servers. Enter the details below to your host list." - }, - "RegistrationDialog": { - "title": "Create New Account" - }, - "RequestPasswordResetDialog": { - "title": "Request Password Reset" - }, - "ResetPasswordDialog": { - "title": "Reset Password" - }, - "AccountActivationForm": { - "error": { - "failed": "Account activation failed" - }, - "label": { - "activate": "Activate Account" - } - }, - "KnownHostForm": { - "help": "Need help adding a new host?", - "label": { - "add": "Add Host", - "find": "Find Host" - } - }, - "LoginForm": { - "label": { - "autoConnect": "Auto Connect", - "forgot": "Forgot Password", - "login": "Login", - "savePassword": "Save Password", - "savedPassword": "Saved Password" - } - }, - "RegisterForm": { - "label": { - "register": "Register" - }, - "toast": { - "registerSuccess": "Registration Successful!" - } - }, - "RequestPasswordResetForm": { - "error": "Request password reset failed", - "mfaEnabled": "Server has multi-factor authentication enabled", - "request": "Request Reset Token", - "skipRequest": "I already have a reset token" - }, - "ResetPasswordForm": { - "error": "Password reset failed", - "label": { - "reset": "Reset Password" - } - } -} +{"Common":{"language":"English","disconnect":"Disconnect","label":{"confirmPassword":"Confirm Password","confirmSure":"Are you sure?","country":"Country","delete":"Delete","email":"Email","hostName":"Host Name","hostAddress":"Host Address","password":"Password","passwordAgain":"Password Again","port":"Port","realName":"Real Name","saveChanges":"Save Changes","token":"Token","username":"Username"},"validation":{"minChars":"Minimum of {count} {count, plural, one {character} other {characters}} required","passwordsMustMatch":"Passwords don't match","required":"Required"},"countries":{"AD":"Andorra","AE":"United Arab Emirates","AF":"Afghanistan","AG":"Antigua and Barbuda","AI":"Anguilla","AL":"Albania","AM":"Armenia","AO":"Angola","AQ":"Antarctica","AR":"Argentina","AS":"American Samoa","AT":"Austria","AU":"Australia","AW":"Aruba","AX":"Åland Islands","AZ":"Azerbaijan","BA":"Bosnia and Herzegovina","BB":"Barbados","BD":"Bangladesh","BE":"Belgium","BF":"Burkina Faso","BG":"Bulgaria","BH":"Bahrain","BI":"Burundi","BJ":"Benin","BL":"Saint Barthélemy","BM":"Bermuda","BN":"Brunei Darussalam","BO":"Bolivia","BQ":"Bonaire, Sint Eustatius and Saba","BR":"Brazil","BS":"Bahamas","BT":"Bhutan","BV":"Bouvet Island","BW":"Botswana","BY":"Belarus","BZ":"Belize","CA":"Canada","CC":"Cocos (Keeling) Islands","CD":"DR Congo","CF":"Central African Republic","CG":"Republic of the Congo","CH":"Switzerland","CI":"Ivory Coast","CK":"Cook Islands","CL":"Chile","CM":"Cameroon","CN":"China","CO":"Colombia","CR":"Costa Rica","CU":"Cuba","CV":"Cape Verde","CW":"Curaçao","CX":"Christmas Island","CY":"Cyprus","CZ":"Czechia","DE":"Germany","DJ":"Djibouti","DK":"Denmark","DM":"Dominica","DO":"Dominican Republic","DZ":"Algeria","EC":"Ecuador","EE":"Estonia","EG":"Egypt","EH":"Western Sahara","ER":"Eritrea","ES":"Spain","ET":"Ethiopia","FI":"Finland","FJ":"Fiji","FK":"Falkland Islands","FM":"Micronesia","FO":"Faroe Islands","FR":"France","GA":"Gabon","GB":"United Kingdom","GD":"Grenada","GE":"Georgia","GF":"French Guiana","GG":"Guernsey","GH":"Ghana","GI":"Gibraltar","GL":"Greenland","GM":"Gambia","GN":"Guinea","GP":"Guadeloupe","GQ":"Equatorial Guinea","GR":"Greece","GS":"South Georgia and the South Sandwich Islands","GT":"Guatemala","GU":"Guam","GW":"Guinea-Bissau","GY":"Guyana","HK":"Hong Kong","HM":"Heard Island and McDonald Islands","HN":"Honduras","HR":"Croatia","HT":"Haiti","HU":"Hungary","ID":"Indonesia","IE":"Ireland","IL":"Israel","IM":"Isle of Man","IN":"India","IO":"British Indian Ocean Territory","IQ":"Iraq","IR":"Iran","IS":"Iceland","IT":"Italy","JE":"Jersey","JM":"Jamaica","JO":"Jordan","JP":"Japan","KE":"Kenya","KG":"Kyrgyzstan","KH":"Cambodia","KI":"Kiribati","KM":"Comoros","KN":"Saint Kitts and Nevis","KP":"North Korea","KR":"South Korea","KW":"Kuwait","KY":"Cayman Islands","KZ":"Kazakhstan","LA":"Laos","LB":"Lebanon","LC":"Saint Lucia","LI":"Liechtenstein","LK":"Sri Lanka","LR":"Liberia","LS":"Lesotho","LT":"Lithuania","LU":"Luxembourg","LV":"Latvia","LY":"Libya","MA":"Morocco","MC":"Monaco","MD":"Moldova","ME":"Montenegro","MF":"Saint Martin (French part)","MG":"Madagascar","MH":"Marshall Islands","MK":"North Macedonia","ML":"Mali","MM":"Myanmar","MN":"Mongolia","MO":"Macao","MP":"Northern Mariana Islands","MQ":"Martinique","MR":"Mauritania","MS":"Montserrat","MT":"Malta","MU":"Mauritius","MV":"Maldives","MW":"Malawi","MX":"Mexico","MY":"Malaysia","MZ":"Mozambique","NA":"Namibia","NC":"New Caledonia","NE":"Niger","NF":"Norfolk Island","NG":"Nigeria","NI":"Nicaragua","NL":"Netherlands","NO":"Norway","NP":"Nepal","NR":"Nauru","NU":"Niue","NZ":"New Zealand","OM":"Oman","PA":"Panama","PE":"Peru","PF":"French Polynesia","PG":"Papua New Guinea","PH":"Philippines","PK":"Pakistan","PL":"Poland","PM":"Saint Pierre and Miquelon","PN":"Pitcairn","PR":"Puerto Rico","PS":"Palestine","PT":"Portugal","PW":"Palau","PY":"Paraguay","QA":"Qatar","RE":"Réunion","RO":"Romania","RS":"Serbia","RU":"Russia","RW":"Rwanda","SA":"Saudi Arabia","SB":"Solomon Islands","SC":"Seychelles","SD":"Sudan","SE":"Sweden","SG":"Singapore","SH":"Saint Helena, Ascension and Tristan da Cunha","SI":"Slovenia","SJ":"Svalbard and Jan Mayen","SK":"Slovakia","SL":"Sierra Leone","SM":"San Marino","SN":"Senegal","SO":"Somalia","SR":"Suriname","SS":"South Sudan","ST":"Sao Tome and Principe","SV":"El Salvador","SX":"Sint Maarten (Dutch part)","SY":"Syria","SZ":"Eswatini","TC":"Turks and Caicos Islands","TD":"Chad","TF":"TAAF","TG":"Togo","TH":"Thailand","TJ":"Tajikistan","TK":"Tokelau","TL":"Timor-Leste","TM":"Turkmenistan","TN":"Tunisia","TO":"Tonga","TR":"Turkey","TT":"Trinidad and Tobago","TV":"Tuvalu","TW":"Taiwan","TZ":"Tanzania","UA":"Ukraine","UG":"Uganda","UM":"United States Minor Outlying Islands","US":"United States","UY":"Uruguay","UZ":"Uzbekistan","VA":"Holy See","VC":"Saint Vincent and the Grenadines","VE":"Venezuela","VG":"British Virgin Islands","VI":"U.S. Virgin Islands","VN":"Viet Nam","VU":"Vanuatu","WF":"Wallis and Futuna","WS":"Samoa","YE":"Yemen","YT":"Mayotte","XK":"Kosovo","ZA":"South Africa","ZM":"Zambia","ZW":"Zimbabwe","EU":"European Union"},"languages":{"en-US":"English - US","fr":"French","nl":"Dutch","pt_BR":"Portuguese - Brazil"}},"KnownHosts":{"label":"Host","add":"Add new host","toast":"Host successfully {mode, select, created {created} deleted {deleted} other {edited}}."},"InitializeContainer":{"title":"DID YOU KNOW","subtitle":"<1>Cockatrice is run by volunteers<1>that love card games!"},"LoginContainer":{"header":{"title":"Login","subtitle":"A cross-platform virtual tabletop for multiplayer card games."},"footer":{"registerPrompt":"Not registered yet?","registerAction":"Create an account","credit":"Cockatrice is an open source project","version":"Version"},"content":{"subtitle1":"Play multiplayer card games online.","subtitle2":"Cross-platform virtual tabletop for multiplayer card games. Forever free."},"toasts":{"passwordResetSuccessToast":"Password Reset Successfully","accountActivationSuccess":"Account Activated Successfully"}},"UnsupportedContainer":{"title":"Unsupported Browser","subtitle1":"Please update your browser and/or check your permissions.","subtitle2":"Note: Private browsing causes some browsers to disable certain permissions or features."},"AccountActivationDialog":{"title":"Account Activation","subtitle1":"Your account has not been activated yet.","subtitle2":"You need to provide the activation token received in the activation email."},"KnownHostDialog":{"title":"{mode, select, edit {Edit} other {Add}} Known Host","subtitle":"Adding a new host allows you to connect to different servers. Enter the details below to your host list."},"RegistrationDialog":{"title":"Create New Account"},"RequestPasswordResetDialog":{"title":"Request Password Reset"},"ResetPasswordDialog":{"title":"Reset Password"},"AccountActivationForm":{"error":{"failed":"Account activation failed"},"label":{"activate":"Activate Account"}},"KnownHostForm":{"help":"Need help adding a new host?","label":{"add":"Add Host","find":"Find Host"}},"LoginForm":{"label":{"autoConnect":"Auto Connect","forgot":"Forgot Password","login":"Login","savePassword":"Save Password","savedPassword":"Saved Password"}},"RegisterForm":{"label":{"register":"Register"},"toast":{"registerSuccess":"Registration Successful!"}},"RequestPasswordResetForm":{"error":"Request password reset failed","mfaEnabled":"Server has multi-factor authentication enabled","request":"Request Reset Token","skipRequest":"I already have a reset token"},"ResetPasswordForm":{"error":"Password reset failed","label":{"reset":"Reset Password"}}} \ No newline at end of file