Fix #45: don't send tokens to deckstats.
This commit is contained in:
parent
4d6f46b06e
commit
7cbe410172
8 changed files with 105 additions and 47 deletions
|
@ -652,41 +652,13 @@ void CardDatabase::loadCardsFromXml(QXmlStreamReader &xml)
|
|||
}
|
||||
}
|
||||
|
||||
LoadStatus CardDatabase::loadFromFile(const QString &fileName, bool tokens)
|
||||
LoadStatus CardDatabase::loadFromFile(const QString &fileName)
|
||||
{
|
||||
QFile file(fileName);
|
||||
file.open(QIODevice::ReadOnly);
|
||||
if (!file.isOpen())
|
||||
return FileError;
|
||||
|
||||
if (tokens) {
|
||||
QMutableHashIterator<QString, CardInfo *> i(cardHash);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
if (i.value()->getIsToken()) {
|
||||
delete i.value();
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
QHashIterator<QString, CardSet *> setIt(setHash);
|
||||
while (setIt.hasNext()) {
|
||||
setIt.next();
|
||||
delete setIt.value();
|
||||
}
|
||||
setHash.clear();
|
||||
|
||||
QMutableHashIterator<QString, CardInfo *> i(cardHash);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
if (!i.value()->getIsToken()) {
|
||||
delete i.value();
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
cardHash.clear();
|
||||
}
|
||||
|
||||
QXmlStreamReader xml(&file);
|
||||
while (!xml.atEnd()) {
|
||||
if (xml.readNext() == QXmlStreamReader::StartElement) {
|
||||
|
@ -738,8 +710,7 @@ bool CardDatabase::saveToFile(const QString &fileName, bool tokens)
|
|||
QHashIterator<QString, CardInfo *> cardIterator(cardHash);
|
||||
while (cardIterator.hasNext()) {
|
||||
CardInfo *card = cardIterator.next().value();
|
||||
if (card->getIsToken() == tokens)
|
||||
xml << card;
|
||||
xml << card;
|
||||
}
|
||||
xml.writeEndElement(); // cards
|
||||
|
||||
|
@ -773,7 +744,7 @@ LoadStatus CardDatabase::loadCardDatabase(const QString &path, bool tokens)
|
|||
{
|
||||
LoadStatus tempLoadStatus = NotLoaded;
|
||||
if (!path.isEmpty())
|
||||
tempLoadStatus = loadFromFile(path, tokens);
|
||||
tempLoadStatus = loadFromFile(path);
|
||||
|
||||
if (tempLoadStatus == Ok) {
|
||||
SetList allSets;
|
||||
|
|
|
@ -186,7 +186,7 @@ public:
|
|||
CardSet *getSet(const QString &setName);
|
||||
QList<CardInfo *> getCardList() const { return cardHash.values(); }
|
||||
SetList getSetList() const;
|
||||
LoadStatus loadFromFile(const QString &fileName, bool tokens = false);
|
||||
LoadStatus loadFromFile(const QString &fileName);
|
||||
bool saveToFile(const QString &fileName, bool tokens = false);
|
||||
QStringList getAllColors() const;
|
||||
QStringList getAllMainCardTypes() const;
|
||||
|
|
|
@ -7,8 +7,10 @@
|
|||
#include <QMessageBox>
|
||||
#include <QDesktopServices>
|
||||
|
||||
DeckStatsInterface::DeckStatsInterface(QObject *parent)
|
||||
: QObject(parent)
|
||||
DeckStatsInterface::DeckStatsInterface(
|
||||
CardDatabase &_cardDatabase,
|
||||
QObject *parent
|
||||
) : QObject(parent), cardDatabase(_cardDatabase)
|
||||
{
|
||||
manager = new QNetworkAccessManager(this);
|
||||
connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(queryFinished(QNetworkReply *)));
|
||||
|
@ -42,7 +44,11 @@ void DeckStatsInterface::queryFinished(QNetworkReply *reply)
|
|||
void DeckStatsInterface::analyzeDeck(DeckList *deck)
|
||||
{
|
||||
QUrl params;
|
||||
params.addQueryItem("deck", deck->writeToString_Plain());
|
||||
|
||||
DeckList deckWithoutTokens;
|
||||
copyDeckWithoutTokens(*deck, deckWithoutTokens);
|
||||
|
||||
params.addQueryItem("deck", deckWithoutTokens.writeToString_Plain());
|
||||
QByteArray data;
|
||||
data.append(params.encodedQuery());
|
||||
|
||||
|
@ -51,3 +57,30 @@ void DeckStatsInterface::analyzeDeck(DeckList *deck)
|
|||
|
||||
manager->post(request, data);
|
||||
}
|
||||
|
||||
struct CopyIfNotAToken {
|
||||
CardDatabase &cardDatabase;
|
||||
DeckList &destination;
|
||||
|
||||
CopyIfNotAToken(
|
||||
CardDatabase &_cardDatabase,
|
||||
DeckList &_destination
|
||||
) : cardDatabase(_cardDatabase), destination(_destination) {};
|
||||
|
||||
void operator()(
|
||||
const InnerDecklistNode *node,
|
||||
const DecklistCardNode *card
|
||||
) const {
|
||||
if (!cardDatabase.getCard(card->getName())->getIsToken()) {
|
||||
destination.addCard(card->getName(), node->getName());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void DeckStatsInterface::copyDeckWithoutTokens(
|
||||
const DeckList &source,
|
||||
DeckList &destination
|
||||
) {
|
||||
CopyIfNotAToken copyIfNotAToken(cardDatabase, destination);
|
||||
source.forEachCard(copyIfNotAToken);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef DECKSTATS_INTERFACE_H
|
||||
#define DECKSTATS_INTERFACE_H
|
||||
|
||||
#include "carddatabase.h"
|
||||
#include "decklist.h"
|
||||
#include <QObject>
|
||||
|
||||
class QNetworkAccessManager;
|
||||
|
@ -11,10 +13,20 @@ class DeckStatsInterface : public QObject {
|
|||
Q_OBJECT
|
||||
private:
|
||||
QNetworkAccessManager *manager;
|
||||
|
||||
CardDatabase &cardDatabase;
|
||||
|
||||
/**
|
||||
* Deckstats doesn't recognize token cards, and instead tries to find the
|
||||
* closest non-token card instead. So we construct a new deck which has no
|
||||
* tokens.
|
||||
*/
|
||||
void copyDeckWithoutTokens(const DeckList &source, DeckList& destination);
|
||||
|
||||
private slots:
|
||||
void queryFinished(QNetworkReply *reply);
|
||||
public:
|
||||
DeckStatsInterface(QObject *parent = 0);
|
||||
DeckStatsInterface(CardDatabase &_cardDatabase, QObject *parent = 0);
|
||||
void analyzeDeck(DeckList *deck);
|
||||
};
|
||||
|
||||
|
|
|
@ -508,7 +508,10 @@ void TabDeckEditor::actPrintDeck()
|
|||
|
||||
void TabDeckEditor::actAnalyzeDeck()
|
||||
{
|
||||
DeckStatsInterface *interface = new DeckStatsInterface(this); // it deletes itself when done
|
||||
DeckStatsInterface *interface = new DeckStatsInterface(
|
||||
*databaseModel->getDatabase(),
|
||||
this
|
||||
); // it deletes itself when done
|
||||
interface->analyzeDeck(deckModel->getDeckList());
|
||||
}
|
||||
|
||||
|
|
|
@ -579,16 +579,30 @@ bool DeckList::loadFromFile_Plain(QIODevice *device)
|
|||
return loadFromStream_Plain(in);
|
||||
}
|
||||
|
||||
struct WriteToStream {
|
||||
QTextStream &stream;
|
||||
|
||||
WriteToStream(QTextStream &_stream) : stream(_stream) {}
|
||||
|
||||
void operator()(
|
||||
const InnerDecklistNode *node,
|
||||
const DecklistCardNode *card
|
||||
) {
|
||||
if (node->getName() == "side") {
|
||||
stream << "SB: ";
|
||||
}
|
||||
stream << QString("%1 %2\n").arg(
|
||||
card->getNumber()
|
||||
).arg(
|
||||
card->getName()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
bool DeckList::saveToStream_Plain(QTextStream &out)
|
||||
{
|
||||
// Support for this is only possible if the internal structure doesn't get more complicated.
|
||||
for (int i = 0; i < root->size(); i++) {
|
||||
InnerDecklistNode *node = dynamic_cast<InnerDecklistNode *>(root->at(i));
|
||||
for (int j = 0; j < node->size(); j++) {
|
||||
DecklistCardNode *card = dynamic_cast<DecklistCardNode *>(node->at(j));
|
||||
out << QString("%1%2 %3\n").arg(node->getName() == "side" ? "SB: " : "").arg(card->getNumber()).arg(card->getName());
|
||||
}
|
||||
}
|
||||
WriteToStream writeToStream(out);
|
||||
forEachCard(writeToStream);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -117,6 +117,7 @@ public:
|
|||
QString getName() const { return name; }
|
||||
void setName(const QString &_name) { name = _name; }
|
||||
float getPrice() const { return price; }
|
||||
|
||||
void setPrice(const float _price) { price = _price; }
|
||||
};
|
||||
|
||||
|
@ -169,6 +170,28 @@ public:
|
|||
InnerDecklistNode *getRoot() const { return root; }
|
||||
DecklistCardNode *addCard(const QString &cardName, const QString &zoneName);
|
||||
bool deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNode = 0);
|
||||
|
||||
/**
|
||||
* Calls a given function object for each card in the deck. It must
|
||||
* take a InnerDecklistNode* as its first argument and a
|
||||
* DecklistCardNode* as its second.
|
||||
*/
|
||||
template <typename Callback>
|
||||
void forEachCard(Callback &callback) const {
|
||||
// Support for this is only possible if the internal structure
|
||||
// doesn't get more complicated.
|
||||
for (int i = 0; i < root->size(); i++) {
|
||||
const InnerDecklistNode *node =
|
||||
dynamic_cast<InnerDecklistNode *>(root->at(i));
|
||||
for (int j = 0; j < node->size(); j++) {
|
||||
const DecklistCardNode *card =
|
||||
dynamic_cast<DecklistCardNode *>(
|
||||
node->at(j)
|
||||
);
|
||||
callback(node, card);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -137,6 +137,7 @@ int OracleImporter::importTextSpoiler(CardSet *set, const QVariant &data)
|
|||
QString cardText;
|
||||
int cardId;
|
||||
int cardLoyalty;
|
||||
bool cardIsToken = false;
|
||||
QMap<int, QVariantMap> splitCards;
|
||||
|
||||
while (it.hasNext()) {
|
||||
|
@ -197,9 +198,10 @@ int OracleImporter::importTextSpoiler(CardSet *set, const QVariant &data)
|
|||
cardText = map.contains("text") ? map.value("text").toString() : QString("");
|
||||
cardId = map.contains("multiverseid") ? map.value("multiverseid").toInt() : 0;
|
||||
cardLoyalty = map.contains("loyalty") ? map.value("loyalty").toInt() : 0;
|
||||
cardIsToken = map.value("layout") == "token";
|
||||
}
|
||||
|
||||
CardInfo *card = addCard(set->getShortName(), cardName, false, cardId, cardCost, cardType, cardPT, cardLoyalty, cardText.split("\n"));
|
||||
CardInfo *card = addCard(set->getShortName(), cardName, cardIsToken, cardId, cardCost, cardType, cardPT, cardLoyalty, cardText.split("\n"));
|
||||
|
||||
if (!set->contains(card)) {
|
||||
card->addToSet(set);
|
||||
|
|
Loading…
Reference in a new issue