diff --git a/launcher/Application.cpp b/launcher/Application.cpp index ac6d7a114..601ccaeff 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -241,7 +241,7 @@ void appDebugOutput(QtMsgType type, const QMessageLogContext& context, const QSt QString out = qFormatLogMessage(type, context, msg); if (APPLICATION->logModel) { - APPLICATION->logModel->append(messageLevelFromQtMsgType(type), out); + APPLICATION->logModel->append(MessageLevel::fromQtMsgType(type), out); } out += QChar::LineFeed; diff --git a/launcher/MessageLevel.cpp b/launcher/MessageLevel.cpp index 913902517..7f2b89339 100644 --- a/launcher/MessageLevel.cpp +++ b/launcher/MessageLevel.cpp @@ -1,6 +1,6 @@ #include "MessageLevel.h" -MessageLevel messageLevelFromName(const QString& levelName) +MessageLevel MessageLevel::fromName(const QString& levelName) { QString name = levelName.toUpper(); if (name == "LAUNCHER") @@ -25,7 +25,7 @@ MessageLevel messageLevelFromName(const QString& levelName) return MessageLevel::Unknown; } -MessageLevel messageLevelFromQtMsgType(QtMsgType type) +MessageLevel MessageLevel::fromQtMsgType(const QtMsgType& type) { switch (type) { case QtDebugMsg: @@ -43,18 +43,20 @@ MessageLevel messageLevelFromQtMsgType(QtMsgType type) } } +/* Get message level from a line. Line is modified if it was successful. */ MessageLevel messageLevelFromLine(QString& line) { // Level prefix int endmark = line.indexOf("]!"); if (line.startsWith("!![") && endmark != -1) { - auto level = messageLevelFromName(line.left(endmark).mid(3)); + auto level = MessageLevel::fromName(line.left(endmark).mid(3)); line = line.mid(endmark + 2); return level; } return MessageLevel::Unknown; } +/* Get message level from a line from the launcher log. Line is modified if it was successful. */ MessageLevel messageLevelFromLauncherLine(QString& line) { // Level prefix @@ -63,7 +65,7 @@ MessageLevel messageLevelFromLauncherLine(QString& line) ++startMark; int endmark = line.indexOf(":"); if (startMark < line.size() && endmark != -1) { - auto level = messageLevelFromName(line.left(endmark).mid(startMark)); + auto level = MessageLevel::fromName(line.left(endmark).mid(startMark)); line = line.mid(endmark + 2); return level; } diff --git a/launcher/MessageLevel.h b/launcher/MessageLevel.h index a79c36d02..6de96bc2e 100644 --- a/launcher/MessageLevel.h +++ b/launcher/MessageLevel.h @@ -2,26 +2,40 @@ #include #include +#include /** * @brief the MessageLevel Enum * defines what level a log message is */ -enum class MessageLevel { - Unknown, /**< No idea what this is or where it came from */ - StdOut, /**< Undetermined stderr messages */ - StdErr, /**< Undetermined stdout messages */ - Launcher, /**< Launcher Messages */ - Trace, /**< Trace Messages */ - Debug, /**< Debug Messages */ - Info, /**< Info Messages */ - Message, /**< Standard Messages */ - Warning, /**< Warnings */ - Error, /**< Errors */ - Fatal, /**< Fatal Errors */ +struct MessageLevel { + enum class Enum { + Unknown, /**< No idea what this is or where it came from */ + StdOut, /**< Undetermined stderr messages */ + StdErr, /**< Undetermined stdout messages */ + Launcher, /**< Launcher Messages */ + Trace, /**< Trace Messages */ + Debug, /**< Debug Messages */ + Info, /**< Info Messages */ + Message, /**< Standard Messages */ + Warning, /**< Warnings */ + Error, /**< Errors */ + Fatal, /**< Fatal Errors */ + }; + using enum Enum; + constexpr MessageLevel(Enum e = Unknown) : m_type(e) {} + static MessageLevel fromName(const QString& type); + static MessageLevel fromQtMsgType(const QtMsgType& type); + static MessageLevel fromLine(const QString& line); + inline bool isValid() const { return m_type != Unknown; } + std::strong_ordering operator<=>(const MessageLevel& other) const = default; + std::strong_ordering operator<=>(const MessageLevel::Enum& other) const { return m_type <=> other; } + explicit operator int() const { return static_cast(m_type); } + explicit operator MessageLevel::Enum() { return m_type; } + + private: + Enum m_type; }; -MessageLevel messageLevelFromName(const QString& levelName); -MessageLevel messageLevelFromQtMsgType(QtMsgType type); /* Get message level from a line. Line is modified if it was successful. */ MessageLevel messageLevelFromLine(QString& line); diff --git a/launcher/launch/LaunchTask.cpp b/launcher/launch/LaunchTask.cpp index 3f628ccb3..67227dcf2 100644 --- a/launcher/launch/LaunchTask.cpp +++ b/launcher/launch/LaunchTask.cpp @@ -217,7 +217,7 @@ shared_qobject_ptr LaunchTask::getLogModel() bool LaunchTask::parseXmlLogs(QString const& line, MessageLevel level) { LogParser* parser; - switch (level) { + switch (static_cast(level)) { case MessageLevel::StdErr: parser = &m_stderrParser; break; @@ -234,7 +234,7 @@ bool LaunchTask::parseXmlLogs(QString const& line, MessageLevel level) auto& model = *getLogModel(); model.append(MessageLevel::Error, tr("[Log4j Parse Error] Failed to parse log4j log event: %1").arg(err.value().errMessage)); return false; - } + } if (items.isEmpty()) return true; diff --git a/launcher/logs/LogParser.cpp b/launcher/logs/LogParser.cpp index cc7cd8b79..bab4b9b9f 100644 --- a/launcher/logs/LogParser.cpp +++ b/launcher/logs/LogParser.cpp @@ -60,7 +60,7 @@ std::optional LogParser::parseAttributes() entry.timestamp = QDateTime::fromSecsSinceEpoch(value.trimmed().toLongLong()); } else if (name == "level"_L1) { entry.levelText = value.trimmed().toString(); - entry.level = messageLevelFromName(entry.levelText); + entry.level = MessageLevel::fromName(entry.levelText); } else if (name == "thread"_L1) { entry.thread = value.trimmed().toString(); } @@ -329,7 +329,7 @@ MessageLevel LogParser::guessLevel(const QString& line, MessageLevel previous) QString timestamp = match.captured("timestamp"); QString levelStr = match.captured("level"); - return messageLevelFromName(levelStr); + return MessageLevel::fromName(levelStr); } else { // Old style forge logs if (line.contains("[INFO]") || line.contains("[CONFIG]") || line.contains("[FINE]") || line.contains("[FINER]") || diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp index 7aadb04a8..5467c84a6 100644 --- a/launcher/minecraft/mod/Mod.cpp +++ b/launcher/minecraft/mod/Mod.cpp @@ -195,9 +195,9 @@ auto Mod::mcVersions() const -> QString auto Mod::releaseType() const -> QString { if (metadata()) - return ModPlatform::indexedVersionTypeToString(metadata()->releaseType); + return metadata()->releaseType.toString(); - return ModPlatform::indexedVersionTypeToString(ModPlatform::IndexedVersionType::Unknown); + return ModPlatform::IndexedVersionType(ModPlatform::IndexedVersionType::Unknown).toString(); } auto Mod::description() const -> QString diff --git a/launcher/modplatform/ModIndex.cpp b/launcher/modplatform/ModIndex.cpp index 5750b631c..7d2c18d03 100644 --- a/launcher/modplatform/ModIndex.cpp +++ b/launcher/modplatform/ModIndex.cpp @@ -45,11 +45,11 @@ QList modLoaderTypesToList(ModLoaderTypes flags) return flagList; } -QString indexedVersionTypeToString(IndexedVersionType type) { - return s_indexed_version_type_names.key(type, "unknown"); +QString IndexedVersionType::toString() const { + return s_indexed_version_type_names.key(m_type, "unknown"); } -IndexedVersionType indexedVersionTypeFromString(const QString& type) { +IndexedVersionType IndexedVersionType::fromString(const QString& type) { return s_indexed_version_type_names.value(type, IndexedVersionType::Unknown); } diff --git a/launcher/modplatform/ModIndex.h b/launcher/modplatform/ModIndex.h index d6283a074..fc0f9780e 100644 --- a/launcher/modplatform/ModIndex.h +++ b/launcher/modplatform/ModIndex.h @@ -23,6 +23,7 @@ #include #include #include +#include #include class QIODevice; @@ -74,9 +75,22 @@ struct DonationData { QString url; }; -enum class IndexedVersionType { Unknown, Release = 1, Beta, Alpha }; -IndexedVersionType indexedVersionTypeFromString(const QString& type); -QString indexedVersionTypeToString(IndexedVersionType type); +struct IndexedVersionType { + enum class Enum { Unknown, Release = 1, Beta, Alpha }; + using enum Enum; + constexpr IndexedVersionType(Enum e = Unknown) : m_type(e) {} + static IndexedVersionType fromString(const QString& type); + inline bool isValid() const { return m_type != Unknown; } + std::strong_ordering operator<=>(const IndexedVersionType& other) const = default; + std::strong_ordering operator<=>(const IndexedVersionType::Enum& other) const { return m_type <=> other; } + QString toString() const; + explicit operator int() const { return static_cast(m_type); } + explicit operator IndexedVersionType::Enum() { return m_type; } + + private: + Enum m_type; +}; + struct Dependency { QVariant addonId; @@ -107,7 +121,8 @@ struct IndexedVersion { QString getVersionDisplayString() const { - auto release_type = version_type != IndexedVersionType::Unknown ? QString(" [%1]").arg(indexedVersionTypeToString(version_type)) : ""; + auto release_type = + version_type.isValid() ? QString(" [%1]").arg(version_type.toString()) : ""; auto versionStr = !version.contains(version_number) ? version_number : ""; QString gameVersion = ""; for (auto v : mcVersion) { diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp index dd8be5cae..128c7856b 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -145,7 +145,7 @@ ModPlatform::IndexedVersion Modrinth::loadIndexedPackVersion(QJsonObject& obj, Q } file.version = Json::requireString(obj, "name"); file.version_number = Json::requireString(obj, "version_number"); - file.version_type = ModPlatform::indexedVersionTypeFromString(Json::requireString(obj, "version_type")); + file.version_type = ModPlatform::IndexedVersionType::fromString(Json::requireString(obj, "version_type")); file.changelog = Json::requireString(obj, "changelog"); diff --git a/launcher/modplatform/packwiz/Packwiz.cpp b/launcher/modplatform/packwiz/Packwiz.cpp index d1cf25cc1..83ca0f4f2 100644 --- a/launcher/modplatform/packwiz/Packwiz.cpp +++ b/launcher/modplatform/packwiz/Packwiz.cpp @@ -198,7 +198,7 @@ void V1::updateModIndex(const QDir& index_dir, Mod& mod) { "side", ModPlatform::SideUtils::toString(mod.side).toStdString() }, { "x-prismlauncher-loaders", loaders }, { "x-prismlauncher-mc-versions", mcVersions }, - { "x-prismlauncher-release-type", ModPlatform::indexedVersionTypeToString(mod.releaseType).toStdString() }, + { "x-prismlauncher-release-type", mod.releaseType.toString().toStdString() }, { "x-prismlauncher-version-number", mod.version_number.toStdString() }, { "download", toml::table{ @@ -272,7 +272,7 @@ auto V1::getIndexForMod(const QDir& index_dir, QString slug) -> Mod mod.name = stringEntry(table, "name"); mod.filename = stringEntry(table, "filename"); mod.side = ModPlatform::SideUtils::fromString(stringEntry(table, "side")); - mod.releaseType = ModPlatform::indexedVersionTypeFromString(table["x-prismlauncher-release-type"].value_or("")); + mod.releaseType = ModPlatform::IndexedVersionType::fromString(table["x-prismlauncher-release-type"].value_or("")); if (auto loaders = table["x-prismlauncher-loaders"]; loaders && loaders.is_array()) { for (auto&& loader : *loaders.as_array()) { if (loader.is_string()) { diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index 181a9d486..4bd9b7051 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -186,8 +186,7 @@ void ResourceDownloadDialog::confirm() for (auto& task : selected) { auto extraInfo = dependencyExtraInfo.value(task->getPack()->addonId.toString()); confirm_dialog->appendResource({ task->getName(), task->getFilename(), ModPlatform::ProviderCapabilities::name(task->getProvider()), - extraInfo.required_by, ModPlatform::indexedVersionTypeToString(task->getVersion().version_type), - !extraInfo.maybe_installed }); + extraInfo.required_by, task->getVersion().version_type.toString(), !extraInfo.maybe_installed }); } if (confirm_dialog->exec()) { diff --git a/launcher/ui/dialogs/ResourceUpdateDialog.cpp b/launcher/ui/dialogs/ResourceUpdateDialog.cpp index ec275cc91..a460e9d35 100644 --- a/launcher/ui/dialogs/ResourceUpdateDialog.cpp +++ b/launcher/ui/dialogs/ResourceUpdateDialog.cpp @@ -453,8 +453,8 @@ void ResourceUpdateDialog::appendResource(CheckUpdateTask::Update const& info, Q if (info.new_version_type.has_value()) { auto new_version_type_item = new QTreeWidgetItem(item_top); - new_version_type_item->setText(0, tr("New Version Type: %1").arg(indexedVersionTypeToString(info.new_version_type.value()))); - new_version_type_item->setData(0, Qt::UserRole, indexedVersionTypeToString(info.new_version_type.value())); + new_version_type_item->setText(0, tr("New Version Type: %1").arg(info.new_version_type.value().toString())); + new_version_type_item->setData(0, Qt::UserRole, info.new_version_type.value().toString()); } if (!requiredBy.isEmpty()) { diff --git a/launcher/ui/pages/instance/LogPage.cpp b/launcher/ui/pages/instance/LogPage.cpp index 02be853c0..9f978ecb7 100644 --- a/launcher/ui/pages/instance/LogPage.cpp +++ b/launcher/ui/pages/instance/LogPage.cpp @@ -60,7 +60,7 @@ QVariant LogFormatProxyModel::data(const QModelIndex& index, int role) const case Qt::FontRole: return m_font; case Qt::ForegroundRole: { - auto level = static_cast(QIdentityProxyModel::data(index, LogModel::LevelRole).toInt()); + MessageLevel level = static_cast(QIdentityProxyModel::data(index, LogModel::LevelRole).toInt()); QColor result = colors.foreground.value(level); if (result.isValid()) @@ -69,7 +69,7 @@ QVariant LogFormatProxyModel::data(const QModelIndex& index, int role) const break; } case Qt::BackgroundRole: { - auto level = static_cast(QIdentityProxyModel::data(index, LogModel::LevelRole).toInt()); + MessageLevel level = static_cast(QIdentityProxyModel::data(index, LogModel::LevelRole).toInt()); QColor result = colors.background.value(level); if (result.isValid()) diff --git a/launcher/ui/pages/modplatform/ResourcePage.cpp b/launcher/ui/pages/modplatform/ResourcePage.cpp index 964e3b662..061e96491 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.cpp +++ b/launcher/ui/pages/modplatform/ResourcePage.cpp @@ -297,8 +297,8 @@ void ResourcePage::versionListUpdated(const QModelIndex& index) continue; auto versionText = version.version; - if (version.version_type != ModPlatform::IndexedVersionType::Unknown) { - versionText += QString(" [%1]").arg(ModPlatform::indexedVersionTypeToString(version.version_type)); + if (version.version_type.isValid()) { + versionText += QString(" [%1]").arg(version.version_type.toString()); } if (version.fileId == installedVersion) { versionText += tr(" [installed]", "Mod version select"); diff --git a/tests/XmlLogs_test.cpp b/tests/XmlLogs_test.cpp index 853c99341..31ffbba1c 100644 --- a/tests/XmlLogs_test.cpp +++ b/tests/XmlLogs_test.cpp @@ -50,7 +50,7 @@ class XmlLogParseTest : public QObject { QList shortTextLevels; shortTextLevels.reserve(24); std::transform(shortTextLevels_s.cbegin(), shortTextLevels_s.cend(), std::back_inserter(shortTextLevels), - [](const QString& line) { return messageLevelFromName(line.trimmed()); }); + [](const QString& line) { return MessageLevel::fromName(line.trimmed()); }); QString longXml = QString::fromUtf8(FS::read(FS::PathCombine(source, "TerraFirmaGreg-Modern-forge.xml.log"))); QString longText = QString::fromUtf8(FS::read(FS::PathCombine(source, "TerraFirmaGreg-Modern-forge.text.log"))); @@ -62,11 +62,11 @@ class XmlLogParseTest : public QObject { QList longTextLevelsPlain; longTextLevelsPlain.reserve(974); std::transform(longTextLevels_s.cbegin(), longTextLevels_s.cend(), std::back_inserter(longTextLevelsPlain), - [](const QString& line) { return messageLevelFromName(line.trimmed()); }); + [](const QString& line) { return MessageLevel::fromName(line.trimmed()); }); QList longTextLevelsXml; longTextLevelsXml.reserve(896); std::transform(longTextLevelsXml_s.cbegin(), longTextLevelsXml_s.cend(), std::back_inserter(longTextLevelsXml), - [](const QString& line) { return messageLevelFromName(line.trimmed()); }); + [](const QString& line) { return MessageLevel::fromName(line.trimmed()); }); QTest::addColumn("log"); QTest::addColumn("num_entries");