mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-07-18 16:32:16 -07:00
Refactor: split card_database into two files
This commit is contained in:
parent
6deca46c6e
commit
3c89f5c31a
9 changed files with 15 additions and 1531 deletions
|
|
@ -26,6 +26,7 @@ set(cockatrice_SOURCES
|
||||||
src/client/ui/widgets/cards/card_info_text_widget.cpp
|
src/client/ui/widgets/cards/card_info_text_widget.cpp
|
||||||
src/client/ui/widgets/cards/card_info_display_widget.cpp
|
src/client/ui/widgets/cards/card_info_display_widget.cpp
|
||||||
src/client/ui/widgets/cards/card_size_widget.cpp
|
src/client/ui/widgets/cards/card_size_widget.cpp
|
||||||
|
src/game/cards/card_info.cpp
|
||||||
src/game/cards/card_item.cpp
|
src/game/cards/card_item.cpp
|
||||||
src/game/cards/card_list.cpp
|
src/game/cards/card_list.cpp
|
||||||
src/game/zones/card_zone.cpp
|
src/game/zones/card_zone.cpp
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@
|
||||||
# cockatrice_xml.* = false
|
# cockatrice_xml.* = false
|
||||||
# cockatrice_xml.xml_3_parser = false
|
# cockatrice_xml.xml_3_parser = false
|
||||||
# cockatrice_xml.xml_4_parser = false
|
# cockatrice_xml.xml_4_parser = false
|
||||||
|
# card_info = false
|
||||||
# card_list = false
|
# card_list = false
|
||||||
|
|
||||||
# stack_zone = false
|
# stack_zone = false
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,8 @@
|
||||||
#include "card_database.h"
|
#include "card_database.h"
|
||||||
|
|
||||||
#include "../../client/network/spoiler_background_updater.h"
|
|
||||||
#include "../../client/ui/picture_loader/picture_loader.h"
|
#include "../../client/ui/picture_loader/picture_loader.h"
|
||||||
#include "../../settings/cache_settings.h"
|
#include "../../settings/cache_settings.h"
|
||||||
#include "../../utility/card_set_comparator.h"
|
#include "../../utility/card_set_comparator.h"
|
||||||
#include "../game_specific_terms.h"
|
|
||||||
#include "./card_database_parser/cockatrice_xml_3.h"
|
#include "./card_database_parser/cockatrice_xml_3.h"
|
||||||
#include "./card_database_parser/cockatrice_xml_4.h"
|
#include "./card_database_parser/cockatrice_xml_4.h"
|
||||||
|
|
||||||
|
|
@ -20,351 +18,6 @@
|
||||||
|
|
||||||
const char *CardDatabase::TOKENS_SETNAME = "TK";
|
const char *CardDatabase::TOKENS_SETNAME = "TK";
|
||||||
|
|
||||||
CardSet::CardSet(const QString &_shortName,
|
|
||||||
const QString &_longName,
|
|
||||||
const QString &_setType,
|
|
||||||
const QDate &_releaseDate,
|
|
||||||
const CardSet::Priority _priority)
|
|
||||||
: shortName(_shortName), longName(_longName), releaseDate(_releaseDate), setType(_setType), priority(_priority)
|
|
||||||
{
|
|
||||||
loadSetOptions();
|
|
||||||
}
|
|
||||||
|
|
||||||
CardSetPtr CardSet::newInstance(const QString &_shortName,
|
|
||||||
const QString &_longName,
|
|
||||||
const QString &_setType,
|
|
||||||
const QDate &_releaseDate,
|
|
||||||
const Priority _priority)
|
|
||||||
{
|
|
||||||
CardSetPtr ptr(new CardSet(_shortName, _longName, _setType, _releaseDate, _priority));
|
|
||||||
// ptr->setSmartPointer(ptr);
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CardSet::getCorrectedShortName() const
|
|
||||||
{
|
|
||||||
// For Windows machines.
|
|
||||||
QSet<QString> invalidFileNames;
|
|
||||||
invalidFileNames << "CON"
|
|
||||||
<< "PRN"
|
|
||||||
<< "AUX"
|
|
||||||
<< "NUL"
|
|
||||||
<< "COM1"
|
|
||||||
<< "COM2"
|
|
||||||
<< "COM3"
|
|
||||||
<< "COM4"
|
|
||||||
<< "COM5"
|
|
||||||
<< "COM6"
|
|
||||||
<< "COM7"
|
|
||||||
<< "COM8"
|
|
||||||
<< "COM9"
|
|
||||||
<< "LPT1"
|
|
||||||
<< "LPT2"
|
|
||||||
<< "LPT3"
|
|
||||||
<< "LPT4"
|
|
||||||
<< "LPT5"
|
|
||||||
<< "LPT6"
|
|
||||||
<< "LPT7"
|
|
||||||
<< "LPT8"
|
|
||||||
<< "LPT9";
|
|
||||||
|
|
||||||
return invalidFileNames.contains(shortName) ? shortName + "_" : shortName;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardSet::loadSetOptions()
|
|
||||||
{
|
|
||||||
sortKey = SettingsCache::instance().cardDatabase().getSortKey(shortName);
|
|
||||||
enabled = SettingsCache::instance().cardDatabase().isEnabled(shortName);
|
|
||||||
isknown = SettingsCache::instance().cardDatabase().isKnown(shortName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardSet::setSortKey(unsigned int _sortKey)
|
|
||||||
{
|
|
||||||
sortKey = _sortKey;
|
|
||||||
SettingsCache::instance().cardDatabase().setSortKey(shortName, _sortKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardSet::setEnabled(bool _enabled)
|
|
||||||
{
|
|
||||||
enabled = _enabled;
|
|
||||||
SettingsCache::instance().cardDatabase().setEnabled(shortName, _enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardSet::setIsKnown(bool _isknown)
|
|
||||||
{
|
|
||||||
isknown = _isknown;
|
|
||||||
SettingsCache::instance().cardDatabase().setIsKnown(shortName, _isknown);
|
|
||||||
}
|
|
||||||
|
|
||||||
class SetList::KeyCompareFunctor
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
inline bool operator()(const CardSetPtr &a, const CardSetPtr &b) const
|
|
||||||
{
|
|
||||||
if (a.isNull() || b.isNull()) {
|
|
||||||
qCDebug(CardDatabaseLog) << "SetList::KeyCompareFunctor a or b is null";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a->getSortKey() < b->getSortKey();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void SetList::sortByKey()
|
|
||||||
{
|
|
||||||
std::sort(begin(), end(), KeyCompareFunctor());
|
|
||||||
}
|
|
||||||
|
|
||||||
int SetList::getEnabledSetsNum()
|
|
||||||
{
|
|
||||||
int num = 0;
|
|
||||||
for (int i = 0; i < size(); ++i) {
|
|
||||||
CardSetPtr set = at(i);
|
|
||||||
if (set && set->getEnabled()) {
|
|
||||||
++num;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SetList::getUnknownSetsNum()
|
|
||||||
{
|
|
||||||
int num = 0;
|
|
||||||
for (int i = 0; i < size(); ++i) {
|
|
||||||
CardSetPtr set = at(i);
|
|
||||||
if (set && !set->getIsKnown() && !set->getIsKnownIgnored()) {
|
|
||||||
++num;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList SetList::getUnknownSetsNames()
|
|
||||||
{
|
|
||||||
QStringList sets = QStringList();
|
|
||||||
for (int i = 0; i < size(); ++i) {
|
|
||||||
CardSetPtr set = at(i);
|
|
||||||
if (set && !set->getIsKnown() && !set->getIsKnownIgnored()) {
|
|
||||||
sets << set->getShortName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sets;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetList::enableAllUnknown()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < size(); ++i) {
|
|
||||||
CardSetPtr set = at(i);
|
|
||||||
if (set && !set->getIsKnown() && !set->getIsKnownIgnored()) {
|
|
||||||
set->setIsKnown(true);
|
|
||||||
set->setEnabled(true);
|
|
||||||
} else if (set && set->getIsKnownIgnored() && !set->getEnabled()) {
|
|
||||||
set->setEnabled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetList::enableAll()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < size(); ++i) {
|
|
||||||
CardSetPtr set = at(i);
|
|
||||||
|
|
||||||
if (set == nullptr) {
|
|
||||||
qCDebug(CardDatabaseLog) << "enabledAll has null";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!set->getIsKnownIgnored()) {
|
|
||||||
set->setIsKnown(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
set->setEnabled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetList::markAllAsKnown()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < size(); ++i) {
|
|
||||||
CardSetPtr set = at(i);
|
|
||||||
if (set && !set->getIsKnown() && !set->getIsKnownIgnored()) {
|
|
||||||
set->setIsKnown(true);
|
|
||||||
set->setEnabled(false);
|
|
||||||
} else if (set && set->getIsKnownIgnored() && !set->getEnabled()) {
|
|
||||||
set->setEnabled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetList::guessSortKeys()
|
|
||||||
{
|
|
||||||
defaultSort();
|
|
||||||
for (int i = 0; i < size(); ++i) {
|
|
||||||
CardSetPtr set = at(i);
|
|
||||||
if (set.isNull()) {
|
|
||||||
qCDebug(CardDatabaseLog) << "guessSortKeys set is null";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
set->setSortKey(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetList::defaultSort()
|
|
||||||
{
|
|
||||||
std::sort(begin(), end(), [](const CardSetPtr &a, const CardSetPtr &b) {
|
|
||||||
// Sort by priority, then by release date, then by short name
|
|
||||||
if (a->getPriority() != b->getPriority()) {
|
|
||||||
return a->getPriority() < b->getPriority(); // lowest first
|
|
||||||
} else if (a->getReleaseDate() != b->getReleaseDate()) {
|
|
||||||
return a->getReleaseDate() > b->getReleaseDate(); // most recent first
|
|
||||||
} else {
|
|
||||||
return a->getShortName() < b->getShortName(); // alphabetically
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
CardInfoPerSet::CardInfoPerSet(const CardSetPtr &_set) : set(_set)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CardInfo::CardInfo(const QString &_name,
|
|
||||||
const QString &_text,
|
|
||||||
bool _isToken,
|
|
||||||
QVariantHash _properties,
|
|
||||||
const QList<CardRelation *> &_relatedCards,
|
|
||||||
const QList<CardRelation *> &_reverseRelatedCards,
|
|
||||||
CardInfoPerSetMap _sets,
|
|
||||||
bool _cipt,
|
|
||||||
bool _landscapeOrientation,
|
|
||||||
int _tableRow,
|
|
||||||
bool _upsideDownArt)
|
|
||||||
: name(_name), text(_text), isToken(_isToken), properties(std::move(_properties)), relatedCards(_relatedCards),
|
|
||||||
reverseRelatedCards(_reverseRelatedCards), sets(std::move(_sets)), cipt(_cipt),
|
|
||||||
landscapeOrientation(_landscapeOrientation), tableRow(_tableRow), upsideDownArt(_upsideDownArt)
|
|
||||||
{
|
|
||||||
pixmapCacheKey = QLatin1String("card_") + name;
|
|
||||||
simpleName = CardInfo::simplifyName(name);
|
|
||||||
|
|
||||||
refreshCachedSetNames();
|
|
||||||
}
|
|
||||||
|
|
||||||
CardInfo::~CardInfo()
|
|
||||||
{
|
|
||||||
PictureLoader::clearPixmapCache(smartThis);
|
|
||||||
}
|
|
||||||
|
|
||||||
CardInfoPtr CardInfo::newInstance(const QString &_name)
|
|
||||||
{
|
|
||||||
return newInstance(_name, QString(), false, QVariantHash(), QList<CardRelation *>(), QList<CardRelation *>(),
|
|
||||||
CardInfoPerSetMap(), false, false, 0, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
CardInfoPtr CardInfo::newInstance(const QString &_name,
|
|
||||||
const QString &_text,
|
|
||||||
bool _isToken,
|
|
||||||
QVariantHash _properties,
|
|
||||||
const QList<CardRelation *> &_relatedCards,
|
|
||||||
const QList<CardRelation *> &_reverseRelatedCards,
|
|
||||||
CardInfoPerSetMap _sets,
|
|
||||||
bool _cipt,
|
|
||||||
bool _landscapeOrientation,
|
|
||||||
int _tableRow,
|
|
||||||
bool _upsideDownArt)
|
|
||||||
{
|
|
||||||
CardInfoPtr ptr(new CardInfo(_name, _text, _isToken, std::move(_properties), _relatedCards, _reverseRelatedCards,
|
|
||||||
_sets, _cipt, _landscapeOrientation, _tableRow, _upsideDownArt));
|
|
||||||
ptr->setSmartPointer(ptr);
|
|
||||||
|
|
||||||
for (const auto &cardInfoPerSetList : _sets) {
|
|
||||||
for (const CardInfoPerSet &set : cardInfoPerSetList) {
|
|
||||||
set.getPtr()->append(ptr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CardInfo::getCorrectedName() const
|
|
||||||
{
|
|
||||||
// remove all the characters reserved in windows file paths,
|
|
||||||
// other oses only disallow a subset of these so it covers all
|
|
||||||
static const QRegularExpression rmrx(R"(( // |[*<>:"\\?\x00-\x08\x10-\x1f]))");
|
|
||||||
static const QRegularExpression spacerx(R"([/\x09-\x0f])");
|
|
||||||
static const QString space(' ');
|
|
||||||
QString result = name;
|
|
||||||
// Fire // Ice, Circle of Protection: Red, "Ach! Hans, Run!", Who/What/When/Where/Why, Question Elemental?
|
|
||||||
return result.remove(rmrx).replace(spacerx, space);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardInfo::addToSet(const CardSetPtr &_set, const CardInfoPerSet _info)
|
|
||||||
{
|
|
||||||
_set->append(smartThis);
|
|
||||||
sets[_set->getShortName()].append(_info);
|
|
||||||
|
|
||||||
refreshCachedSetNames();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardInfo::combineLegalities(const QVariantHash &props)
|
|
||||||
{
|
|
||||||
QHashIterator<QString, QVariant> it(props);
|
|
||||||
while (it.hasNext()) {
|
|
||||||
it.next();
|
|
||||||
if (it.key().startsWith("format-")) {
|
|
||||||
smartThis->setProperty(it.key(), it.value().toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardInfo::refreshCachedSetNames()
|
|
||||||
{
|
|
||||||
QStringList setList;
|
|
||||||
// update the cached list of set names
|
|
||||||
for (const auto &cardInfoPerSetList : sets) {
|
|
||||||
for (const auto &set : cardInfoPerSetList) {
|
|
||||||
if (set.getPtr()->getEnabled()) {
|
|
||||||
setList << set.getPtr()->getShortName();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setsNames = setList.join(", ");
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CardInfo::simplifyName(const QString &name)
|
|
||||||
{
|
|
||||||
static const QRegularExpression spaceOrSplit("(\\s+|\\/\\/.*)");
|
|
||||||
static const QRegularExpression nonAlnum("[^a-z0-9]");
|
|
||||||
|
|
||||||
QString simpleName = name.toLower();
|
|
||||||
|
|
||||||
// remove spaces and right halves of split cards
|
|
||||||
simpleName.remove(spaceOrSplit);
|
|
||||||
|
|
||||||
// So Aetherling would work, but not Ætherling since 'Æ' would get replaced
|
|
||||||
// with nothing.
|
|
||||||
simpleName.replace("æ", "ae");
|
|
||||||
|
|
||||||
// Replace Jötun Grunt with Jotun Grunt.
|
|
||||||
simpleName = simpleName.normalized(QString::NormalizationForm_KD);
|
|
||||||
|
|
||||||
// remove all non alphanumeric characters from the name
|
|
||||||
simpleName.remove(nonAlnum);
|
|
||||||
return simpleName;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QChar CardInfo::getColorChar() const
|
|
||||||
{
|
|
||||||
QString colors = getColors();
|
|
||||||
switch (colors.size()) {
|
|
||||||
case 0:
|
|
||||||
return QChar();
|
|
||||||
case 1:
|
|
||||||
return colors.at(0);
|
|
||||||
default:
|
|
||||||
return QChar('m');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CardDatabase::CardDatabase(QObject *parent) : QObject(parent), loadStatus(NotLoaded)
|
CardDatabase::CardDatabase(QObject *parent) : QObject(parent), loadStatus(NotLoaded)
|
||||||
{
|
{
|
||||||
qRegisterMetaType<CardInfoPtr>("CardInfoPtr");
|
qRegisterMetaType<CardInfoPtr>("CardInfoPtr");
|
||||||
|
|
@ -883,65 +536,4 @@ bool CardDatabase::saveCustomTokensToFile()
|
||||||
|
|
||||||
availableParsers.first()->saveToFile(tmpSets, tmpCards, fileName);
|
availableParsers.first()->saveToFile(tmpSets, tmpCards, fileName);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CardRelation::CardRelation(const QString &_name,
|
|
||||||
AttachType _attachType,
|
|
||||||
bool _isCreateAllExclusion,
|
|
||||||
bool _isVariableCount,
|
|
||||||
int _defaultCount,
|
|
||||||
bool _isPersistent)
|
|
||||||
: name(_name), attachType(_attachType), isCreateAllExclusion(_isCreateAllExclusion),
|
|
||||||
isVariableCount(_isVariableCount), defaultCount(_defaultCount), isPersistent(_isPersistent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardInfo::resetReverseRelatedCards2Me()
|
|
||||||
{
|
|
||||||
for (CardRelation *cardRelation : this->getReverseRelatedCards2Me()) {
|
|
||||||
cardRelation->deleteLater();
|
|
||||||
}
|
|
||||||
reverseRelatedCardsToMe = QList<CardRelation *>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Back-compatibility methods. Remove ASAP
|
|
||||||
const QString CardInfo::getCardType() const
|
|
||||||
{
|
|
||||||
return getProperty(Mtg::CardType);
|
|
||||||
}
|
|
||||||
void CardInfo::setCardType(const QString &value)
|
|
||||||
{
|
|
||||||
setProperty(Mtg::CardType, value);
|
|
||||||
}
|
|
||||||
const QString CardInfo::getCmc() const
|
|
||||||
{
|
|
||||||
return getProperty(Mtg::ConvertedManaCost);
|
|
||||||
}
|
|
||||||
const QString CardInfo::getColors() const
|
|
||||||
{
|
|
||||||
return getProperty(Mtg::Colors);
|
|
||||||
}
|
|
||||||
void CardInfo::setColors(const QString &value)
|
|
||||||
{
|
|
||||||
setProperty(Mtg::Colors, value);
|
|
||||||
}
|
|
||||||
const QString CardInfo::getLoyalty() const
|
|
||||||
{
|
|
||||||
return getProperty(Mtg::Loyalty);
|
|
||||||
}
|
|
||||||
const QString CardInfo::getMainCardType() const
|
|
||||||
{
|
|
||||||
return getProperty(Mtg::MainCardType);
|
|
||||||
}
|
|
||||||
const QString CardInfo::getManaCost() const
|
|
||||||
{
|
|
||||||
return getProperty(Mtg::ManaCost);
|
|
||||||
}
|
|
||||||
const QString CardInfo::getPowTough() const
|
|
||||||
{
|
|
||||||
return getProperty(Mtg::PowTough);
|
|
||||||
}
|
|
||||||
void CardInfo::setPowTough(const QString &value)
|
|
||||||
{
|
|
||||||
setProperty(Mtg::PowTough, value);
|
|
||||||
}
|
|
||||||
|
|
@ -1,16 +1,14 @@
|
||||||
#ifndef CARDDATABASE_H
|
#ifndef CARDDATABASE_H
|
||||||
#define CARDDATABASE_H
|
#define CARDDATABASE_H
|
||||||
|
|
||||||
|
#include "card_info.h"
|
||||||
|
|
||||||
#include <QBasicMutex>
|
#include <QBasicMutex>
|
||||||
#include <QDate>
|
#include <QDate>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
#include <QMap>
|
|
||||||
#include <QMetaType>
|
|
||||||
#include <QSharedPointer>
|
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QVariant>
|
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
|
@ -18,406 +16,8 @@ inline Q_LOGGING_CATEGORY(CardDatabaseLog, "card_database");
|
||||||
inline Q_LOGGING_CATEGORY(CardDatabaseLoadingLog, "card_database.loading");
|
inline Q_LOGGING_CATEGORY(CardDatabaseLoadingLog, "card_database.loading");
|
||||||
inline Q_LOGGING_CATEGORY(CardDatabaseLoadingSuccessOrFailureLog, "card_database.loading.success_or_failure");
|
inline Q_LOGGING_CATEGORY(CardDatabaseLoadingSuccessOrFailureLog, "card_database.loading.success_or_failure");
|
||||||
|
|
||||||
class CardDatabase;
|
|
||||||
class CardInfo;
|
|
||||||
class CardInfoPerSet;
|
|
||||||
class CardSet;
|
|
||||||
class CardRelation;
|
|
||||||
class ICardDatabaseParser;
|
class ICardDatabaseParser;
|
||||||
|
|
||||||
typedef QMap<QString, QString> QStringMap;
|
|
||||||
typedef QSharedPointer<CardInfo> CardInfoPtr;
|
|
||||||
typedef QSharedPointer<CardSet> CardSetPtr;
|
|
||||||
typedef QMap<QString, QList<CardInfoPerSet>> CardInfoPerSetMap;
|
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(CardInfoPtr)
|
|
||||||
|
|
||||||
class CardSet : public QList<CardInfoPtr>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum Priority
|
|
||||||
{
|
|
||||||
PriorityFallback = 0,
|
|
||||||
PriorityPrimary = 10,
|
|
||||||
PrioritySecondary = 20,
|
|
||||||
PriorityReprint = 30,
|
|
||||||
PriorityOther = 40,
|
|
||||||
PriorityLowest = 100,
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString shortName, longName;
|
|
||||||
unsigned int sortKey;
|
|
||||||
QDate releaseDate;
|
|
||||||
QString setType;
|
|
||||||
Priority priority;
|
|
||||||
bool enabled, isknown;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit CardSet(const QString &_shortName = QString(),
|
|
||||||
const QString &_longName = QString(),
|
|
||||||
const QString &_setType = QString(),
|
|
||||||
const QDate &_releaseDate = QDate(),
|
|
||||||
const Priority _priority = PriorityFallback);
|
|
||||||
static CardSetPtr newInstance(const QString &_shortName = QString(),
|
|
||||||
const QString &_longName = QString(),
|
|
||||||
const QString &_setType = QString(),
|
|
||||||
const QDate &_releaseDate = QDate(),
|
|
||||||
const Priority _priority = PriorityFallback);
|
|
||||||
QString getCorrectedShortName() const;
|
|
||||||
QString getShortName() const
|
|
||||||
{
|
|
||||||
return shortName;
|
|
||||||
}
|
|
||||||
QString getLongName() const
|
|
||||||
{
|
|
||||||
return longName;
|
|
||||||
}
|
|
||||||
QString getSetType() const
|
|
||||||
{
|
|
||||||
return setType;
|
|
||||||
}
|
|
||||||
QDate getReleaseDate() const
|
|
||||||
{
|
|
||||||
return releaseDate;
|
|
||||||
}
|
|
||||||
Priority getPriority() const
|
|
||||||
{
|
|
||||||
return priority;
|
|
||||||
}
|
|
||||||
void setLongName(const QString &_longName)
|
|
||||||
{
|
|
||||||
longName = _longName;
|
|
||||||
}
|
|
||||||
void setSetType(const QString &_setType)
|
|
||||||
{
|
|
||||||
setType = _setType;
|
|
||||||
}
|
|
||||||
void setReleaseDate(const QDate &_releaseDate)
|
|
||||||
{
|
|
||||||
releaseDate = _releaseDate;
|
|
||||||
}
|
|
||||||
void setPriority(const Priority _priority)
|
|
||||||
{
|
|
||||||
priority = _priority;
|
|
||||||
}
|
|
||||||
|
|
||||||
void loadSetOptions();
|
|
||||||
int getSortKey() const
|
|
||||||
{
|
|
||||||
return sortKey;
|
|
||||||
}
|
|
||||||
void setSortKey(unsigned int _sortKey);
|
|
||||||
bool getEnabled() const
|
|
||||||
{
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
void setEnabled(bool _enabled);
|
|
||||||
bool getIsKnown() const
|
|
||||||
{
|
|
||||||
return isknown;
|
|
||||||
}
|
|
||||||
void setIsKnown(bool _isknown);
|
|
||||||
|
|
||||||
// Determine incomplete sets.
|
|
||||||
bool getIsKnownIgnored() const
|
|
||||||
{
|
|
||||||
return longName.length() + setType.length() + releaseDate.toString().length() == 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class SetList : public QList<CardSetPtr>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
class KeyCompareFunctor;
|
|
||||||
|
|
||||||
public:
|
|
||||||
void sortByKey();
|
|
||||||
void guessSortKeys();
|
|
||||||
void enableAllUnknown();
|
|
||||||
void enableAll();
|
|
||||||
void markAllAsKnown();
|
|
||||||
int getEnabledSetsNum();
|
|
||||||
int getUnknownSetsNum();
|
|
||||||
QStringList getUnknownSetsNames();
|
|
||||||
void defaultSort();
|
|
||||||
};
|
|
||||||
|
|
||||||
class CardInfoPerSet
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit CardInfoPerSet(const CardSetPtr &_set = QSharedPointer<CardSet>(nullptr));
|
|
||||||
~CardInfoPerSet() = default;
|
|
||||||
|
|
||||||
bool operator==(const CardInfoPerSet &other) const
|
|
||||||
{
|
|
||||||
return this->set == other.set && this->properties == other.properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
CardSetPtr set;
|
|
||||||
// per-set card properties;
|
|
||||||
QVariantHash properties;
|
|
||||||
|
|
||||||
public:
|
|
||||||
const CardSetPtr getPtr() const
|
|
||||||
{
|
|
||||||
return set;
|
|
||||||
}
|
|
||||||
const QStringList getProperties() const
|
|
||||||
{
|
|
||||||
return properties.keys();
|
|
||||||
}
|
|
||||||
const QString getProperty(const QString &propertyName) const
|
|
||||||
{
|
|
||||||
return properties.value(propertyName).toString();
|
|
||||||
}
|
|
||||||
void setProperty(const QString &_name, const QString &_value)
|
|
||||||
{
|
|
||||||
properties.insert(_name, _value);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CardInfo : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
private:
|
|
||||||
CardInfoPtr smartThis;
|
|
||||||
// The card name
|
|
||||||
QString name;
|
|
||||||
// The name without punctuation or capitalization, for better card name recognition.
|
|
||||||
QString simpleName;
|
|
||||||
// The key used to identify this card in the cache
|
|
||||||
QString pixmapCacheKey;
|
|
||||||
// card text
|
|
||||||
QString text;
|
|
||||||
// whether this is not a "real" card but a token
|
|
||||||
bool isToken;
|
|
||||||
// basic card properties; common for all the sets
|
|
||||||
QVariantHash properties;
|
|
||||||
// the cards i'm related to
|
|
||||||
QList<CardRelation *> relatedCards;
|
|
||||||
// the card i'm reverse-related to
|
|
||||||
QList<CardRelation *> reverseRelatedCards;
|
|
||||||
// the cards thare are reverse-related to me
|
|
||||||
QList<CardRelation *> reverseRelatedCardsToMe;
|
|
||||||
// card sets
|
|
||||||
CardInfoPerSetMap sets;
|
|
||||||
// cached set names
|
|
||||||
QString setsNames;
|
|
||||||
// positioning properties; used by UI
|
|
||||||
bool cipt;
|
|
||||||
bool landscapeOrientation;
|
|
||||||
int tableRow;
|
|
||||||
bool upsideDownArt;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit CardInfo(const QString &_name,
|
|
||||||
const QString &_text,
|
|
||||||
bool _isToken,
|
|
||||||
QVariantHash _properties,
|
|
||||||
const QList<CardRelation *> &_relatedCards,
|
|
||||||
const QList<CardRelation *> &_reverseRelatedCards,
|
|
||||||
CardInfoPerSetMap _sets,
|
|
||||||
bool _cipt,
|
|
||||||
bool _landscapeOrientation,
|
|
||||||
int _tableRow,
|
|
||||||
bool _upsideDownArt);
|
|
||||||
CardInfo(const CardInfo &other)
|
|
||||||
: QObject(other.parent()), name(other.name), simpleName(other.simpleName), pixmapCacheKey(other.pixmapCacheKey),
|
|
||||||
text(other.text), isToken(other.isToken), properties(other.properties), relatedCards(other.relatedCards),
|
|
||||||
reverseRelatedCards(other.reverseRelatedCards), reverseRelatedCardsToMe(other.reverseRelatedCardsToMe),
|
|
||||||
sets(other.sets), setsNames(other.setsNames), cipt(other.cipt),
|
|
||||||
landscapeOrientation(other.landscapeOrientation), tableRow(other.tableRow), upsideDownArt(other.upsideDownArt)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
~CardInfo() override;
|
|
||||||
|
|
||||||
static CardInfoPtr newInstance(const QString &_name);
|
|
||||||
|
|
||||||
static CardInfoPtr newInstance(const QString &_name,
|
|
||||||
const QString &_text,
|
|
||||||
bool _isToken,
|
|
||||||
QVariantHash _properties,
|
|
||||||
const QList<CardRelation *> &_relatedCards,
|
|
||||||
const QList<CardRelation *> &_reverseRelatedCards,
|
|
||||||
CardInfoPerSetMap _sets,
|
|
||||||
bool _cipt,
|
|
||||||
bool _landscapeOrientation,
|
|
||||||
int _tableRow,
|
|
||||||
bool _upsideDownArt);
|
|
||||||
|
|
||||||
CardInfoPtr clone() const
|
|
||||||
{
|
|
||||||
// Use the copy constructor to create a new instance
|
|
||||||
CardInfoPtr newCardInfo = CardInfoPtr(new CardInfo(*this));
|
|
||||||
newCardInfo->setSmartPointer(newCardInfo); // Set the smart pointer for the new instance
|
|
||||||
return newCardInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setSmartPointer(CardInfoPtr _ptr)
|
|
||||||
{
|
|
||||||
smartThis = std::move(_ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// basic properties
|
|
||||||
inline const QString &getName() const
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
const QString &getSimpleName() const
|
|
||||||
{
|
|
||||||
return simpleName;
|
|
||||||
}
|
|
||||||
void setPixmapCacheKey(QString _pixmapCacheKey)
|
|
||||||
{
|
|
||||||
pixmapCacheKey = _pixmapCacheKey;
|
|
||||||
}
|
|
||||||
const QString &getPixmapCacheKey() const
|
|
||||||
{
|
|
||||||
return pixmapCacheKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString &getText() const
|
|
||||||
{
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
void setText(const QString &_text)
|
|
||||||
{
|
|
||||||
text = _text;
|
|
||||||
emit cardInfoChanged(smartThis);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool getIsToken() const
|
|
||||||
{
|
|
||||||
return isToken;
|
|
||||||
}
|
|
||||||
const QStringList getProperties() const
|
|
||||||
{
|
|
||||||
return properties.keys();
|
|
||||||
}
|
|
||||||
const QString getProperty(const QString &propertyName) const
|
|
||||||
{
|
|
||||||
return properties.value(propertyName).toString();
|
|
||||||
}
|
|
||||||
void setProperty(const QString &_name, const QString &_value)
|
|
||||||
{
|
|
||||||
properties.insert(_name, _value);
|
|
||||||
emit cardInfoChanged(smartThis);
|
|
||||||
}
|
|
||||||
bool hasProperty(const QString &propertyName) const
|
|
||||||
{
|
|
||||||
return properties.contains(propertyName);
|
|
||||||
}
|
|
||||||
const CardInfoPerSetMap &getSets() const
|
|
||||||
{
|
|
||||||
return sets;
|
|
||||||
}
|
|
||||||
const QString &getSetsNames() const
|
|
||||||
{
|
|
||||||
return setsNames;
|
|
||||||
}
|
|
||||||
const QString getSetProperty(const QString &setName, const QString &propertyName) const
|
|
||||||
{
|
|
||||||
if (!sets.contains(setName))
|
|
||||||
return "";
|
|
||||||
|
|
||||||
for (const auto &set : sets[setName]) {
|
|
||||||
if (QLatin1String("card_") + this->getName() + QString("_") + QString(set.getProperty("uuid")) ==
|
|
||||||
this->getPixmapCacheKey()) {
|
|
||||||
return set.getProperty(propertyName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sets[setName][0].getProperty(propertyName);
|
|
||||||
}
|
|
||||||
|
|
||||||
// related cards
|
|
||||||
const QList<CardRelation *> &getRelatedCards() const
|
|
||||||
{
|
|
||||||
return relatedCards;
|
|
||||||
}
|
|
||||||
const QList<CardRelation *> &getReverseRelatedCards() const
|
|
||||||
{
|
|
||||||
return reverseRelatedCards;
|
|
||||||
}
|
|
||||||
const QList<CardRelation *> &getReverseRelatedCards2Me() const
|
|
||||||
{
|
|
||||||
return reverseRelatedCardsToMe;
|
|
||||||
}
|
|
||||||
const QList<CardRelation *> getAllRelatedCards() const
|
|
||||||
{
|
|
||||||
QList<CardRelation *> result;
|
|
||||||
result.append(getRelatedCards());
|
|
||||||
result.append(getReverseRelatedCards2Me());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
void resetReverseRelatedCards2Me();
|
|
||||||
void addReverseRelatedCards2Me(CardRelation *cardRelation)
|
|
||||||
{
|
|
||||||
reverseRelatedCardsToMe.append(cardRelation);
|
|
||||||
}
|
|
||||||
|
|
||||||
// positioning
|
|
||||||
bool getCipt() const
|
|
||||||
{
|
|
||||||
return cipt;
|
|
||||||
}
|
|
||||||
bool getLandscapeOrientation() const
|
|
||||||
{
|
|
||||||
return landscapeOrientation;
|
|
||||||
}
|
|
||||||
int getTableRow() const
|
|
||||||
{
|
|
||||||
return tableRow;
|
|
||||||
}
|
|
||||||
void setTableRow(int _tableRow)
|
|
||||||
{
|
|
||||||
tableRow = _tableRow;
|
|
||||||
}
|
|
||||||
bool getUpsideDownArt() const
|
|
||||||
{
|
|
||||||
return upsideDownArt;
|
|
||||||
}
|
|
||||||
const QChar getColorChar() const;
|
|
||||||
|
|
||||||
// Back-compatibility methods. Remove ASAP
|
|
||||||
const QString getCardType() const;
|
|
||||||
void setCardType(const QString &value);
|
|
||||||
const QString getCmc() const;
|
|
||||||
const QString getColors() const;
|
|
||||||
void setColors(const QString &value);
|
|
||||||
const QString getLoyalty() const;
|
|
||||||
const QString getMainCardType() const;
|
|
||||||
const QString getManaCost() const;
|
|
||||||
const QString getPowTough() const;
|
|
||||||
void setPowTough(const QString &value);
|
|
||||||
|
|
||||||
// methods using per-set properties
|
|
||||||
QString getCustomPicURL(const QString &set) const
|
|
||||||
{
|
|
||||||
return getSetProperty(set, "picurl");
|
|
||||||
}
|
|
||||||
QString getCorrectedName() const;
|
|
||||||
void addToSet(const CardSetPtr &_set, CardInfoPerSet _info = CardInfoPerSet());
|
|
||||||
void combineLegalities(const QVariantHash &props);
|
|
||||||
void emitPixmapUpdated()
|
|
||||||
{
|
|
||||||
emit pixmapUpdated();
|
|
||||||
}
|
|
||||||
void refreshCachedSetNames();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simplify a name to have no punctuation and lowercase all letters, for
|
|
||||||
* less strict name-matching.
|
|
||||||
*/
|
|
||||||
static QString simplifyName(const QString &name);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void pixmapUpdated();
|
|
||||||
void cardInfoChanged(CardInfoPtr card);
|
|
||||||
};
|
|
||||||
|
|
||||||
enum LoadStatus
|
enum LoadStatus
|
||||||
{
|
{
|
||||||
Ok,
|
Ok,
|
||||||
|
|
@ -523,79 +123,4 @@ signals:
|
||||||
void cardRemoved(CardInfoPtr card);
|
void cardRemoved(CardInfoPtr card);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CardRelation : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
enum AttachType
|
|
||||||
{
|
|
||||||
DoesNotAttach = 0,
|
|
||||||
AttachTo = 1,
|
|
||||||
TransformInto = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString name;
|
|
||||||
AttachType attachType;
|
|
||||||
bool isCreateAllExclusion;
|
|
||||||
bool isVariableCount;
|
|
||||||
int defaultCount;
|
|
||||||
bool isPersistent;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit CardRelation(const QString &_name = QString(),
|
|
||||||
AttachType _attachType = DoesNotAttach,
|
|
||||||
bool _isCreateAllExclusion = false,
|
|
||||||
bool _isVariableCount = false,
|
|
||||||
int _defaultCount = 1,
|
|
||||||
bool _isPersistent = false);
|
|
||||||
|
|
||||||
inline const QString &getName() const
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
AttachType getAttachType() const
|
|
||||||
{
|
|
||||||
return attachType;
|
|
||||||
}
|
|
||||||
bool getDoesAttach() const
|
|
||||||
{
|
|
||||||
return attachType != DoesNotAttach;
|
|
||||||
}
|
|
||||||
bool getDoesTransform() const
|
|
||||||
{
|
|
||||||
return attachType == TransformInto;
|
|
||||||
}
|
|
||||||
QString getAttachTypeAsString() const
|
|
||||||
{
|
|
||||||
switch (attachType) {
|
|
||||||
case AttachTo:
|
|
||||||
return "attach";
|
|
||||||
case TransformInto:
|
|
||||||
return "transform";
|
|
||||||
default:
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bool getCanCreateAnother() const
|
|
||||||
{
|
|
||||||
return !getDoesAttach();
|
|
||||||
}
|
|
||||||
bool getIsCreateAllExclusion() const
|
|
||||||
{
|
|
||||||
return isCreateAllExclusion;
|
|
||||||
}
|
|
||||||
bool getIsVariable() const
|
|
||||||
{
|
|
||||||
return isVariableCount;
|
|
||||||
}
|
|
||||||
int getDefaultCount() const
|
|
||||||
{
|
|
||||||
return defaultCount;
|
|
||||||
}
|
|
||||||
bool getIsPersistent() const
|
|
||||||
{
|
|
||||||
return isPersistent;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,16 @@
|
||||||
#include "card_info.h"
|
#include "card_info.h"
|
||||||
|
|
||||||
#include "../../client/network/spoiler_background_updater.h"
|
|
||||||
#include "../../client/ui/picture_loader/picture_loader.h"
|
#include "../../client/ui/picture_loader/picture_loader.h"
|
||||||
#include "../../settings/cache_settings.h"
|
#include "../../settings/cache_settings.h"
|
||||||
#include "../../utility/card_set_comparator.h"
|
|
||||||
#include "../game_specific_terms.h"
|
#include "../game_specific_terms.h"
|
||||||
#include "./card_database_parser/cockatrice_xml_3.h"
|
|
||||||
#include "./card_database_parser/cockatrice_xml_4.h"
|
|
||||||
|
|
||||||
#include <QCryptographicHash>
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QDirIterator>
|
|
||||||
#include <QFile>
|
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
const char *CardDatabase::TOKENS_SETNAME = "TK";
|
|
||||||
|
|
||||||
CardSet::CardSet(const QString &_shortName,
|
CardSet::CardSet(const QString &_shortName,
|
||||||
const QString &_longName,
|
const QString &_longName,
|
||||||
const QString &_setType,
|
const QString &_setType,
|
||||||
|
|
@ -102,7 +93,7 @@ public:
|
||||||
inline bool operator()(const CardSetPtr &a, const CardSetPtr &b) const
|
inline bool operator()(const CardSetPtr &a, const CardSetPtr &b) const
|
||||||
{
|
{
|
||||||
if (a.isNull() || b.isNull()) {
|
if (a.isNull() || b.isNull()) {
|
||||||
qCDebug(CardDatabaseLog) << "SetList::KeyCompareFunctor a or b is null";
|
qCDebug(CardInfoLog) << "SetList::KeyCompareFunctor a or b is null";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -170,7 +161,7 @@ void SetList::enableAll()
|
||||||
CardSetPtr set = at(i);
|
CardSetPtr set = at(i);
|
||||||
|
|
||||||
if (set == nullptr) {
|
if (set == nullptr) {
|
||||||
qCDebug(CardDatabaseLog) << "enabledAll has null";
|
qCDebug(CardInfoLog) << "enabledAll has null";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -201,7 +192,7 @@ void SetList::guessSortKeys()
|
||||||
for (int i = 0; i < size(); ++i) {
|
for (int i = 0; i < size(); ++i) {
|
||||||
CardSetPtr set = at(i);
|
CardSetPtr set = at(i);
|
||||||
if (set.isNull()) {
|
if (set.isNull()) {
|
||||||
qCDebug(CardDatabaseLog) << "guessSortKeys set is null";
|
qCDebug(CardInfoLog) << "guessSortKeys set is null";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
set->setSortKey(i);
|
set->setSortKey(i);
|
||||||
|
|
@ -365,526 +356,6 @@ const QChar CardInfo::getColorChar() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CardDatabase::CardDatabase(QObject *parent) : QObject(parent), loadStatus(NotLoaded)
|
|
||||||
{
|
|
||||||
qRegisterMetaType<CardInfoPtr>("CardInfoPtr");
|
|
||||||
qRegisterMetaType<CardInfoPtr>("CardSetPtr");
|
|
||||||
|
|
||||||
// add new parsers here
|
|
||||||
availableParsers << new CockatriceXml4Parser;
|
|
||||||
availableParsers << new CockatriceXml3Parser;
|
|
||||||
|
|
||||||
for (auto &parser : availableParsers) {
|
|
||||||
connect(parser, &ICardDatabaseParser::addCard, this, &CardDatabase::addCard, Qt::DirectConnection);
|
|
||||||
connect(parser, &ICardDatabaseParser::addSet, this, &CardDatabase::addSet, Qt::DirectConnection);
|
|
||||||
}
|
|
||||||
|
|
||||||
connect(&SettingsCache::instance(), &SettingsCache::cardDatabasePathChanged, this,
|
|
||||||
&CardDatabase::loadCardDatabases);
|
|
||||||
}
|
|
||||||
|
|
||||||
CardDatabase::~CardDatabase()
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
qDeleteAll(availableParsers);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardDatabase::clear()
|
|
||||||
{
|
|
||||||
clearDatabaseMutex->lock();
|
|
||||||
|
|
||||||
QHashIterator<QString, CardInfoPtr> i(cards);
|
|
||||||
while (i.hasNext()) {
|
|
||||||
i.next();
|
|
||||||
if (i.value()) {
|
|
||||||
removeCard(i.value());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cards.clear();
|
|
||||||
simpleNameCards.clear();
|
|
||||||
|
|
||||||
sets.clear();
|
|
||||||
ICardDatabaseParser::clearSetlist();
|
|
||||||
|
|
||||||
loadStatus = NotLoaded;
|
|
||||||
|
|
||||||
clearDatabaseMutex->unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardDatabase::addCard(CardInfoPtr card)
|
|
||||||
{
|
|
||||||
if (card == nullptr) {
|
|
||||||
qCDebug(CardDatabaseLog) << "CardDatabase::addCard(nullptr)";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if card already exists just add the new set property
|
|
||||||
if (cards.contains(card->getName())) {
|
|
||||||
CardInfoPtr sameCard = cards[card->getName()];
|
|
||||||
for (const auto &cardInfoPerSetList : card->getSets()) {
|
|
||||||
for (const CardInfoPerSet &set : cardInfoPerSetList) {
|
|
||||||
sameCard->addToSet(set.getPtr(), set);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
addCardMutex->lock();
|
|
||||||
cards.insert(card->getName(), card);
|
|
||||||
simpleNameCards.insert(card->getSimpleName(), card);
|
|
||||||
addCardMutex->unlock();
|
|
||||||
emit cardAdded(card);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardDatabase::removeCard(CardInfoPtr card)
|
|
||||||
{
|
|
||||||
if (card.isNull()) {
|
|
||||||
qCDebug(CardDatabaseLog) << "CardDatabase::removeCard(nullptr)";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto *cardRelation : card->getRelatedCards())
|
|
||||||
cardRelation->deleteLater();
|
|
||||||
|
|
||||||
for (auto *cardRelation : card->getReverseRelatedCards())
|
|
||||||
cardRelation->deleteLater();
|
|
||||||
|
|
||||||
for (auto *cardRelation : card->getReverseRelatedCards2Me())
|
|
||||||
cardRelation->deleteLater();
|
|
||||||
|
|
||||||
removeCardMutex->lock();
|
|
||||||
cards.remove(card->getName());
|
|
||||||
simpleNameCards.remove(card->getSimpleName());
|
|
||||||
removeCardMutex->unlock();
|
|
||||||
emit cardRemoved(card);
|
|
||||||
}
|
|
||||||
|
|
||||||
CardInfoPtr CardDatabase::getCard(const QString &cardName) const
|
|
||||||
{
|
|
||||||
return getCardFromMap(cards, cardName);
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<CardInfoPtr> CardDatabase::getCards(const QStringList &cardNames) const
|
|
||||||
{
|
|
||||||
QList<CardInfoPtr> cardInfos;
|
|
||||||
for (const QString &cardName : cardNames) {
|
|
||||||
CardInfoPtr ptr = getCardFromMap(cards, cardName);
|
|
||||||
if (ptr)
|
|
||||||
cardInfos.append(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return cardInfos;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<CardInfoPtr> CardDatabase::getCardsByNameAndProviderId(const QMap<QString, QString> &cardNames) const
|
|
||||||
{
|
|
||||||
QList<CardInfoPtr> cardInfos;
|
|
||||||
for (const QString &cardName : cardNames) {
|
|
||||||
CardInfoPtr ptr = getCardByNameAndProviderId(cardName, cardNames[cardName]);
|
|
||||||
if (ptr)
|
|
||||||
cardInfos.append(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return cardInfos;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 &cardInfoPerSetList : info->getSets()) {
|
|
||||||
for (const auto &set : cardInfoPerSetList) {
|
|
||||||
if (set.getProperty("uuid") == providerId) {
|
|
||||||
CardInfoPtr cardFromSpecificSet = info->clone();
|
|
||||||
cardFromSpecificSet->setPixmapCacheKey(QLatin1String("card_") + QString(info->getName()) +
|
|
||||||
QString("_") + QString(set.getProperty("uuid")));
|
|
||||||
return cardFromSpecificSet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
CardInfoPtr CardDatabase::getCardBySimpleName(const QString &cardName) const
|
|
||||||
{
|
|
||||||
return getCardFromMap(simpleNameCards, CardInfo::simplifyName(cardName));
|
|
||||||
}
|
|
||||||
|
|
||||||
CardInfoPtr CardDatabase::guessCard(const QString &cardName, const QString &providerId) const
|
|
||||||
{
|
|
||||||
CardInfoPtr temp = providerId.isEmpty() ? getCard(cardName) : getCardByNameAndProviderId(cardName, providerId);
|
|
||||||
|
|
||||||
if (temp == nullptr) { // get card by simple name instead
|
|
||||||
temp = getCardBySimpleName(cardName);
|
|
||||||
if (temp == nullptr) { // still could not find the card, so simplify the cardName too
|
|
||||||
const auto &simpleCardName = CardInfo::simplifyName(cardName);
|
|
||||||
temp = getCardBySimpleName(simpleCardName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return temp; // returns nullptr if not found
|
|
||||||
}
|
|
||||||
|
|
||||||
CardSetPtr CardDatabase::getSet(const QString &setName)
|
|
||||||
{
|
|
||||||
if (sets.contains(setName)) {
|
|
||||||
return sets.value(setName);
|
|
||||||
} else {
|
|
||||||
CardSetPtr newSet = CardSet::newInstance(setName);
|
|
||||||
sets.insert(setName, newSet);
|
|
||||||
return newSet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardDatabase::addSet(CardSetPtr set)
|
|
||||||
{
|
|
||||||
sets.insert(set->getShortName(), set);
|
|
||||||
}
|
|
||||||
|
|
||||||
SetList CardDatabase::getSetList() const
|
|
||||||
{
|
|
||||||
SetList result;
|
|
||||||
QHashIterator<QString, CardSetPtr> i(sets);
|
|
||||||
while (i.hasNext()) {
|
|
||||||
i.next();
|
|
||||||
result << i.value();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
CardInfoPtr CardDatabase::getCardFromMap(const CardNameMap &cardMap, const QString &cardName) const
|
|
||||||
{
|
|
||||||
if (cardMap.contains(cardName))
|
|
||||||
return cardMap.value(cardName);
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadStatus CardDatabase::loadFromFile(const QString &fileName)
|
|
||||||
{
|
|
||||||
QFile file(fileName);
|
|
||||||
file.open(QIODevice::ReadOnly);
|
|
||||||
if (!file.isOpen()) {
|
|
||||||
return FileError;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto parser : availableParsers) {
|
|
||||||
file.reset();
|
|
||||||
if (parser->getCanParseFile(fileName, file)) {
|
|
||||||
file.reset();
|
|
||||||
parser->parseFile(file);
|
|
||||||
return Ok;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadStatus CardDatabase::loadCardDatabase(const QString &path)
|
|
||||||
{
|
|
||||||
auto startTime = QTime::currentTime();
|
|
||||||
LoadStatus tempLoadStatus = NotLoaded;
|
|
||||||
if (!path.isEmpty()) {
|
|
||||||
loadFromFileMutex->lock();
|
|
||||||
tempLoadStatus = loadFromFile(path);
|
|
||||||
loadFromFileMutex->unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
int msecs = startTime.msecsTo(QTime::currentTime());
|
|
||||||
qCDebug(CardDatabaseLoadingLog) << "Path =" << path << "Status =" << tempLoadStatus << "Cards =" << cards.size()
|
|
||||||
<< "Sets =" << sets.size() << QString("%1ms").arg(msecs);
|
|
||||||
|
|
||||||
return tempLoadStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadStatus CardDatabase::loadCardDatabases()
|
|
||||||
{
|
|
||||||
reloadDatabaseMutex->lock();
|
|
||||||
|
|
||||||
qCDebug(CardDatabaseLoadingLog) << "Started";
|
|
||||||
|
|
||||||
clear(); // remove old db
|
|
||||||
|
|
||||||
loadStatus = loadCardDatabase(SettingsCache::instance().getCardDatabasePath()); // load main card database
|
|
||||||
loadCardDatabase(SettingsCache::instance().getTokenDatabasePath()); // load tokens database
|
|
||||||
loadCardDatabase(SettingsCache::instance().getSpoilerCardDatabasePath()); // load spoilers database
|
|
||||||
|
|
||||||
// find all custom card databases, recursively & following symlinks
|
|
||||||
// then load them alphabetically
|
|
||||||
QDirIterator customDatabaseIterator(SettingsCache::instance().getCustomCardDatabasePath(), QStringList() << "*.xml",
|
|
||||||
QDir::Files, QDirIterator::Subdirectories | QDirIterator::FollowSymlinks);
|
|
||||||
QStringList databasePaths;
|
|
||||||
while (customDatabaseIterator.hasNext()) {
|
|
||||||
customDatabaseIterator.next();
|
|
||||||
databasePaths.push_back(customDatabaseIterator.filePath());
|
|
||||||
}
|
|
||||||
databasePaths.sort();
|
|
||||||
|
|
||||||
for (auto i = 0; i < databasePaths.size(); ++i) {
|
|
||||||
const auto &databasePath = databasePaths.at(i);
|
|
||||||
qCDebug(CardDatabaseLoadingLog) << "Loading Custom Set" << i << "(" << databasePath << ")";
|
|
||||||
loadCardDatabase(databasePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
// AFTER all the cards have been loaded
|
|
||||||
|
|
||||||
// Refresh the pixmap cache keys for all cards by setting them to the UUID of the preferred printing
|
|
||||||
refreshPreferredPrintings();
|
|
||||||
// resolve the reverse-related tags
|
|
||||||
refreshCachedReverseRelatedCards();
|
|
||||||
|
|
||||||
if (loadStatus == Ok) {
|
|
||||||
checkUnknownSets(); // update deck editors, etc
|
|
||||||
qCDebug(CardDatabaseLoadingSuccessOrFailureLog) << "Success";
|
|
||||||
emit cardDatabaseLoadingFinished();
|
|
||||||
} else {
|
|
||||||
qCDebug(CardDatabaseLoadingSuccessOrFailureLog) << "Failed";
|
|
||||||
emit cardDatabaseLoadingFailed(); // bring up the settings dialog
|
|
||||||
}
|
|
||||||
|
|
||||||
reloadDatabaseMutex->unlock();
|
|
||||||
return loadStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardDatabase::refreshPreferredPrintings()
|
|
||||||
{
|
|
||||||
for (const CardInfoPtr &card : cards) {
|
|
||||||
card->setPixmapCacheKey(QLatin1String("card_") + QString(card->getName()) + QString("_") +
|
|
||||||
QString(getPreferredPrintingProviderIdForCard(card->getName())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CardInfoPerSet CardDatabase::getPreferredSetForCard(const QString &cardName) const
|
|
||||||
{
|
|
||||||
CardInfoPtr cardInfo = getCard(cardName);
|
|
||||||
if (!cardInfo) {
|
|
||||||
return CardInfoPerSet(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
CardInfoPerSetMap setMap = cardInfo->getSets();
|
|
||||||
if (setMap.empty()) {
|
|
||||||
return CardInfoPerSet(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
CardSetPtr preferredSet = nullptr;
|
|
||||||
CardInfoPerSet preferredCard;
|
|
||||||
SetPriorityComparator comparator;
|
|
||||||
|
|
||||||
for (const auto &cardInfoPerSetList : setMap) {
|
|
||||||
for (auto &cardInfoForSet : cardInfoPerSetList) {
|
|
||||||
CardSetPtr currentSet = cardInfoForSet.getPtr();
|
|
||||||
if (!preferredSet || comparator(currentSet, preferredSet)) {
|
|
||||||
preferredSet = currentSet;
|
|
||||||
preferredCard = cardInfoForSet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (preferredSet) {
|
|
||||||
return preferredCard;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CardInfoPerSet(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
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 (const auto &cardInfoPerSetList : setMap) {
|
|
||||||
for (auto &cardInfoForSet : cardInfoPerSetList) {
|
|
||||||
if (cardInfoForSet.getProperty("uuid") == providerId) {
|
|
||||||
return cardInfoForSet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (providerId.isNull()) {
|
|
||||||
return getPreferredSetForCard(cardName);
|
|
||||||
}
|
|
||||||
|
|
||||||
return CardInfoPerSet(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
CardInfoPerSet CardDatabase::getSpecificSetForCard(const QString &cardName,
|
|
||||||
const QString &setShortName,
|
|
||||||
const QString &collectorNumber) const
|
|
||||||
{
|
|
||||||
CardInfoPtr cardInfo = getCard(cardName);
|
|
||||||
if (!cardInfo) {
|
|
||||||
return CardInfoPerSet(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
CardInfoPerSetMap setMap = cardInfo->getSets();
|
|
||||||
if (setMap.empty()) {
|
|
||||||
return CardInfoPerSet(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto &cardInfoPerSetList : setMap) {
|
|
||||||
for (auto &cardInfoForSet : cardInfoPerSetList) {
|
|
||||||
if (cardInfoForSet.getPtr()->getShortName() == setShortName &&
|
|
||||||
cardInfoForSet.getProperty("num") == collectorNumber) {
|
|
||||||
return cardInfoForSet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return CardInfoPerSet(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CardDatabase::getPreferredPrintingProviderIdForCard(const QString &cardName)
|
|
||||||
{
|
|
||||||
CardInfoPerSet preferredSetCardInfo = getPreferredSetForCard(cardName);
|
|
||||||
QString preferredPrintingProviderId = preferredSetCardInfo.getProperty(QString("uuid"));
|
|
||||||
if (preferredPrintingProviderId.isEmpty()) {
|
|
||||||
CardInfoPtr defaultCardInfo = getCard(cardName);
|
|
||||||
if (defaultCardInfo.isNull()) {
|
|
||||||
return cardName;
|
|
||||||
}
|
|
||||||
return defaultCardInfo->getName();
|
|
||||||
}
|
|
||||||
return preferredPrintingProviderId;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CardDatabase::isProviderIdForPreferredPrinting(const QString &cardName, const QString &providerId)
|
|
||||||
{
|
|
||||||
if (providerId.startsWith("card_")) {
|
|
||||||
return providerId ==
|
|
||||||
QLatin1String("card_") + cardName + QString("_") + getPreferredPrintingProviderIdForCard(cardName);
|
|
||||||
}
|
|
||||||
return providerId == getPreferredPrintingProviderIdForCard(cardName);
|
|
||||||
}
|
|
||||||
|
|
||||||
CardInfoPerSet CardDatabase::getSetInfoForCard(const CardInfoPtr &_card)
|
|
||||||
{
|
|
||||||
const CardInfoPerSetMap &setMap = _card->getSets();
|
|
||||||
if (setMap.empty()) {
|
|
||||||
return CardInfoPerSet(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto &cardInfoPerSetList : setMap) {
|
|
||||||
for (const auto &cardInfoForSet : cardInfoPerSetList) {
|
|
||||||
if (QLatin1String("card_") + _card->getName() + QString("_") + cardInfoForSet.getProperty("uuid") ==
|
|
||||||
_card->getPixmapCacheKey()) {
|
|
||||||
return cardInfoForSet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return CardInfoPerSet(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardDatabase::refreshCachedReverseRelatedCards()
|
|
||||||
{
|
|
||||||
for (const CardInfoPtr &card : cards)
|
|
||||||
card->resetReverseRelatedCards2Me();
|
|
||||||
|
|
||||||
for (const CardInfoPtr &card : cards) {
|
|
||||||
if (card->getReverseRelatedCards().isEmpty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (CardRelation *cardRelation : card->getReverseRelatedCards()) {
|
|
||||||
const QString &targetCard = cardRelation->getName();
|
|
||||||
if (!cards.contains(targetCard)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto *newCardRelation = new CardRelation(
|
|
||||||
card->getName(), cardRelation->getAttachType(), cardRelation->getIsCreateAllExclusion(),
|
|
||||||
cardRelation->getIsVariable(), cardRelation->getDefaultCount(), cardRelation->getIsPersistent());
|
|
||||||
cards.value(targetCard)->addReverseRelatedCards2Me(newCardRelation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList CardDatabase::getAllMainCardTypes() const
|
|
||||||
{
|
|
||||||
QSet<QString> types;
|
|
||||||
QHashIterator<QString, CardInfoPtr> cardIterator(cards);
|
|
||||||
while (cardIterator.hasNext()) {
|
|
||||||
types.insert(cardIterator.next().value()->getMainCardType());
|
|
||||||
}
|
|
||||||
return types.values();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardDatabase::checkUnknownSets()
|
|
||||||
{
|
|
||||||
auto _sets = getSetList();
|
|
||||||
|
|
||||||
if (_sets.getEnabledSetsNum()) {
|
|
||||||
// if some sets are first found on this run, ask the user
|
|
||||||
int numUnknownSets = _sets.getUnknownSetsNum();
|
|
||||||
QStringList unknownSetNames = _sets.getUnknownSetsNames();
|
|
||||||
if (numUnknownSets > 0) {
|
|
||||||
emit cardDatabaseNewSetsFound(numUnknownSets, unknownSetNames);
|
|
||||||
} else {
|
|
||||||
_sets.markAllAsKnown();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// No set enabled. Probably this is the first time running trice
|
|
||||||
_sets.guessSortKeys();
|
|
||||||
_sets.sortByKey();
|
|
||||||
_sets.enableAll();
|
|
||||||
notifyEnabledSetsChanged();
|
|
||||||
|
|
||||||
emit cardDatabaseAllNewSetsEnabled();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardDatabase::enableAllUnknownSets()
|
|
||||||
{
|
|
||||||
auto _sets = getSetList();
|
|
||||||
_sets.enableAllUnknown();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardDatabase::markAllSetsAsKnown()
|
|
||||||
{
|
|
||||||
auto _sets = getSetList();
|
|
||||||
_sets.markAllAsKnown();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardDatabase::notifyEnabledSetsChanged()
|
|
||||||
{
|
|
||||||
// refresh the list of cached set names
|
|
||||||
for (const CardInfoPtr &card : cards)
|
|
||||||
card->refreshCachedSetNames();
|
|
||||||
|
|
||||||
// inform the carddatabasemodels that they need to re-check their list of cards
|
|
||||||
emit cardDatabaseEnabledSetsChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CardDatabase::saveCustomTokensToFile()
|
|
||||||
{
|
|
||||||
QString fileName =
|
|
||||||
SettingsCache::instance().getCustomCardDatabasePath() + "/" + CardDatabase::TOKENS_SETNAME + ".xml";
|
|
||||||
|
|
||||||
SetNameMap tmpSets;
|
|
||||||
CardSetPtr customTokensSet = getSet(CardDatabase::TOKENS_SETNAME);
|
|
||||||
tmpSets.insert(CardDatabase::TOKENS_SETNAME, customTokensSet);
|
|
||||||
|
|
||||||
CardNameMap tmpCards;
|
|
||||||
for (const CardInfoPtr &card : cards) {
|
|
||||||
if (card->getSets().contains(CardDatabase::TOKENS_SETNAME)) {
|
|
||||||
tmpCards.insert(card->getName(), card);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
availableParsers.first()->saveToFile(tmpSets, tmpCards, fileName);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
CardRelation::CardRelation(const QString &_name,
|
CardRelation::CardRelation(const QString &_name,
|
||||||
AttachType _attachType,
|
AttachType _attachType,
|
||||||
bool _isCreateAllExclusion,
|
bool _isCreateAllExclusion,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
#ifndef CARDDATABASE_H
|
#ifndef CARD_INFO_H
|
||||||
#define CARDDATABASE_H
|
#define CARD_INFO_H
|
||||||
|
|
||||||
#include <QBasicMutex>
|
|
||||||
#include <QDate>
|
#include <QDate>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
|
@ -11,14 +10,10 @@
|
||||||
#include <QSharedPointer>
|
#include <QSharedPointer>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QVector>
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
inline Q_LOGGING_CATEGORY(CardDatabaseLog, "card_database");
|
inline Q_LOGGING_CATEGORY(CardInfoLog, "card_info");
|
||||||
inline Q_LOGGING_CATEGORY(CardDatabaseLoadingLog, "card_database.loading");
|
|
||||||
inline Q_LOGGING_CATEGORY(CardDatabaseLoadingSuccessOrFailureLog, "card_database.loading.success_or_failure");
|
|
||||||
|
|
||||||
class CardDatabase;
|
|
||||||
class CardInfo;
|
class CardInfo;
|
||||||
class CardInfoPerSet;
|
class CardInfoPerSet;
|
||||||
class CardSet;
|
class CardSet;
|
||||||
|
|
@ -418,111 +413,6 @@ signals:
|
||||||
void cardInfoChanged(CardInfoPtr card);
|
void cardInfoChanged(CardInfoPtr card);
|
||||||
};
|
};
|
||||||
|
|
||||||
enum LoadStatus
|
|
||||||
{
|
|
||||||
Ok,
|
|
||||||
VersionTooOld,
|
|
||||||
Invalid,
|
|
||||||
NotLoaded,
|
|
||||||
FileError,
|
|
||||||
NoCards
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef QHash<QString, CardInfoPtr> CardNameMap;
|
|
||||||
typedef QHash<QString, CardSetPtr> SetNameMap;
|
|
||||||
|
|
||||||
class CardDatabase : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
protected:
|
|
||||||
/*
|
|
||||||
* The cards, indexed by name.
|
|
||||||
*/
|
|
||||||
CardNameMap cards;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The cards, indexed by their simple name.
|
|
||||||
*/
|
|
||||||
CardNameMap simpleNameCards;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The sets, indexed by short name.
|
|
||||||
*/
|
|
||||||
SetNameMap sets;
|
|
||||||
|
|
||||||
LoadStatus loadStatus;
|
|
||||||
|
|
||||||
QVector<ICardDatabaseParser *> availableParsers;
|
|
||||||
|
|
||||||
private:
|
|
||||||
CardInfoPtr getCardFromMap(const CardNameMap &cardMap, const QString &cardName) const;
|
|
||||||
void checkUnknownSets();
|
|
||||||
void refreshCachedReverseRelatedCards();
|
|
||||||
|
|
||||||
QBasicMutex *reloadDatabaseMutex = new QBasicMutex(), *clearDatabaseMutex = new QBasicMutex(),
|
|
||||||
*loadFromFileMutex = new QBasicMutex(), *addCardMutex = new QBasicMutex(),
|
|
||||||
*removeCardMutex = new QBasicMutex();
|
|
||||||
|
|
||||||
public:
|
|
||||||
static const char *TOKENS_SETNAME;
|
|
||||||
|
|
||||||
explicit CardDatabase(QObject *parent = nullptr);
|
|
||||||
~CardDatabase() override;
|
|
||||||
void clear();
|
|
||||||
void removeCard(CardInfoPtr card);
|
|
||||||
[[nodiscard]] CardInfoPtr getCard(const QString &cardName) const;
|
|
||||||
[[nodiscard]] QList<CardInfoPtr> getCards(const QStringList &cardNames) const;
|
|
||||||
QList<CardInfoPtr> getCardsByNameAndProviderId(const QMap<QString, QString> &cardNames) const;
|
|
||||||
[[nodiscard]] CardInfoPtr getCardByNameAndProviderId(const QString &cardName, const QString &providerId) const;
|
|
||||||
[[nodiscard]] CardInfoPerSet getPreferredSetForCard(const QString &cardName) const;
|
|
||||||
[[nodiscard]] CardInfoPerSet getSpecificSetForCard(const QString &cardName, const QString &providerId) const;
|
|
||||||
CardInfoPerSet
|
|
||||||
getSpecificSetForCard(const QString &cardName, const QString &setShortName, const QString &collectorNumber) const;
|
|
||||||
QString getPreferredPrintingProviderIdForCard(const QString &cardName);
|
|
||||||
[[nodiscard]] CardInfoPtr guessCard(const QString &cardName, const QString &providerId = QString()) const;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get a card by its simple name. The name will be simplified in this
|
|
||||||
* function, so you don't need to simplify it beforehand.
|
|
||||||
*/
|
|
||||||
[[nodiscard]] CardInfoPtr getCardBySimpleName(const QString &cardName) const;
|
|
||||||
|
|
||||||
CardSetPtr getSet(const QString &setName);
|
|
||||||
bool isProviderIdForPreferredPrinting(const QString &cardName, const QString &providerId);
|
|
||||||
static CardInfoPerSet getSetInfoForCard(const CardInfoPtr &_card);
|
|
||||||
const CardNameMap &getCardList() const
|
|
||||||
{
|
|
||||||
return cards;
|
|
||||||
}
|
|
||||||
SetList getSetList() const;
|
|
||||||
LoadStatus loadFromFile(const QString &fileName);
|
|
||||||
bool saveCustomTokensToFile();
|
|
||||||
QStringList getAllMainCardTypes() const;
|
|
||||||
LoadStatus getLoadStatus() const
|
|
||||||
{
|
|
||||||
return loadStatus;
|
|
||||||
}
|
|
||||||
void enableAllUnknownSets();
|
|
||||||
void markAllSetsAsKnown();
|
|
||||||
void notifyEnabledSetsChanged();
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
LoadStatus loadCardDatabases();
|
|
||||||
void refreshPreferredPrintings();
|
|
||||||
void addCard(CardInfoPtr card);
|
|
||||||
void addSet(CardSetPtr set);
|
|
||||||
protected slots:
|
|
||||||
LoadStatus loadCardDatabase(const QString &path);
|
|
||||||
signals:
|
|
||||||
void cardDatabaseLoadingFinished();
|
|
||||||
void cardDatabaseLoadingFailed();
|
|
||||||
void cardDatabaseNewSetsFound(int numUnknownSets, QStringList unknownSetsNames);
|
|
||||||
void cardDatabaseAllNewSetsEnabled();
|
|
||||||
void cardDatabaseEnabledSetsChanged();
|
|
||||||
void cardAdded(CardInfoPtr card);
|
|
||||||
void cardRemoved(CardInfoPtr card);
|
|
||||||
};
|
|
||||||
|
|
||||||
class CardRelation : public QObject
|
class CardRelation : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ set(dbconverter_SOURCES
|
||||||
../cockatrice/src/game/cards/card_database_parser/card_database_parser.cpp
|
../cockatrice/src/game/cards/card_database_parser/card_database_parser.cpp
|
||||||
../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_3.cpp
|
../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_3.cpp
|
||||||
../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_4.cpp
|
../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_4.cpp
|
||||||
|
../cockatrice/src/game/cards/card_info.cpp
|
||||||
../cockatrice/src/settings/settings_manager.cpp
|
../cockatrice/src/settings/settings_manager.cpp
|
||||||
${VERSION_STRING_CPP}
|
${VERSION_STRING_CPP}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ set(oracle_SOURCES
|
||||||
src/qt-json/json.cpp
|
src/qt-json/json.cpp
|
||||||
../cockatrice/src/game/cards/card_database.cpp
|
../cockatrice/src/game/cards/card_database.cpp
|
||||||
../cockatrice/src/game/cards/card_database_manager.cpp
|
../cockatrice/src/game/cards/card_database_manager.cpp
|
||||||
|
../cockatrice/src/game/cards/card_info.cpp
|
||||||
../cockatrice/src/client/ui/picture_loader/picture_loader.cpp
|
../cockatrice/src/client/ui/picture_loader/picture_loader.cpp
|
||||||
../cockatrice/src/client/ui/picture_loader/picture_loader_worker.cpp
|
../cockatrice/src/client/ui/picture_loader/picture_loader_worker.cpp
|
||||||
../cockatrice/src/client/ui/picture_loader/picture_to_load.cpp
|
../cockatrice/src/client/ui/picture_loader/picture_to_load.cpp
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ add_executable(
|
||||||
../../cockatrice/src/game/cards/card_database_parser/card_database_parser.cpp
|
../../cockatrice/src/game/cards/card_database_parser/card_database_parser.cpp
|
||||||
../../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_3.cpp
|
../../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_3.cpp
|
||||||
../../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_4.cpp
|
../../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_4.cpp
|
||||||
|
../../cockatrice/src/game/cards/card_info.cpp
|
||||||
../../cockatrice/src/settings/settings_manager.cpp
|
../../cockatrice/src/settings/settings_manager.cpp
|
||||||
carddatabase_test.cpp
|
carddatabase_test.cpp
|
||||||
mocks.cpp
|
mocks.cpp
|
||||||
|
|
@ -35,6 +36,7 @@ add_executable(
|
||||||
../../cockatrice/src/game/cards/card_database_parser/card_database_parser.cpp
|
../../cockatrice/src/game/cards/card_database_parser/card_database_parser.cpp
|
||||||
../../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_3.cpp
|
../../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_3.cpp
|
||||||
../../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_4.cpp
|
../../cockatrice/src/game/cards/card_database_parser/cockatrice_xml_4.cpp
|
||||||
|
../../cockatrice/src/game/cards/card_info.cpp
|
||||||
../../cockatrice/src/game/filters/filter_card.cpp
|
../../cockatrice/src/game/filters/filter_card.cpp
|
||||||
../../cockatrice/src/game/filters/filter_string.cpp
|
../../cockatrice/src/game/filters/filter_string.cpp
|
||||||
../../cockatrice/src/game/filters/filter_tree.cpp
|
../../cockatrice/src/game/filters/filter_tree.cpp
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue