Extract the xml parser from carddatabase (#3223)
This commit is contained in:
parent
9727699e26
commit
a7f4aace9c
10 changed files with 510 additions and 384 deletions
|
@ -120,6 +120,7 @@ SET(cockatrice_SOURCES
|
||||||
src/userconnection_information.cpp
|
src/userconnection_information.cpp
|
||||||
src/spoilerbackgroundupdater.cpp
|
src/spoilerbackgroundupdater.cpp
|
||||||
src/handle_public_servers.cpp
|
src/handle_public_servers.cpp
|
||||||
|
src/carddbparser/cockatricexml3.cpp
|
||||||
${VERSION_STRING_CPP}
|
${VERSION_STRING_CPP}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "carddatabase.h"
|
#include "carddatabase.h"
|
||||||
|
#include "carddbparser/cockatricexml3.h"
|
||||||
#include "pictureloader.h"
|
#include "pictureloader.h"
|
||||||
#include "settingscache.h"
|
#include "settingscache.h"
|
||||||
#include "spoilerbackgroundupdater.h"
|
#include "spoilerbackgroundupdater.h"
|
||||||
|
@ -10,26 +11,8 @@
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
const int CardDatabase::versionNeeded = 3;
|
|
||||||
const char *CardDatabase::TOKENS_SETNAME = "TK";
|
const char *CardDatabase::TOKENS_SETNAME = "TK";
|
||||||
|
|
||||||
static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardSetPtr &set)
|
|
||||||
{
|
|
||||||
if (set.isNull()) {
|
|
||||||
qDebug() << "&operator<< set is nullptr";
|
|
||||||
return xml;
|
|
||||||
}
|
|
||||||
|
|
||||||
xml.writeStartElement("set");
|
|
||||||
xml.writeTextElement("name", set->getShortName());
|
|
||||||
xml.writeTextElement("longname", set->getLongName());
|
|
||||||
xml.writeTextElement("settype", set->getSetType());
|
|
||||||
xml.writeTextElement("releasedate", set->getReleaseDate().toString(Qt::ISODate));
|
|
||||||
xml.writeEndElement();
|
|
||||||
|
|
||||||
return xml;
|
|
||||||
}
|
|
||||||
|
|
||||||
CardSet::CardSet(const QString &_shortName,
|
CardSet::CardSet(const QString &_shortName,
|
||||||
const QString &_longName,
|
const QString &_longName,
|
||||||
const QString &_setType,
|
const QString &_setType,
|
||||||
|
@ -396,123 +379,25 @@ const QChar CardInfo::getColorChar() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfoPtr &info)
|
|
||||||
{
|
|
||||||
if (info.isNull()) {
|
|
||||||
qDebug() << "operator<< info is nullptr";
|
|
||||||
return xml;
|
|
||||||
}
|
|
||||||
|
|
||||||
xml.writeStartElement("card");
|
|
||||||
xml.writeTextElement("name", info->getName());
|
|
||||||
|
|
||||||
const SetList &sets = info->getSets();
|
|
||||||
QString tmpString;
|
|
||||||
QString tmpSet;
|
|
||||||
for (int i = 0; i < sets.size(); i++) {
|
|
||||||
xml.writeStartElement("set");
|
|
||||||
|
|
||||||
tmpSet = sets[i]->getShortName();
|
|
||||||
xml.writeAttribute("rarity", info->getRarity(tmpSet));
|
|
||||||
xml.writeAttribute("muId", QString::number(info->getMuId(tmpSet)));
|
|
||||||
|
|
||||||
tmpString = info->getCollectorNumber(tmpSet);
|
|
||||||
if (!tmpString.isEmpty()) {
|
|
||||||
xml.writeAttribute("num", info->getCollectorNumber(tmpSet));
|
|
||||||
}
|
|
||||||
|
|
||||||
tmpString = info->getCustomPicURL(tmpSet);
|
|
||||||
if (!tmpString.isEmpty()) {
|
|
||||||
xml.writeAttribute("picURL", tmpString);
|
|
||||||
}
|
|
||||||
|
|
||||||
xml.writeCharacters(tmpSet);
|
|
||||||
xml.writeEndElement();
|
|
||||||
}
|
|
||||||
const QStringList &colors = info->getColors();
|
|
||||||
for (int i = 0; i < colors.size(); i++) {
|
|
||||||
xml.writeTextElement("color", colors[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
const QList<CardRelation *> related = info->getRelatedCards();
|
|
||||||
for (auto i : related) {
|
|
||||||
xml.writeStartElement("related");
|
|
||||||
if (i->getDoesAttach()) {
|
|
||||||
xml.writeAttribute("attach", "attach");
|
|
||||||
}
|
|
||||||
if (i->getIsCreateAllExclusion()) {
|
|
||||||
xml.writeAttribute("exclude", "exclude");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i->getIsVariable()) {
|
|
||||||
if (1 == i->getDefaultCount()) {
|
|
||||||
xml.writeAttribute("count", "x");
|
|
||||||
} else {
|
|
||||||
xml.writeAttribute("count", "x=" + QString::number(i->getDefaultCount()));
|
|
||||||
}
|
|
||||||
} else if (1 != i->getDefaultCount()) {
|
|
||||||
xml.writeAttribute("count", QString::number(i->getDefaultCount()));
|
|
||||||
}
|
|
||||||
xml.writeCharacters(i->getName());
|
|
||||||
xml.writeEndElement();
|
|
||||||
}
|
|
||||||
const QList<CardRelation *> reverseRelated = info->getReverseRelatedCards();
|
|
||||||
for (auto i : reverseRelated) {
|
|
||||||
xml.writeStartElement("reverse-related");
|
|
||||||
if (i->getDoesAttach()) {
|
|
||||||
xml.writeAttribute("attach", "attach");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i->getIsCreateAllExclusion()) {
|
|
||||||
xml.writeAttribute("exclude", "exclude");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i->getIsVariable()) {
|
|
||||||
if (1 == i->getDefaultCount()) {
|
|
||||||
xml.writeAttribute("count", "x");
|
|
||||||
} else {
|
|
||||||
xml.writeAttribute("count", "x=" + QString::number(i->getDefaultCount()));
|
|
||||||
}
|
|
||||||
} else if (1 != i->getDefaultCount()) {
|
|
||||||
xml.writeAttribute("count", QString::number(i->getDefaultCount()));
|
|
||||||
}
|
|
||||||
xml.writeCharacters(i->getName());
|
|
||||||
xml.writeEndElement();
|
|
||||||
}
|
|
||||||
xml.writeTextElement("manacost", info->getManaCost());
|
|
||||||
xml.writeTextElement("cmc", info->getCmc());
|
|
||||||
xml.writeTextElement("type", info->getCardType());
|
|
||||||
if (!info->getPowTough().isEmpty()) {
|
|
||||||
xml.writeTextElement("pt", info->getPowTough());
|
|
||||||
}
|
|
||||||
xml.writeTextElement("tablerow", QString::number(info->getTableRow()));
|
|
||||||
xml.writeTextElement("text", info->getText());
|
|
||||||
if (info->getMainCardType() == "Planeswalker") {
|
|
||||||
xml.writeTextElement("loyalty", info->getLoyalty());
|
|
||||||
}
|
|
||||||
if (info->getCipt()) {
|
|
||||||
xml.writeTextElement("cipt", "1");
|
|
||||||
}
|
|
||||||
if (info->getIsToken()) {
|
|
||||||
xml.writeTextElement("token", "1");
|
|
||||||
}
|
|
||||||
if (info->getUpsideDownArt()) {
|
|
||||||
xml.writeTextElement("upsidedown", "1");
|
|
||||||
}
|
|
||||||
|
|
||||||
xml.writeEndElement(); // card
|
|
||||||
|
|
||||||
return xml;
|
|
||||||
}
|
|
||||||
|
|
||||||
CardDatabase::CardDatabase(QObject *parent) : QObject(parent), loadStatus(NotLoaded)
|
CardDatabase::CardDatabase(QObject *parent) : QObject(parent), loadStatus(NotLoaded)
|
||||||
{
|
{
|
||||||
qRegisterMetaType<CardInfoPtr>("CardInfoPtr");
|
qRegisterMetaType<CardInfoPtr>("CardInfoPtr");
|
||||||
|
qRegisterMetaType<CardInfoPtr>("CardSetPtr");
|
||||||
|
|
||||||
|
// add new parsers here
|
||||||
|
availableParsers << new CockatriceXml3Parser;
|
||||||
|
|
||||||
|
for (auto &parser : availableParsers) {
|
||||||
|
connect(parser, SIGNAL(addCard(CardInfoPtr)), this, SLOT(addCard(CardInfoPtr)));
|
||||||
|
connect(parser, SIGNAL(addSet(CardSetPtr)), this, SLOT(addSet(CardSetPtr)));
|
||||||
|
}
|
||||||
|
|
||||||
connect(settingsCache, SIGNAL(cardDatabasePathChanged()), this, SLOT(loadCardDatabases()));
|
connect(settingsCache, SIGNAL(cardDatabasePathChanged()), this, SLOT(loadCardDatabases()));
|
||||||
}
|
}
|
||||||
|
|
||||||
CardDatabase::~CardDatabase()
|
CardDatabase::~CardDatabase()
|
||||||
{
|
{
|
||||||
|
qDeleteAll(availableParsers);
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -609,6 +494,11 @@ CardSetPtr CardDatabase::getSet(const QString &setName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CardDatabase::addSet(CardSetPtr set)
|
||||||
|
{
|
||||||
|
sets.insert(set->getShortName(), set);
|
||||||
|
}
|
||||||
|
|
||||||
SetList CardDatabase::getSetList() const
|
SetList CardDatabase::getSetList() const
|
||||||
{
|
{
|
||||||
SetList result;
|
SetList result;
|
||||||
|
@ -620,159 +510,6 @@ SetList CardDatabase::getSetList() const
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardDatabase::loadSetsFromXml(QXmlStreamReader &xml)
|
|
||||||
{
|
|
||||||
while (!xml.atEnd()) {
|
|
||||||
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xml.name() == "set") {
|
|
||||||
QString shortName, longName, setType;
|
|
||||||
QDate releaseDate;
|
|
||||||
while (!xml.atEnd()) {
|
|
||||||
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xml.name() == "name") {
|
|
||||||
shortName = xml.readElementText();
|
|
||||||
} else if (xml.name() == "longname") {
|
|
||||||
longName = xml.readElementText();
|
|
||||||
} else if (xml.name() == "settype") {
|
|
||||||
setType = xml.readElementText();
|
|
||||||
} else if (xml.name() == "releasedate") {
|
|
||||||
releaseDate = QDate::fromString(xml.readElementText(), Qt::ISODate);
|
|
||||||
} else if (xml.name() != "") {
|
|
||||||
qDebug() << "[XMLReader] Unknown set property" << xml.name() << ", trying to continue anyway";
|
|
||||||
xml.skipCurrentElement();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CardSetPtr newSet = getSet(shortName);
|
|
||||||
newSet->setLongName(longName);
|
|
||||||
newSet->setSetType(setType);
|
|
||||||
newSet->setReleaseDate(releaseDate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardDatabase::loadCardsFromXml(QXmlStreamReader &xml)
|
|
||||||
{
|
|
||||||
while (!xml.atEnd()) {
|
|
||||||
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xml.name() == "card") {
|
|
||||||
QString name, manacost, cmc, type, pt, text, loyalty;
|
|
||||||
QStringList colors;
|
|
||||||
QList<CardRelation *> relatedCards, reverseRelatedCards;
|
|
||||||
QStringMap customPicURLs;
|
|
||||||
MuidMap muids;
|
|
||||||
QStringMap collectorNumbers, rarities;
|
|
||||||
SetList sets;
|
|
||||||
int tableRow = 0;
|
|
||||||
bool cipt = false;
|
|
||||||
bool isToken = false;
|
|
||||||
bool upsideDown = false;
|
|
||||||
while (!xml.atEnd()) {
|
|
||||||
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xml.name() == "name") {
|
|
||||||
name = xml.readElementText();
|
|
||||||
} else if (xml.name() == "manacost") {
|
|
||||||
manacost = xml.readElementText();
|
|
||||||
} else if (xml.name() == "cmc") {
|
|
||||||
cmc = xml.readElementText();
|
|
||||||
} else if (xml.name() == "type") {
|
|
||||||
type = xml.readElementText();
|
|
||||||
} else if (xml.name() == "pt") {
|
|
||||||
pt = xml.readElementText();
|
|
||||||
} else if (xml.name() == "text") {
|
|
||||||
text = xml.readElementText();
|
|
||||||
} else if (xml.name() == "set") {
|
|
||||||
QXmlStreamAttributes attrs = xml.attributes();
|
|
||||||
QString setName = xml.readElementText();
|
|
||||||
sets.append(getSet(setName));
|
|
||||||
if (attrs.hasAttribute("muId")) {
|
|
||||||
muids[setName] = attrs.value("muId").toString().toInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attrs.hasAttribute("picURL")) {
|
|
||||||
customPicURLs[setName] = attrs.value("picURL").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attrs.hasAttribute("num")) {
|
|
||||||
collectorNumbers[setName] = attrs.value("num").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attrs.hasAttribute("rarity")) {
|
|
||||||
rarities[setName] = attrs.value("rarity").toString();
|
|
||||||
}
|
|
||||||
} else if (xml.name() == "color") {
|
|
||||||
colors << xml.readElementText();
|
|
||||||
} else if (xml.name() == "related" || xml.name() == "reverse-related") {
|
|
||||||
bool attach = false;
|
|
||||||
bool exclude = false;
|
|
||||||
bool variable = false;
|
|
||||||
int count = 1;
|
|
||||||
QXmlStreamAttributes attrs = xml.attributes();
|
|
||||||
QString cardName = xml.readElementText();
|
|
||||||
if (attrs.hasAttribute("count")) {
|
|
||||||
if (attrs.value("count").toString().indexOf("x=") == 0) {
|
|
||||||
variable = true;
|
|
||||||
count = attrs.value("count").toString().remove(0, 2).toInt();
|
|
||||||
} else if (attrs.value("count").toString().indexOf("x") == 0) {
|
|
||||||
variable = true;
|
|
||||||
} else {
|
|
||||||
count = attrs.value("count").toString().toInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count < 1) {
|
|
||||||
count = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attrs.hasAttribute("attach")) {
|
|
||||||
attach = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attrs.hasAttribute("exclude")) {
|
|
||||||
exclude = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto *relation = new CardRelation(cardName, attach, exclude, variable, count);
|
|
||||||
if (xml.name() == "reverse-related") {
|
|
||||||
reverseRelatedCards << relation;
|
|
||||||
} else {
|
|
||||||
relatedCards << relation;
|
|
||||||
}
|
|
||||||
} else if (xml.name() == "tablerow") {
|
|
||||||
tableRow = xml.readElementText().toInt();
|
|
||||||
} else if (xml.name() == "cipt") {
|
|
||||||
cipt = (xml.readElementText() == "1");
|
|
||||||
} else if (xml.name() == "upsidedown") {
|
|
||||||
upsideDown = (xml.readElementText() == "1");
|
|
||||||
} else if (xml.name() == "loyalty") {
|
|
||||||
loyalty = xml.readElementText();
|
|
||||||
} else if (xml.name() == "token") {
|
|
||||||
isToken = static_cast<bool>(xml.readElementText().toInt());
|
|
||||||
} else if (xml.name() != "") {
|
|
||||||
qDebug() << "[XMLReader] Unknown card property" << xml.name() << ", trying to continue anyway";
|
|
||||||
xml.skipCurrentElement();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addCard(CardInfo::newInstance(name, isToken, manacost, cmc, type, pt, text, colors, relatedCards,
|
|
||||||
reverseRelatedCards, upsideDown, loyalty, cipt, tableRow, sets, customPicURLs,
|
|
||||||
muids, collectorNumbers, rarities));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CardInfoPtr CardDatabase::getCardFromMap(const CardNameMap &cardMap, const QString &cardName) const
|
CardInfoPtr CardDatabase::getCardFromMap(const CardNameMap &cardMap, const QString &cardName) const
|
||||||
{
|
{
|
||||||
if (cardMap.contains(cardName))
|
if (cardMap.contains(cardName))
|
||||||
|
@ -789,81 +526,16 @@ LoadStatus CardDatabase::loadFromFile(const QString &fileName)
|
||||||
return FileError;
|
return FileError;
|
||||||
}
|
}
|
||||||
|
|
||||||
QXmlStreamReader xml(&file);
|
for (auto parser : availableParsers) {
|
||||||
while (!xml.atEnd()) {
|
file.reset();
|
||||||
if (xml.readNext() == QXmlStreamReader::StartElement) {
|
if (parser->getCanParseFile(fileName, file)) {
|
||||||
if (xml.name() != "cockatrice_carddatabase") {
|
file.reset();
|
||||||
return Invalid;
|
parser->parseFile(file);
|
||||||
}
|
return Ok;
|
||||||
|
|
||||||
int version = xml.attributes().value("version").toString().toInt();
|
|
||||||
if (version < versionNeeded) {
|
|
||||||
qDebug() << "[XMLReader] Version too old: " << version;
|
|
||||||
return VersionTooOld;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!xml.atEnd()) {
|
|
||||||
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xml.name() == "sets") {
|
|
||||||
loadSetsFromXml(xml);
|
|
||||||
} else if (xml.name() == "cards") {
|
|
||||||
loadCardsFromXml(xml);
|
|
||||||
} else if (xml.name() != "") {
|
|
||||||
qDebug() << "[XMLReader] Unknown item" << xml.name() << ", trying to continue anyway";
|
|
||||||
xml.skipCurrentElement();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cards.isEmpty()) {
|
return Invalid;
|
||||||
return NoCards;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CardDatabase::saveToFile(const QString &fileName, bool tokens)
|
|
||||||
{
|
|
||||||
QFile file(fileName);
|
|
||||||
if (!file.open(QIODevice::WriteOnly)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QXmlStreamWriter xml(&file);
|
|
||||||
|
|
||||||
xml.setAutoFormatting(true);
|
|
||||||
xml.writeStartDocument();
|
|
||||||
xml.writeStartElement("cockatrice_carddatabase");
|
|
||||||
xml.writeAttribute("version", QString::number(versionNeeded));
|
|
||||||
|
|
||||||
if (!tokens) {
|
|
||||||
xml.writeStartElement("sets");
|
|
||||||
QHashIterator<QString, CardSetPtr> setIterator(sets);
|
|
||||||
while (setIterator.hasNext()) {
|
|
||||||
xml << setIterator.next().value();
|
|
||||||
}
|
|
||||||
|
|
||||||
xml.writeEndElement(); // sets
|
|
||||||
}
|
|
||||||
|
|
||||||
xml.writeStartElement("cards");
|
|
||||||
QHashIterator<QString, CardInfoPtr> cardIterator(cards);
|
|
||||||
while (cardIterator.hasNext()) {
|
|
||||||
CardInfoPtr card = cardIterator.next().value();
|
|
||||||
if (tokens == card->getIsToken()) {
|
|
||||||
xml << card;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
xml.writeEndElement(); // cards
|
|
||||||
|
|
||||||
xml.writeEndElement(); // cockatrice_carddatabase
|
|
||||||
xml.writeEndDocument();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadStatus CardDatabase::loadCardDatabase(const QString &path)
|
LoadStatus CardDatabase::loadCardDatabase(const QString &path)
|
||||||
|
@ -1031,33 +703,20 @@ void CardDatabase::notifyEnabledSetsChanged()
|
||||||
|
|
||||||
bool CardDatabase::saveCustomTokensToFile()
|
bool CardDatabase::saveCustomTokensToFile()
|
||||||
{
|
{
|
||||||
CardSetPtr customTokensSet = getSet(CardDatabase::TOKENS_SETNAME);
|
|
||||||
QString fileName = settingsCache->getCustomCardDatabasePath() + "/" + CardDatabase::TOKENS_SETNAME + ".xml";
|
QString fileName = settingsCache->getCustomCardDatabasePath() + "/" + CardDatabase::TOKENS_SETNAME + ".xml";
|
||||||
QFile file(fileName);
|
|
||||||
if (!file.open(QIODevice::WriteOnly)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QXmlStreamWriter xml(&file);
|
SetNameMap tmpSets;
|
||||||
|
CardSetPtr customTokensSet = getSet(CardDatabase::TOKENS_SETNAME);
|
||||||
|
tmpSets.insert(CardDatabase::TOKENS_SETNAME, customTokensSet);
|
||||||
|
|
||||||
xml.setAutoFormatting(true);
|
CardNameMap tmpCards;
|
||||||
xml.writeStartDocument();
|
for (CardInfoPtr card : cards) {
|
||||||
xml.writeStartElement("cockatrice_carddatabase");
|
|
||||||
xml.writeAttribute("version", QString::number(versionNeeded));
|
|
||||||
|
|
||||||
xml.writeStartElement("cards");
|
|
||||||
QHashIterator<QString, CardInfoPtr> cardIterator(cards);
|
|
||||||
while (cardIterator.hasNext()) {
|
|
||||||
CardInfoPtr card = cardIterator.next().value();
|
|
||||||
if (card->getSets().contains(customTokensSet)) {
|
if (card->getSets().contains(customTokensSet)) {
|
||||||
xml << card;
|
tmpCards.insert(card->getName(), card);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
xml.writeEndElement(); // cards
|
|
||||||
|
|
||||||
xml.writeEndElement(); // cockatrice_carddatabase
|
|
||||||
xml.writeEndDocument();
|
|
||||||
|
|
||||||
|
availableParsers.first()->saveToFile(tmpSets, tmpCards, fileName);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,19 +2,20 @@
|
||||||
#define CARDDATABASE_H
|
#define CARDDATABASE_H
|
||||||
|
|
||||||
#include <QBasicMutex>
|
#include <QBasicMutex>
|
||||||
#include <QDataStream>
|
|
||||||
#include <QDate>
|
#include <QDate>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QMetaType>
|
#include <QMetaType>
|
||||||
#include <QPixmap>
|
#include <QSharedPointer>
|
||||||
#include <QXmlStreamReader>
|
#include <QStringList>
|
||||||
|
#include <QVector>
|
||||||
|
|
||||||
class CardDatabase;
|
class CardDatabase;
|
||||||
class CardInfo;
|
class CardInfo;
|
||||||
class CardSet;
|
class CardSet;
|
||||||
class CardRelation;
|
class CardRelation;
|
||||||
|
class ICardDatabaseParser;
|
||||||
|
|
||||||
typedef QMap<QString, QString> QStringMap;
|
typedef QMap<QString, QString> QStringMap;
|
||||||
typedef QMap<QString, int> MuidMap;
|
typedef QMap<QString, int> MuidMap;
|
||||||
|
@ -58,15 +59,15 @@ public:
|
||||||
{
|
{
|
||||||
return releaseDate;
|
return releaseDate;
|
||||||
}
|
}
|
||||||
void setLongName(QString &_longName)
|
void setLongName(const QString &_longName)
|
||||||
{
|
{
|
||||||
longName = _longName;
|
longName = _longName;
|
||||||
}
|
}
|
||||||
void setSetType(QString &_setType)
|
void setSetType(const QString &_setType)
|
||||||
{
|
{
|
||||||
setType = _setType;
|
setType = _setType;
|
||||||
}
|
}
|
||||||
void setReleaseDate(QDate &_releaseDate)
|
void setReleaseDate(const QDate &_releaseDate)
|
||||||
{
|
{
|
||||||
releaseDate = _releaseDate;
|
releaseDate = _releaseDate;
|
||||||
}
|
}
|
||||||
|
@ -398,11 +399,9 @@ protected:
|
||||||
|
|
||||||
LoadStatus loadStatus;
|
LoadStatus loadStatus;
|
||||||
|
|
||||||
private:
|
QVector<ICardDatabaseParser *> availableParsers;
|
||||||
static const int versionNeeded;
|
|
||||||
void loadCardsFromXml(QXmlStreamReader &xml);
|
|
||||||
void loadSetsFromXml(QXmlStreamReader &xml);
|
|
||||||
|
|
||||||
|
private:
|
||||||
CardInfoPtr getCardFromMap(const CardNameMap &cardMap, const QString &cardName) const;
|
CardInfoPtr getCardFromMap(const CardNameMap &cardMap, const QString &cardName) const;
|
||||||
void checkUnknownSets();
|
void checkUnknownSets();
|
||||||
void refreshCachedReverseRelatedCards();
|
void refreshCachedReverseRelatedCards();
|
||||||
|
@ -417,7 +416,6 @@ public:
|
||||||
explicit CardDatabase(QObject *parent = nullptr);
|
explicit CardDatabase(QObject *parent = nullptr);
|
||||||
~CardDatabase() override;
|
~CardDatabase() override;
|
||||||
void clear();
|
void clear();
|
||||||
void addCard(CardInfoPtr card);
|
|
||||||
void removeCard(CardInfoPtr card);
|
void removeCard(CardInfoPtr card);
|
||||||
CardInfoPtr getCard(const QString &cardName) const;
|
CardInfoPtr getCard(const QString &cardName) const;
|
||||||
QList<CardInfoPtr> getCards(const QStringList &cardNames) const;
|
QList<CardInfoPtr> getCards(const QStringList &cardNames) const;
|
||||||
|
@ -435,7 +433,6 @@ public:
|
||||||
}
|
}
|
||||||
SetList getSetList() const;
|
SetList getSetList() const;
|
||||||
LoadStatus loadFromFile(const QString &fileName);
|
LoadStatus loadFromFile(const QString &fileName);
|
||||||
bool saveToFile(const QString &fileName, bool tokens = false);
|
|
||||||
bool saveCustomTokensToFile();
|
bool saveCustomTokensToFile();
|
||||||
QStringList getAllColors() const;
|
QStringList getAllColors() const;
|
||||||
QStringList getAllMainCardTypes() const;
|
QStringList getAllMainCardTypes() const;
|
||||||
|
@ -449,6 +446,8 @@ public:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
LoadStatus loadCardDatabases();
|
LoadStatus loadCardDatabases();
|
||||||
|
void addCard(CardInfoPtr card);
|
||||||
|
void addSet(CardSetPtr set);
|
||||||
private slots:
|
private slots:
|
||||||
LoadStatus loadCardDatabase(const QString &path);
|
LoadStatus loadCardDatabase(const QString &path);
|
||||||
signals:
|
signals:
|
||||||
|
|
24
cockatrice/src/carddbparser/carddatabaseparser.h
Normal file
24
cockatrice/src/carddbparser/carddatabaseparser.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef CARDDATABASE_PARSER_H
|
||||||
|
#define CARDDATABASE_PARSER_H
|
||||||
|
|
||||||
|
#include <QIODevice>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
#include "../carddatabase.h"
|
||||||
|
|
||||||
|
class ICardDatabaseParser : public QObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~ICardDatabaseParser()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual bool getCanParseFile(const QString &name, QIODevice &device) = 0;
|
||||||
|
virtual void parseFile(QIODevice &device) = 0;
|
||||||
|
virtual bool saveToFile(SetNameMap sets, CardNameMap cards, const QString &fileName) = 0;
|
||||||
|
signals:
|
||||||
|
virtual void addCard(CardInfoPtr card) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_INTERFACE(ICardDatabaseParser, "ICardDatabaseParser")
|
||||||
|
|
||||||
|
#endif
|
396
cockatrice/src/carddbparser/cockatricexml3.cpp
Normal file
396
cockatrice/src/carddbparser/cockatricexml3.cpp
Normal file
|
@ -0,0 +1,396 @@
|
||||||
|
#include "cockatricexml3.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QXmlStreamReader>
|
||||||
|
|
||||||
|
#define COCKATRICE_XML3_TAGNAME "cockatrice_carddatabase"
|
||||||
|
#define COCKATRICE_XML3_TAGVER 3
|
||||||
|
|
||||||
|
bool CockatriceXml3Parser::getCanParseFile(const QString &fileName, QIODevice &device)
|
||||||
|
{
|
||||||
|
qDebug() << "[CockatriceXml3Parser] Trying to parse: " << fileName;
|
||||||
|
|
||||||
|
if (!fileName.endsWith(".xml", Qt::CaseInsensitive)) {
|
||||||
|
qDebug() << "[CockatriceXml3Parser] Parsing failed: wrong extension";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QXmlStreamReader xml(&device);
|
||||||
|
while (!xml.atEnd()) {
|
||||||
|
if (xml.readNext() == QXmlStreamReader::StartElement) {
|
||||||
|
if (xml.name() == COCKATRICE_XML3_TAGNAME) {
|
||||||
|
int version = xml.attributes().value("version").toString().toInt();
|
||||||
|
if (version == COCKATRICE_XML3_TAGVER) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
qDebug() << "[CockatriceXml3Parser] Parsing failed: wrong version" << version;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
qDebug() << "[CockatriceXml3Parser] Parsing failed: wrong element tag" << xml.name();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CockatriceXml3Parser::parseFile(QIODevice &device)
|
||||||
|
{
|
||||||
|
QXmlStreamReader xml(&device);
|
||||||
|
while (!xml.atEnd()) {
|
||||||
|
if (xml.readNext() == QXmlStreamReader::StartElement) {
|
||||||
|
while (!xml.atEnd()) {
|
||||||
|
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xml.name() == "sets") {
|
||||||
|
loadSetsFromXml(xml);
|
||||||
|
} else if (xml.name() == "cards") {
|
||||||
|
loadCardsFromXml(xml);
|
||||||
|
} else if (xml.name() != "") {
|
||||||
|
qDebug() << "[CockatriceXml3Parser] Unknown item" << xml.name() << ", trying to continue anyway";
|
||||||
|
xml.skipCurrentElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CardSetPtr CockatriceXml3Parser::internalAddSet(const QString &setName,
|
||||||
|
const QString &longName,
|
||||||
|
const QString &setType,
|
||||||
|
const QDate &releaseDate)
|
||||||
|
{
|
||||||
|
if (sets.contains(setName)) {
|
||||||
|
return sets.value(setName);
|
||||||
|
}
|
||||||
|
|
||||||
|
CardSetPtr newSet = CardSet::newInstance(setName);
|
||||||
|
newSet->setLongName(longName);
|
||||||
|
newSet->setSetType(setType);
|
||||||
|
newSet->setReleaseDate(releaseDate);
|
||||||
|
|
||||||
|
sets.insert(setName, newSet);
|
||||||
|
emit addSet(newSet);
|
||||||
|
return newSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CockatriceXml3Parser::loadSetsFromXml(QXmlStreamReader &xml)
|
||||||
|
{
|
||||||
|
while (!xml.atEnd()) {
|
||||||
|
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xml.name() == "set") {
|
||||||
|
QString shortName, longName, setType;
|
||||||
|
QDate releaseDate;
|
||||||
|
while (!xml.atEnd()) {
|
||||||
|
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xml.name() == "name") {
|
||||||
|
shortName = xml.readElementText();
|
||||||
|
} else if (xml.name() == "longname") {
|
||||||
|
longName = xml.readElementText();
|
||||||
|
} else if (xml.name() == "settype") {
|
||||||
|
setType = xml.readElementText();
|
||||||
|
} else if (xml.name() == "releasedate") {
|
||||||
|
releaseDate = QDate::fromString(xml.readElementText(), Qt::ISODate);
|
||||||
|
} else if (xml.name() != "") {
|
||||||
|
qDebug() << "[CockatriceXml3Parser] Unknown set property" << xml.name()
|
||||||
|
<< ", trying to continue anyway";
|
||||||
|
xml.skipCurrentElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internalAddSet(shortName, longName, setType, releaseDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CockatriceXml3Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
||||||
|
{
|
||||||
|
while (!xml.atEnd()) {
|
||||||
|
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xml.name() == "card") {
|
||||||
|
QString name, manacost, cmc, type, pt, text, loyalty;
|
||||||
|
QStringList colors;
|
||||||
|
QList<CardRelation *> relatedCards, reverseRelatedCards;
|
||||||
|
QStringMap customPicURLs;
|
||||||
|
MuidMap muids;
|
||||||
|
QStringMap collectorNumbers, rarities;
|
||||||
|
SetList sets;
|
||||||
|
int tableRow = 0;
|
||||||
|
bool cipt = false;
|
||||||
|
bool isToken = false;
|
||||||
|
bool upsideDown = false;
|
||||||
|
while (!xml.atEnd()) {
|
||||||
|
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xml.name() == "name") {
|
||||||
|
name = xml.readElementText();
|
||||||
|
} else if (xml.name() == "manacost") {
|
||||||
|
manacost = xml.readElementText();
|
||||||
|
} else if (xml.name() == "cmc") {
|
||||||
|
cmc = xml.readElementText();
|
||||||
|
} else if (xml.name() == "type") {
|
||||||
|
type = xml.readElementText();
|
||||||
|
} else if (xml.name() == "pt") {
|
||||||
|
pt = xml.readElementText();
|
||||||
|
} else if (xml.name() == "text") {
|
||||||
|
text = xml.readElementText();
|
||||||
|
} else if (xml.name() == "set") {
|
||||||
|
QXmlStreamAttributes attrs = xml.attributes();
|
||||||
|
QString setName = xml.readElementText();
|
||||||
|
sets.append(internalAddSet(setName));
|
||||||
|
if (attrs.hasAttribute("muId")) {
|
||||||
|
muids[setName] = attrs.value("muId").toString().toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attrs.hasAttribute("picURL")) {
|
||||||
|
customPicURLs[setName] = attrs.value("picURL").toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attrs.hasAttribute("num")) {
|
||||||
|
collectorNumbers[setName] = attrs.value("num").toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attrs.hasAttribute("rarity")) {
|
||||||
|
rarities[setName] = attrs.value("rarity").toString();
|
||||||
|
}
|
||||||
|
} else if (xml.name() == "color") {
|
||||||
|
colors << xml.readElementText();
|
||||||
|
} else if (xml.name() == "related" || xml.name() == "reverse-related") {
|
||||||
|
bool attach = false;
|
||||||
|
bool exclude = false;
|
||||||
|
bool variable = false;
|
||||||
|
int count = 1;
|
||||||
|
QXmlStreamAttributes attrs = xml.attributes();
|
||||||
|
QString cardName = xml.readElementText();
|
||||||
|
if (attrs.hasAttribute("count")) {
|
||||||
|
if (attrs.value("count").toString().indexOf("x=") == 0) {
|
||||||
|
variable = true;
|
||||||
|
count = attrs.value("count").toString().remove(0, 2).toInt();
|
||||||
|
} else if (attrs.value("count").toString().indexOf("x") == 0) {
|
||||||
|
variable = true;
|
||||||
|
} else {
|
||||||
|
count = attrs.value("count").toString().toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count < 1) {
|
||||||
|
count = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attrs.hasAttribute("attach")) {
|
||||||
|
attach = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attrs.hasAttribute("exclude")) {
|
||||||
|
exclude = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto *relation = new CardRelation(cardName, attach, exclude, variable, count);
|
||||||
|
if (xml.name() == "reverse-related") {
|
||||||
|
reverseRelatedCards << relation;
|
||||||
|
} else {
|
||||||
|
relatedCards << relation;
|
||||||
|
}
|
||||||
|
} else if (xml.name() == "tablerow") {
|
||||||
|
tableRow = xml.readElementText().toInt();
|
||||||
|
} else if (xml.name() == "cipt") {
|
||||||
|
cipt = (xml.readElementText() == "1");
|
||||||
|
} else if (xml.name() == "upsidedown") {
|
||||||
|
upsideDown = (xml.readElementText() == "1");
|
||||||
|
} else if (xml.name() == "loyalty") {
|
||||||
|
loyalty = xml.readElementText();
|
||||||
|
} else if (xml.name() == "token") {
|
||||||
|
isToken = static_cast<bool>(xml.readElementText().toInt());
|
||||||
|
} else if (xml.name() != "") {
|
||||||
|
qDebug() << "[CockatriceXml3Parser] Unknown card property" << xml.name()
|
||||||
|
<< ", trying to continue anyway";
|
||||||
|
xml.skipCurrentElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CardInfoPtr newCard = CardInfo::newInstance(
|
||||||
|
name, isToken, manacost, cmc, type, pt, text, colors, relatedCards, reverseRelatedCards, upsideDown,
|
||||||
|
loyalty, cipt, tableRow, sets, customPicURLs, muids, collectorNumbers, rarities);
|
||||||
|
emit addCard(newCard);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardSetPtr &set)
|
||||||
|
{
|
||||||
|
if (set.isNull()) {
|
||||||
|
qDebug() << "&operator<< set is nullptr";
|
||||||
|
return xml;
|
||||||
|
}
|
||||||
|
|
||||||
|
xml.writeStartElement("set");
|
||||||
|
xml.writeTextElement("name", set->getShortName());
|
||||||
|
xml.writeTextElement("longname", set->getLongName());
|
||||||
|
xml.writeTextElement("settype", set->getSetType());
|
||||||
|
xml.writeTextElement("releasedate", set->getReleaseDate().toString(Qt::ISODate));
|
||||||
|
xml.writeEndElement();
|
||||||
|
|
||||||
|
return xml;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfoPtr &info)
|
||||||
|
{
|
||||||
|
if (info.isNull()) {
|
||||||
|
qDebug() << "operator<< info is nullptr";
|
||||||
|
return xml;
|
||||||
|
}
|
||||||
|
|
||||||
|
xml.writeStartElement("card");
|
||||||
|
xml.writeTextElement("name", info->getName());
|
||||||
|
|
||||||
|
const SetList &sets = info->getSets();
|
||||||
|
QString tmpString;
|
||||||
|
QString tmpSet;
|
||||||
|
for (int i = 0; i < sets.size(); i++) {
|
||||||
|
xml.writeStartElement("set");
|
||||||
|
|
||||||
|
tmpSet = sets[i]->getShortName();
|
||||||
|
xml.writeAttribute("rarity", info->getRarity(tmpSet));
|
||||||
|
xml.writeAttribute("muId", QString::number(info->getMuId(tmpSet)));
|
||||||
|
|
||||||
|
tmpString = info->getCollectorNumber(tmpSet);
|
||||||
|
if (!tmpString.isEmpty()) {
|
||||||
|
xml.writeAttribute("num", info->getCollectorNumber(tmpSet));
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpString = info->getCustomPicURL(tmpSet);
|
||||||
|
if (!tmpString.isEmpty()) {
|
||||||
|
xml.writeAttribute("picURL", tmpString);
|
||||||
|
}
|
||||||
|
|
||||||
|
xml.writeCharacters(tmpSet);
|
||||||
|
xml.writeEndElement();
|
||||||
|
}
|
||||||
|
const QStringList &colors = info->getColors();
|
||||||
|
for (int i = 0; i < colors.size(); i++) {
|
||||||
|
xml.writeTextElement("color", colors[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QList<CardRelation *> related = info->getRelatedCards();
|
||||||
|
for (auto i : related) {
|
||||||
|
xml.writeStartElement("related");
|
||||||
|
if (i->getDoesAttach()) {
|
||||||
|
xml.writeAttribute("attach", "attach");
|
||||||
|
}
|
||||||
|
if (i->getIsCreateAllExclusion()) {
|
||||||
|
xml.writeAttribute("exclude", "exclude");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i->getIsVariable()) {
|
||||||
|
if (1 == i->getDefaultCount()) {
|
||||||
|
xml.writeAttribute("count", "x");
|
||||||
|
} else {
|
||||||
|
xml.writeAttribute("count", "x=" + QString::number(i->getDefaultCount()));
|
||||||
|
}
|
||||||
|
} else if (1 != i->getDefaultCount()) {
|
||||||
|
xml.writeAttribute("count", QString::number(i->getDefaultCount()));
|
||||||
|
}
|
||||||
|
xml.writeCharacters(i->getName());
|
||||||
|
xml.writeEndElement();
|
||||||
|
}
|
||||||
|
const QList<CardRelation *> reverseRelated = info->getReverseRelatedCards();
|
||||||
|
for (auto i : reverseRelated) {
|
||||||
|
xml.writeStartElement("reverse-related");
|
||||||
|
if (i->getDoesAttach()) {
|
||||||
|
xml.writeAttribute("attach", "attach");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i->getIsCreateAllExclusion()) {
|
||||||
|
xml.writeAttribute("exclude", "exclude");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i->getIsVariable()) {
|
||||||
|
if (1 == i->getDefaultCount()) {
|
||||||
|
xml.writeAttribute("count", "x");
|
||||||
|
} else {
|
||||||
|
xml.writeAttribute("count", "x=" + QString::number(i->getDefaultCount()));
|
||||||
|
}
|
||||||
|
} else if (1 != i->getDefaultCount()) {
|
||||||
|
xml.writeAttribute("count", QString::number(i->getDefaultCount()));
|
||||||
|
}
|
||||||
|
xml.writeCharacters(i->getName());
|
||||||
|
xml.writeEndElement();
|
||||||
|
}
|
||||||
|
xml.writeTextElement("manacost", info->getManaCost());
|
||||||
|
xml.writeTextElement("cmc", info->getCmc());
|
||||||
|
xml.writeTextElement("type", info->getCardType());
|
||||||
|
if (!info->getPowTough().isEmpty()) {
|
||||||
|
xml.writeTextElement("pt", info->getPowTough());
|
||||||
|
}
|
||||||
|
xml.writeTextElement("tablerow", QString::number(info->getTableRow()));
|
||||||
|
xml.writeTextElement("text", info->getText());
|
||||||
|
if (info->getMainCardType() == "Planeswalker") {
|
||||||
|
xml.writeTextElement("loyalty", info->getLoyalty());
|
||||||
|
}
|
||||||
|
if (info->getCipt()) {
|
||||||
|
xml.writeTextElement("cipt", "1");
|
||||||
|
}
|
||||||
|
if (info->getIsToken()) {
|
||||||
|
xml.writeTextElement("token", "1");
|
||||||
|
}
|
||||||
|
if (info->getUpsideDownArt()) {
|
||||||
|
xml.writeTextElement("upsidedown", "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
xml.writeEndElement(); // card
|
||||||
|
|
||||||
|
return xml;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CockatriceXml3Parser::saveToFile(SetNameMap sets, CardNameMap cards, const QString &fileName)
|
||||||
|
{
|
||||||
|
QFile file(fileName);
|
||||||
|
if (!file.open(QIODevice::WriteOnly)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QXmlStreamWriter xml(&file);
|
||||||
|
|
||||||
|
xml.setAutoFormatting(true);
|
||||||
|
xml.writeStartDocument();
|
||||||
|
xml.writeStartElement(COCKATRICE_XML3_TAGNAME);
|
||||||
|
xml.writeAttribute("version", QString::number(COCKATRICE_XML3_TAGVER));
|
||||||
|
|
||||||
|
if (sets.count() > 0) {
|
||||||
|
xml.writeStartElement("sets");
|
||||||
|
for (CardSetPtr set : sets) {
|
||||||
|
xml << set;
|
||||||
|
}
|
||||||
|
xml.writeEndElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cards.count() > 0) {
|
||||||
|
xml.writeStartElement("cards");
|
||||||
|
for (CardInfoPtr card : cards) {
|
||||||
|
xml << card;
|
||||||
|
}
|
||||||
|
xml.writeEndElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
xml.writeEndElement(); // cockatrice_carddatabase
|
||||||
|
xml.writeEndDocument();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
36
cockatrice/src/carddbparser/cockatricexml3.h
Normal file
36
cockatrice/src/carddbparser/cockatricexml3.h
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#ifndef COCKATRICE_XML3_H
|
||||||
|
#define COCKATRICE_XML3_H
|
||||||
|
|
||||||
|
#include <QXmlStreamReader>
|
||||||
|
|
||||||
|
#include "carddatabaseparser.h"
|
||||||
|
|
||||||
|
class CockatriceXml3Parser : public ICardDatabaseParser
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_INTERFACES(ICardDatabaseParser)
|
||||||
|
public:
|
||||||
|
CockatriceXml3Parser() = default;
|
||||||
|
~CockatriceXml3Parser() = default;
|
||||||
|
bool getCanParseFile(const QString &name, QIODevice &device);
|
||||||
|
void parseFile(QIODevice &device);
|
||||||
|
bool saveToFile(SetNameMap sets, CardNameMap cards, const QString &fileName);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*
|
||||||
|
* A cached list of the available sets, needed to cross-reference sets from cards.
|
||||||
|
*/
|
||||||
|
SetNameMap sets;
|
||||||
|
|
||||||
|
CardSetPtr internalAddSet(const QString &setName,
|
||||||
|
const QString &longName = "",
|
||||||
|
const QString &setType = "",
|
||||||
|
const QDate &releaseDate = QDate());
|
||||||
|
void loadCardsFromXml(QXmlStreamReader &xml);
|
||||||
|
void loadSetsFromXml(QXmlStreamReader &xml);
|
||||||
|
signals:
|
||||||
|
void addCard(CardInfoPtr card);
|
||||||
|
void addSet(CardSetPtr set);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -13,6 +13,7 @@ SET(oracle_SOURCES
|
||||||
src/oracleimporter.cpp
|
src/oracleimporter.cpp
|
||||||
../cockatrice/src/carddatabase.cpp
|
../cockatrice/src/carddatabase.cpp
|
||||||
../cockatrice/src/pictureloader.cpp
|
../cockatrice/src/pictureloader.cpp
|
||||||
|
../cockatrice/src/carddbparser/cockatricexml3.cpp
|
||||||
../cockatrice/src/settingscache.cpp
|
../cockatrice/src/settingscache.cpp
|
||||||
../cockatrice/src/shortcutssettings.cpp
|
../cockatrice/src/shortcutssettings.cpp
|
||||||
../cockatrice/src/settings/carddatabasesettings.cpp
|
../cockatrice/src/settings/carddatabasesettings.cpp
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "oracleimporter.h"
|
#include "oracleimporter.h"
|
||||||
|
#include "carddbparser/cockatricexml3.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QtWidgets>
|
#include <QtWidgets>
|
||||||
|
@ -174,6 +175,7 @@ int OracleImporter::importTextSpoiler(CardSetPtr set, const QVariant &data)
|
||||||
|
|
||||||
QString layout = map.value("layout").toString();
|
QString layout = map.value("layout").toString();
|
||||||
|
|
||||||
|
// don't import tokens from the json file
|
||||||
if (layout == "token")
|
if (layout == "token")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -362,3 +364,9 @@ int OracleImporter::startImport()
|
||||||
// total number of sets
|
// total number of sets
|
||||||
return setIndex;
|
return setIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OracleImporter::saveToFile(const QString &fileName)
|
||||||
|
{
|
||||||
|
CockatriceXml3Parser parser;
|
||||||
|
return parser.saveToFile(sets, cards, fileName);
|
||||||
|
}
|
|
@ -81,6 +81,7 @@ public:
|
||||||
OracleImporter(const QString &_dataDir, QObject *parent = 0);
|
OracleImporter(const QString &_dataDir, QObject *parent = 0);
|
||||||
bool readSetsFromByteArray(const QByteArray &data);
|
bool readSetsFromByteArray(const QByteArray &data);
|
||||||
int startImport();
|
int startImport();
|
||||||
|
bool saveToFile(const QString &fileName);
|
||||||
int importTextSpoiler(CardSetPtr set, const QVariant &data);
|
int importTextSpoiler(CardSetPtr set, const QVariant &data);
|
||||||
QList<SetToDownload> &getSets()
|
QList<SetToDownload> &getSets()
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,6 +2,7 @@ ADD_DEFINITIONS("-DCARDDB_DATADIR=\"${CMAKE_CURRENT_SOURCE_DIR}/data/\"")
|
||||||
add_executable(carddatabase_test
|
add_executable(carddatabase_test
|
||||||
carddatabase_test.cpp
|
carddatabase_test.cpp
|
||||||
../../cockatrice/src/carddatabase.cpp
|
../../cockatrice/src/carddatabase.cpp
|
||||||
|
../../cockatrice/src/carddbparser/cockatricexml3.cpp
|
||||||
|
|
||||||
)
|
)
|
||||||
if(NOT GTEST_FOUND)
|
if(NOT GTEST_FOUND)
|
||||||
|
|
Loading…
Reference in a new issue