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);
|
QFile file(fileName);
|
||||||
file.open(QIODevice::ReadOnly);
|
file.open(QIODevice::ReadOnly);
|
||||||
if (!file.isOpen())
|
if (!file.isOpen())
|
||||||
return FileError;
|
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);
|
QXmlStreamReader xml(&file);
|
||||||
while (!xml.atEnd()) {
|
while (!xml.atEnd()) {
|
||||||
if (xml.readNext() == QXmlStreamReader::StartElement) {
|
if (xml.readNext() == QXmlStreamReader::StartElement) {
|
||||||
|
@ -738,8 +710,7 @@ bool CardDatabase::saveToFile(const QString &fileName, bool tokens)
|
||||||
QHashIterator<QString, CardInfo *> cardIterator(cardHash);
|
QHashIterator<QString, CardInfo *> cardIterator(cardHash);
|
||||||
while (cardIterator.hasNext()) {
|
while (cardIterator.hasNext()) {
|
||||||
CardInfo *card = cardIterator.next().value();
|
CardInfo *card = cardIterator.next().value();
|
||||||
if (card->getIsToken() == tokens)
|
xml << card;
|
||||||
xml << card;
|
|
||||||
}
|
}
|
||||||
xml.writeEndElement(); // cards
|
xml.writeEndElement(); // cards
|
||||||
|
|
||||||
|
@ -773,7 +744,7 @@ LoadStatus CardDatabase::loadCardDatabase(const QString &path, bool tokens)
|
||||||
{
|
{
|
||||||
LoadStatus tempLoadStatus = NotLoaded;
|
LoadStatus tempLoadStatus = NotLoaded;
|
||||||
if (!path.isEmpty())
|
if (!path.isEmpty())
|
||||||
tempLoadStatus = loadFromFile(path, tokens);
|
tempLoadStatus = loadFromFile(path);
|
||||||
|
|
||||||
if (tempLoadStatus == Ok) {
|
if (tempLoadStatus == Ok) {
|
||||||
SetList allSets;
|
SetList allSets;
|
||||||
|
|
|
@ -186,7 +186,7 @@ public:
|
||||||
CardSet *getSet(const QString &setName);
|
CardSet *getSet(const QString &setName);
|
||||||
QList<CardInfo *> getCardList() const { return cardHash.values(); }
|
QList<CardInfo *> getCardList() const { return cardHash.values(); }
|
||||||
SetList getSetList() const;
|
SetList getSetList() const;
|
||||||
LoadStatus loadFromFile(const QString &fileName, bool tokens = false);
|
LoadStatus loadFromFile(const QString &fileName);
|
||||||
bool saveToFile(const QString &fileName, bool tokens = false);
|
bool saveToFile(const QString &fileName, bool tokens = false);
|
||||||
QStringList getAllColors() const;
|
QStringList getAllColors() const;
|
||||||
QStringList getAllMainCardTypes() const;
|
QStringList getAllMainCardTypes() const;
|
||||||
|
|
|
@ -7,8 +7,10 @@
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
|
|
||||||
DeckStatsInterface::DeckStatsInterface(QObject *parent)
|
DeckStatsInterface::DeckStatsInterface(
|
||||||
: QObject(parent)
|
CardDatabase &_cardDatabase,
|
||||||
|
QObject *parent
|
||||||
|
) : QObject(parent), cardDatabase(_cardDatabase)
|
||||||
{
|
{
|
||||||
manager = new QNetworkAccessManager(this);
|
manager = new QNetworkAccessManager(this);
|
||||||
connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(queryFinished(QNetworkReply *)));
|
connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(queryFinished(QNetworkReply *)));
|
||||||
|
@ -42,7 +44,11 @@ void DeckStatsInterface::queryFinished(QNetworkReply *reply)
|
||||||
void DeckStatsInterface::analyzeDeck(DeckList *deck)
|
void DeckStatsInterface::analyzeDeck(DeckList *deck)
|
||||||
{
|
{
|
||||||
QUrl params;
|
QUrl params;
|
||||||
params.addQueryItem("deck", deck->writeToString_Plain());
|
|
||||||
|
DeckList deckWithoutTokens;
|
||||||
|
copyDeckWithoutTokens(*deck, deckWithoutTokens);
|
||||||
|
|
||||||
|
params.addQueryItem("deck", deckWithoutTokens.writeToString_Plain());
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
data.append(params.encodedQuery());
|
data.append(params.encodedQuery());
|
||||||
|
|
||||||
|
@ -51,3 +57,30 @@ void DeckStatsInterface::analyzeDeck(DeckList *deck)
|
||||||
|
|
||||||
manager->post(request, data);
|
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
|
#ifndef DECKSTATS_INTERFACE_H
|
||||||
#define DECKSTATS_INTERFACE_H
|
#define DECKSTATS_INTERFACE_H
|
||||||
|
|
||||||
|
#include "carddatabase.h"
|
||||||
|
#include "decklist.h"
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
class QNetworkAccessManager;
|
class QNetworkAccessManager;
|
||||||
|
@ -11,10 +13,20 @@ class DeckStatsInterface : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
QNetworkAccessManager *manager;
|
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:
|
private slots:
|
||||||
void queryFinished(QNetworkReply *reply);
|
void queryFinished(QNetworkReply *reply);
|
||||||
public:
|
public:
|
||||||
DeckStatsInterface(QObject *parent = 0);
|
DeckStatsInterface(CardDatabase &_cardDatabase, QObject *parent = 0);
|
||||||
void analyzeDeck(DeckList *deck);
|
void analyzeDeck(DeckList *deck);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -508,7 +508,10 @@ void TabDeckEditor::actPrintDeck()
|
||||||
|
|
||||||
void TabDeckEditor::actAnalyzeDeck()
|
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());
|
interface->analyzeDeck(deckModel->getDeckList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -579,16 +579,30 @@ bool DeckList::loadFromFile_Plain(QIODevice *device)
|
||||||
return loadFromStream_Plain(in);
|
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)
|
bool DeckList::saveToStream_Plain(QTextStream &out)
|
||||||
{
|
{
|
||||||
// Support for this is only possible if the internal structure doesn't get more complicated.
|
WriteToStream writeToStream(out);
|
||||||
for (int i = 0; i < root->size(); i++) {
|
forEachCard(writeToStream);
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -117,6 +117,7 @@ public:
|
||||||
QString getName() const { return name; }
|
QString getName() const { return name; }
|
||||||
void setName(const QString &_name) { name = _name; }
|
void setName(const QString &_name) { name = _name; }
|
||||||
float getPrice() const { return price; }
|
float getPrice() const { return price; }
|
||||||
|
|
||||||
void setPrice(const float _price) { price = _price; }
|
void setPrice(const float _price) { price = _price; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -169,6 +170,28 @@ public:
|
||||||
InnerDecklistNode *getRoot() const { return root; }
|
InnerDecklistNode *getRoot() const { return root; }
|
||||||
DecklistCardNode *addCard(const QString &cardName, const QString &zoneName);
|
DecklistCardNode *addCard(const QString &cardName, const QString &zoneName);
|
||||||
bool deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNode = 0);
|
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
|
#endif
|
||||||
|
|
|
@ -137,6 +137,7 @@ int OracleImporter::importTextSpoiler(CardSet *set, const QVariant &data)
|
||||||
QString cardText;
|
QString cardText;
|
||||||
int cardId;
|
int cardId;
|
||||||
int cardLoyalty;
|
int cardLoyalty;
|
||||||
|
bool cardIsToken = false;
|
||||||
QMap<int, QVariantMap> splitCards;
|
QMap<int, QVariantMap> splitCards;
|
||||||
|
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
|
@ -197,9 +198,10 @@ int OracleImporter::importTextSpoiler(CardSet *set, const QVariant &data)
|
||||||
cardText = map.contains("text") ? map.value("text").toString() : QString("");
|
cardText = map.contains("text") ? map.value("text").toString() : QString("");
|
||||||
cardId = map.contains("multiverseid") ? map.value("multiverseid").toInt() : 0;
|
cardId = map.contains("multiverseid") ? map.value("multiverseid").toInt() : 0;
|
||||||
cardLoyalty = map.contains("loyalty") ? map.value("loyalty").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)) {
|
if (!set->contains(card)) {
|
||||||
card->addToSet(set);
|
card->addToSet(set);
|
||||||
|
|
Loading…
Reference in a new issue