mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-03-21 17:55:21 -05:00
Some checks failed
Build Desktop / Configure (push) Has been cancelled
Build Docker Image / amd64 & arm64 (push) Has been cancelled
Build Desktop / ${{matrix.distro}} ${{matrix.version}} (Debian, DEB, 11) (push) Has been cancelled
Build Desktop / ${{matrix.distro}} ${{matrix.version}} (Debian, DEB, 13) (push) Has been cancelled
Build Desktop / ${{matrix.distro}} ${{matrix.version}} (Debian, DEB, skip, 12) (push) Has been cancelled
Build Desktop / ${{matrix.distro}} ${{matrix.version}} (Fedora, RPM, 43) (push) Has been cancelled
Build Desktop / ${{matrix.distro}} ${{matrix.version}} (Fedora, RPM, skip, 42) (push) Has been cancelled
Build Desktop / ${{matrix.distro}} ${{matrix.version}} (Servatrice_Debian, DEB, yes, skip, 11) (push) Has been cancelled
Build Desktop / ${{matrix.distro}} ${{matrix.version}} (Ubuntu, DEB, 24.04) (push) Has been cancelled
Build Desktop / ${{matrix.distro}} ${{matrix.version}} (Ubuntu, DEB, skip, 22.04) (push) Has been cancelled
Build Desktop / ${{matrix.distro}} ${{matrix.version}} (yes, Arch, skip) (push) Has been cancelled
Build Desktop / ${{matrix.os}} ${{matrix.target}}${{ matrix.soc == 'Intel' && ' Intel' || '' }}${{ matrix.type == 'Debug' && ' Debug' || '' }} (Windows10-installer, true, Visual Studio 17 2022, x64, 1, Windows, -Win10, win64_msvc2019_64, qtimageformats qtmultimedia qt… (push) Has been cancelled
Build Desktop / ${{matrix.os}} ${{matrix.target}}${{ matrix.soc == 'Intel' && ' Intel' || '' }}${{ matrix.type == 'Debug' && ' Debug' || '' }} (Windows7-installer, true, Visual Studio 17 2022, x64, 1, Windows, -Win7, win64_msvc2019_64, 5.15.*, windows-2022, 7, Release) (push) Has been cancelled
Build Desktop / ${{matrix.os}} ${{matrix.target}}${{ matrix.soc == 'Intel' && ' Intel' || '' }}${{ matrix.type == 'Debug' && ' Debug' || '' }} (false, Ninja, macOS, clang_64, qtimageformats qtmultimedia qtwebsockets, 6.6.*, macos-15, Apple, 15, Debug, 1, 16.4) (push) Has been cancelled
Build Desktop / ${{matrix.os}} ${{matrix.target}}${{ matrix.soc == 'Intel' && ' Intel' || '' }}${{ matrix.type == 'Debug' && ' Debug' || '' }} (macOS13_Intel-package, false, Ninja, 1, macOS, 13, -macOS13_Intel, clang_64, qtimageformats qtmultimedia qtwebsockets, 6.6.*… (push) Has been cancelled
Build Desktop / ${{matrix.os}} ${{matrix.target}}${{ matrix.soc == 'Intel' && ' Intel' || '' }}${{ matrix.type == 'Debug' && ' Debug' || '' }} (macOS14-package, false, Ninja, 1, macOS, -macOS14, clang_64, qtimageformats qtmultimedia qtwebsockets, 6.6.*, macos-14, Appl… (push) Has been cancelled
Build Desktop / ${{matrix.os}} ${{matrix.target}}${{ matrix.soc == 'Intel' && ' Intel' || '' }}${{ matrix.type == 'Debug' && ' Debug' || '' }} (macOS15-package, false, Ninja, 1, macOS, -macOS15, clang_64, qtimageformats qtmultimedia qtwebsockets, 6.6.*, macos-15, Appl… (push) Has been cancelled
* [Card DB] Properly pass along set priority controller to parsers Took 16 minutes Took 35 seconds * More adjustments. Took 13 minutes --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
157 lines
5.4 KiB
C++
157 lines
5.4 KiB
C++
#include "card_database_loader.h"
|
|
|
|
#include "card_database.h"
|
|
#include "parser/cockatrice_xml_3.h"
|
|
#include "parser/cockatrice_xml_4.h"
|
|
|
|
#include <QDebug>
|
|
#include <QDirIterator>
|
|
#include <QFile>
|
|
#include <QTime>
|
|
|
|
CardDatabaseLoader::CardDatabaseLoader(QObject *parent,
|
|
CardDatabase *db,
|
|
ICardDatabasePathProvider *_pathProvider,
|
|
ICardPreferenceProvider *_preferenceProvider,
|
|
ICardSetPriorityController *_priorityController)
|
|
: QObject(parent), database(db), pathProvider(_pathProvider)
|
|
{
|
|
// instantiate available parsers here and connect them to the database
|
|
availableParsers << new CockatriceXml4Parser(_preferenceProvider, _priorityController);
|
|
availableParsers << new CockatriceXml3Parser(_priorityController);
|
|
|
|
for (auto *p : availableParsers) {
|
|
// connect parser outputs to the database adders
|
|
connect(p, &ICardDatabaseParser::addCard, database, &CardDatabase::addCard, Qt::DirectConnection);
|
|
connect(p, &ICardDatabaseParser::addSet, database, &CardDatabase::addSet, Qt::DirectConnection);
|
|
connect(p, &ICardDatabaseParser::addFormat, database, &CardDatabase::addFormat, Qt::DirectConnection);
|
|
}
|
|
|
|
// when SettingsCache's path changes, trigger reloads
|
|
connect(pathProvider, &ICardDatabasePathProvider::cardDatabasePathChanged, this,
|
|
&CardDatabaseLoader::loadCardDatabases);
|
|
}
|
|
|
|
CardDatabaseLoader::~CardDatabaseLoader()
|
|
{
|
|
qDeleteAll(availableParsers);
|
|
availableParsers.clear();
|
|
}
|
|
|
|
LoadStatus CardDatabaseLoader::loadFromFile(const QString &fileName)
|
|
{
|
|
QFile file(fileName);
|
|
if (!file.open(QIODevice::ReadOnly)) {
|
|
return FileError;
|
|
}
|
|
|
|
for (auto parser : availableParsers) {
|
|
file.reset();
|
|
if (parser->getCanParseFile(fileName, file)) {
|
|
file.reset();
|
|
parser->parseFile(file);
|
|
return Ok;
|
|
}
|
|
}
|
|
|
|
return Invalid;
|
|
}
|
|
|
|
LoadStatus CardDatabaseLoader::loadCardDatabase(const QString &path)
|
|
{
|
|
auto startTime = QTime::currentTime();
|
|
LoadStatus tempLoadStatus = NotLoaded;
|
|
if (!path.isEmpty()) {
|
|
QMutexLocker locker(loadFromFileMutex);
|
|
tempLoadStatus = loadFromFile(path);
|
|
}
|
|
|
|
int msecs = startTime.msecsTo(QTime::currentTime());
|
|
qCInfo(CardDatabaseLoadingLog) << "Loaded card database: Path =" << path << "Status =" << tempLoadStatus
|
|
<< "Cards =" << (database ? database->cards.size() : 0)
|
|
<< "Sets =" << (database ? database->sets.size() : 0) << QString("%1ms").arg(msecs);
|
|
|
|
return tempLoadStatus;
|
|
}
|
|
|
|
LoadStatus CardDatabaseLoader::loadCardDatabases()
|
|
{
|
|
QMutexLocker locker(reloadDatabaseMutex);
|
|
|
|
if (!database) {
|
|
qCWarning(CardDatabaseLoadingLog) << "Loader has no database pointer";
|
|
emit loadingFailed();
|
|
return FileError;
|
|
}
|
|
emit loadingStarted();
|
|
qCInfo(CardDatabaseLoadingLog) << "Card Database Loading Started";
|
|
|
|
database->clear(); // remove old db
|
|
|
|
LoadStatus loadStatus = loadCardDatabase(pathProvider->getCardDatabasePath()); // load main card database
|
|
loadCardDatabase(pathProvider->getTokenDatabasePath()); // load tokens database
|
|
loadCardDatabase(pathProvider->getSpoilerCardDatabasePath()); // load spoilers database
|
|
|
|
// find all custom card databases, recursively & following symlinks
|
|
// then load them alphabetically
|
|
const QStringList customPaths = collectCustomDatabasePaths();
|
|
for (int i = 0; i < customPaths.size(); ++i) {
|
|
const auto &p = customPaths.at(i);
|
|
qCInfo(CardDatabaseLoadingLog) << "Loading Custom Set" << i << "(" << p << ")";
|
|
loadCardDatabase(p);
|
|
}
|
|
|
|
// AFTER all the cards have been loaded
|
|
|
|
// resolve the reverse-related tags
|
|
|
|
database->refreshCachedReverseRelatedCards();
|
|
|
|
if (loadStatus == Ok) {
|
|
database->checkUnknownSets(); // update deck editors, etc
|
|
qCInfo(CardDatabaseLoadingSuccessOrFailureLog) << "Card Database Loading Success";
|
|
emit loadingFinished();
|
|
} else {
|
|
qCInfo(CardDatabaseLoadingSuccessOrFailureLog) << "Card Database Loading Failed";
|
|
emit loadingFailed(); // bring up the settings dialog
|
|
}
|
|
|
|
return loadStatus;
|
|
}
|
|
|
|
QStringList CardDatabaseLoader::collectCustomDatabasePaths() const
|
|
{
|
|
QDirIterator it(pathProvider->getCustomCardDatabasePath(), {"*.xml"}, QDir::Files,
|
|
QDirIterator::Subdirectories | QDirIterator::FollowSymlinks);
|
|
|
|
QStringList paths;
|
|
while (it.hasNext())
|
|
paths << it.next();
|
|
paths.sort();
|
|
return paths;
|
|
}
|
|
|
|
bool CardDatabaseLoader::saveCustomTokensToFile()
|
|
{
|
|
if (!database) {
|
|
qCWarning(CardDatabaseLog) << "saveCustomTokensToFile: database pointer missing";
|
|
return false;
|
|
}
|
|
|
|
QString fileName = pathProvider->getCustomCardDatabasePath() + "/" + CardSet::TOKENS_SETNAME + ".xml";
|
|
|
|
SetNameMap tmpSets;
|
|
CardSetPtr customTokensSet = database->getSet(CardSet::TOKENS_SETNAME);
|
|
tmpSets.insert(CardSet::TOKENS_SETNAME, customTokensSet);
|
|
|
|
CardNameMap tmpCards;
|
|
for (const CardInfoPtr &card : database->cards) {
|
|
if (card->getSets().contains(CardSet::TOKENS_SETNAME)) {
|
|
tmpCards.insert(card->getName(), card);
|
|
}
|
|
}
|
|
|
|
availableParsers.first()->saveToFile(FormatRulesNameMap(), tmpSets, tmpCards, fileName);
|
|
return true;
|
|
}
|