From 02de7e1c559b9ec1e47cee718c74f92d13a48245 Mon Sep 17 00:00:00 2001 From: Bryce! Date: Sun, 1 Nov 2026 17:37:00 -0500 Subject: [PATCH] Preserve unknown cards in deck analysis exports --- .../network/interfaces/deck_stats_interface.cpp | 9 +++++---- .../network/interfaces/tapped_out_interface.cpp | 13 +++++++------ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/cockatrice/src/client/network/interfaces/deck_stats_interface.cpp b/cockatrice/src/client/network/interfaces/deck_stats_interface.cpp index 29ceec040..5be4c8a9a 100644 --- a/cockatrice/src/client/network/interfaces/deck_stats_interface.cpp +++ b/cockatrice/src/client/network/interfaces/deck_stats_interface.cpp @@ -32,9 +32,8 @@ bool normalizeAnalysisUrl(QUrl &url, const QString &serviceHost) const QString host = url.host().toLower(); const bool legacyHttp = url.scheme() == QStringLiteral("http"); const int defaultPort = legacyHttp ? 80 : 443; - if (!url.isValid() || (!legacyHttp && url.scheme() != QStringLiteral("https")) || - !url.userInfo().isEmpty() || !url.path().startsWith('/') || - (url.port() != -1 && url.port() != defaultPort) || + if (!url.isValid() || (!legacyHttp && url.scheme() != QStringLiteral("https")) || !url.userInfo().isEmpty() || + !url.path().startsWith('/') || (url.port() != -1 && url.port() != defaultPort) || (host != serviceHost && host != QStringLiteral("www.") + serviceHost)) { return false; } @@ -135,7 +134,9 @@ void DeckStatsInterface::copyDeckWithoutTokens(const DeckList &source, DeckList { auto copyIfNotAToken = [&destination](const auto node, const auto card) { CardInfoPtr dbCard = CardDatabaseManager::query()->getCardInfo(card->getName()); - if (dbCard && !dbCard->getIsToken() && node->getName() != DECK_ZONE_MAYBEBOARD) { + // Missing local card data is not evidence that a card is a token. Keep + // its original name and quantity so the service analyzes the whole deck. + if ((!dbCard || !dbCard->getIsToken()) && node->getName() != DECK_ZONE_MAYBEBOARD) { DecklistCardNode *addedCard = destination.addCard(card->getName(), node->getName(), -1); addedCard->setNumber(card->getNumber()); } diff --git a/cockatrice/src/client/network/interfaces/tapped_out_interface.cpp b/cockatrice/src/client/network/interfaces/tapped_out_interface.cpp index 5be282a5d..41d387557 100644 --- a/cockatrice/src/client/network/interfaces/tapped_out_interface.cpp +++ b/cockatrice/src/client/network/interfaces/tapped_out_interface.cpp @@ -38,9 +38,8 @@ bool normalizeAnalysisUrl(QUrl &url, const QString &serviceHost) const QString host = url.host().toLower(); const bool legacyHttp = url.scheme() == QStringLiteral("http"); const int defaultPort = legacyHttp ? 80 : 443; - if (!url.isValid() || (!legacyHttp && url.scheme() != QStringLiteral("https")) || - !url.userInfo().isEmpty() || !url.path().startsWith('/') || - (url.port() != -1 && url.port() != defaultPort) || + if (!url.isValid() || (!legacyHttp && url.scheme() != QStringLiteral("https")) || !url.userInfo().isEmpty() || + !url.path().startsWith('/') || (url.port() != -1 && url.port() != defaultPort) || (host != serviceHost && host != QStringLiteral("www.") + serviceHost)) { return false; } @@ -106,8 +105,8 @@ void TappedOutInterface::queryFinished(QNetworkReply *reply) const QString data = QString::fromUtf8(reply->readAll()); QStringList errorMessageList = {tr("Unable to analyze the deck on TappedOut.")}; - static const QRegularExpression errorsRx( - "
(.*?)", QRegularExpression::DotMatchesEverythingOption); + static const QRegularExpression errorsRx("
(.*?)", + QRegularExpression::DotMatchesEverythingOption); const auto match = errorsRx.match(data); if (match.hasMatch()) { static const QRegularExpression itemRx("
  • (.*?)
  • ", QRegularExpression::DotMatchesEverythingOption); @@ -155,7 +154,9 @@ void TappedOutInterface::copyDeckSplitMainAndSide(const DeckList &source, DeckLi { auto copyMainOrSide = [&mainboard, &sideboard](const auto node, const auto card) { CardInfoPtr dbCard = CardDatabaseManager::query()->getCardInfo(card->getName()); - if (!dbCard || dbCard->getIsToken() || node->getName() == DECK_ZONE_MAYBEBOARD) { + // Exclude confirmed tokens, but preserve cards missing from the local + // database, including newly released cards in an imported deck. + if ((dbCard && dbCard->getIsToken()) || node->getName() == DECK_ZONE_MAYBEBOARD) { return; }