From 1a0bbdd9acaf1c5edaad6d3f0790c1b02674c0ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sun, 21 Feb 2016 01:44:27 +0100 Subject: GH-1453 report version file problems in the version page --- logic/minecraft/MinecraftProfile.cpp | 26 ++++++++++++++++- logic/minecraft/MinecraftVersion.cpp | 54 ++++++++++++++++++++++++++++++++---- logic/minecraft/MinecraftVersion.h | 7 +++++ logic/minecraft/OneSixInstance.cpp | 19 +++++++++++++ logic/minecraft/ProfilePatch.h | 54 ++++++++++++++++++++++++++++++++++++ logic/minecraft/ProfileUtils.cpp | 19 +++++++++++-- logic/minecraft/VersionFile.cpp | 26 +++++++++-------- 7 files changed, 184 insertions(+), 21 deletions(-) (limited to 'logic') diff --git a/logic/minecraft/MinecraftProfile.cpp b/logic/minecraft/MinecraftProfile.cpp index 4f33920b..360fa575 100644 --- a/logic/minecraft/MinecraftProfile.cpp +++ b/logic/minecraft/MinecraftProfile.cpp @@ -295,6 +295,8 @@ QVariant MinecraftProfile::data(const QModelIndex &index, int role) const if (row < 0 || row >= VersionPatches.size()) return QVariant(); + auto patch = VersionPatches.at(row); + if (role == Qt::DisplayRole) { switch (column) @@ -303,7 +305,6 @@ QVariant MinecraftProfile::data(const QModelIndex &index, int role) const return VersionPatches.at(row)->getPatchName(); case 1: { - auto patch = VersionPatches.at(row); if(patch->isCustom()) { return QString("%1 (Custom)").arg(patch->getPatchVersion()); @@ -317,6 +318,29 @@ QVariant MinecraftProfile::data(const QModelIndex &index, int role) const return QVariant(); } } + if(role == Qt::DecorationRole) + { + switch(column) + { + case 0: + { + auto severity = patch->getProblemSeverity(); + switch (severity) + { + case PROBLEM_WARNING: + return "warning"; + case PROBLEM_ERROR: + return "error"; + default: + return QVariant(); + } + } + default: + { + return QVariant(); + } + } + } return QVariant(); } QVariant MinecraftProfile::headerData(int section, Qt::Orientation orientation, int role) const diff --git a/logic/minecraft/MinecraftVersion.cpp b/logic/minecraft/MinecraftVersion.cpp index 96d64d6d..e6895bf7 100644 --- a/logic/minecraft/MinecraftVersion.cpp +++ b/logic/minecraft/MinecraftVersion.cpp @@ -89,12 +89,36 @@ QString MinecraftVersion::getUrl() const VersionFilePtr MinecraftVersion::getVersionFile() { QFileInfo versionFile(QString("versions/%1/%1.dat").arg(m_descriptor)); - - auto loadedVersionFile = ProfileUtils::parseBinaryJsonFile(versionFile); - loadedVersionFile->name = "Minecraft"; - //FIXME: possibly not the best place for this... but w/e - loadedVersionFile->setCustomizable(true); - return loadedVersionFile; + m_problems.clear(); + m_problemSeverity = PROBLEM_NONE; + if(!versionFile.exists()) + { + if(m_loadedVersionFile) + { + m_loadedVersionFile.reset(); + } + addProblem(PROBLEM_WARNING, QObject::tr("The patch file doesn't exist locally. It's possible it just needs to be downloaded.")); + } + else + { + try + { + if(versionFile.lastModified() != m_loadedVersionFileTimestamp) + { + auto loadedVersionFile = ProfileUtils::parseBinaryJsonFile(versionFile); + loadedVersionFile->name = "Minecraft"; + loadedVersionFile->setCustomizable(true); + m_loadedVersionFileTimestamp = versionFile.lastModified(); + m_loadedVersionFile = loadedVersionFile; + } + } + catch(Exception e) + { + m_loadedVersionFile.reset(); + addProblem(PROBLEM_ERROR, QObject::tr("The patch file couldn't be read:\n%1").arg(e.cause())); + } + } + return m_loadedVersionFile; } bool MinecraftVersion::isCustomizable() @@ -114,6 +138,24 @@ bool MinecraftVersion::isCustomizable() return false; } +const QList &MinecraftVersion::getProblems() +{ + if(m_versionSource != Builtin && getVersionFile()) + { + return getVersionFile()->getProblems(); + } + return ProfilePatch::getProblems(); +} + +ProblemSeverity MinecraftVersion::getProblemSeverity() +{ + if(m_versionSource != Builtin && getVersionFile()) + { + return getVersionFile()->getProblemSeverity(); + } + return ProfilePatch::getProblemSeverity(); +} + void MinecraftVersion::applyTo(MinecraftProfile *version) { // do we have this one cached? diff --git a/logic/minecraft/MinecraftVersion.h b/logic/minecraft/MinecraftVersion.h index 120ea8ce..afeac3b7 100644 --- a/logic/minecraft/MinecraftVersion.h +++ b/logic/minecraft/MinecraftVersion.h @@ -78,6 +78,9 @@ public: /* methods */ QString getUrl() const; + virtual const QList &getProblems() override; + virtual ProblemSeverity getProblemSeverity() override; + private: /* methods */ void applyFileTo(MinecraftProfile *version); @@ -124,4 +127,8 @@ public: /* data */ /// an update available from Mojang MinecraftVersionPtr upstreamUpdate; + +private: /* data */ + QDateTime m_loadedVersionFileTimestamp; + mutable VersionFilePtr m_loadedVersionFile; }; diff --git a/logic/minecraft/OneSixInstance.cpp b/logic/minecraft/OneSixInstance.cpp index da1b21cb..9a3920cc 100644 --- a/logic/minecraft/OneSixInstance.cpp +++ b/logic/minecraft/OneSixInstance.cpp @@ -111,6 +111,14 @@ QStringList OneSixInstance::processMinecraftArgs(AuthSessionPtr session) // blatant self-promotion. token_mapping["profile_name"] = token_mapping["version_name"] = "MultiMC5"; + if(m_version->isVanilla()) + { + token_mapping["version_type"] = m_version->type; + } + else + { + token_mapping["version_type"] = "custom"; + } QString absRootDir = QDir(minecraftRoot()).absolutePath(); token_mapping["game_directory"] = absRootDir; @@ -119,10 +127,21 @@ QStringList OneSixInstance::processMinecraftArgs(AuthSessionPtr session) token_mapping["user_properties"] = session->serializeUserProperties(); token_mapping["user_type"] = session->user_type; + // 1.7.3+ assets tokens token_mapping["assets_root"] = absAssetsDir; token_mapping["assets_index_name"] = m_version->assets; + // 1.9+ version type token + if(m_version->isVanilla()) + { + token_mapping["version_type"] = m_version->type; + } + else + { + token_mapping["version_type"] = "custom"; + } + QStringList parts = args_pattern.split(' ', QString::SkipEmptyParts); for (int i = 0; i < parts.length(); i++) { diff --git a/logic/minecraft/ProfilePatch.h b/logic/minecraft/ProfilePatch.h index de42cb7a..e4bb1c02 100644 --- a/logic/minecraft/ProfilePatch.h +++ b/logic/minecraft/ProfilePatch.h @@ -6,6 +6,35 @@ #include "JarMod.h" class MinecraftProfile; + +enum ProblemSeverity +{ + PROBLEM_NONE, + PROBLEM_WARNING, + PROBLEM_ERROR +}; + +class PatchProblem +{ +public: + PatchProblem(ProblemSeverity severity, const QString & description) + { + m_severity = severity; + m_description = description; + } + const QString & getDescription() const + { + return m_description; + } + const ProblemSeverity getSeverity() const + { + return m_severity; + } +private: + ProblemSeverity m_severity; + QString m_description; +}; + class ProfilePatch { public: @@ -32,6 +61,31 @@ public: virtual QString getPatchName() = 0; virtual QString getPatchVersion() = 0; virtual QString getPatchFilename() = 0; + + virtual const QList& getProblems() + { + return m_problems; + } + virtual void addProblem(ProblemSeverity severity, const QString &description) + { + if(severity > m_problemSeverity) + { + m_problemSeverity = severity; + } + m_problems.append(PatchProblem(severity, description)); + } + virtual ProblemSeverity getProblemSeverity() + { + return m_problemSeverity; + } + virtual bool hasFailed() + { + return getProblemSeverity() == PROBLEM_ERROR; + } + +protected: + QList m_problems; + ProblemSeverity m_problemSeverity = PROBLEM_NONE; }; typedef std::shared_ptr ProfilePatchPtr; diff --git a/logic/minecraft/ProfileUtils.cpp b/logic/minecraft/ProfileUtils.cpp index 9a886f1d..5816f207 100644 --- a/logic/minecraft/ProfileUtils.cpp +++ b/logic/minecraft/ProfileUtils.cpp @@ -107,13 +107,26 @@ VersionFilePtr parseJsonFile(const QFileInfo &fileInfo, const bool requireOrder) .arg(fileInfo.fileName(), file.errorString())); } QJsonParseError error; - QJsonDocument doc = QJsonDocument::fromJson(file.readAll(), &error); + auto data = file.readAll(); + QJsonDocument doc = QJsonDocument::fromJson(data, &error); if (error.error != QJsonParseError::NoError) { + int line = 0; + int column = 0; + for(int i = 0; i < error.offset; i++) + { + if(data[i] == '\n') + { + line++; + column = 0; + continue; + } + column++; + } throw JSONValidationError( - QObject::tr("Unable to process the version file %1: %2 at %3.") + QObject::tr("Unable to process the version file %1: %2 at line %3 column %4.") .arg(fileInfo.fileName(), error.errorString()) - .arg(error.offset)); + .arg(line).arg(column)); } return VersionFile::fromJson(doc, file.fileName(), requireOrder); } diff --git a/logic/minecraft/VersionFile.cpp b/logic/minecraft/VersionFile.cpp index 50f4c289..fee83900 100644 --- a/logic/minecraft/VersionFile.cpp +++ b/logic/minecraft/VersionFile.cpp @@ -15,8 +15,6 @@ using namespace Json; #include "VersionBuildError.h" #include -#define CURRENT_MINIMUM_LAUNCHER_VERSION 18 - static void readString(const QJsonObject &root, const QString &key, QString &variable) { if (root.contains(key)) @@ -50,6 +48,19 @@ int findLibraryByName(QList haystack, const GradleSpecifier &n return retval; } +void checkMinimumLauncherVersion(VersionFilePtr out) +{ + const int CURRENT_MINIMUM_LAUNCHER_VERSION = 14; + if (out->minimumLauncherVersion > CURRENT_MINIMUM_LAUNCHER_VERSION) + { + out->addProblem( + PROBLEM_WARNING, + QObject::tr("The 'minimumLauncherVersion' value of this version (%1) is higher than supported by MultiMC (%2). It might not work properly!") + .arg(out->minimumLauncherVersion) + .arg(CURRENT_MINIMUM_LAUNCHER_VERSION)); + } +} + VersionFilePtr VersionFile::fromMojangJson(const QJsonDocument &doc, const QString &filename) { VersionFilePtr out(new VersionFile()); @@ -82,6 +93,7 @@ VersionFilePtr VersionFile::fromMojangJson(const QJsonDocument &doc, const QStri if (root.contains("minimumLauncherVersion")) { out->minimumLauncherVersion = requireInteger(root.value("minimumLauncherVersion")); + checkMinimumLauncherVersion(out); } if (root.contains("libraries")) @@ -149,6 +161,7 @@ VersionFilePtr VersionFile::fromJson(const QJsonDocument &doc, const QString &fi if (root.contains("minimumLauncherVersion")) { out->minimumLauncherVersion = requireInteger(root.value("minimumLauncherVersion")); + checkMinimumLauncherVersion(out); } if (root.contains("tweakers")) @@ -304,15 +317,6 @@ bool VersionFile::hasJarMods() void VersionFile::applyTo(MinecraftProfile *version) { - if (minimumLauncherVersion != -1) - { - if (minimumLauncherVersion > CURRENT_MINIMUM_LAUNCHER_VERSION) - { - throw LauncherVersionError(minimumLauncherVersion, - CURRENT_MINIMUM_LAUNCHER_VERSION); - } - } - if (!version->id.isNull() && !mcVersion.isNull()) { if (QRegExp(mcVersion, Qt::CaseInsensitive, QRegExp::Wildcard).indexIn(version->id) == -- cgit v1.2.3