Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/emulationstation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ void EmulationStation::assembleList(QString &finalOutput,
int dotMod = 1 + gameEntries.length() * 0.1;

finalOutput.append("<?xml version=\"1.0\"?>\n");
finalOutput.append(taintGamelist());
finalOutput.append("<gameList>\n");

for (auto &entry : gameEntries) {
Expand Down
2 changes: 2 additions & 0 deletions src/emulationstation.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ class EmulationStation : public AbstractFrontend {
GameEntry::Types supportedMedia() override;
QString elem(const QString &elem, const QString &data, bool addEmptyElem,
bool isPath = false);
// ES-DE may return <alternativeEmulator/> element
virtual QString taintGamelist() { return ""; };

private:
QString createXml(GameEntry &entry);
Expand Down
73 changes: 73 additions & 0 deletions src/esde.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,21 @@
#include "esde.h"

#include "emulationstation.h"
#include "xmlreader.h"

#include <QDebug>
#include <QDir>
#include <QProcessEnvironment>
#include <QRegularExpression>
#include <QStringBuilder>
#include <QStringList>
#include <QTemporaryFile>

static const QRegularExpression RE_ALT_EMU =
QRegularExpression("(<alternativeEmulator>)(.*?)(</"
"alternativeEmulator>)|(<alternativeEmulator/>)",
QRegularExpression::CaseInsensitiveOption |
QRegularExpression::DotMatchesEverythingOption);

Esde::Esde() {}

Expand All @@ -40,6 +50,69 @@ inline const QString baseFolder() {
return QString(QDir::homePath() % "/ES-DE");
}

bool Esde::loadOldGameList(const QString &gameListFileString) {
XmlReader gameListReader = XmlReader(config->inputFolder);

QFile esDeGamelist = QFile(gameListFileString);
altEmu = "";
// Coding Horror: For some reason ES-DE decided to create a gamelist file
// with two root XML elements. This clearly violates the XML standard!
// However, to keep the UX for ES-DE users smooth, this is a workaround. cf.
// #219 and https://gitlab.com/es-de/emulationstation-de/-/issues/1705
if (esDeGamelist.open(QIODevice::ReadOnly)) {
// assume the offending part in first 1K
QString clutter = esDeGamelist.read(1024);
esDeGamelist.close();
QRegularExpressionMatch m = RE_ALT_EMU.match(clutter);
if (m.hasMatch()) {
altEmu = m.captured(0).replace("\t", " ") % "\n";
qDebug() << "Non-XML compliant ES-DE gamelist detected, applying "
"workaround";
// move orig file
QString tmpFn;
if (QTemporaryFile tmpFile; tmpFile.open()) {
tmpFn = tmpFile.fileName();
}
if (!QFile::copy(gameListFileString, tmpFn)) {
qDebug() << "Copy failed from" << gameListFileString << "to"
<< tmpFn;
return false;
}
if (!QFile::remove(gameListFileString)) {
qDebug() << "Remove failed, file" << gameListFileString;
return false;
}
QFile invalidXmlFile = QFile(tmpFn);
if (invalidXmlFile.open(QIODevice::ReadOnly) &&
esDeGamelist.open(QIODevice::ReadWrite | QIODevice::Text)) {
// create a standard compliant XML
QString part;
bool replaced = false;
while (!invalidXmlFile.atEnd()) {
part = invalidXmlFile.read(4096);
if (QString tmpPart = part.remove(RE_ALT_EMU);
!replaced && tmpPart.length() != part.length()) {
replaced = true;
part = tmpPart;
};
esDeGamelist.write(part.toStdString().c_str(),
part.length());
}
esDeGamelist.close();
invalidXmlFile.close();
qDebug() << "Gamelist now XML compliant, removed temporarily:"
<< altEmu;
}
invalidXmlFile.remove();
}
}
if (gameListReader.setFile(gameListFileString)) {
oldEntries = gameListReader.getEntries(extraGamelistTags(true));
return true;
}
return false;
}

void Esde::setConfig(Settings *config) {
this->config = config;
if (config->scraper == "cache") {
Expand Down
5 changes: 5 additions & 0 deletions src/esde.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,18 @@ class Esde : public EmulationStation {
QString getInputFolder() override;
QString getGameListFolder() override;
QString getMediaFolder() override;
bool loadOldGameList(const QString &gameListFileString) override;

protected:
QStringList createEsVariantXml(const GameEntry &entry) override;
QStringList extraGamelistTags(bool isFolder) override;
GameEntry::Types supportedMedia() override;
bool addEmptyElement() override { return false; };
bool gamelistHasMediaPaths() override { return false; };
QString taintGamelist() override { return altEmu; };

private:
QString altEmu;
};

#endif // ESDE_H
21 changes: 15 additions & 6 deletions src/gameentry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,18 +146,27 @@ void GameEntry::setEsExtra(const QString &tagName, QString value,
};

const QStringList GameEntry::extraElemNames(Format type, bool isFolder) const {
QStringList tagNames;
tagNames += {"favorite", "hidden", "playcount",
"lastplayed", "kidgame", "sortname"};
QStringList tagNames = QStringList({"favorite", "hidden", "kidgame",
"lastplayed", "playcount", "sortname"});
if (type == Format::RETROPIE) {
return tagNames;
}
// ES-DE
tagNames +=
{"collectionsortname", "completed", "broken", "nogamecount",
"nomultiscrape", "hidemetadata", "controller", "altemulator"};
// cf. src/es-app/MetaData.cpp
tagNames += {"altemulator", "broken", "collectionsortname",
"completed", "controller", "hidemetadata",
"nogamecount", "nomultiscrape", "playtime"};
if (isFolder) {
tagNames.append("folderlink");
// these are not for folders but don't care to remove them from tagNames
// as these tags won't be around initially anyway.
//
// "altemulator"
// "collectionsortname"
// "nogamecount"
// "playcount"
// "playtime"
// "sortname"
}
return tagNames;
};
Loading